aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--linden/indra/llxml/llcontrol.cpp9
-rw-r--r--linden/indra/newview/CMakeLists.txt3
-rw-r--r--linden/indra/newview/app_settings/settings.xml55
-rw-r--r--linden/indra/newview/llagent.cpp119
-rw-r--r--linden/indra/newview/llagent.h4
-rw-r--r--linden/indra/newview/llappviewer.cpp14
-rw-r--r--linden/indra/newview/llchatbar.cpp15
-rw-r--r--linden/indra/newview/llfirstuse.cpp15
-rw-r--r--linden/indra/newview/llfirstuse.h4
-rw-r--r--linden/indra/newview/llfloaterabout.cpp6
-rw-r--r--linden/indra/newview/llfloateractivespeakers.cpp6
-rw-r--r--linden/indra/newview/llfloateranimpreview.cpp1
-rw-r--r--linden/indra/newview/llfloateravatarpicker.cpp4
-rw-r--r--linden/indra/newview/llfloaterbeacons.cpp4
-rw-r--r--linden/indra/newview/llfloaterchat.cpp4
-rw-r--r--linden/indra/newview/llfloaterinspect.cpp4
-rw-r--r--linden/indra/newview/llfloaterland.cpp4
-rw-r--r--linden/indra/newview/llfloatermap.cpp4
-rw-r--r--linden/indra/newview/llfloaterobjectiminfo.cpp4
-rw-r--r--linden/indra/newview/llfloaterproperties.cpp5
-rw-r--r--linden/indra/newview/llfloaterregioninfo.cpp4
-rw-r--r--linden/indra/newview/llfloaterreporter.cpp6
-rw-r--r--linden/indra/newview/llfloatersettingsdebug.cpp4
-rw-r--r--linden/indra/newview/llfloaterteleporthistory.cpp30
-rw-r--r--linden/indra/newview/llfloaterworldmap.cpp12
-rw-r--r--linden/indra/newview/llgesturemgr.cpp1
-rw-r--r--linden/indra/newview/llglsandbox.cpp8
-rw-r--r--linden/indra/newview/llhoverview.cpp20
-rw-r--r--linden/indra/newview/llhudeffectlookat.cpp5
-rw-r--r--linden/indra/newview/llhudtext.cpp3
-rw-r--r--linden/indra/newview/llimpanel.cpp14
-rw-r--r--linden/indra/newview/llimview.cpp6
-rw-r--r--linden/indra/newview/llinventoryactions.cpp9
-rw-r--r--linden/indra/newview/llinventorybridge.cpp66
-rw-r--r--linden/indra/newview/llinventorybridge.h35
-rw-r--r--linden/indra/newview/llinventorymodel.cpp4
-rw-r--r--linden/indra/newview/llinventoryview.cpp4
-rw-r--r--linden/indra/newview/llmaniptranslate.cpp4
-rw-r--r--linden/indra/newview/llnetmap.cpp8
-rw-r--r--linden/indra/newview/llnotify.cpp2
-rw-r--r--linden/indra/newview/lloverlaybar.cpp4
-rw-r--r--linden/indra/newview/llpanelavatar.cpp4
-rw-r--r--linden/indra/newview/llpanelclassified.cpp4
-rw-r--r--linden/indra/newview/llpanelcontents.cpp4
-rw-r--r--linden/indra/newview/llpaneldisplay.cpp4
-rw-r--r--linden/indra/newview/llpanelinventory.cpp17
-rw-r--r--linden/indra/newview/llpanelland.cpp4
-rw-r--r--linden/indra/newview/llpanellogin.cpp4
-rw-r--r--linden/indra/newview/llpanelobject.cpp4
-rw-r--r--linden/indra/newview/llpanelpermissions.cpp6
-rw-r--r--linden/indra/newview/llpanelpick.cpp4
-rw-r--r--linden/indra/newview/llprefsim.cpp4
-rw-r--r--linden/indra/newview/llpreviewscript.cpp3
-rw-r--r--linden/indra/newview/llselectmgr.cpp15
-rw-r--r--linden/indra/newview/llstartup.cpp14
-rw-r--r--linden/indra/newview/llstatusbar.cpp6
-rw-r--r--linden/indra/newview/lltoolbar.cpp4
-rw-r--r--linden/indra/newview/lltooldraganddrop.cpp28
-rw-r--r--linden/indra/newview/lltoolface.cpp9
-rw-r--r--linden/indra/newview/lltoolgrab.cpp28
-rw-r--r--linden/indra/newview/lltoolpie.cpp117
-rw-r--r--linden/indra/newview/lltoolplacer.cpp8
-rw-r--r--linden/indra/newview/lltoolselect.cpp5
-rw-r--r--linden/indra/newview/lltracker.cpp11
-rw-r--r--linden/indra/newview/llviewercontrol.cpp20
-rw-r--r--linden/indra/newview/llviewerdisplay.cpp4
-rw-r--r--linden/indra/newview/llviewermenu.cpp102
-rwxr-xr-xlinden/indra/newview/llviewermessage.cpp127
-rw-r--r--linden/indra/newview/llviewerobject.cpp22
-rw-r--r--linden/indra/newview/llviewertexteditor.cpp12
-rw-r--r--linden/indra/newview/llviewerwindow.cpp36
-rw-r--r--linden/indra/newview/llvoavatar.cpp58
-rw-r--r--linden/indra/newview/llvoavatar.h3
-rw-r--r--linden/indra/newview/llvovolume.cpp4
-rw-r--r--linden/indra/newview/llworldmapview.cpp7
-rw-r--r--linden/indra/newview/panelradar.cpp6
-rw-r--r--linden/indra/newview/pipeline.cpp4
-rw-r--r--linden/indra/newview/rlvdefines.h217
-rw-r--r--linden/indra/newview/rlvevent.h227
-rw-r--r--linden/indra/newview/rlvextensions.cpp109
-rw-r--r--linden/indra/newview/rlvextensions.h33
-rw-r--r--linden/indra/newview/rlvfloaterbehaviour.cpp17
-rw-r--r--linden/indra/newview/rlvfloaterbehaviour.h18
-rw-r--r--linden/indra/newview/rlvhandler.cpp2809
-rw-r--r--linden/indra/newview/rlvhandler.h321
-rw-r--r--linden/indra/newview/rlvhelper.cpp649
-rw-r--r--linden/indra/newview/rlvhelper.h206
-rw-r--r--linden/indra/newview/rlvmultistringsearch.cpp16
-rw-r--r--linden/indra/newview/rlvmultistringsearch.h16
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml8
90 files changed, 3477 insertions, 2414 deletions
diff --git a/linden/indra/llxml/llcontrol.cpp b/linden/indra/llxml/llcontrol.cpp
index 1d1f024..452167e 100644
--- a/linden/indra/llxml/llcontrol.cpp
+++ b/linden/indra/llxml/llcontrol.cpp
@@ -1099,6 +1099,15 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
1099 } 1099 }
1100*/ 1100*/
1101 1101
1102// [RLVa:KB] - Checked: 2010-06-20 (RLVa-1.1.2a) | Added: RLVa-1.1.2a
1103 // HACK-RLVa: bad code but it's just a temporary measure to provide a smooth changeover from the old to the new rebranded settings
1104 if ( (name.length() >= 14) && (0 == name.find("RestrainedLife")) )
1105 {
1106 // Transparently convert the old settings name to the new one while preserving the user override
1107 name = "RestrainedLove" + name.substr(14);
1108 }
1109// [/RLVa:KB]
1110
1102 // If the control exists just set the value from the input file. 1111 // If the control exists just set the value from the input file.
1103 LLControlVariable* existing_control = getControl(name); 1112 LLControlVariable* existing_control = getControl(name);
1104 if(existing_control) 1113 if(existing_control)
diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt
index 9260b75..9ac2d57 100644
--- a/linden/indra/newview/CMakeLists.txt
+++ b/linden/indra/newview/CMakeLists.txt
@@ -486,6 +486,7 @@ set(viewer_SOURCE_FILES
486 primbackup.cpp 486 primbackup.cpp
487 rlvhandler.cpp 487 rlvhandler.cpp
488 rlvhelper.cpp 488 rlvhelper.cpp
489 rlvcommon.cpp
489 rlvmultistringsearch.cpp 490 rlvmultistringsearch.cpp
490 rlvextensions.cpp 491 rlvextensions.cpp
491 rlvfloaterbehaviour.cpp 492 rlvfloaterbehaviour.cpp
@@ -937,9 +938,9 @@ set(viewer_HEADER_FILES
937 primbackup.h 938 primbackup.h
938 randgauss.h 939 randgauss.h
939 rlvdefines.h 940 rlvdefines.h
940 rlvevent.h
941 rlvhandler.h 941 rlvhandler.h
942 rlvhelper.h 942 rlvhelper.h
943 rlvcommon.h
943 rlvmultistringsearch.h 944 rlvmultistringsearch.h
944 rlvextensions.h 945 rlvextensions.h
945 rlvfloaterbehaviour.h 946 rlvfloaterbehaviour.h
diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml
index d33285d..3be4ed4 100644
--- a/linden/indra/newview/app_settings/settings.xml
+++ b/linden/indra/newview/app_settings/settings.xml
@@ -1784,10 +1784,10 @@
1784 1784
1785 <!-- End: Spellcheck & Translation --> 1785 <!-- End: Spellcheck & Translation -->
1786 1786
1787 <key>RestrainedLife</key> 1787 <key>RestrainedLove</key>
1788 <map> 1788 <map>
1789 <key>Comment</key> 1789 <key>Comment</key>
1790 <string>Toggles the RestrainedLife features (BDSM lockable toys support). Needs a restart of the viewer.</string> 1790 <string>Toggles the RestrainedLove features (BDSM lockable toys support). Needs a restart of the viewer.</string>
1791 <key>Persist</key> 1791 <key>Persist</key>
1792 <integer>1</integer> 1792 <integer>1</integer>
1793 <key>Type</key> 1793 <key>Type</key>
@@ -1795,10 +1795,10 @@
1795 <key>Value</key> 1795 <key>Value</key>
1796 <integer>0</integer> 1796 <integer>0</integer>
1797 </map> 1797 </map>
1798 <key>RestrainedLifeDebug</key> 1798 <key>RestrainedLoveDebug</key>
1799 <map> 1799 <map>
1800 <key>Comment</key> 1800 <key>Comment</key>
1801 <string>Toggles the RestrainedLife debug mode (displays the commands when in debug mode).</string> 1801 <string>Toggles the RestrainedLove debug mode (displays the commands when in debug mode).</string>
1802 <key>Persist</key> 1802 <key>Persist</key>
1803 <integer>1</integer> 1803 <integer>1</integer>
1804 <key>Type</key> 1804 <key>Type</key>
@@ -1806,10 +1806,10 @@
1806 <key>Value</key> 1806 <key>Value</key>
1807 <integer>0</integer> 1807 <integer>0</integer>
1808 </map> 1808 </map>
1809 <key>RestrainedLifeNoSetEnv</key> 1809 <key>RestrainedLoveNoSetEnv</key>
1810 <map> 1810 <map>
1811 <key>Comment</key> 1811 <key>Comment</key>
1812 <string>When TRUE, forbids to set the environment (time of day and Windlight settings) via RestrainedLife. Needs a restart of the viewer.</string> 1812 <string>When TRUE, forbids to set the environment (time of day and Windlight settings) via RestrainedLove. Needs a restart of the viewer.</string>
1813 <key>Persist</key> 1813 <key>Persist</key>
1814 <integer>1</integer> 1814 <integer>1</integer>
1815 <key>Type</key> 1815 <key>Type</key>
@@ -1817,10 +1817,10 @@
1817 <key>Value</key> 1817 <key>Value</key>
1818 <integer>0</integer> 1818 <integer>0</integer>
1819 </map> 1819 </map>
1820 <key>RestrainedLifeForbidGiveToRLV</key> 1820 <key>RestrainedLoveForbidGiveToRLV</key>
1821 <map> 1821 <map>
1822 <key>Comment</key> 1822 <key>Comment</key>
1823 <string>When FALSE, allows to give sub-folders to the #RLV RestrainedLife folder.</string> 1823 <string>When FALSE, allows to give sub-folders to the #RLV RestrainedLove folder.</string>
1824 <key>Persist</key> 1824 <key>Persist</key>
1825 <integer>1</integer> 1825 <integer>1</integer>
1826 <key>Type</key> 1826 <key>Type</key>
@@ -1828,6 +1828,17 @@
1828 <key>Value</key> 1828 <key>Value</key>
1829 <integer>1</integer> 1829 <integer>1</integer>
1830 </map> 1830 </map>
1831 <key>RLVaEnableCompositeFolders</key>
1832 <map>
1833 <key>Comment</key>
1834 <string>Enables composite folders for shared inventory</string>
1835 <key>Persist</key>
1836 <integer>1</integer>
1837 <key>Type</key>
1838 <string>Boolean</string>
1839 <key>Value</key>
1840 <integer>0</integer>
1841 </map>
1831 <key>RLVaEnableLegacyNaming</key> 1842 <key>RLVaEnableLegacyNaming</key>
1832 <map> 1843 <map>
1833 <key>Comment</key> 1844 <key>Comment</key>
@@ -1842,7 +1853,7 @@
1842 <key>RLVaEnableWear</key> 1853 <key>RLVaEnableWear</key>
1843 <map> 1854 <map>
1844 <key>Comment</key> 1855 <key>Comment</key>
1845 <string>When TRUE, enables the "Wear" option on the inventory item context menu for attachments.</string> 1856 <string>Enables the "Wear" option on the inventory item context menu for attachments</string>
1846 <key>Persist</key> 1857 <key>Persist</key>
1847 <integer>1</integer> 1858 <integer>1</integer>
1848 <key>Type</key> 1859 <key>Type</key>
@@ -1850,10 +1861,21 @@
1850 <key>Value</key> 1861 <key>Value</key>
1851 <integer>1</integer> 1862 <integer>1</integer>
1852 </map> 1863 </map>
1864 <key>RLVaEnableSharedWear</key>
1865 <map>
1866 <key>Comment</key>
1867 <string>Attachments in the shared #RLV folder can be force-attached without needing to specify an attachment point (as long as no attachment is non-detachable)</string>
1868 <key>Persist</key>
1869 <integer>1</integer>
1870 <key>Type</key>
1871 <string>Boolean</string>
1872 <key>Value</key>
1873 <integer>0</integer>
1874 </map>
1853 <key>RLVaHideLockedLayers</key> 1875 <key>RLVaHideLockedLayers</key>
1854 <map> 1876 <map>
1855 <key>Comment</key> 1877 <key>Comment</key>
1856 <string>When TRUE, hides worn but "remove outfit" restricted clothing layers from @getoufit</string> 1878 <string>Hides "remove outfit" restricted worn clothing layers from @getoufit</string>
1857 <key>Persist</key> 1879 <key>Persist</key>
1858 <integer>1</integer> 1880 <integer>1</integer>
1859 <key>Type</key> 1881 <key>Type</key>
@@ -1864,7 +1886,7 @@
1864 <key>RLVaHideLockedAttachments</key> 1886 <key>RLVaHideLockedAttachments</key>
1865 <map> 1887 <map>
1866 <key>Comment</key> 1888 <key>Comment</key>
1867 <string>When TRUE, hides worn but "no detach" restricted attachments from @getattach</string> 1889 <string>Hides non-detachable worn attachments from @getattach</string>
1868 <key>Persist</key> 1890 <key>Persist</key>
1869 <integer>1</integer> 1891 <integer>1</integer>
1870 <key>Type</key> 1892 <key>Type</key>
@@ -1872,6 +1894,17 @@
1872 <key>Value</key> 1894 <key>Value</key>
1873 <integer>0</integer> 1895 <integer>0</integer>
1874 </map> 1896 </map>
1897 <key>RLVaSharedInvAutoRename</key>
1898 <map>
1899 <key>Comment</key>
1900 <string>Automatically renames shared inventory items when worn</string>
1901 <key>Persist</key>
1902 <integer>1</integer>
1903 <key>Type</key>
1904 <string>Boolean</string>
1905 <key>Value</key>
1906 <integer>1</integer>
1907 </map>
1875 <key>RLVaShowNameTags</key> 1908 <key>RLVaShowNameTags</key>
1876 <map> 1909 <map>
1877 <key>Comment</key> 1910 <key>Comment</key>
diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp
index fc12f33..eb5cf9b 100644
--- a/linden/indra/newview/llagent.cpp
+++ b/linden/indra/newview/llagent.cpp
@@ -136,6 +136,10 @@
136#include "llviewerjoystick.h" 136#include "llviewerjoystick.h"
137#include "llfollowcam.h" 137#include "llfollowcam.h"
138 138
139// [RLVa:KB]
140#include "rlvhandler.h"
141// [/RLVa:KB]
142
139using namespace LLVOAvatarDefines; 143using namespace LLVOAvatarDefines;
140 144
141extern LLMenuBarGL* gMenuBarView; 145extern LLMenuBarGL* gMenuBarView;
@@ -4878,7 +4882,15 @@ void LLAgent::onAnimStop(const LLUUID& id)
4878 } 4882 }
4879 else if (id == ANIM_AGENT_AWAY) 4883 else if (id == ANIM_AGENT_AWAY)
4880 { 4884 {
4885 //clearAFK();
4886// [RLVa:KB] - Checked: 2009-10-19 (RLVa-1.1.0g) | Added: RLVa-1.1.0g
4887#ifdef RLV_EXTENSION_CMD_ALLOWIDLE
4888 if (!gRlvHandler.hasBehaviour(RLV_BHVR_ALLOWIDLE))
4889 clearAFK();
4890#else
4881 clearAFK(); 4891 clearAFK();
4892#endif // RLV_EXTENSION_CMD_ALLOWIDLE
4893// [/RLVa:KB]
4882 } 4894 }
4883 else if (id == ANIM_AGENT_STANDUP) 4895 else if (id == ANIM_AGENT_STANDUP)
4884 { 4896 {
@@ -5220,7 +5232,7 @@ void LLAgent::buildLocationString(std::string& str)
5220// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) 5232// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a)
5221 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) 5233 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))
5222 { 5234 {
5223 str = rlv_handler_t::cstrHidden; 5235 str = RlvStrings::getString(RLV_STRING_HIDDEN);
5224 return; 5236 return;
5225 } 5237 }
5226// [/RLVa:KB] 5238// [/RLVa:KB]
@@ -6223,14 +6235,21 @@ void LLAgent::teleportCancel()
6223 6235
6224void LLAgent::teleportViaLocation(const LLVector3d& pos_global) 6236void LLAgent::teleportViaLocation(const LLVector3d& pos_global)
6225{ 6237{
6226// [RLVa:KB] - Alternate: Snowglobe-1.0 | Checked: 2009-07-07 (RLVa-1.0.0d) 6238// [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2010-03-02 (RLVa-1.1.1a) | Modified: RLVa-1.2.0a
6227 // If we're getting teleported due to @tpto we should disregard any @tploc=n or @unsit=n restrictions from the same object 6239 if (rlv_handler_t::isEnabled())
6228 if ( (rlv_handler_t::isEnabled()) &&
6229 ( (gRlvHandler.hasBehaviourExcept(RLV_BHVR_TPLOC, gRlvHandler.getCurrentObject())) ||
6230 ( (mAvatarObject.notNull()) && (mAvatarObject->mIsSitting) &&
6231 (gRlvHandler.hasBehaviourExcept(RLV_BHVR_UNSIT, gRlvHandler.getCurrentObject()))) ) )
6232 { 6240 {
6233 return; 6241 // If we're getting teleported due to @tpto we should disregard any @tploc=n or @unsit=n restrictions from the same object
6242 if ( (gRlvHandler.hasBehaviourExcept(RLV_BHVR_TPLOC, gRlvHandler.getCurrentObject())) ||
6243 ( (mAvatarObject.notNull()) && (mAvatarObject->mIsSitting) &&
6244 (gRlvHandler.hasBehaviourExcept(RLV_BHVR_UNSIT, gRlvHandler.getCurrentObject()))) )
6245 {
6246 return;
6247 }
6248
6249 if ( (gRlvHandler.getCurrentCommand()) && (RLV_BHVR_TPTO == gRlvHandler.getCurrentCommand()->getBehaviourType()) )
6250 {
6251 gRlvHandler.setCanCancelTp(false);
6252 }
6234 } 6253 }
6235// [/RLVa:KB] 6254// [/RLVa:KB]
6236 6255
@@ -6300,7 +6319,7 @@ void LLAgent::setTeleportState(ETeleportState state)
6300 // We're outa here. Save "back" slurl. 6319 // We're outa here. Save "back" slurl.
6301 mTeleportSourceSLURL = getSLURL(); 6320 mTeleportSourceSLURL = getSLURL();
6302 } 6321 }
6303// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-07 (RLVa-1.0.0d) | Added: RLVa-0.2.0b 6322// [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Version: 1.23.4 | Checked: 2009-07-07 (RLVa-1.0.0d) | Added: RLVa-0.2.0b
6304 if ( (rlv_handler_t::isEnabled()) && (TELEPORT_NONE == mTeleportState) ) 6323 if ( (rlv_handler_t::isEnabled()) && (TELEPORT_NONE == mTeleportState) )
6305 { 6324 {
6306 gRlvHandler.setCanCancelTp(true); 6325 gRlvHandler.setCanCancelTp(true);
@@ -6943,14 +6962,14 @@ void LLAgent::processAgentInitialWearablesUpdate( LLMessageSystem* mesgsys, void
6943 } 6962 }
6944 6963
6945 // now that we have the asset ids...request the wearable assets 6964 // now that we have the asset ids...request the wearable assets
6946// [RLVa:KB] - Checked: 2009-08-08 (RLVa-1.0.1g) | Added: RLVa-1.0.1g 6965// [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2009-08-08 (RLVa-1.0.1g) | Added: RLVa-1.0.1g
6947 LLInventoryFetchObserver::item_ref_t rlvItems; 6966 LLInventoryFetchObserver::item_ref_t rlvItems;
6948// [/RLVa:KB] 6967// [/RLVa:KB]
6949 for( i = 0; i < WT_COUNT; i++ ) 6968 for( i = 0; i < WT_COUNT; i++ )
6950 { 6969 {
6951 if( !gAgent.mWearableEntry[i].mItemID.isNull() ) 6970 if( !gAgent.mWearableEntry[i].mItemID.isNull() )
6952 { 6971 {
6953// [RLVa:KB] - Checked: 2009-08-08 (RLVa-1.0.1g) | Added: RLVa-1.0.1g 6972// [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2009-08-08 (RLVa-1.0.1g) | Added: RLVa-1.0.1g
6954 if (rlv_handler_t::isEnabled()) 6973 if (rlv_handler_t::isEnabled())
6955 rlvItems.push_back(gAgent.mWearableEntry[i].mItemID); 6974 rlvItems.push_back(gAgent.mWearableEntry[i].mItemID);
6956// [/RLVa:KB] 6975// [/RLVa:KB]
@@ -6962,7 +6981,7 @@ void LLAgent::processAgentInitialWearablesUpdate( LLMessageSystem* mesgsys, void
6962 } 6981 }
6963 } 6982 }
6964 6983
6965// [RLVa:KB] - Checked: 2009-08-08 (RLVa-1.0.1g) | Added: RLVa-1.0.1g 6984// [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2009-08-08 (RLVa-1.0.1g) | Added: RLVa-1.0.1g
6966 // TODO-RLVa: checking that we're in STATE_STARTED is probably not needed, but leave it until we can be absolutely sure 6985 // TODO-RLVa: checking that we're in STATE_STARTED is probably not needed, but leave it until we can be absolutely sure
6967 if ( (rlv_handler_t::isEnabled()) && (LLStartUp::getStartupState() == STATE_STARTED) ) 6986 if ( (rlv_handler_t::isEnabled()) && (LLStartUp::getStartupState() == STATE_STARTED) )
6968 { 6987 {
@@ -7949,93 +7968,37 @@ void LLAgent::userRemoveAllAttachments( void* userdata )
7949 return; 7968 return;
7950 } 7969 }
7951 7970
7952// [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a 7971// [RLVa:KB] - Checked: 2009-11-24 (RLVa-1.1.0f) | Modified: RLVa-1.1.0e
7953 // NOTE-RLVa: This function is called from inside RlvHandler as well, hence the rather heavy modifications 7972 std::list<U32> LocalIDs;
7954 std::list<U32> rlvAttachments; 7973 for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); iter != avatarp->mAttachmentPoints.end(); )
7955 // TODO-RLVa: Once we have the improved "removeWearable" logic implemented we can just get rid of the whole "rlvCompFolders" hassle
7956 #ifdef RLV_EXPERIMENTAL_COMPOSITES
7957 std::list<LLUUID> rlvCompFolders;
7958 #endif // RLV_EXPERIMENTAL_COMPOSITES
7959
7960 for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin();
7961 iter != avatarp->mAttachmentPoints.end(); )
7962 { 7974 {
7963 LLVOAvatar::attachment_map_t::iterator curiter = iter++; 7975 LLVOAvatar::attachment_map_t::iterator curiter = iter++;
7964 LLViewerJointAttachment* attachment = curiter->second; 7976 LLViewerJointAttachment* attachment = curiter->second;
7965 LLViewerObject* objectp = attachment->getObject(); 7977 LLViewerObject* objectp = attachment->getObject();
7966 if (objectp) 7978 if (objectp)
7967 { 7979 {
7968 if (rlv_handler_t::isEnabled()) 7980 if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.isLockedAttachment(curiter->first, RLV_LOCK_REMOVE)) )
7969 { 7981 continue;
7970 if (gRlvHandler.isLockedAttachment(curiter->first, RLV_LOCK_REMOVE)) 7982 LocalIDs.push_back(objectp->getLocalID());
7971 continue;
7972
7973 // Check if we're being called in response to an RLV command (that would be @detach=force)
7974 if ( (gRlvHandler.getCurrentCommand()) && (attachment->getItemID().notNull()) )
7975 {
7976 if (!gRlvHandler.isStrippable(attachment->getItemID())) // "nostrip" can be taken off by the user but not @detach
7977 continue;
7978
7979 #ifdef RLV_EXPERIMENTAL_COMPOSITES
7980 LLViewerInventoryCategory* pFolder;
7981 if (gRlvHandler.getCompositeInfo(attachment->getItemID(), NULL, &pFolder))
7982 {
7983 #ifdef RLV_EXPERIMENTAL_COMPOSITE_LOCKING
7984 if (!gRlvHandler.canTakeOffComposite(pFolder))
7985 continue;
7986 #endif // RLV_EXPERIMENTAL_COMPOSITE_LOCKING
7987
7988 // The attachment belongs to a composite folder so there may be additional things we need to take off
7989 if (std::find(rlvCompFolders.begin(), rlvCompFolders.end(), pFolder->getUUID()) != rlvCompFolders.end())
7990 rlvCompFolders.push_back(pFolder->getUUID());
7991 }
7992 #endif // RLV_EXPERIMENTAL_COMPOSITES
7993 }
7994 }
7995 rlvAttachments.push_back(objectp->getLocalID());
7996 } 7983 }
7997 } 7984 }
7998 7985
7999 // Only send the message if we actually have something to detach 7986 // Only send the message if we actually have something to detach
8000 if (rlvAttachments.size() > 0) 7987 if (LocalIDs.size() > 0)
8001 { 7988 {
8002 gMessageSystem->newMessage("ObjectDetach"); 7989 gMessageSystem->newMessage("ObjectDetach");
8003 gMessageSystem->nextBlockFast(_PREHASH_AgentData); 7990 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
8004 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); 7991 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
8005 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 7992 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
8006 7993
8007 for (std::list<U32>::const_iterator itAttach = rlvAttachments.begin(); itAttach != rlvAttachments.end(); ++itAttach) 7994 for (std::list<U32>::const_iterator itLocalID = LocalIDs.begin(); itLocalID != LocalIDs.end(); ++itLocalID)
8008 { 7995 {
8009 gMessageSystem->nextBlockFast(_PREHASH_ObjectData); 7996 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
8010 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, *itAttach); 7997 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, *itLocalID);
8011 } 7998 }
8012 7999
8013 gMessageSystem->sendReliable( gAgent.getRegionHost() ); 8000 gMessageSystem->sendReliable(gAgent.getRegionHost());
8014 } 8001 }
8015
8016 #ifdef RLV_EXPERIMENTAL_COMPOSITES
8017 if (rlv_handler_t::isEnabled)
8018 {
8019 // If we encountered any composite folders then we need to @detach all of them
8020 for (std::list<LLUUID>::const_iterator itFolder = rlvCompFolders.begin(); itFolder != rlvCompFolders.end(); ++itFolder)
8021 {
8022 std::string strFolder = gRlvHandler.getSharedPath(*itFolder);
8023
8024 // It shouldn't happen but make absolutely sure that we don't issue @detach:=force and reenter this function
8025 if (!strFolder.empty())
8026 {
8027 std::string strCmd = "detach:" + strFolder + "=force";
8028 #ifdef RLV_DEBUG
8029 RLV_INFOS << "\t- detaching composite folder: @" << strCmd << LL_ENDL;
8030 #endif // RLV_DEBUG
8031
8032 // HACK-RLV: executing a command while another command is currently executing isn't the best thing to do, however
8033 // in this specific case it is safe (and still better than making processForceCommand public)
8034 gRlvHandler.processCommand(gRlvHandler.getCurrentObject(), strCmd);
8035 }
8036 }
8037 }
8038 #endif // RLV_EXPERIMENTAL_COMPOSITES
8039// [/RLVa:KB] 8002// [/RLVa:KB]
8040} 8003}
8041 8004
diff --git a/linden/indra/newview/llagent.h b/linden/indra/newview/llagent.h
index f1cad9c..141c72c 100644
--- a/linden/indra/newview/llagent.h
+++ b/linden/indra/newview/llagent.h
@@ -69,10 +69,6 @@
69#include "llfollowcam.h" 69#include "llfollowcam.h"
70// end Ventrella 70// end Ventrella
71 71
72// [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d)
73#include "rlvhandler.h"
74// [/RLVa:KB]
75
76const U8 AGENT_STATE_TYPING = 0x04; // Typing indication 72const U8 AGENT_STATE_TYPING = 0x04; // Typing indication
77const U8 AGENT_STATE_EDITING = 0x10; // Set when agent has objects selected 73const U8 AGENT_STATE_EDITING = 0x10; // Set when agent has objects selected
78 74
diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp
index 96fc451..76488fb 100644
--- a/linden/indra/newview/llappviewer.cpp
+++ b/linden/indra/newview/llappviewer.cpp
@@ -178,6 +178,10 @@
178#include "hippoLimits.h" 178#include "hippoLimits.h"
179#include "hippoUpdate.h" 179#include "hippoUpdate.h"
180 180
181// [RLVa:KB]
182#include "rlvhandler.h"
183// [/RLVa:KB]
184
181// *FIX: These extern globals should be cleaned up. 185// *FIX: These extern globals should be cleaned up.
182// The globals either represent state/config/resource-storage of either 186// The globals either represent state/config/resource-storage of either
183// this app, or another 'component' of the viewer. App globals should be 187// this app, or another 'component' of the viewer. App globals should be
@@ -328,7 +332,15 @@ static std::string gHelperURI;
328void idle_afk_check() 332void idle_afk_check()
329{ 333{
330 // check idle timers 334 // check idle timers
335 //if (gAllowIdleAFK && (gAwayTriggerTimer.getElapsedTimeF32() > gSavedSettings.getF32("AFKTimeout")))
336// [RLVa:KB] - Checked: 2009-10-19 (RLVa-1.1.0g) | Added: RLVa-1.1.0g
337#ifdef RLV_EXTENSION_CMD_ALLOWIDLE
338 if ( (gAllowIdleAFK || gRlvHandler.hasBehaviour(RLV_BHVR_ALLOWIDLE)) &&
339 (gAwayTriggerTimer.getElapsedTimeF32() > gSavedSettings.getF32("AFKTimeout")))
340#else
331 if (gAllowIdleAFK && (gAwayTriggerTimer.getElapsedTimeF32() > gSavedSettings.getF32("AFKTimeout"))) 341 if (gAllowIdleAFK && (gAwayTriggerTimer.getElapsedTimeF32() > gSavedSettings.getF32("AFKTimeout")))
342#endif // RLV_EXTENSION_CMD_ALLOWIDLE
343// [/RLVa:KB]
332 { 344 {
333 gAgent.setAFK(); 345 gAgent.setAFK();
334 } 346 }
@@ -4230,7 +4242,7 @@ void LLAppViewer::handleLoginComplete()
4230 } 4242 }
4231 writeDebugInfo(); 4243 writeDebugInfo();
4232 4244
4233// [RLVa:KB] - Alternate: Snowglobe-1.0 | Checked: 2009-08-05 (RLVa-1.0.1e) | Modified: RLVa-1.0.1e 4245// [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2009-08-05 (RLVa-1.0.1e) | Modified: RLVa-1.0.1e
4234 // NOTE: this function isn't called in Imprudence so any changes need to go in idle_startup() instead 4246 // NOTE: this function isn't called in Imprudence so any changes need to go in idle_startup() instead
4235 gRlvHandler.initLookupTables(); 4247 gRlvHandler.initLookupTables();
4236 4248
diff --git a/linden/indra/newview/llchatbar.cpp b/linden/indra/newview/llchatbar.cpp
index a22fd8f..19ac2ab 100644
--- a/linden/indra/newview/llchatbar.cpp
+++ b/linden/indra/newview/llchatbar.cpp
@@ -88,6 +88,9 @@ void toggleChatHistory(void* user_data);
88void send_chat_from_viewer(std::string utf8_out_text, EChatType type, S32 channel); 88void send_chat_from_viewer(std::string utf8_out_text, EChatType type, S32 channel);
89// [/RLVa:KB] 89// [/RLVa:KB]
90 90
91// [RLVa:KB]
92#include "rlvhandler.h"
93// [/RLVa:KB]
91 94
92class LLChatBarGestureObserver : public LLGestureManagerObserver 95class LLChatBarGestureObserver : public LLGestureManagerObserver
93{ 96{
@@ -788,7 +791,7 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL
788 utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1); 791 utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1);
789 } 792 }
790 793
791// [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) | Modified: RLVa-0.2.0b 794// [RLVa:KB] - Checked: 2010-03-27 (RLVa-1.1.1a) | Modified: RLVa-1.2.0b
792 if ( (0 == channel) && (rlv_handler_t::isEnabled()) ) 795 if ( (0 == channel) && (rlv_handler_t::isEnabled()) )
793 { 796 {
794 // Adjust the (public) chat "volume" on chat and gestures (also takes care of playing the proper animation) 797 // Adjust the (public) chat "volume" on chat and gestures (also takes care of playing the proper animation)
@@ -799,7 +802,7 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL
799 else if ( (CHAT_TYPE_WHISPER == type) && (gRlvHandler.hasBehaviour(RLV_BHVR_CHATWHISPER)) ) 802 else if ( (CHAT_TYPE_WHISPER == type) && (gRlvHandler.hasBehaviour(RLV_BHVR_CHATWHISPER)) )
800 type = CHAT_TYPE_NORMAL; 803 type = CHAT_TYPE_NORMAL;
801 804
802 animate &= !gRlvHandler.hasBehaviour(RLV_BHVR_REDIRCHAT); 805 animate &= !gRlvHandler.hasBehaviour( (!rlvIsEmote(utf8_text)) ? RLV_BHVR_REDIRCHAT : RLV_BHVR_REDIREMOTE );
803 } 806 }
804// [/RLVa:KB] 807// [/RLVa:KB]
805 808
@@ -843,7 +846,7 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL
843void send_chat_from_viewer(std::string utf8_out_text, EChatType type, S32 channel) 846void send_chat_from_viewer(std::string utf8_out_text, EChatType type, S32 channel)
844// [/RLVa:KB] 847// [/RLVa:KB]
845{ 848{
846// [RLVa:KB] - Checked: 2009-08-05 (RLVa-1.0.1e) | Modified: RLVa-1.0.1e 849// [RLVa:KB] - Checked: 2010-02-27 (RLVa-1.1.1a) | Modified: RLVa-1.2.0a
847 // Only process chat messages (ie not CHAT_TYPE_START, CHAT_TYPE_STOP, etc) 850 // Only process chat messages (ie not CHAT_TYPE_START, CHAT_TYPE_STOP, etc)
848 if ( (rlv_handler_t::isEnabled()) && ( (CHAT_TYPE_WHISPER == type) || (CHAT_TYPE_NORMAL == type) || (CHAT_TYPE_SHOUT == type) ) ) 851 if ( (rlv_handler_t::isEnabled()) && ( (CHAT_TYPE_WHISPER == type) || (CHAT_TYPE_NORMAL == type) || (CHAT_TYPE_SHOUT == type) ) )
849 { 852 {
@@ -864,8 +867,8 @@ void send_chat_from_viewer(std::string utf8_out_text, EChatType type, S32 channe
864 return; 867 return;
865 } 868 }
866 869
867 // Filter public chat if sendchat restricted (and filter anything that redirchat didn't redirect) 870 // Filter public chat if sendchat restricted
868 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SENDCHAT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_REDIRCHAT)) ) 871 if (gRlvHandler.hasBehaviour(RLV_BHVR_SENDCHAT))
869 gRlvHandler.filterChat(utf8_out_text, true); 872 gRlvHandler.filterChat(utf8_out_text, true);
870 } 873 }
871 else 874 else
@@ -875,7 +878,7 @@ void send_chat_from_viewer(std::string utf8_out_text, EChatType type, S32 channe
875 return; 878 return;
876 879
877 // Don't allow chat on debug channel if @sendchat, @redirchat or @rediremote restricted (shows as public chat on viewers) 880 // Don't allow chat on debug channel if @sendchat, @redirchat or @rediremote restricted (shows as public chat on viewers)
878 if (channel >= CHAT_CHANNEL_DEBUG) 881 if (CHAT_CHANNEL_DEBUG == channel)
879 { 882 {
880 bool fIsEmote = rlvIsEmote(utf8_out_text); 883 bool fIsEmote = rlvIsEmote(utf8_out_text);
881 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SENDCHAT)) || 884 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SENDCHAT)) ||
diff --git a/linden/indra/newview/llfirstuse.cpp b/linden/indra/newview/llfirstuse.cpp
index e82aa96..0b777ea 100644
--- a/linden/indra/newview/llfirstuse.cpp
+++ b/linden/indra/newview/llfirstuse.cpp
@@ -328,21 +328,6 @@ void LLFirstUse::showRlvFirstUseNotification(const std::string& strName)
328 } 328 }
329} 329}
330 330
331void LLFirstUse::warnRlvGiveToRLV()
332{
333 if ( (gSavedSettings.getWarning(RLV_SETTING_FIRSTUSE_GIVETORLV)) && (RlvSettings::getForbidGiveToRLV()) )
334 LLNotifications::instance().add(RLV_SETTING_FIRSTUSE_GIVETORLV, LLSD(), LLSD(), &LLFirstUse::onRlvGiveToRLVConfirmation);
335}
336
337void LLFirstUse::onRlvGiveToRLVConfirmation(const LLSD& notification, const LLSD& response)
338{
339 gSavedSettings.setWarning(RLV_SETTING_FIRSTUSE_GIVETORLV, FALSE);
340
341 S32 idxOption = LLNotification::getSelectedOption(notification, response);
342 if ( (0 == idxOption) || (1 == idxOption) )
343 gSavedSettings.setBOOL(RLV_SETTING_FORBIDGIVETORLV, (idxOption == 1));
344}
345
346// [/RLVa:KB] 331// [/RLVa:KB]
347 332
348void LLFirstUse::callbackClientTags(const LLSD& notification, const LLSD& response) 333void LLFirstUse::callbackClientTags(const LLSD& notification, const LLSD& response)
diff --git a/linden/indra/newview/llfirstuse.h b/linden/indra/newview/llfirstuse.h
index b0bf05f..42443ff 100644
--- a/linden/indra/newview/llfirstuse.h
+++ b/linden/indra/newview/llfirstuse.h
@@ -127,10 +127,6 @@ public:
127 static void useRlvDetach() { showRlvFirstUseNotification(RLV_SETTING_FIRSTUSE_DETACH); } 127 static void useRlvDetach() { showRlvFirstUseNotification(RLV_SETTING_FIRSTUSE_DETACH); }
128 static void useRlvEnableWear() { showRlvFirstUseNotification(RLV_SETTING_FIRSTUSE_ENABLEWEAR); } 128 static void useRlvEnableWear() { showRlvFirstUseNotification(RLV_SETTING_FIRSTUSE_ENABLEWEAR); }
129 static void useRlvFartouch() { showRlvFirstUseNotification(RLV_SETTING_FIRSTUSE_FARTOUCH); } 129 static void useRlvFartouch() { showRlvFirstUseNotification(RLV_SETTING_FIRSTUSE_FARTOUCH); }
130
131 static void warnRlvGiveToRLV();
132protected:
133 static void onRlvGiveToRLVConfirmation(const LLSD& notification, const LLSD& response);
134// [/RLVa:KB] 130// [/RLVa:KB]
135}; 131};
136 132
diff --git a/linden/indra/newview/llfloaterabout.cpp b/linden/indra/newview/llfloaterabout.cpp
index 900f6e7..9870cf0 100644
--- a/linden/indra/newview/llfloaterabout.cpp
+++ b/linden/indra/newview/llfloaterabout.cpp
@@ -61,6 +61,10 @@
61#include "llwindow.h" 61#include "llwindow.h"
62#include "viewerversion.h" 62#include "viewerversion.h"
63 63
64// [RLVa:KB]
65#include "rlvhandler.h"
66// [/RLVa:KB]
67
64#if LL_WINDOWS 68#if LL_WINDOWS
65#include "lldxhardware.h" 69#include "lldxhardware.h"
66#endif 70#endif
@@ -142,7 +146,7 @@ LLFloaterAbout::LLFloaterAbout()
142// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-04 (RLVa-1.0.0a) 146// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-04 (RLVa-1.0.0a)
143 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) 147 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))
144 { 148 {
145 support.append(rlv_handler_t::cstrHidden); 149 support.append(RlvStrings::getString(RLV_STRING_HIDDEN));
146 support.append("\n\n"); 150 support.append("\n\n");
147 } 151 }
148 else if (region) 152 else if (region)
diff --git a/linden/indra/newview/llfloateractivespeakers.cpp b/linden/indra/newview/llfloateractivespeakers.cpp
index 51e7b89..59de717 100644
--- a/linden/indra/newview/llfloateractivespeakers.cpp
+++ b/linden/indra/newview/llfloateractivespeakers.cpp
@@ -51,6 +51,10 @@
51#include "llworld.h" 51#include "llworld.h"
52#include "llappviewer.h" 52#include "llappviewer.h"
53 53
54// [RLVa:KB]
55#include "rlvhandler.h"
56// [/RLVa:KB]
57
54const F32 SPEAKER_TIMEOUT = 10.f; // seconds of not being on voice channel before removed from list of active speakers 58const F32 SPEAKER_TIMEOUT = 10.f; // seconds of not being on voice channel before removed from list of active speakers
55const F32 RESORT_TIMEOUT = 5.f; // seconds of mouse inactivity before it's ok to sort regardless of mouse-in-view. 59const F32 RESORT_TIMEOUT = 5.f; // seconds of mouse inactivity before it's ok to sort regardless of mouse-in-view.
56const LLColor4 INACTIVE_COLOR(0.3f, 0.3f, 0.3f, 0.5f); 60const LLColor4 INACTIVE_COLOR(0.3f, 0.3f, 0.3f, 0.5f);
@@ -103,7 +107,7 @@ void LLSpeaker::onAvatarNameLookup(const LLUUID& id, const std::string& first, c
103// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-1.0.0g 107// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-1.0.0g
104 // TODO-RLVa: this seems to get called per frame which is very likely an LL bug that will eventuall get fixed 108 // TODO-RLVa: this seems to get called per frame which is very likely an LL bug that will eventuall get fixed
105 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) 109 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
106 speaker_ptr->mDisplayName = gRlvHandler.getAnonym(speaker_ptr->mDisplayName); 110 speaker_ptr->mDisplayName = RlvStrings::getAnonym(speaker_ptr->mDisplayName);
107// [/RLVa:KB] 111// [/RLVa:KB]
108 } 112 }
109} 113}
diff --git a/linden/indra/newview/llfloateranimpreview.cpp b/linden/indra/newview/llfloateranimpreview.cpp
index da1d5fc..09d3b2c 100644
--- a/linden/indra/newview/llfloateranimpreview.cpp
+++ b/linden/indra/newview/llfloateranimpreview.cpp
@@ -60,6 +60,7 @@
60#include "lltoolmgr.h" 60#include "lltoolmgr.h"
61#include "llui.h" 61#include "llui.h"
62#include "llviewercamera.h" 62#include "llviewercamera.h"
63#include "llviewercontrol.h"
63#include "llviewerobjectlist.h" 64#include "llviewerobjectlist.h"
64#include "llviewerwindow.h" 65#include "llviewerwindow.h"
65#include "llviewermenufile.h" // upload_new_resource() 66#include "llviewermenufile.h" // upload_new_resource()
diff --git a/linden/indra/newview/llfloateravatarpicker.cpp b/linden/indra/newview/llfloateravatarpicker.cpp
index 4eca8af..1788481 100644
--- a/linden/indra/newview/llfloateravatarpicker.cpp
+++ b/linden/indra/newview/llfloateravatarpicker.cpp
@@ -48,6 +48,10 @@
48#include "llviewercontrol.h" 48#include "llviewercontrol.h"
49#include "llworld.h" 49#include "llworld.h"
50 50
51// [RLVa:KB]
52#include "rlvhandler.h"
53// [/RLVa:KB]
54
51const S32 MIN_WIDTH = 200; 55const S32 MIN_WIDTH = 200;
52const S32 MIN_HEIGHT = 340; 56const S32 MIN_HEIGHT = 340;
53const LLRect FLOATER_RECT(0, 380, 240, 0); 57const LLRect FLOATER_RECT(0, 380, 240, 0);
diff --git a/linden/indra/newview/llfloaterbeacons.cpp b/linden/indra/newview/llfloaterbeacons.cpp
index 5a5de77..aa89780 100644
--- a/linden/indra/newview/llfloaterbeacons.cpp
+++ b/linden/indra/newview/llfloaterbeacons.cpp
@@ -38,8 +38,8 @@
38#include "llcheckboxctrl.h" 38#include "llcheckboxctrl.h"
39#include "pipeline.h" 39#include "pipeline.h"
40 40
41// [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) 41// [RLVa:KB]
42#include "llagent.h" 42#include "rlvhandler.h"
43// [/RLVa:KB] 43// [/RLVa:KB]
44 44
45LLFloaterBeacons::LLFloaterBeacons(const LLSD& seed) 45LLFloaterBeacons::LLFloaterBeacons(const LLSD& seed)
diff --git a/linden/indra/newview/llfloaterchat.cpp b/linden/indra/newview/llfloaterchat.cpp
index 59f4d70..3f0b184 100644
--- a/linden/indra/newview/llfloaterchat.cpp
+++ b/linden/indra/newview/llfloaterchat.cpp
@@ -91,6 +91,10 @@ const F32 CHAT_MSG_SIZE = 8.0f;
91const LLColor4 MUTED_MSG_COLOR(0.5f, 0.5f, 0.5f, 1.f); 91const LLColor4 MUTED_MSG_COLOR(0.5f, 0.5f, 0.5f, 1.f);
92const S32 MAX_CHATTER_COUNT = 16; 92const S32 MAX_CHATTER_COUNT = 16;
93 93
94// [RLVa:KB]
95#include "rlvhandler.h"
96// [/RLVa:KB]
97
94// 98//
95// Global statics 99// Global statics
96// 100//
diff --git a/linden/indra/newview/llfloaterinspect.cpp b/linden/indra/newview/llfloaterinspect.cpp
index 4822bb0..51c7835 100644
--- a/linden/indra/newview/llfloaterinspect.cpp
+++ b/linden/indra/newview/llfloaterinspect.cpp
@@ -43,7 +43,7 @@
43#include "llviewerobject.h" 43#include "llviewerobject.h"
44#include "lluictrlfactory.h" 44#include "lluictrlfactory.h"
45 45
46// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) 46// [RLVa:KB]
47#include "rlvhandler.h" 47#include "rlvhandler.h"
48// [/RLVa:KB] 48// [/RLVa:KB]
49 49
@@ -241,7 +241,7 @@ void LLFloaterInspect::refresh()
241 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) 241 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
242 { 242 {
243 // TODO-RLVa: shouldn't filter if this is a group-owned prim (will show "(nobody)") 243 // TODO-RLVa: shouldn't filter if this is a group-owned prim (will show "(nobody)")
244 owner_name = gRlvHandler.getAnonym(owner_name); 244 owner_name = RlvStrings::getAnonym(owner_name);
245 } 245 }
246// [/RLVa:KB] 246// [/RLVa:KB]
247 gCacheName->getFullName(obj->mPermissions->getCreator(), creator_name); 247 gCacheName->getFullName(obj->mPermissions->getCreator(), creator_name);
diff --git a/linden/indra/newview/llfloaterland.cpp b/linden/indra/newview/llfloaterland.cpp
index 066b739..7dd4f8d 100644
--- a/linden/indra/newview/llfloaterland.cpp
+++ b/linden/indra/newview/llfloaterland.cpp
@@ -78,6 +78,10 @@
78 78
79#include "hippoGridManager.h" 79#include "hippoGridManager.h"
80 80
81// [RLVa:KB]
82#include "rlvhandler.h"
83// [/RLVa:KB]
84
81static std::string OWNER_ONLINE = "0"; 85static std::string OWNER_ONLINE = "0";
82static std::string OWNER_OFFLINE = "1"; 86static std::string OWNER_OFFLINE = "1";
83static std::string OWNER_GROUP = "2"; 87static std::string OWNER_GROUP = "2";
diff --git a/linden/indra/newview/llfloatermap.cpp b/linden/indra/newview/llfloatermap.cpp
index b56fb5f..c15678d 100644
--- a/linden/indra/newview/llfloatermap.cpp
+++ b/linden/indra/newview/llfloatermap.cpp
@@ -46,6 +46,10 @@
46#include "panelradar.h" 46#include "panelradar.h"
47 47
48 48
49// [RLVa:KB]
50#include "rlvhandler.h"
51// [/RLVa:KB]
52
49LLFloaterMap::LLFloaterMap(const LLSD& key) 53LLFloaterMap::LLFloaterMap(const LLSD& key)
50 : 54 :
51 LLFloater(std::string("minimap")), 55 LLFloater(std::string("minimap")),
diff --git a/linden/indra/newview/llfloaterobjectiminfo.cpp b/linden/indra/newview/llfloaterobjectiminfo.cpp
index fa7964c..06e6213 100644
--- a/linden/indra/newview/llfloaterobjectiminfo.cpp
+++ b/linden/indra/newview/llfloaterobjectiminfo.cpp
@@ -47,7 +47,7 @@
47#include "llurldispatcher.h" 47#include "llurldispatcher.h"
48#include "llviewercontrol.h" 48#include "llviewercontrol.h"
49 49
50// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-04 (RLVa-1.0.0a) | Added: RLVa-0.2.0g 50// [RLVa:KB] - Version: 1.23.4
51#include "rlvhandler.h" 51#include "rlvhandler.h"
52// [/RLVa:KB] 52// [/RLVa:KB]
53 53
@@ -190,7 +190,7 @@ void LLFloaterObjectIMInfo::nameCallback(const LLUUID& id, const std::string& fi
190// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.0g 190// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.0g
191 if ( (!is_group) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (gRlvHandler.isAgentNearby(id)) ) 191 if ( (!is_group) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (gRlvHandler.isAgentNearby(id)) )
192 { 192 {
193 self->mOwnerName = gRlvHandler.getAnonym(self->mOwnerName); 193 self->mOwnerName = RlvStrings::getAnonym(self->mOwnerName);
194 } 194 }
195// [/RLVa:KB] 195// [/RLVa:KB]
196 196
diff --git a/linden/indra/newview/llfloaterproperties.cpp b/linden/indra/newview/llfloaterproperties.cpp
index 7dc6e42..40b293a 100644
--- a/linden/indra/newview/llfloaterproperties.cpp
+++ b/linden/indra/newview/llfloaterproperties.cpp
@@ -61,6 +61,9 @@
61 61
62#include "hippoGridManager.h" 62#include "hippoGridManager.h"
63 63
64// [RLVa:KB]
65#include "rlvhandler.h"
66// [/RLVa:KB]
64 67
65//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 68//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
66// Class LLPropertiesObserver 69// Class LLPropertiesObserver
@@ -362,7 +365,7 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
362// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) 365// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e)
363 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) 366 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
364 { 367 {
365 name = gRlvHandler.getAnonym(name); 368 name = RlvStrings::getAnonym(name);
366 } 369 }
367// [/RLVa:KB] 370// [/RLVa:KB]
368 } 371 }
diff --git a/linden/indra/newview/llfloaterregioninfo.cpp b/linden/indra/newview/llfloaterregioninfo.cpp
index 08d845b..deee0f6 100644
--- a/linden/indra/newview/llfloaterregioninfo.cpp
+++ b/linden/indra/newview/llfloaterregioninfo.cpp
@@ -81,6 +81,10 @@
81#include "llviewerwindow.h" 81#include "llviewerwindow.h"
82#include "llvlcomposition.h" 82#include "llvlcomposition.h"
83 83
84// [RLVa:KB]
85#include "rlvhandler.h"
86// [/RLVa:KB]
87
84#define ELAR_ENABLED 0 // Enable when server support is implemented 88#define ELAR_ENABLED 0 // Enable when server support is implemented
85 89
86const S32 TERRAIN_TEXTURE_COUNT = 4; 90const S32 TERRAIN_TEXTURE_COUNT = 4;
diff --git a/linden/indra/newview/llfloaterreporter.cpp b/linden/indra/newview/llfloaterreporter.cpp
index a7f41ea..50e2480 100644
--- a/linden/indra/newview/llfloaterreporter.cpp
+++ b/linden/indra/newview/llfloaterreporter.cpp
@@ -84,6 +84,10 @@
84 84
85#include "llassetuploadresponders.h" 85#include "llassetuploadresponders.h"
86 86
87// [RLVa:KB]
88#include "rlvhandler.h"
89// [/RLVa:KB]
90
87const U32 INCLUDE_SCREENSHOT = 0x01 << 0; 91const U32 INCLUDE_SCREENSHOT = 0x01 << 0;
88 92
89//----------------------------------------------------------------------------- 93//-----------------------------------------------------------------------------
@@ -319,7 +323,7 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id)
319// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) 323// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a)
320 if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) 324 if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) )
321 { 325 {
322 childSetText("sim_field", rlv_handler_t::cstrHiddenRegion); 326 childSetText("sim_field", RlvStrings::getString(RLV_STRING_HIDDEN_REGION));
323 } 327 }
324// [/RLVa:KB] 328// [/RLVa:KB]
325 LLVector3d global_pos; 329 LLVector3d global_pos;
diff --git a/linden/indra/newview/llfloatersettingsdebug.cpp b/linden/indra/newview/llfloatersettingsdebug.cpp
index fd6c47b..0aa0607 100644
--- a/linden/indra/newview/llfloatersettingsdebug.cpp
+++ b/linden/indra/newview/llfloatersettingsdebug.cpp
@@ -40,7 +40,7 @@
40#include "llcolorswatch.h" 40#include "llcolorswatch.h"
41#include "llviewercontrol.h" 41#include "llviewercontrol.h"
42 42
43// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0g) 43// [RLVa:KB]
44#include "rlvhandler.h" 44#include "rlvhandler.h"
45#include "rlvextensions.h" 45#include "rlvextensions.h"
46// [/RLVa:KB] 46// [/RLVa:KB]
@@ -258,7 +258,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp)
258 fEnable &= !((gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)) && 258 fEnable &= !((gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)) &&
259 (("VertexShaderEnable" == controlp->getName()) || ("WindLightUseAtmosShaders" == controlp->getName()))); 259 (("VertexShaderEnable" == controlp->getName()) || ("WindLightUseAtmosShaders" == controlp->getName())));
260 #ifdef RLV_EXTENSION_STARTLOCATION 260 #ifdef RLV_EXTENSION_STARTLOCATION
261 // Don't allow toggling RestrainedLifeLoginLastLocation 261 // Don't allow toggling RLVaLoginLastLocation
262 fEnable &= !(RLV_SETTING_LOGINLASTLOCATION == controlp->getName()); 262 fEnable &= !(RLV_SETTING_LOGINLASTLOCATION == controlp->getName());
263 #endif // RLV_EXTENSION_STARTLOCATION 263 #endif // RLV_EXTENSION_STARTLOCATION
264 264
diff --git a/linden/indra/newview/llfloaterteleporthistory.cpp b/linden/indra/newview/llfloaterteleporthistory.cpp
index 70a2d71..65675fa 100644
--- a/linden/indra/newview/llfloaterteleporthistory.cpp
+++ b/linden/indra/newview/llfloaterteleporthistory.cpp
@@ -204,23 +204,13 @@ void LLFloaterTeleportHistory::addEntry(std::string regionName, S16 x, S16 y, S1
204 value["columns"][4]["value"] = simString; 204 value["columns"][4]["value"] = simString;
205 value["out"]=outList; 205 value["out"]=outList;
206 206
207// [RLVa:KB] - Alternate: Emerald-370 207// [RLVa:KB] - Alternate: Imprudence-1.4
208 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) 208 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))
209 { 209 {
210 // TODO: This is the original code from Emerald. It 210 value["columns"][0]["value"] = RlvStrings::getString(RLV_STRING_HIDDEN_REGION);
211 // uses the class RlvStrings, defined in rlvcommon.cpp 211 value["columns"][1]["value"] = RlvStrings::getString(RLV_STRING_HIDDEN);
212 // to load localized strings. For Imprudence we use the 212 value["columns"][3]["value"] = RlvStrings::getString(RLV_STRING_HIDDEN);
213 // old fashioned way via RlvHandler with English 213 value["columns"][4]["value"] = RlvStrings::getString(RLV_STRING_HIDDEN);
214 // strings only!
215 // value["columns"][0]["value"] = RlvStrings::getString(RLV_STRING_HIDDEN_REGION);
216 // value["columns"][1]["value"] = RlvStrings::getString(RLV_STRING_HIDDEN);
217 // value["columns"][3]["value"] = RlvStrings::getString(RLV_STRING_HIDDEN);
218 // value["columns"][4]["value"] = RlvStrings::getString(RLV_STRING_HIDDEN);
219
220 value["columns"][0]["value"] = RlvHandler::cstrHiddenRegion;
221 value["columns"][1]["value"] = RlvHandler::cstrHidden;
222 value["columns"][3]["value"] = RlvHandler::cstrHidden;
223 value["columns"][4]["value"] = RlvHandler::cstrHidden;
224 } 214 }
225// [/RLVa:KB] 215// [/RLVa:KB]
226 saveEntry(value); 216 saveEntry(value);
@@ -238,16 +228,10 @@ void LLFloaterTeleportHistory::addEntry(std::string regionName, S16 x, S16 y, S1
238 228
239void LLFloaterTeleportHistory::setButtonsEnabled(BOOL on) 229void LLFloaterTeleportHistory::setButtonsEnabled(BOOL on)
240{ 230{
241// [RLVa:KB] - Alternate: Emerald-370 231// [RLVa:KB] - Alternate: Imprudence-1.4
242 if (rlv_handler_t::isEnabled()) 232 if (rlv_handler_t::isEnabled())
243 { 233 {
244 // TODO: This is the original code from Emerald. It 234 if ( (pItem) && (pItem->getColumn(4)) && (RlvStrings::getString(RLV_STRING_HIDDEN) == pItem->getColumn(4)->getValue().asString()) )
245 // uses the class RlvStrings, defined in rlvcommon.cpp
246 // to load localized strings. For Imprudence we use the
247 // old fashioned way via RlvHandler with English
248 // strings only!
249 //if ( (pItem) && (pItem->getColumn(4)) && (RlvStrings::getString(RLV_STRING_HIDDEN) == pItem->getColumn(4)->getValue().asString()) )
250 if ( (pItem) && (pItem->getColumn(4)) && (RlvHandler::cstrHidden == pItem->getColumn(4)->getValue().asString()) )
251 { 235 {
252 on = FALSE; 236 on = FALSE;
253 } 237 }
diff --git a/linden/indra/newview/llfloaterworldmap.cpp b/linden/indra/newview/llfloaterworldmap.cpp
index 781cf4d..0a01ca7 100644
--- a/linden/indra/newview/llfloaterworldmap.cpp
+++ b/linden/indra/newview/llfloaterworldmap.cpp
@@ -72,6 +72,10 @@
72 72
73#include "hippoLimits.h" 73#include "hippoLimits.h"
74 74
75// [RLVa:KB]
76#include "rlvhandler.h"
77// [/RLVa:KB]
78
75//--------------------------------------------------------------------------- 79//---------------------------------------------------------------------------
76// Constants 80// Constants
77//--------------------------------------------------------------------------- 81//---------------------------------------------------------------------------
@@ -661,8 +665,8 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)
661 F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS ); 665 F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS );
662 std::string full_name = llformat("%s (%d, %d, %d)", 666 std::string full_name = llformat("%s (%d, %d, %d)",
663// sim_name.c_str(), 667// sim_name.c_str(),
664// [RLVa:KB] - Alternate: Snowglobe-1.0 | Checked: 2009-07-04 (RLVa-1.0.0a) 668// [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2009-07-04 (RLVa-1.0.0a)
665 (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? sim_name.c_str() : rlv_handler_t::cstrHiddenRegion.c_str(), 669 (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? sim_name.c_str() : RlvStrings::getString(RLV_STRING_HIDDEN_REGION).c_str(),
666// [/RLVa:KB] 670// [/RLVa:KB]
667 llround(region_x), 671 llround(region_x),
668 llround(region_y), 672 llround(region_y),
@@ -721,7 +725,7 @@ void LLFloaterWorldMap::updateLocation()
721// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) 725// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a)
722 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) 726 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))
723 { 727 {
724 childSetValue("location", rlv_handler_t::cstrHiddenRegion); 728 childSetValue("location", RlvStrings::getString(RLV_STRING_HIDDEN_REGION));
725 mSLURL.clear(); 729 mSLURL.clear();
726 } 730 }
727// [/RLVa:KB] 731// [/RLVa:KB]
@@ -771,7 +775,7 @@ void LLFloaterWorldMap::updateLocation()
771// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) 775// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a)
772 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) 776 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))
773 { 777 {
774 childSetValue("location", rlv_handler_t::cstrHiddenRegion); 778 childSetValue("location", RlvStrings::getString(RLV_STRING_HIDDEN_REGION));
775 mSLURL.clear(); 779 mSLURL.clear();
776 } 780 }
777// [/RLVa:KB] 781// [/RLVa:KB]
diff --git a/linden/indra/newview/llgesturemgr.cpp b/linden/indra/newview/llgesturemgr.cpp
index 2203452..c3f7b93 100644
--- a/linden/indra/newview/llgesturemgr.cpp
+++ b/linden/indra/newview/llgesturemgr.cpp
@@ -58,6 +58,7 @@
58#include "llpreviewtexture.h" 58#include "llpreviewtexture.h"
59#include "llviewermessage.h" 59#include "llviewermessage.h"
60#include "llvoavatar.h" 60#include "llvoavatar.h"
61#include "llviewercontrol.h"
61#include "llviewerimagelist.h" 62#include "llviewerimagelist.h"
62#include "llviewerstats.h" 63#include "llviewerstats.h"
63#include "llweb.h" 64#include "llweb.h"
diff --git a/linden/indra/newview/llglsandbox.cpp b/linden/indra/newview/llglsandbox.cpp
index 3acfbf3..a487150 100644
--- a/linden/indra/newview/llglsandbox.cpp
+++ b/linden/indra/newview/llglsandbox.cpp
@@ -69,6 +69,10 @@
69#include "pipeline.h" 69#include "pipeline.h"
70#include "llspatialpartition.h" 70#include "llspatialpartition.h"
71 71
72// [RLVa:KB]
73#include "rlvhandler.h"
74// [/RLVa:KB]
75
72BOOL LLAgent::setLookAt(ELookAtType target_type, LLViewerObject *object, LLVector3 position) 76BOOL LLAgent::setLookAt(ELookAtType target_type, LLViewerObject *object, LLVector3 position)
73{ 77{
74 if(object && object->isAttachment()) 78 if(object && object->isAttachment())
@@ -168,8 +172,8 @@ extern BOOL gDebugSelect;
168// Returns true if you got at least one object 172// Returns true if you got at least one object
169void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) 173void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
170{ 174{
171// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0b) 175// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l
172 if (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) 176 if ( (rlv_handler_t::isEnabled()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT))) )
173 { 177 {
174 return; 178 return;
175 } 179 }
diff --git a/linden/indra/newview/llhoverview.cpp b/linden/indra/newview/llhoverview.cpp
index 6367380..120bbaa 100644
--- a/linden/indra/newview/llhoverview.cpp
+++ b/linden/indra/newview/llhoverview.cpp
@@ -75,6 +75,10 @@
75 75
76#include "hippoGridManager.h" 76#include "hippoGridManager.h"
77 77
78// [RLVa:KB]
79#include "rlvhandler.h"
80// [/RLVa:KB]
81
78// 82//
79// Constants 83// Constants
80// 84//
@@ -251,7 +255,7 @@ void LLHoverView::updateText()
251// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) 255// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e)
252 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) 256 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
253 { 257 {
254 line = gRlvHandler.getAnonym(line.append(firstname->getString()).append(1, ' ').append(lastname->getString())); 258 line = RlvStrings::getAnonym(line.append(firstname->getString()).append(1, ' ').append(lastname->getString()));
255 } 259 }
256 else 260 else
257 { 261 {
@@ -350,7 +354,7 @@ void LLHoverView::updateText()
350// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) 354// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e)
351 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) 355 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
352 { 356 {
353 name = gRlvHandler.getAnonym(name); 357 name = RlvStrings::getAnonym(name);
354 } 358 }
355// [/RLVa:KB] 359// [/RLVa:KB]
356 360
@@ -538,7 +542,8 @@ void LLHoverView::updateText()
538 if (hover_parcel) 542 if (hover_parcel)
539 { 543 {
540// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | Added: RLVa-0.2.0b 544// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | Added: RLVa-0.2.0b
541 line.append( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? hover_parcel->getName() : rlv_handler_t::cstrHiddenParcel ); 545 line.append( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))
546 ? hover_parcel->getName() : RlvStrings::getString(RLV_STRING_HIDDEN_PARCEL) );
542// [/RLVa:KB] 547// [/RLVa:KB]
543 //line.append(hover_parcel->getName()); 548 //line.append(hover_parcel->getName());
544 } 549 }
@@ -570,7 +575,7 @@ void LLHoverView::updateText()
570 else if(gCacheName->getFullName(owner, name)) 575 else if(gCacheName->getFullName(owner, name))
571 { 576 {
572// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.0b 577// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.0b
573 line.append( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? name : gRlvHandler.getAnonym(name)); 578 line.append( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? name : RlvStrings::getAnonym(name));
574// [/RLVa:KB] 579// [/RLVa:KB]
575 //line.append(name); 580 //line.append(name);
576 } 581 }
@@ -683,7 +688,14 @@ void LLHoverView::draw()
683 // To toggle off hover tips, you have to just suppress the draw. 688 // To toggle off hover tips, you have to just suppress the draw.
684 // The picking is still needed to do cursor changes over physical 689 // The picking is still needed to do cursor changes over physical
685 // and scripted objects. JC 690 // and scripted objects. JC
691// if (!sShowHoverTips)
692// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l
693#ifdef RLV_EXTENSION_CMD_INTERACT
694 if ( (!sShowHoverTips) || (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT)) )
695#else
686 if (!sShowHoverTips) 696 if (!sShowHoverTips)
697#endif // RLV_EXTENSION_CMD_INTERACT
698// [/RLVa:KB]
687 { 699 {
688 return; 700 return;
689 } 701 }
diff --git a/linden/indra/newview/llhudeffectlookat.cpp b/linden/indra/newview/llhudeffectlookat.cpp
index 2c0431b..75e2f30 100644
--- a/linden/indra/newview/llhudeffectlookat.cpp
+++ b/linden/indra/newview/llhudeffectlookat.cpp
@@ -48,6 +48,9 @@
48#include "llselectmgr.h" 48#include "llselectmgr.h"
49#include "llglheaders.h" 49#include "llglheaders.h"
50#include "llresmgr.h" 50#include "llresmgr.h"
51// [RLVa:KB] - Imprudence-1.3.0
52#include "rlvhandler.h"
53// [/RLVa:KB]
51 54
52#include "llxmltree.h" 55#include "llxmltree.h"
53 56
@@ -599,7 +602,7 @@ void LLHUDEffectLookAt::render()
599 // Show anonyms in place of actual names when @shownames=n restricted 602 // Show anonyms in place of actual names when @shownames=n restricted
600 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) 603 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
601 { 604 {
602 text = gRlvHandler.getAnonym(text); 605 text = RlvStrings::getAnonym(text);
603 } 606 }
604// [/RLVa:KB] 607// [/RLVa:KB]
605 608
diff --git a/linden/indra/newview/llhudtext.cpp b/linden/indra/newview/llhudtext.cpp
index 7d9f7f9..7c0c469 100644
--- a/linden/indra/newview/llhudtext.cpp
+++ b/linden/indra/newview/llhudtext.cpp
@@ -57,6 +57,9 @@
57#include "pipeline.h" 57#include "pipeline.h"
58#include <boost/tokenizer.hpp> 58#include <boost/tokenizer.hpp>
59 59
60// [RLVa:KB]
61#include "rlvhandler.h"
62// [/RLVa:KB]
60 63
61const F32 SPRING_STRENGTH = 0.7f; 64const F32 SPRING_STRENGTH = 0.7f;
62const F32 RESTORATION_SPRING_TIME_CONSTANT = 0.1f; 65const F32 RESTORATION_SPRING_TIME_CONSTANT = 0.1f;
diff --git a/linden/indra/newview/llimpanel.cpp b/linden/indra/newview/llimpanel.cpp
index 808a2c9..d9e822f 100644
--- a/linden/indra/newview/llimpanel.cpp
+++ b/linden/indra/newview/llimpanel.cpp
@@ -79,6 +79,10 @@
79#include "llstylemap.h" 79#include "llstylemap.h"
80#include <sys/stat.h> 80#include <sys/stat.h>
81 81
82// [RLVa:KB]
83#include "rlvhandler.h"
84// [/RLVa:KB]
85
82// 86//
83// Constants 87// Constants
84// 88//
@@ -2115,18 +2119,18 @@ void LLFloaterIMPanel::sendMsg()
2115 // Truncate and convert to UTF8 for transport 2119 // Truncate and convert to UTF8 for transport
2116 utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1); 2120 utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1);
2117 2121
2118// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-1.0.0g 2122// [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-1.0.0g
2119 if (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM)) 2123 if (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM))
2120 { 2124 {
2121 if (IM_NOTHING_SPECIAL == mDialog) // One-on-one IM: allow if recipient is a sendim exception 2125 if (IM_NOTHING_SPECIAL == mDialog) // One-on-one IM: allow if recipient is a sendim exception
2122 { 2126 {
2123 if (!gRlvHandler.isException(RLV_BHVR_SENDIM, mOtherParticipantUUID)) 2127 if (!gRlvHandler.isException(RLV_BHVR_SENDIM, mOtherParticipantUUID))
2124 utf8_text = rlv_handler_t::cstrBlockedSendIM; 2128 utf8_text = RlvStrings::getString(RLV_STRING_BLOCKED_SENDIM);
2125 } 2129 }
2126 else if (gAgent.isInGroup(mSessionUUID)) // Group chat: allow if recipient is a sendim exception 2130 else if (gAgent.isInGroup(mSessionUUID)) // Group chat: allow if recipient is a sendim exception
2127 { 2131 {
2128 if (!gRlvHandler.isException(RLV_BHVR_SENDIM, mSessionUUID)) 2132 if (!gRlvHandler.isException(RLV_BHVR_SENDIM, mSessionUUID))
2129 utf8_text = rlv_handler_t::cstrBlockedSendIM; 2133 utf8_text = RlvStrings::getString(RLV_STRING_BLOCKED_SENDIM);
2130 } 2134 }
2131 else if (mSpeakers) // Conference chat: allow if all participants are sendim exceptions 2135 else if (mSpeakers) // Conference chat: allow if all participants are sendim exceptions
2132 { 2136 {
@@ -2139,14 +2143,14 @@ void LLFloaterIMPanel::sendMsg()
2139 LLSpeaker* pSpeaker = *itSpeaker; 2143 LLSpeaker* pSpeaker = *itSpeaker;
2140 if ( (gAgent.getID() != pSpeaker->mID) && (!gRlvHandler.isException(RLV_BHVR_SENDIM, pSpeaker->mID)) ) 2144 if ( (gAgent.getID() != pSpeaker->mID) && (!gRlvHandler.isException(RLV_BHVR_SENDIM, pSpeaker->mID)) )
2141 { 2145 {
2142 utf8_text = rlv_handler_t::cstrBlockedSendIM; 2146 utf8_text = RlvStrings::getString(RLV_STRING_BLOCKED_SENDIM);
2143 break; 2147 break;
2144 } 2148 }
2145 } 2149 }
2146 } 2150 }
2147 else // Catch all fall-through 2151 else // Catch all fall-through
2148 { 2152 {
2149 utf8_text = rlv_handler_t::cstrBlockedSendIM; 2153 utf8_text = RlvStrings::getString(RLV_STRING_BLOCKED_SENDIM);
2150 } 2154 }
2151 } 2155 }
2152// [/RLVa:KB] 2156// [/RLVa:KB]
diff --git a/linden/indra/newview/llimview.cpp b/linden/indra/newview/llimview.cpp
index a6eaeb3..5061197 100644
--- a/linden/indra/newview/llimview.cpp
+++ b/linden/indra/newview/llimview.cpp
@@ -71,6 +71,10 @@
71 71
72#include "llfirstuse.h" 72#include "llfirstuse.h"
73 73
74// [RLVa:KB]
75#include "rlvhandler.h"
76// [/RLVa:KB]
77
74// 78//
75// Globals 79// Globals
76// 80//
@@ -1682,7 +1686,7 @@ public:
1682 return; 1686 return;
1683 } 1687 }
1684 else if (!gRlvHandler.isException(RLV_BHVR_RECVIM, from_id)) 1688 else if (!gRlvHandler.isException(RLV_BHVR_RECVIM, from_id))
1685 message = message.substr(0, message_offset) + rlv_handler_t::cstrBlockedRecvIM; 1689 message = message.substr(0, message_offset) + RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM);
1686 } 1690 }
1687// [/RLVa:KB] 1691// [/RLVa:KB]
1688 1692
diff --git a/linden/indra/newview/llinventoryactions.cpp b/linden/indra/newview/llinventoryactions.cpp
index f3277ad..7ae96ad 100644
--- a/linden/indra/newview/llinventoryactions.cpp
+++ b/linden/indra/newview/llinventoryactions.cpp
@@ -89,6 +89,9 @@
89// Defined in llinventorybridge.cpp 89// Defined in llinventorybridge.cpp
90void wear_attachments_on_avatar(const std::set<LLUUID>& item_ids, BOOL remove); 90void wear_attachments_on_avatar(const std::set<LLUUID>& item_ids, BOOL remove);
91 91
92// Defined in llinventorybridge.cpp
93void wear_attachments_on_avatar(const std::set<LLUUID>& item_ids, BOOL remove);
94
92const std::string NEW_LSL_NAME = "New Script"; // *TODO:Translate? (probably not) 95const std::string NEW_LSL_NAME = "New Script"; // *TODO:Translate? (probably not)
93const std::string NEW_NOTECARD_NAME = "New Note"; // *TODO:Translate? (probably not) 96const std::string NEW_NOTECARD_NAME = "New Note"; // *TODO:Translate? (probably not)
94const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probably not) 97const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probably not)
@@ -125,6 +128,12 @@ bool doToSelected(LLFolderView* folder, std::string action)
125 return true; 128 return true;
126 } 129 }
127 130
131 if ( ("attach" == action) && (selected_items.size() > 1) )
132 {
133 wear_attachments_on_avatar(selected_items, FALSE);
134 return true;
135 }
136
128 LLMultiPreview* multi_previewp = NULL; 137 LLMultiPreview* multi_previewp = NULL;
129 LLMultiProperties* multi_propertiesp = NULL; 138 LLMultiProperties* multi_propertiesp = NULL;
130 139
diff --git a/linden/indra/newview/llinventorybridge.cpp b/linden/indra/newview/llinventorybridge.cpp
index 0f999fc..b1627b5 100644
--- a/linden/indra/newview/llinventorybridge.cpp
+++ b/linden/indra/newview/llinventorybridge.cpp
@@ -94,6 +94,10 @@
94#include "llfloateropenobject.h" 94#include "llfloateropenobject.h"
95#include "llwlparammanager.h" 95#include "llwlparammanager.h"
96 96
97// [RLVa:KB]
98#include "rlvhandler.h"
99// [/RLVa:KB]
100
97// Helpers 101// Helpers
98// bug in busy count inc/dec right now, logic is complex... do we really need it? 102// bug in busy count inc/dec right now, logic is complex... do we really need it?
99void inc_busy_count() 103void inc_busy_count()
@@ -164,7 +168,9 @@ struct LLWearInfo
164 BOOL mAppend; 168 BOOL mAppend;
165}; 169};
166 170
167BOOL gAddToOutfit = FALSE; 171// [RLVa:KB] - Made this part of LLWearableHoldingPattern
172//BOOL gAddToOutfit = FALSE;
173// [/RLVa:KB]
168 174
169// +=================================================+ 175// +=================================================+
170// | LLInvFVBridge | 176// | LLInvFVBridge |
@@ -498,14 +504,14 @@ void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
498 items.push_back(std::string("Open")); 504 items.push_back(std::string("Open"));
499 items.push_back(std::string("Properties")); 505 items.push_back(std::string("Properties"));
500 506
501// [RLVa:KB] - Checked: 2009-10-13 (RLVa-1.0.5c) | Modified: RLVa-1.0.5c 507// [RLVa:KB] - Checked: 2009-11-11 (RLVa-1.1.0a) | Modified: RLVa-1.1.0a
502 if (rlv_handler_t::isEnabled()) 508 if (rlv_handler_t::isEnabled())
503 { 509 {
504 LLInventoryObject* pItem = (mInventoryPanel->getModel()) ? mInventoryPanel->getModel()->getObject(mUUID) : NULL; 510 LLInventoryObject* pItem = (mInventoryPanel->getModel()) ? mInventoryPanel->getModel()->getObject(mUUID) : NULL;
505 if ( (pItem) && 511 if ( (pItem) &&
506 ( ((LLAssetType::AT_NOTECARD == pItem->getType()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE))) || 512 ( ((LLAssetType::AT_NOTECARD == pItem->getType()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE))) ||
507 ((LLAssetType::AT_LSL_TEXT == pItem->getType()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWSCRIPT))) || 513 ((LLAssetType::AT_LSL_TEXT == pItem->getType()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWSCRIPT))) ||
508 ((LLAssetType::AT_NOTECARD == pItem->getType()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWTEXTURE))) ) ) 514 ((LLAssetType::AT_TEXTURE == pItem->getType()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWTEXTURE))) ) )
509 { 515 {
510 disabled_items.push_back(std::string("Open")); 516 disabled_items.push_back(std::string("Open"));
511 } 517 }
@@ -2503,9 +2509,10 @@ void open_texture(const LLUUID& item_id,
2503 const LLUUID& source_id, 2509 const LLUUID& source_id,
2504 BOOL take_focus) 2510 BOOL take_focus)
2505{ 2511{
2506// [RLVa:KB] - Checked: 2009-10-13 (RLVa-1.0.5c) | Added: RLVa-1.0.5c 2512// [RLVa:KB] - Checked: 2009-11-11 (RLVa-1.1.0a) | Modified: RLVa-1.1.0a
2507 if (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWTEXTURE)) 2513 if (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWTEXTURE))
2508 { 2514 {
2515 RlvNotifications::notifyBlockedViewTexture();
2509 return; 2516 return;
2510 } 2517 }
2511// [/RLVa:KB] 2518// [/RLVa:KB]
@@ -3008,9 +3015,10 @@ void open_notecard(LLViewerInventoryItem* inv_item,
3008 const LLUUID& source_id, 3015 const LLUUID& source_id,
3009 BOOL take_focus) 3016 BOOL take_focus)
3010{ 3017{
3011// [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) 3018// [RLVa:KB] - Checked: 2009-11-11 (RLVa-1.1.0a) | Modified: RLVa-1.1.0a
3012 if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE)) ) 3019 if (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE))
3013 { 3020 {
3021 RlvNotifications::notifyBlockedViewNote();
3014 return; 3022 return;
3015 } 3023 }
3016// [/RLVa:KB] 3024// [/RLVa:KB]
@@ -3867,9 +3875,10 @@ LLUIImagePtr LLLSLTextBridge::getIcon() const
3867 3875
3868void LLLSLTextBridge::openItem() 3876void LLLSLTextBridge::openItem()
3869{ 3877{
3870// [RLVa:KB] - Checked: 2009-10-13 (RLVa-1.0.5c) | Modified: RLVa-1.0.5c 3878// [RLVa:KB] - Checked: 2009-11-11 (RLVa-1.1.0a) | Modified: RLVa-1.1.0a
3871 if (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWSCRIPT)) 3879 if (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWSCRIPT))
3872 { 3880 {
3881 RlvNotifications::notifyBlockedViewScript();
3873 return; 3882 return;
3874 } 3883 }
3875// [/RLVa:KB] 3884// [/RLVa:KB]
@@ -3917,6 +3926,9 @@ void wear_inventory_item_on_avatar( LLInventoryItem* item )
3917 } 3926 }
3918} 3927}
3919 3928
3929// [RLVa:KB] - Checked: 2009-12-18 (RLVa-1.1.0i) | Added: RLVa-1.1.0i
3930// Moved to llinventorybridge.h because we need it in RlvForceWear
3931/*
3920struct LLFoundData 3932struct LLFoundData
3921{ 3933{
3922 LLFoundData(const LLUUID& item_id, 3934 LLFoundData(const LLUUID& item_id,
@@ -3948,7 +3960,8 @@ struct LLWearableHoldingPattern
3948 found_list_t mFoundList; 3960 found_list_t mFoundList;
3949 S32 mResolved; 3961 S32 mResolved;
3950}; 3962};
3951 3963*/
3964// [/RLVa:KB]
3952 3965
3953class LLOutfitObserver : public LLInventoryFetchObserver 3966class LLOutfitObserver : public LLInventoryFetchObserver
3954{ 3967{
@@ -4376,7 +4389,10 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, void* userdata )
4376 // wearables can be resolved immediately, then the 4389 // wearables can be resolved immediately, then the
4377 // callback will be called (and this object deleted) 4390 // callback will be called (and this object deleted)
4378 // before the final getNextData(). 4391 // before the final getNextData().
4379 LLWearableHoldingPattern* holder = new LLWearableHoldingPattern; 4392// LLWearableHoldingPattern* holder = new LLWearableHoldingPattern;
4393// [RLVa:KB] - Checked: 2009-12-18 (RLVa-1.1.0i) | Added: RLVa-1.1.0i
4394 LLWearableHoldingPattern* holder = new LLWearableHoldingPattern(wear_info->mAppend);
4395// [/RLVa:KB]
4380 LLFoundData* found; 4396 LLFoundData* found;
4381 LLDynamicArray<LLFoundData*> found_container; 4397 LLDynamicArray<LLFoundData*> found_container;
4382 for(i = 0; i < wearable_count; ++i) 4398 for(i = 0; i < wearable_count; ++i)
@@ -4390,7 +4406,9 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, void* userdata )
4390 } 4406 }
4391 for(i = 0; i < wearable_count; ++i) 4407 for(i = 0; i < wearable_count; ++i)
4392 { 4408 {
4393 gAddToOutfit = wear_info->mAppend; 4409// [RLVa:KB] - Part of LLWearableHoldingPattern
4410// gAddToOutfit = wear_info->mAppend;
4411// [/RLVa:KB]
4394 4412
4395 found = found_container.get(i); 4413 found = found_container.get(i);
4396 gWearableList.getAsset(found->mAssetID, 4414 gWearableList.getAsset(found->mAssetID,
@@ -4422,7 +4440,9 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, void* userdata )
4422void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void* data) 4440void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void* data)
4423{ 4441{
4424 LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data; 4442 LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data;
4425 BOOL append= gAddToOutfit; 4443// [RLVa:KB] - Part of LLWearableHoldingPattern
4444// BOOL append= gAddToOutfit;
4445// [/RLVa:KB]
4426 4446
4427 if(wearable) 4447 if(wearable)
4428 { 4448 {
@@ -4440,7 +4460,10 @@ void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void* data)
4440 holder->mResolved += 1; 4460 holder->mResolved += 1;
4441 if(holder->mResolved >= (S32)holder->mFoundList.size()) 4461 if(holder->mResolved >= (S32)holder->mFoundList.size())
4442 { 4462 {
4443 wear_inventory_category_on_avatar_step3(holder, append); 4463// wear_inventory_category_on_avatar_step3(holder, append);
4464// [RLVa:KB] - Checked: 2009-12-18 (RLVa-1.1.0i) | Added: RLVa-1.1.0i
4465 wear_inventory_category_on_avatar_step3(holder, holder->mAddToOutfit);
4466// [/RLVa:KB]
4444 } 4467 }
4445} 4468}
4446 4469
@@ -4595,7 +4618,7 @@ void wear_attachments_on_avatar(const LLInventoryModel::item_array_t& items, BOO
4595 msg->nextBlockFast(_PREHASH_HeaderData); 4618 msg->nextBlockFast(_PREHASH_HeaderData);
4596 msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id ); 4619 msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id );
4597 msg->addU8Fast(_PREHASH_TotalObjects, count ); 4620 msg->addU8Fast(_PREHASH_TotalObjects, count );
4598// msg->addBOOLFast(_PREHASH_FirstDetachAll, remove ); 4621// msg->addBOOLFast(_PREHASH_FirstDetachAll, !wear_info->mAppend );
4599// [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a 4622// [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a
4600 // This really should just *always* be FALSE since TRUE can result in loss of the current asset state 4623 // This really should just *always* be FALSE since TRUE can result in loss of the current asset state
4601 msg->addBOOLFast(_PREHASH_FirstDetachAll, 4624 msg->addBOOLFast(_PREHASH_FirstDetachAll,
@@ -4608,11 +4631,22 @@ void wear_attachments_on_avatar(const LLInventoryModel::item_array_t& items, BOO
4608 msg->addUUIDFast(_PREHASH_ItemID, item->getUUID() ); 4631 msg->addUUIDFast(_PREHASH_ItemID, item->getUUID() );
4609 msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner()); 4632 msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner());
4610// msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point 4633// msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point
4611// [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a 4634// [RLVa:KB] - Checked: 2009-11-16 (RLVa-1.1.0c) | Modified: RLVa-1.1.0c
4635 // We'll attach to the default attachment point if:
4636 // - RLV isn't enabled (or nothing is currently locked on)
4637 // - "Enable Default Wear" is checked and the current attach isn't the direct result of an RLV command
4638 // - "Enable Shared Wear" is checked and the current attach is the direct result of an RLV command
4639 // RELEASE-RLVa: make sure the above assertions are still valid
4612 msg->addU8Fast(_PREHASH_AttachmentPt, 4640 msg->addU8Fast(_PREHASH_AttachmentPt,
4613 ( (!rlv_handler_t::isEnabled()) || (RlvSettings::getEnableWear()) || (!gRlvHandler.hasLockedAttachment(RLV_LOCK_ANY)) ) 4641 ( (!rlv_handler_t::isEnabled()) || (!gRlvHandler.hasLockedAttachment(RLV_LOCK_ANY)) ||
4642#ifndef RLV_WORKAROUND_REZMULTIPLEATTACH
4643 ( (!gRlvHandler.getCurrentCommand()) && (RlvSettings::getEnableWear()) ) ||
4644 ( (gRlvHandler.getCurrentCommand()) && (RlvSettings::getEnableSharedWear()) ) )
4645#else
4646 (RlvSettings::getEnableWear()) )
4647#endif // RLV_WORKAROUND_REZMULTIPLEATTACH
4614 ? 0 4648 ? 0
4615 : gRlvHandler.getAttachPointIndex(gRlvHandler.getAttachPoint(item, true))); 4649 : gRlvHandler.getAttachPointIndex(gRlvHandler.getAttachPoint(item, true)) );
4616// [/RLVa:KB] 4650// [/RLVa:KB]
4617 pack_permissions_slam(msg, item->getFlags(), item->getPermissions()); 4651 pack_permissions_slam(msg, item->getFlags(), item->getPermissions());
4618 msg->addStringFast(_PREHASH_Name, item->getName()); 4652 msg->addStringFast(_PREHASH_Name, item->getName());
diff --git a/linden/indra/newview/llinventorybridge.h b/linden/indra/newview/llinventorybridge.h
index d6001b7..45486ed 100644
--- a/linden/indra/newview/llinventorybridge.h
+++ b/linden/indra/newview/llinventorybridge.h
@@ -94,6 +94,41 @@ struct LLAttachmentRezAction
94 S32 mAttachPt; 94 S32 mAttachPt;
95}; 95};
96 96
97// [RLVa:KB] - Checked: 2009-12-18 (RLVa-1.1.0i) | Added: RLVa-1.1.0i
98// Moved from llinventorybridge.cpp because we need it in RlvForceWear
99struct LLFoundData
100{
101 LLFoundData(const LLUUID& item_id,
102 const LLUUID& asset_id,
103 const std::string& name,
104 LLAssetType::EType asset_type) :
105 mItemID(item_id),
106 mAssetID(asset_id),
107 mName(name),
108 mAssetType(asset_type),
109 mWearable( NULL ) {}
110
111 LLUUID mItemID;
112 LLUUID mAssetID;
113 std::string mName;
114 LLAssetType::EType mAssetType;
115 LLWearable* mWearable;
116};
117
118struct LLWearableHoldingPattern
119{
120 LLWearableHoldingPattern(BOOL fAddToOutfit) : mResolved(0), mAddToOutfit(fAddToOutfit) {}
121 ~LLWearableHoldingPattern()
122 {
123 for_each(mFoundList.begin(), mFoundList.end(), DeletePointer());
124 mFoundList.clear();
125 }
126 typedef std::list<LLFoundData*> found_list_t;
127 found_list_t mFoundList;
128 S32 mResolved;
129 BOOL mAddToOutfit;
130};
131// [/RLVa:KB]
97 132
98//helper functions 133//helper functions
99class LLShowProps 134class LLShowProps
diff --git a/linden/indra/newview/llinventorymodel.cpp b/linden/indra/newview/llinventorymodel.cpp
index c066a04..1c7a049 100644
--- a/linden/indra/newview/llinventorymodel.cpp
+++ b/linden/indra/newview/llinventorymodel.cpp
@@ -61,6 +61,10 @@
61#include "llsdutil.h" 61#include "llsdutil.h"
62#include <deque> 62#include <deque>
63 63
64// [RLVa:KB]
65#include "rlvhandler.h"
66// [/RLVa:KB]
67
64//#define DIFF_INVENTORY_FILES 68//#define DIFF_INVENTORY_FILES
65#ifdef DIFF_INVENTORY_FILES 69#ifdef DIFF_INVENTORY_FILES
66#include "process.h" 70#include "process.h"
diff --git a/linden/indra/newview/llinventoryview.cpp b/linden/indra/newview/llinventoryview.cpp
index 939d50b..f8fb439 100644
--- a/linden/indra/newview/llinventoryview.cpp
+++ b/linden/indra/newview/llinventoryview.cpp
@@ -86,6 +86,10 @@
86 86
87#include "llsdserialize.h" 87#include "llsdserialize.h"
88 88
89// [RLVa:KB]
90#include "rlvhandler.h"
91// [/RLVa:KB]
92
89static LLRegisterWidget<LLInventoryPanel> r("inventory_panel"); 93static LLRegisterWidget<LLInventoryPanel> r("inventory_panel");
90 94
91LLDynamicArray<LLInventoryView*> LLInventoryView::sActiveViews; 95LLDynamicArray<LLInventoryView*> LLInventoryView::sActiveViews;
diff --git a/linden/indra/newview/llmaniptranslate.cpp b/linden/indra/newview/llmaniptranslate.cpp
index 1362f0a..01fe6f8 100644
--- a/linden/indra/newview/llmaniptranslate.cpp
+++ b/linden/indra/newview/llmaniptranslate.cpp
@@ -68,6 +68,10 @@
68 68
69#include "hippoLimits.h" 69#include "hippoLimits.h"
70 70
71// [RLVa:KB]
72#include "rlvhandler.h"
73// [/RLVa:KB]
74
71const S32 NUM_AXES = 3; 75const S32 NUM_AXES = 3;
72const S32 MOUSE_DRAG_SLOP = 2; // pixels 76const S32 MOUSE_DRAG_SLOP = 2; // pixels
73const F32 HANDLE_HIDE_ANGLE = 0.15f; // radians 77const F32 HANDLE_HIDE_ANGLE = 0.15f; // radians
diff --git a/linden/indra/newview/llnetmap.cpp b/linden/indra/newview/llnetmap.cpp
index 8a12ff3..dc4456a 100644
--- a/linden/indra/newview/llnetmap.cpp
+++ b/linden/indra/newview/llnetmap.cpp
@@ -73,6 +73,10 @@
73 73
74#include "hippoLimits.h" 74#include "hippoLimits.h"
75 75
76// [RLVa:KB]
77#include "rlvhandler.h"
78// [/RLVa:KB]
79
76const F32 MAP_SCALE_MIN = 32; 80const F32 MAP_SCALE_MIN = 32;
77const F32 MAP_SCALE_MID = 1024; 81const F32 MAP_SCALE_MID = 1024;
78//const F32 MAP_SCALE_MAX = 4096; Now uses the max height value from hippo limits 82//const F32 MAP_SCALE_MAX = 4096; Now uses the max height value from hippo limits
@@ -640,14 +644,14 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rec
640 { 644 {
641// msg.append(fullname); 645// msg.append(fullname);
642// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.0b 646// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.0b
643 msg.append( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? fullname : gRlvHandler.getAnonym(fullname) ); 647 msg.append( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? fullname : RlvStrings::getAnonym(fullname) );
644// [/RLVa:KB] 648// [/RLVa:KB]
645 msg.append("\n"); 649 msg.append("\n");
646 } 650 }
647 651
648// msg.append( region->getName() ); 652// msg.append( region->getName() );
649// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-04 (RLVa-1.0.0a) | Modified: RLVa-0.2.0b 653// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-04 (RLVa-1.0.0a) | Modified: RLVa-0.2.0b
650 msg.append( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? region->getName() : rlv_handler_t::cstrHidden ); 654 msg.append( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? region->getName() : RlvStrings::getString(RLV_STRING_HIDDEN) );
651// [/RLVa:KB] 655// [/RLVa:KB]
652 msg.append("\n"); 656 msg.append("\n");
653 gSavedSettings.getBOOL( "MiniMapTeleport" ) ? 657 gSavedSettings.getBOOL( "MiniMapTeleport" ) ?
diff --git a/linden/indra/newview/llnotify.cpp b/linden/indra/newview/llnotify.cpp
index 1a7b247..b0f5f91 100644
--- a/linden/indra/newview/llnotify.cpp
+++ b/linden/indra/newview/llnotify.cpp
@@ -57,7 +57,7 @@
57 57
58#include "hippoGridManager.h" 58#include "hippoGridManager.h"
59 59
60// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-10 (RLVa-1.0.0e) | Added: RLVa-0.2.0b 60// [RLVa:KB] - Version: 1.23.4
61#include "rlvhandler.h" 61#include "rlvhandler.h"
62// [/RLVa:KB] 62// [/RLVa:KB]
63 63
diff --git a/linden/indra/newview/lloverlaybar.cpp b/linden/indra/newview/lloverlaybar.cpp
index 14ae3ff..5ca5905 100644
--- a/linden/indra/newview/lloverlaybar.cpp
+++ b/linden/indra/newview/lloverlaybar.cpp
@@ -67,6 +67,10 @@
67#include "llwindlightremotectrl.h" 67#include "llwindlightremotectrl.h"
68#include "llselectmgr.h" 68#include "llselectmgr.h"
69 69
70// [RLVa:KB]
71#include "rlvhandler.h"
72// [/RLVa:KB]
73
70// 74//
71// Globals 75// Globals
72// 76//
diff --git a/linden/indra/newview/llpanelavatar.cpp b/linden/indra/newview/llpanelavatar.cpp
index e88a16a..f4501be 100644
--- a/linden/indra/newview/llpanelavatar.cpp
+++ b/linden/indra/newview/llpanelavatar.cpp
@@ -81,6 +81,10 @@
81#include "roles_constants.h" 81#include "roles_constants.h"
82#include "lluictrlfactory.h" 82#include "lluictrlfactory.h"
83 83
84// [RLVa:KB]
85#include "rlvhandler.h"
86// [/RLVa:KB]
87
84// Statics 88// Statics
85std::list<LLPanelAvatar*> LLPanelAvatar::sAllPanels; 89std::list<LLPanelAvatar*> LLPanelAvatar::sAllPanels;
86BOOL LLPanelAvatar::sAllowFirstLife = FALSE; 90BOOL LLPanelAvatar::sAllowFirstLife = FALSE;
diff --git a/linden/indra/newview/llpanelclassified.cpp b/linden/indra/newview/llpanelclassified.cpp
index 36fc86d..2249479 100644
--- a/linden/indra/newview/llpanelclassified.cpp
+++ b/linden/indra/newview/llpanelclassified.cpp
@@ -72,6 +72,10 @@
72 72
73#include "hippoGridManager.h" 73#include "hippoGridManager.h"
74 74
75// [RLVa:KB]
76#include "rlvhandler.h"
77// [/RLVa:KB]
78
75const S32 MINIMUM_PRICE_FOR_LISTING = 50; // L$ 79const S32 MINIMUM_PRICE_FOR_LISTING = 50; // L$
76const S32 MATURE_UNDEFINED = -1; 80const S32 MATURE_UNDEFINED = -1;
77const S32 MATURE_CONTENT = 1; 81const S32 MATURE_CONTENT = 1;
diff --git a/linden/indra/newview/llpanelcontents.cpp b/linden/indra/newview/llpanelcontents.cpp
index e5c4f79..02befea 100644
--- a/linden/indra/newview/llpanelcontents.cpp
+++ b/linden/indra/newview/llpanelcontents.cpp
@@ -68,8 +68,8 @@
68#include "lltoolcomp.h" 68#include "lltoolcomp.h"
69#include "llpanelinventory.h" 69#include "llpanelinventory.h"
70 70
71// [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) 71// [RLVa:KB]
72#include "llvoavatar.h" 72#include "rlvhandler.h"
73// [/RLVa:KB] 73// [/RLVa:KB]
74 74
75// 75//
diff --git a/linden/indra/newview/llpaneldisplay.cpp b/linden/indra/newview/llpaneldisplay.cpp
index e17ba2b..15b4615 100644
--- a/linden/indra/newview/llpaneldisplay.cpp
+++ b/linden/indra/newview/llpaneldisplay.cpp
@@ -83,6 +83,10 @@
83// parent 83// parent
84#include "llfloaterpreference.h" 84#include "llfloaterpreference.h"
85 85
86// [RLVa:KB]
87#include "rlvhandler.h"
88// [/RLVa:KB]
89
86#include <boost/regex.hpp> 90#include <boost/regex.hpp>
87 91
88const F32 MAX_USER_FAR_CLIP = 512.f; 92const F32 MAX_USER_FAR_CLIP = 512.f;
diff --git a/linden/indra/newview/llpanelinventory.cpp b/linden/indra/newview/llpanelinventory.cpp
index 333b83f..41ba513 100644
--- a/linden/indra/newview/llpanelinventory.cpp
+++ b/linden/indra/newview/llpanelinventory.cpp
@@ -84,8 +84,8 @@
84 84
85#include "hippoGridManager.h" 85#include "hippoGridManager.h"
86 86
87// [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) 87// [RLVa:KB]
88#include "llvoavatar.h" 88#include "rlvhandler.h"
89// [/RLVa:KB] 89// [/RLVa:KB]
90 90
91///---------------------------------------------------------------------------- 91///----------------------------------------------------------------------------
@@ -750,13 +750,13 @@ void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
750 { 750 {
751 disabled_items.push_back(std::string("Task Open")); 751 disabled_items.push_back(std::string("Task Open"));
752 } 752 }
753// [RLVa:KB] - Checked: 2009-10-13 (RLVa-1.0.5c) | Modified: RLVa-1.0.5c 753// [RLVa:KB] - Checked: 2009-11-11 (RLVa-1.1.0a) | Modified: RLVa-1.1.0a
754 else if (rlv_handler_t::isEnabled()) 754 else if (rlv_handler_t::isEnabled())
755 { 755 {
756 bool fLocked = gRlvHandler.isLockedAttachment(gObjectList.findObject(mPanel->getTaskUUID()), RLV_LOCK_REMOVE); 756 bool fLocked = gRlvHandler.isLockedAttachment(gObjectList.findObject(mPanel->getTaskUUID()), RLV_LOCK_REMOVE);
757 if ( ((LLAssetType::AT_LSL_TEXT == item->getType()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_VIEWSCRIPT)) || (fLocked))) || 757 if ( ((LLAssetType::AT_LSL_TEXT == item->getType()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_VIEWSCRIPT)) || (fLocked))) ||
758 ((LLAssetType::AT_NOTECARD == item->getType()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE)) || (fLocked))) || 758 ((LLAssetType::AT_NOTECARD == item->getType()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE)) || (fLocked))) ||
759 ((LLAssetType::AT_NOTECARD == item->getType()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWTEXTURE))) ) 759 ((LLAssetType::AT_TEXTURE == item->getType()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWTEXTURE))) )
760 { 760 {
761 disabled_items.push_back(std::string("Task Open")); 761 disabled_items.push_back(std::string("Task Open"));
762 } 762 }
@@ -986,9 +986,10 @@ LLUIImagePtr LLTaskTextureBridge::getIcon() const
986 986
987void LLTaskTextureBridge::openItem() 987void LLTaskTextureBridge::openItem()
988{ 988{
989// [RLVa:KB] - Checked: 2009-10-13 (RLVa-1.0.5c) | Added: RLVa-1.0.5c 989// [RLVa:KB] - Checked: 2009-11-11 (RLVa-1.1.0a) | Modified: RLVa-1.1.0a
990 if (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWTEXTURE)) 990 if (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWTEXTURE))
991 { 991 {
992 RlvNotifications::notifyBlockedViewTexture();
992 return; 993 return;
993 } 994 }
994// [/RLVa:KB] 995// [/RLVa:KB]
@@ -1274,11 +1275,12 @@ LLTaskLSLBridge::LLTaskLSLBridge(
1274 1275
1275void LLTaskLSLBridge::openItem() 1276void LLTaskLSLBridge::openItem()
1276{ 1277{
1277// [RLVa:KB] - Checked: 2009-10-13 (RLVa-1.0.5c) | Modified: RLVa-1.0.5c 1278// [RLVa:KB] - Checked: 2009-11-11 (RLVa-1.1.0a) | Modified: RLVa-1.1.0a
1278 LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); 1279 LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
1279 if ( (rlv_handler_t::isEnabled()) && 1280 if ( (rlv_handler_t::isEnabled()) &&
1280 ((gRlvHandler.hasBehaviour(RLV_BHVR_VIEWSCRIPT)) || (gRlvHandler.isLockedAttachment(object, RLV_LOCK_REMOVE))) ) 1281 ((gRlvHandler.hasBehaviour(RLV_BHVR_VIEWSCRIPT)) || (gRlvHandler.isLockedAttachment(object, RLV_LOCK_REMOVE))) )
1281 { 1282 {
1283 RlvNotifications::notifyBlockedViewScript();
1282 return; 1284 return;
1283 } 1285 }
1284// [/RLVa:KB] 1286// [/RLVa:KB]
@@ -1401,10 +1403,11 @@ void LLTaskNotecardBridge::openItem()
1401 { 1403 {
1402 return; 1404 return;
1403 } 1405 }
1404// [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a 1406// [RLVa:KB] - Checked: 2009-11-11 (RLVa-1.1.0a) | Modified: RLVa-1.1.0a
1405 if ( (rlv_handler_t::isEnabled()) && 1407 if ( (rlv_handler_t::isEnabled()) &&
1406 ( (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE)) || (gRlvHandler.isLockedAttachment(object, RLV_LOCK_REMOVE)) ) ) 1408 ( (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE)) || (gRlvHandler.isLockedAttachment(object, RLV_LOCK_REMOVE)) ) )
1407 { 1409 {
1410 RlvNotifications::notifyBlockedViewNote();
1408 return; 1411 return;
1409 } 1412 }
1410// [/RLVa:KB] 1413// [/RLVa:KB]
diff --git a/linden/indra/newview/llpanelland.cpp b/linden/indra/newview/llpanelland.cpp
index 7c9faaf..ea6a557 100644
--- a/linden/indra/newview/llpanelland.cpp
+++ b/linden/indra/newview/llpanelland.cpp
@@ -51,6 +51,10 @@
51 51
52#include "hippoGridManager.h" 52#include "hippoGridManager.h"
53 53
54// [RLVa:KB]
55#include "rlvhandler.h"
56// [/RLVa:KB]
57
54LLPanelLandSelectObserver* LLPanelLandInfo::sObserver = NULL; 58LLPanelLandSelectObserver* LLPanelLandInfo::sObserver = NULL;
55LLPanelLandInfo* LLPanelLandInfo::sInstance = NULL; 59LLPanelLandInfo* LLPanelLandInfo::sInstance = NULL;
56 60
diff --git a/linden/indra/newview/llpanellogin.cpp b/linden/indra/newview/llpanellogin.cpp
index 23b7785..69539c7 100644
--- a/linden/indra/newview/llpanellogin.cpp
+++ b/linden/indra/newview/llpanellogin.cpp
@@ -83,7 +83,7 @@
83 83
84#include "llglheaders.h" 84#include "llglheaders.h"
85 85
86// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) 86// [RLVa:KB]
87#include "rlvhandler.h" 87#include "rlvhandler.h"
88// [/RLVa:KB] 88// [/RLVa:KB]
89 89
@@ -737,7 +737,7 @@ void LLPanelLogin::refreshLocation( bool force_visible )
737 if ( ! force_visible ) 737 if ( ! force_visible )
738 show_start = gSavedSettings.getBOOL("ShowStartLocation"); 738 show_start = gSavedSettings.getBOOL("ShowStartLocation");
739 739
740// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) 740// [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2009-07-08 (RLVa-1.0.0e)
741 // TODO-RLVa: figure out some way to make this work with RLV_EXTENSION_STARTLOCATION 741 // TODO-RLVa: figure out some way to make this work with RLV_EXTENSION_STARTLOCATION
742 #ifndef RLV_EXTENSION_STARTLOCATION 742 #ifndef RLV_EXTENSION_STARTLOCATION
743 if (rlv_handler_t::isEnabled()) 743 if (rlv_handler_t::isEnabled())
diff --git a/linden/indra/newview/llpanelobject.cpp b/linden/indra/newview/llpanelobject.cpp
index 10cd0bd..706f98e 100644
--- a/linden/indra/newview/llpanelobject.cpp
+++ b/linden/indra/newview/llpanelobject.cpp
@@ -78,8 +78,8 @@
78 78
79#include "hippoLimits.h" 79#include "hippoLimits.h"
80 80
81// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) 81// [RLVa:KB]
82#include "llvoavatar.h" 82#include "rlvhandler.h"
83// [/RLVa:KB] 83// [/RLVa:KB]
84 84
85// 85//
diff --git a/linden/indra/newview/llpanelpermissions.cpp b/linden/indra/newview/llpanelpermissions.cpp
index fc05744..8492988 100644
--- a/linden/indra/newview/llpanelpermissions.cpp
+++ b/linden/indra/newview/llpanelpermissions.cpp
@@ -70,6 +70,10 @@
70 70
71#include "hippoGridManager.h" 71#include "hippoGridManager.h"
72 72
73// [RLVa:KB]
74#include "rlvhandler.h"
75// [/RLVa:KB]
76
73///---------------------------------------------------------------------------- 77///----------------------------------------------------------------------------
74/// Class llpanelpermissions 78/// Class llpanelpermissions
75///---------------------------------------------------------------------------- 79///----------------------------------------------------------------------------
@@ -349,7 +353,7 @@ void LLPanelPermissions::refresh()
349 // Only filter the owner name if: the selection is all owned by the same avie and not group owned 353 // Only filter the owner name if: the selection is all owned by the same avie and not group owned
350 if ( (owners_identical) && (!LLSelectMgr::getInstance()->selectIsGroupOwned()) ) 354 if ( (owners_identical) && (!LLSelectMgr::getInstance()->selectIsGroupOwned()) )
351 { 355 {
352 owner_name = gRlvHandler.getAnonym(owner_name); 356 owner_name = RlvStrings::getAnonym(owner_name);
353 fRlvEnableOwner = false; 357 fRlvEnableOwner = false;
354 } 358 }
355 } 359 }
diff --git a/linden/indra/newview/llpanelpick.cpp b/linden/indra/newview/llpanelpick.cpp
index 9c2638f..3417b17 100644
--- a/linden/indra/newview/llpanelpick.cpp
+++ b/linden/indra/newview/llpanelpick.cpp
@@ -59,6 +59,10 @@
59#include "llviewerregion.h" 59#include "llviewerregion.h"
60#include "llviewerwindow.h" 60#include "llviewerwindow.h"
61 61
62// [RLVa:KB]
63#include "rlvhandler.h"
64// [/RLVa:KB]
65
62//static 66//static
63std::list<LLPanelPick*> LLPanelPick::sAllPanels; 67std::list<LLPanelPick*> LLPanelPick::sAllPanels;
64 68
diff --git a/linden/indra/newview/llprefsim.cpp b/linden/indra/newview/llprefsim.cpp
index e7c39e2..2c8ef4d 100644
--- a/linden/indra/newview/llprefsim.cpp
+++ b/linden/indra/newview/llprefsim.cpp
@@ -50,6 +50,10 @@
50 50
51#include "hippoGridManager.h" 51#include "hippoGridManager.h"
52 52
53// [RLVa:KB]
54#include "rlvhandler.h"
55// [/RLVa:KB]
56
53class LLPrefsIMImpl : public LLPanel 57class LLPrefsIMImpl : public LLPanel
54{ 58{
55public: 59public:
diff --git a/linden/indra/newview/llpreviewscript.cpp b/linden/indra/newview/llpreviewscript.cpp
index bde7242..98a5d8f 100644
--- a/linden/indra/newview/llpreviewscript.cpp
+++ b/linden/indra/newview/llpreviewscript.cpp
@@ -89,6 +89,9 @@
89 89
90#include "llpanelinventory.h" 90#include "llpanelinventory.h"
91 91
92// [RLVa:KB]
93#include "rlvhandler.h"
94// [/RLVa:KB]
92 95
93const std::string HELLO_LSL = 96const std::string HELLO_LSL =
94 "default\n" 97 "default\n"
diff --git a/linden/indra/newview/llselectmgr.cpp b/linden/indra/newview/llselectmgr.cpp
index 1634950..f154de9 100644
--- a/linden/indra/newview/llselectmgr.cpp
+++ b/linden/indra/newview/llselectmgr.cpp
@@ -87,6 +87,10 @@
87 87
88#include "llglheaders.h" 88#include "llglheaders.h"
89 89
90// [RLVa:KB]
91#include "rlvhandler.h"
92// [/RLVa:KB]
93
90LLViewerObject* getSelectedParentObject(LLViewerObject *object) ; 94LLViewerObject* getSelectedParentObject(LLViewerObject *object) ;
91// 95//
92// Consts 96// Consts
@@ -3446,6 +3450,17 @@ void LLSelectMgr::deselectAllIfTooFar()
3446 return; 3450 return;
3447 } 3451 }
3448 3452
3453// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l
3454#ifdef RLV_EXTENSION_CMD_INTERACT
3455 // [Fall-back code] Don't allow an active selection (except for HUD attachments - see above) when @interact=n restricted
3456 if (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT))
3457 {
3458 deselectAll();
3459 return;
3460 }
3461#endif // RLV_EXTENSION_CMD_INTERACT
3462// [/RLVa:KB]
3463
3449 // HACK: Don't deselect when we're navigating to rate an object's 3464 // HACK: Don't deselect when we're navigating to rate an object's
3450 // owner or creator. JC 3465 // owner or creator. JC
3451 if (gPieObject->getVisible()) 3466 if (gPieObject->getVisible())
diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp
index b70253e..e997e5f 100644
--- a/linden/indra/newview/llstartup.cpp
+++ b/linden/indra/newview/llstartup.cpp
@@ -201,6 +201,10 @@
201#include "llmozlib.h" 201#include "llmozlib.h"
202#endif // LL_LIBXUL_ENABLED 202#endif // LL_LIBXUL_ENABLED
203 203
204// [RLVa:KB]
205#include "rlvhandler.h"
206// [/RLVa:KB]
207
204#if LL_WINDOWS 208#if LL_WINDOWS
205#include "llwindebug.h" 209#include "llwindebug.h"
206#include "lldxhardware.h" 210#include "lldxhardware.h"
@@ -2426,6 +2430,14 @@ bool idle_startup()
2426 LLInventoryView::toggleVisibility(NULL); 2430 LLInventoryView::toggleVisibility(NULL);
2427 } 2431 }
2428 2432
2433// [RLVa:KB] - Checked: 2009-11-27 (RLVa-1.1.0f) | Added: RLVa-1.1.0f
2434 if (rlv_handler_t::isEnabled())
2435 {
2436 // Regularly process a select subset of retained commands during logon
2437 gIdleCallbacks.addFunction(RlvHandler::onIdleStartup, new LLTimer());
2438 }
2439// [/RLVa:KB]
2440
2429 LLStartUp::setStartupState( STATE_MISC ); 2441 LLStartUp::setStartupState( STATE_MISC );
2430 return FALSE; 2442 return FALSE;
2431 } 2443 }
@@ -2828,7 +2840,7 @@ bool idle_startup()
2828 // reset keyboard focus to sane state of pointing at world 2840 // reset keyboard focus to sane state of pointing at world
2829 gFocusMgr.setKeyboardFocus(NULL); 2841 gFocusMgr.setKeyboardFocus(NULL);
2830 2842
2831// [RLVa:KB] - Alternate: Snowglobe-1.0 | Checked: 2009-08-05 (RLVa-1.0.1e) | Modified: RLVa-1.0.1e 2843// [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2009-08-05 (RLVa-1.0.1e) | Modified: RLVa-1.0.1e
2832 // RELEASE-RLVa: this should go in LLAppViewer::handleLoginComplete() but Imprudence doesn't call that function 2844 // RELEASE-RLVa: this should go in LLAppViewer::handleLoginComplete() but Imprudence doesn't call that function
2833 gRlvHandler.initLookupTables(); 2845 gRlvHandler.initLookupTables();
2834 2846
diff --git a/linden/indra/newview/llstatusbar.cpp b/linden/indra/newview/llstatusbar.cpp
index fbb99f0..e88d6dc 100644
--- a/linden/indra/newview/llstatusbar.cpp
+++ b/linden/indra/newview/llstatusbar.cpp
@@ -93,6 +93,9 @@ LLStatusBar *gStatusBar = NULL;
93S32 STATUS_BAR_HEIGHT = 0; 93S32 STATUS_BAR_HEIGHT = 0;
94extern S32 MENU_BAR_HEIGHT; 94extern S32 MENU_BAR_HEIGHT;
95 95
96// [RLVa:KB]
97#include "rlvhandler.h"
98// [/RLVa:KB]
96 99
97// TODO: these values ought to be in the XML too 100// TODO: these values ought to be in the XML too
98const S32 MENU_PARCEL_SPACING = 1; // Distance from right of menu item to parcel information 101const S32 MENU_PARCEL_SPACING = 1; // Distance from right of menu item to parcel information
@@ -539,7 +542,8 @@ void LLStatusBar::refresh()
539 { 542 {
540 // TODO-RLVa: find out whether the LCD code is still used because if so then we need to filter that as well 543 // TODO-RLVa: find out whether the LCD code is still used because if so then we need to filter that as well
541 location_name = llformat("%s (%s) - %s", 544 location_name = llformat("%s (%s) - %s",
542 rlv_handler_t::cstrHiddenRegion.c_str(), region->getSimAccessString().c_str(), rlv_handler_t::cstrHidden.c_str()); 545 RlvStrings::getString(RLV_STRING_HIDDEN_REGION).c_str(), region->getSimAccessString().c_str(),
546 RlvStrings::getString(RLV_STRING_HIDDEN).c_str());
543 } 547 }
544// [/RLVa:KB] 548// [/RLVa:KB]
545 549
diff --git a/linden/indra/newview/lltoolbar.cpp b/linden/indra/newview/lltoolbar.cpp
index 645d29a..e961a9b 100644
--- a/linden/indra/newview/lltoolbar.cpp
+++ b/linden/indra/newview/lltoolbar.cpp
@@ -67,6 +67,10 @@
67#include "llimpanel.h" 67#include "llimpanel.h"
68#include "llscrolllistctrl.h" 68#include "llscrolllistctrl.h"
69 69
70// [RLVa:KB]
71#include "rlvhandler.h"
72// [/RLVa:KB]
73
70#if LL_DARWIN 74#if LL_DARWIN
71 75
72 #include "llresizehandle.h" 76 #include "llresizehandle.h"
diff --git a/linden/indra/newview/lltooldraganddrop.cpp b/linden/indra/newview/lltooldraganddrop.cpp
index a3ed16b..2bc6e3e 100644
--- a/linden/indra/newview/lltooldraganddrop.cpp
+++ b/linden/indra/newview/lltooldraganddrop.cpp
@@ -72,6 +72,9 @@
72#include "llparcel.h" // RezWithLandGroup 72#include "llparcel.h" // RezWithLandGroup
73#include "llviewerparcelmgr.h" // RezWithLandGroup 73#include "llviewerparcelmgr.h" // RezWithLandGroup
74 74
75// [RLVa:KB]
76#include "rlvhandler.h"
77// [/RLVa:KB]
75 78
76// MAX ITEMS is based on (sizeof(uuid)+2) * count must be < MTUBYTES 79// MAX ITEMS is based on (sizeof(uuid)+2) * count must be < MTUBYTES
77// or 18 * count < 1200 => count < 1200/18 => 66. I've cut it down a 80// or 18 * count < 1200 => count < 1200/18 => 66. I've cut it down a
@@ -2183,8 +2186,8 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(
2183EAcceptance LLToolDragAndDrop::dad3dRezObjectOnLand( 2186EAcceptance LLToolDragAndDrop::dad3dRezObjectOnLand(
2184 LLViewerObject* obj, S32 face, MASK mask, BOOL drop) 2187 LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
2185{ 2188{
2186// [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) 2189// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l
2187 if (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) 2190 if ( (rlv_handler_t::isEnabled()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) || (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT))) )
2188 { 2191 {
2189 return ACCEPT_NO_LOCKED; 2192 return ACCEPT_NO_LOCKED;
2190 } 2193 }
@@ -2253,9 +2256,12 @@ EAcceptance LLToolDragAndDrop::dad3dRezObjectOnLand(
2253EAcceptance LLToolDragAndDrop::dad3dRezObjectOnObject( 2256EAcceptance LLToolDragAndDrop::dad3dRezObjectOnObject(
2254 LLViewerObject* obj, S32 face, MASK mask, BOOL drop) 2257 LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
2255{ 2258{
2256// [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) 2259// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l
2257 // NOTE: if (mask & MASK_CONTROL) then it's a drop rather than a rez, so we let that pass through 2260 // NOTE: if (mask & MASK_CONTROL) then it's a drop rather than a rez, so we let that pass through when @rez=n restricted
2258 if ( !(mask & MASK_CONTROL) && (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) ) 2261 // (but not when @interact=n restricted unless the drop target is a HUD attachment)
2262 if ( (rlv_handler_t::isEnabled()) &&
2263 ( ( (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) && ((mask & MASK_CONTROL) == 0) ) ||
2264 ( (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT)) && (((mask & MASK_CONTROL) == 0) || (!obj->isHUDAttachment())) ) ) )
2259 { 2265 {
2260 return ACCEPT_NO_LOCKED; 2266 return ACCEPT_NO_LOCKED;
2261 } 2267 }
@@ -2844,9 +2850,9 @@ EAcceptance LLToolDragAndDrop::dad3dGiveInventoryCategory(
2844EAcceptance LLToolDragAndDrop::dad3dRezFromObjectOnLand( 2850EAcceptance LLToolDragAndDrop::dad3dRezFromObjectOnLand(
2845 LLViewerObject* obj, S32 face, MASK mask, BOOL drop) 2851 LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
2846{ 2852{
2847// [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) 2853// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l
2848 // NOTE: it looks like this is only ever called from LLToolDragAndDrop::dad3dRezObjectOnLand() making this a bit redundant 2854 // [Fall-back code] Looks like this is only ever called from LLToolDragAndDrop::dad3dRezObjectOnObject()
2849 if (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) 2855 if ( (rlv_handler_t::isEnabled()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) || (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT))) )
2850 { 2856 {
2851 return ACCEPT_NO_LOCKED; 2857 return ACCEPT_NO_LOCKED;
2852 } 2858 }
@@ -2873,9 +2879,9 @@ EAcceptance LLToolDragAndDrop::dad3dRezFromObjectOnLand(
2873EAcceptance LLToolDragAndDrop::dad3dRezFromObjectOnObject( 2879EAcceptance LLToolDragAndDrop::dad3dRezFromObjectOnObject(
2874 LLViewerObject* obj, S32 face, MASK mask, BOOL drop) 2880 LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
2875{ 2881{
2876// [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) 2882// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l
2877 // NOTE: it looks like this is only ever called from LLToolDragAndDrop::dad3dRezObjectOnObject) making this a bit redundant 2883 // [Fall-back code] Looks like this is only ever called from LLToolDragAndDrop::dad3dRezObjectOnObject()
2878 if (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) 2884 if ( (rlv_handler_t::isEnabled()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) || (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT))) )
2879 { 2885 {
2880 return ACCEPT_NO_LOCKED; 2886 return ACCEPT_NO_LOCKED;
2881 } 2887 }
diff --git a/linden/indra/newview/lltoolface.cpp b/linden/indra/newview/lltoolface.cpp
index 3cddba7..735ecd9 100644
--- a/linden/indra/newview/lltoolface.cpp
+++ b/linden/indra/newview/lltoolface.cpp
@@ -48,6 +48,10 @@
48#include "llviewerwindow.h" 48#include "llviewerwindow.h"
49#include "llfloatertools.h" 49#include "llfloatertools.h"
50 50
51// [RLVa:KB]
52#include "rlvhandler.h"
53// [/RLVa:KB]
54
51// 55//
52// Member functions 56// Member functions
53// 57//
@@ -100,11 +104,10 @@ void LLToolFace::pickCallback(const LLPickInfo& pick_info)
100 return; 104 return;
101 } 105 }
102 106
103// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f 107// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l
104 if ( (rlv_handler_t::isEnabled()) && 108 if ( (rlv_handler_t::isEnabled()) &&
105 ( (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) || 109 ( (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) ||
106 ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && ((!hit_obj->isAttachment()) || (!hit_obj->permYouOwner())) && 110 ((gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && (!gRlvHandler.canTouch(hit_obj, pick_info.mObjectOffset))) ) )
107 (dist_vec_squared(gAgent.getPositionAgent(), hit_obj->getPositionRegion() + pick_info.mObjectOffset) > 1.5f * 1.5f) )))
108 { 111 {
109 return; 112 return;
110 } 113 }
diff --git a/linden/indra/newview/lltoolgrab.cpp b/linden/indra/newview/lltoolgrab.cpp
index 260d533..9b6d6f7 100644
--- a/linden/indra/newview/lltoolgrab.cpp
+++ b/linden/indra/newview/lltoolgrab.cpp
@@ -66,6 +66,10 @@
66 66
67#include "hippoLimits.h" 67#include "hippoLimits.h"
68 68
69// [RLVa:KB]
70#include "rlvhandler.h"
71// [/RLVa:KB]
72
69const S32 SLOP_DIST_SQ = 4; 73const S32 SLOP_DIST_SQ = 4;
70 74
71// Override modifier key behavior with these buttons 75// Override modifier key behavior with these buttons
@@ -160,7 +164,11 @@ void LLToolGrab::pickCallback(const LLPickInfo& pick_info)
160 } 164 }
161 165
162 // if not over object, do nothing 166 // if not over object, do nothing
163 if (!objectp) 167// if (!objectp)
168// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Added: RLVa-1.1.0l
169 // Block initiating a drag operation on an object that can't be touched
170 if ( (!objectp) || ((rlv_handler_t::isEnabled()) && (!gRlvHandler.canTouch(objectp, pick_info.mObjectOffset))) )
171// [/RLVa:KB]
164 { 172 {
165 LLToolGrab::getInstance()->setMouseCapture(TRUE); 173 LLToolGrab::getInstance()->setMouseCapture(TRUE);
166 LLToolGrab::getInstance()->mMode = GRAB_NOOBJECT; 174 LLToolGrab::getInstance()->mMode = GRAB_NOOBJECT;
@@ -188,12 +196,7 @@ BOOL LLToolGrab::handleObjectHit(const LLPickInfo& info)
188 return FALSE; 196 return FALSE;
189 } 197 }
190 198
191 //if (objectp->isAvatar()) 199 if (objectp->isAvatar())
192// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f
193 if ( (objectp->isAvatar()) ||
194 ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && ((!objectp->isAttachment()) || (!objectp->permYouOwner())) &&
195 (dist_vec_squared(gAgent.getPositionAgent(), mGrabPick.mIntersection) > 1.5f * 1.5f) ) )
196// [/RLVa:KB]
197 { 200 {
198 if (gGrabTransientTool) 201 if (gGrabTransientTool)
199 { 202 {
@@ -428,12 +431,10 @@ BOOL LLToolGrab::handleHover(S32 x, S32 y, MASK mask)
428 return TRUE; 431 return TRUE;
429 } 432 }
430 433
431// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-0.2.0f 434// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l
432 // Don't allow dragging beyond 1.5m under @fartouch=n 435 // Block dragging an object beyond touch range when @fartouch=n restricted
433 LLViewerObject* pObj; 436 if ( (rlv_handler_t::isEnabled()) && (GRAB_INACTIVE != mMode) && (GRAB_NOOBJECT != mMode) && (hasMouseCapture()) &&
434 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && (GRAB_INACTIVE != mMode) && (hasMouseCapture()) && 437 (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && (!gRlvHandler.canTouch(mGrabPick.getObject(), mGrabPick.mObjectOffset)) )
435 ((pObj = mGrabPick.getObject()) != NULL) && (!pObj->isDead()) && (!pObj->isHUDAttachment()) &&
436 (dist_vec_squared(gAgent.getPositionAgent(), pObj->getPositionRegion() + mGrabPick.mObjectOffset) > 1.5f * 1.5f) )
437 { 438 {
438 if (gGrabTransientTool) 439 if (gGrabTransientTool)
439 { 440 {
@@ -442,6 +443,7 @@ BOOL LLToolGrab::handleHover(S32 x, S32 y, MASK mask)
442 gGrabTransientTool = NULL; 443 gGrabTransientTool = NULL;
443 } 444 }
444 setMouseCapture(FALSE); 445 setMouseCapture(FALSE);
446 return TRUE;
445 } 447 }
446// [/RLVa:KB] 448// [/RLVa:KB]
447 449
diff --git a/linden/indra/newview/lltoolpie.cpp b/linden/indra/newview/lltoolpie.cpp
index 2b63a24..02ad008 100644
--- a/linden/indra/newview/lltoolpie.cpp
+++ b/linden/indra/newview/lltoolpie.cpp
@@ -68,6 +68,10 @@
68#include "llui.h" 68#include "llui.h"
69#include "llweb.h" 69#include "llweb.h"
70 70
71// [RLVa:KB]
72#include "rlvhandler.h"
73// [/RLVa:KB]
74
71extern void handle_buy(void*); 75extern void handle_buy(void*);
72 76
73extern BOOL gDebugClicks; 77extern BOOL gDebugClicks;
@@ -167,10 +171,10 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show)
167 // If it's a left-click, and we have a special action, do it. 171 // If it's a left-click, and we have a special action, do it.
168 if (useClickAction(always_show, mask, object, parent)) 172 if (useClickAction(always_show, mask, object, parent))
169 { 173 {
170// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f 174// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l
171 // Block left-click special actions (fallback code really since LLToolSelect::handleObjectSelection() wouldn't select it anyway) 175 // Block left-click special actions when fartouch restricted
172 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && 176 if ( (rlv_handler_t::isEnabled()) &&
173 (dist_vec_squared(gAgent.getPositionAgent(), mPick.mIntersection) > 1.5f * 1.5f) ) 177 (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && (!gRlvHandler.canTouch(object, mPick.mObjectOffset)) )
174 { 178 {
175 return TRUE; 179 return TRUE;
176 } 180 }
@@ -253,6 +257,14 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show)
253 ((object->usePhysics() || (parent && !parent->isAvatar() && parent->usePhysics())) || touchable) && 257 ((object->usePhysics() || (parent && !parent->isAvatar() && parent->usePhysics())) || touchable) &&
254 !always_show) 258 !always_show)
255 { 259 {
260// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l
261 // Triggered by left-clicking on a touchable object
262 if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canTouch(object, mPick.mObjectOffset)) )
263 {
264 return LLTool::handleMouseDown(x, y, mask);
265 }
266// [/RLVa:KB]
267
256 gGrabTransientTool = this; 268 gGrabTransientTool = this;
257 LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolGrab::getInstance() ); 269 LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolGrab::getInstance() );
258 return LLToolGrab::getInstance()->handleObjectHit( mPick ); 270 return LLToolGrab::getInstance()->handleObjectHit( mPick );
@@ -377,20 +389,17 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show)
377 } 389 }
378 390
379// gPieAvatar->show(x, y, mPieMouseButtonDown); 391// gPieAvatar->show(x, y, mPieMouseButtonDown);
380// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-0.2.0f 392// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l
381 #ifdef RLV_EXPERIMENTAL_FARTOUCH_FEEDBACK 393 // Don't show the pie menu on empty selection when fartouch/interaction restricted [see LLToolSelect::handleObjectSelection()]
382 // If we have an empty selection under @fartouch=n don't show the pie menu but play the "operation block" sound 394 if ( (!rlv_handler_t::isEnabled()) || (!LLSelectMgr::getInstance()->getSelection()->isEmpty()) ||
383 if ( (!gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) || (!LLSelectMgr::getInstance()->getSelection()->isEmpty()) ) 395 (!gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) )
384 { 396 {
385 #endif // RLV_EXPERIMENTAL_FARTOUCH_FEEDBACK 397 gPieAvatar->show(x, y, mPieMouseButtonDown);
386 gPieAvatar->show(x, y, mPieMouseButtonDown); 398 }
387 #ifdef RLV_EXPERIMENTAL_FARTOUCH_FEEDBACK 399 else
388 } 400 {
389 else 401 make_ui_sound("UISndInvalidOp");
390 { 402 }
391 make_ui_sound("UISndInvalidOp");
392 }
393 #endif // RLV_EXPERIMENTAL_FARTOUCH_FEEDBACK
394// [/RLVa:KB] 403// [/RLVa:KB]
395 } 404 }
396 else if (object->isAttachment() && !object->isHUDAttachment()) 405 else if (object->isAttachment() && !object->isHUDAttachment())
@@ -421,31 +430,28 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show)
421 //gMuteObjectPieMenu->setLabel("Mute"); 430 //gMuteObjectPieMenu->setLabel("Mute");
422 } 431 }
423 432
424// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-0.2.0f 433// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l
425 #ifdef RLV_EXPERIMENTAL_FARTOUCH_FEEDBACK 434 // Don't show the pie menu on empty selection when fartouch/interaction restricted
426 // If we have an empty selection under @fartouch=n don't show the pie menu but play the "operation block" sound 435 // (not entirely accurate in case of Tools / Select Only XXX [see LLToolSelect::handleObjectSelection()]
427 // (not entirely accurate in case of Tools / Select Only XXX [see LLToolSelect::handleObjectSelection()] 436 if ( (!rlv_handler_t::isEnabled()) || (!LLSelectMgr::getInstance()->getSelection()->isEmpty()) ||
428 if ( (!gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) || (!LLSelectMgr::getInstance()->getSelection()->isEmpty()) ) 437 (!gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) )
429 { 438 {
430 #endif // RLV_EXPERIMENTAL_FARTOUCH_FEEDBACK
431// [/RLVa:KB] 439// [/RLVa:KB]
432 gPieObject->show(x, y, mPieMouseButtonDown); 440 gPieObject->show(x, y, mPieMouseButtonDown);
433 441
434 // VEFFECT: ShowPie object 442 // VEFFECT: ShowPie object
435 // Don't show when you click on someone else, it freaks them 443 // Don't show when you click on someone else, it freaks them
436 // out. 444 // out.
437 LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_SPHERE, TRUE); 445 LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_SPHERE, TRUE);
438 effectp->setPositionGlobal(mPick.mPosGlobal); 446 effectp->setPositionGlobal(mPick.mPosGlobal);
439 effectp->setColor(LLColor4U(gAgent.getEffectColor())); 447 effectp->setColor(LLColor4U(gAgent.getEffectColor()));
440 effectp->setDuration(0.25f); 448 effectp->setDuration(0.25f);
441// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-0.2.0f 449// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-0.2.0f
442 #ifdef RLV_EXPERIMENTAL_FARTOUCH_FEEDBACK 450 }
443 } 451 else
444 else 452 {
445 { 453 make_ui_sound("UISndInvalidOp");
446 make_ui_sound("UISndInvalidOp"); 454 }
447 }
448 #endif // RLV_EXPERIMENTAL_FARTOUCH_FEEDBACK
449// [/RLVa:KB] 455// [/RLVa:KB]
450 } 456 }
451 } 457 }
@@ -514,7 +520,11 @@ ECursorType cursor_from_object(LLViewerObject* object)
514 switch(click_action) 520 switch(click_action)
515 { 521 {
516 case CLICK_ACTION_SIT: 522 case CLICK_ACTION_SIT:
517 if ((gAgent.getAvatarObject() != NULL) && (!gAgent.getAvatarObject()->mIsSitting)) // not already sitting? 523// if ((gAgent.getAvatarObject() != NULL) && (!gAgent.getAvatarObject()->mIsSitting)) // not already sitting?
524// [RLVa:KB] - Checked: 2009-12-22 (RLVa-1.1.0k) | Added: RLVa-1.1.0j
525 if ( ((gAgent.getAvatarObject() != NULL) && (!gAgent.getAvatarObject()->mIsSitting)) && // not already sitting?
526 ((!rlv_handler_t::isEnabled()) || (gRlvHandler.canSit(object, gViewerWindow->getHoverPick().mObjectOffset))) )
527// [/RLVa:KB]
518 { 528 {
519 cursor = UI_CURSOR_TOOLSIT; 529 cursor = UI_CURSOR_TOOLSIT;
520 } 530 }
@@ -619,7 +629,21 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
619 LLViewerObject *parent = NULL; 629 LLViewerObject *parent = NULL;
620 if (gHoverView) 630 if (gHoverView)
621 { 631 {
622 object = gViewerWindow->getHoverPick().getObject(); 632// object = gViewerWindow->getHoverPick().getObject();
633// [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l
634 // Block all special click action cursors when:
635 // - @fartouch=n restricted and the object is out of range
636 // - @interact=n restricted and the object isn't a HUD attachment
637 const LLPickInfo& pick = gViewerWindow->getHoverPick();
638 object = pick.getObject();
639 if ( (object) && (rlv_handler_t::isEnabled()) &&
640 ( ((gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH))) && (!gRlvHandler.canTouch(object, pick.mObjectOffset)) ||
641 ((gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT)) && (!object->isHUDAttachment())) ) )
642 {
643 gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
644 return TRUE;
645 }
646// [/RLVa:KB]
623 } 647 }
624 648
625 if (object) 649 if (object)
@@ -633,6 +657,13 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
633 gViewerWindow->getWindow()->setCursor(cursor); 657 gViewerWindow->getWindow()->setCursor(cursor);
634 lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl; 658 lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
635 } 659 }
660// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Added: RLVa-1.1.0l
661 else if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canTouch(object)) )
662 {
663 // Block showing the "grab" or "touch" cursor if we can't touch the object (@fartouch=n is handled above)
664 gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
665 }
666// [/RLVa:KB]
636 else if ((object && !object->isAvatar() && object->usePhysics()) 667 else if ((object && !object->isAvatar() && object->usePhysics())
637 || (parent && !parent->isAvatar() && parent->usePhysics())) 668 || (parent && !parent->isAvatar() && parent->usePhysics()))
638 { 669 {
diff --git a/linden/indra/newview/lltoolplacer.cpp b/linden/indra/newview/lltoolplacer.cpp
index 00b0c9f..477dbca 100644
--- a/linden/indra/newview/lltoolplacer.cpp
+++ b/linden/indra/newview/lltoolplacer.cpp
@@ -69,6 +69,10 @@
69#include "llviewerparcelmgr.h" // RezWithLandGroup 69#include "llviewerparcelmgr.h" // RezWithLandGroup
70#include "roles_constants.h" // Ele: Land Group Override 70#include "roles_constants.h" // Ele: Land Group Override
71 71
72// [RLVa:KB]
73#include "rlvhandler.h"
74// [/RLVa:KB]
75
72const LLVector3 DEFAULT_OBJECT_SCALE(0.5f, 0.5f, 0.5f); 76const LLVector3 DEFAULT_OBJECT_SCALE(0.5f, 0.5f, 0.5f);
73 77
74//static 78//static
@@ -556,8 +560,8 @@ BOOL LLToolPlacer::placeObject(S32 x, S32 y, MASK mask)
556{ 560{
557 BOOL added = TRUE; 561 BOOL added = TRUE;
558 562
559// [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) 563// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l
560 if (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) 564 if ( (rlv_handler_t::isEnabled()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) || (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT))) )
561 { 565 {
562 return TRUE; // Callers seem to expect a "did you handle it?" so we return TRUE rather than FALSE 566 return TRUE; // Callers seem to expect a "did you handle it?" so we return TRUE rather than FALSE
563 } 567 }
diff --git a/linden/indra/newview/lltoolselect.cpp b/linden/indra/newview/lltoolselect.cpp
index 02755d7..1e412de 100644
--- a/linden/indra/newview/lltoolselect.cpp
+++ b/linden/indra/newview/lltoolselect.cpp
@@ -51,7 +51,8 @@
51#include "llvoavatar.h" 51#include "llvoavatar.h"
52#include "llworld.h" 52#include "llworld.h"
53 53
54// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) 54// [RLVa:KB]
55#include "rlvhandler.h"
55#include "llfloatertools.h" 56#include "llfloatertools.h"
56// [/RLVa:KB] 57// [/RLVa:KB]
57 58
@@ -88,7 +89,7 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi
88 object = object->getRootEdit(); 89 object = object->getRootEdit();
89 } 90 }
90 91
91// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f 92// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l
92 if (rlv_handler_t::isEnabled()) 93 if (rlv_handler_t::isEnabled())
93 { 94 {
94 if (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) 95 if (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT))
diff --git a/linden/indra/newview/lltracker.cpp b/linden/indra/newview/lltracker.cpp
index 654510d..43fd4c0 100644
--- a/linden/indra/newview/lltracker.cpp
+++ b/linden/indra/newview/lltracker.cpp
@@ -65,6 +65,10 @@
65#include "llworldmapview.h" 65#include "llworldmapview.h"
66#include "llviewercontrol.h" 66#include "llviewercontrol.h"
67 67
68// [RLVa:KB]
69#include "rlvhandler.h"
70// [/RLVa:KB]
71
68const F32 DESTINATION_REACHED_RADIUS = 3.0f; 72const F32 DESTINATION_REACHED_RADIUS = 3.0f;
69const F32 DESTINATION_VISITED_RADIUS = 6.0f; 73const F32 DESTINATION_VISITED_RADIUS = 6.0f;
70 74
@@ -185,7 +189,7 @@ void LLTracker::render3D()
185 // instance()->mBeaconText, instance()->mTrackedLocationName ); 189 // instance()->mBeaconText, instance()->mTrackedLocationName );
186// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | Added: RLVa-1.0.0a 190// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | Added: RLVa-1.0.0a
187 renderBeacon(instance()->mTrackedPositionGlobal, gTrackColor, instance()->mBeaconText, 191 renderBeacon(instance()->mTrackedPositionGlobal, gTrackColor, instance()->mBeaconText,
188 (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? instance()->mTrackedLocationName : rlv_handler_t::cstrHidden); 192 (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? instance()->mTrackedLocationName : RlvStrings::getString(RLV_STRING_HIDDEN));
189// [/RLVa:KB] 193// [/RLVa:KB]
190 } 194 }
191 } 195 }
@@ -231,7 +235,8 @@ void LLTracker::render3D()
231 // instance()->mBeaconText, instance()->mTrackedLandmarkName ); 235 // instance()->mBeaconText, instance()->mTrackedLandmarkName );
232// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | Added: RLVa-1.0.0a 236// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | Added: RLVa-1.0.0a
233 renderBeacon( instance()->mTrackedPositionGlobal, gTrackColor, instance()->mBeaconText, 237 renderBeacon( instance()->mTrackedPositionGlobal, gTrackColor, instance()->mBeaconText,
234 (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? instance()->mTrackedLandmarkName : rlv_handler_t::cstrHidden); 238 (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? instance()->mTrackedLandmarkName
239 : RlvStrings::getString(RLV_STRING_HIDDEN));
235// [/RLVa:KB] 240// [/RLVa:KB]
236 } 241 }
237 } 242 }
@@ -264,7 +269,7 @@ void LLTracker::render3D()
264 // instance()->mBeaconText, av_tracker.getName() ); 269 // instance()->mBeaconText, av_tracker.getName() );
265// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | Added: RLVa-1.0.0a 270// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | Added: RLVa-1.0.0a
266 renderBeacon( av_tracker.getGlobalPos(), gTrackColor, instance()->mBeaconText, 271 renderBeacon( av_tracker.getGlobalPos(), gTrackColor, instance()->mBeaconText,
267 (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? av_tracker.getName() : rlv_handler_t::cstrHidden); 272 (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? av_tracker.getName() : RlvStrings::getString(RLV_STRING_HIDDEN));
268// [/RLVa:KB] 273// [/RLVa:KB]
269 } 274 }
270 } 275 }
diff --git a/linden/indra/newview/llviewercontrol.cpp b/linden/indra/newview/llviewercontrol.cpp
index 50224ad..88ea904 100644
--- a/linden/indra/newview/llviewercontrol.cpp
+++ b/linden/indra/newview/llviewercontrol.cpp
@@ -520,19 +520,6 @@ bool handleSliderScrollWheelMultiplierChanged(const LLSD& newvalue)
520 return true; 520 return true;
521} 521}
522 522
523// [RLVa:KB] - Checked: 2009-08-11 (RLVa-1.0.1h) | Added: RLVa-1.0.1h
524bool rlvHandleEnableLegacyNamingChanged(const LLSD& newvalue)
525{
526 rlv_handler_t::fLegacyNaming = newvalue.asBoolean();
527 return true;
528}
529
530bool rlvHandleShowNameTagsChanged(const LLSD& newvalue)
531{
532 RlvSettings::fShowNameTags = newvalue.asBoolean();
533 return true;
534}
535// [/RLVa:KB]
536 523
537//////////////////////////////////////////////////////////////////////////// 524////////////////////////////////////////////////////////////////////////////
538 525
@@ -677,13 +664,6 @@ void settings_setup_listeners()
677 gSavedSettings.getControl("MediaDebugLevel")->getSignal()->connect(boost::bind(&handleMediaDebugLevelChanged, _1)); 664 gSavedSettings.getControl("MediaDebugLevel")->getSignal()->connect(boost::bind(&handleMediaDebugLevelChanged, _1));
678 gSavedSettings.getControl("SliderScrollWheelMultiplier")->getSignal()->connect(boost::bind(&handleSliderScrollWheelMultiplierChanged, _1)); 665 gSavedSettings.getControl("SliderScrollWheelMultiplier")->getSignal()->connect(boost::bind(&handleSliderScrollWheelMultiplierChanged, _1));
679 gSavedSettings.getControl("TranslateChat")->getSignal()->connect(boost::bind(&handleTranslateChatPrefsChanged, _1)); 666 gSavedSettings.getControl("TranslateChat")->getSignal()->connect(boost::bind(&handleTranslateChatPrefsChanged, _1));
680
681// [RLVa:KB] - Checked: 2009-08-11 (RLVa-1.0.1h) | Added: RLVa-1.0.1h
682 if (gSavedSettings.controlExists(RLV_SETTING_ENABLELEGACYNAMING))
683 gSavedSettings.getControl(RLV_SETTING_ENABLELEGACYNAMING)->getSignal()->connect(boost::bind(&rlvHandleEnableLegacyNamingChanged, _1));
684 if (gSavedSettings.controlExists(RLV_SETTING_SHOWNAMETAGS))
685 gSavedSettings.getControl(RLV_SETTING_SHOWNAMETAGS)->getSignal()->connect(boost::bind(&rlvHandleShowNameTagsChanged, _1));
686// [/RLVa:KB]
687} 667}
688 668
689template <> eControlType get_control_type<U32>(const U32& in, LLSD& out) 669template <> eControlType get_control_type<U32>(const U32& in, LLSD& out)
diff --git a/linden/indra/newview/llviewerdisplay.cpp b/linden/indra/newview/llviewerdisplay.cpp
index 5316337..78940cc 100644
--- a/linden/indra/newview/llviewerdisplay.cpp
+++ b/linden/indra/newview/llviewerdisplay.cpp
@@ -83,6 +83,10 @@
83#include "llwaterparammanager.h" 83#include "llwaterparammanager.h"
84#include "llpostprocess.h" 84#include "llpostprocess.h"
85 85
86// [RLVa:KB]
87#include "rlvhandler.h"
88// [/RLVa:KB]
89
86extern LLPointer<LLImageGL> gStartImageGL; 90extern LLPointer<LLImageGL> gStartImageGL;
87 91
88LLPointer<LLImageGL> gDisconnectedImagep = NULL; 92LLPointer<LLImageGL> gDisconnectedImagep = NULL;
diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp
index 6ec7e46..524654a 100644
--- a/linden/indra/newview/llviewermenu.cpp
+++ b/linden/indra/newview/llviewermenu.cpp
@@ -241,10 +241,8 @@ void init_debug_ui_menu(LLMenuGL* menu);
241void init_debug_xui_menu(LLMenuGL* menu); 241void init_debug_xui_menu(LLMenuGL* menu);
242void init_debug_avatar_menu(LLMenuGL* menu); 242void init_debug_avatar_menu(LLMenuGL* menu);
243void init_debug_baked_texture_menu(LLMenuGL* menu); 243void init_debug_baked_texture_menu(LLMenuGL* menu);
244// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) 244// [RLVa:KB]
245#ifdef RLV_DEBUG_TESTS 245#include "rlvhandler.h"
246 #include "rlvtest.h"
247#endif // RLV_DEBUG_TESTS
248#include "rlvfloaterbehaviour.h" 246#include "rlvfloaterbehaviour.h"
249void init_debug_rlva_menu(LLMenuGL* menu); 247void init_debug_rlva_menu(LLMenuGL* menu);
250// [/RLVa:KB] 248// [/RLVa:KB]
@@ -860,7 +858,7 @@ void init_client_menu(LLMenuGL* menu)
860 init_debug_world_menu(sub_menu); 858 init_debug_world_menu(sub_menu);
861 menu->appendMenu(sub_menu); 859 menu->appendMenu(sub_menu);
862 860
863// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.1b 861// [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.1b
864 #ifdef RLV_ADVANCED_MENU 862 #ifdef RLV_ADVANCED_MENU
865 if (rlv_handler_t::isEnabled()) 863 if (rlv_handler_t::isEnabled())
866 { 864 {
@@ -970,7 +968,7 @@ void init_client_menu(LLMenuGL* menu)
970// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-1.0.0e 968// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-1.0.0e
971 #ifdef RLV_ADVANCED_TOGGLE_RLVA 969 #ifdef RLV_ADVANCED_TOGGLE_RLVA
972 if (gSavedSettings.controlExists(RLV_SETTING_MAIN)) 970 if (gSavedSettings.controlExists(RLV_SETTING_MAIN))
973 menu->append(new LLMenuItemCheckGL("Restrained Life API", &rlvToggleEnabled, NULL, &rlvGetEnabled, NULL)); 971 menu->append(new LLMenuItemCheckGL("RestrainedLove API", &rlvToggleEnabled, NULL, &rlvGetEnabled, NULL));
974 #endif // RLV_ADVANCED_TOGGLE_RLVA 972 #endif // RLV_ADVANCED_TOGGLE_RLVA
975// [/RLVa:KB] 973// [/RLVa:KB]
976 974
@@ -1433,7 +1431,7 @@ void init_debug_baked_texture_menu(LLMenuGL* menu)
1433 menu->createJumpKeys(); 1431 menu->createJumpKeys();
1434} 1432}
1435 1433
1436// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-1.0.0g 1434// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-11-17 (RLVa-1.1.0d) | Modified: RLVa-1.1.0d
1437void init_debug_rlva_menu(LLMenuGL* menu) 1435void init_debug_rlva_menu(LLMenuGL* menu)
1438{ 1436{
1439 // Debug options 1437 // Debug options
@@ -1442,26 +1440,31 @@ void init_debug_rlva_menu(LLMenuGL* menu)
1442 1440
1443 if (gSavedSettings.controlExists(RLV_SETTING_DEBUG)) 1441 if (gSavedSettings.controlExists(RLV_SETTING_DEBUG))
1444 pDbgMenu->append(new LLMenuItemCheckGL("Show Debug Messages", menu_toggle_control, NULL, menu_check_control, (void*)RLV_SETTING_DEBUG)); 1442 pDbgMenu->append(new LLMenuItemCheckGL("Show Debug Messages", menu_toggle_control, NULL, menu_check_control, (void*)RLV_SETTING_DEBUG));
1443 pDbgMenu->append(new LLMenuItemCallGL("Dump Attachment Locks", RlvHandler::dumpAttachmentLocks, NULL, NULL));
1445 pDbgMenu->appendSeparator(); 1444 pDbgMenu->appendSeparator();
1446 if (gSavedSettings.controlExists(RLV_SETTING_ENABLELEGACYNAMING)) 1445 if (gSavedSettings.controlExists(RLV_SETTING_ENABLELEGACYNAMING))
1447 pDbgMenu->append(new LLMenuItemCheckGL("Enable Legacy Naming", menu_toggle_control, NULL, menu_check_control, (void*)RLV_SETTING_ENABLELEGACYNAMING)); 1446 pDbgMenu->append(new LLMenuItemCheckGL("Enable Legacy Naming", menu_toggle_control, NULL, menu_check_control, (void*)RLV_SETTING_ENABLELEGACYNAMING));
1447 if (gSavedSettings.controlExists(RLV_SETTING_SHAREDINVAUTORENAME))
1448 pDbgMenu->append(new LLMenuItemCheckGL("Rename Shared Items on Wear", menu_toggle_control, NULL, menu_check_control, (void*)RLV_SETTING_SHAREDINVAUTORENAME));
1448 1449
1449 menu->appendMenu(pDbgMenu); 1450 menu->appendMenu(pDbgMenu);
1450 menu->appendSeparator(); 1451 menu->appendSeparator();
1451 } 1452 }
1452 1453
1453 #ifdef RLV_EXTENSION_ENABLE_WEAR 1454 if (gSavedSettings.controlExists(RLV_SETTING_ENABLEWEAR))
1454 if (gSavedSettings.controlExists(RLV_SETTING_ENABLEWEAR)) 1455 menu->append(new LLMenuItemCheckGL("Enable Default Wear", menu_toggle_control, rlvEnableWearEnabler, menu_check_control, (void*)RLV_SETTING_ENABLEWEAR));
1455 menu->append(new LLMenuItemCheckGL("Enable Wear", menu_toggle_control, rlvEnableWearEnabler, menu_check_control, (void*)RLV_SETTING_ENABLEWEAR)); 1456#ifndef RLV_WORKAROUND_REZMULTIPLEATTACH
1456 menu->appendSeparator(); 1457 if (gSavedSettings.controlExists(RLV_SETTING_ENABLESHAREDWEAR))
1457 #endif // RLV_EXTENSION_ENABLE_WEAR 1458 menu->append(new LLMenuItemCheckGL("Enable Shared Wear", menu_toggle_control, rlvEnableSharedWearEnabler, menu_check_control, (void*)RLV_SETTING_ENABLESHAREDWEAR));
1459#endif // RLV_WORKAROUND_REZMULTIPLEATTACH
1460 menu->appendSeparator();
1458 1461
1459 #ifdef RLV_EXTENSION_HIDELOCKED 1462 #ifdef RLV_EXTENSION_HIDELOCKED
1460 if ( (gSavedSettings.controlExists(RLV_SETTING_HIDELOCKEDLAYER)) && 1463 if ( (gSavedSettings.controlExists(RLV_SETTING_HIDELOCKEDLAYER)) &&
1461 (gSavedSettings.controlExists(RLV_SETTING_HIDELOCKEDATTACH)) ) 1464 (gSavedSettings.controlExists(RLV_SETTING_HIDELOCKEDATTACH)) )
1462 { 1465 {
1463 menu->append(new LLMenuItemCheckGL("Hide locked layers", menu_toggle_control, NULL, menu_check_control, (void*)RLV_SETTING_HIDELOCKEDLAYER)); 1466 menu->append(new LLMenuItemCheckGL("Hide Locked Layers", menu_toggle_control, NULL, menu_check_control, (void*)RLV_SETTING_HIDELOCKEDLAYER));
1464 menu->append(new LLMenuItemCheckGL("Hide locked attachments", menu_toggle_control, NULL, menu_check_control, (void*)RLV_SETTING_HIDELOCKEDATTACH)); 1467 menu->append(new LLMenuItemCheckGL("Hide Locked Attachments", menu_toggle_control, NULL, menu_check_control, (void*)RLV_SETTING_HIDELOCKEDATTACH));
1465 //sub_menu->append(new LLMenuItemToggleGL("Hide locked inventory", &rlv_handler_t::fHideLockedInventory)); 1468 //sub_menu->append(new LLMenuItemToggleGL("Hide locked inventory", &rlv_handler_t::fHideLockedInventory));
1466 menu->appendSeparator(); 1469 menu->appendSeparator();
1467 } 1470 }
@@ -1662,13 +1665,10 @@ class LLObjectTouch : public view_listener_t
1662 1665
1663 LLPickInfo pick = LLToolPie::getInstance()->getPick(); 1666 LLPickInfo pick = LLToolPie::getInstance()->getPick();
1664 1667
1665// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-0.2.0f 1668// [RLVa:KB] - Checked: 2010-01-01 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l
1666 // TODO-RLVa: this code is rather redundant since we'll never get an active selection to show a pie menu for 1669 if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canTouch(object, pick.mObjectOffset)) )
1667 // [msg->addVector3("Position", pick.mIntersection) <- see llDetectedTouchPos()]
1668 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && ((!object->isAttachment()) || (!object->permYouOwner())) &&
1669 (dist_vec_squared(gAgent.getPositionAgent(), pick.mIntersection) > 1.5f * 1.5f) )
1670 { 1670 {
1671 return true; // Can't touch in-world objects (or other avie's attachments) farther than 1.5m away under @fartouch=n 1671 return true;
1672 } 1672 }
1673// [/RLVa:KB] 1673// [/RLVa:KB]
1674 1674
@@ -1720,12 +1720,10 @@ class LLObjectEnableTouch : public view_listener_t
1720 { 1720 {
1721 LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); 1721 LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
1722 bool new_value = obj && obj->flagHandleTouch(); 1722 bool new_value = obj && obj->flagHandleTouch();
1723// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-0.2.0f 1723// [RLVa:KB] - Version: 1.23.4 | Checked: 2010-01-01 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l
1724 // TODO-RLVa: this code is rather redundant since we'll never get an active selection to show a pie menu for 1724 if ( (new_value) && (rlv_handler_t::isEnabled()) && (!gRlvHandler.canTouch(obj, LLToolPie::getInstance()->getPick().mObjectOffset)) )
1725 if ( (new_value) && (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && ((!obj->isAttachment()) || (!obj->permYouOwner())) &&
1726 (dist_vec_squared(gAgent.getPositionAgent(), LLToolPie::getInstance()->getPick().mIntersection) > 1.5f * 1.5f) )
1727 { 1725 {
1728 new_value = false; // Can't touch in-world objects (or other avie's attachments) farther than 1.5m away under @fartouch=n 1726 new_value = false;
1729 } 1727 }
1730// [/RLVa:KB] 1728// [/RLVa:KB]
1731 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); 1729 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
@@ -2681,7 +2679,7 @@ class LLAvatarFreeze : public view_listener_t
2681 LLSD args; 2679 LLSD args;
2682// args["AVATAR_NAME"] = fullname; 2680// args["AVATAR_NAME"] = fullname;
2683// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) 2681// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e)
2684 args["AVATAR_NAME"] = (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? fullname : gRlvHandler.getAnonym(fullname); 2682 args["AVATAR_NAME"] = (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? fullname : RlvStrings::getAnonym(fullname);
2685// [/RLVa:KB] 2683// [/RLVa:KB]
2686 LLNotifications::instance().add("FreezeAvatarFullname", 2684 LLNotifications::instance().add("FreezeAvatarFullname",
2687 args, 2685 args,
@@ -2810,7 +2808,7 @@ class LLAvatarEject : public view_listener_t
2810// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) 2808// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e)
2811 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (!fullname.empty()) ) 2809 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (!fullname.empty()) )
2812 { 2810 {
2813 fullname = gRlvHandler.getAnonym(fullname); 2811 fullname = RlvStrings::getAnonym(fullname);
2814 } 2812 }
2815// [/RLVa:KB] 2813// [/RLVa:KB]
2816 2814
@@ -3418,10 +3416,9 @@ bool handle_sit_or_stand()
3418 return true; 3416 return true;
3419 } 3417 }
3420 3418
3421// [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0c) 3419// [RLVa:KB] - Checked: 2009-12-22 (RLVa-1.1.0k) | Modified: RLVa-1.1.0j
3422 if ( (rlv_handler_t::isEnabled()) && 3420 // Block if we can't sit on the selected object (also handles sitting and prevented from standing up)
3423 ( ((gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (gAgent.getAvatarObject()) && (gAgent.getAvatarObject()->mIsSitting)) || 3421 if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canSit(object, pick.mObjectOffset)) )
3424 (gRlvHandler.hasBehaviour(RLV_BHVR_SIT)) ) )
3425 { 3422 {
3426 return true; 3423 return true;
3427 } 3424 }
@@ -3437,15 +3434,6 @@ bool handle_sit_or_stand()
3437 3434
3438 if (object && object->getPCode() == LL_PCODE_VOLUME) 3435 if (object && object->getPCode() == LL_PCODE_VOLUME)
3439 { 3436 {
3440// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0g
3441 if ( (rlv_handler_t::isEnabled()) &&
3442 ((gRlvHandler.hasBehaviour(RLV_BHVR_SITTP)) || (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH))) &&
3443 (dist_vec_squared(gAgent.getPositionGlobal(), object->getPositionGlobal() + LLVector3d(pick.mObjectOffset)) > 1.5f * 1.5f) )
3444 {
3445 return true; // Don't allow sitting farther away than 1.5m under @sittp=n or @fartouch=n
3446 }
3447// [/RLVa:KB]
3448
3449 gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit); 3437 gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit);
3450 gMessageSystem->nextBlockFast(_PREHASH_AgentData); 3438 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
3451 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); 3439 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
@@ -3483,8 +3471,8 @@ class LLLandSit : public view_listener_t
3483{ 3471{
3484 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) 3472 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
3485 { 3473 {
3486// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) 3474// [RLVa:KB] - Checked: 2010-03-31 (RLVa-1.1.1a) | Modified: RLVa-1.2.0c
3487 if (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) 3475 if ( (rlv_handler_t::isEnabled()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SIT))) )
3488 { 3476 {
3489 return true; 3477 return true;
3490 } 3478 }
@@ -5800,7 +5788,9 @@ class LLObjectEnableSitOrStand : public view_listener_t
5800 new_value = true; 5788 new_value = true;
5801 } 5789 }
5802 } 5790 }
5803 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); 5791// [RLVa:KB] - Checked: 2009-12-22 (RLVa-1.1.0k) | Added: RLVa-1.1.0j
5792// gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
5793// [/RLVa:KB]
5804 5794
5805 // Update label 5795 // Update label
5806 std::string label; 5796 std::string label;
@@ -5816,6 +5806,9 @@ class LLObjectEnableSitOrStand : public view_listener_t
5816 if (sitting_on_selection()) 5806 if (sitting_on_selection())
5817 { 5807 {
5818 label = stand_text; 5808 label = stand_text;
5809// [RLVa:KB] - Checked: 2009-12-22 (RLVa-1.1.0k) | Added: RLVa-1.1.0j
5810 new_value &= !gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT);
5811// [/RLVa:KB]
5819 } 5812 }
5820 else 5813 else
5821 { 5814 {
@@ -5828,8 +5821,22 @@ class LLObjectEnableSitOrStand : public view_listener_t
5828 { 5821 {
5829 label = sit_text; 5822 label = sit_text;
5830 } 5823 }
5824// [RLVa:KB] - Checked: 2009-12-22 (RLVa-1.1.0k) | Added: RLVa-1.1.0j
5825 if ( (rlv_handler_t::isEnabled()) && (new_value) )
5826 {
5827 // RELEASE-RLVa: [2009-12-22] make sure we examine the same object that handle_sit_or_stand() will request a sit for
5828 const LLPickInfo& pick = LLToolPie::getInstance()->getPick();
5829 if (pick.mObjectID.notNull())
5830 {
5831 new_value = gRlvHandler.canSit(pick.getObject(), pick.mObjectOffset);
5832 }
5833 }
5834// [/RLVa:KB]
5831 } 5835 }
5832 gMenuHolder->childSetText("Object Sit", label); 5836 gMenuHolder->childSetText("Object Sit", label);
5837// [RLVa:KB] - Checked: 2009-12-22 (RLVa-1.1.0k) | Added: RLVa-1.1.0j
5838 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
5839// [/RLVa:KB]
5833 5840
5834 return true; 5841 return true;
5835 } 5842 }
@@ -7569,6 +7576,9 @@ class LLWorldEnableTeleportHome : public view_listener_t
7569 LLViewerRegion* regionp = gAgent.getRegion(); 7576 LLViewerRegion* regionp = gAgent.getRegion();
7570 bool agent_on_prelude = (regionp && regionp->isPrelude()); 7577 bool agent_on_prelude = (regionp && regionp->isPrelude());
7571 bool enable_teleport_home = gAgent.isGodlike() || !agent_on_prelude; 7578 bool enable_teleport_home = gAgent.isGodlike() || !agent_on_prelude;
7579// [RLVa:KB] - Checked: 2009-12-22 (RLVa-1.1.0k) | Added: RLVa-1.1.0j
7580 enable_teleport_home &= !gRlvHandler.hasBehaviour(RLV_BHVR_TPLM);
7581// [/RLVa:KB]
7572 gMenuHolder->findControl(userdata["control"].asString())->setValue(enable_teleport_home); 7582 gMenuHolder->findControl(userdata["control"].asString())->setValue(enable_teleport_home);
7573 return true; 7583 return true;
7574 } 7584 }
@@ -11420,4 +11430,10 @@ void initialize_menus()
11420 addMenu(new RLVaBehaviorsShow(), "RLVa.Behaviors.Show"); 11430 addMenu(new RLVaBehaviorsShow(), "RLVa.Behaviors.Show");
11421// [/RLVa:KB] 11431// [/RLVa:KB]
11422 11432
11433// [RLVa:KB] - Checked: 2010-01-18 (RLVa-1.1.0m) | Added: RLVa-1.1.0m
11434 if (rlv_handler_t::isEnabled())
11435 {
11436 addMenu(new RlvEnableIfNot(), "RLV.EnableIfNot");
11437 }
11438// [/RLVa:KB]
11423} 11439}
diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp
index 52113ce..a512a66 100755
--- a/linden/indra/newview/llviewermessage.cpp
+++ b/linden/indra/newview/llviewermessage.cpp
@@ -143,6 +143,10 @@
143 143
144#include "panelradarentry.h" 144#include "panelradarentry.h"
145 145
146// [RLVa:KB]
147#include "rlvhandler.h"
148// [/RLVa:KB]
149
146#include <boost/tokenizer.hpp> 150#include <boost/tokenizer.hpp>
147#include <boost/regex.hpp> // Boost Reg Expresions 151#include <boost/regex.hpp> // Boost Reg Expresions
148 152
@@ -1130,7 +1134,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
1130 std::string full_name = first_name + " " + last_name; 1134 std::string full_name = first_name + " " + last_name;
1131 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (gRlvHandler.isAgentNearby(mFromID)) ) 1135 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (gRlvHandler.isAgentNearby(mFromID)) )
1132 { 1136 {
1133 full_name = gRlvHandler.getAnonym(full_name); 1137 full_name = RlvStrings::getAnonym(full_name);
1134 } 1138 }
1135 from_string = std::string("An object named '") + mFromName + "' owned by " + full_name; 1139 from_string = std::string("An object named '") + mFromName + "' owned by " + full_name;
1136 chatHistory_string = mFromName + " owned by " + full_name; 1140 chatHistory_string = mFromName + " owned by " + full_name;
@@ -1199,6 +1203,23 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
1199 // This is an offer from an agent. In this case, the back 1203 // This is an offer from an agent. In this case, the back
1200 // end has already copied the items into your inventory, 1204 // end has already copied the items into your inventory,
1201 // so we can fetch it out of our inventory. 1205 // so we can fetch it out of our inventory.
1206// [RLVa:KB] - Checked: 2010-01-01 (RLVa-1.1.0l) | Added: RLVa-1.1.0l
1207#ifdef RLV_EXTENSION_GIVETORLV_A2A
1208 if ( (rlv_handler_t::isEnabled()) && (!RlvSettings::getForbidGiveToRLV()) &&
1209 (LLAssetType::AT_CATEGORY == mType) && (mDesc.find(RLV_PUTINV_PREFIX) == 0) )
1210 {
1211 RlvGiveToRLVAgentOffer* pOffer = new RlvGiveToRLVAgentOffer();
1212 LLInventoryFetchComboObserver::folder_ref_t folders;
1213 folders.push_back(mObjectID);
1214 pOffer->fetchDescendents(folders);
1215 if (pOffer->isEverythingComplete())
1216 pOffer->done();
1217 else
1218 gInventory.addObserver(pOffer);
1219 }
1220#endif // RLV_EXTENSION_GIVETORLV_A2A
1221// [/RLVa:KB]
1222
1202 LLInventoryFetchObserver::item_ref_t items; 1223 LLInventoryFetchObserver::item_ref_t items;
1203 items.push_back(mObjectID); 1224 items.push_back(mObjectID);
1204 LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(from_string); 1225 LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(from_string);
@@ -1389,7 +1410,7 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
1389// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) 1410// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e)
1390 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (gRlvHandler.isAgentNearby(info->mFromID)) ) 1411 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (gRlvHandler.isAgentNearby(info->mFromID)) )
1391 { 1412 {
1392 first_name = gRlvHandler.getAnonym(first_name.append(" ").append(last_name)); 1413 first_name = RlvStrings::getAnonym(first_name.append(" ").append(last_name));
1393 last_name.clear(); 1414 last_name.clear();
1394 } 1415 }
1395// [/RLVa:KB] 1416// [/RLVa:KB]
@@ -1415,7 +1436,7 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
1415// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) 1436// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e)
1416 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (gRlvHandler.isAgentNearby(info->mFromID)) ) 1437 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (gRlvHandler.isAgentNearby(info->mFromID)) )
1417 { 1438 {
1418 args["NAME"] = gRlvHandler.getAnonym(info->mFromName); 1439 args["NAME"] = RlvStrings::getAnonym(info->mFromName);
1419 } 1440 }
1420// [/RLVa:KB] 1441// [/RLVa:KB]
1421 p.name = "UserGiveItem"; 1442 p.name = "UserGiveItem";
@@ -1840,7 +1861,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1840// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) 1861// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g)
1841 else if ( (rlv_handler_t::isEnabled()) && (offline == IM_ONLINE) && ("@version" == message) ) 1862 else if ( (rlv_handler_t::isEnabled()) && (offline == IM_ONLINE) && ("@version" == message) )
1842 { 1863 {
1843 rlvSendBusyMessage(from_id, gRlvHandler.getVersionString(), session_id); 1864 rlvSendBusyMessage(from_id, RlvStrings::getVersion(), session_id);
1844 // We won't receive a typing stop message, so do that manually (see comment at the end of LLFloaterIMPanel::sendMsg) 1865 // We won't receive a typing stop message, so do that manually (see comment at the end of LLFloaterIMPanel::sendMsg)
1845 LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem); 1866 LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
1846 gIMMgr->processIMTypingStop(im_info); 1867 gIMMgr->processIMTypingStop(im_info);
@@ -1916,7 +1937,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1916 gRlvHandler.filterLocation(message); 1937 gRlvHandler.filterLocation(message);
1917 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) 1938 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
1918 { 1939 {
1919 name = gRlvHandler.getAnonym(name); 1940 name = RlvStrings::getAnonym(name);
1920 gRlvHandler.filterNames(message); 1941 gRlvHandler.filterNames(message);
1921 } 1942 }
1922 } 1943 }
@@ -1940,9 +1961,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1940// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) 1961// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g)
1941 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM)) && (!gRlvHandler.isException(RLV_BHVR_RECVIM, from_id)) ) 1962 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM)) && (!gRlvHandler.isException(RLV_BHVR_RECVIM, from_id)) )
1942 { 1963 {
1943 rlvSendBusyMessage(from_id, rlv_handler_t::cstrMsgRecvIM, session_id); 1964 if (!is_muted)
1944 1965 rlvSendBusyMessage(from_id, RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM_REMOTE), session_id);
1945 message = message.substr(0, message_offset) + rlv_handler_t::cstrBlockedRecvIM; 1966 message = message.substr(0, message_offset) + RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM);
1946 } 1967 }
1947// [/RLVa:KB] 1968// [/RLVa:KB]
1948 1969
@@ -2167,7 +2188,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
2167// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) 2188// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e)
2168 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (gRlvHandler.isAgentNearby(from_id)) ) 2189 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (gRlvHandler.isAgentNearby(from_id)) )
2169 { 2190 {
2170 name = gRlvHandler.getAnonym(name); 2191 name = RlvStrings::getAnonym(name);
2171 } 2192 }
2172// [/RLVa:KB] 2193// [/RLVa:KB]
2173 } 2194 }
@@ -2207,11 +2228,17 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
2207 } 2228 }
2208 else 2229 else
2209 { 2230 {
2210// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-09-10 (RLVa-1.0.3a) 2231// [RLVa:KB] - Version: 1.23.4 | Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l
2211 if ( (rlv_handler_t::isEnabled()) && (dialog == IM_TASK_INVENTORY_OFFERED) && 2232 if ( (rlv_handler_t::isEnabled()) &&
2212 (info->mDesc.find(RLV_PUTINV_PREFIX) == 1) && (gRlvHandler.getSharedRoot()) ) 2233 (
2234 ((IM_TASK_INVENTORY_OFFERED == dialog) && (info->mDesc.find(RLV_PUTINV_PREFIX) == 1))
2235#ifdef RLV_EXTENSION_GIVETORLV_A2A
2236 || ((IM_INVENTORY_OFFERED == dialog) && (info->mDesc.find(RLV_PUTINV_PREFIX) == 0))
2237#endif // RLV_EXTENSION_GIVETORLV_A2A
2238 ) &&
2239 (gRlvHandler.getSharedRoot()) )
2213 { 2240 {
2214 LLFirstUse::warnRlvGiveToRLV(); 2241 RlvNotifications::warnGiveToRLV();
2215 } 2242 }
2216// [/RLVa:KB] 2243// [/RLVa:KB]
2217 2244
@@ -2225,7 +2252,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
2225// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.0b 2252// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.0b
2226 bool fRlvObfuscate = (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && 2253 bool fRlvObfuscate = (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) &&
2227 (gRlvHandler.isAgentNearby(from_id)) && (!gAvatarInfoInstances.checkData(from_id)); 2254 (gRlvHandler.isAgentNearby(from_id)) && (!gAvatarInfoInstances.checkData(from_id));
2228 args["NAME"] = (!fRlvObfuscate) ? name : gRlvHandler.getAnonym(name); 2255 args["NAME"] = (!fRlvObfuscate) ? name : RlvStrings::getAnonym(name);
2229// [/RLVa:KB] 2256// [/RLVa:KB]
2230 //args["NAME"] = name; 2257 //args["NAME"] = name;
2231 LLNotifications::instance().add("InventoryAccepted", args); 2258 LLNotifications::instance().add("InventoryAccepted", args);
@@ -2236,7 +2263,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
2236// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.0b 2263// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.0b
2237 bool fRlvObfuscate = (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && 2264 bool fRlvObfuscate = (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) &&
2238 (gRlvHandler.isAgentNearby(from_id)) && (!gAvatarInfoInstances.checkData(from_id)); 2265 (gRlvHandler.isAgentNearby(from_id)) && (!gAvatarInfoInstances.checkData(from_id));
2239 args["NAME"] = (!fRlvObfuscate) ? name : gRlvHandler.getAnonym(name); 2266 args["NAME"] = (!fRlvObfuscate) ? name : RlvStrings::getAnonym(name);
2240// [/RLVa:KB] 2267// [/RLVa:KB]
2241 //args["NAME"] = name; 2268 //args["NAME"] = name;
2242 LLNotifications::instance().add("InventoryDeclined", args); 2269 LLNotifications::instance().add("InventoryDeclined", args);
@@ -2285,7 +2312,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
2285 else 2312 else
2286 { 2313 {
2287 if ( (from_id != gAgent.getID()) && (!gRlvHandler.isException(RLV_BHVR_RECVIM, from_id)) ) 2314 if ( (from_id != gAgent.getID()) && (!gRlvHandler.isException(RLV_BHVR_RECVIM, from_id)) )
2288 message = message.substr(0, message_offset) + rlv_handler_t::cstrBlockedRecvIM; 2315 message = message.substr(0, message_offset) + RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM);
2289 } 2316 }
2290 } 2317 }
2291// [/RLVa:KB] 2318// [/RLVa:KB]
@@ -2453,7 +2480,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
2453 if ( ( (gRlvHandler.hasBehaviour(RLV_BHVR_TPLURE)) && (!gRlvHandler.isException(RLV_BHVR_TPLURE, from_id)) ) || 2480 if ( ( (gRlvHandler.hasBehaviour(RLV_BHVR_TPLURE)) && (!gRlvHandler.isException(RLV_BHVR_TPLURE, from_id)) ) ||
2454 ( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (pAvatar) && (pAvatar->mIsSitting) ) ) 2481 ( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (pAvatar) && (pAvatar->mIsSitting) ) )
2455 { 2482 {
2456 rlvSendBusyMessage(from_id, rlv_handler_t::cstrMsgTpLure); 2483 rlvSendBusyMessage(from_id, RlvStrings::getString(RLV_STRING_BLOCKED_TPLURE_REMOTE));
2457 return; 2484 return;
2458 } 2485 }
2459 2486
@@ -2461,7 +2488,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
2461 if ( ( (gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM)) && (!gRlvHandler.isException(RLV_BHVR_RECVIM, from_id)) ) || 2488 if ( ( (gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM)) && (!gRlvHandler.isException(RLV_BHVR_RECVIM, from_id)) ) ||
2462 (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) 2489 (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) )
2463 { 2490 {
2464 message = rlv_handler_t::cstrHidden; 2491 message = RlvStrings::getString(RLV_STRING_HIDDEN);
2465 } 2492 }
2466 } 2493 }
2467// [/RLVa:KB] 2494// [/RLVa:KB]
@@ -2945,7 +2972,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
2945 if (CHAT_SOURCE_AGENT == chat.mSourceType) 2972 if (CHAT_SOURCE_AGENT == chat.mSourceType)
2946 { 2973 {
2947 if (chat.mFromID != gAgent.getID()) 2974 if (chat.mFromID != gAgent.getID())
2948 from_name = gRlvHandler.getAnonym(from_name); 2975 from_name = RlvStrings::getAnonym(from_name);
2949 } 2976 }
2950 else 2977 else
2951 { 2978 {
@@ -3045,7 +3072,8 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
3045 verb = " " + LLTrans::getString("whisper") + " "; 3072 verb = " " + LLTrans::getString("whisper") + " ";
3046 break; 3073 break;
3047 case CHAT_TYPE_OWNER: 3074 case CHAT_TYPE_OWNER:
3048// [RLVa:KB] - Checked: 2009-08-28 (RLVa-1.0.2a) | Modified: RLVa-1.0.2a 3075// [RLVa:KB] - Checked: 2009-11-25 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
3076 // TODO-RLVa: [2009-11-25] this could really use some rewriting
3049 if ( (rlv_handler_t::isEnabled()) && (mesg.length() > 3) && (RLV_CMD_PREFIX == mesg[0]) && (CHAT_TYPE_OWNER == chat.mChatType) ) 3077 if ( (rlv_handler_t::isEnabled()) && (mesg.length() > 3) && (RLV_CMD_PREFIX == mesg[0]) && (CHAT_TYPE_OWNER == chat.mChatType) )
3050 { 3078 {
3051 mesg.erase(0, 1); 3079 mesg.erase(0, 1);
@@ -3054,24 +3082,33 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
3054 std::string strExecuted, strFailed, strRetained, *pstr; 3082 std::string strExecuted, strFailed, strRetained, *pstr;
3055 3083
3056 boost_tokenizer tokens(mesg, boost::char_separator<char>(",", "", boost::drop_empty_tokens)); 3084 boost_tokenizer tokens(mesg, boost::char_separator<char>(",", "", boost::drop_empty_tokens));
3057 for (boost_tokenizer::const_iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken) 3085 for (boost_tokenizer::iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken)
3058 { 3086 {
3059 if (LLStartUp::getStartupState() == STATE_STARTED) 3087 std::string strCmd = *itToken;
3088
3089 ERlvCmdRet eRet = gRlvHandler.processCommand(from_id, strCmd, true);
3090 if (RlvSettings::getDebug())
3060 { 3091 {
3061 if (gRlvHandler.processCommand(from_id, *itToken, true)) 3092 if ( RLV_RET_SUCCESS == (eRet & RLV_RET_SUCCESS) )
3062 pstr = &strExecuted; 3093 pstr = &strExecuted;
3094 else if ( RLV_RET_FAILED == (eRet & RLV_RET_FAILED) )
3095 pstr = &strFailed;
3096 else if (RLV_RET_RETAINED == eRet)
3097 pstr = &strRetained;
3063 else 3098 else
3099 {
3100 RLV_ASSERT(false);
3064 pstr = &strFailed; 3101 pstr = &strFailed;
3065 } 3102 }
3066 else
3067 {
3068 gRlvHandler.retainCommand(from_name, from_id, *itToken);
3069 pstr = &strRetained;
3070 }
3071 3103
3072 if (!pstr->empty()) 3104 const char* pstrSuffix = RlvStrings::getStringFromReturnCode(eRet);
3073 pstr->push_back(','); 3105 if (pstrSuffix)
3074 pstr->append(*itToken); 3106 strCmd.append(" (").append(pstrSuffix).append(")");
3107
3108 if (!pstr->empty())
3109 pstr->push_back(',');
3110 pstr->append(strCmd);
3111 }
3075 } 3112 }
3076 3113
3077 if (!RlvSettings::getDebug()) 3114 if (!RlvSettings::getDebug())
@@ -3079,11 +3116,20 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
3079 3116
3080 // Silly people want comprehensive debug messages, blah :p 3117 // Silly people want comprehensive debug messages, blah :p
3081 if ( (!strExecuted.empty()) && (strFailed.empty()) && (strRetained.empty()) ) 3118 if ( (!strExecuted.empty()) && (strFailed.empty()) && (strRetained.empty()) )
3119 {
3082 verb = " executes: @"; 3120 verb = " executes: @";
3121 mesg = strExecuted;
3122 }
3083 else if ( (strExecuted.empty()) && (!strFailed.empty()) && (strRetained.empty()) ) 3123 else if ( (strExecuted.empty()) && (!strFailed.empty()) && (strRetained.empty()) )
3124 {
3084 verb = " failed: @"; 3125 verb = " failed: @";
3126 mesg = strFailed;
3127 }
3085 else if ( (strExecuted.empty()) && (strFailed.empty()) && (!strRetained.empty()) ) 3128 else if ( (strExecuted.empty()) && (strFailed.empty()) && (!strRetained.empty()) )
3129 {
3086 verb = " retained: @"; 3130 verb = " retained: @";
3131 mesg = strRetained;
3132 }
3087 else 3133 else
3088 { 3134 {
3089 verb = ": @"; 3135 verb = ": @";
@@ -3098,9 +3144,9 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
3098 break; 3144 break;
3099 } 3145 }
3100// [/RLVa:KB] 3146// [/RLVa:KB]
3101// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) 3147// [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2009-07-10 (RLVa-1.0.0g)
3102 // Copy/paste from above 3148 // Copy/paste from above
3103 if ( (chatter) && (chat.mChatType != CHAT_TYPE_DEBUG_MSG) ) 3149 if ( (chatter) && (chat.mSourceType == CHAT_SOURCE_OBJECT && chat.mChatType != CHAT_TYPE_DEBUG_MSG) )
3104 { 3150 {
3105 LLPointer<LLViewerPartSourceChat> psc = new LLViewerPartSourceChat(chatter->getPositionAgent()); 3151 LLPointer<LLViewerPartSourceChat> psc = new LLViewerPartSourceChat(chatter->getPositionAgent());
3106 psc->setSourceObject(chatter); 3152 psc->setSourceObject(chatter);
@@ -5361,7 +5407,7 @@ void notify_cautioned_script_question(const LLSD& notification, const LLSD& resp
5361// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) 5407// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a)
5362 if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) 5408 if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) )
5363 { 5409 {
5364 notice.setArg("[REGIONNAME]", rlv_handler_t::cstrHiddenRegion); 5410 notice.setArg("[REGIONNAME]", RlvStrings::getString(RLV_STRING_HIDDEN_REGION));
5365 } 5411 }
5366// [/RLVa:KB] 5412// [/RLVa:KB]
5367 std::string formatpos = llformat("%.1f, %.1f,%.1f", objpos[VX], objpos[VY], objpos[VZ]); 5413 std::string formatpos = llformat("%.1f, %.1f,%.1f", objpos[VX], objpos[VY], objpos[VZ]);
@@ -5588,12 +5634,12 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
5588 LLViewerObject* pObj = gObjectList.findObject(taskid); 5634 LLViewerObject* pObj = gObjectList.findObject(taskid);
5589 if (pObj) 5635 if (pObj)
5590 { 5636 {
5591 if (pObj->permYouOwner()) 5637// if (pObj->permYouOwner())
5592 { 5638// {
5593 // PERMISSION_TAKE_CONTROLS and PERMISSION_ATTACH are only auto-granted to objects this avie owns 5639 // PERMISSION_TAKE_CONTROLS and PERMISSION_ATTACH are only auto-granted to objects this avie owns
5594 rlvQuestionsOther &= ~(LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_TAKE_CONTROLS] | 5640 rlvQuestionsOther &= ~(LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_TAKE_CONTROLS] |
5595 LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_ATTACH]); 5641 LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_ATTACH]);
5596 } 5642// }
5597 } 5643 }
5598 } 5644 }
5599 5645
@@ -5944,7 +5990,7 @@ bool handle_lure_callback(const LLSD& notification, const LLSD& response)
5944 { 5990 {
5945 if (!gRlvHandler.isException(RLV_BHVR_SENDIM, it->asUUID())) 5991 if (!gRlvHandler.isException(RLV_BHVR_SENDIM, it->asUUID()))
5946 { 5992 {
5947 text = rlv_handler_t::cstrHidden; 5993 text = RlvStrings::getString(RLV_STRING_HIDDEN);
5948 break; 5994 break;
5949 } 5995 }
5950 } 5996 }
@@ -5984,7 +6030,8 @@ void handle_lure(LLDynamicArray<LLUUID>& ids)
5984{ 6030{
5985 LLSD edit_args; 6031 LLSD edit_args;
5986// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-04 (RLVa-1.0.0a) 6032// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-04 (RLVa-1.0.0a)
5987 edit_args["REGION"] = (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? gAgent.getRegion()->getName() : rlv_handler_t::cstrHidden; 6033 edit_args["REGION"] =
6034 (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? gAgent.getRegion()->getName() : RlvStrings::getString(RLV_STRING_HIDDEN);
5988// [/RLVa:KB] 6035// [/RLVa:KB]
5989 //edit_args["REGION"] = gAgent.getRegion()->getName(); 6036 //edit_args["REGION"] = gAgent.getRegion()->getName();
5990 6037
diff --git a/linden/indra/newview/llviewerobject.cpp b/linden/indra/newview/llviewerobject.cpp
index cbd0472..1b79cd6 100644
--- a/linden/indra/newview/llviewerobject.cpp
+++ b/linden/indra/newview/llviewerobject.cpp
@@ -98,6 +98,10 @@
98#include "llvowlsky.h" 98#include "llvowlsky.h"
99#include "llmanip.h" 99#include "llmanip.h"
100 100
101// [RLVa:KB]
102#include "rlvhandler.h"
103// [/RLVa:KB]
104
101//#define DEBUG_UPDATE_TYPE 105//#define DEBUG_UPDATE_TYPE
102 106
103BOOL gVelocityInterpolate = TRUE; 107BOOL gVelocityInterpolate = TRUE;
@@ -1616,6 +1620,24 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
1616 gObjectList.killObject(this); 1620 gObjectList.killObject(this);
1617 return retval; 1621 return retval;
1618 } 1622 }
1623// [RLVa:KB] - Checked: 2009-12-27 (RLVa-1.1.0k) | Added: RLVa-1.1.0k
1624 if ( (rlv_handler_t::isEnabled()) && (sent_parentp->isAvatar()) && (sent_parentp->getID() == gAgent.getID()) )
1625 {
1626 // Rezzed object that's being worn as an attachment (we're assuming this will be due to llAttachToAvatar())
1627 S32 idxAttachPt = ATTACHMENT_ID_FROM_STATE(getState());
1628 if (gRlvHandler.isLockedAttachment(idxAttachPt, RLV_LOCK_ANY))
1629 {
1630 // If this will end up on an "add locked" attachment point then treat the attach as a user action
1631 LLNameValue* nvItem = getNVPair("AttachItemID");
1632 if (nvItem)
1633 {
1634 LLUUID idItem(nvItem->getString());
1635 if (idItem.notNull())
1636 gRlvHandler.onWearAttachment(idItem);
1637 }
1638 }
1639 }
1640// [/RLVa:KB]
1619 sent_parentp->addChild(this); 1641 sent_parentp->addChild(this);
1620 // make sure this object gets a non-damped update 1642 // make sure this object gets a non-damped update
1621 if (sent_parentp->mDrawable.notNull()) 1643 if (sent_parentp->mDrawable.notNull())
diff --git a/linden/indra/newview/llviewertexteditor.cpp b/linden/indra/newview/llviewertexteditor.cpp
index 981c9bc..1616b97 100644
--- a/linden/indra/newview/llviewertexteditor.cpp
+++ b/linden/indra/newview/llviewertexteditor.cpp
@@ -63,6 +63,10 @@
63#include "llappviewer.h" // for gPacificDaylightTime 63#include "llappviewer.h" // for gPacificDaylightTime
64#include "viewertime.h" 64#include "viewertime.h"
65 65
66// [RLVa:KB]
67#include "rlvhandler.h"
68// [/RLVa:KB]
69
66static LLRegisterWidget<LLViewerTextEditor> r("text_editor"); 70static LLRegisterWidget<LLViewerTextEditor> r("text_editor");
67 71
68///---------------------------------------------------------------------------- 72///----------------------------------------------------------------------------
@@ -97,9 +101,10 @@ public:
97 } 101 }
98 else 102 else
99 { 103 {
100// [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) 104// [RLVa:KB] - Checked: 2009-11-11 (RLVa-1.1.0a) | Modified: RLVa-1.1.0a
101 if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE)) ) 105 if (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE))
102 { 106 {
107 RlvNotifications::notifyBlockedViewNote();
103 return; 108 return;
104 } 109 }
105// [/RLVa:KB] 110// [/RLVa:KB]
@@ -1388,9 +1393,10 @@ BOOL LLViewerTextEditor::openEmbeddedItem(LLInventoryItem* item, llwchar wc)
1388 1393
1389void LLViewerTextEditor::openEmbeddedTexture( LLInventoryItem* item, llwchar wc ) 1394void LLViewerTextEditor::openEmbeddedTexture( LLInventoryItem* item, llwchar wc )
1390{ 1395{
1391// [RLVa:KB] - Checked: 2009-10-13 (RLVa-1.0.5c) | Added: RLVa-1.0.5c 1396// [RLVa:KB] - Checked: 2009-11-11 (RLVa-1.1.0a) | Modified: RLVa-1.1.0a
1392 if (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWTEXTURE)) 1397 if (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWTEXTURE))
1393 { 1398 {
1399 RlvNotifications::notifyBlockedViewTexture();
1394 return; 1400 return;
1395 } 1401 }
1396// [/RLVa:KB] 1402// [/RLVa:KB]
diff --git a/linden/indra/newview/llviewerwindow.cpp b/linden/indra/newview/llviewerwindow.cpp
index 3a68f0f..401e62d 100644
--- a/linden/indra/newview/llviewerwindow.cpp
+++ b/linden/indra/newview/llviewerwindow.cpp
@@ -187,6 +187,10 @@
187#include "llfloatertest.h" // HACK! 187#include "llfloatertest.h" // HACK!
188#include "llfloaternotificationsconsole.h" 188#include "llfloaternotificationsconsole.h"
189 189
190// [RLVa:KB]
191#include "rlvhandler.h"
192// [/RLVa:KB]
193
190#if LL_WINDOWS 194#if LL_WINDOWS
191#include <tchar.h> // For Unicode conversion methods 195#include <tchar.h> // For Unicode conversion methods
192#endif 196#endif
@@ -3473,17 +3477,41 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
3473 } 3477 }
3474 3478
3475 else // check ALL objects 3479 else // check ALL objects
3476 { 3480 {
3477 found = gPipeline.lineSegmentIntersectInHUD(mouse_hud_start, mouse_hud_end, pick_transparent, 3481 found = gPipeline.lineSegmentIntersectInHUD(mouse_hud_start, mouse_hud_end, pick_transparent,
3478 face_hit, intersection, uv, normal, binormal); 3482 face_hit, intersection, uv, normal, binormal);
3479 3483
3480 if (!found) // if not found in HUD, look in world: 3484// [RLVa:KB] - Checked: 2009-12-28 (RLVa-1.1.0k) | Modified: RLVa-1.1.0k
3485 if ( (rlv_handler_t::isEnabled()) && (LLToolCamera::getInstance()->hasMouseCapture()) && (gKeyboard->currentMask(TRUE) & MASK_ALT) )
3486 {
3487 found = NULL;
3488 }
3489// [/RLVa:KB]
3481 3490
3482 { 3491 if (!found) // if not found in HUD, look in world:
3492 {
3483 found = gPipeline.lineSegmentIntersectInWorld(mouse_world_start, mouse_world_end, pick_transparent, 3493 found = gPipeline.lineSegmentIntersectInWorld(mouse_world_start, mouse_world_end, pick_transparent,
3484 face_hit, intersection, uv, normal, binormal); 3494 face_hit, intersection, uv, normal, binormal);
3485 }
3486 3495
3496// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Added: RLVa-1.1.0l
3497#ifdef RLV_EXTENSION_CMD_INTERACT
3498 if ( (rlv_handler_t::isEnabled()) && (found) && (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT)) )
3499 {
3500 // Allow picking if:
3501 // - the drag-and-drop tool is active (allows inventory offers)
3502 // - the camera tool is active
3503 // - the pie tool is active *and* we picked our own avie (allows "mouse steering" and the self pie menu)
3504 LLTool* pCurTool = LLToolMgr::getInstance()->getCurrentTool();
3505 if ( (LLToolDragAndDrop::getInstance() != pCurTool) &&
3506 (!LLToolCamera::getInstance()->hasMouseCapture()) &&
3507 ((LLToolPie::getInstance() != pCurTool) || (gAgent.getID() != found->getID())) )
3508 {
3509 found = NULL;
3510 }
3511 }
3512#endif // RLV_EXTENSION_CMD_INTERACT
3513// [/RLVa:KB]
3514 }
3487 } 3515 }
3488 3516
3489 return found; 3517 return found;
diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp
index 3be166e..d2aa3d8 100644
--- a/linden/indra/newview/llvoavatar.cpp
+++ b/linden/indra/newview/llvoavatar.cpp
@@ -96,7 +96,7 @@
96#include "hippoLimits.h"// getMaxPrimScale 96#include "hippoLimits.h"// getMaxPrimScale
97 97
98// [RLVa:KB] 98// [RLVa:KB]
99#include "llstartup.h" 99#include "rlvhandler.h"
100// [/RLVa:KB] 100// [/RLVa:KB]
101 101
102using namespace LLVOAvatarDefines; 102using namespace LLVOAvatarDefines;
@@ -3473,10 +3473,10 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
3473 BOOL render_name = visible_chat || 3473 BOOL render_name = visible_chat ||
3474 (visible_avatar && 3474 (visible_avatar &&
3475// [RLVa:KB] - Checked: 2009-08-11 (RLVa-1.0.1h) | Added: RLVa-1.0.0h 3475// [RLVa:KB] - Checked: 2009-08-11 (RLVa-1.0.1h) | Added: RLVa-1.0.0h
3476 ( (!fRlvShowNames) || (RlvSettings::fShowNameTags) ) && 3476 ( (!fRlvShowNames) || (RlvSettings::getShowNameTags()) ) &&
3477// [/RLVa:KB] 3477// [/RLVa:KB]
3478 ((sRenderName == RENDER_NAME_ALWAYS) || 3478 ((sRenderName == RENDER_NAME_ALWAYS) ||
3479 (sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME))); 3479 (sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME)));
3480 // If it's your own avatar, don't draw in mouselook, and don't 3480 // If it's your own avatar, don't draw in mouselook, and don't
3481 // draw if we're specifically hiding our own name. 3481 // draw if we're specifically hiding our own name.
3482 if (mIsSelf) 3482 if (mIsSelf)
@@ -3506,7 +3506,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
3506 } 3506 }
3507 else if (sRenderGroupTitles != mRenderGroupTitles) 3507 else if (sRenderGroupTitles != mRenderGroupTitles)
3508// [/RLVa] 3508// [/RLVa]
3509 //if (sRenderGroupTitles != mRenderGroupTitles) 3509// if (sRenderGroupTitles != mRenderGroupTitles)
3510 { 3510 {
3511 mRenderGroupTitles = sRenderGroupTitles; 3511 mRenderGroupTitles = sRenderGroupTitles;
3512 new_name = TRUE; 3512 new_name = TRUE;
@@ -3662,7 +3662,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
3662 } 3662 }
3663 else 3663 else
3664 { 3664 {
3665 line = gRlvHandler.getAnonym(line.assign(firstname->getString()).append(" ").append(lastname->getString())); 3665 line = RlvStrings::getAnonym(line.assign(firstname->getString()).append(" ").append(lastname->getString()));
3666 } 3666 }
3667// [/RLVa:KB] 3667// [/RLVa:KB]
3668 3668
@@ -6746,14 +6746,6 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object)
6746 gPipeline.markMoved(mDrawable, TRUE); 6746 gPipeline.markMoved(mDrawable, TRUE);
6747 mIsSitting = TRUE; 6747 mIsSitting = TRUE;
6748 LLFloaterAO::ChangeStand(); 6748 LLFloaterAO::ChangeStand();
6749// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.1d
6750 #ifdef RLV_EXTENSION_STARTLOCATION
6751 if (rlv_handler_t::isEnabled())
6752 {
6753 RlvSettings::updateLoginLastLocation();
6754 }
6755 #endif // RLV_EXTENSION_STARTLOCATION
6756// [/RLVa:KB]
6757 mRoot.getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject 6749 mRoot.getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject
6758 mRoot.setPosition(getPosition()); 6750 mRoot.setPosition(getPosition());
6759 mRoot.updateWorldMatrixChildren(); 6751 mRoot.updateWorldMatrixChildren();
@@ -6762,6 +6754,15 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object)
6762 6754
6763 if (mIsSelf) 6755 if (mIsSelf)
6764 { 6756 {
6757// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.1d
6758 #ifdef RLV_EXTENSION_STARTLOCATION
6759 if (rlv_handler_t::isEnabled())
6760 {
6761 RlvSettings::updateLoginLastLocation();
6762 }
6763 #endif // RLV_EXTENSION_STARTLOCATION
6764// [/RLVa:KB]
6765
6765 // Might be first sit 6766 // Might be first sit
6766 LLFirstUse::useSit(); 6767 LLFirstUse::useSit();
6767 6768
@@ -6815,14 +6816,6 @@ void LLVOAvatar::getOffObject()
6815 gPipeline.markMoved(mDrawable, TRUE); 6816 gPipeline.markMoved(mDrawable, TRUE);
6816 6817
6817 mIsSitting = FALSE; 6818 mIsSitting = FALSE;
6818// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.1d
6819 #ifdef RLV_EXTENSION_STARTLOCATION
6820 if (rlv_handler_t::isEnabled())
6821 {
6822 RlvSettings::updateLoginLastLocation();
6823 }
6824 #endif // RLV_EXTENSION_STARTLOCATION
6825// [/RLVa:KB]
6826 mRoot.getXform()->setParent(NULL); // LLVOAvatar::getOffObject 6819 mRoot.getXform()->setParent(NULL); // LLVOAvatar::getOffObject
6827 mRoot.setPosition(cur_position_world); 6820 mRoot.setPosition(cur_position_world);
6828 mRoot.setRotation(cur_rotation_world); 6821 mRoot.setRotation(cur_rotation_world);
@@ -6833,6 +6826,15 @@ void LLVOAvatar::getOffObject()
6833 6826
6834 if (mIsSelf) 6827 if (mIsSelf)
6835 { 6828 {
6829// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.1d
6830 #ifdef RLV_EXTENSION_STARTLOCATION
6831 if (rlv_handler_t::isEnabled())
6832 {
6833 RlvSettings::updateLoginLastLocation();
6834 }
6835 #endif // RLV_EXTENSION_STARTLOCATION
6836// [/RLVa:KB]
6837
6836 LLQuaternion av_rot = gAgent.getFrameAgent().getQuaternion(); 6838 LLQuaternion av_rot = gAgent.getFrameAgent().getQuaternion();
6837 LLQuaternion obj_rot = sit_object ? sit_object->getRenderRotation() : LLQuaternion::DEFAULT; 6839 LLQuaternion obj_rot = sit_object ? sit_object->getRenderRotation() : LLQuaternion::DEFAULT;
6838 av_rot = av_rot * obj_rot; 6840 av_rot = av_rot * obj_rot;
@@ -6908,6 +6910,20 @@ LLViewerObject* LLVOAvatar::getWornAttachment( const LLUUID& inv_item_id )
6908 return NULL; 6910 return NULL;
6909} 6911}
6910 6912
6913// [RLVa:KB] - Checked: 2009-12-18 (RLVa-1.1.0i) | Added: RLVa-1.1.0i
6914LLViewerJointAttachment* LLVOAvatar::getWornAttachmentPoint(const LLUUID& inv_item_id)
6915{
6916 for (attachment_map_t::const_iterator itAttach = mAttachmentPoints.begin();
6917 itAttach != mAttachmentPoints.end(); ++itAttach)
6918 {
6919 LLViewerJointAttachment* pAttachPt = itAttach->second;
6920 if (pAttachPt->getItemID() == inv_item_id)
6921 return pAttachPt;
6922 }
6923 return NULL;
6924}
6925// [/RLVa:KB]
6926
6911const std::string LLVOAvatar::getAttachedPointName(const LLUUID& inv_item_id) 6927const std::string LLVOAvatar::getAttachedPointName(const LLUUID& inv_item_id)
6912{ 6928{
6913 for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); 6929 for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
diff --git a/linden/indra/newview/llvoavatar.h b/linden/indra/newview/llvoavatar.h
index 0c32244..50ce53a 100644
--- a/linden/indra/newview/llvoavatar.h
+++ b/linden/indra/newview/llvoavatar.h
@@ -288,6 +288,9 @@ public:
288 288
289 BOOL isWearingAttachment( const LLUUID& inv_item_id ); 289 BOOL isWearingAttachment( const LLUUID& inv_item_id );
290 LLViewerObject* getWornAttachment( const LLUUID& inv_item_id ); 290 LLViewerObject* getWornAttachment( const LLUUID& inv_item_id );
291// [RLVa:KB] - Checked: 2009-12-18 (RLVa-1.1.0i) | Added: RLVa-1.1.0i
292 LLViewerJointAttachment* getWornAttachmentPoint(const LLUUID& inv_item_id);
293// [/RLVa:KB]
291 const std::string getAttachedPointName(const LLUUID& inv_item_id); 294 const std::string getAttachedPointName(const LLUUID& inv_item_id);
292 295
293 static LLVOAvatar* findAvatarFromAttachment( LLViewerObject* obj ); 296 static LLVOAvatar* findAvatarFromAttachment( LLViewerObject* obj );
diff --git a/linden/indra/newview/llvovolume.cpp b/linden/indra/newview/llvovolume.cpp
index bed3e13..f3b8447 100644
--- a/linden/indra/newview/llvovolume.cpp
+++ b/linden/indra/newview/llvovolume.cpp
@@ -64,6 +64,10 @@
64#include "llselectmgr.h" 64#include "llselectmgr.h"
65#include "pipeline.h" 65#include "pipeline.h"
66 66
67// [RLVa:KB]
68#include "rlvhandler.h"
69// [/RLVa:KB]
70
67const S32 MIN_QUIET_FRAMES_COALESCE = 30; 71const S32 MIN_QUIET_FRAMES_COALESCE = 30;
68const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; 72const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
69const F32 FORCE_CULL_AREA = 8.f; 73const F32 FORCE_CULL_AREA = 8.f;
diff --git a/linden/indra/newview/llworldmapview.cpp b/linden/indra/newview/llworldmapview.cpp
index e12bd08..443ee74 100644
--- a/linden/indra/newview/llworldmapview.cpp
+++ b/linden/indra/newview/llworldmapview.cpp
@@ -64,6 +64,9 @@
64#include "lltexturefetch.h" 64#include "lltexturefetch.h"
65#include "llappviewer.h" // Only for constants! 65#include "llappviewer.h" // Only for constants!
66#include "lltrans.h" 66#include "lltrans.h"
67// [RLVa:KB]
68#include "rlvhandler.h"
69// [/RLVa:KB]
67 70
68#include "llglheaders.h" 71#include "llglheaders.h"
69 72
@@ -696,7 +699,7 @@ void LLWorldMapView::draw()
696// [RLVa:KB] - Alternate: Snowglobe-1.0 | Checked: 2009-07-04 (RLVa-1.0.0a) 699// [RLVa:KB] - Alternate: Snowglobe-1.0 | Checked: 2009-07-04 (RLVa-1.0.0a)
697 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) 700 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))
698 { 701 {
699 mesg = rlv_handler_t::cstrHidden; 702 mesg = RlvStrings::getString(RLV_STRING_HIDDEN);
700 } 703 }
701 else if (info->mAccess == SIM_ACCESS_DOWN) 704 else if (info->mAccess == SIM_ACCESS_DOWN)
702// [/RLVa:KB] 705// [/RLVa:KB]
@@ -1285,7 +1288,7 @@ BOOL LLWorldMapView::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* stic
1285// [RLVa:KB] - Alternate: Snowglobe-1.0 | Checked: 2009-07-04 (RLVa-1.0.0a) 1288// [RLVa:KB] - Alternate: Snowglobe-1.0 | Checked: 2009-07-04 (RLVa-1.0.0a)
1286 std::string message = 1289 std::string message =
1287 llformat("%s (%s)", 1290 llformat("%s (%s)",
1288 (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? info->mName.c_str() : rlv_handler_t::cstrHidden.c_str(), 1291 (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? info->mName.c_str() : RlvStrings::getString(RLV_STRING_HIDDEN).c_str(),
1289 LLViewerRegion::accessToString(info->mAccess).c_str()); 1292 LLViewerRegion::accessToString(info->mAccess).c_str());
1290// [/RLVa:KB] 1293// [/RLVa:KB]
1291 1294
diff --git a/linden/indra/newview/panelradar.cpp b/linden/indra/newview/panelradar.cpp
index ce91da2..8ff5fad 100644
--- a/linden/indra/newview/panelradar.cpp
+++ b/linden/indra/newview/panelradar.cpp
@@ -57,7 +57,9 @@
57#include "llvoavatar.h" 57#include "llvoavatar.h"
58#include "llworld.h" 58#include "llworld.h"
59#include "panelradarentry.h" 59#include "panelradarentry.h"
60 60// [RLVa:KB] - Alternate: Imprudence-1.2.0
61#include "rlvhandler.h"
62// [/RLVa:KB]
61 63
62PanelRadar::PanelRadar() 64PanelRadar::PanelRadar()
63 : 65 :
@@ -303,7 +305,7 @@ void PanelRadar::updateRadarDisplay()
303// [RLVa:KB] - Alternate: Imprudence-1.2.0 305// [RLVa:KB] - Alternate: Imprudence-1.2.0
304 element["columns"][0]["value"] = 306 element["columns"][0]["value"] =
305 (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) 307 (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
306 ? gRlvHandler.getAnonym(entry->getName()) 308 ? RlvStrings::getAnonym(entry->getName())
307 : typing + entry->getName() + " " + mute_text; 309 : typing + entry->getName() + " " + mute_text;
308// [/RLVa:KB] 310// [/RLVa:KB]
309 element["columns"][1]["column"] = "avatar_distance"; 311 element["columns"][1]["column"] = "avatar_distance";
diff --git a/linden/indra/newview/pipeline.cpp b/linden/indra/newview/pipeline.cpp
index 0ca94dc..cf766e0 100644
--- a/linden/indra/newview/pipeline.cpp
+++ b/linden/indra/newview/pipeline.cpp
@@ -102,6 +102,10 @@
102#include "llspatialpartition.h" 102#include "llspatialpartition.h"
103#include "llmutelist.h" 103#include "llmutelist.h"
104 104
105// [RLVa:KB]
106#include "rlvhandler.h"
107// [/RLVa:KB]
108
105#ifdef _DEBUG 109#ifdef _DEBUG
106// Debug indices is disabled for now for debug performance - djs 4/24/02 110// Debug indices is disabled for now for debug performance - djs 4/24/02
107//#define DEBUG_INDICES 111//#define DEBUG_INDICES
diff --git a/linden/indra/newview/rlvdefines.h b/linden/indra/newview/rlvdefines.h
index 21d7105..df67a55 100644
--- a/linden/indra/newview/rlvdefines.h
+++ b/linden/indra/newview/rlvdefines.h
@@ -1,3 +1,19 @@
1/**
2 *
3 * Copyright (c) 2009-2010, Kitty Barnett
4 *
5 * The source code in this file is provided to you under the terms of the
6 * GNU General Public License, version 2.0, but WITHOUT ANY WARRANTY;
7 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
8 * PARTICULAR PURPOSE. Terms of the GPL can be found in doc/GPL-license.txt
9 * in this distribution, or online at http://www.gnu.org/licenses/gpl-2.0.txt
10 *
11 * By copying, modifying or distributing this software, you acknowledge that
12 * you have read and understood your obligations described above, and agree to
13 * abide by those obligations.
14 *
15 */
16
1#ifndef RLV_DEFINES_H 17#ifndef RLV_DEFINES_H
2#define RLV_DEFINES_H 18#define RLV_DEFINES_H
3 19
@@ -10,8 +26,7 @@
10// Comment out if you provide your own way to enable/disable RLVa 26// Comment out if you provide your own way to enable/disable RLVa
11#define RLV_ADVANCED_TOGGLE_RLVA 27#define RLV_ADVANCED_TOGGLE_RLVA
12 28
13// Provides access to "advanced" feature through the RLVa debug menu 29// Provides access to "advanced" features through the RLVa debug menu
14#define RLV_EXTENSION_ENABLE_WEAR // "Enable Wear"
15#define RLV_EXTENSION_FLOATER_RESTRICTIONS // Enables the Advanced / RLVa / Restrictions... floater 30#define RLV_EXTENSION_FLOATER_RESTRICTIONS // Enables the Advanced / RLVa / Restrictions... floater
16#define RLV_EXTENSION_HIDELOCKED // "Hide locked layers", "Hide locked attachments" and "Hide locked inventory" 31#define RLV_EXTENSION_HIDELOCKED // "Hide locked layers", "Hide locked attachments" and "Hide locked inventory"
17 32
@@ -19,41 +34,56 @@
19#define RLV_EXTENSION_CMD_GETSETDEBUG_EX // Extends the debug variables accessible through @getdebug_xxx/@setdebug_xxx 34#define RLV_EXTENSION_CMD_GETSETDEBUG_EX // Extends the debug variables accessible through @getdebug_xxx/@setdebug_xxx
20#define RLV_EXTENSION_CMD_FINDFOLDERS // @findfolders:<option>=<channel> - @findfolder with multiple results 35#define RLV_EXTENSION_CMD_FINDFOLDERS // @findfolders:<option>=<channel> - @findfolder with multiple results
21#define RLV_EXTENSION_FLAG_NOSTRIP // Layers and attachments marked as "nostrip" are exempt from @detach/@remoutfit 36#define RLV_EXTENSION_FLAG_NOSTRIP // Layers and attachments marked as "nostrip" are exempt from @detach/@remoutfit
37#define RLV_EXTENSION_FORCEWEAR_GESTURES // @attach*/detach* commands also (de)activate gestures
38#define RLV_EXTENSION_GIVETORLV_A2A // Allow "Give to #RLV" on avatar-to-avatar inventory offers
39#define RLV_EXTENSION_NOTIFY_BEHAVIOUR // Provides the option to show a customizable notification whenever a behaviour gets (un)set
22#define RLV_EXTENSION_STARTLOCATION // Reenables "Start Location" at login if not @tploc=n or @unsit=n restricted at last logoff 40#define RLV_EXTENSION_STARTLOCATION // Reenables "Start Location" at login if not @tploc=n or @unsit=n restricted at last logoff
23#define RLV_EXPERIMENTAL // Enables/disables experimental features en masse 41#define RLV_EXPERIMENTAL // Enables/disables experimental features en masse
42//#define RLV_EXPERIMENTAL_CMDS // Enables/disables experimental commands en masse
24 43
25// Experimental features 44// Experimental features
26#ifdef RLV_EXPERIMENTAL 45#ifdef RLV_EXPERIMENTAL
27 // Stable (will mature to RLV_EXTENSION_XXX in next release if no bugs are found) 46 // Stable (will mature to RLV_EXTENSION_XXX in next release if no bugs are found)
28 #define RLV_EXPERIMENTAL_FARTOUCH_FEEDBACK // Enables "cleaner" UI responses when fartouch blocks something
29 47
30 // Under testing (stable, but requires further testing - safe for public release but may be quirky) 48 // Under testing (stable, but requires further testing - safe for public release but may be quirky)
31 #define RLV_EXPERIMENTAL_FIRSTUSE // Enables a number of "first use" popups 49 #define RLV_EXPERIMENTAL_COMPOSITEFOLDERS
32 50
33 // Under development (don't include in public release) 51 // Under development (don't include in public release)
34 #if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG 52 #if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG
53 #define RLV_EXPERIMENTAL_FIRSTUSE // Enables a number of "first use" popups
35 #endif // LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG 54 #endif // LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG
36#endif // RLV_EXPERIMENTAL 55#endif // RLV_EXPERIMENTAL
37 56
57// Experimental commands (not part of the RLV API spec, disabled on public releases)
58#ifdef RLV_EXPERIMENTAL_CMDS
59 #define RLV_EXTENSION_CMD_ALLOWIDLE // Forces "Away" status when idle (effect is the same as setting AllowIdleAFK to TRUE)
60 #define RLV_EXTENSION_CMD_GETXXXNAMES // @get[add|rem]attachnames:<option>=<channel> and @get[add|rem]outfitnames=<channel>
61 #define RLV_EXTENSION_CMD_INTERACT // @interact=n
62 #define RLV_EXTENSION_CMD_TOUCHXXX // @touch:uuid=n|y, @touchworld[:<uuid>]=n|y, @touchattach[:<uuid>]=n|y, @touchud[:<uuid>]=n|y
63#endif // RLV_EXPERIMENTAL_CMDS
64
65// Workarounds
66#define RLV_WORKAROUND_REZMULTIPLEATTACH // See http://jira.secondlife.com/browse/SVC-5383 ; disables "Shared Wear"
67
38// ============================================================================ 68// ============================================================================
39// Defines 69// Defines
40// 70//
41 71
42// Version of the specifcation we support 72// Version of the specifcation we support
43const S32 RLV_VERSION_MAJOR = 1; 73const S32 RLV_VERSION_MAJOR = 1;
44const S32 RLV_VERSION_MINOR = 22; 74const S32 RLV_VERSION_MINOR = 23;
45const S32 RLV_VERSION_PATCH = 0; 75const S32 RLV_VERSION_PATCH = 0;
46const S32 RLV_VERSION_BUILD = 0; 76const S32 RLV_VERSION_BUILD = 0;
47 77
48// Implementation version 78// Implementation version
49const S32 RLVa_VERSION_MAJOR = 1; 79const S32 RLVa_VERSION_MAJOR = 1;
50const S32 RLVa_VERSION_MINOR = 0; 80const S32 RLVa_VERSION_MINOR = 1;
51const S32 RLVa_VERSION_PATCH = 5; 81const S32 RLVa_VERSION_PATCH = 2;
52const S32 RLVa_VERSION_BUILD = 4; 82const S32 RLVa_VERSION_BUILD = 1;
53 83
54// The official viewer version we're patching against 84// The official viewer version we're patching against
55#define RLV_MAKE_TARGET(x, y, z) ((x << 16) | (y << 8) | z) 85#define RLV_MAKE_TARGET(x, y, z) ((x << 16) | (y << 8) | z)
56#define RLV_TARGET RLV_MAKE_TARGET(1, 23, 4) 86#define RLV_TARGET RLV_MAKE_TARGET(1, 23, 5)
57 87
58// Defining these makes it easier if we ever need to change our tag 88// Defining these makes it easier if we ever need to change our tag
59#define RLV_WARNS LL_WARNS("RLV") 89#define RLV_WARNS LL_WARNS("RLV")
@@ -92,75 +122,88 @@ const S32 RLVa_VERSION_BUILD = 4;
92// Enumeration declarations 122// Enumeration declarations
93// 123//
94 124
95// NOTE: any changes to this enumeration should be reflected in initLookupTable() 125// NOTE: any changes to this enumeration should be reflected in RlvCommand::initLookupTable()
96enum ERlvBehaviour { 126enum ERlvBehaviour {
97 RLV_BHVR_VERSION = 0, // "version" 127 RLV_BHVR_DETACH = 0, // "detach"
98 RLV_BHVR_DETACH, // "detach" 128 RLV_BHVR_ATTACH, // "attach"
99 RLV_BHVR_SENDCHAT, // "sendchat" 129 RLV_BHVR_ADDATTACH, // "addattach"
130 RLV_BHVR_REMATTACH, // "remattach"
131 RLV_BHVR_ADDOUTFIT, // "addoutfit"
132 RLV_BHVR_REMOUTFIT, // "remoutfit"
100 RLV_BHVR_EMOTE, // "emote" 133 RLV_BHVR_EMOTE, // "emote"
101 RLV_BHVR_CHATSHOUT, // "chatshout" 134 RLV_BHVR_SENDCHAT, // "sendchat"
102 RLV_BHVR_CHATNORMAL, // "chatnormal" 135 RLV_BHVR_RECVCHAT, // "recvchat"
103 RLV_BHVR_CHATWHISPER, // "chatwhisper" 136 RLV_BHVR_RECVEMOTE, // "recvemote"
104 RLV_BHVR_REDIRCHAT, // "redirchat" 137 RLV_BHVR_REDIRCHAT, // "redirchat"
105 RLV_BHVR_REDIREMOTE, // "rediremote" 138 RLV_BHVR_REDIREMOTE, // "rediremote"
139 RLV_BHVR_CHATWHISPER, // "chatwhisper"
140 RLV_BHVR_CHATNORMAL, // "chatnormal"
141 RLV_BHVR_CHATSHOUT, // "chatshout"
142 RLV_BHVR_SENDCHANNEL, // "sendchannel"
106 RLV_BHVR_SENDIM, // "sendim" 143 RLV_BHVR_SENDIM, // "sendim"
107 RLV_BHVR_RECVCHAT, // "recvchat"
108 RLV_BHVR_RECVEMOTE, // "recvemote"
109 RLV_BHVR_RECVIM, // "recvim" 144 RLV_BHVR_RECVIM, // "recvim"
145 RLV_BHVR_PERMISSIVE, // "permissive"
146 RLV_BHVR_NOTIFY, // "notify"
147 RLV_BHVR_SHOWINV, // "showinv"
148 RLV_BHVR_SHOWMINIMAP, // "showminimap"
149 RLV_BHVR_SHOWWORLDMAP, // "showworldmap"
150 RLV_BHVR_SHOWLOC, // "showloc"
151 RLV_BHVR_SHOWNAMES, // "shownames"
152 RLV_BHVR_SHOWHOVERTEXT, // "showhovertext"
153 RLV_BHVR_SHOWHOVERTEXTHUD, // "showhovertexthud"
154 RLV_BHVR_SHOWHOVERTEXTWORLD, // "showhovertextworld"
155 RLV_BHVR_SHOWHOVERTEXTALL, // "showhovertextall"
110 RLV_BHVR_TPLM, // "tplm" 156 RLV_BHVR_TPLM, // "tplm"
111 RLV_BHVR_TPLOC, // "tploc" 157 RLV_BHVR_TPLOC, // "tploc"
112 RLV_BHVR_TPLURE, // "tplure" 158 RLV_BHVR_TPLURE, // "tplure"
113 RLV_BHVR_SITTP, // "sittp" 159 RLV_BHVR_VIEWNOTE, // "viewnote"
160 RLV_BHVR_VIEWSCRIPT, // "viewscript"
161 RLV_BHVR_VIEWTEXTURE, // "viewtexture"
162 RLV_BHVR_ACCEPTPERMISSION, // "acceptpermission"
163 RLV_BHVR_ACCEPTTP, // "accepttp"
164 RLV_BHVR_DEFAULTWEAR, // "defaultwear"
165 RLV_BHVR_ALLOWIDLE, // "allowidle"
114 RLV_BHVR_EDIT, // "edit" 166 RLV_BHVR_EDIT, // "edit"
115 RLV_BHVR_REZ, // "rez" 167 RLV_BHVR_REZ, // "rez"
116 RLV_BHVR_ADDOUTFIT, // "addoutfit" 168 RLV_BHVR_FARTOUCH, // "fartouch"
117 RLV_BHVR_REMOUTFIT, // "remoutfit" 169 RLV_BHVR_INTERACT, // "interact"
118 RLV_BHVR_GETOUTFIT, // "getoutfit" 170 RLV_BHVR_TOUCH, // "touch"
119 RLV_BHVR_ADDATTACH, // "addattach" 171 RLV_BHVR_TOUCHATTACH, // "touchattach"
120 RLV_BHVR_REMATTACH, // "remattach" 172 RLV_BHVR_TOUCHHUD, // "touchhud"
121 RLV_BHVR_GETATTACH, // "getattach" 173 RLV_BHVR_TOUCHWORLD, // "touchworld"
122 RLV_BHVR_SHOWINV, // "showinv" 174 RLV_BHVR_FLY, // "fly"
123 RLV_BHVR_VIEWNOTE, // "viewnote"
124 RLV_BHVR_UNSIT, // "unsit" 175 RLV_BHVR_UNSIT, // "unsit"
125 RLV_BHVR_SIT, // "sit" 176 RLV_BHVR_SIT, // "sit"
126 RLV_BHVR_SENDCHANNEL, // "sendchannel" 177 RLV_BHVR_SITTP, // "sittp"
127 RLV_BHVR_GETSTATUS, // "getstatus" 178 RLV_BHVR_SETDEBUG, // "setdebug"
128 RLV_BHVR_GETSTATUSALL, // "getstatusall" 179 RLV_BHVR_SETENV, // "setenv"
129 RLV_BHVR_GETINV, // "getinv" 180 RLV_BHVR_DETACHME, // "detachme"
130 RLV_BHVR_GETINVWORN, // "getinvworn" 181 RLV_BHVR_DETACHTHIS, // "detachthis"
131 RLV_BHVR_FINDFOLDER, // "findfolder"
132 RLV_BHVR_FINDFOLDERS, // "findfolders"
133 RLV_BHVR_ATTACH, // "attach"
134 RLV_BHVR_ATTACHALL, // "attachall"
135 RLV_BHVR_DETACHALL, // "detachall" 182 RLV_BHVR_DETACHALL, // "detachall"
136 RLV_BHVR_GETPATH, // "getpath" 183 RLV_BHVR_DETACHALLTHIS, // "detachallthis"
137 RLV_BHVR_ATTACHTHIS, // "attachthis" 184 RLV_BHVR_ATTACHTHIS, // "attachthis"
185 RLV_BHVR_ATTACHALL, // "attachall"
138 RLV_BHVR_ATTACHALLTHIS, // "attachallthis" 186 RLV_BHVR_ATTACHALLTHIS, // "attachallthis"
139 RLV_BHVR_DETACHTHIS, // "detachthis"
140 RLV_BHVR_DETACHALLTHIS, // "detachallthis"
141 RLV_BHVR_FARTOUCH, // "fartouch"
142 RLV_BHVR_SHOWWORLDMAP, // "showworldmap"
143 RLV_BHVR_SHOWMINIMAP, // "showminimap"
144 RLV_BHVR_SHOWLOC, // "showloc"
145 RLV_BHVR_TPTO, // "tpto" 187 RLV_BHVR_TPTO, // "tpto"
146 RLV_BHVR_ACCEPTTP, // "accepttp" 188 RLV_BHVR_VERSION, // "version"
147 RLV_BHVR_ACCEPTPERMISSION, // "acceptpermission" 189 RLV_BHVR_VERSIONNEW, // "versionnew"
148 RLV_BHVR_SHOWNAMES, // "shownames"
149 RLV_BHVR_FLY, // "fly"
150 RLV_BHVR_GETSITID, // "getsitid"
151 RLV_BHVR_SETDEBUG, // "setdebug"
152 RLV_BHVR_SETENV, // "setenv"
153 RLV_BHVR_DETACHME, // "detachme"
154 RLV_BHVR_SHOWHOVERTEXTALL, // "showhovertextall"
155 RLV_BHVR_SHOWHOVERTEXTWORLD, // "showhovertextworld"
156 RLV_BHVR_SHOWHOVERTEXTHUD, // "showhovertexthud"
157 RLV_BHVR_SHOWHOVERTEXT, // "showhovertext"
158 RLV_BHVR_NOTIFY, // "notify"
159 RLV_BHVR_DEFAULTWEAR, // "defaultwear"
160 RLV_BHVR_VERSIONNUM, // "versionnum" 190 RLV_BHVR_VERSIONNUM, // "versionnum"
161 RLV_BHVR_PERMISSIVE, // "permissive" 191 RLV_BHVR_GETATTACH, // "getattach"
162 RLV_BHVR_VIEWSCRIPT, // "viewscript" 192 RLV_BHVR_GETATTACHNAMES, // "getattachnames"
163 RLV_BHVR_VIEWTEXTURE, // "viewtexture" 193 RLV_BHVR_GETADDATTACHNAMES, // "getaddattachnames"
194 RLV_BHVR_GETREMATTACHNAMES, // "getremattachnames"
195 RLV_BHVR_GETOUTFIT, // "getoutfit"
196 RLV_BHVR_GETOUTFITNAMES, // "getoutfitnames"
197 RLV_BHVR_GETADDOUTFITNAMES, // "getaddoutfitnames"
198 RLV_BHVR_GETREMOUTFITNAMES, // "getremoutfitnames"
199 RLV_BHVR_FINDFOLDER, // "findfolder"
200 RLV_BHVR_FINDFOLDERS, // "findfolders"
201 RLV_BHVR_GETPATH, // "getpath"
202 RLV_BHVR_GETINV, // "getinv"
203 RLV_BHVR_GETINVWORN, // "getinvworn"
204 RLV_BHVR_GETSITID, // "getsitid"
205 RLV_BHVR_GETSTATUS, // "getstatus"
206 RLV_BHVR_GETSTATUSALL, // "getstatusall"
164 207
165 RLV_BHVR_COUNT, 208 RLV_BHVR_COUNT,
166 RLV_BHVR_UNKNOWN 209 RLV_BHVR_UNKNOWN
@@ -176,16 +219,19 @@ enum ERlvParamType {
176}; 219};
177 220
178enum ERlvCmdRet { 221enum ERlvCmdRet {
179 RLV_RET_NOERROR, // Command executed succesfully 222 RLV_RET_UNKNOWN = 0x0000, // Unknown error (should only be used internally)
180 RLV_RET_RETAINED, // Command was retained 223 RLV_RET_RETAINED, // Command was retained
181 RLV_RET_DISABLED, // Command is disabled (by user) 224 RLV_RET_SUCCESS = 0x0100, // Command executed succesfully
182 RLV_RET_FAILED, // Command failed (general failure) 225 RLV_RET_SUCCESS_UNSET, // Command executed succesfully (RLV_TYPE_REMOVE for an unrestricted behaviour)
226 RLV_RET_SUCCESS_DUPLICATE, // Command executed succesfully (RLV_TYPE_ADD for an already restricted behaviour)
227 RLV_RET_FAILED = 0x0200, // Command failed (general failure)
183 RLV_RET_FAILED_SYNTAX, // Command failed (syntax error) 228 RLV_RET_FAILED_SYNTAX, // Command failed (syntax error)
184 RLV_RET_FAILED_UNSET, // Command failed (unset restriction)
185 RLV_RET_FAILED_DUPLICATE, // Command failed (duplicate)
186 RLV_RET_FAILED_OPTION, // Command failed (invalid option) 229 RLV_RET_FAILED_OPTION, // Command failed (invalid option)
187 RLV_RET_FAILED_PARAM, // Command failed (invalid param) 230 RLV_RET_FAILED_PARAM, // Command failed (invalid param)
188 RLV_RET_UNKNOWN // Command unkown 231 RLV_RET_FAILED_LOCK, // Command failed (command is locked by another object)
232 RLV_RET_FAILED_DISABLED, // Command failed (command disabled by user)
233 RLV_RET_FAILED_UNKNOWN, // Command failed (unknown command)
234 RLV_RET_FAILED_NOSHAREDROOT, // Command failed (missing #RLV)
189}; 235};
190 236
191enum ERlvExceptionCheck { 237enum ERlvExceptionCheck {
@@ -200,20 +246,35 @@ enum ERlvLockMask {
200 RLV_LOCK_ANY = RLV_LOCK_ADD | RLV_LOCK_REMOVE 246 RLV_LOCK_ANY = RLV_LOCK_ADD | RLV_LOCK_REMOVE
201}; 247};
202 248
249enum ERlvAttachGroupType
250{
251 RLV_ATTACHGROUP_HEAD = 0,
252 RLV_ATTACHGROUP_TORSO,
253 RLV_ATTACHGROUP_ARMS,
254 RLV_ATTACHGROUP_LEGS,
255 RLV_ATTACHGROUP_HUD,
256 RLV_ATTACHGROUP_COUNT,
257 RLV_ATTACHGROUP_INVALID
258};
259
203// ============================================================================ 260// ============================================================================
204// Settings 261// Settings
262//
205 263
206#define RLV_SETTING_MAIN "RestrainedLife" 264#define RLV_SETTING_MAIN "RestrainedLove"
207#define RLV_SETTING_DEBUG "RestrainedLifeDebug" 265#define RLV_SETTING_DEBUG "RestrainedLoveDebug"
208#define RLV_SETTING_NOSETENV "RestrainedLifeNoSetEnv" 266#define RLV_SETTING_NOSETENV "RestrainedLoveNoSetEnv"
209#define RLV_SETTING_FORBIDGIVETORLV "RestrainedLifeForbidGiveToRLV" 267#define RLV_SETTING_FORBIDGIVETORLV "RestrainedLoveForbidGiveToRLV"
210 268
211#define RLV_SETTING_ENABLEWEAR "RLVaEnableWear" 269#define RLV_SETTING_ENABLECOMPOSITES "RLVaEnableCompositeFolders"
212#define RLV_SETTING_ENABLELEGACYNAMING "RLVaEnableLegacyNaming" 270#define RLV_SETTING_ENABLELEGACYNAMING "RLVaEnableLegacyNaming"
271#define RLV_SETTING_ENABLEWEAR "RLVaEnableWear"
272#define RLV_SETTING_ENABLESHAREDWEAR "RLVaEnableSharedWear"
213#define RLV_SETTING_HIDELOCKEDLAYER "RLVaHideLockedLayers" 273#define RLV_SETTING_HIDELOCKEDLAYER "RLVaHideLockedLayers"
214#define RLV_SETTING_HIDELOCKEDATTACH "RLVaHideLockedAttachments" 274#define RLV_SETTING_HIDELOCKEDATTACH "RLVaHideLockedAttachments"
215#define RLV_SETTING_HIDELOCKEDINVENTORY "RLVaHideLockedInventory" 275#define RLV_SETTING_HIDELOCKEDINVENTORY "RLVaHideLockedInventory"
216#define RLV_SETTING_LOGINLASTLOCATION "RLVaLoginLastLocation" 276#define RLV_SETTING_LOGINLASTLOCATION "RLVaLoginLastLocation"
277#define RLV_SETTING_SHAREDINVAUTORENAME "RLVaSharedInvAutoRename"
217#define RLV_SETTING_SHOWNAMETAGS "RLVaShowNameTags" 278#define RLV_SETTING_SHOWNAMETAGS "RLVaShowNameTags"
218 279
219#define RLV_SETTING_FIRSTUSE_PREFIX "FirstRLV" 280#define RLV_SETTING_FIRSTUSE_PREFIX "FirstRLV"
@@ -223,5 +284,19 @@ enum ERlvLockMask {
223#define RLV_SETTING_FIRSTUSE_GIVETORLV RLV_SETTING_FIRSTUSE_PREFIX"GiveToRLV" 284#define RLV_SETTING_FIRSTUSE_GIVETORLV RLV_SETTING_FIRSTUSE_PREFIX"GiveToRLV"
224 285
225// ============================================================================ 286// ============================================================================
287// Strings
288//
289
290#define RLV_STRING_HIDDEN "hidden_generic"
291#define RLV_STRING_HIDDEN_PARCEL "hidden_parcel"
292#define RLV_STRING_HIDDEN_REGION "hidden_region"
293
294#define RLV_STRING_BLOCKED_RECVIM "blocked_recvim"
295#define RLV_STRING_BLOCKED_RECVIM_REMOTE "blocked_recvim_remote"
296#define RLV_STRING_BLOCKED_SENDIM "blocked_sendim"
297#define RLV_STRING_BLOCKED_VIEWXXX "blocked_viewxxx"
298#define RLV_STRING_BLOCKED_TPLURE_REMOTE "blocked_tplure_remote"
299
300// ============================================================================
226 301
227#endif // RLV_DEFINES_H 302#endif // RLV_DEFINES_H
diff --git a/linden/indra/newview/rlvevent.h b/linden/indra/newview/rlvevent.h
deleted file mode 100644
index a98996f..0000000
--- a/linden/indra/newview/rlvevent.h
+++ /dev/null
@@ -1,227 +0,0 @@
1#ifndef RLV_EVENTEMITTER_H
2#define RLV_EVENTEMITTER_H
3
4#include <algorithm>
5#include <typeinfo>
6#include <list>
7
8#include "lluuid.h"
9
10#include "rlvhelper.h"
11
12// ============================================================================
13// RlvEvent - Passed to observer event handlers (contains the same paramaters as RlvHandler::processXXXCommand)
14//
15
16class RlvEvent
17{
18public:
19 RlvEvent(const LLUUID& uuid, const RlvCommand& rlvCmd) : m_UUID(uuid), m_rlvCmd(rlvCmd) {}
20 virtual ~RlvEvent() {}
21
22 const LLUUID& getSenderID() const { return m_UUID; };
23 const RlvCommand& getCommand() const { return m_rlvCmd; };
24
25protected:
26 LLUUID m_UUID;
27 RlvCommand m_rlvCmd;
28};
29
30// ============================================================================
31/*
32 * RlvObserver
33 * ===========
34 * Provides a way to extend the existing command set without changing the main RlvHandler class
35 *
36 * Steps:
37 * - derive your class from RlvObserver
38 * - override any of the event functions you need
39 * - add it as an observer: gRlvHandler.addObserver(new RlbObserverDerivedClass());
40 * - done
41 *
42 * Notes:
43 * - as long as you don't call gRlvHandler.remObserver() your class will be cleaned up from
44 * RlvEventEmitter destructor (see below)
45 * - event handlers are called only if RlvHandler didn't handle it so while you can
46 * add a new command @foobar=n, you won't get called for @detach=n
47 * - event handlers are called *after* the command is added so a call to
48 * RlvHandler::hasBehaviour("foobar") would return TRUE
49 * - return TRUE if you handled the command (won't get passed on to the next observer)
50 * return FALSE if you didn't handle the command (gets passed on to the next observer)
51 *
52 */
53
54class RlvObserver
55{
56public:
57 virtual ~RlvObserver() {}
58
59 typedef RlvEvent EventType;
60
61 virtual BOOL onAddCommand(const EventType& rlvEvent) { return FALSE; }
62 virtual BOOL onRemoveCommand(const EventType& rlvEvent) { return FALSE; }
63 virtual BOOL onClearCommand(const EventType& rlvEvent) { return FALSE; }
64 virtual BOOL onReplyCommand(const EventType& rlvEvent) { return FALSE; }
65 virtual BOOL onForceCommand(const EventType& rlvEvent) { return FALSE; }
66};
67
68// ============================================================================
69/*
70 * RlvEventEmitter
71 * ===============
72 * Essentially a slightly modified eventEmitter (see lleventemitter.h)
73 *
74 * Changes:
75 * - if an event handler returns TRUE then no further observers are notified
76 * - cleans up the (remaining) observers in the destructor
77 */
78
79template < class T >
80class RlvEventEmitter
81{
82 public:
83 typedef typename T::EventType EventType;
84 typedef std::list< T* > ObserverContainer;
85 typedef BOOL ( T::*observerMethod )( const EventType& );
86
87 protected:
88 ObserverContainer observers;
89
90 public:
91 RlvEventEmitter() { };
92
93 ~RlvEventEmitter()
94 {
95 clearObservers();
96 }
97
98 BOOL addObserver ( T* observerIn )
99 {
100 if ( ! observerIn )
101 return FALSE;
102
103 // check if observer already exists
104 if ( std::find ( observers.begin (), observers.end (), observerIn ) != observers.end () )
105 return FALSE;
106
107 // save it
108 observers.push_back ( observerIn );
109
110 return true;
111 }
112
113 BOOL remObserver ( T* observerIn )
114 {
115 if ( ! observerIn )
116 return FALSE;
117
118 observers.remove ( observerIn );
119
120 return TRUE;
121 }
122
123 void clearObservers()
124 {
125 typename std::list< T* >::iterator iter = observers.begin ();
126
127 while (iter != observers.end ())
128 {
129 delete *iter;
130 ++iter;
131 };
132
133 observers.clear();
134 }
135
136 BOOL update ( observerMethod method, const EventType& msgIn )
137 {
138 typename std::list< T* >::iterator iter = observers.begin ();
139
140 BOOL fContinue = TRUE;
141 while ( (iter != observers.end ()) && (fContinue) )
142 {
143 fContinue = !( ( ( *iter )->*method ) ( msgIn ) );
144 ++iter;
145 };
146
147 return !fContinue;
148 }
149};
150
151// ============================================================================
152
153class RlvBehaviourObserver
154{
155public:
156 virtual ~RlvBehaviourObserver() {}
157 virtual void changed(const RlvCommand& rlvCmd, bool fInternal) = 0;
158};
159
160// ============================================================================
161
162class RlvBehaviourNotifyObserver : public RlvBehaviourObserver
163{
164public:
165 virtual ~RlvBehaviourNotifyObserver() { }
166
167 void changed(const RlvCommand& rlvCmd, bool fInternal)
168 {
169 if (fInternal)
170 return;
171
172 std::string strCmd = rlvCmd.asString(), strNotify; ERlvParamType eCmdType = rlvCmd.getParamType();
173 if ( (RLV_TYPE_ADD == eCmdType) || (RLV_TYPE_REMOVE == eCmdType) )
174 strNotify = llformat("/%s=%s", strCmd.c_str(), rlvCmd.getParam().c_str());
175 else if (RLV_TYPE_CLEAR == eCmdType)
176 strNotify = llformat("/%s", strCmd.c_str());
177 else
178 return;
179
180 for (std::multimap<LLUUID, notifyData>::const_iterator itNotify = m_Notifications.begin();
181 itNotify != m_Notifications.end(); ++itNotify)
182 {
183 if ( (itNotify->second.strFilter.empty()) || (std::string::npos != strCmd.find(itNotify->second.strFilter)) )
184 rlvSendChatReply(itNotify->second.nChannel, strNotify);
185 }
186 }
187
188 void addNotify(const LLUUID& idObj, S32 nChannel, const std::string& strFilter)
189 {
190 m_Notifications.insert(std::pair<LLUUID, notifyData>(idObj, notifyData(nChannel, strFilter)));
191 }
192
193 void clearNotify(const LLUUID& idObj)
194 {
195 m_Notifications.erase(idObj);
196 }
197
198 bool hasNotify()
199 {
200 return (m_Notifications.size() != 0);
201 }
202
203 void removeNotify(const LLUUID& idObj, S32 nChannel, const std::string& strFilter)
204 {
205 for (std::multimap<LLUUID, notifyData>::iterator itNotify = m_Notifications.lower_bound(idObj),
206 endNotify = m_Notifications.upper_bound(idObj); itNotify != endNotify; ++itNotify)
207 {
208 if ( (itNotify->second.nChannel == nChannel) && (itNotify->second.strFilter == strFilter) )
209 {
210 m_Notifications.erase(itNotify);
211 break;
212 }
213 }
214 }
215protected:
216 struct notifyData
217 {
218 S32 nChannel;
219 std::string strFilter;
220 notifyData(S32 channel, const std::string& filter) : nChannel(channel), strFilter(filter) {}
221 };
222 std::multimap<LLUUID, notifyData> m_Notifications;
223};
224
225// ============================================================================
226
227#endif // RLV_EVENTEMITTER_H
diff --git a/linden/indra/newview/rlvextensions.cpp b/linden/indra/newview/rlvextensions.cpp
index f31c62e..c20c077 100644
--- a/linden/indra/newview/rlvextensions.cpp
+++ b/linden/indra/newview/rlvextensions.cpp
@@ -1,3 +1,19 @@
1/**
2 *
3 * Copyright (c) 2009-2010, Kitty Barnett
4 *
5 * The source code in this file is provided to you under the terms of the
6 * GNU General Public License, version 2.0, but WITHOUT ANY WARRANTY;
7 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
8 * PARTICULAR PURPOSE. Terms of the GPL can be found in doc/GPL-license.txt
9 * in this distribution, or online at http://www.gnu.org/licenses/gpl-2.0.txt
10 *
11 * By copying, modifying or distributing this software, you acknowledge that
12 * you have read and understood your obligations described above, and agree to
13 * abide by those obligations.
14 *
15 */
16
1#include "llviewerprecompiledheaders.h" 17#include "llviewerprecompiledheaders.h"
2#include "llagent.h" 18#include "llagent.h"
3#include "llfloaterwindlight.h" 19#include "llfloaterwindlight.h"
@@ -38,19 +54,19 @@ RlvExtGetSet::RlvExtGetSet()
38} 54}
39 55
40// Checked: 2009-05-17 (RLVa-0.2.0a) 56// Checked: 2009-05-17 (RLVa-0.2.0a)
41BOOL RlvExtGetSet::onForceCommand(const RlvEvent& rlvEvent) 57bool RlvExtGetSet::onForceCommand(const LLUUID& idObj, const RlvCommand& rlvCmd, ERlvCmdRet& cmdRet)
42{ 58{
43 return processCommand(rlvEvent.getSenderID(), rlvEvent.getCommand()); 59 return processCommand(idObj, rlvCmd, cmdRet);
44} 60}
45 61
46// Checked: 2009-05-17 (RLVa-0.2.0a) 62// Checked: 2009-05-17 (RLVa-0.2.0a)
47BOOL RlvExtGetSet::onReplyCommand(const EventType& rlvEvent) 63bool RlvExtGetSet::onReplyCommand(const LLUUID& idObj, const RlvCommand& rlvCmd, ERlvCmdRet& cmdRet)
48{ 64{
49 return processCommand(rlvEvent.getSenderID(), rlvEvent.getCommand()); 65 return processCommand(idObj, rlvCmd, cmdRet);
50} 66}
51 67
52// Checked: 2009-06-18 (RLVa-0.2.1d) | Modified: RLVa-0.2.1d 68// Checked: 2009-12-23 (RLVa-1.1.0k) | Modified: RLVa-1.1.0k
53BOOL RlvExtGetSet::processCommand(const LLUUID& idObj, const RlvCommand& rlvCmd) 69bool RlvExtGetSet::processCommand(const LLUUID& idObj, const RlvCommand& rlvCmd, ERlvCmdRet& eRet)
54{ 70{
55 std::string strBehaviour = rlvCmd.getBehaviour(), strGetSet, strSetting; 71 std::string strBehaviour = rlvCmd.getBehaviour(), strGetSet, strSetting;
56 int idxSetting = strBehaviour.find('_'); 72 int idxSetting = strBehaviour.find('_');
@@ -67,13 +83,14 @@ BOOL RlvExtGetSet::processCommand(const LLUUID& idObj, const RlvCommand& rlvCmd)
67 if ( ("get" == strGetSet) && (RLV_TYPE_REPLY == rlvCmd.getParamType()) ) 83 if ( ("get" == strGetSet) && (RLV_TYPE_REPLY == rlvCmd.getParamType()) )
68 { 84 {
69 rlvSendChatReply(rlvCmd.getParam(), onGetDebug(strSetting)); 85 rlvSendChatReply(rlvCmd.getParam(), onGetDebug(strSetting));
70 return TRUE; 86 eRet = RLV_RET_SUCCESS;
87 return true;
71 } 88 }
72 else if ( ("set" == strGetSet) && (RLV_TYPE_FORCE == rlvCmd.getParamType()) ) 89 else if ( ("set" == strGetSet) && (RLV_TYPE_FORCE == rlvCmd.getParamType()) )
73 { 90 {
74 if (!gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETDEBUG, idObj)) 91 if (!gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETDEBUG, idObj))
75 onSetDebug(strSetting, rlvCmd.getOption()); 92 eRet = onSetDebug(strSetting, rlvCmd.getOption());
76 return TRUE; 93 return true;
77 } 94 }
78 } 95 }
79 else if ("env" == strBehaviour) 96 else if ("env" == strBehaviour)
@@ -81,13 +98,14 @@ BOOL RlvExtGetSet::processCommand(const LLUUID& idObj, const RlvCommand& rlvCmd)
81 if ( ("get" == strGetSet) && (RLV_TYPE_REPLY == rlvCmd.getParamType()) ) 98 if ( ("get" == strGetSet) && (RLV_TYPE_REPLY == rlvCmd.getParamType()) )
82 { 99 {
83 rlvSendChatReply(rlvCmd.getParam(), onGetEnv(strSetting)); 100 rlvSendChatReply(rlvCmd.getParam(), onGetEnv(strSetting));
84 return TRUE; 101 eRet = RLV_RET_SUCCESS;
102 return true;
85 } 103 }
86 else if ( ("set" == strGetSet) && (RLV_TYPE_FORCE == rlvCmd.getParamType()) ) 104 else if ( ("set" == strGetSet) && (RLV_TYPE_FORCE == rlvCmd.getParamType()) )
87 { 105 {
88 if (!gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETENV, idObj)) 106 if (!gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETENV, idObj))
89 onSetEnv(strSetting, rlvCmd.getOption()); 107 eRet = onSetEnv(strSetting, rlvCmd.getOption());
90 return TRUE; 108 return true;
91 } 109 }
92 } 110 }
93 } 111 }
@@ -97,7 +115,7 @@ BOOL RlvExtGetSet::processCommand(const LLUUID& idObj, const RlvCommand& rlvCmd)
97 F32 nAngle = 0.0f; 115 F32 nAngle = 0.0f;
98 if (LLStringUtil::convertToF32(rlvCmd.getOption(), nAngle)) 116 if (LLStringUtil::convertToF32(rlvCmd.getOption(), nAngle))
99 { 117 {
100 nAngle += RLV_SETROT_OFFSET; 118 nAngle = RLV_SETROT_OFFSET - nAngle;
101 119
102 gAgent.startCameraAnimation(); 120 gAgent.startCameraAnimation();
103 121
@@ -106,10 +124,13 @@ BOOL RlvExtGetSet::processCommand(const LLUUID& idObj, const RlvCommand& rlvCmd)
106 at.normalize(); 124 at.normalize();
107 gAgent.resetAxes(at); 125 gAgent.resetAxes(at);
108 126
109 return TRUE; 127 eRet = RLV_RET_SUCCESS;
110 } 128 }
129 else
130 eRet = RLV_RET_FAILED_OPTION;
131 return true;
111 } 132 }
112 return FALSE; 133 return false;
113} 134}
114 135
115// Checked: 2009-06-03 (RLVa-0.2.0h) | Modified: RLVa-0.2.0h 136// Checked: 2009-06-03 (RLVa-0.2.0h) | Modified: RLVa-0.2.0h
@@ -117,6 +138,10 @@ bool RlvExtGetSet::findDebugSetting(std::string& strSetting, S16& flags)
117{ 138{
118 LLStringUtil::toLower(strSetting); // Convenience for non-RLV calls 139 LLStringUtil::toLower(strSetting); // Convenience for non-RLV calls
119 140
141 // HACK-RLVa: bad code but it's just a temporary measure to provide a smooth changeover from the old to the new rebranded settings
142 if ( (strSetting.length() >= 14) && (0 == strSetting.find("restrainedlife")) )
143 strSetting = "restrainedlove" + strSetting.substr(14);
144
120 std::string strTemp; 145 std::string strTemp;
121 for (std::map<std::string, S16>::const_iterator itSetting = m_DbgAllowed.begin(); itSetting != m_DbgAllowed.end(); ++itSetting) 146 for (std::map<std::string, S16>::const_iterator itSetting = m_DbgAllowed.begin(); itSetting != m_DbgAllowed.end(); ++itSetting)
122 { 147 {
@@ -194,11 +219,12 @@ std::string RlvExtGetSet::onGetPseudoDebug(const std::string& strSetting)
194} 219}
195 220
196// Checked: 2009-10-10 (RLVa-1.0.4e) | Modified: RLVa-1.0.4e 221// Checked: 2009-10-10 (RLVa-1.0.4e) | Modified: RLVa-1.0.4e
197void RlvExtGetSet::onSetDebug(std::string strSetting, const std::string& strValue) 222ERlvCmdRet RlvExtGetSet::onSetDebug(std::string strSetting, const std::string& strValue)
198{ 223{
199 S16 dbgFlags; 224 S16 dbgFlags; ERlvCmdRet eRet = RLV_RET_FAILED_UNKNOWN;
200 if ( (findDebugSetting(strSetting, dbgFlags)) && ((dbgFlags & DBG_WRITE) == DBG_WRITE) ) 225 if ( (findDebugSetting(strSetting, dbgFlags)) && ((dbgFlags & DBG_WRITE) == DBG_WRITE) )
201 { 226 {
227 eRet = RLV_RET_FAILED_OPTION;
202 if ((dbgFlags & DBG_PSEUDO) == 0) 228 if ((dbgFlags & DBG_PSEUDO) == 0)
203 { 229 {
204 LLControlVariable* pSetting = gSavedSettings.getControl(strSetting); 230 LLControlVariable* pSetting = gSavedSettings.getControl(strSetting);
@@ -209,18 +235,28 @@ void RlvExtGetSet::onSetDebug(std::string strSetting, const std::string& strValu
209 { 235 {
210 case TYPE_U32: 236 case TYPE_U32:
211 if (LLStringUtil::convertToU32(strValue, u32Value)) 237 if (LLStringUtil::convertToU32(strValue, u32Value))
238 {
212 gSavedSettings.setU32(strSetting, u32Value); 239 gSavedSettings.setU32(strSetting, u32Value);
240 eRet = RLV_RET_SUCCESS;
241 }
213 break; 242 break;
214 case TYPE_S32: 243 case TYPE_S32:
215 if (LLStringUtil::convertToS32(strValue, s32Value)) 244 if (LLStringUtil::convertToS32(strValue, s32Value))
245 {
216 gSavedSettings.setS32(strSetting, s32Value); 246 gSavedSettings.setS32(strSetting, s32Value);
247 eRet = RLV_RET_SUCCESS;
248 }
217 break; 249 break;
218 case TYPE_BOOLEAN: 250 case TYPE_BOOLEAN:
219 if (LLStringUtil::convertToBOOL(strValue, fValue)) 251 if (LLStringUtil::convertToBOOL(strValue, fValue))
252 {
220 gSavedSettings.setBOOL(strSetting, fValue); 253 gSavedSettings.setBOOL(strSetting, fValue);
254 eRet = RLV_RET_SUCCESS;
255 }
221 break; 256 break;
222 default: 257 default:
223 RLV_ERRS << "Unexpected debug setting type" << LL_ENDL; 258 RLV_ERRS << "Unexpected debug setting type" << LL_ENDL;
259 eRet = RLV_RET_FAILED;
224 break; 260 break;
225 } 261 }
226 262
@@ -230,20 +266,26 @@ void RlvExtGetSet::onSetDebug(std::string strSetting, const std::string& strValu
230 } 266 }
231 else 267 else
232 { 268 {
233 onSetPseudoDebug(strSetting, strValue); 269 eRet = onSetPseudoDebug(strSetting, strValue);
234 } 270 }
235 } 271 }
272 return eRet;
236} 273}
237 274
238// Checked: 2009-10-10 (RLVa-1.0.4e) | Modified: RLVa-1.0.4e 275// Checked: 2009-10-10 (RLVa-1.0.4e) | Modified: RLVa-1.0.4e
239void RlvExtGetSet::onSetPseudoDebug(const std::string& strSetting, const std::string& strValue) 276ERlvCmdRet RlvExtGetSet::onSetPseudoDebug(const std::string& strSetting, const std::string& strValue)
240{ 277{
278 ERlvCmdRet eRet = RLV_RET_FAILED_OPTION;
241 if ("AvatarSex" == strSetting) 279 if ("AvatarSex" == strSetting)
242 { 280 {
243 BOOL fValue; 281 BOOL fValue;
244 if (LLStringUtil::convertToBOOL(strValue, fValue)) 282 if (LLStringUtil::convertToBOOL(strValue, fValue))
283 {
245 m_PseudoDebug[strSetting] = strValue; 284 m_PseudoDebug[strSetting] = strValue;
285 eRet = RLV_RET_SUCCESS;
286 }
246 } 287 }
288 return eRet;
247} 289}
248 290
249// Checked: 2009-09-16 (RLVa-1.0.3c) | Modified: RLVa-1.0.3c 291// Checked: 2009-09-16 (RLVa-1.0.3c) | Modified: RLVa-1.0.3c
@@ -322,7 +364,7 @@ std::string RlvExtGetSet::onGetEnv(std::string strSetting)
322} 364}
323 365
324// Checked: 2009-09-16 (RLVa-1.0.3c) | Modified: RLVa-1.0.3c 366// Checked: 2009-09-16 (RLVa-1.0.3c) | Modified: RLVa-1.0.3c
325void RlvExtGetSet::onSetEnv(std::string strSetting, const std::string& strValue) 367ERlvCmdRet RlvExtGetSet::onSetEnv(std::string strSetting, const std::string& strValue)
326{ 368{
327 // HACK: see RlvExtGetSet::onGetEnv 369 // HACK: see RlvExtGetSet::onGetEnv
328 if (!LLFloaterWindLight::isOpen()) 370 if (!LLFloaterWindLight::isOpen())
@@ -337,8 +379,8 @@ void RlvExtGetSet::onSetEnv(std::string strSetting, const std::string& strValue)
337 379
338 F32 nValue = 0.0f; 380 F32 nValue = 0.0f;
339 // Sanity check - make sure strValue specifies a number for all settings except "preset" 381 // Sanity check - make sure strValue specifies a number for all settings except "preset"
340 if ( (rlv_handler_t::fNoSetEnv) || ( (!LLStringUtil::convertToF32(strValue, nValue)) && ("preset" != strSetting) )) 382 if ( (RlvSettings::getNoSetEnv()) || ( (!LLStringUtil::convertToF32(strValue, nValue)) && ("preset" != strSetting) ))
341 return; 383 return RLV_RET_FAILED_OPTION;
342 384
343 // Not quite correct, but RLV-1.16.0 will halt the default daytime cycle on invalid commands so we need to as well 385 // Not quite correct, but RLV-1.16.0 will halt the default daytime cycle on invalid commands so we need to as well
344 pWLParams->mAnimator.mIsRunning = false; 386 pWLParams->mAnimator.mIsRunning = false;
@@ -357,19 +399,19 @@ void RlvExtGetSet::onSetEnv(std::string strSetting, const std::string& strValue)
357 pWLParams->mAnimator.mIsRunning = true; 399 pWLParams->mAnimator.mIsRunning = true;
358 pWLParams->mAnimator.mUseLindenTime = true; 400 pWLParams->mAnimator.mUseLindenTime = true;
359 } 401 }
360 return; 402 return RLV_RET_SUCCESS;
361 } 403 }
362 // See LLFloaterWindLight::onChangePresetName() 404 // See LLFloaterWindLight::onChangePresetName()
363 else if ("preset" == strSetting) 405 else if ("preset" == strSetting)
364 { 406 {
365 pWLParams->loadPreset(strValue, true); 407 pWLParams->loadPreset(strValue, true);
366 return; 408 return RLV_RET_SUCCESS;
367 } 409 }
368 // See LLFloaterWindLight::onStarAlphaMoved 410 // See LLFloaterWindLight::onStarAlphaMoved
369 else if ("starbrightness" == strSetting) 411 else if ("starbrightness" == strSetting)
370 { 412 {
371 pWLParams->mCurParams.setStarBrightness(nValue); 413 pWLParams->mCurParams.setStarBrightness(nValue);
372 return; 414 return RLV_RET_SUCCESS;
373 } 415 }
374 // See LLFloaterWindLight::onGlowRMoved() / LLFloaterWindLight::onGlowBMoved() 416 // See LLFloaterWindLight::onGlowRMoved() / LLFloaterWindLight::onGlowBMoved()
375 else if ( ("sunglowfocus" == strSetting) || ("sunglowsize" == strSetting) ) 417 else if ( ("sunglowfocus" == strSetting) || ("sunglowsize" == strSetting) )
@@ -382,7 +424,7 @@ void RlvExtGetSet::onSetEnv(std::string strSetting, const std::string& strValue)
382 424
383 pColour->update(pWLParams->mCurParams); 425 pColour->update(pWLParams->mCurParams);
384 pWLParams->propagateParameters(); 426 pWLParams->propagateParameters();
385 return; 427 return RLV_RET_SUCCESS;
386 } 428 }
387 // See LLFloaterWindLight::onSunMoved() 429 // See LLFloaterWindLight::onSunMoved()
388 else if ( ("eastangle" == strSetting) || ("sunmoonposition" == strSetting) ) 430 else if ( ("eastangle" == strSetting) || ("sunmoonposition" == strSetting) )
@@ -401,18 +443,18 @@ void RlvExtGetSet::onSetEnv(std::string strSetting, const std::string& strValue)
401 443
402 pColour->update(pWLParams->mCurParams); 444 pColour->update(pWLParams->mCurParams);
403 pWLParams->propagateParameters(); 445 pWLParams->propagateParameters();
404 return; 446 return RLV_RET_SUCCESS;
405 } 447 }
406 // See LLFloaterWindLight::onCloudScrollXMoved() / LLFloaterWindLight::onCloudScrollYMoved() 448 // See LLFloaterWindLight::onCloudScrollXMoved() / LLFloaterWindLight::onCloudScrollYMoved()
407 else if ("cloudscrollx" == strSetting) 449 else if ("cloudscrollx" == strSetting)
408 { 450 {
409 pWLParams->mCurParams.setCloudScrollX(nValue + 10.0f); 451 pWLParams->mCurParams.setCloudScrollX(nValue + 10.0f);
410 return; 452 return RLV_RET_SUCCESS;
411 } 453 }
412 else if ("cloudscrolly" == strSetting) 454 else if ("cloudscrolly" == strSetting)
413 { 455 {
414 pWLParams->mCurParams.setCloudScrollY(nValue + 10.0f); 456 pWLParams->mCurParams.setCloudScrollY(nValue + 10.0f);
415 return; 457 return RLV_RET_SUCCESS;
416 } 458 }
417 // See LLFloaterWindLight::onFloatControlMoved() 459 // See LLFloaterWindLight::onFloatControlMoved()
418 else if ("cloudcoverage" == strSetting) pFloat = &pWLParams->mCloudCoverage; 460 else if ("cloudcoverage" == strSetting) pFloat = &pWLParams->mCloudCoverage;
@@ -430,14 +472,14 @@ void RlvExtGetSet::onSetEnv(std::string strSetting, const std::string& strValue)
430 pFloat->x = nValue / pFloat->mult; 472 pFloat->x = nValue / pFloat->mult;
431 pFloat->update(pWLParams->mCurParams); 473 pFloat->update(pWLParams->mCurParams);
432 pWLParams->propagateParameters(); 474 pWLParams->propagateParameters();
433 return; 475 return RLV_RET_SUCCESS;
434 } 476 }
435 else if (pColour) 477 else if (pColour)
436 { 478 {
437 pColour->r = nValue; 479 pColour->r = nValue;
438 pColour->update(pWLParams->mCurParams); 480 pColour->update(pWLParams->mCurParams);
439 pWLParams->propagateParameters(); 481 pWLParams->propagateParameters();
440 return; 482 return RLV_RET_SUCCESS;
441 } 483 }
442 484
443 // RGBI settings 485 // RGBI settings
@@ -466,7 +508,7 @@ void RlvExtGetSet::onSetEnv(std::string strSetting, const std::string& strValue)
466 if ('i' == ch) // (See: LLFloaterWindLight::onColorControlIMoved) 508 if ('i' == ch) // (See: LLFloaterWindLight::onColorControlIMoved)
467 { 509 {
468 if (!pColour->hasSliderName) 510 if (!pColour->hasSliderName)
469 return; 511 return RLV_RET_FAILED_UNKNOWN;
470 512
471 F32 curMax = llmax(pColour->r, pColour->g, pColour->b); 513 F32 curMax = llmax(pColour->r, pColour->g, pColour->b);
472 if ( (0.0f == nValue) || (0.0f == curMax) ) 514 if ( (0.0f == nValue) || (0.0f == curMax) )
@@ -490,8 +532,11 @@ void RlvExtGetSet::onSetEnv(std::string strSetting, const std::string& strValue)
490 532
491 pColour->update(pWLParams->mCurParams); 533 pColour->update(pWLParams->mCurParams);
492 pWLParams->propagateParameters(); 534 pWLParams->propagateParameters();
535
536 return RLV_RET_SUCCESS;
493 } 537 }
494 } 538 }
539 return RLV_RET_FAILED_UNKNOWN;
495} 540}
496 541
497// ============================================================================ 542// ============================================================================
diff --git a/linden/indra/newview/rlvextensions.h b/linden/indra/newview/rlvextensions.h
index 5720ba0..3e3e75e 100644
--- a/linden/indra/newview/rlvextensions.h
+++ b/linden/indra/newview/rlvextensions.h
@@ -1,8 +1,23 @@
1/**
2 *
3 * Copyright (c) 2009-2010, Kitty Barnett
4 *
5 * The source code in this file is provided to you under the terms of the
6 * GNU General Public License, version 2.0, but WITHOUT ANY WARRANTY;
7 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
8 * PARTICULAR PURPOSE. Terms of the GPL can be found in doc/GPL-license.txt
9 * in this distribution, or online at http://www.gnu.org/licenses/gpl-2.0.txt
10 *
11 * By copying, modifying or distributing this software, you acknowledge that
12 * you have read and understood your obligations described above, and agree to
13 * abide by those obligations.
14 *
15 */
16
1#ifndef RLV_EXTENSIONS_H 17#ifndef RLV_EXTENSIONS_H
2#define RLV_EXTENSIONS_H 18#define RLV_EXTENSIONS_H
3 19
4#include "rlvhelper.h" 20#include "rlvcommon.h"
5#include "rlvevent.h"
6 21
7// ============================================================================ 22// ============================================================================
8/* 23/*
@@ -12,24 +27,24 @@
12 * 27 *
13 */ 28 */
14 29
15class RlvExtGetSet : public RlvObserver 30class RlvExtGetSet : public RlvCommandHandler
16{ 31{
17public: 32public:
18 RlvExtGetSet(); 33 RlvExtGetSet();
19 virtual ~RlvExtGetSet() {} 34 virtual ~RlvExtGetSet() {}
20 35
21 virtual BOOL onForceCommand(const RlvEvent& rlvEvent); 36 virtual bool onForceCommand(const LLUUID& idObj, const RlvCommand& rlvCmd, ERlvCmdRet& cmdRet);
22 virtual BOOL onReplyCommand(const RlvEvent& rlvEvent); 37 virtual bool onReplyCommand(const LLUUID& idObj, const RlvCommand& rlvCmd, ERlvCmdRet& cmdRet);
23protected: 38protected:
24 std::string onGetDebug(std::string strSetting); 39 std::string onGetDebug(std::string strSetting);
25 std::string onGetPseudoDebug(const std::string& strSetting); 40 std::string onGetPseudoDebug(const std::string& strSetting);
26 void onSetDebug(std::string strSetting, const std::string& strValue); 41 ERlvCmdRet onSetDebug(std::string strSetting, const std::string& strValue);
27 void onSetPseudoDebug(const std::string& strSetting, const std::string& strValue); 42 ERlvCmdRet onSetPseudoDebug(const std::string& strSetting, const std::string& strValue);
28 43
29 std::string onGetEnv(std::string strSetting); 44 std::string onGetEnv(std::string strSetting);
30 void onSetEnv(std::string strSetting, const std::string& strValue); 45 ERlvCmdRet onSetEnv(std::string strSetting, const std::string& strValue);
31 46
32 BOOL processCommand(const LLUUID& idObj, const RlvCommand& rlvCmd); 47 bool processCommand(const LLUUID& idObj, const RlvCommand& rlvCmd, ERlvCmdRet& eRet);
33 48
34public: 49public:
35 enum { DBG_READ = 0x01, DBG_WRITE = 0x02, DBG_PERSIST = 0x04, DBG_PSEUDO = 0x08 }; 50 enum { DBG_READ = 0x01, DBG_WRITE = 0x02, DBG_PERSIST = 0x04, DBG_PSEUDO = 0x08 };
diff --git a/linden/indra/newview/rlvfloaterbehaviour.cpp b/linden/indra/newview/rlvfloaterbehaviour.cpp
index 39fcf12..d34a511 100644
--- a/linden/indra/newview/rlvfloaterbehaviour.cpp
+++ b/linden/indra/newview/rlvfloaterbehaviour.cpp
@@ -1,3 +1,19 @@
1/**
2 *
3 * Copyright (c) 2009-2010, Kitty Barnett
4 *
5 * The source code in this file is provided to you under the terms of the
6 * GNU General Public License, version 2.0, but WITHOUT ANY WARRANTY;
7 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
8 * PARTICULAR PURPOSE. Terms of the GPL can be found in doc/GPL-license.txt
9 * in this distribution, or online at http://www.gnu.org/licenses/gpl-2.0.txt
10 *
11 * By copying, modifying or distributing this software, you acknowledge that
12 * you have read and understood your obligations described above, and agree to
13 * abide by those obligations.
14 *
15 */
16
1#include "llviewerprecompiledheaders.h" 17#include "llviewerprecompiledheaders.h"
2 18
3#include "llagent.h" 19#include "llagent.h"
@@ -9,6 +25,7 @@
9#include "llvoavatar.h" 25#include "llvoavatar.h"
10 26
11#include "rlvfloaterbehaviour.h" 27#include "rlvfloaterbehaviour.h"
28#include "rlvhandler.h"
12 29
13// ============================================================================ 30// ============================================================================
14 31
diff --git a/linden/indra/newview/rlvfloaterbehaviour.h b/linden/indra/newview/rlvfloaterbehaviour.h
index 1410dd5..8cbc94c 100644
--- a/linden/indra/newview/rlvfloaterbehaviour.h
+++ b/linden/indra/newview/rlvfloaterbehaviour.h
@@ -1,8 +1,24 @@
1/**
2 *
3 * Copyright (c) 2009-2010, Kitty Barnett
4 *
5 * The source code in this file is provided to you under the terms of the
6 * GNU General Public License, version 2.0, but WITHOUT ANY WARRANTY;
7 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
8 * PARTICULAR PURPOSE. Terms of the GPL can be found in doc/GPL-license.txt
9 * in this distribution, or online at http://www.gnu.org/licenses/gpl-2.0.txt
10 *
11 * By copying, modifying or distributing this software, you acknowledge that
12 * you have read and understood your obligations described above, and agree to
13 * abide by those obligations.
14 *
15 */
16
1#ifndef RLV_FLOATER_BEHAVIOUR 17#ifndef RLV_FLOATER_BEHAVIOUR
2#define RLV_FLOATER_BEHAVIOUR 18#define RLV_FLOATER_BEHAVIOUR
3 19
4#include "llfloater.h" 20#include "llfloater.h"
5#include "rlvevent.h" 21#include "rlvcommon.h"
6 22
7// ============================================================================ 23// ============================================================================
8 24
diff --git a/linden/indra/newview/rlvhandler.cpp b/linden/indra/newview/rlvhandler.cpp
index 18c0836..43a5ba3 100644
--- a/linden/indra/newview/rlvhandler.cpp
+++ b/linden/indra/newview/rlvhandler.cpp
@@ -1,12 +1,26 @@
1/**
2 *
3 * Copyright (c) 2009-2010, Kitty Barnett
4 *
5 * The source code in this file is provided to you under the terms of the
6 * GNU General Public License, version 2.0, but WITHOUT ANY WARRANTY;
7 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
8 * PARTICULAR PURPOSE. Terms of the GPL can be found in doc/GPL-license.txt
9 * in this distribution, or online at http://www.gnu.org/licenses/gpl-2.0.txt
10 *
11 * By copying, modifying or distributing this software, you acknowledge that
12 * you have read and understood your obligations described above, and agree to
13 * abide by those obligations.
14 *
15 */
16
1#include "llviewerprecompiledheaders.h" 17#include "llviewerprecompiledheaders.h"
2#include "llagent.h" 18#include "llcallbacklist.h"
3#include "lldrawpoolalpha.h" 19#include "lldrawpoolalpha.h"
4#include "llfirstuse.h"
5#include "llfloaterbeacons.h" 20#include "llfloaterbeacons.h"
6#include "llfloaterchat.h" 21#include "llfloaterchat.h"
7#include "llfloaterdaycycle.h" 22#include "llfloaterdaycycle.h"
8#include "llfloaterenvsettings.h" 23#include "llfloaterenvsettings.h"
9#include "llfloatergodtools.h"
10#include "llfloaterland.h" 24#include "llfloaterland.h"
11#include "llfloatermap.h" 25#include "llfloatermap.h"
12#include "llfloaterregioninfo.h" 26#include "llfloaterregioninfo.h"
@@ -14,22 +28,19 @@
14#include "llfloaterwater.h" 28#include "llfloaterwater.h"
15#include "llfloaterwindlight.h" 29#include "llfloaterwindlight.h"
16#include "llfloaterworldmap.h" 30#include "llfloaterworldmap.h"
17#include "llgesturemgr.h"
18#include "llinventoryview.h" 31#include "llinventoryview.h"
19#include "llstartup.h" 32#include "llstartup.h"
20#include "llviewermenu.h" 33#include "llviewermenu.h"
21#include "llviewermessage.h" 34#include "llviewermessage.h"
35#include "llviewerobjectlist.h"
22#include "llviewerparcelmgr.h" 36#include "llviewerparcelmgr.h"
23#include "llviewerregion.h" 37#include "llviewerregion.h"
24#include "llviewerwindow.h" 38#include "llviewerwindow.h"
25#include "llvoavatar.h"
26#include "llworld.h" 39#include "llworld.h"
27#include "pipeline.h" 40#include "pipeline.h"
28 41
29#include "rlvhelper.h"
30#include "rlvevent.h"
31#include "rlvextensions.h"
32#include "rlvhandler.h" 42#include "rlvhandler.h"
43#include "rlvextensions.h"
33 44
34// Only defined in llinventorybridge.cpp 45// Only defined in llinventorybridge.cpp
35#if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 46#if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11
@@ -43,46 +54,51 @@ extern const char* NEW_CATEGORY_NAME;
43// 54//
44 55
45BOOL RlvHandler::m_fEnabled = FALSE; 56BOOL RlvHandler::m_fEnabled = FALSE;
46BOOL RlvHandler::fNoSetEnv = FALSE; 57bool RlvHandler::m_fFetchStarted = false;
47BOOL RlvHandler::fLegacyNaming = FALSE; 58bool RlvHandler::m_fFetchComplete = false;
48BOOL RlvHandler::m_fFetchStarted = FALSE;
49BOOL RlvHandler::m_fFetchComplete = FALSE;
50RlvMultiStringSearch RlvHandler::m_AttachLookup; 59RlvMultiStringSearch RlvHandler::m_AttachLookup;
51
52const std::string RlvHandler::cstrSharedRoot = RLV_ROOT_FOLDER; 60const std::string RlvHandler::cstrSharedRoot = RLV_ROOT_FOLDER;
53 61
54// Keep these consistent with regular RLV
55const std::string RlvHandler::cstrBlockedRecvIM = "*** IM blocked by your viewer";
56const std::string RlvHandler::cstrBlockedSendIM = "*** IM blocked by sender's viewer";
57const std::string RlvHandler::cstrHidden = "(Hidden)";
58const std::string RlvHandler::cstrHiddenParcel = "(Hidden parcel)";
59const std::string RlvHandler::cstrHiddenRegion = "(Hidden region)";
60const std::string RlvHandler::cstrMsgRecvIM =
61 "The Resident you messaged is prevented from reading your instant messages at the moment, please try again later.";
62const std::string RlvHandler::cstrMsgTpLure =
63 "The Resident you invited is prevented from accepting teleport offers. Please try again later.";
64
65const std::string RlvHandler::cstrAnonyms[] =
66{
67 "A resident", "This resident", "That resident", "An individual", "This individual", "That individual", "A person",
68 "This person", "That person", "A stranger", "This stranger", "That stranger", "A being", "This being",
69 "That being", "An agent", "This agent", "That agent", "A soul", "This soul", "That soul", "Somebody",
70 "Some people", "Someone", "Mysterious one", "An unknown being", "Unidentified one", "An unknown person"
71};
72
73rlv_handler_t gRlvHandler; 62rlv_handler_t gRlvHandler;
74 63
75// ============================================================================ 64// ============================================================================
76// Helper functions 65// Attachment group helper functions
77// 66//
78 67
79// Checked: 2009-07-12 (RLVa-1.0.0h) | Added: RLVa-0.2.0e 68// Has to match the order of ERlvAttachGroupType
80inline bool rlvIsWearingItem(const LLInventoryItem* pItem) 69const std::string cstrAttachGroups[RLV_ATTACHGROUP_COUNT] = { "head", "torso", "arms", "legs", "hud" };
70
71// Checked: 2009-10-19 (RLVa-1.1.0e) | Added: RLVa-1.1.0e
72inline ERlvAttachGroupType rlvGetAttachGroupTypeFromIndex(S32 idxGroup)
81{ 73{
82 return 74 switch (idxGroup)
83 ((LLAssetType::AT_OBJECT == pItem->getType()) && (gAgent.getAvatarObject()->isWearingAttachment(pItem->getUUID()))) || 75 {
84 ((LLAssetType::AT_GESTURE == pItem->getType()) && (gGestureManager.isGestureActive(pItem->getUUID()))) || 76 case 0: // Right Hand
85 (gAgent.isWearingItem(pItem->getUUID())); 77 case 1: // Right Arm
78 case 3: // Left Arm
79 case 4: // Left Hand
80 return RLV_ATTACHGROUP_ARMS;
81 case 2: // Head
82 return RLV_ATTACHGROUP_HEAD;
83 case 5: // Left Leg
84 case 7: // Right Leg
85 return RLV_ATTACHGROUP_LEGS;
86 case 6: // Torso
87 return RLV_ATTACHGROUP_TORSO;
88 case 8: // HUD
89 return RLV_ATTACHGROUP_HUD;
90 default:
91 return RLV_ATTACHGROUP_INVALID;
92 }
93}
94
95// Checked: 2009-10-19 (RLVa-1.1.0e) | Added: RLVa-1.1.0e
96inline ERlvAttachGroupType rlvGetAttachGroupTypeFromString(const std::string& strGroup)
97{
98 for (int idx = 0; idx < RLV_ATTACHGROUP_COUNT; idx++)
99 if (cstrAttachGroups[idx] == strGroup)
100 return (ERlvAttachGroupType)idx;
101 return RLV_ATTACHGROUP_INVALID;
86} 102}
87 103
88// ============================================================================ 104// ============================================================================
@@ -116,7 +132,7 @@ static bool rlvParseNotifyOption(const std::string& strOption, S32& nChannel, st
116 132
117// Checked: 2009-08-04 (RLVa-1.0.1d) | Modified: RLVa-1.0.1d 133// Checked: 2009-08-04 (RLVa-1.0.1d) | Modified: RLVa-1.0.1d
118RlvHandler::RlvHandler() 134RlvHandler::RlvHandler()
119 : m_fCanCancelTp(true), m_idCurObject(LLUUID::null), m_pCurCommand(NULL), m_pGCTimer(NULL), m_pWLSnapshot(NULL), m_pBhvrNotify(NULL) 135 : m_fCanCancelTp(true), m_pGCTimer(NULL), m_pWLSnapshot(NULL), m_pBhvrNotify(NULL)
120{ 136{
121 // Array auto-initialization to 0 is non-standard? (Compiler warning in VC-8.0) 137 // Array auto-initialization to 0 is non-standard? (Compiler warning in VC-8.0)
122 memset(m_LayersAdd, 0, sizeof(S16) * WT_COUNT); 138 memset(m_LayersAdd, 0, sizeof(S16) * WT_COUNT);
@@ -137,38 +153,30 @@ RlvHandler::~RlvHandler()
137// Attachment related functions 153// Attachment related functions
138// 154//
139 155
140// Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0d
141inline LLViewerJointAttachment* RlvHandler::getAttachPoint(const std::string& strText, bool fExact) const
142{
143 LLVOAvatar* pAvatar = gAgent.getAvatarObject();
144 return (pAvatar) ? get_if_there(pAvatar->mAttachmentPoints, getAttachPointIndex(strText, fExact), (LLViewerJointAttachment*)NULL)
145 : NULL;
146}
147
148// Checked: 2009-07-29 (RLVa-1.0.1b) | Modified: RLVa-1.0.1b 156// Checked: 2009-07-29 (RLVa-1.0.1b) | Modified: RLVa-1.0.1b
149LLViewerJointAttachment* RlvHandler::getAttachPoint(const LLInventoryCategory* pFolder, bool /*fStrict*/) const 157S32 RlvHandler::getAttachPointIndex(const LLInventoryCategory* pFolder, bool /*fStrict*/) const
150{ 158{
151 if (!pFolder) 159 if (!pFolder)
152 return NULL; 160 return 0;
153 161
154 // RLVa-1.0.1 added support for legacy matching (See http://rlva.catznip.com/blog/2009/07/attachment-point-naming-convention/) 162 // RLVa-1.0.1 added support for legacy matching (See http://rlva.catznip.com/blog/2009/07/attachment-point-naming-convention/)
155 if (fLegacyNaming) 163 if (RlvSettings::getEnableLegacyNaming())
156 return getAttachPointLegacy(pFolder); 164 return getAttachPointIndexLegacy(pFolder);
157 165
158 // Otherwise the only valid way to specify an attachment point in a folder name is: ^\.\(\s+attachpt\s+\) 166 // Otherwise the only valid way to specify an attachment point in a folder name is: ^\.\(\s+attachpt\s+\)
159 std::string::size_type idxMatch; 167 std::string::size_type idxMatch;
160 std::string strAttachPt = rlvGetFirstParenthesisedText(pFolder->getName(), &idxMatch); 168 std::string strAttachPt = rlvGetFirstParenthesisedText(pFolder->getName(), &idxMatch);
161 LLStringUtil::trim(strAttachPt); 169 LLStringUtil::trim(strAttachPt);
162 170
163 return ( (1 == idxMatch) && (RLV_FOLDER_PREFIX_HIDDEN == pFolder->getName().at(0)) ) ? getAttachPoint(strAttachPt, true) : NULL; 171 return ( (1 == idxMatch) && (RLV_FOLDER_PREFIX_HIDDEN == pFolder->getName().at(0)) ) ? getAttachPointIndex(strAttachPt, true) : 0;
164} 172}
165 173
166// Checked: 2009-07-29 (RLVa-1.0.1b) | Modified: RLVa-1.0.1b 174// Checked: 2009-07-29 (RLVa-1.0.1b) | Modified: RLVa-1.0.1b
167LLViewerJointAttachment* RlvHandler::getAttachPoint(const LLInventoryItem* pItem, bool fStrict) const 175S32 RlvHandler::getAttachPointIndex(const LLInventoryItem* pItem, bool fStrict) const
168{ 176{
169 // Sanity check - if it's not an object then it can't have an attachment point 177 // Sanity check - if it's not an object then it can't have an attachment point
170 if ( (!pItem) || (LLAssetType::AT_OBJECT != pItem->getType()) ) 178 if ( (!pItem) || (LLAssetType::AT_OBJECT != pItem->getType()) )
171 return NULL; 179 return 0;
172 180
173 // The attachment point should be placed at the end of the item's name, surrounded by parenthesis 181 // The attachment point should be placed at the end of the item's name, surrounded by parenthesis
174 // (if there is no such text then strAttachPt will be an empty string which is fine since it means we'll look at the item's parent) 182 // (if there is no such text then strAttachPt will be an empty string which is fine since it means we'll look at the item's parent)
@@ -177,20 +185,20 @@ LLViewerJointAttachment* RlvHandler::getAttachPoint(const LLInventoryItem* pItem
177 185
178 // If the item is modify : we look at the item's name first and only then at the containing folder 186 // If the item is modify : we look at the item's name first and only then at the containing folder
179 // If the item is no modify: we look at the containing folder's name first and only then at the item itself 187 // If the item is no modify: we look at the containing folder's name first and only then at the item itself
180 LLViewerJointAttachment* pAttachPt; 188 S32 idxAttachPt = 0;
181 if (pItem->getPermissions().allowModifyBy(gAgent.getID())) 189 if (pItem->getPermissions().allowModifyBy(gAgent.getID()))
182 { 190 {
183 pAttachPt = (!strAttachPt.empty()) ? getAttachPoint(strAttachPt, true) : NULL; 191 idxAttachPt = (!strAttachPt.empty()) ? getAttachPointIndex(strAttachPt, true) : 0;
184 if (!pAttachPt) 192 if (!idxAttachPt)
185 pAttachPt = getAttachPoint(gInventory.getCategory(pItem->getParentUUID()), fStrict); 193 idxAttachPt = getAttachPointIndex(gInventory.getCategory(pItem->getParentUUID()), fStrict);
186 } 194 }
187 else 195 else
188 { 196 {
189 pAttachPt = getAttachPoint(gInventory.getCategory(pItem->getParentUUID()), fStrict); 197 idxAttachPt = getAttachPointIndex(gInventory.getCategory(pItem->getParentUUID()), fStrict);
190 if ( (!pAttachPt) && (!strAttachPt.empty()) ) 198 if ( (!idxAttachPt) && (!strAttachPt.empty()) )
191 pAttachPt = getAttachPoint(strAttachPt, true); 199 idxAttachPt = getAttachPointIndex(strAttachPt, true);
192 } 200 }
193 return pAttachPt; 201 return idxAttachPt;
194} 202}
195 203
196// Checked: 2009-07-12 (RLVa-1.0.0h) | Added: RLVa-0.2.2a 204// Checked: 2009-07-12 (RLVa-1.0.0h) | Added: RLVa-0.2.2a
@@ -210,11 +218,11 @@ S32 RlvHandler::getAttachPointIndex(const LLViewerJointAttachment* pAttachPt) co
210} 218}
211 219
212// Checked: 2009-07-29 (RLVa-1.0.1b) | Added: RLVa-1.0.1b 220// Checked: 2009-07-29 (RLVa-1.0.1b) | Added: RLVa-1.0.1b
213LLViewerJointAttachment* RlvHandler::getAttachPointLegacy(const LLInventoryCategory* pFolder) const 221S32 RlvHandler::getAttachPointIndexLegacy(const LLInventoryCategory* pFolder) const
214{ 222{
215 // Hopefully some day this can just be deprecated (see http://rlva.catznip.com/blog/2009/07/attachment-point-naming-convention/) 223 // Hopefully some day this can just be deprecated (see http://rlva.catznip.com/blog/2009/07/attachment-point-naming-convention/)
216 if ( (!pFolder) || (pFolder->getName().empty()) ) 224 if ( (!pFolder) || (pFolder->getName().empty()) )
217 return NULL; 225 return 0;
218 226
219 // Check for a (...) block *somewhere* in the name 227 // Check for a (...) block *somewhere* in the name
220 std::string::size_type idxMatch; 228 std::string::size_type idxMatch;
@@ -236,7 +244,7 @@ LLViewerJointAttachment* RlvHandler::getAttachPointLegacy(const LLInventoryCateg
236 if (RLV_FOLDER_PREFIX_HIDDEN == strAttachPt[0]) 244 if (RLV_FOLDER_PREFIX_HIDDEN == strAttachPt[0])
237 strAttachPt.erase(0, 1); 245 strAttachPt.erase(0, 1);
238 } 246 }
239 return getAttachPoint(strAttachPt, true); 247 return getAttachPointIndex(strAttachPt, true);
240} 248}
241 249
242bool RlvHandler::hasLockedHUD() const 250bool RlvHandler::hasLockedHUD() const
@@ -255,16 +263,12 @@ bool RlvHandler::hasLockedHUD() const
255 return false; // None of our locked attachments is a HUD 263 return false; // None of our locked attachments is a HUD
256} 264}
257 265
258// Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a
259bool RlvHandler::isLockedAttachment(const LLInventoryItem* pItem, ERlvLockMask eLock) const
260{
261 LLVOAvatar* pAvatar = gAgent.getAvatarObject();
262 return (pItem) && (pAvatar) && (isLockedAttachment(pAvatar->getWornAttachment(pItem->getUUID()), eLock));
263}
264
265// Checked: 2009-10-13 (RLVa-1.0.5b) | Added: RLVa-1.0.5b 266// Checked: 2009-10-13 (RLVa-1.0.5b) | Added: RLVa-1.0.5b
266bool RlvHandler::isLockedAttachmentExcept(S32 idxAttachPt, ERlvLockMask eLock, LLViewerObject *pObj) const 267bool RlvHandler::isLockedAttachmentExcept(S32 idxAttachPt, ERlvLockMask eLock, LLViewerObject *pExceptObj) const
267{ 268{
269 if (!pExceptObj)
270 return isLockedAttachment(idxAttachPt, eLock);
271
268 // Loop over every object that marked the specific attachment point eLock type locked (but ignore pObj and any of its children) 272 // Loop over every object that marked the specific attachment point eLock type locked (but ignore pObj and any of its children)
269 LLViewerObject* pTempObj; 273 LLViewerObject* pTempObj;
270 if (eLock & RLV_LOCK_REMOVE) 274 if (eLock & RLV_LOCK_REMOVE)
@@ -272,7 +276,7 @@ bool RlvHandler::isLockedAttachmentExcept(S32 idxAttachPt, ERlvLockMask eLock, L
272 for (rlv_attachlock_map_t::const_iterator itAttach = m_AttachRem.lower_bound(idxAttachPt), 276 for (rlv_attachlock_map_t::const_iterator itAttach = m_AttachRem.lower_bound(idxAttachPt),
273 endAttach = m_AttachRem.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach) 277 endAttach = m_AttachRem.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach)
274 { 278 {
275 if ( ((pTempObj = gObjectList.findObject(itAttach->second)) == NULL) || (pTempObj->getRootEdit()->getID() != pObj->getID()) ) 279 if ( ((pTempObj = gObjectList.findObject(itAttach->second)) == NULL) || (pTempObj->getRootEdit()->getID() != pExceptObj->getID()) )
276 return true; 280 return true;
277 } 281 }
278 } 282 }
@@ -281,7 +285,7 @@ bool RlvHandler::isLockedAttachmentExcept(S32 idxAttachPt, ERlvLockMask eLock, L
281 for (rlv_attachlock_map_t::const_iterator itAttach = m_AttachAdd.lower_bound(idxAttachPt), 285 for (rlv_attachlock_map_t::const_iterator itAttach = m_AttachAdd.lower_bound(idxAttachPt),
282 endAttach = m_AttachAdd.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach) 286 endAttach = m_AttachAdd.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach)
283 { 287 {
284 if ( ((pTempObj = gObjectList.findObject(itAttach->second)) == NULL) || (pTempObj->getRootEdit()->getID() != pObj->getID()) ) 288 if ( ((pTempObj = gObjectList.findObject(itAttach->second)) == NULL) || (pTempObj->getRootEdit()->getID() != pExceptObj->getID()) )
285 return true; 289 return true;
286 } 290 }
287 } 291 }
@@ -310,6 +314,40 @@ void RlvHandler::addAttachmentLock(S32 idxAttachPt, const LLUUID &idRlvObj, ERlv
310 } 314 }
311} 315}
312 316
317// Checked: 2010-07-18 (RLVa-1.1.2b) | Added: RLVa-1.1.2a
318void RlvHandler::dumpAttachmentLocks(void*)
319{
320 LLVOAvatar* pAvatar = gAgent.getAvatarObject();
321 if (!pAvatar)
322 {
323 RLV_INFOS << "No avatar object to dump attachments for" << RLV_ENDL;
324 return;
325 }
326
327 RLV_INFOS << "Dumping 'remove' locks:" << RLV_ENDL;
328 for (rlv_attachlock_map_t::iterator itAttachPt = gRlvHandler.m_AttachRem.begin();
329 itAttachPt != gRlvHandler.m_AttachRem.end(); ++itAttachPt)
330 {
331 // Grab the attachment on the attachment point that's locked (if there is one)
332 /*const*/ LLViewerJointAttachment* pAttachPt =
333 get_if_there(pAvatar->mAttachmentPoints, (S32)itAttachPt->first, (LLViewerJointAttachment*)NULL);
334 /*const*/ LLViewerObject* pAttachObj = (pAttachPt) ? pAttachPt->getObject() : NULL;
335 const LLViewerInventoryItem* pAttachItem = (pAttachPt) ? gInventory.getItem(pAttachPt->getItemID()) : NULL;
336
337 // Grab the locking attachment (if we can)
338 /*const*/ LLViewerObject* pRlvObj = gObjectList.findObject(itAttachPt->second);
339 /*const*/ LLViewerJointAttachment* pRlvAttachPt = (pRlvObj) ? pAvatar->getTargetAttachmentPoint(pRlvObj) : NULL;
340 const LLViewerInventoryItem* pRlvItem = (pRlvAttachPt) ? gInventory.getItem(pRlvAttachPt->getItemID()) : NULL;
341
342 std::string strMsg = llformat("'%s' on %s held by '%s' on %s",
343 ((pAttachItem) ? pAttachItem->getName().c_str() : ((pAttachObj) ? pAttachObj->getID().asString().c_str() : "(empty)")),
344 (pAttachPt) ? pAttachPt->getName().c_str() : "(unknown)",
345 ((pRlvItem) ? pRlvItem->getName().c_str() : ((pRlvObj) ? pRlvObj->getID().asString().c_str() : "(empty)")),
346 (pRlvAttachPt) ? pRlvAttachPt->getName().c_str() : "(unknown)");
347 RLV_INFOS << strMsg << RLV_ENDL;
348 }
349}
350
313// Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a 351// Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a
314void RlvHandler::removeAttachmentLock(S32 idxAttachPt, const LLUUID &idRlvObj, ERlvLockMask eLock) 352void RlvHandler::removeAttachmentLock(S32 idxAttachPt, const LLUUID &idRlvObj, ERlvLockMask eLock)
315{ 353{
@@ -344,7 +382,7 @@ void RlvHandler::removeAttachmentLock(S32 idxAttachPt, const LLUUID &idRlvObj, E
344} 382}
345 383
346#ifdef RLV_EXTENSION_FLAG_NOSTRIP 384#ifdef RLV_EXTENSION_FLAG_NOSTRIP
347 // Checked: 2009-05-26 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d 385 // Checked: 2009-12-25 (RLVa-1.1.0k) | Modified: RLVa-1.1.0k
348 bool RlvHandler::isStrippable(const LLUUID& idItem) const 386 bool RlvHandler::isStrippable(const LLUUID& idItem) const
349 { 387 {
350 // An item is exempt from @detach or @remoutfit if: 388 // An item is exempt from @detach or @remoutfit if:
@@ -359,8 +397,13 @@ void RlvHandler::removeAttachmentLock(S32 idxAttachPt, const LLUUID &idRlvObj, E
359 return false; 397 return false;
360 398
361 LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID()); 399 LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID());
362 if ( (pFolder) && (std::string::npos != pFolder->getName().find(RLV_FOLDER_FLAG_NOSTRIP)) ) 400 while ( (pFolder) && gAgent.getInventoryRootID() != (pFolder->getUUID()) )
363 return false; 401 {
402 if (std::string::npos != pFolder->getName().find(RLV_FOLDER_FLAG_NOSTRIP))
403 return false;
404 // If the item's parent is a folded folder then we need to check its parent as well
405 pFolder = (isFoldedFolder(pFolder, false, true)) ? gInventory.getCategory(pFolder->getParentUUID()) : NULL;
406 }
364 } 407 }
365 } 408 }
366 return true; 409 return true;
@@ -419,539 +462,210 @@ bool RlvHandler::isException(ERlvBehaviour eBhvr, const RlvExceptionOption& varO
419// Command processing functions 462// Command processing functions
420// 463//
421 464
422// Checked: 2009-06-03 (RLVa-0.2.0h) 465// Checked: 2009-11-27 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
423void RlvHandler::addBehaviourObserver(RlvBehaviourObserver* pBhvrObserver) 466void RlvHandler::addBehaviourObserver(RlvBehaviourObserver* pBhvrObserver)
424{ 467{
425 std::list<RlvBehaviourObserver*>::iterator itBhvrObserver = std::find(m_BhvrObservers.begin(), m_BhvrObservers.end(), pBhvrObserver); 468 if ( (pBhvrObserver) && (std::find(m_BhvrObservers.begin(), m_BhvrObservers.end(), pBhvrObserver) == m_BhvrObservers.end()) )
426 if (itBhvrObserver == m_BhvrObservers.end())
427 m_BhvrObservers.push_back(pBhvrObserver); 469 m_BhvrObservers.push_back(pBhvrObserver);
428} 470}
429 471
430// Checked: 2009-06-03 (RLVa-0.2.0h) 472// Checked: 2009-11-27 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
473void RlvHandler::addCommandHandler(RlvCommandHandler* pCmdHandler)
474{
475 if ( (pCmdHandler) && (std::find(m_CommandHandlers.begin(), m_CommandHandlers.end(), pCmdHandler) == m_CommandHandlers.end()) )
476 m_CommandHandlers.push_back(pCmdHandler);
477}
478
479// Checked: 2009-11-27 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
431void RlvHandler::removeBehaviourObserver(RlvBehaviourObserver* pBhvrObserver) 480void RlvHandler::removeBehaviourObserver(RlvBehaviourObserver* pBhvrObserver)
432{ 481{
433 std::list<RlvBehaviourObserver*>::iterator itBhvrObserver = std::find(m_BhvrObservers.begin(), m_BhvrObservers.end(), pBhvrObserver); 482 if (pBhvrObserver)
434 if (itBhvrObserver != m_BhvrObservers.end()) 483 m_BhvrObservers.remove(pBhvrObserver);
435 m_BhvrObservers.erase(itBhvrObserver); 484}
485
486// Checked: 2009-11-27 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
487void RlvHandler::removeCommandHandler(RlvCommandHandler* pCmdHandler)
488{
489 if (pCmdHandler)
490 m_CommandHandlers.remove(pCmdHandler);
491}
492
493// Checked: 2009-10-26 (RLVa-1.1.0a) | Modified: RLVa-1.1.0a
494void RlvHandler::clearCommandHandlers()
495{
496 std::list<RlvCommandHandler*>::const_iterator itHandler = m_CommandHandlers.begin();
497 while (itHandler != m_CommandHandlers.end())
498 {
499 delete *itHandler;
500 ++itHandler;
501 }
502 m_CommandHandlers.clear();
436} 503}
437 504
438// Checked: 2009-06-03 (RLVa-0.2.0h) 505// Checked: 2009-06-03 (RLVa-0.2.0h)
439void RlvHandler::notifyBehaviourObservers(const RlvCommand& rlvCmd, bool fInternal) 506void RlvHandler::notifyBehaviourObservers(const RlvCommand& rlvCmd, bool fInternal)
440{ 507{
441 for (std::list<RlvBehaviourObserver*>::const_iterator itBhvrObserver = m_BhvrObservers.begin(); 508 for (std::list<RlvBehaviourObserver*>::const_iterator itBhvrObserver = m_BhvrObservers.begin();
442 itBhvrObserver != m_BhvrObservers.end(); ++itBhvrObserver) 509 itBhvrObserver != m_BhvrObservers.end(); ++itBhvrObserver)
443 { 510 {
444 (*itBhvrObserver)->changed(rlvCmd, fInternal); 511 (*itBhvrObserver)->changed(rlvCmd, fInternal);
445 } 512 }
446} 513}
447 514
448// Checked: 515// Checked: 2009-11-26 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
449BOOL RlvHandler::processCommand(const LLUUID& idObj, const std::string& strCmd, bool fFromObj) 516bool RlvHandler::notifyCommandHandlers(rlvCommandHandler f, const LLUUID& idObj, const RlvCommand& rlvCmd, ERlvCmdRet& eRet, bool fNotifyAll) const
517{
518 std::list<RlvCommandHandler*>::const_iterator itHandler = m_CommandHandlers.begin(); bool fContinue = true; eRet = RLV_RET_UNKNOWN;
519 while ( (itHandler != m_CommandHandlers.end()) && ((fContinue) || (fNotifyAll)) )
520 {
521 ERlvCmdRet eCmdRet = RLV_RET_UNKNOWN;
522 if ((fContinue = !((*itHandler)->*f)(idObj, rlvCmd, eCmdRet)) == false)
523 eRet = eCmdRet;
524 ++itHandler;
525 }
526 RLV_ASSERT( (fContinue) || (eRet != RLV_RET_UNKNOWN) );
527 return !fContinue;
528}
529
530// Checked: 2009-11-25 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
531ERlvCmdRet RlvHandler::processCommand(const LLUUID& idObj, const RlvCommand& rlvCmd, bool fFromObj)
450{ 532{
451 #ifdef RLV_DEBUG 533 #ifdef RLV_DEBUG
452 RLV_INFOS << "[" << idObj << "]: " << strCmd << LL_ENDL; 534 RLV_INFOS << "[" << idObj << "]: " << rlvCmd.asString() << RLV_ENDL;
453 #endif // RLV_DEBUG 535 #endif // RLV_DEBUG
454 536
455 RlvCommand rlvCmd(strCmd);
456 if (!rlvCmd.isValid()) 537 if (!rlvCmd.isValid())
457 { 538 {
458 #ifdef RLV_DEBUG 539 #ifdef RLV_DEBUG
459 RLV_INFOS << "\t-> invalid command: " << strCmd << LL_ENDL; 540 RLV_INFOS << "\t-> invalid syntax" << RLV_ENDL;
460 #endif // RLV_DEBUG 541 #endif // RLV_DEBUG
461 return FALSE; 542 return RLV_RET_FAILED_SYNTAX;
462 } 543 }
463 544
464 // NOTE: if we pass RlvObject::m_UUID for idObj somewhere and process a @clear then it will point to invalid/cleared memory at the end 545 // Using a stack for executing commands solves a few problems:
465 // so make sure to *always* pass our private copy to other functions 546 // - if we passed RlvObject::m_UUID for idObj somewhere and process a @clear then idObj points to invalid/cleared memory at the end
466 m_pCurCommand = &rlvCmd; m_idCurObject = idObj; 547 // - if command X triggers command Y along the way then getCurrentCommand()/getCurrentObject() still return Y even when finished
548 m_CurCommandStack.push(&rlvCmd); m_CurObjectStack.push(idObj);
549 const LLUUID& idCurObj = m_CurObjectStack.top();
467 550
468 BOOL fRet = FALSE; 551 ERlvCmdRet eRet = RLV_RET_UNKNOWN;
469 switch (rlvCmd.getParamType()) 552 switch (rlvCmd.getParamType())
470 { 553 {
471 case RLV_TYPE_ADD: // Checked: 2009-06-03 (RLVa-0.2.0h) | Modified: RLVa-0.2.0h 554 case RLV_TYPE_ADD: // Checked: 2009-11-26 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
472 { 555 {
473 if ( (m_Behaviours[rlvCmd.getBehaviourType()]) && 556 if ( (m_Behaviours[rlvCmd.getBehaviourType()]) &&
474 ( (RLV_BHVR_SETDEBUG == rlvCmd.getBehaviourType()) || (RLV_BHVR_SETENV == rlvCmd.getBehaviourType()) ) ) 557 ( (RLV_BHVR_SETDEBUG == rlvCmd.getBehaviourType()) || (RLV_BHVR_SETENV == rlvCmd.getBehaviourType()) ) )
475 { 558 {
476 // Some restrictions can only be held by one single object to avoid deadlocks 559 // Some restrictions can only be held by one single object to avoid deadlocks
477 #ifdef RLV_DEBUG 560 #ifdef RLV_DEBUG
478 RLV_INFOS << "\t- " << rlvCmd.getBehaviour() << " is already set by another object => discarding" << LL_ENDL; 561 RLV_INFOS << "\t- " << rlvCmd.getBehaviour() << " is already set by another object => discarding" << RLV_ENDL;
479 #endif // RLV_DEBUG 562 #endif // RLV_DEBUG
563 eRet = RLV_RET_FAILED_LOCK;
480 break; 564 break;
481 } 565 }
482 566
483 rlv_object_map_t::iterator itObj = m_Objects.find(m_idCurObject); 567 rlv_object_map_t::iterator itObj = m_Objects.find(idCurObj); bool fAdded = false;
484 if (itObj != m_Objects.end()) 568 if (itObj != m_Objects.end())
485 { 569 {
486 RlvObject& rlvObj = itObj->second; 570 RlvObject& rlvObj = itObj->second;
487 fRet = rlvObj.addCommand(rlvCmd); 571 fAdded = rlvObj.addCommand(rlvCmd);
488 } 572 }
489 else 573 else
490 { 574 {
491 RlvObject rlvObj(m_idCurObject); 575 RlvObject rlvObj(idCurObj);
492 fRet = rlvObj.addCommand(rlvCmd); 576 fAdded = rlvObj.addCommand(rlvCmd);
493 m_Objects.insert(std::pair<LLUUID, RlvObject>(m_idCurObject, rlvObj)); 577 m_Objects.insert(std::pair<LLUUID, RlvObject>(idCurObj, rlvObj));
494 } 578 }
495 579
496 #ifdef RLV_DEBUG 580 #ifdef RLV_DEBUG
497 RLV_INFOS << "\t- " << ( (fRet) ? "adding behaviour" : "skipping duplicate") << LL_ENDL; 581 RLV_INFOS << "\t- " << ( (fAdded) ? "adding behaviour" : "skipping duplicate" ) << RLV_ENDL;
498 #endif // RLV_DEBUG 582 #endif // RLV_DEBUG
499 583
500 if (fRet) { // If FALSE then this was a duplicate, there's no need to handle those 584 if (fAdded) { // If FALSE then this was a duplicate, there's no need to handle those
501 if (!m_pGCTimer) 585 if (!m_pGCTimer)
502 m_pGCTimer = new RlvGCTimer(); 586 m_pGCTimer = new RlvGCTimer();
503 processAddCommand(m_idCurObject, rlvCmd); 587 eRet = processAddRemCommand(idCurObj, rlvCmd);
504 notifyBehaviourObservers(rlvCmd, !fFromObj); 588 notifyBehaviourObservers(rlvCmd, !fFromObj);
505 } 589 }
590 else
591 {
592 eRet = RLV_RET_SUCCESS_DUPLICATE;
593 }
506 } 594 }
507 break; 595 break;
508 case RLV_TYPE_REMOVE: // Checked: 596 case RLV_TYPE_REMOVE: // Checked: 2009-11-26 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
509 { 597 {
510 rlv_object_map_t::iterator itObj = m_Objects.find(m_idCurObject); 598 rlv_object_map_t::iterator itObj = m_Objects.find(idCurObj); bool fRemoved = false;
511 if (itObj != m_Objects.end()) 599 if (itObj != m_Objects.end())
512 fRet = itObj->second.removeCommand(rlvCmd); 600 fRemoved = itObj->second.removeCommand(rlvCmd);
513 601
514 #ifdef RLV_DEBUG 602 #ifdef RLV_DEBUG
515 RLV_INFOS << "\t- " << ( (fRet) ? "removing behaviour" 603 RLV_INFOS << "\t- " << ( (fRemoved) ? "removing behaviour"
516 : "skipping remove (unset behaviour or unknown object)") << LL_ENDL; 604 : "skipping remove (unset behaviour or unknown object)") << RLV_ENDL;
517 #endif // RLV_DEBUG 605 #endif // RLV_DEBUG
518 606
519 if (fRet) { // Don't handle non-sensical removes 607 if (fRemoved) { // Don't handle non-sensical removes
520 processRemoveCommand(m_idCurObject, rlvCmd); 608 eRet = processAddRemCommand(idCurObj, rlvCmd);
521 notifyBehaviourObservers(rlvCmd, !fFromObj); 609 notifyBehaviourObservers(rlvCmd, !fFromObj);
522 610
523 if (0 == itObj->second.m_Commands.size()) 611 if (0 == itObj->second.m_Commands.size())
524 { 612 {
525 #ifdef RLV_DEBUG 613 #ifdef RLV_DEBUG
526 RLV_INFOS << "\t- command list empty => removing " << m_idCurObject << LL_ENDL; 614 RLV_INFOS << "\t- command list empty => removing " << idCurObj << RLV_ENDL;
527 #endif // RLV_DEBUG 615 #endif // RLV_DEBUG
528 m_Objects.erase(itObj); 616 m_Objects.erase(itObj);
529 } 617 }
530 } 618 }
619 else
620 {
621 eRet = RLV_RET_SUCCESS_UNSET;
622 }
531 } 623 }
532 break; 624 break;
533 case RLV_TYPE_CLEAR: 625 case RLV_TYPE_CLEAR: // Checked: 2009-11-25 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
534 fRet = processClearCommand(m_idCurObject, rlvCmd); 626 eRet = processClearCommand(idCurObj, rlvCmd);
535 notifyBehaviourObservers(rlvCmd, !fFromObj); 627 notifyBehaviourObservers(rlvCmd, !fFromObj);
536 break; 628 break;
537 case RLV_TYPE_FORCE: // Checked: 629 case RLV_TYPE_FORCE: // Checked: 2009-11-26 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
538 fRet = processForceCommand(m_idCurObject, rlvCmd); 630 eRet = processForceCommand(idCurObj, rlvCmd);
539 break;
540 case RLV_TYPE_REPLY: // Checked:
541 fRet = processReplyCommand(m_idCurObject, rlvCmd);
542 break; 631 break;
543 case RLV_TYPE_UNKNOWN: // Checked: 632 case RLV_TYPE_REPLY: // Checked: 2009-11-25 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
633 eRet = processReplyCommand(idCurObj, rlvCmd);
544 break; 634 break;
545 #ifdef LL_GNUC 635 case RLV_TYPE_UNKNOWN: // Checked: 2009-11-25 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
546 default: 636 default:
637 eRet = RLV_RET_FAILED_PARAM;
547 break; 638 break;
548 #endif // LL_GNUC
549 } 639 }
640 RLV_ASSERT(RLV_RET_UNKNOWN != eRet);
550 641
551 #ifdef RLV_DEBUG 642 #ifdef RLV_DEBUG
552 RLV_INFOS << "\t--> command " << ((fRet) ? "succeeded" : "failed") << LL_ENDL; 643 RLV_INFOS << "\t--> command " << ((eRet & RLV_RET_SUCCESS) ? "succeeded" : "failed") << RLV_ENDL;
553 #endif // RLV_DEBUG 644 #endif // RLV_DEBUG
554 645
555 m_pCurCommand = NULL; m_idCurObject.setNull(); 646 m_CurCommandStack.pop(); m_CurObjectStack.pop();
556 return fRet; 647 return eRet;
557} 648}
558 649
559BOOL RlvHandler::processAddCommand(const LLUUID& uuid, const RlvCommand& rlvCmd) 650// Checked: 2009-11-25 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
651void RlvHandler::processRetainedCommands(ERlvBehaviour eBhvrFilter /*=RLV_BHVR_UNKNOWN*/, ERlvParamType eTypeFilter /*=RLV_TYPE_UNKNOWN*/)
560{ 652{
561 // NOTE: - at this point the command has already been added to the corresponding RlvObject instance 653 rlv_retained_list_t::iterator itCmd = m_Retained.begin(), itCurCmd;
562 // - the object's UUID may or may not exist in gObjectList (see handling of @detach=n) 654 while (itCmd != m_Retained.end())
563
564 ERlvBehaviour eBehaviour = rlvCmd.getBehaviourType();
565 const std::string& strOption = rlvCmd.getOption();
566
567 if ( (RLV_BHVR_UNKNOWN != eBehaviour) && (strOption.empty()) )
568 { 655 {
569 if (rlvCmd.isStrict()) 656 itCurCmd = itCmd++; // Point the loop iterator ahead
570 addException(uuid, RLV_BHVR_PERMISSIVE, eBehaviour);
571 m_Behaviours[eBehaviour]++;
572 }
573 657
574 bool fRefCount = false; // Unused for the moment 658 const RlvRetainedCommand& cmd = *itCurCmd;
575 switch (eBehaviour) 659 if ( ((RLV_BHVR_UNKNOWN == eBhvrFilter) || (cmd.rlvCmd.getBehaviourType() == eBhvrFilter)) &&
576 { 660 ((RLV_TYPE_UNKNOWN == eTypeFilter) || (cmd.rlvCmd.getParamType() == eTypeFilter)) )
577 case RLV_BHVR_DETACH: // @detach[:<option>]=n - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a 661 {
578 onAddRemDetach(uuid, rlvCmd, fRefCount); 662 processCommand(cmd.idObject, cmd.rlvCmd, true);
579 break; 663 m_Retained.erase(itCurCmd);
580 case RLV_BHVR_ADDATTACH: // @addattach[:<option>]=n - Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a 664 }
581 case RLV_BHVR_REMATTACH: // @addattach[:<option>]=n - Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a
582 onAddRemAttach(uuid, rlvCmd, fRefCount);
583 break;
584 case RLV_BHVR_REDIRCHAT: // @redirchat:<option>=n - Checked: 2009-07-07 (RLVa-1.0.0d)
585 case RLV_BHVR_REDIREMOTE: // @rediremote:<option>=n - Checked: 2009-07-07 (RLVa-1.0.0d) | Added: RLVa-0.2.2a
586 {
587 if (!strOption.empty())
588 m_Behaviours[eBehaviour]++; // @redirchat and @rediremote don't have an optionless version so keep track of it here
589 else
590 m_Behaviours[eBehaviour]--; // @redirchat=n and @rediremote=n are undefined, don't keep track of them
591 }
592 break;
593 case RLV_BHVR_SHOWWORLDMAP: // @showworldmap=n - Checked: 2009-07-05 (RLVa-1.0.0c)
594 {
595 // Simulate clicking the Map button [see LLToolBar::onClickMap()]
596 if (gFloaterWorldMap->getVisible())
597 LLFloaterWorldMap::toggle(NULL);
598 }
599 break;
600 case RLV_BHVR_SHOWMINIMAP: // @showminimap=n - Checked: 2009-07-05 (RLVa-1.0.0c)
601 {
602 // Simulate clicking the Minimap button [see LLToolBar::onClickRadar()]
603 #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11
604 if (gFloaterMap->getVisible())
605 LLFloaterMap::toggle(NULL);
606 #else // Version: 1.23.4
607 if (LLFloaterMap::instanceVisible())
608 LLFloaterMap::hideInstance();
609 #endif
610 }
611 break;
612 #ifdef RLV_EXTENSION_STARTLOCATION
613 case RLV_BHVR_TPLOC: // @tploc=n - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.1d
614 case RLV_BHVR_UNSIT: // @unsit=n - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.1d
615 {
616 if (strOption.empty())
617 RlvSettings::updateLoginLastLocation();
618 }
619 break;
620 #endif // RLV_EXTENSION_STARTLOCATION
621 case RLV_BHVR_EDIT: // @edit=n - Checked: 2009-07-04 (RLVa-1.0.0b)
622 {
623 // Turn off "View / Highlight Transparent"
624 LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
625
626 // Close the Beacons floater if it's open
627 if (LLFloaterBeacons::instanceVisible())
628 LLFloaterBeacons::toggleInstance();
629
630 // Get rid of the build floater if it's open [copy/paste from toggle_build_mode()]
631 if (gFloaterTools->getVisible())
632 {
633 gAgent.resetView(FALSE);
634 gFloaterTools->close();
635 gViewerWindow->showCursor();
636 }
637 }
638 break;
639 case RLV_BHVR_ADDOUTFIT: // @addoutfit[:<layer>]=n - Checked: 2009-07-07 (RLVa-1.0.0d)
640 case RLV_BHVR_REMOUTFIT: // @remoutfit[:<layer>]=n - Checked: 2009-07-07 (RLVa-1.0.0d)
641 {
642 S16* pLayers = (eBehaviour == RLV_BHVR_ADDOUTFIT) ? m_LayersAdd : m_LayersRem;
643
644 if (strOption.empty())
645 {
646 for (int idx = 0; idx < WT_COUNT; idx++)
647 pLayers[idx]++;
648 }
649 else
650 {
651 EWearableType type = LLWearable::typeNameToType(strOption);
652 if (WT_INVALID != type)
653 {
654 pLayers[type]++;
655 m_Behaviours[eBehaviour]++;
656 }
657 }
658 }
659 break;
660 case RLV_BHVR_SHOWINV: // @showinv=n - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-1.0.0g
661 {
662 // Close all open inventory windows
663 LLInventoryView::closeAll();
664 }
665 break;
666 case RLV_BHVR_SHOWLOC: // @showloc=n - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
667 {
668 // If we're the first @showloc=n restriction refresh all object text so we can filter it if necessary
669 if (1 == m_Behaviours[RLV_BHVR_SHOWLOC])
670 LLHUDText::refreshAllObjectText();
671
672 // Close the "About Land" floater if it's currently visible
673 if (LLFloaterLand::instanceVisible())
674 LLFloaterLand::hideInstance();
675
676 // Close the "Estate Tools" floater is it's currently visible
677 if (LLFloaterRegionInfo::instanceVisible())
678 LLFloaterRegionInfo::hideInstance();
679
680 // NOTE: we should close the "God Tools" floater as well, but since calling LLFloaterGodTools::instance() always
681 // creates a new instance of the floater and since it's very unlikely to be open it's just better not to
682 }
683 break;
684 case RLV_BHVR_SHOWNAMES: // @shownames=n - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
685 {
686 // If we're the first @shownames=n restriction refresh all object text so we can filter it if necessary
687 if (1 == m_Behaviours[RLV_BHVR_SHOWNAMES])
688 LLHUDText::refreshAllObjectText();
689
690 // Close the "Active Speakers" panel if it's currently visible
691 LLFloaterChat::getInstance()->childSetVisible("active_speakers_panel", false);
692 }
693 break;
694 case RLV_BHVR_FARTOUCH:
695 {
696 #ifdef RLV_EXPERIMENTAL_FIRSTUSE
697 //LLFirstUse::useRlvFartouch();
698 #endif // RLV_EXPERIMENTAL_FIRSTUSE
699 }
700 break;
701 case RLV_BHVR_FLY: // @fly=n - Checked: 2009-07-05 (RLVa-1.0.0c)
702 {
703 // If currently flying, simulate clicking the Fly button [see LLToolBar::onClickFly()]
704 if (gAgent.getFlying())
705 gAgent.toggleFlying();
706 }
707 break;
708 case RLV_BHVR_SETENV: // @setenv=n - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0a
709 {
710 if (!fNoSetEnv)
711 {
712 // Only close the floaters if their instance exists and they're actually visible
713 if ( (LLFloaterEnvSettings::isOpen()) && (LLFloaterEnvSettings::instance()->getVisible()) )
714 LLFloaterEnvSettings::instance()->close();
715 if ( (LLFloaterWindLight::isOpen()) && (LLFloaterWindLight::instance()->getVisible()) )
716 LLFloaterWindLight::instance()->close();
717 if ( (LLFloaterWater::isOpen()) && (LLFloaterWater::instance()->getVisible()) )
718 LLFloaterWater::instance()->close();
719 if ( (LLFloaterDayCycle::isOpen()) && (LLFloaterDayCycle::instance()->getVisible()) )
720 LLFloaterDayCycle::instance()->close();
721
722 // Save the current WindLight params so we can restore them on @setenv=y
723 if (m_pWLSnapshot)
724 {
725 RLV_ERRS << "m_pWLSnapshot != NULL" << LL_ENDL; // Safety net in case we set @setenv=n for more than 1 object
726 delete m_pWLSnapshot;
727 }
728 m_pWLSnapshot = RlvWLSnapshot::takeSnapshot();
729 }
730 }
731 break;
732 case RLV_BHVR_SHOWHOVERTEXTALL: // @showhovertextal=n - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
733 case RLV_BHVR_SHOWHOVERTEXTWORLD: // @showhovertextworld=n - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
734 case RLV_BHVR_SHOWHOVERTEXTHUD: // @showhovertexthud=n - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
735 {
736 // Refresh all hover text (LLHUDText::setStringUTF8() will decide what needs clearing and what doesn't)
737 LLHUDText::refreshAllObjectText();
738 }
739 break;
740 case RLV_BHVR_SHOWHOVERTEXT: // @showhovertext:<uuid>=n - Checked: 2009-07-09 (RLVa-0.2.2a) | Modified: RLVa-1.0.0f
741 {
742 LLUUID idException(strOption);
743 if (idException.notNull()) // If there's an option it should be a valid UUID
744 {
745 addException(uuid, eBehaviour, idException);
746
747 // Clear the object's hover text
748 LLViewerObject* pObj = gObjectList.findObject(idException);
749 if ( (pObj) && (pObj->mText.notNull()) && (!pObj->mText->getObjectText().empty()) )
750 pObj->mText->setStringUTF8("");
751 }
752 }
753 break;
754 case RLV_BHVR_NOTIFY: // @notify:<option>=add - Checked: 2009-08-04 (RLVa-1.0.1d) | Modified: RLVa-1.0.1d
755 {
756 S32 nChannel; std::string strFilter;
757 if ( (!strOption.empty()) && (rlvParseNotifyOption(strOption, nChannel, strFilter)) )
758 {
759 if (!m_pBhvrNotify)
760 addBehaviourObserver(m_pBhvrNotify = new RlvBehaviourNotifyObserver());
761 m_pBhvrNotify->addNotify(uuid, nChannel, strFilter);
762 }
763 }
764 break;
765 case RLV_BHVR_SENDCHANNEL: // @sendchannel:<uuid>=add - Checked: 2009-10-05 (RLVa-1.0.4a) | Modified: RLVa-1.0.4a
766 {
767 S32 nChannel; // If there's an option it should be a valid (=positive and non-zero) chat channel
768 if ( (!strOption.empty()) && (LLStringUtil::convertToS32(strOption, nChannel)) && (nChannel > 0) )
769 addException(uuid, eBehaviour, nChannel);
770 }
771 break;
772 case RLV_BHVR_RECVCHAT: // @recvchat:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
773 case RLV_BHVR_RECVEMOTE: // @recvemote:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
774 case RLV_BHVR_RECVIM: // @recvim:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
775 case RLV_BHVR_SENDIM: // @sendim:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
776 case RLV_BHVR_TPLURE: // @tplure:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
777 case RLV_BHVR_ACCEPTTP: // @accepttp:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
778 {
779 LLUUID idException(strOption);
780 if (idException.notNull()) // If there's an option it should be a valid UUID
781 addException(uuid, eBehaviour, LLUUID(strOption));
782 }
783 break;
784 case RLV_BHVR_UNKNOWN:
785 {
786 // Give our observers a chance to handle any command we don't
787 RlvEvent rlvEvent(uuid, rlvCmd);
788 m_Emitter.update(&RlvObserver::onAddCommand, rlvEvent);
789 }
790 break;
791 default:
792 break;
793 }
794 return TRUE; // Add command success/failure is decided by RlvObject::addCommand()
795}
796
797// Checked: 2009-08-05 (RLVa-1.0.1e) | Added: RLVa-1.0.1e
798void RlvHandler::processRetainedCommands()
799{
800 for (rlv_retained_list_t::const_iterator itCmd = m_Retained.begin(); itCmd != m_Retained.end(); ++itCmd)
801 {
802 const RlvRetainedCommand& cmd = *itCmd;
803 processCommand(cmd.idObject, cmd.strCmd, true);
804 }
805 m_Retained.clear();
806}
807
808BOOL RlvHandler::processRemoveCommand(const LLUUID& uuid, const RlvCommand& rlvCmd)
809{
810 // NOTE: - the RlvObject instance still exists at this point, but the viewer might already have removed it from its object list
811 ERlvBehaviour eBehaviour = rlvCmd.getBehaviourType();
812 const std::string& strOption = rlvCmd.getOption();
813
814 if ( (RLV_BHVR_UNKNOWN != eBehaviour) && (strOption.empty()) )
815 {
816 if (rlvCmd.isStrict())
817 removeException(uuid, RLV_BHVR_PERMISSIVE, eBehaviour);
818 m_Behaviours[eBehaviour]--;
819 }
820
821 bool fRefCount = false; // Unused for the moment
822 switch (eBehaviour)
823 {
824 case RLV_BHVR_DETACH: // @detach[:<option>]=y - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a
825 onAddRemDetach(uuid, rlvCmd, fRefCount);
826 break;
827 case RLV_BHVR_ADDATTACH: // @addattach[:<option>]=y - Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a
828 case RLV_BHVR_REMATTACH: // @addattach[:<option>]=y - Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a
829 onAddRemAttach(uuid, rlvCmd, fRefCount);
830 break;
831 case RLV_BHVR_REDIRCHAT: // @redirchat:<option>=y - Checked: 2009-07-07 (RLVa-1.0.0d)
832 case RLV_BHVR_REDIREMOTE: // @rediremote:<option>=y - Checked: 2009-07-07 (RLVa-1.0.0d) | Added: RLVa-0.2.2a
833 {
834 if (!strOption.empty())
835 m_Behaviours[eBehaviour]--; // @redirchat and @rediremote don't have an optionless version so keep track of it here
836 else
837 m_Behaviours[eBehaviour]++; // @redirchat=n and @rediremote=n are undefined, don't keep track of them
838 }
839 break;
840 #ifdef RLV_EXTENSION_STARTLOCATION
841 case RLV_BHVR_TPLOC: // @tploc=y - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.1d
842 case RLV_BHVR_UNSIT: // @unsit=y - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.1d
843 {
844 if (strOption.empty())
845 RlvSettings::updateLoginLastLocation();
846 }
847 break;
848 #endif // RLV_EXTENSION_STARTLOCATION
849 case RLV_BHVR_ADDOUTFIT: // @addoutfit[:<layer>]=y - Checked: 2009-07-07 (RLVa-1.0.0d)
850 case RLV_BHVR_REMOUTFIT: // @remoutfit[:<layer>]=y - Checked: 2009-07-07 (RLVa-1.0.0d)
851 {
852 S16* pLayers = (eBehaviour == RLV_BHVR_ADDOUTFIT) ? m_LayersAdd : m_LayersRem;
853
854 if (strOption.empty())
855 {
856 for (int idx = 0; idx < WT_COUNT; idx++)
857 pLayers[idx]--;
858 }
859 else
860 {
861 EWearableType type = LLWearable::typeNameToType(strOption);
862 if (WT_INVALID != type)
863 {
864 pLayers[type]--;
865 m_Behaviours[eBehaviour]--;
866 }
867 }
868 }
869 break;
870 case RLV_BHVR_SETENV: // @setenv=y - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-0.2.0h
871 {
872 if (!fNoSetEnv)
873 {
874 // Restore WindLight parameters to what they were before @setenv=n was issued
875 RlvWLSnapshot::restoreSnapshot(m_pWLSnapshot);
876 delete m_pWLSnapshot;
877 m_pWLSnapshot = NULL;
878 }
879 }
880 break;
881 case RLV_BHVR_SHOWLOC: // @showloc=y - Checked: 2009-07-09 (RLVa-1.0.0f) | Added: RLVa-1.0.0f
882 case RLV_BHVR_SHOWNAMES: // @shownames=y - Checked: 2009-07-09 (RLVa-1.0.0f) | Added: RLVa-1.0.0f
883 case RLV_BHVR_SHOWHOVERTEXTALL: // @showhovertextal=y - Checked: 2009-07-09 (RLVa-1.0.0f) | Added: RLVa-1.0.0f
884 case RLV_BHVR_SHOWHOVERTEXTWORLD: // @showhovertextworld=y - Checked: 2009-07-09 (RLVa-1.0.0f) | Added: RLVa-1.0.0f
885 case RLV_BHVR_SHOWHOVERTEXTHUD: // @showhovertexthud=y - Checked: 2009-07-09 (RLVa-1.0.0f) | Added: RLVa-1.0.0f
886 {
887 // If this was the last of any of the five restrictions we should refresh all hover text in case anything needs restoring
888 if (!m_Behaviours[eBehaviour])
889 LLHUDText::refreshAllObjectText();
890 }
891 break;
892 case RLV_BHVR_SHOWHOVERTEXT: // @showhovertext:<uuid>=y - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
893 {
894 LLUUID idException(strOption);
895 if (idException.notNull()) // If there's an option it should be a valid UUID
896 {
897 removeException(uuid, eBehaviour, idException);
898
899 // Restore the object's hover text
900 LLViewerObject* pObj = gObjectList.findObject(idException);
901 if ( (pObj) && (pObj->mText.notNull()) && (!pObj->mText->getObjectText().empty()) )
902 pObj->mText->setStringUTF8(pObj->mText->getObjectText());
903 }
904 }
905 break;
906 case RLV_BHVR_NOTIFY: // @notify:<option>=rem - Checked: 2009-08-04 (RLVa-1.0.1d) | Modified: RLVa-1.0.1d
907 {
908 S32 nChannel; std::string strFilter;
909 if ( (m_pBhvrNotify) && (!strOption.empty()) && (rlvParseNotifyOption(strOption, nChannel, strFilter)) )
910 {
911 m_pBhvrNotify->removeNotify(uuid, nChannel, strFilter);
912
913 if (!m_pBhvrNotify->hasNotify())
914 {
915 removeBehaviourObserver(m_pBhvrNotify);
916 delete m_pBhvrNotify;
917 m_pBhvrNotify = NULL;
918 }
919 }
920 }
921 break;
922 case RLV_BHVR_SENDCHANNEL: // @sendchannel:<uuid>=rem - Checked: 2009-10-05 (RLVa-1.0.4a) | Modified: RLVa-1.0.4a
923 {
924 S32 nChannel; // If there's an option it should be a valid (=positive and non-zero) chat channel
925 if ( (!strOption.empty()) && (LLStringUtil::convertToS32(strOption, nChannel)) && (nChannel > 0) )
926 removeException(uuid, eBehaviour, nChannel);
927 }
928 break;
929 case RLV_BHVR_RECVCHAT: // @recvchat:<uuid>=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
930 case RLV_BHVR_RECVEMOTE: // @recvemote:<uui>=red - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
931 case RLV_BHVR_RECVIM: // @recvim:<uuid>=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
932 case RLV_BHVR_SENDIM: // @sendim:<uuid>=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
933 case RLV_BHVR_TPLURE: // @recvim:<uuid>=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
934 case RLV_BHVR_ACCEPTTP: // @accepttp:<uuid>=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
935 {
936 LLUUID idException(strOption);
937 if (idException.notNull()) // If there's an option it should be a valid UUID
938 removeException(uuid, eBehaviour, LLUUID(strOption));
939 }
940 break;
941 case RLV_BHVR_UNKNOWN:
942 {
943 // Give our observers a chance to handle any command we don't
944 RlvEvent rlvEvent(uuid, rlvCmd);
945 m_Emitter.update(&RlvObserver::onRemoveCommand, rlvEvent);
946 }
947 break;
948 default:
949 break;
950 } 665 }
951 return TRUE; // Remove commands don't fail, doesn't matter what we return here
952} 666}
953 667
954BOOL RlvHandler::processClearCommand(const LLUUID idObj, const RlvCommand& rlvCmd) 668ERlvCmdRet RlvHandler::processClearCommand(const LLUUID& idObj, const RlvCommand& rlvCmd)
955{ 669{
956 const std::string& strFilter = rlvCmd.getParam(); std::string strCmdRem; 670 const std::string& strFilter = rlvCmd.getParam(); std::string strCmdRem;
957 671
@@ -974,340 +688,10 @@ BOOL RlvHandler::processClearCommand(const LLUUID idObj, const RlvCommand& rlvCm
974 } 688 }
975 689
976 // Let our observers know about clear commands 690 // Let our observers know about clear commands
977 RlvEvent rlvEvent(idObj, rlvCmd); 691 ERlvCmdRet eRet = RLV_RET_SUCCESS;
978 m_Emitter.update(&RlvObserver::onClearCommand, rlvEvent); 692 notifyCommandHandlers(&RlvCommandHandler::onClearCommand, idObj, rlvCmd, eRet, true);
979 693
980 return TRUE; // Don't fail clear commands even if the object didn't exist since it confuses people 694 return RLV_RET_SUCCESS; // Don't fail clear commands even if the object didn't exist since it confuses people
981}
982
983BOOL RlvHandler::processForceCommand(const LLUUID& idObj, const RlvCommand& rlvCmd) const
984{
985 const std::string& strOption = rlvCmd.getOption();
986 BOOL fHandled = TRUE;
987
988 switch (rlvCmd.getBehaviourType())
989 {
990 case RLV_BHVR_DETACH: // @detach[:<option>]=force - Checked: 2009-10-12 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a
991 onForceDetach(idObj, rlvCmd);
992 break;
993 case RLV_BHVR_REMATTACH: // @remattach[:<option>]=force - Checked: 2009-10-12 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a
994 onForceRemAttach(idObj, rlvCmd);
995 break;
996 case RLV_BHVR_REMOUTFIT: // @remoutfit:<option>=force - Checked:
997 onForceRemOutfit(idObj, strOption);
998 break;
999 case RLV_BHVR_UNSIT: // @unsit=force - Checked: 2009-06-02 (RLVa-0.2.0g)
1000 {
1001 LLVOAvatar* pAvatar = gAgent.getAvatarObject();
1002 if ( (pAvatar) && (pAvatar->mIsSitting) && (!hasBehaviourExcept(RLV_BHVR_UNSIT, idObj)) )
1003 {
1004 // See behaviour notes on why we have to force an agent update here
1005 gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
1006 send_agent_update(TRUE, TRUE);
1007 }
1008 }
1009 break;
1010 case RLV_BHVR_TPTO: // @tpto:<option>=force - Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-1.0.0h
1011 {
1012 fHandled = FALSE;
1013 if ( (!strOption.empty()) && (-1 == strOption.find_first_not_of("0123456789/.")) )
1014 {
1015 LLVector3d posGlobal;
1016
1017 boost_tokenizer tokens(strOption, boost::char_separator<char>("/", "", boost::keep_empty_tokens)); int idx = 0;
1018 for (boost_tokenizer::const_iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken)
1019 {
1020 if (idx < 3)
1021 LLStringUtil::convertToF64(*itToken, posGlobal[idx++]);
1022 }
1023
1024 if (idx == 3)
1025 {
1026 gAgent.teleportViaLocation(posGlobal);
1027 fHandled = TRUE;
1028 }
1029 }
1030 }
1031 break;
1032 case RLV_BHVR_SIT: // @sit:<option>=force - Checked: 2009-06-02 (RLVa-0.2.0g)
1033 fHandled = onForceSit(idObj, rlvCmd.getOption());
1034 break;
1035 case RLV_BHVR_ADDOUTFIT: // @addoutfit:<option>=force <- synonym of @attach:<option>=force
1036 case RLV_BHVR_ATTACH: // @attach:<option>=force - Checked:
1037 onForceWear(rlvCmd.getOption(), true, false); // Force attach single folder
1038 break;
1039 case RLV_BHVR_ATTACHALL: // @attachall:<option>=force - Checked:
1040 onForceWear(rlvCmd.getOption(), true, true); // Force attach nested folders
1041 break;
1042 case RLV_BHVR_DETACHALL: // @detachall:<option>=force - Checked:
1043 onForceWear(rlvCmd.getOption(), false, true); // Force detach nested folders
1044 break;
1045 case RLV_BHVR_ATTACHTHIS:
1046 case RLV_BHVR_ATTACHALLTHIS:
1047 case RLV_BHVR_DETACHTHIS:
1048 case RLV_BHVR_DETACHALLTHIS:
1049 {
1050 ERlvBehaviour eBehaviour = rlvCmd.getBehaviourType();
1051 std::string strReply;
1052 if (onGetPath(idObj, strOption, strReply))
1053 {
1054 LLStringUtil::toLower(strReply);
1055 onForceWear(strReply,
1056 (RLV_BHVR_ATTACHTHIS == eBehaviour) || (RLV_BHVR_ATTACHALLTHIS == eBehaviour),
1057 (RLV_BHVR_ATTACHALLTHIS == eBehaviour) || (RLV_BHVR_DETACHALLTHIS == eBehaviour));
1058 }
1059 }
1060 break;
1061 case RLV_BHVR_DETACHME: // @detachme=force - Checked: 2009-06-07 (RLVa-0.2.1c)
1062 {
1063 // NOTE: @detachme=force could be seen as a @detach:<attachpt>=force but RLV implements it as a "detach by UUID"
1064 LLViewerObject* pObj; LLVOAvatar* pAvatar; LLViewerJointAttachment* pAttachPt;
1065 if ( ((pObj = gObjectList.findObject(idObj)) != NULL) && (pObj->isAttachment()) &&
1066 ((pAvatar = gAgent.getAvatarObject()) != NULL) &&
1067 ((pAttachPt = pAvatar->getTargetAttachmentPoint(pObj->getRootEdit())) != NULL) )
1068 {
1069 handle_detach_from_avatar(pAttachPt);
1070 }
1071 }
1072 break;
1073 case RLV_BHVR_UNKNOWN:
1074 {
1075 // Give our observers a chance to handle any command we don't
1076 RlvEvent rlvEvent(idObj, rlvCmd);
1077 fHandled = m_Emitter.update(&RlvObserver::onForceCommand, rlvEvent);
1078 }
1079 break;
1080 default:
1081 break;
1082 }
1083 return fHandled; // If we handled it then it'll still be TRUE; if an observer doesn't handle it'll be FALSE
1084}
1085
1086// Checked: 2009-07-12 (RLVa-1.0.0h)
1087BOOL RlvHandler::processReplyCommand(const LLUUID& uuid, const RlvCommand& rlvCmd) const
1088{
1089 const std::string& strOption = rlvCmd.getOption();
1090 const std::string& strChannel = rlvCmd.getParam();
1091 std::string strReply;
1092
1093 BOOL fHandled = TRUE;
1094 switch (rlvCmd.getBehaviourType())
1095 {
1096 case RLV_BHVR_VERSION: // @version=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h)
1097 strReply = getVersionString();
1098 break;
1099 case RLV_BHVR_VERSIONNUM: // @versionnum=<channel> - Checked: 2009-10-04 (RLVa-1.0.4b) | Added: RLVa-1.0.4b
1100 strReply = getVersionNumString();
1101 break;
1102 case RLV_BHVR_GETOUTFIT: // @getoufit[:<layer>]=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0d
1103 {
1104 // (Quirk: RLV 1.16.1 will execute @getoutfit=<channel> if <layer> is invalid, so we need to as well)
1105 EWearableType layerType = LLWearable::typeNameToType(strOption);
1106
1107 const EWearableType layerTypes[] =
1108 {
1109 WT_GLOVES, WT_JACKET, WT_PANTS, WT_SHIRT, WT_SHOES, WT_SKIRT, WT_SOCKS,
1110 WT_UNDERPANTS, WT_UNDERSHIRT, WT_SKIN, WT_EYES, WT_HAIR, WT_SHAPE, WT_ALPHA, WT_TATTOO
1111 };
1112
1113 #ifdef RLV_EXPERIMENTAL_COMPOSITE_FOLDING
1114 for (int idx = 0, cnt = sizeof(layerTypes) / sizeof(EWearableType); idx < cnt; idx++)
1115 {
1116 if ( (WT_INVALID == layerType) || (layerTypes[idx] == layerType) )
1117 {
1118 // TODO-RLVa: add support for 'fHideLockedLayers'
1119 bool fWorn = (gAgent.getWearable(layerTypes[idx])) &&
1120 (!isHiddenCompositeItem(gAgent.getWearableItem(layerTypes[idx]),
1121 LLWearable::typeToTypeName(layerTypes[idx])));
1122 strReply.push_back( (fWorn) ? '1' : '0' );
1123 }
1124 }
1125 #else
1126 for (int idx = 0, cnt = sizeof(layerTypes) / sizeof(EWearableType); idx < cnt; idx++)
1127 if ( (WT_INVALID == layerType) || (layerTypes[idx] == layerType) )
1128 {
1129 // We never hide body parts, even if they're "locked" and we're hiding locked layers
1130 // (nor do we hide a layer if the issuing object is the only one that has this layer locked)
1131 bool fWorn = (gAgent.getWearable(layerTypes[idx])) &&
1132 ( (!RlvSettings::getHideLockedLayers()) ||
1133 (LLAssetType::AT_BODYPART == LLWearable::typeToAssetType(layerTypes[idx])) ||
1134 ( (isRemovableExcept(layerTypes[idx], uuid)) &&
1135 (isStrippable(gAgent.getWearableItem(layerTypes[idx]))) ) );
1136 strReply.push_back( (fWorn) ? '1' : '0' );
1137 //strReply.push_back( (gAgent.getWearable(layerTypes[idx])) ? '1' : '0' );
1138 }
1139 #endif // RLV_EXPERIMENTAL_COMPOSITE_FOLDING
1140 }
1141 break;
1142 case RLV_BHVR_GETATTACH: // @getattach[:<layer>]=<channel> - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a
1143 {
1144 // If we're fetching all worn attachments then the reply should start with 0
1145 if (strOption.empty())
1146 strReply.push_back('0');
1147
1148 LLVOAvatar* pAvatar = gAgent.getAvatarObject(); std::string strAttachName;
1149 for (LLVOAvatar::attachment_map_t::const_iterator itAttach = pAvatar->mAttachmentPoints.begin();
1150 itAttach != pAvatar->mAttachmentPoints.end(); ++itAttach)
1151 {
1152 LLViewerJointAttachment* pAttachment = itAttach->second;
1153 if (!pAttachment)
1154 continue;
1155
1156 strAttachName = pAttachment->getName(); // Capitalized (see avatar_lad.xml)
1157 LLStringUtil::toLower(strAttachName);
1158
1159 #ifdef RLV_EXPERIMENTAL_COMPOSITE_FOLDING
1160 if ( (strOption.empty()) || (strOption == strAttachName) )
1161 {
1162 // TODO-RLVa: add support for 'fHideLockedAttach'
1163 bool fWorn = (pAttachment->getItemID().notNull()) &&
1164 (!isHiddenCompositeItem(pAttachment->getItemID(), strAttachName));
1165 strReply.push_back( (fWorn) ? '1' : '0' );
1166 }
1167 #else
1168 if ( (strOption.empty()) || (strOption == strAttachName) )
1169 {
1170 bool fWorn = (pAttachment->getItemID().notNull()) &&
1171 ( (!RlvSettings::getHideLockedAttach()) ||
1172 ( (!isLockedAttachmentExcept(itAttach->first, RLV_LOCK_REMOVE, gObjectList.findObject(uuid))) &&
1173 (isStrippable(pAttachment->getItemID())) ) );
1174 strReply.push_back( (fWorn) ? '1' : '0' );
1175 }
1176 #endif // RLV_EXPERIMENTAL_COMPOSITE_FOLDING
1177 }
1178 }
1179 break;
1180 case RLV_BHVR_GETSTATUS: // @getstatus[:<option>]=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h)
1181 {
1182 // NOTE: specification says response should start with '/' but RLV-1.16.1 returns an empty string when no rules are set
1183 rlv_object_map_t::const_iterator itObj = m_Objects.find(uuid);
1184 if (itObj != m_Objects.end())
1185 {
1186 std::string strObjStatus = itObj->second.getStatusString(strOption);
1187 if (!strObjStatus.empty())
1188 {
1189 strReply.push_back('/');
1190 strReply += strObjStatus;
1191 }
1192 }
1193 }
1194 break;
1195 case RLV_BHVR_GETSTATUSALL: // @getstatusall[:<option>]=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h)
1196 {
1197 // NOTE: specification says response should start with '/' but RLV-1.16.1 returns an empty string when no rules are set
1198 std::string strObjStatus;
1199 for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj)
1200 {
1201 strObjStatus = itObj->second.getStatusString(strOption);
1202 if (!strObjStatus.empty())
1203 {
1204 strReply.push_back('/');
1205 strReply += strObjStatus;
1206 }
1207 }
1208 }
1209 break;
1210 case RLV_BHVR_GETINV: // @getinv[:<path>]=<channel> - Checked: 2009-07-28 (RLVa-1.0.1b) | Modified: RLVa-1.0.1b
1211 {
1212 LLViewerInventoryCategory* pFolder = getSharedFolder(strOption);
1213 if (pFolder)
1214 {
1215 LLInventoryModel::cat_array_t* pFolders;
1216 LLInventoryModel::item_array_t* pItems;
1217 gInventory.getDirectDescendentsOf(pFolder->getUUID(), pFolders, pItems);
1218
1219 if (pFolders)
1220 {
1221 for (S32 idxFolder = 0, cntFolder = pFolders->count(); idxFolder < cntFolder; idxFolder++)
1222 {
1223 const std::string& strFolder = pFolders->get(idxFolder)->getName();
1224 if ( (!strFolder.empty()) && (RLV_FOLDER_PREFIX_HIDDEN != strFolder[0]) &&
1225 (!isFoldedFolder(pFolders->get(idxFolder).get(), true)) )
1226 {
1227 if (!strReply.empty())
1228 strReply.push_back(',');
1229 strReply += strFolder;
1230 }
1231 }
1232 }
1233 }
1234 }
1235 break;
1236 case RLV_BHVR_GETINVWORN: // @getinvworn[:path]=<channel> - Checked:
1237 onGetInvWorn(rlvCmd.getOption(), strReply);
1238 break;
1239 case RLV_BHVR_FINDFOLDER: // @findfolder:<criteria>=<channel> - Checked: 2009-08-26 (RLVa-1.0.2a) | Modified: RLVa-1.0.2a
1240 {
1241 // COMPAT-RLV: RLV 1.16.1 returns the first random folder it finds (probably tries to match "" to a folder name?)
1242 // (just going to stick with what's there for now... no option => no folder)
1243 LLInventoryModel::cat_array_t folders;
1244 if ( (!strOption.empty()) && (findSharedFolders(strOption, folders)) )
1245 {
1246 // We need to return an "in depth" result so whoever has the most '/' is our lucky winner
1247 // (maxSlashes needs to be initialized to -1 since children of the #RLV folder won't have '/' in their shared path)
1248 int maxSlashes = -1, curSlashes; std::string strFolderName;
1249 for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++)
1250 {
1251 strFolderName = getSharedPath(folders.get(idxFolder));
1252
1253 curSlashes = std::count(strFolderName.begin(), strFolderName.end(), '/');
1254 if (curSlashes > maxSlashes)
1255 {
1256 maxSlashes = curSlashes;
1257 strReply = strFolderName;
1258 }
1259 }
1260 }
1261 }
1262 break;
1263 #ifdef RLV_EXTENSION_CMD_FINDFOLDERS
1264 case RLV_BHVR_FINDFOLDERS: // @findfolders:<criteria>=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h) | Added: RLVa-0.2.0b
1265 {
1266 LLInventoryModel::cat_array_t folders;
1267 if ( (!strOption.empty()) && (findSharedFolders(strOption, folders)) )
1268 {
1269 for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++)
1270 {
1271 if (!strReply.empty())
1272 strReply.push_back(',');
1273 strReply += getSharedPath(folders.get(idxFolder));
1274 }
1275 }
1276 }
1277 break;
1278 #endif // RLV_EXTENSION_CMD_FINDFOLDERS
1279 case RLV_BHVR_GETPATH: // @getpath[:<option>]=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h)
1280 onGetPath(uuid, rlvCmd.getOption(), strReply);
1281 break;
1282 case RLV_BHVR_GETSITID: // @getsitid=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h)
1283 {
1284 // (Quirk: RLV 1.16.1 returns a NULL uuid if we're not sitting)
1285 LLVOAvatar* pAvatarObj = gAgent.getAvatarObject(); LLUUID uuid;
1286 if ( (pAvatarObj) && (pAvatarObj->mIsSitting) )
1287 {
1288 // LLVOAvatar inherits from 2 classes so make sure we get the right vfptr
1289 LLViewerObject* pAvatar = dynamic_cast<LLViewerObject*>(pAvatarObj), *pParent;
1290 // (If there is a parent, we need to upcast it from LLXform to LLViewerObject to get its UUID)
1291 if ( (pAvatar) && ((pParent = static_cast<LLViewerObject*>(pAvatar->getRoot())) != pAvatar) )
1292 uuid = pParent->getID();
1293 }
1294 strReply = uuid.asString();
1295 }
1296 break;
1297 case RLV_BHVR_UNKNOWN:
1298 {
1299 // Give our observers a chance to handle any command we don't
1300 RlvEvent rlvEvent(uuid, rlvCmd);
1301 return m_Emitter.update(&RlvObserver::onReplyCommand, rlvEvent);
1302 }
1303 break;
1304 default:
1305 break;
1306 }
1307
1308 if (fHandled)
1309 rlvSendChatReply(strChannel, strReply);
1310 return fHandled;
1311} 695}
1312 696
1313// ============================================================================ 697// ============================================================================
@@ -1340,7 +724,7 @@ void RlvHandler::initLookupTables()
1340 } 724 }
1341} 725}
1342 726
1343// Checked: 2009-08-11 (RLVa-1.0.1h) | Modified: RLVa-1.0.1h 727// Checked: 2010-07-18 (RLVa-1.1.2b) | Modified: RLVa-1.1.2a
1344void RlvHandler::onAttach(LLViewerJointAttachment* pAttachPt) 728void RlvHandler::onAttach(LLViewerJointAttachment* pAttachPt)
1345{ 729{
1346 // Sanity check - LLVOAvatar::attachObject() should call us *after* calling LLViewerJointAttachment::addObject() 730 // Sanity check - LLVOAvatar::attachObject() should call us *after* calling LLViewerJointAttachment::addObject()
@@ -1359,25 +743,25 @@ void RlvHandler::onAttach(LLViewerJointAttachment* pAttachPt)
1359 rlv_object_map_t::iterator itObj = m_Objects.find(pObj->getID()); 743 rlv_object_map_t::iterator itObj = m_Objects.find(pObj->getID());
1360 if (itObj != m_Objects.end()) 744 if (itObj != m_Objects.end())
1361 { 745 {
1362 // Save the attachment point index 746 // Only if we haven't been able to find this object (= attachment that rezzed in) or if it's a rezzed prim attached from in-world
1363 itObj->second.m_idxAttachPt = idxAttachPt; 747 if ( (!itObj->second.m_fLookup) || (!itObj->second.m_idxAttachPt) )
1364
1365 // If it's an attachment we processed commands for but that only just rezzed in we need to mark it as existing in gObjectList
1366 if (!itObj->second.m_fLookup)
1367 itObj->second.m_fLookup = true;
1368
1369 // In both cases we should check for "@detach=n" and actually lock down the attachment point it got attached to
1370 if (itObj->second.hasBehaviour(RLV_BHVR_DETACH, false))
1371 { 748 {
1372 // (Copy/paste from processAddCommand) 749 // Reset any lookup information we might have for this object
1373 addAttachmentLock(idxAttachPt, itObj->second.m_UUID, RLV_LOCK_REMOVE); 750 itObj->second.m_idxAttachPt = idxAttachPt;
751 itObj->second.m_fLookup = true;
1374 752
1375 if (pObj->isHUDAttachment()) 753 // In both cases we should check for "@detach=n" and actually lock down the attachment point it got attached to
1376 LLPipeline::sShowHUDAttachments = TRUE; // Prevents hiding of locked HUD attachments 754 if (itObj->second.hasBehaviour(RLV_BHVR_DETACH, false))
755 {
756 // (Copy/paste from processAddCommand)
757 addAttachmentLock(idxAttachPt, itObj->second.m_UUID, RLV_LOCK_REMOVE);
758 if (pObj->isHUDAttachment())
759 LLPipeline::sShowHUDAttachments = TRUE; // Prevents hiding of locked HUD attachments
760 }
1377 } 761 }
1378 } 762 }
1379 763
1380 // Fetch the inventory item if we don't currently have it since we might need it for reattach-on-detach 764 // Fetch the inventory item if it isn't already (we need it for a potential reattach-on-detach)
1381 const LLUUID& idItem = pAttachPt->getItemID(); 765 const LLUUID& idItem = pAttachPt->getItemID();
1382 LLViewerInventoryItem* pItem = ( (idItem.notNull()) && (gInventory.isInventoryUsable()) ) ? gInventory.getItem(idItem) : NULL; 766 LLViewerInventoryItem* pItem = ( (idItem.notNull()) && (gInventory.isInventoryUsable()) ) ? gInventory.getItem(idItem) : NULL;
1383 if ( (STATE_STARTED == LLStartUp::getStartupState()) && (pItem != NULL) ) 767 if ( (STATE_STARTED == LLStartUp::getStartupState()) && (pItem != NULL) )
@@ -1386,20 +770,22 @@ void RlvHandler::onAttach(LLViewerJointAttachment* pAttachPt)
1386 f.fetchItem(idItem); 770 f.fetchItem(idItem);
1387 } 771 }
1388 772
1389 // If what we're wearing is located under the shared root then append the attachment point name (if needed) 773 // If what we're wearing is located under the shared root then append the attachment point name as needed
1390 LLViewerInventoryCategory* pRlvRoot = getSharedRoot(); 774 LLViewerInventoryCategory* pRlvRoot = getSharedRoot();
1391 if ( (STATE_STARTED == LLStartUp::getStartupState()) && (pRlvRoot) && (pItem) && (pItem->isComplete()) && 775 if ( (!RlvSettings::getEnableSharedWear()) && (RlvSettings::getSharedInvAutoRename()) &&
776 (STATE_STARTED == LLStartUp::getStartupState()) && (pRlvRoot) && (pItem) && (pItem->isComplete()) &&
1392 (gInventory.isObjectDescendentOf(idItem, pRlvRoot->getUUID())) ) 777 (gInventory.isObjectDescendentOf(idItem, pRlvRoot->getUUID())) )
1393 { 778 {
1394 std::string strAttachPt = pAttachPt->getName(); 779 // TODO: find a not too convoluted way to rename the attachment in case it specifies a name different than the current attach point
1395 LLStringUtil::toLower(strAttachPt); 780 S32 idxAttachPtItem = getAttachPointIndex(pItem, true);
1396 781 if ( (idxAttachPt != idxAttachPtItem) && (!idxAttachPtItem) )
1397 // If we can modify the item then it should contain the attach point name itself, otherwise its parent should
1398 if (pItem->getPermissions().allowModifyBy(gAgent.getID()))
1399 { 782 {
1400 if (!getAttachPoint(pItem, true)) 783 std::string strAttachPt = pAttachPt->getName();
784 LLStringUtil::toLower(strAttachPt);
785
786 // If we can modify the item then we rename it directly, otherwise we create a new folder and move it
787 if (pItem->getPermissions().allowModifyBy(gAgent.getID()))
1401 { 788 {
1402 // It doesn't specify an attach point and we can rename it [see LLItemBridge::renameItem()]
1403 std::string strName = pItem->getName(); 789 std::string strName = pItem->getName();
1404 LLStringUtil::truncate(strName, DB_INV_ITEM_NAME_STR_LEN - strAttachPt.length() - 3); 790 LLStringUtil::truncate(strName, DB_INV_ITEM_NAME_STR_LEN - strAttachPt.length() - 3);
1405 791
@@ -1410,25 +796,30 @@ void RlvHandler::onAttach(LLViewerJointAttachment* pAttachPt)
1410 gInventory.updateItem(pItem); 796 gInventory.updateItem(pItem);
1411 //gInventory.notifyObservers(); <- done further down in LLVOAvatar::attachObject() 797 //gInventory.notifyObservers(); <- done further down in LLVOAvatar::attachObject()
1412 } 798 }
1413 } 799 else
1414 else
1415 {
1416 // Folder can't be the shared root, or be its direct descendant (= nested at least 2 levels deep)
1417 LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID());
1418 if ( (pFolder) &&
1419 (pFolder->getUUID() != pRlvRoot->getUUID()) && (pFolder->getParentUUID() != pRlvRoot->getUUID()) &&
1420 (!getAttachPoint(pFolder, true)) )
1421 { 800 {
1422 // It's no mod and its parent folder doesn't contain an attach point 801 // Don't do anything if the item is a direct descendant of the shared root, or a folded folder
1423 if ( (1 == rlvGetDirectDescendentsCount(pFolder, LLAssetType::AT_OBJECT)) && (NEW_CATEGORY_NAME == pFolder->getName()) ) 802 LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID());
803 if ( (pFolder) && (pFolder->getUUID() != pRlvRoot->getUUID()) && (!isFoldedFolder(pFolder, true, false)) )
1424 { 804 {
1425 // Only rename if there's exactly 1 object/attachment inside of it [see LLFolderBridge::renameItem()] 805 std::string strFolderName = ".(" + strAttachPt + ")";
1426 std::string strName = ".(" + strAttachPt + ")";
1427 806
1428 pFolder->rename(strName); 807 // Rename the item's parent folder if it's called "New Folder", isn't directly under #RLV and contains exactly 1 object
1429 pFolder->updateServer(FALSE); 808 if ( (NEW_CATEGORY_NAME == pFolder->getName()) && (pFolder->getParentUUID() != pRlvRoot->getUUID()) &&
1430 gInventory.updateCategory(pFolder); 809 (1 == rlvGetDirectDescendentsCount(pFolder, LLAssetType::AT_OBJECT)) )
1431 //gInventory.notifyObservers(); <- done further down in LLVOAvatar::attachObject() 810 {
811 pFolder->rename(strFolderName);
812 pFolder->updateServer(FALSE);
813 gInventory.updateCategory(pFolder);
814 //gInventory.notifyObservers(); <- done further down in LLVOAvatar::attachObject()
815 }
816 else
817 {
818 // "No modify" item with a non-renameable parent: create a new folder named and move the item into it
819 LLUUID idAttachFolder = gInventory.createNewCategory(pFolder->getUUID(), LLAssetType::AT_NONE, strFolderName);
820 move_inventory_item(gAgent.getID(), gAgent.getSessionID(), pItem->getUUID(), idAttachFolder, std::string(), NULL);
821 //gInventory.notifyObservers(); <- done further down in LLVOAvatar::attachObject()
822 }
1432 } 823 }
1433 } 824 }
1434 } 825 }
@@ -1515,6 +906,28 @@ bool RlvHandler::onGC()
1515 return (0 != m_Objects.size()); // GC will kill itself if it has nothing to do 906 return (0 != m_Objects.size()); // GC will kill itself if it has nothing to do
1516} 907}
1517 908
909// Checked: 2009-11-26 (RLVa-1.1.0f) | Added: RLVa-1.1.0f
910void RlvHandler::onIdleStartup(void* pParam)
911{
912 LLTimer* pTimer = (LLTimer*)pParam;
913 if (LLStartUp::getStartupState() < STATE_STARTED)
914 {
915 // We don't want to run this *too* often
916 if ( (LLStartUp::getStartupState() >= STATE_MISC) && (pTimer->getElapsedTimeF32() >= 2.0) )
917 {
918 gRlvHandler.processRetainedCommands(RLV_BHVR_VERSION, RLV_TYPE_REPLY);
919 gRlvHandler.processRetainedCommands(RLV_BHVR_VERSIONNUM, RLV_TYPE_REPLY);
920 pTimer->reset();
921 }
922 }
923 else
924 {
925 // Clean-up
926 gIdleCallbacks.deleteFunction(onIdleStartup, pParam);
927 delete pTimer;
928 }
929}
930
1518// ============================================================================ 931// ============================================================================
1519// String/chat censoring functions 932// String/chat censoring functions
1520// 933//
@@ -1593,13 +1006,14 @@ void RlvHandler::filterLocation(std::string& strUTF8Text) const
1593 1006
1594 // Filter any mention of the surrounding region names 1007 // Filter any mention of the surrounding region names
1595 LLWorld::region_list_t regions = LLWorld::getInstance()->getRegionList(); 1008 LLWorld::region_list_t regions = LLWorld::getInstance()->getRegionList();
1009 const std::string& strHiddenRegion = RlvStrings::getString(RLV_STRING_HIDDEN_REGION);
1596 for (LLWorld::region_list_t::const_iterator itRegion = regions.begin(); itRegion != regions.end(); ++itRegion) 1010 for (LLWorld::region_list_t::const_iterator itRegion = regions.begin(); itRegion != regions.end(); ++itRegion)
1597 rlvStringReplace(strUTF8Text, (*itRegion)->getName(), rlv_handler_t::cstrHiddenRegion); 1011 rlvStringReplace(strUTF8Text, (*itRegion)->getName(), strHiddenRegion);
1598 1012
1599 // Filter any mention of the parcel name 1013 // Filter any mention of the parcel name
1600 LLViewerParcelMgr* pParcelMgr = LLViewerParcelMgr::getInstance(); 1014 LLViewerParcelMgr* pParcelMgr = LLViewerParcelMgr::getInstance();
1601 if (pParcelMgr) 1015 if (pParcelMgr)
1602 rlvStringReplace(strUTF8Text, pParcelMgr->getAgentParcelName(), rlv_handler_t::cstrHiddenParcel); 1016 rlvStringReplace(strUTF8Text, pParcelMgr->getAgentParcelName(), RlvStrings::getString(RLV_STRING_HIDDEN_PARCEL));
1603} 1017}
1604 1018
1605void RlvHandler::filterNames(std::string& strUTF8Text) const 1019void RlvHandler::filterNames(std::string& strUTF8Text) const
@@ -1638,55 +1052,36 @@ void RlvHandler::filterNames(std::string& strUTF8Text) const
1638 { 1052 {
1639 strName = strFirstName + " " + strLastName; 1053 strName = strFirstName + " " + strLastName;
1640 1054
1641 rlvStringReplace(strUTF8Text, strName, getAnonym(strName)); 1055 rlvStringReplace(strUTF8Text, strName, RlvStrings::getAnonym(strName));
1642 } 1056 }
1643 } 1057 }
1644 #endif 1058 #endif
1645} 1059}
1646 1060
1647const std::string& RlvHandler::getAnonym(const std::string& strName) const 1061// Checked: 2010-02-27 (RLVa-1.1.1a) | Modified: RLVa-1.2.0a
1648{
1649 const char* pszName = strName.c_str();
1650 U32 nHash = 0;
1651
1652 // Test with 11,264 SL names showed a 3.33% - 3.82% occurance for each so we *should* get a very even spread
1653 for (int idx = 0, cnt = strName.length(); idx < cnt; idx++)
1654 nHash += pszName[idx];
1655
1656 return cstrAnonyms[nHash % 28];
1657}
1658
1659// Checked: 2009-07-07 (RLVa-1.0.0d) | Modified: RLVa-0.2.2a
1660bool RlvHandler::redirectChatOrEmote(const std::string& strUTF8Text) const 1062bool RlvHandler::redirectChatOrEmote(const std::string& strUTF8Text) const
1661{ 1063{
1662 // Sanity check - @redirchat only for chat and @rediremote only for emotes 1064 // Sanity check - @redirchat only for chat and @rediremote only for emotes
1663 bool fIsEmote = rlvIsEmote(strUTF8Text); 1065 ERlvBehaviour eBhvr = (!rlvIsEmote(strUTF8Text)) ? RLV_BHVR_REDIRCHAT : RLV_BHVR_REDIREMOTE;
1664 if ( ((!fIsEmote) && (!hasBehaviour(RLV_BHVR_REDIRCHAT))) || ((fIsEmote) && (!hasBehaviour(RLV_BHVR_REDIREMOTE))) ) 1066 if (!hasBehaviour(eBhvr))
1665 return false; 1067 return false;
1666 1068
1667 if (!fIsEmote) 1069 if (RLV_BHVR_REDIRCHAT == eBhvr)
1668 { 1070 {
1669 std::string strText = strUTF8Text; 1071 std::string strText = strUTF8Text;
1670 filterChat(strText, true); 1072 filterChat(strText, false);
1671 if (strText != "...") 1073 if (strText != "...")
1672 return false; // @sendchat wouldn't filter it so @redirchat won't redirect it either 1074 return false; // @sendchat wouldn't filter it so @redirchat won't redirect it either
1673 } 1075 }
1674 1076
1675 bool fSendChannel = hasBehaviour(RLV_BHVR_SENDCHANNEL); S32 nChannel = 0; 1077 for (rlv_exception_map_t::const_iterator itRedir = m_Exceptions.lower_bound(eBhvr),
1676 for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj) 1078 endRedir = m_Exceptions.upper_bound(eBhvr); itRedir != endRedir; ++itRedir)
1677 { 1079 {
1678 for (rlv_command_list_t::const_iterator itCmd = itObj->second.m_Commands.begin(), 1080 S32 nChannel = boost::get<S32>(itRedir->second.varOption);
1679 endCmd = itObj->second.m_Commands.end(); itCmd != endCmd; ++itCmd) 1081 if ( (!hasBehaviour(RLV_BHVR_SENDCHANNEL)) || (isException(RLV_BHVR_SENDCHANNEL, nChannel)) )
1680 { 1082 rlvSendChatReply(nChannel, strUTF8Text);
1681 if ( ( ((!fIsEmote) && (RLV_BHVR_REDIRCHAT == itCmd->getBehaviourType())) || // Redirect if: (not an emote and @redirchat
1682 ((fIsEmote) && (RLV_BHVR_REDIREMOTE == itCmd->getBehaviourType())) ) && // OR an emote and @rediremote)
1683 (LLStringUtil::convertToS32(itCmd->getOption(), nChannel)) && // AND the channel is a number
1684 ( (!fSendChannel) || (isException(RLV_BHVR_SENDCHANNEL, nChannel)) ) ) // AND we're allowed to send to that channel
1685 {
1686 rlvSendChatReply(nChannel, strUTF8Text);
1687 }
1688 }
1689 } 1083 }
1084
1690 return true; 1085 return true;
1691} 1086}
1692 1087
@@ -1694,7 +1089,8 @@ bool RlvHandler::redirectChatOrEmote(const std::string& strUTF8Text) const
1694// Public service functions (called by the outside world or by extension handlers) 1089// Public service functions (called by the outside world or by extension handlers)
1695// 1090//
1696 1091
1697BOOL RlvHandler::isAgentNearby(const LLUUID& uuid) const 1092// Checked: 2009-11-24 (RLVa-1.1.0e)
1093bool RlvHandler::isAgentNearby(const LLUUID& idAgent) const
1698{ 1094{
1699 #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 1095 #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11
1700 for (LLWorld::region_list_t::const_iterator itRegion = LLWorld::getInstance()->mActiveRegionList.begin(); 1096 for (LLWorld::region_list_t::const_iterator itRegion = LLWorld::getInstance()->mActiveRegionList.begin();
@@ -1704,20 +1100,19 @@ BOOL RlvHandler::isAgentNearby(const LLUUID& uuid) const
1704 1100
1705 for (S32 idxAgent = 0, cntAgent = pRegion->mMapAvatars.count(); idxAgent < cntAgent; idxAgent++) 1101 for (S32 idxAgent = 0, cntAgent = pRegion->mMapAvatars.count(); idxAgent < cntAgent; idxAgent++)
1706 if (pRegion->mMapAvatarIDs.get(idxAgent) == uuid) 1102 if (pRegion->mMapAvatarIDs.get(idxAgent) == uuid)
1707 return TRUE; 1103 return true;
1708 } 1104 }
1709 #else // Version: trunk 1105 #else // Version: 1.23.4
1710 // TODO-RLV: rewrite this to fit trunk, but still need the radius limited to a sane range
1711 std::vector<LLUUID> idAgents; 1106 std::vector<LLUUID> idAgents;
1712 LLWorld::getInstance()->getAvatars(&idAgents, NULL); 1107 LLWorld::getInstance()->getAvatars(&idAgents, NULL);
1713 1108
1714 for (int idxAgent = 0, cntAgent = idAgents.size(); idxAgent < cntAgent; idxAgent++) 1109 for (int idxAgent = 0, cntAgent = idAgents.size(); idxAgent < cntAgent; idxAgent++)
1715 { 1110 {
1716 if (idAgents[idxAgent] == uuid) 1111 if (idAgents[idxAgent] == idAgent)
1717 return TRUE; 1112 return true;
1718 } 1113 }
1719 #endif 1114 #endif
1720 return FALSE; 1115 return false;
1721} 1116}
1722 1117
1723// ============================================================================ 1118// ============================================================================
@@ -1733,7 +1128,7 @@ public:
1733 virtual void done() 1128 virtual void done()
1734 { 1129 {
1735 RLV_INFOS << "Shared folders fetch completed" << LL_ENDL; 1130 RLV_INFOS << "Shared folders fetch completed" << LL_ENDL;
1736 RlvHandler::m_fFetchComplete = TRUE; 1131 RlvHandler::m_fFetchComplete = true;
1737 1132
1738 gInventory.removeObserver(this); 1133 gInventory.removeObserver(this);
1739 delete this; 1134 delete this;
@@ -1749,26 +1144,22 @@ void RlvHandler::fetchSharedInventory()
1749 return; 1144 return;
1750 1145
1751 // Grab all the folders under the shared root 1146 // Grab all the folders under the shared root
1752 LLInventoryModel::cat_array_t folders; 1147 LLInventoryModel::cat_array_t folders;
1753 LLInventoryModel::item_array_t items; 1148 LLInventoryModel::item_array_t items;
1754 gInventory.collectDescendents(pRlvRoot->getUUID(), folders, items, FALSE); 1149 gInventory.collectDescendents(pRlvRoot->getUUID(), folders, items, FALSE);
1755 1150
1756 /* 1151 // Add them to the "to fetch" list
1757 * Add them to the "to fetch" list
1758 */
1759 LLInventoryFetchDescendentsObserver::folder_ref_t fetchFolders; 1152 LLInventoryFetchDescendentsObserver::folder_ref_t fetchFolders;
1760
1761 fetchFolders.push_back(pRlvRoot->getUUID()); 1153 fetchFolders.push_back(pRlvRoot->getUUID());
1762 for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++) 1154 for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++)
1763 fetchFolders.push_back(folders.get(idxFolder)->getUUID()); 1155 fetchFolders.push_back(folders.get(idxFolder)->getUUID());
1764 1156
1765 /* 1157 // Now fetch them all in one go
1766 * Now fetch them all in one go
1767 */
1768 RlvSharedRootFetcher* fetcher = new RlvSharedRootFetcher; 1158 RlvSharedRootFetcher* fetcher = new RlvSharedRootFetcher;
1769 1159
1770 RLV_INFOS << "Starting fetch of " << fetchFolders.size() << " shared folders" << LL_ENDL; 1160 RLV_INFOS << "Starting fetch of " << fetchFolders.size() << " shared folders" << RLV_ENDL;
1771 fetcher->fetchDescendents(fetchFolders); 1161 fetcher->fetchDescendents(fetchFolders);
1162 m_fFetchStarted = true;
1772 1163
1773 if (fetcher->isEverythingComplete()) 1164 if (fetcher->isEverythingComplete())
1774 fetcher->done(); 1165 fetcher->done();
@@ -1796,7 +1187,7 @@ LLViewerInventoryCategory* RlvHandler::getSharedRoot()
1796{ 1187{
1797 if (gInventory.isInventoryUsable()) 1188 if (gInventory.isInventoryUsable())
1798 { 1189 {
1799 LLInventoryModel::cat_array_t* pFolders; 1190 LLInventoryModel::cat_array_t* pFolders;
1800 LLInventoryModel::item_array_t* pItems; 1191 LLInventoryModel::item_array_t* pItems;
1801 gInventory.getDirectDescendentsOf(gAgent.getInventoryRootID(), pFolders, pItems); 1192 gInventory.getDirectDescendentsOf(gAgent.getInventoryRootID(), pFolders, pItems);
1802 if (pFolders) 1193 if (pFolders)
@@ -1902,15 +1293,15 @@ std::string RlvHandler::getSharedPath(const LLViewerInventoryCategory* pFolder)
1902// Composite folders 1293// Composite folders
1903// 1294//
1904 1295
1905#ifdef RLV_EXPERIMENTAL_COMPOSITES 1296#ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
1906 // Checked: 1297 // Checked: 2009-12-18 (RLVa-1.1.0k) | Modified: RLVa-1.1.0i
1907 bool RlvHandler::getCompositeInfo(const LLInventoryCategory* pFolder, std::string* pstrName) const 1298 bool RlvHandler::getCompositeInfo(const LLInventoryCategory* pFolder, std::string* pstrName) const
1908 { 1299 {
1909 if (pFolder) 1300 if (pFolder)
1910 { 1301 {
1911 // Composite folder naming: ^\.?[Folder] 1302 // Composite folder naming: ^\.?[Folder]
1912 const std::string& cstrFolder = pFolder->getName(); 1303 const std::string& cstrFolder = pFolder->getName();
1913 int idxStart = cstrFolder.find('['), idxEnd = cstrFolder.find(']', idxStart); 1304 std::string::size_type idxStart = cstrFolder.find('['), idxEnd = cstrFolder.find(']', idxStart);
1914 if ( ((0 == idxStart) || (1 == idxStart)) && (idxEnd - idxStart > 1) ) 1305 if ( ((0 == idxStart) || (1 == idxStart)) && (idxEnd - idxStart > 1) )
1915 { 1306 {
1916 if (pstrName) 1307 if (pstrName)
@@ -1921,21 +1312,17 @@ std::string RlvHandler::getSharedPath(const LLViewerInventoryCategory* pFolder)
1921 return false; 1312 return false;
1922 } 1313 }
1923 1314
1924 // Checked: 1315 // Checked: 2009-12-18 (RLVa-1.1.0k) | Modified: RLVa-1.1.0i
1925 bool RlvHandler::getCompositeInfo(const LLUUID& idItem, std::string* pstrName, LLViewerInventoryCategory** ppFolder) const 1316 bool RlvHandler::getCompositeInfo(const LLUUID& idItem, std::string* pstrName, LLViewerInventoryCategory** ppFolder) const
1926 { 1317 {
1927 LLViewerInventoryCategory* pRlvRoot; LLViewerInventoryItem* pItem; 1318 LLViewerInventoryCategory* pRlvRoot; LLViewerInventoryItem* pItem;
1928
1929 if ( (idItem.notNull()) && ((pRlvRoot = getSharedRoot()) != NULL) && 1319 if ( (idItem.notNull()) && ((pRlvRoot = getSharedRoot()) != NULL) &&
1930 (gInventory.isObjectDescendentOf(idItem, pRlvRoot->getUUID())) && ((pItem = gInventory.getItem(idItem)) != NULL) ) 1320 (gInventory.isObjectDescendentOf(idItem, pRlvRoot->getUUID())) && ((pItem = gInventory.getItem(idItem)) != NULL) )
1931 { 1321 {
1932 // We know it's an item in a folder under the shared root... 1322 // We know it's an item in a folder under the shared root (we need its parent if it's a folded folder)
1933 LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID()); 1323 LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID());
1934 if (getAttachPoint(pFolder, true)) 1324 if (isFoldedFolder(pFolder, true, false)) // Don't check if the folder is a composite folder
1935 {
1936 // ... but it could be named ".(attachpt)" in which case we need its parent
1937 pFolder = gInventory.getCategory(pFolder->getParentUUID()); 1325 pFolder = gInventory.getCategory(pFolder->getParentUUID());
1938 }
1939 1326
1940 if ( (pFolder) && (getCompositeInfo(pFolder, pstrName)) ) 1327 if ( (pFolder) && (getCompositeInfo(pFolder, pstrName)) )
1941 { 1328 {
@@ -1946,7 +1333,7 @@ std::string RlvHandler::getSharedPath(const LLViewerInventoryCategory* pFolder)
1946 } 1333 }
1947 return false; 1334 return false;
1948 } 1335 }
1949#endif // RLV_EXPERIMENTAL_COMPOSITES 1336#endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
1950 1337
1951#ifdef RLV_EXPERIMENTAL_COMPOSITE_FOLDING 1338#ifdef RLV_EXPERIMENTAL_COMPOSITE_FOLDING
1952 // Checked: 1339 // Checked:
@@ -1985,367 +1372,124 @@ std::string RlvHandler::getSharedPath(const LLViewerInventoryCategory* pFolder)
1985 } 1372 }
1986#endif // RLV_EXPERIMENTAL_COMPOSITEFOLDING 1373#endif // RLV_EXPERIMENTAL_COMPOSITEFOLDING
1987 1374
1988#ifdef RLV_EXPERIMENTAL_COMPOSITE_LOCKING 1375#ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
1989 // Checked: 1376 // Checked: 2009-12-18 (RLVa-1.1.0k) | Modified: RLVa-1.1.0i
1990 bool RlvHandler::canTakeOffComposite(const LLInventoryCategory* pFolder) const 1377 bool RlvHandler::canTakeOffComposite(const LLInventoryCategory* pFolder) const
1991 { 1378 {
1992 if (!pFolder) // If there's no folder then there is nothing to take off 1379 // Sanity check - if there's no folder or no avatar then there is nothing to take off
1380 LLVOAvatar* pAvatar = gAgent.getAvatarObject();
1381 if ( (!pFolder) || (!pAvatar) )
1993 return false; 1382 return false;
1383 // Sanity check - if nothing is locked then we can definitely take it off
1384 if ( (!hasBehaviour(RLV_BHVR_REMOUTFIT)) && (!hasLockedAttachment(RLV_LOCK_REMOVE)) )
1385 return true;
1994 1386
1995 LLInventoryModel::cat_array_t folders; 1387 LLInventoryModel::cat_array_t folders;
1996 LLInventoryModel::item_array_t items; 1388 LLInventoryModel::item_array_t items;
1997 RlvWearableItemCollector functor(pFolder->getUUID(), true, false); 1389 RlvWearableItemCollector functor(pFolder->getUUID(), true, false);
1998
1999 // Grab a list of all the items @detachthis would be detaching/unwearing
2000 gInventory.collectDescendentsIf(pFolder->getUUID(), folders, items, FALSE, functor); 1390 gInventory.collectDescendentsIf(pFolder->getUUID(), folders, items, FALSE, functor);
2001 if (!items.count())
2002 return false; // There are no wearable items in the folder so there is nothing to take off
2003 1391
2004 LLViewerInventoryItem* pItem;
2005 for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++) 1392 for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++)
2006 { 1393 {
2007 pItem = items.get(idxItem); 1394 const LLViewerInventoryItem* pItem = items.get(idxItem);
2008
2009 switch (pItem->getType()) 1395 switch (pItem->getType())
2010 { 1396 {
1397 case LLAssetType::AT_BODYPART:
2011 case LLAssetType::AT_CLOTHING: 1398 case LLAssetType::AT_CLOTHING:
2012 { 1399 {
2013 LLWearable* pWearable = gAgent.getWearableFromWearableItem(pItem->getUUID()); 1400 LLWearable* pWearable = gAgent.getWearableFromWearableItem(pItem->getUUID());
2014 if ( (pWearable) && (!isRemovable(pWearable->getType())) ) 1401 if ( (pWearable) && (!isRemovable(pWearable->getType())) )
2015 return false; // If one clothing layer in the composite folder is unremoveable then the entire folder is 1402 return false; // If one wearable in the folder is non-removeable then the entire folder should be
2016 } 1403 }
2017 break; 1404 break;
2018 case LLAssetType::AT_OBJECT: 1405 case LLAssetType::AT_OBJECT:
2019 { 1406 {
2020 LLVOAvatar* pAvatar; LLViewerObject* pObj; 1407 LLViewerObject* pObj = pAvatar->getWornAttachment(pItem->getUUID());
2021 if ( ((pAvatar = gAgent.getAvatarObject()) != NULL) && 1408 if ( (pObj != NULL) && (isLockedAttachment(pObj, RLV_LOCK_REMOVE)) )
2022 ((pObj = pAvatar->getWornAttachment(pItem->getUUID())) != NULL) && (!isDetachable(pObj)) ) 1409 return false; // If one attachment in the folder is non-detachable then the entire folder should be
2023 {
2024 return false; // If one attachment in the composite folder is undetachable then the entire folder is
2025 }
2026 } 1410 }
2027 break; 1411 break;
2028 #ifdef LL_GNUC
2029 default: 1412 default:
2030 break; 1413 break;
2031 #endif // LL_GNUC
2032 } 1414 }
2033 } 1415 }
2034 return true; 1416 return true;
2035 } 1417 }
2036#endif // RLV_EXPERIMENTAL_COMPOSITE_LOCKING
2037
2038// ============================================================================
2039// Event handlers
2040//
2041
2042// Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0d
2043void RlvHandler::onForceRemOutfit(const LLUUID& idObj, const std::string& strOption) const
2044{
2045 EWearableType typeOption = LLWearable::typeNameToType(strOption), type;
2046 if ( (WT_INVALID == typeOption) && (!strOption.empty()) )
2047 return;
2048
2049 // Before we had an option and optionless branch, but with the addition of composites and nostrip there's less duplication this way
2050 for (int idxType = 0; idxType < WT_COUNT; idxType++)
2051 {
2052 type = (EWearableType)idxType;
2053 if (LLAssetType::AT_CLOTHING != LLWearable::typeToAssetType(type))
2054 continue; // Only strip clothing, not bodyparts
2055
2056 if ( ((typeOption == type) || (strOption.empty())) && (gAgent.getWearable(type)) && (isStrippable(gAgent.getWearableItem(type))) )
2057 {
2058 #ifdef RLV_EXPERIMENTAL_COMPOSITES
2059 // If we're stripping something that's part of a composite folder then we should @detachthis instead
2060 if (isCompositeDescendent(gAgent.getWearableItem(type)))
2061 {
2062 std::string strCmd = "detachthis:" + LLWearable::typeToTypeName(type) + "=force";
2063 #ifdef RLV_DEBUG
2064 RLV_INFOS << "\t- '" << LLWearable::typeToTypeName(type) << "' is composite descendent: @" << strCmd << LL_ENDL;
2065 #endif // RLV_DEBUG
2066 processForceCommand(idObj, RlvCommand(strCmd));
2067 }
2068 else
2069 #endif // RLV_EXPERIMENTAL_COMPOSITES
2070 {
2071 gAgent.removeWearable(type);
2072 }
2073 }
2074 }
2075}
2076 1418
2077// Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0g 1419 // Checked: 2009-12-18 (RLVa-1.1.0k) | Modified: RLVa-1.1.0i
2078bool RlvHandler::onForceSit(const LLUUID& idObj, const std::string& strOption) const 1420 bool RlvHandler::canWearComposite(const LLInventoryCategory* pFolder) const
2079{
2080 LLViewerObject* pObject = NULL; LLUUID idTarget(strOption);
2081 // Sanity checking - we need to know about the object and it should identify a prim/linkset
2082 if ( (idTarget.isNull()) || ((pObject = gObjectList.findObject(idTarget)) == NULL) || (LL_PCODE_VOLUME != pObject->getPCode()) )
2083 return false;
2084
2085 // Don't force sit if:
2086 // 1) currently sitting and prevented from standing up
2087 // 2) prevented from sitting
2088 // 3) @sittp=n restricted (except if @sittp=n was issued by the same prim that's currently force sitting the avie)
2089 if ( ( (hasBehaviour(RLV_BHVR_UNSIT)) && (gAgent.getAvatarObject()) && (gAgent.getAvatarObject()->mIsSitting) ) ||
2090 ( (hasBehaviour(RLV_BHVR_SIT)) ) ||
2091 ( (hasBehaviourExcept(RLV_BHVR_SITTP, idObj)) &&
2092 (dist_vec_squared(gAgent.getPositionGlobal(), pObject->getPositionGlobal()) > 1.5f * 1.5f) ))
2093 { 1421 {
2094 return false; 1422 // Sanity check - if there's no folder or no avatar then there is nothing to wear
2095 } 1423 LLVOAvatar* pAvatar = gAgent.getAvatarObject();
2096 1424 if ( (!pFolder) || (!pAvatar) )
2097 // Copy/paste from handle_sit_or_stand() [see http://wiki.secondlife.com/wiki/AgentRequestSit] 1425 return false;
2098 gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit); 1426 // Sanity check - if nothing is locked then we can definitely wear it
2099 gMessageSystem->nextBlockFast(_PREHASH_AgentData); 1427 if ( (!hasBehaviour(RLV_BHVR_ADDOUTFIT)) && (!hasBehaviour(RLV_BHVR_REMOUTFIT)) && (!hasLockedAttachment(RLV_LOCK_ANY)) )
2100 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); 1428 return true;
2101 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
2102 gMessageSystem->nextBlockFast(_PREHASH_TargetObject);
2103 gMessageSystem->addUUIDFast(_PREHASH_TargetID, pObject->mID);
2104 // Offset: "a rough position in local coordinates for the edge to sit on"
2105 // (we might not even be looking at the object so I don't think we can supply the offset to an edge)
2106 gMessageSystem->addVector3Fast(_PREHASH_Offset, LLVector3::zero);
2107 pObject->getRegion()->sendReliableMessage();
2108
2109 return true;
2110}
2111
2112// Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a
2113void RlvHandler::onForceWear(const std::string& strPath, bool fAttach, bool fMatchAll) const
2114{
2115 // See LLWearableBridge::wearOnAvatar(): don't wear anything until initial wearables are loaded, can destroy clothing items
2116 if (!gAgent.areWearablesLoaded())
2117 return;
2118
2119 LLViewerInventoryCategory* pFolder = getSharedFolder(strPath);
2120 if (!pFolder) // Folder not found = nothing to attach
2121 return;
2122 1429
2123 LLInventoryModel::cat_array_t folders; 1430 LLInventoryModel::cat_array_t folders;
2124 LLInventoryModel::item_array_t items; 1431 LLInventoryModel::item_array_t items;
2125 RlvWearableItemCollector functor(pFolder->getUUID(), fAttach, fMatchAll); 1432 RlvWearableItemCollector functor(pFolder->getUUID(), true, false);
1433 gInventory.collectDescendentsIf(pFolder->getUUID(), folders, items, FALSE, functor);
2126 1434
2127 // Grab a list of all the items we'll be wearing/attaching 1435 for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++)
2128 gInventory.collectDescendentsIf(pFolder->getUUID(), folders, items, FALSE, functor); 1436 {
1437 LLViewerInventoryItem* pItem = items.get(idxItem);
2129 1438
2130 LLViewerInventoryItem* pItem; 1439 if (RlvForceWear::isWearingItem(pItem))
2131 for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++) 1440 continue; // Don't examine any items we're already wearing
2132 {
2133 pItem = items.get(idxItem);
2134 1441
2135 switch (pItem->getType()) 1442 // A wearable layer or attachment point:
2136 { 1443 // - can't be "add locked"
2137 case LLAssetType::AT_CLOTHING: 1444 // - can't be worn and "remove locked"
2138 case LLAssetType::AT_BODYPART: 1445 // - can't be worn and have its item belong to a *different* composite folder that we can't take off
2139 { 1446 switch (pItem->getType())
2140 LLWearable* pWearable = gAgent.getWearableFromWearableItem(pItem->getUUID()); 1447 {
2141 1448 case LLAssetType::AT_BODYPART:
2142 #ifdef RLV_EXPERIMENTAL_COMPOSITE_LOCKING 1449 case LLAssetType::AT_CLOTHING:
2143 // If we're already wearing something on this layer then we have to check if it isn't part of a composite 1450 {
2144 // folder that has at least one unremovable item (in which case we can't wear or remove this item) 1451 // NOTE: without its asset we don't know what type the wearable is so we need to look at the item's flags instead
2145 LLViewerInventoryCategory* pCompositeFolder; 1452 EWearableType wtType = (EWearableType)(pItem->getFlags() & LLInventoryItem::II_FLAGS_WEARABLES_MASK);
2146 if ( (!pWearable) || (!getCompositeInfo(pItem->getUUID(), NULL, &pCompositeFolder)) || 1453 LLViewerInventoryCategory* pFolder;
2147 (canTakeOffComposite(pFolder))) 1454 if ( (!isWearable(wtType)) ||
1455 ( (gAgent.getWearable(wtType)) && (!isRemovable(wtType)) ) ||
1456 ( (gRlvHandler.getCompositeInfo(gAgent.getWearableItem(wtType), NULL, &pFolder)) &&
1457 (pFolder->getUUID() != pItem->getParentUUID()) && (!gRlvHandler.canTakeOffComposite(pFolder)) ) )
2148 { 1458 {
2149 #endif // RLV_EXPERIMENTAL_COMPOSITE_LOCKING 1459 return false;
2150 if (fAttach)
2151 {
2152 // Simulate wearing a clothing item from inventory (right click / "Wear")
2153 // LLWearableBridge::performAction() => LLWearableBridge::wearOnAvatar() => wear_inventory_item_on_avatar()
2154 wear_inventory_item_on_avatar(pItem);
2155 }
2156 else
2157 {
2158 if ( (pWearable) && (LLAssetType::AT_CLOTHING == pItem->getType()) )
2159 gAgent.removeWearable(pWearable->getType());
2160 }
2161 #ifdef RLV_EXPERIMENTAL_COMPOSITE_LOCKING
2162 } 1460 }
2163 #endif // RLV_EXPERIMENTAL_COMPOSITE_LOCKING 1461 }
2164 } 1462 break;
2165 break; 1463 case LLAssetType::AT_OBJECT:
2166 case LLAssetType::AT_OBJECT: 1464 {
2167 { 1465 // If we made it here then *something* is add/remove locked so we absolutely need to know its attachment point
2168 LLVOAvatar* pAvatar = gAgent.getAvatarObject(); 1466 LLViewerJointAttachment* pAttachPt = getAttachPoint(pItem, true);
2169 LLViewerObject* pObj; 1467 LLViewerInventoryCategory* pFolder;
2170 1468 if ( (!pAttachPt) || (isLockedAttachment(pAttachPt, RLV_LOCK_ADD)) ||
2171 #ifdef RLV_EXPERIMENTAL_COMPOSITE_LOCKING 1469 ( (pAttachPt->getObject()) && (isLockedAttachment(pAttachPt, RLV_LOCK_REMOVE)) ) ||
2172 // If we're already wearing something on this attach point then we have to check if it isn't part of a composite 1470 ( (gRlvHandler.getCompositeInfo(pAttachPt->getItemID(), NULL, &pFolder)) &&
2173 // folder that has at least one unremovable item (in which case we can't attach or detach this item) 1471 (pFolder->getUUID() != pItem->getParentUUID()) && (!gRlvHandler.canTakeOffComposite(pFolder)) ) )
2174 LLViewerInventoryCategory* pCompositeFolder;
2175 if ( (pAvatar) &&
2176 ( ((pObj = pAvatar->getWornAttachment(pItem->getUUID())) == NULL) ||
2177 (!getCompositeInfo(pItem->getUUID(), NULL, &pCompositeFolder)) || (canTakeOffComposite(pFolder)) ) )
2178 { 1472 {
2179 #endif // RLV_EXPERIMENTAL_COMPOSITE_LOCKING 1473 return false;
2180 if (fAttach)
2181 {
2182 // Simulate wearing an object to a specific attachment point (copy/paste to suppress replacement dialog)
2183 // LLAttachObject::handleEvent() => rez_attachment()
2184 LLViewerJointAttachment* pAttachPt = getAttachPoint(pItem, true);
2185 if ( (pAttachPt) && // Need a specific attach pt that
2186 ( (!isLockedAttachment(pAttachPt->getObject(), RLV_LOCK_REMOVE)) && // doesn't have locked object
2187 (!isLockedAttachment(pAttachPt, RLV_LOCK_ADD)) ) ) // and that can be attached to
2188 {
2189 RlvAttachmentManager::forceAttach(pItem->getUUID(), getAttachPointIndex(pAttachPt->getName(), true));
2190 }
2191 }
2192 else
2193 {
2194 if ( (pAvatar) && ((pObj = pAvatar->getWornAttachment(pItem->getUUID())) != NULL) )
2195 {
2196 LLViewerJointAttachment* pAttachment = pAvatar->getTargetAttachmentPoint(pObj);
2197 if (pAttachment)
2198 handle_detach_from_avatar(pAttachment);
2199 }
2200 }
2201 #ifdef RLV_EXPERIMENTAL_COMPOSITE_LOCKING
2202 } 1474 }
2203 #endif // RLV_EXPERIMENTAL_COMPOSITE_LOCKING 1475 }
2204 } 1476 break;
2205 break; 1477 default:
2206 #ifdef LL_GNUC 1478 break;
2207 default: 1479 }
2208 break;
2209 #endif // LL_GNUC
2210 }
2211 }
2212}
2213
2214// Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0g
2215bool RlvHandler::onGetPath(const LLUUID &uuid, const std::string& strOption, std::string& strReply) const
2216{
2217 // Sanity check - no need to go through all this trouble if we don't have a shared root
2218 LLViewerInventoryCategory* pRlvRoot = getSharedRoot();
2219 if (!pRlvRoot)
2220 return false;
2221
2222 LLUUID idItem;
2223
2224 // <option> can be a clothing layer
2225 EWearableType layerType = LLWearable::typeNameToType(strOption);
2226 if (WT_INVALID != layerType)
2227 {
2228 idItem = gAgent.getWearableItem(layerType);
2229 }
2230 else
2231 {
2232 LLViewerJointAttachment* pAttachPt = NULL;
2233
2234 // ... or it can be empty
2235 if (strOption.empty())
2236 {
2237 // (in which case we act on the object that issued the command)
2238 LLViewerObject* pObj = gObjectList.findObject(uuid);
2239 if ( (pObj) && (pObj->isAttachment()) && (gAgent.getAvatarObject()) )
2240 pAttachPt = gAgent.getAvatarObject()->getTargetAttachmentPoint(pObj);
2241 }
2242 else
2243 {
2244 // ... or it can specify an attach point
2245 pAttachPt = getAttachPoint(strOption, true);
2246 }
2247
2248 // If we found something, get its inventory item UUID
2249 if (pAttachPt)
2250 idItem = pAttachPt->getItemID();
2251 }
2252
2253 // If we found something and it's under the shared root, then get its path
2254 if ( (!idItem.isNull()) && (gInventory.isObjectDescendentOf(idItem, pRlvRoot->getUUID())) )
2255 {
2256 LLInventoryItem* pItem = gInventory.getItem(idItem);
2257 if (pItem)
2258 {
2259 // ... unless the containing folder's name specifies an attach point (or nostrip) in which case we need its parent
2260 LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID());
2261 #ifdef RLV_EXTENSION_FLAG_NOSTRIP
2262 if ( (getAttachPoint(pFolder, true)) || (pFolder->getName() == ".("RLV_FOLDER_FLAG_NOSTRIP")") )
2263 #else
2264 if (getAttachPoint(pFolder, true))
2265 #endif // RLV_EXTENSION_FLAG_NOSTRIP
2266 strReply = getSharedPath(pFolder->getParentUUID());
2267 else
2268 strReply = getSharedPath(pFolder);
2269 } 1480 }
1481 return true;
2270 } 1482 }
2271 return !strReply.empty(); 1483#endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
2272}
2273
2274struct rlv_wear_info { U32 cntWorn, cntTotal, cntChildWorn, cntChildTotal; };
2275
2276// Checked: 2009-05-30 (RLVa-0.2.0e) | Modified: RLVa-0.2.0e
2277void RlvHandler::onGetInvWorn(const std::string& strPath, std::string& strReply) const
2278{
2279 // Sanity check - getAvatarObject() can't be NULL [see rlvIsWearingItem()] and the folder should exist and not be hidden
2280 LLViewerInventoryCategory* pFolder = getSharedFolder(strPath);
2281 if ((!gAgent.getAvatarObject()) || (!pFolder) || (pFolder->getName().empty()) || (RLV_FOLDER_PREFIX_HIDDEN == pFolder->getName()[0]))
2282 return;
2283
2284 // Collect everything @attachall would be attaching
2285 LLInventoryModel::cat_array_t folders;
2286 LLInventoryModel::item_array_t items;
2287 RlvWearableItemCollector functor(pFolder->getUUID(), true, true);
2288 gInventory.collectDescendentsIf(pFolder->getUUID(), folders, items, FALSE, functor);
2289
2290 rlv_wear_info wi = {0};
2291
2292 // Add all the folders to a lookup map
2293 std::map<LLUUID, rlv_wear_info> mapFolders;
2294 mapFolders.insert(std::pair<LLUUID, rlv_wear_info>(pFolder->getUUID(), wi));
2295 for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++)
2296 mapFolders.insert(std::pair<LLUUID, rlv_wear_info>(folders.get(idxFolder)->getUUID(), wi));
2297
2298 // Iterate over all the found items
2299 LLViewerInventoryItem* pItem; std::map<LLUUID, rlv_wear_info>::iterator itFolder;
2300 for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++)
2301 {
2302 pItem = items.get(idxItem);
2303
2304 // The "folded parent" is the folder this item should be considered a direct descendent of (may or may not match actual parent)
2305 const LLUUID& idParent = functor.getFoldedParent(pItem->getParentUUID());
2306
2307 // Walk up the tree: sooner or later one of the parents will be a folder in the map
2308 LLViewerInventoryCategory* pParent = gInventory.getCategory(idParent);
2309 while ( (itFolder = mapFolders.find(pParent->getUUID())) == mapFolders.end() )
2310 pParent = gInventory.getCategory(pParent->getParentUUID());
2311
2312 U32 &cntWorn = (idParent == pParent->getUUID()) ? itFolder->second.cntWorn : itFolder->second.cntChildWorn,
2313 &cntTotal = (idParent == pParent->getUUID()) ? itFolder->second.cntTotal : itFolder->second.cntChildTotal;
2314
2315 if (rlvIsWearingItem(pItem))
2316 cntWorn++;
2317 cntTotal++;
2318 }
2319
2320 // Extract the result for the main folder
2321 itFolder = mapFolders.find(pFolder->getUUID());
2322 wi.cntWorn = itFolder->second.cntWorn;
2323 wi.cntTotal = itFolder->second.cntTotal;
2324 mapFolders.erase(itFolder);
2325
2326 // Build the result for each child folder
2327 for (itFolder = mapFolders.begin(); itFolder != mapFolders.end(); ++itFolder)
2328 {
2329 rlv_wear_info& wiFolder = itFolder->second;
2330
2331 wi.cntChildWorn += wiFolder.cntWorn + wiFolder.cntChildWorn;
2332 wi.cntChildTotal += wiFolder.cntTotal + wiFolder.cntChildTotal;
2333
2334 strReply += llformat(",%s|%d%d", gInventory.getCategory(itFolder->first)->getName().c_str(),
2335 (0 == wiFolder.cntTotal) ? 0 : (0 == wiFolder.cntWorn) ? 1 : (wiFolder.cntWorn != wiFolder.cntTotal) ? 2 : 3,
2336 (0 == wiFolder.cntChildTotal) ? 0 : (0 == wiFolder.cntChildWorn) ? 1 : (wiFolder.cntChildWorn != wiFolder.cntChildTotal) ? 2 : 3
2337 );
2338 }
2339 1484
2340 // Now just prepend the root and done 1485// ============================================================================
2341 strReply = llformat("|%d%d", (0 == wi.cntTotal) ? 0 : (0 == wi.cntWorn) ? 1 : (wi.cntWorn != wi.cntTotal) ? 2 : 3, 1486// Event handlers
2342 (0 == wi.cntChildTotal) ? 0 : (0 == wi.cntChildWorn) ? 1 : (wi.cntChildWorn != wi.cntChildTotal) ? 2: 3) + strReply; 1487//
2343}
2344 1488
2345// (In case anyone cares: this isn't used in public builds) 1489// (In case anyone cares: this isn't used in public builds)
2346bool RlvHandler::getWornInfo(const LLInventoryCategory* pFolder, U8& wiFolder, U8& wiChildren) const 1490bool RlvHandler::getWornInfo(const LLInventoryCategory* pFolder, U8& wiFolder, U8& wiChildren) const
2347{ 1491{
2348 // Sanity check - getAvatarObject() can't be NULL [see rlvIsWearingItem()] and the folder should exist and not be hidden 1492 // Sanity check - getAvatarObject() can't be NULL [see RlvForceWear::isWearingItem()] and the folder should exist and not be hidden
2349 if ((!gAgent.getAvatarObject()) || (!pFolder) || (pFolder->getName().empty()) || (RLV_FOLDER_PREFIX_HIDDEN == pFolder->getName()[0])) 1493 if ((!gAgent.getAvatarObject()) || (!pFolder) || (pFolder->getName().empty()) || (RLV_FOLDER_PREFIX_HIDDEN == pFolder->getName()[0]))
2350 return false; 1494 return false;
2351 1495
@@ -2363,7 +1507,7 @@ bool RlvHandler::getWornInfo(const LLInventoryCategory* pFolder, U8& wiFolder, U
2363 bool fDirectDescendent = (pFolder->getUUID() == functor.getFoldedParent(pItem->getParentUUID())); 1507 bool fDirectDescendent = (pFolder->getUUID() == functor.getFoldedParent(pItem->getParentUUID()));
2364 U32 &refWorn = (fDirectDescendent) ? cntWorn : cntChildWorn, &refTotal = (fDirectDescendent) ? cntTotal : cntChildTotal; 1508 U32 &refWorn = (fDirectDescendent) ? cntWorn : cntChildWorn, &refTotal = (fDirectDescendent) ? cntTotal : cntChildTotal;
2365 1509
2366 if (rlvIsWearingItem(pItem)) 1510 if (RlvForceWear::isWearingItem(pItem))
2367 refWorn++; 1511 refWorn++;
2368 refTotal++; 1512 refTotal++;
2369 } 1513 }
@@ -2379,6 +1523,7 @@ bool RlvHandler::getWornInfo(const LLInventoryCategory* pFolder, U8& wiFolder, U
2379// Initialization helper functions 1523// Initialization helper functions
2380// 1524//
2381 1525
1526// Checked: 2009-11-25 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
2382BOOL RlvHandler::setEnabled(BOOL fEnable) 1527BOOL RlvHandler::setEnabled(BOOL fEnable)
2383{ 1528{
2384 if (m_fEnabled == fEnable) 1529 if (m_fEnabled == fEnable)
@@ -2386,17 +1531,17 @@ BOOL RlvHandler::setEnabled(BOOL fEnable)
2386 1531
2387 if (fEnable) 1532 if (fEnable)
2388 { 1533 {
2389 if (gSavedSettings.controlExists(RLV_SETTING_NOSETENV)) 1534 // Initialize the command lookup table
2390 fNoSetEnv = gSavedSettings.getBOOL(RLV_SETTING_NOSETENV);
2391 if (gSavedSettings.controlExists(RLV_SETTING_ENABLELEGACYNAMING))
2392 fLegacyNaming = gSavedSettings.getBOOL(RLV_SETTING_ENABLELEGACYNAMING);
2393 if (gSavedSettings.controlExists(RLV_SETTING_SHOWNAMETAGS))
2394 RlvSettings::fShowNameTags = gSavedSettings.getBOOL(RLV_SETTING_SHOWNAMETAGS);
2395
2396 RlvCommand::initLookupTable(); 1535 RlvCommand::initLookupTable();
1536
1537 // Initialize static classes
1538 RlvSettings::initClass();
1539 RlvStrings::initClass();
1540
2397 gRlvHandler.m_pAttachMgr = new RlvAttachmentManager(); 1541 gRlvHandler.m_pAttachMgr = new RlvAttachmentManager();
2398 gRlvHandler.addObserver(new RlvExtGetSet()); 1542 gRlvHandler.addCommandHandler(new RlvExtGetSet());
2399 1543
1544 // Fetch shared inventory if we're enabled after logon
2400 if (LLStartUp::getStartupState() >= STATE_CLEANUP) 1545 if (LLStartUp::getStartupState() >= STATE_CLEANUP)
2401 fetchSharedInventory(); 1546 fetchSharedInventory();
2402 1547
@@ -2404,17 +1549,7 @@ BOOL RlvHandler::setEnabled(BOOL fEnable)
2404 } 1549 }
2405 else if (canDisable()) 1550 else if (canDisable())
2406 { 1551 {
2407 #ifdef RLV_DEBUG
2408 RLV_INFOS << "Disabling RLV:" << LL_ENDL;
2409 #endif // RLV_DEBUG
2410
2411 gRlvHandler.clearState(); 1552 gRlvHandler.clearState();
2412
2413 #ifdef RLV_DEBUG
2414 RLV_INFOS << "\t--> RLV disabled" << LL_ENDL;
2415 #endif // RLV_DEBUG
2416
2417 m_fEnabled = FALSE;
2418 } 1553 }
2419 1554
2420 #ifdef RLV_ADVANCED_MENU 1555 #ifdef RLV_ADVANCED_MENU
@@ -2466,7 +1601,7 @@ void RlvHandler::clearState()
2466 memset(m_LayersRem, 0, sizeof(S16) * WT_COUNT); 1601 memset(m_LayersRem, 0, sizeof(S16) * WT_COUNT);
2467 memset(m_Behaviours, 0, sizeof(S16) * RLV_BHVR_COUNT); 1602 memset(m_Behaviours, 0, sizeof(S16) * RLV_BHVR_COUNT);
2468 m_Retained.clear(); 1603 m_Retained.clear();
2469 m_Emitter.clearObservers(); // <- calls delete on all active observers 1604 clearCommandHandlers(); // <- calls delete on all registered command handlers
2470 1605
2471 // Clear dynamically allocated memory 1606 // Clear dynamically allocated memory
2472 delete m_pGCTimer; 1607 delete m_pGCTimer;
@@ -2481,6 +1616,359 @@ void RlvHandler::clearState()
2481// Command handlers (RLV_TYPE_ADD and RLV_TYPE_REMOVE) 1616// Command handlers (RLV_TYPE_ADD and RLV_TYPE_REMOVE)
2482// 1617//
2483 1618
1619#define VERIFY_OPTION(x) { if (!(x)) { eRet = RLV_RET_FAILED_OPTION; break; } }
1620#define VERIFY_OPTION_REF(x) { if (!(x)) { eRet = RLV_RET_FAILED_OPTION; break; } fRefCount = true; }
1621
1622// Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1623ERlvCmdRet RlvHandler::processAddRemCommand(const LLUUID& idObj, const RlvCommand& rlvCmd)
1624{
1625 // NOTE: - at this point the command has already been:
1626 // * added to the RlvObject
1627 // * removed from the RlvObject (which still exists at this point even if this is the last restriction)
1628 // - the object's UUID may or may not exist in gObjectList (see handling of @detach=n|y)
1629 ERlvBehaviour eBhvr = rlvCmd.getBehaviourType(); ERlvParamType eType = rlvCmd.getParamType();
1630
1631 ERlvCmdRet eRet = RLV_RET_SUCCESS; bool fRefCount = false, fRefreshHover = false; const std::string& strOption = rlvCmd.getOption();
1632 switch (eBhvr)
1633 {
1634 case RLV_BHVR_DETACH: // @detach[:<option>]=n|y
1635 eRet = onAddRemDetach(idObj, rlvCmd, fRefCount);
1636 break;
1637 case RLV_BHVR_ADDATTACH: // @addattach[:<option>]=n|y
1638 case RLV_BHVR_REMATTACH: // @addattach[:<option>]=n|y
1639 eRet = onAddRemAttach(idObj, rlvCmd, fRefCount);
1640 break;
1641 case RLV_BHVR_ADDOUTFIT: // @addoutfit[:<layer>]=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1642 case RLV_BHVR_REMOUTFIT: // @remoutfit[:<layer>]=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1643 {
1644 // If there's an option it should specify a wearable type name (reference count on no option *and* a valid option)
1645 EWearableType wtType = LLWearable::typeNameToType(strOption);
1646 VERIFY_OPTION_REF( (strOption.empty()) || (WT_INVALID != wtType) );
1647
1648 S16* pLayers = (RLV_BHVR_ADDOUTFIT == eBhvr) ? m_LayersAdd : m_LayersRem;
1649 for (int idxType = 0; idxType < WT_COUNT; idxType++)
1650 {
1651 if ( ((EWearableType)idxType == wtType) || (WT_INVALID == wtType) )
1652 {
1653 if (RLV_TYPE_ADD == eType)
1654 pLayers[idxType]++;
1655 else
1656 pLayers[idxType]--;
1657 }
1658 }
1659 }
1660 break;
1661 case RLV_BHVR_REDIRCHAT: // @redirchat:<channel>=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1662 case RLV_BHVR_REDIREMOTE: // @rediremote:<channel>=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1663 {
1664 // There should be an option and it should specify a valid reply channel (if there's an empty option the command is invalid)
1665 S32 nChannel = 0;
1666 VERIFY_OPTION_REF( (LLStringUtil::convertToS32(strOption, nChannel)) && (rlvIsValidReplyChannel(nChannel)) );
1667
1668 if (RLV_TYPE_ADD == eType)
1669 addException(idObj, eBhvr, nChannel);
1670 else
1671 removeException(idObj, eBhvr, nChannel);
1672 }
1673 break;
1674 case RLV_BHVR_SENDCHANNEL: // @sendchannel[:<channel>]=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1675 {
1676 // If there's an option then it should be a valid (= positive and non-zero) chat channel (only reference count empty option)
1677 S32 nChannel = 0;
1678 if ( (LLStringUtil::convertToS32(strOption, nChannel)) && (nChannel > 0) )
1679 {
1680 if (RLV_TYPE_ADD == eType)
1681 addException(idObj, eBhvr, nChannel);
1682 else
1683 removeException(idObj, eBhvr, nChannel);
1684 break;
1685 }
1686 VERIFY_OPTION_REF(strOption.empty());
1687 }
1688 break;
1689 case RLV_BHVR_NOTIFY: // @notify:<params>=add|rem - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1690 {
1691 // There should be an option that we can successfully parse (if there's an empty option the command is invalid)
1692 S32 nChannel; std::string strFilter;
1693 VERIFY_OPTION_REF( (!strOption.empty()) && (rlvParseNotifyOption(strOption, nChannel, strFilter)) );
1694
1695 if (RLV_TYPE_ADD == eType)
1696 {
1697 if (!m_pBhvrNotify)
1698 addBehaviourObserver(m_pBhvrNotify = new RlvBehaviourNotifyObserver());
1699 m_pBhvrNotify->addNotify(idObj, nChannel, strFilter);
1700 }
1701 else if (m_pBhvrNotify)
1702 {
1703 m_pBhvrNotify->removeNotify(idObj, nChannel, strFilter);
1704 if (!m_pBhvrNotify->hasNotify())
1705 {
1706 removeBehaviourObserver(m_pBhvrNotify);
1707 delete m_pBhvrNotify;
1708 m_pBhvrNotify = NULL;
1709 }
1710 }
1711 }
1712 break;
1713 case RLV_BHVR_SHOWINV: // @showinv=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1714 {
1715 VERIFY_OPTION_REF(strOption.empty());
1716
1717 if (RLV_TYPE_ADD == eType)
1718 {
1719 // Close all open inventory windows
1720 LLInventoryView::closeAll();
1721 }
1722 }
1723 break;
1724 case RLV_BHVR_SHOWMINIMAP: // @showminimap=n|y - Checked: 2009-12-05 (RLVa-1.1.0g) | Modified: RLVa-1.1.0g
1725 {
1726 VERIFY_OPTION_REF(strOption.empty());
1727
1728 if (RLV_TYPE_ADD == eType)
1729 {
1730 // Simulate clicking the Minimap button [see LLToolBar::onClickRadar()]
1731 #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11
1732 if (gFloaterMap->getVisible())
1733 LLFloaterMap::toggle(NULL);
1734 #else // Version: 1.23.4
1735 if (LLFloaterMap::instanceVisible())
1736 LLFloaterMap::hideInstance();
1737 #endif
1738 }
1739 }
1740 break;
1741 case RLV_BHVR_SHOWWORLDMAP: // @showworldmap=n|y - Checked: 2009-12-05 (RLVa-1.1.0g) | Modified: RLVa-1.1.0g
1742 {
1743 VERIFY_OPTION_REF(strOption.empty());
1744
1745 if (RLV_TYPE_ADD == eType)
1746 {
1747 // Simulate clicking the Map button [see LLToolBar::onClickMap()]
1748 if (gFloaterWorldMap->getVisible())
1749 LLFloaterWorldMap::toggle(NULL);
1750 }
1751 }
1752 break;
1753 case RLV_BHVR_SHOWLOC: // @showloc=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1754 {
1755 VERIFY_OPTION_REF(strOption.empty());
1756
1757 if (RLV_TYPE_ADD == eType)
1758 {
1759 // If this is the first @showloc=n restriction refresh all object text so we can filter it if necessary
1760 fRefreshHover = (0 == m_Behaviours[RLV_BHVR_SHOWLOC]);
1761
1762 // Close the "About Land" floater if it's currently visible
1763 if (LLFloaterLand::instanceVisible())
1764 LLFloaterLand::hideInstance();
1765
1766 // Close the "Estate Tools" floater is it's currently visible
1767 if (LLFloaterRegionInfo::instanceVisible())
1768 LLFloaterRegionInfo::hideInstance();
1769
1770 // NOTE: we should close the "God Tools" floater as well, but since calling LLFloaterGodTools::instance() always
1771 // creates a new instance of the floater and since it's very unlikely to be open it's just better not to
1772 }
1773 else
1774 {
1775 // If this is the last @showloc=n restriction refresh all object text in case anything needs restoring
1776 fRefreshHover = (1 == m_Behaviours[RLV_BHVR_SHOWLOC]);
1777 }
1778 }
1779 break;
1780 case RLV_BHVR_SHOWNAMES: // @shownames=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1781 {
1782 VERIFY_OPTION_REF(strOption.empty());
1783
1784 if (RLV_TYPE_ADD == eType)
1785 {
1786 // If this is the first @shownames=n restriction refresh all object text so we can filter it if necessary
1787 fRefreshHover = (0 == m_Behaviours[RLV_BHVR_SHOWNAMES]);
1788
1789 // Close the "Active Speakers" panel if it's currently visible
1790 LLFloaterChat::getInstance()->childSetVisible("active_speakers_panel", false);
1791 }
1792 else
1793 {
1794 // If this is the last @shownames=n restriction refresh all object text in case anything needs restoring
1795 fRefreshHover = (1 == m_Behaviours[RLV_BHVR_SHOWNAMES]);
1796 }
1797 }
1798 break;
1799 case RLV_BHVR_SHOWHOVERTEXTALL: // @showhovertextall=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1800 case RLV_BHVR_SHOWHOVERTEXTWORLD: // @showhovertextworld=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1801 case RLV_BHVR_SHOWHOVERTEXTHUD: // @showhovertexthud=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1802 {
1803 VERIFY_OPTION_REF(strOption.empty());
1804
1805 // Refresh all object text on the first/last add/rem(LLHUDText::setStringUTF8() decides what needs clearing and what doesn't)
1806 fRefreshHover = ((RLV_TYPE_ADD == eType) && (0 == m_Behaviours[eBhvr])) ||
1807 ((RLV_TYPE_REMOVE == eType) && (1 == m_Behaviours[eBhvr]));
1808 }
1809 break;
1810 case RLV_BHVR_SHOWHOVERTEXT: // @showhovertext:<uuid>=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1811 {
1812 // There should be an option and it should specify a valid UUID
1813 LLUUID idException(strOption);
1814 VERIFY_OPTION_REF(idException.notNull());
1815
1816 if (RLV_TYPE_ADD == eType)
1817 addException(idObj, eBhvr, idException);
1818 else
1819 removeException(idObj, eBhvr, idException);
1820
1821 // Clear/restore the object's hover text as needed
1822 LLViewerObject* pObj = gObjectList.findObject(idException);
1823 if ( (pObj) && (pObj->mText.notNull()) && (!pObj->mText->getObjectText().empty()) )
1824 pObj->mText->setStringUTF8( (RLV_TYPE_ADD == eType) ? "" : pObj->mText->getObjectText());
1825 }
1826 break;
1827 case RLV_BHVR_EDIT: // @edit=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1828 {
1829 VERIFY_OPTION_REF(strOption.empty());
1830
1831 if (RLV_TYPE_ADD == eType)
1832 {
1833 // Turn off "View / Highlight Transparent"
1834 LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
1835
1836 // Close the Beacons floater if it's open
1837 if (LLFloaterBeacons::instanceVisible())
1838 LLFloaterBeacons::toggleInstance();
1839
1840 // Get rid of the build floater if it's open [copy/paste from toggle_build_mode()]
1841 if (gFloaterTools->getVisible())
1842 {
1843 gAgent.resetView(FALSE);
1844 gFloaterTools->close();
1845 gViewerWindow->showCursor();
1846 }
1847 }
1848 }
1849 break;
1850#ifdef RLV_EXTENSION_CMD_TOUCHXXX
1851 case RLV_BHVR_TOUCH: // @touch:<uuid>=n - Checked: 2010-01-01 (RLVa-1.1.0l) | Added: RLVa-1.1.0l
1852 {
1853 // There should be an option and it should specify a valid UUID
1854 LLUUID idException(strOption);
1855 VERIFY_OPTION_REF(idException.notNull());
1856
1857 if (RLV_TYPE_ADD == eType)
1858 addException(idObj, eBhvr, idException);
1859 else
1860 removeException(idObj, eBhvr, idException);
1861 }
1862 break;
1863#endif // RLV_EXTENSION_CMD_TOUCHXXX
1864 case RLV_BHVR_FLY: // @fly=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1865 {
1866 VERIFY_OPTION_REF(strOption.empty());
1867
1868 if (RLV_TYPE_ADD == eType)
1869 gAgent.setFlying(FALSE);
1870 }
1871 break;
1872 case RLV_BHVR_SETENV: // @setenv=n|y
1873 eRet = onAddRemSetEnv(idObj, rlvCmd, fRefCount);
1874 break;
1875 // The following block is only valid if there's no option
1876 case RLV_BHVR_EMOTE: // @emote=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1877 case RLV_BHVR_SENDCHAT: // @sendchat=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1878 case RLV_BHVR_CHATWHISPER: // @chatwhisper=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1879 case RLV_BHVR_CHATNORMAL: // @chatnormal=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1880 case RLV_BHVR_CHATSHOUT: // @chatshout=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1881 case RLV_BHVR_PERMISSIVE: // @permissive=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1882 case RLV_BHVR_TPLM: // @tplm=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1883 case RLV_BHVR_TPLOC: // @tploc=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1884 case RLV_BHVR_VIEWNOTE: // @viewnote=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1885 case RLV_BHVR_VIEWSCRIPT: // @viewscript=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1886 case RLV_BHVR_VIEWTEXTURE: // @viewtexture=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1887 case RLV_BHVR_ACCEPTPERMISSION: // @acceptpermission=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1888 case RLV_BHVR_DEFAULTWEAR: // @defaultwear=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1889#ifdef RLV_EXTENSION_CMD_ALLOWIDLE
1890 case RLV_BHVR_ALLOWIDLE: // @allowidle=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1891#endif // RLV_EXTENSION_CMD_ALLOWIDLE
1892 case RLV_BHVR_REZ: // @rez=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1893 case RLV_BHVR_FARTOUCH: // @fartouch=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1894#ifdef RLV_EXTENSION_CMD_INTERACT
1895 case RLV_BHVR_INTERACT: // @interact=n|y - Checked: 2010-01-01 (RLVa-1.1.0l) | Added: RLVa-1.1.0l
1896#endif // RLV_EXTENSION_CMD_INTERACT
1897 case RLV_BHVR_UNSIT: // @unsit=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1898 case RLV_BHVR_SIT: // @sit=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1899 case RLV_BHVR_SITTP: // @sittp=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1900 case RLV_BHVR_SETDEBUG: // @setdebug=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1901 VERIFY_OPTION_REF(strOption.empty());
1902 break;
1903 // The following block is only valid if there's no option (= restriction) or if it specifies a valid UUID (= behaviour exception)
1904 case RLV_BHVR_RECVCHAT: // @recvchat[:<uuid>]=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1905 case RLV_BHVR_RECVEMOTE: // @recvemote[:<uuid>]=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1906 case RLV_BHVR_SENDIM: // @sendim[:<uuid>]=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1907 case RLV_BHVR_RECVIM: // @recvim[:<uuid>]=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1908 case RLV_BHVR_TPLURE: // @tplure[:<uuid>]=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1909 case RLV_BHVR_ACCEPTTP: // @accepttp[:<uuid>]=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
1910#ifdef RLV_EXTENSION_CMD_TOUCHXXX
1911 case RLV_BHVR_TOUCHWORLD: // @touchworld[:<uuid>=n|y - Checked: 2010-01-01 (RLVa-1.1.0l) | Added: RLVa-1.1.0l
1912 case RLV_BHVR_TOUCHATTACH: // @touchattach[:<uuid>=n|y - Checked: 2010-01-01 (RLVa-1.1.0l) | Added: RLVa-1.1.0l
1913 case RLV_BHVR_TOUCHHUD: // @touchhud[:<uuid>=n|y - Checked: 2010-01-01 (RLVa-1.1.0l) | Added: RLVa-1.1.0l
1914#endif // RLV_EXTENSION_CMD_TOUCHXXX
1915 {
1916 LLUUID idException(strOption);
1917 if (idException.notNull()) // If there's an option then it should specify a valid UUID
1918 {
1919 if (RLV_TYPE_ADD == eType)
1920 addException(idObj, eBhvr, idException);
1921 else
1922 removeException(idObj, eBhvr, idException);
1923 break;
1924 }
1925 VERIFY_OPTION_REF(strOption.empty());
1926 }
1927 break;
1928 case RLV_BHVR_UNKNOWN:
1929 // Pass unknown commands on to registered command handlers
1930 return (notifyCommandHandlers(&RlvCommandHandler::onAddRemCommand, idObj, rlvCmd, eRet, false)) ? eRet : RLV_RET_FAILED_UNKNOWN;
1931 default:
1932 // Fail with "Invalid param" if none of the above handled it
1933 eRet = RLV_RET_FAILED_PARAM;
1934 break;
1935 }
1936
1937 // If this command represents a behaviour restriction that's been added/removed then we need to do some additional processing
1938 if ( (RLV_RET_SUCCESS == eRet) && (fRefCount) )
1939 {
1940 if (RLV_TYPE_ADD == eType)
1941 {
1942 if (rlvCmd.isStrict())
1943 addException(idObj, RLV_BHVR_PERMISSIVE, eBhvr);
1944 m_Behaviours[eBhvr]++;
1945 }
1946 else
1947 {
1948 if (rlvCmd.isStrict())
1949 removeException(idObj, RLV_BHVR_PERMISSIVE, eBhvr);
1950 m_Behaviours[eBhvr]--;
1951 }
1952
1953 // Since canShowHoverText() uses hasBehaviour() refreshing object text needs to wait until after we've reference counted
1954 if (fRefreshHover)
1955 LLHUDText::refreshAllObjectText();
1956
1957 // Since RlvSettings::updateLoginLastLocation() uses hasBehaviour() it needs to be called after we've reference counted
1958 #ifdef RLV_EXTENSION_STARTLOCATION
1959 RlvSettings::updateLoginLastLocation();
1960 #endif // RLV_EXTENSION_STARTLOCATION
1961
1962 // Show an - optional - notification on every global behaviour change
1963 #ifdef RLV_EXTENSION_NOTIFY_BEHAVIOUR
1964 if ( ((RLV_TYPE_ADD == eType) && (1 == m_Behaviours[eBhvr])) || (0 == m_Behaviours[eBhvr]) )
1965 RlvNotifications::notifyBehaviour(eBhvr, eType);
1966 #endif // RLV_EXTENSION_NOTIFY_BEHAVIOUR
1967 }
1968
1969 return eRet;
1970}
1971
2484// Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a 1972// Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a
2485ERlvCmdRet RlvHandler::onAddRemAttach(const LLUUID& idObj, const RlvCommand& rlvCmd, bool& fRefCount) 1973ERlvCmdRet RlvHandler::onAddRemAttach(const LLUUID& idObj, const RlvCommand& rlvCmd, bool& fRefCount)
2486{ 1974{
@@ -2511,10 +1999,10 @@ ERlvCmdRet RlvHandler::onAddRemAttach(const LLUUID& idObj, const RlvCommand& rlv
2511 LLPipeline::sShowHUDAttachments = TRUE; 1999 LLPipeline::sShowHUDAttachments = TRUE;
2512 2000
2513 fRefCount = rlvCmd.getOption().empty(); // Only reference count global locks 2001 fRefCount = rlvCmd.getOption().empty(); // Only reference count global locks
2514 return RLV_RET_NOERROR; 2002 return RLV_RET_SUCCESS;
2515} 2003}
2516 2004
2517// Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a 2005// Checked: 2010-07-18 (RLVa-1.1.2b) | Modified: RLVa-1.1.2a
2518ERlvCmdRet RlvHandler::onAddRemDetach(const LLUUID& idObj, const RlvCommand& rlvCmd, bool& fRefCount) 2006ERlvCmdRet RlvHandler::onAddRemDetach(const LLUUID& idObj, const RlvCommand& rlvCmd, bool& fRefCount)
2519{ 2007{
2520 S32 idxAttachPt = 0; 2008 S32 idxAttachPt = 0;
@@ -2526,7 +2014,7 @@ ERlvCmdRet RlvHandler::onAddRemDetach(const LLUUID& idObj, const RlvCommand& rlv
2526 // * @detach=y: - if it ever rezzed as an attachment we'll have cached its attach point 2014 // * @detach=y: - if it ever rezzed as an attachment we'll have cached its attach point
2527 // - if it never rezzed as an attachment there won't be a lock to remove 2015 // - if it never rezzed as an attachment there won't be a lock to remove
2528 rlv_object_map_t::const_iterator itObj = m_Objects.find(idObj); 2016 rlv_object_map_t::const_iterator itObj = m_Objects.find(idObj);
2529 if (itObj != m_Objects.end()) 2017 if ( (itObj != m_Objects.end()) && (itObj->second.m_fLookup) && (itObj->second.m_idxAttachPt) )
2530 idxAttachPt = itObj->second.m_idxAttachPt; 2018 idxAttachPt = itObj->second.m_idxAttachPt;
2531 } 2019 }
2532 else // @detach:<attachpt>=n|y 2020 else // @detach:<attachpt>=n|y
@@ -2536,7 +2024,7 @@ ERlvCmdRet RlvHandler::onAddRemDetach(const LLUUID& idObj, const RlvCommand& rlv
2536 2024
2537 // The attach point can be zero for @detach=n|y (i.e. non-attachment) but should always be non-zero for @detach:<attachpt>=n|y 2025 // The attach point can be zero for @detach=n|y (i.e. non-attachment) but should always be non-zero for @detach:<attachpt>=n|y
2538 if (0 == idxAttachPt) 2026 if (0 == idxAttachPt)
2539 return (rlvCmd.getOption().empty()) ? RLV_RET_NOERROR : RLV_RET_FAILED_OPTION; 2027 return (rlvCmd.getOption().empty()) ? RLV_RET_SUCCESS : RLV_RET_FAILED_OPTION;
2540 2028
2541 // Actually lock the attachment point (@detach=n locks remove only; @detach:<attachpt>=n locks both remove and add) 2029 // Actually lock the attachment point (@detach=n locks remove only; @detach:<attachpt>=n locks both remove and add)
2542 ERlvLockMask eLock = (rlvCmd.getOption().empty()) ? RLV_LOCK_REMOVE : (ERlvLockMask)(RLV_LOCK_ADD | RLV_LOCK_REMOVE); 2030 ERlvLockMask eLock = (rlvCmd.getOption().empty()) ? RLV_LOCK_REMOVE : (ERlvLockMask)(RLV_LOCK_ADD | RLV_LOCK_REMOVE);
@@ -2550,67 +2038,726 @@ ERlvCmdRet RlvHandler::onAddRemDetach(const LLUUID& idObj, const RlvCommand& rlv
2550 LLPipeline::sShowHUDAttachments = TRUE; 2038 LLPipeline::sShowHUDAttachments = TRUE;
2551 2039
2552 fRefCount = false; // Don't reference count @detach[:<option>]=n 2040 fRefCount = false; // Don't reference count @detach[:<option>]=n
2553 return RLV_RET_NOERROR; 2041 return RLV_RET_SUCCESS;
2554} 2042}
2555 2043
2556// ============================================================================ 2044// Checked: 2009-12-05 (RLVa-1.1.0h) | Added: RLVa-1.1.0h
2557// Command handlers (RLV_TYPE_FORCE) 2045ERlvCmdRet RlvHandler::onAddRemSetEnv(const LLUUID& idObj, const RlvCommand& rlvCmd, bool& fRefCount)
2558//
2559
2560// Checked: 2009-10-12 (RLVa-1.0.5b) | Modified: RLVa-1.0.5b
2561ERlvCmdRet RlvHandler::onForceDetach(const LLUUID& idObj, const RlvCommand& rlvCmd) const
2562{ 2046{
2563 // TODO-RLVA: this still needs a rewrite to conform to the new event handler system 2047 // Sanity check - there shouldn't be an option
2564 if ( (rlvCmd.getOption().empty()) || (getAttachPointIndex(rlvCmd.getOption(), true)) ) 2048 if (!rlvCmd.getOption().empty())
2049 return RLV_RET_FAILED_OPTION;
2050 if (RlvSettings::getNoSetEnv())
2051 return RLV_RET_FAILED_DISABLED;
2052
2053 if (RLV_TYPE_ADD == rlvCmd.getParamType())
2565 { 2054 {
2566 onForceRemAttach(idObj, rlvCmd); 2055 // Only close the floaters if their instance exists and they're actually visible
2056 if ( (LLFloaterEnvSettings::isOpen()) && (LLFloaterEnvSettings::instance()->getVisible()) )
2057 LLFloaterEnvSettings::instance()->close();
2058 if ( (LLFloaterWindLight::isOpen()) && (LLFloaterWindLight::instance()->getVisible()) )
2059 LLFloaterWindLight::instance()->close();
2060 if ( (LLFloaterWater::isOpen()) && (LLFloaterWater::instance()->getVisible()) )
2061 LLFloaterWater::instance()->close();
2062 if ( (LLFloaterDayCycle::isOpen()) && (LLFloaterDayCycle::instance()->getVisible()) )
2063 LLFloaterDayCycle::instance()->close();
2064
2065 // Save the current WindLight params so we can restore them on @setenv=y
2066 if (m_pWLSnapshot)
2067 {
2068 RLV_ERRS << "m_pWLSnapshot != NULL" << RLV_ENDL; // Safety net in case we set @setenv=n for more than 1 object
2069 delete m_pWLSnapshot;
2070 }
2071 m_pWLSnapshot = RlvWLSnapshot::takeSnapshot();
2567 } 2072 }
2568 else 2073 else
2569 { 2074 {
2570 // Force detach single folder 2075 // Restore WindLight parameters to what they were before @setenv=n was issued
2571 onForceWear(rlvCmd.getOption(), false, false); 2076 RlvWLSnapshot::restoreSnapshot(m_pWLSnapshot);
2077 delete m_pWLSnapshot;
2078 m_pWLSnapshot = NULL;
2572 } 2079 }
2080 fRefCount = true;
2081 return RLV_RET_SUCCESS;
2082}
2083
2084// ============================================================================
2085// Command handlers (RLV_TYPE_FORCE)
2086//
2087
2088// Checked: 2009-12-21 (RLVa-1.1.0j) | Modified: RLVa-1.1.0j
2089ERlvCmdRet RlvHandler::processForceCommand(const LLUUID& idObj, const RlvCommand& rlvCmd) const
2090{
2091 RLV_ASSERT(RLV_TYPE_FORCE == rlvCmd.getParamType());
2092
2093 ERlvCmdRet eRet = RLV_RET_SUCCESS;
2094 switch (rlvCmd.getBehaviourType())
2095 {
2096 case RLV_BHVR_DETACH: // @detach[:<option>]=force - Checked: 2009-12-21 (RLVa-1.1.0k) | Modified: RLVa-1.1.0j
2097 eRet = onForceRemAttach(idObj, rlvCmd);
2098 if (RLV_RET_SUCCESS != eRet)
2099 eRet = onForceWear(rlvCmd.getOption(), false, false);
2100 break;
2101 case RLV_BHVR_REMATTACH: // @remattach[:<option>]=force
2102 eRet = onForceRemAttach(idObj, rlvCmd);
2103 break;
2104 case RLV_BHVR_REMOUTFIT: // @remoutfit[:<option>]=force
2105 eRet = onForceRemOutfit(idObj, rlvCmd);
2106 break;
2107 case RLV_BHVR_UNSIT: // @unsit=force - Checked: 2009-12-21 (RLVa-1.1.0k) | Modified: RLVa-0.2.0g
2108 {
2109 VERIFY_OPTION(rlvCmd.getOption().empty());
2110 LLVOAvatar* pAvatar = gAgent.getAvatarObject();
2111 if ( (pAvatar) && (pAvatar->mIsSitting) && (!hasBehaviourExcept(RLV_BHVR_UNSIT, idObj)) )
2112 {
2113 gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
2114 send_agent_update(TRUE, TRUE); // See behaviour notes on why we have to force an agent update here
2115 }
2116 }
2117 break;
2118 case RLV_BHVR_SIT: // @sit:<option>=force
2119 eRet = onForceSit(idObj, rlvCmd);
2120 break;
2121 case RLV_BHVR_TPTO: // @tpto:<option>=force - Checked: 2009-07-12 (RLVa-1.0.0k) | Modified: RLVa-1.0.0h
2122 {
2123 eRet = RLV_RET_FAILED_OPTION;
2124 if ( (!rlvCmd.getOption().empty()) && (std::string::npos == rlvCmd.getOption().find_first_not_of("0123456789/.")) )
2125 {
2126 LLVector3d posGlobal;
2573 2127
2574 return RLV_RET_NOERROR; 2128 boost_tokenizer tokens(rlvCmd.getOption(), boost::char_separator<char>("/", "", boost::keep_empty_tokens)); int idx = 0;
2129 for (boost_tokenizer::const_iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken)
2130 {
2131 if (idx < 3)
2132 LLStringUtil::convertToF64(*itToken, posGlobal[idx++]);
2133 }
2134
2135 if (idx == 3)
2136 {
2137 gAgent.teleportViaLocation(posGlobal);
2138 eRet = RLV_RET_SUCCESS;
2139 }
2140 }
2141 }
2142 break;
2143 case RLV_BHVR_ADDOUTFIT: // @addoutfit:<option>=force <- synonym of @attach:<option>=force
2144 case RLV_BHVR_ATTACH: // @attach:<option>=force
2145 eRet = onForceWear(rlvCmd.getOption(), true, false); // Force attach single folder
2146 break;
2147 case RLV_BHVR_ATTACHALL: // @attachall:<option>=force
2148 eRet = onForceWear(rlvCmd.getOption(), true, true); // Force attach nested folders
2149 break;
2150 case RLV_BHVR_DETACHALL: // @detachall:<option>=force
2151 eRet = onForceWear(rlvCmd.getOption(), false, true); // Force detach nested folders
2152 break;
2153 case RLV_BHVR_ATTACHTHIS: // @attachthis[:<option>]=force
2154 case RLV_BHVR_ATTACHALLTHIS:// @attachallthis[:<option>]=force
2155 case RLV_BHVR_DETACHTHIS: // @detachthis[:<option>]=force
2156 case RLV_BHVR_DETACHALLTHIS:// @detachallthis[:<option>]=force
2157 {
2158 ERlvBehaviour eBehaviour = rlvCmd.getBehaviourType(); std::string strReply;
2159 if ( ((eRet = onGetPath(idObj, rlvCmd, strReply)) == RLV_RET_SUCCESS) && (!strReply.empty()) )
2160 {
2161 LLStringUtil::toLower(strReply);
2162 eRet = onForceWear(strReply,
2163 (RLV_BHVR_ATTACHTHIS == eBehaviour) || (RLV_BHVR_ATTACHALLTHIS == eBehaviour),
2164 (RLV_BHVR_ATTACHALLTHIS == eBehaviour) || (RLV_BHVR_DETACHALLTHIS == eBehaviour));
2165 }
2166 }
2167 break;
2168 case RLV_BHVR_DETACHME: // @detachme=force - Checked:
2169 {
2170 // NOTE: @detachme=force could be seen as a @detach:<attachpt>=force but RLV implements it as a "detach by UUID"
2171 VERIFY_OPTION(rlvCmd.getOption().empty());
2172 LLViewerObject* pObj = NULL; LLVOAvatar* pAvatar = NULL; LLViewerJointAttachment* pAttachPt = NULL;
2173 if ( ((pObj = gObjectList.findObject(idObj)) != NULL) && (pObj->isAttachment()) &&
2174 ((pAvatar = gAgent.getAvatarObject()) != NULL) &&
2175 ((pAttachPt = pAvatar->getTargetAttachmentPoint(pObj->getRootEdit())) != NULL) )
2176 {
2177 // @detachme should respect locks but shouldn't respect things like nostrip so handle it like a manual user detach
2178 handle_detach_from_avatar(pAttachPt);
2179 }
2180 }
2181 break;
2182 case RLV_BHVR_UNKNOWN:
2183 // Pass unknown commands on to registered command handlers
2184 return (notifyCommandHandlers(&RlvCommandHandler::onForceCommand, idObj, rlvCmd, eRet, false)) ? eRet : RLV_RET_FAILED_UNKNOWN;
2185 default:
2186 // Fail with "Invalid param" if none of the above handled it
2187 eRet = RLV_RET_FAILED_PARAM;
2188 break;
2189 }
2190 return eRet;
2575} 2191}
2576 2192
2577// Checked: 2009-10-12 (RLVa-1.0.5b) | Added: RLVa-1.0.5b 2193// Checked: 2009-11-24 (RLVa-1.1.0k) | Modified: RLVa-1.1.0e
2578ERlvCmdRet RlvHandler::onForceRemAttach(const LLUUID& idObj, const RlvCommand& rlvCmd) const 2194ERlvCmdRet RlvHandler::onForceRemAttach(const LLUUID& idObj, const RlvCommand& rlvCmd) const
2579{ 2195{
2580 S32 idxAttachPt = 0; 2196 RLV_ASSERT(RLV_TYPE_FORCE == rlvCmd.getParamType());
2581 if (rlvCmd.getOption().empty()) 2197 RLV_ASSERT( (RLV_BHVR_REMATTACH == rlvCmd.getBehaviourType()) || (RLV_BHVR_DETACH == rlvCmd.getBehaviourType()) );
2198
2199 LLVOAvatar* pAvatar = gAgent.getAvatarObject();
2200 if (!pAvatar)
2201 return RLV_RET_FAILED;
2202
2203 S32 idxAttachPt = 0; ERlvAttachGroupType eAttachGroup = RLV_ATTACHGROUP_INVALID;
2204 // @remattach:<attachpt>=force - force detach single worn attachment
2205 if ((idxAttachPt = getAttachPointIndex(rlvCmd.getOption(), true)) != 0)
2582 { 2206 {
2583 // Simulate right-click / Take Off > Detach All 2207 LLViewerJointAttachment* pAttachPt = get_if_there(pAvatar->mAttachmentPoints, (S32)idxAttachPt, (LLViewerJointAttachment*)NULL);
2584 LLAgent::userRemoveAllAttachments(NULL); 2208 if (pAttachPt)
2585 return RLV_RET_NOERROR; 2209 {
2210 RlvForceWear rlvWear;
2211 rlvWear.forceDetach(pAttachPt);
2212 rlvWear.done();
2213 }
2214 return RLV_RET_SUCCESS;
2586 } 2215 }
2587 else if ((idxAttachPt = getAttachPointIndex(rlvCmd.getOption(), true)) != 0) 2216 // @remattach:<group>=force - force detach worn attachments belonging to <group>
2217 // @remattach=force - force detach all worn attachments
2218 else if ( ((eAttachGroup = rlvGetAttachGroupTypeFromString(rlvCmd.getOption())) != RLV_ATTACHGROUP_INVALID) ||
2219 (rlvCmd.getOption().empty()) )
2588 { 2220 {
2589 // Simulate right-click / Take Off > Detach > ... 2221 RlvForceWear rlvWear;
2590 LLVOAvatar* pAvatar; LLViewerJointAttachment* pAttachmentPt; 2222 for (LLVOAvatar::attachment_map_t::const_iterator itAttach = pAvatar->mAttachmentPoints.begin();
2591 if ( ((pAvatar = gAgent.getAvatarObject()) != NULL) && // Make sure we're actually wearing something on the attachment point 2223 itAttach != pAvatar->mAttachmentPoints.end(); ++itAttach)
2592 ((pAttachmentPt = get_if_there(pAvatar->mAttachmentPoints, (S32)idxAttachPt, (LLViewerJointAttachment*)NULL)) != NULL) &&
2593 (isStrippable(pAttachmentPt->getItemID())) ) // ... and that it's not marked as "nostrip"
2594 { 2224 {
2595 #ifdef RLV_EXPERIMENTAL_COMPOSITES 2225 LLViewerJointAttachment* pAttachPt = itAttach->second;
2596 // If we're stripping something that's part of a composite folder then we should @detachthis instead 2226 if ( (pAttachPt) && (pAttachPt->getObject()) &&
2597 if (isCompositeDescendent(pAttachmentPt->getItemID())) 2227 ((RLV_ATTACHGROUP_INVALID == eAttachGroup) || (rlvGetAttachGroupTypeFromIndex(pAttachPt->getGroup()) == eAttachGroup)) )
2228 {
2229 rlvWear.forceDetach(pAttachPt);
2230 }
2231 }
2232 rlvWear.done();
2233 return RLV_RET_SUCCESS;
2234 }
2235 return RLV_RET_FAILED_OPTION;
2236}
2237
2238// Checked: 2009-12-18 (RLVa-1.1.0k) | Modified: RLVa-1.1.0i
2239ERlvCmdRet RlvHandler::onForceRemOutfit(const LLUUID& idObj, const RlvCommand& rlvCmd) const
2240{
2241 EWearableType wtOption = LLWearable::typeNameToType(rlvCmd.getOption()), wtType;
2242 if ( (WT_INVALID == wtOption) && (!rlvCmd.getOption().empty()) )
2243 return RLV_RET_FAILED_OPTION;
2244
2245 RlvForceWear rlvWear;
2246 for (int idxType = 0; idxType < WT_COUNT; idxType++)
2247 {
2248 wtType = (EWearableType)idxType;
2249 if ( (wtType == wtOption) || (WT_INVALID == wtOption) )
2250 rlvWear.forceRemove(wtType);
2251 }
2252 rlvWear.done();
2253 return RLV_RET_SUCCESS;
2254}
2255
2256// Checked: 2009-12-21 (RLVa-1.1.0j) | Modified: RLVa-1.1.0j
2257ERlvCmdRet RlvHandler::onForceSit(const LLUUID& idObj, const RlvCommand& rlvCmd) const
2258{
2259 LLViewerObject* pObj = NULL; LLUUID idTarget(rlvCmd.getOption());
2260 // Sanity checking - we need to know about the object and it should identify a prim/linkset
2261 if ( (idTarget.isNull()) || ((pObj = gObjectList.findObject(idTarget)) == NULL) || (LL_PCODE_VOLUME != pObj->getPCode()) )
2262 return RLV_RET_FAILED_OPTION;
2263
2264 if (!canSit(pObj))
2265 return RLV_RET_FAILED_LOCK;
2266
2267 // Copy/paste from handle_sit_or_stand() [see http://wiki.secondlife.com/wiki/AgentRequestSit]
2268 gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit);
2269 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
2270 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
2271 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
2272 gMessageSystem->nextBlockFast(_PREHASH_TargetObject);
2273 gMessageSystem->addUUIDFast(_PREHASH_TargetID, pObj->mID);
2274 // Offset: "a rough position in local coordinates for the edge to sit on"
2275 // (we might not even be looking at the object so I don't think we can supply the offset to an edge)
2276 gMessageSystem->addVector3Fast(_PREHASH_Offset, LLVector3::zero);
2277 pObj->getRegion()->sendReliableMessage();
2278
2279 return RLV_RET_SUCCESS;
2280}
2281
2282// Checked: 2009-12-18 (RLVa-1.1.0k) | Modified: RLVa-1.1.0i
2283ERlvCmdRet RlvHandler::onForceWear(const std::string& strPath, bool fAttach, bool fMatchAll) const
2284{
2285 LLViewerInventoryCategory* pFolder = getSharedFolder(strPath), *pRlvRoot = getSharedRoot();
2286 if ( (!pFolder) || (pFolder->getUUID() == pRlvRoot->getUUID()) )
2287 return (pRlvRoot != NULL) ? RLV_RET_FAILED_OPTION : RLV_RET_FAILED_NOSHAREDROOT;
2288
2289 RlvForceWear rlvWear;
2290 rlvWear.forceFolder(pFolder,
2291 (fAttach) ? RlvForceWear::ACTION_ATTACH : RlvForceWear::ACTION_DETACH,
2292 (fMatchAll) ? (RlvForceWear::eWearFlags)(RlvForceWear::FLAG_DEFAULT | RlvForceWear::FLAG_MATCHALL) : (RlvForceWear::FLAG_DEFAULT));
2293 rlvWear.done();
2294
2295 return RLV_RET_SUCCESS;
2296}
2297
2298// ============================================================================
2299// Command handlers (RLV_TYPE_REPLY)
2300//
2301
2302// Checked: 2009-11-26 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
2303ERlvCmdRet RlvHandler::processReplyCommand(const LLUUID& idObj, const RlvCommand& rlvCmd) const
2304{
2305 RLV_ASSERT(RLV_TYPE_REPLY == rlvCmd.getParamType());
2306
2307 // Sanity check - <param> should specify a - valid - reply channel
2308 S32 nChannel;
2309 if ( (!LLStringUtil::convertToS32(rlvCmd.getParam(), nChannel)) || (!rlvIsValidReplyChannel(nChannel)) )
2310 return RLV_RET_FAILED_PARAM;
2311
2312 ERlvCmdRet eRet = RLV_RET_SUCCESS; std::string strReply;
2313 switch (rlvCmd.getBehaviourType())
2314 {
2315 case RLV_BHVR_VERSION: // @version=<channel> - Checked: 2010-03-27 (RLVa-1.2.0b)
2316 case RLV_BHVR_VERSIONNEW: // @versionnew=<channel> - Checked: 2010-03-27 (RLVa-1.2.0b) | Added: RLVa-1.2.0b
2317 // NOTE: RLV will respond even if there's an option
2318 strReply = RlvStrings::getVersion(RLV_BHVR_VERSION == rlvCmd.getBehaviourType());
2319 break;
2320 case RLV_BHVR_VERSIONNUM: // @versionnum=<channel> - Checked: 2009-11-26 (RLVa-1.1.0f) | Added: RLVa-1.0.4b
2321 // NOTE: RLV will respond even if there's an option
2322 strReply = RlvStrings::getVersionNum();
2323 break;
2324 case RLV_BHVR_GETATTACH: // @getattach[:<layer>]=<channel>
2325 eRet = onGetAttach(idObj, rlvCmd, strReply);
2326 break;
2327#ifdef RLV_EXTENSION_CMD_GETXXXNAMES
2328 case RLV_BHVR_GETATTACHNAMES: // @getattachnames[:<grp>]=<channel>
2329 case RLV_BHVR_GETADDATTACHNAMES:// @getaddattachnames[:<grp>]=<channel>
2330 case RLV_BHVR_GETREMATTACHNAMES:// @getremattachnames[:<grp>]=<channel>
2331 eRet = onGetAttachNames(idObj, rlvCmd, strReply);
2332 break;
2333#endif // RLV_EXTENSION_CMD_GETXXXNAMES
2334 case RLV_BHVR_GETOUTFIT: // @getoutfit[:<layer>]=<channel>
2335 eRet = onGetOutfit(idObj, rlvCmd, strReply);
2336 break;
2337#ifdef RLV_EXTENSION_CMD_GETXXXNAMES
2338 case RLV_BHVR_GETOUTFITNAMES: // @getoutfitnames=<channel>
2339 case RLV_BHVR_GETADDOUTFITNAMES:// @getaddoutfitnames=<channel>
2340 case RLV_BHVR_GETREMOUTFITNAMES:// @getremoutfitnames=<channel>
2341 eRet = onGetOutfitNames(idObj, rlvCmd, strReply);
2342 break;
2343#endif // RLV_EXTENSION_CMD_GETXXXNAMES
2344 case RLV_BHVR_FINDFOLDER: // @findfolder:<criteria>=<channel>
2345#ifdef RLV_EXTENSION_CMD_FINDFOLDERS
2346 case RLV_BHVR_FINDFOLDERS: // @findfolders:<criteria>=<channel>
2347#endif // RLV_EXTENSION_CMD_FINDFOLDERS
2348 eRet = onFindFolder(idObj, rlvCmd, strReply);
2349 break;
2350 case RLV_BHVR_GETPATH: // @getpath[:<option>]=<channel>
2351 eRet = onGetPath(idObj, rlvCmd, strReply);
2352 break;
2353 case RLV_BHVR_GETINV: // @getinv[:<path>]=<channel>
2354 eRet = onGetInv(idObj, rlvCmd, strReply);
2355 break;
2356 case RLV_BHVR_GETINVWORN: // @getinvworn[:path]=<channel>
2357 eRet = onGetInvWorn(idObj, rlvCmd, strReply);
2358 break;
2359 case RLV_BHVR_GETSITID: // @getsitid=<channel> - Checked: 2009-11-26 (RLVa-1.1.0f)
2360 {
2361 // NOTE: RLV 1.16.1 returns a NULL UUID if we're not sitting
2362 LLVOAvatar* pAvatar = gAgent.getAvatarObject(); LLUUID idSitObj;
2363 if ( (pAvatar) && (pAvatar->mIsSitting) )
2598 { 2364 {
2599 std::string strCmd = "detachthis:" + strOption + "=force"; 2365 // LLVOAvatar inherits from 2 classes so make sure we get the right vfptr
2600 #ifdef RLV_DEBUG 2366 LLViewerObject* pAvatarObj = dynamic_cast<LLViewerObject*>(pAvatar), *pParent;
2601 RLV_INFOS << "\t- '" << strOption << "' belongs to composite folder: @" << strCmd << LL_ENDL; 2367 // (If there is a parent, we need to upcast it from LLXform to LLViewerObject to get its UUID)
2602 #endif // RLV_DEBUG 2368 if ( (pAvatarObj) && ((pParent = static_cast<LLViewerObject*>(pAvatarObj->getRoot())) != pAvatarObj) )
2603 processForceCommand(idObj, RlvCommand(strCmd)); 2369 idSitObj = pParent->getID();
2604 } 2370 }
2605 else 2371 strReply = idSitObj.asString();
2606 #endif // RLV_EXPERIMENTAL_COMPOSITES 2372 }
2373 break;
2374 case RLV_BHVR_GETSTATUS: // @getstatus[:<option>]=<channel> - Checked: 2009-11-26 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
2375 {
2376 // NOTE: specification says response should start with '/' but RLV-1.16.1 returns an empty string when no rules are set
2377 rlv_object_map_t::const_iterator itObj = m_Objects.find(idObj);
2378 if (itObj != m_Objects.end())
2379 strReply = itObj->second.getStatusString(rlvCmd.getOption());
2380 }
2381 break;
2382 case RLV_BHVR_GETSTATUSALL: // @getstatusall[:<option>]=<channel> - Checked: 2009-11-26 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
2383 {
2384 // NOTE: specification says response should start with '/' but RLV-1.16.1 returns an empty string when no rules are set
2385 for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj)
2386 strReply += itObj->second.getStatusString(rlvCmd.getOption());
2387 }
2388 break;
2389 case RLV_BHVR_UNKNOWN:
2390 // Pass unknown commands on to registered command handlers
2391 return (notifyCommandHandlers(&RlvCommandHandler::onReplyCommand, idObj, rlvCmd, eRet, false)) ? eRet : RLV_RET_FAILED_UNKNOWN;
2392 default:
2393 // Fail with "Invalid param" if none of the above handled it
2394 return RLV_RET_FAILED_PARAM;
2395 }
2396
2397 // If we made it this far then:
2398 // - the command was handled successfully so we send off the response
2399 // - the command failed but we still send off an (empty) response to keep the issuing script from blocking
2400 rlvSendChatReply(nChannel, strReply);
2401
2402 return eRet;
2403}
2404
2405// Checked: 2009-11-24 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
2406ERlvCmdRet RlvHandler::onFindFolder(const LLUUID& idObj, const RlvCommand& rlvCmd, std::string& strReply) const
2407{
2408 RLV_ASSERT(RLV_TYPE_REPLY == rlvCmd.getParamType());
2409 RLV_ASSERT( (RLV_BHVR_FINDFOLDER == rlvCmd.getBehaviourType()) || (RLV_BHVR_FINDFOLDERS == rlvCmd.getBehaviourType()) );
2410
2411 // (Compatibility: RLV 1.16.1 returns the first random folder it finds while we return a blank on no option)
2412 if (rlvCmd.getOption().empty())
2413 return RLV_RET_FAILED_OPTION;
2414
2415 LLInventoryModel::cat_array_t folders;
2416 if (findSharedFolders(rlvCmd.getOption(), folders))
2417 {
2418 if (RLV_BHVR_FINDFOLDER == rlvCmd.getBehaviourType())
2419 {
2420 // We need to return an "in depth" result so whoever has the most '/' is our lucky winner
2421 // (maxSlashes needs to be initialized to -1 since children of the #RLV folder won't have '/' in their shared path)
2422 int maxSlashes = -1, curSlashes; std::string strFolderName;
2423 for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++)
2424 {
2425 strFolderName = getSharedPath(folders.get(idxFolder));
2426
2427 curSlashes = std::count(strFolderName.begin(), strFolderName.end(), '/');
2428 if (curSlashes > maxSlashes)
2607 { 2429 {
2608 handle_detach_from_avatar(pAttachmentPt); 2430 maxSlashes = curSlashes;
2431 strReply = strFolderName;
2609 } 2432 }
2433 }
2434 }
2435 else if (RLV_BHVR_FINDFOLDERS == rlvCmd.getBehaviourType())
2436 {
2437 for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++)
2438 {
2439 if (!strReply.empty())
2440 strReply.push_back(',');
2441 strReply += getSharedPath(folders.get(idxFolder));
2442 }
2610 } 2443 }
2611 return RLV_RET_NOERROR;
2612 } 2444 }
2613 return RLV_RET_FAILED_OPTION; 2445 return RLV_RET_SUCCESS;
2446}
2447
2448// Checked: 2009-11-24 (RLVa-1.1.0f) | Modified: RLVa-1.1.0e
2449ERlvCmdRet RlvHandler::onGetAttach(const LLUUID& idObj, const RlvCommand& rlvCmd, std::string& strReply) const
2450{
2451 RLV_ASSERT(RLV_TYPE_REPLY == rlvCmd.getParamType());
2452 RLV_ASSERT(RLV_BHVR_GETATTACH == rlvCmd.getBehaviourType());
2453
2454 LLVOAvatar* pAvatar = gAgent.getAvatarObject();
2455 if (!pAvatar)
2456 return RLV_RET_FAILED;
2457
2458 // Sanity check - <option> should specify an attachment point or be empty
2459 S32 idxAttachPt = getAttachPointIndex(rlvCmd.getOption(), true);
2460 if ( (idxAttachPt == 0) && (!rlvCmd.getOption().empty()) )
2461 return RLV_RET_FAILED_OPTION;
2462
2463 // If we're fetching all worn attachments then the reply should start with 0
2464 if (0 == idxAttachPt)
2465 strReply.push_back('0');
2466
2467 for (LLVOAvatar::attachment_map_t::const_iterator itAttach = pAvatar->mAttachmentPoints.begin();
2468 itAttach != pAvatar->mAttachmentPoints.end(); ++itAttach)
2469 {
2470 LLViewerJointAttachment* pAttachPt = itAttach->second;
2471 if ( (0 == idxAttachPt) || (itAttach->first == idxAttachPt) )
2472 {
2473 bool fWorn = (pAttachPt->getObject() != NULL) &&
2474 ( (!RlvSettings::getHideLockedAttach()) ||
2475 (RlvForceWear::isForceDetachable(pAttachPt, true, gObjectList.findObject(idObj))) );
2476 strReply.push_back( (fWorn) ? '1' : '0' );
2477 }
2478 }
2479 return RLV_RET_SUCCESS;
2480}
2481
2482// Checked: 2009-10-19 (RLVa-1.1.0f) | Added: RLVa-1.1.0e
2483ERlvCmdRet RlvHandler::onGetAttachNames(const LLUUID& idObj, const RlvCommand& rlvCmd, std::string& strReply) const
2484{
2485 RLV_ASSERT(RLV_TYPE_REPLY == rlvCmd.getParamType());
2486 RLV_ASSERT( (RLV_BHVR_GETATTACHNAMES == rlvCmd.getBehaviourType()) || (RLV_BHVR_GETADDATTACHNAMES == rlvCmd.getBehaviourType()) ||
2487 (RLV_BHVR_GETREMATTACHNAMES == rlvCmd.getBehaviourType()) );
2488
2489 LLVOAvatar* pAvatar = gAgent.getAvatarObject();
2490 if (!pAvatar)
2491 return RLV_RET_FAILED;
2492
2493 ERlvAttachGroupType eAttachGroup = rlvGetAttachGroupTypeFromString(rlvCmd.getOption());
2494 for (LLVOAvatar::attachment_map_t::const_iterator itAttach = pAvatar->mAttachmentPoints.begin();
2495 itAttach != pAvatar->mAttachmentPoints.end(); ++itAttach)
2496 {
2497 LLViewerJointAttachment* pAttachPt = itAttach->second;
2498 if ( (RLV_ATTACHGROUP_INVALID == eAttachGroup) || (rlvGetAttachGroupTypeFromIndex(pAttachPt->getGroup()) == eAttachGroup) )
2499 {
2500 bool fAdd = false;
2501 switch (rlvCmd.getBehaviourType())
2502 {
2503 case RLV_BHVR_GETATTACHNAMES: // Every attachment point that has an attached object (locked or unlocked)
2504 fAdd = (pAttachPt->getObject() != NULL);
2505 break;
2506 case RLV_BHVR_GETADDATTACHNAMES: // Every attachment point that can be worn on (but ignore any locks set by the issuer)
2507 fAdd = (!isLockedAttachmentExcept(itAttach->first, RLV_LOCK_ADD, gObjectList.findObject(idObj))) &&
2508 ( (pAttachPt->getObject() == NULL) ||
2509 (!isLockedAttachmentExcept(itAttach->first, RLV_LOCK_REMOVE, gObjectList.findObject(idObj))) );
2510 break;
2511 case RLV_BHVR_GETREMATTACHNAMES: // Every attachment point that can be detached (but ignore any locks set by the issuer)
2512 fAdd = RlvForceWear::isForceDetachable(pAttachPt, true, gObjectList.findObject(idObj));
2513 break;
2514 default:
2515 break;
2516 }
2517
2518 if (fAdd)
2519 {
2520 if (!strReply.empty())
2521 strReply.push_back(',');
2522 strReply.append(pAttachPt->getName());
2523 }
2524 }
2525 }
2526 return RLV_RET_SUCCESS;
2527}
2528
2529// Checked: 2009-11-21 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
2530ERlvCmdRet RlvHandler::onGetInv(const LLUUID& idObj, const RlvCommand& rlvCmd, std::string& strReply) const
2531{
2532 RLV_ASSERT(RLV_TYPE_REPLY == rlvCmd.getParamType());
2533 RLV_ASSERT(RLV_BHVR_GETINV == rlvCmd.getBehaviourType());
2534
2535 LLViewerInventoryCategory* pFolder = getSharedFolder(rlvCmd.getOption());
2536 if (!pFolder)
2537 return (getSharedRoot() != NULL) ? RLV_RET_FAILED_OPTION : RLV_RET_FAILED_NOSHAREDROOT;
2538
2539 LLInventoryModel::cat_array_t* pFolders;
2540 LLInventoryModel::item_array_t* pItems;
2541 gInventory.getDirectDescendentsOf(pFolder->getUUID(), pFolders, pItems);
2542 if (!pFolders)
2543 return RLV_RET_FAILED;
2544
2545 for (S32 idxFolder = 0, cntFolder = pFolders->count(); idxFolder < cntFolder; idxFolder++)
2546 {
2547 // Return all folders that:
2548 // - aren't hidden
2549 // - aren't a folded folder (only really matters when "Enable Legacy Naming" is enabled - see related blog post)
2550 // (we can skip checking for .<composite> folders since the ones we'll want to hide start with '.' anyway)
2551 const std::string& strFolder = pFolders->get(idxFolder)->getName();
2552 if ( (!strFolder.empty()) && (RLV_FOLDER_PREFIX_HIDDEN != strFolder[0]) &&
2553 (!isFoldedFolder(pFolders->get(idxFolder).get(), true, false)) )
2554 {
2555 if (!strReply.empty())
2556 strReply.push_back(',');
2557 strReply += strFolder;
2558 }
2559 }
2560 return RLV_RET_SUCCESS;
2561}
2562
2563struct rlv_wear_info { U32 cntWorn, cntTotal, cntChildWorn, cntChildTotal; };
2564
2565// Checked: 2009-11-27 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
2566ERlvCmdRet RlvHandler::onGetInvWorn(const LLUUID& idObj, const RlvCommand& rlvCmd, std::string& strReply) const
2567{
2568 // Sanity check - getAvatarObject() can't be NULL [see RlvForceWear::isWearingItem()]
2569 if (!gAgent.getAvatarObject())
2570 return RLV_RET_FAILED;
2571 // Sanity check - folder should exist and not be hidden
2572 LLViewerInventoryCategory* pFolder = getSharedFolder(rlvCmd.getOption());
2573 if ( (!pFolder) || (pFolder->getName().empty()) || (RLV_FOLDER_PREFIX_HIDDEN == pFolder->getName()[0]) )
2574 return (getSharedRoot() != NULL) ? RLV_RET_FAILED_OPTION : RLV_RET_FAILED_NOSHAREDROOT;
2575
2576 // Collect everything @attachall would be attaching
2577 LLInventoryModel::cat_array_t folders;
2578 LLInventoryModel::item_array_t items;
2579 RlvWearableItemCollector functor(pFolder->getUUID(), true, true);
2580 gInventory.collectDescendentsIf(pFolder->getUUID(), folders, items, FALSE, functor);
2581
2582 rlv_wear_info wi = {0};
2583
2584 // Add all the folders to a lookup map
2585 std::map<LLUUID, rlv_wear_info> mapFolders;
2586 mapFolders.insert(std::pair<LLUUID, rlv_wear_info>(pFolder->getUUID(), wi));
2587 for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++)
2588 mapFolders.insert(std::pair<LLUUID, rlv_wear_info>(folders.get(idxFolder)->getUUID(), wi));
2589
2590 // Iterate over all the found items
2591 LLViewerInventoryItem* pItem; std::map<LLUUID, rlv_wear_info>::iterator itFolder;
2592 for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++)
2593 {
2594 pItem = items.get(idxItem);
2595
2596 // The "folded parent" is the folder this item should be considered a direct descendent of (may or may not match actual parent)
2597 const LLUUID& idParent = functor.getFoldedParent(pItem->getParentUUID());
2598
2599 // Walk up the tree: sooner or later one of the parents will be a folder in the map
2600 LLViewerInventoryCategory* pParent = gInventory.getCategory(idParent);
2601 while ( (itFolder = mapFolders.find(pParent->getUUID())) == mapFolders.end() )
2602 pParent = gInventory.getCategory(pParent->getParentUUID());
2603
2604 U32 &cntWorn = (idParent == pParent->getUUID()) ? itFolder->second.cntWorn : itFolder->second.cntChildWorn,
2605 &cntTotal = (idParent == pParent->getUUID()) ? itFolder->second.cntTotal : itFolder->second.cntChildTotal;
2606
2607 if (RlvForceWear::isWearingItem(pItem))
2608 cntWorn++;
2609 cntTotal++;
2610 }
2611
2612 // Extract the result for the main folder
2613 itFolder = mapFolders.find(pFolder->getUUID());
2614 wi.cntWorn = itFolder->second.cntWorn;
2615 wi.cntTotal = itFolder->second.cntTotal;
2616 mapFolders.erase(itFolder);
2617
2618 // Build the result for each child folder
2619 for (itFolder = mapFolders.begin(); itFolder != mapFolders.end(); ++itFolder)
2620 {
2621 rlv_wear_info& wiFolder = itFolder->second;
2622
2623 wi.cntChildWorn += wiFolder.cntWorn + wiFolder.cntChildWorn;
2624 wi.cntChildTotal += wiFolder.cntTotal + wiFolder.cntChildTotal;
2625
2626 strReply += llformat(",%s|%d%d", gInventory.getCategory(itFolder->first)->getName().c_str(),
2627 (0 == wiFolder.cntTotal) ? 0 : (0 == wiFolder.cntWorn) ? 1 : (wiFolder.cntWorn != wiFolder.cntTotal) ? 2 : 3,
2628 (0 == wiFolder.cntChildTotal) ? 0 : (0 == wiFolder.cntChildWorn) ? 1 : (wiFolder.cntChildWorn != wiFolder.cntChildTotal) ? 2 : 3
2629 );
2630 }
2631
2632 // Now just prepend the root and done
2633 strReply = llformat("|%d%d", (0 == wi.cntTotal) ? 0 : (0 == wi.cntWorn) ? 1 : (wi.cntWorn != wi.cntTotal) ? 2 : 3,
2634 (0 == wi.cntChildTotal) ? 0 : (0 == wi.cntChildWorn) ? 1 : (wi.cntChildWorn != wi.cntChildTotal) ? 2: 3) + strReply;
2635
2636 return RLV_RET_SUCCESS;
2637}
2638
2639// Checked: 2009-11-24 (RLVa-1.1.0f) | Modified: RLVa-1.1.0e
2640ERlvCmdRet RlvHandler::onGetOutfit(const LLUUID& idObj, const RlvCommand& rlvCmd, std::string& strReply) const
2641{
2642 RLV_ASSERT(RLV_TYPE_REPLY == rlvCmd.getParamType());
2643 RLV_ASSERT(RLV_BHVR_GETOUTFIT == rlvCmd.getBehaviourType());
2644
2645 // (Compatibility: RLV 1.16.1 will execute @getoutfit=<channel> if <layer> is invalid while we just return failure)
2646 EWearableType layerType = LLWearable::typeNameToType(rlvCmd.getOption());
2647 if ( (WT_INVALID == layerType) && (!rlvCmd.getOption().empty()) )
2648 return RLV_RET_FAILED_OPTION;
2649
2650 const EWearableType layerTypes[] =
2651 {
2652 WT_GLOVES, WT_JACKET, WT_PANTS, WT_SHIRT, WT_SHOES, WT_SKIRT, WT_SOCKS,
2653 WT_UNDERPANTS, WT_UNDERSHIRT, WT_SKIN, WT_EYES, WT_HAIR, WT_SHAPE, WT_ALPHA, WT_TATTOO
2654 };
2655
2656 for (int idx = 0, cnt = sizeof(layerTypes) / sizeof(EWearableType); idx < cnt; idx++)
2657 if ( (WT_INVALID == layerType) || (layerTypes[idx] == layerType) )
2658 {
2659 // We never hide body parts, even if they're "locked" and we're hiding locked layers
2660 // (nor do we hide a layer if the issuing object is the only one that has this layer locked)
2661 bool fWorn = (gAgent.getWearable(layerTypes[idx])) &&
2662 ( (!RlvSettings::getHideLockedLayers()) ||
2663 (LLAssetType::AT_BODYPART == LLWearable::typeToAssetType(layerTypes[idx])) ||
2664 ( (isRemovableExcept(layerTypes[idx], idObj)) &&
2665 (isStrippable(gAgent.getWearableItem(layerTypes[idx]))) ) );
2666 strReply.push_back( (fWorn) ? '1' : '0' );
2667 }
2668
2669 return RLV_RET_SUCCESS;
2670}
2671
2672// Checked: 2009-11-21 (RLVa-1.1.0f) | Added: RLVa-1.1.0e
2673ERlvCmdRet RlvHandler::onGetOutfitNames(const LLUUID& idObj, const RlvCommand& rlvCmd, std::string& strReply) const
2674{
2675 RLV_ASSERT(RLV_TYPE_REPLY == rlvCmd.getParamType());
2676 RLV_ASSERT( (RLV_BHVR_GETOUTFITNAMES == rlvCmd.getBehaviourType()) || (RLV_BHVR_GETADDOUTFITNAMES == rlvCmd.getBehaviourType()) ||
2677 (RLV_BHVR_GETREMOUTFITNAMES == rlvCmd.getBehaviourType()) );
2678
2679 // Sanity check - all these commands are optionless
2680 if (!rlvCmd.getOption().empty())
2681 return RLV_RET_FAILED_OPTION;
2682
2683 for (int idxType = 0; idxType < WT_COUNT; idxType++)
2684 {
2685 bool fAdd = false; EWearableType wtType = (EWearableType)idxType;
2686 switch (rlvCmd.getBehaviourType())
2687 {
2688 case RLV_BHVR_GETOUTFITNAMES: // Every layer that's worn
2689 fAdd = (gAgent.getWearable(wtType) != NULL);
2690 break;
2691 case RLV_BHVR_GETADDOUTFITNAMES: // Every layer that can be worn on (but ignore any locks set by the issuer)
2692 fAdd = (isWearable(wtType)) && ( (gAgent.getWearable(wtType) == NULL) || (isRemovableExcept(wtType, idObj)) );
2693 break;
2694 case RLV_BHVR_GETREMOUTFITNAMES: // Every layer that can be removed (but ignore any locks set by the issuer)
2695 fAdd = (gAgent.getWearable(wtType) != NULL) &&
2696 (LLAssetType::AT_BODYPART != LLWearable::typeToAssetType(wtType)) &&
2697 (isRemovableExcept(wtType, idObj)) && (isStrippable(gAgent.getWearableItem(wtType)));
2698 break;
2699 default:
2700 break;
2701 }
2702
2703 if (fAdd)
2704 {
2705 if (!strReply.empty())
2706 strReply.push_back(',');
2707 strReply.append(LLWearable::typeToTypeName((EWearableType)idxType));
2708 }
2709 }
2710 return RLV_RET_SUCCESS;
2711}
2712
2713// Checked: 2009-11-26 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
2714ERlvCmdRet RlvHandler::onGetPath(const LLUUID& idObj, const RlvCommand& rlvCmd, std::string& strReply) const
2715{
2716 // NOTE: @attachthis/attachallthis/detachthis/detachallthis call us directly to simulate @attach:getpath[:<option>]=force
2717
2718 // Sanity check - no need to go through all this trouble if we don't have a shared root
2719 LLViewerInventoryCategory* pRlvRoot = getSharedRoot();
2720 if (!pRlvRoot)
2721 return RLV_RET_FAILED_NOSHAREDROOT;
2722
2723 EWearableType wtType = LLWearable::typeNameToType(rlvCmd.getOption()); LLUUID idItem;
2724 if (WT_INVALID != wtType) // <option> can be a clothing layer
2725 {
2726 idItem = gAgent.getWearableItem(wtType);
2727 }
2728 else
2729 {
2730 LLViewerJointAttachment* pAttachPt = NULL;
2731
2732 if (rlvCmd.getOption().empty()) // ... or it can be empty (in which case we act on the object that issued the command)
2733 {
2734 LLViewerObject* pObj = gObjectList.findObject(idObj);
2735 if ( (pObj) && (pObj->isAttachment()) && (gAgent.getAvatarObject()) )
2736 pAttachPt = gAgent.getAvatarObject()->getTargetAttachmentPoint(pObj);
2737 }
2738 else // ... or it can specify an attachment point
2739 {
2740 pAttachPt = getAttachPoint(rlvCmd.getOption(), true);
2741 }
2742
2743 // If we found something get its inventory item UUID, otherwise return failure
2744 if (!pAttachPt)
2745 return RLV_RET_FAILED_OPTION;
2746 idItem = pAttachPt->getItemID();
2747 }
2748
2749 // If what we found is under the shared root then get its path
2750 if ( (!idItem.isNull()) && (gInventory.isObjectDescendentOf(idItem, pRlvRoot->getUUID())) )
2751 {
2752 LLInventoryItem* pItem = gInventory.getItem(idItem);
2753 if (pItem)
2754 {
2755 // (unless the containing folder is a folded folder in which case we need its parent)
2756 LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID());
2757 strReply = getSharedPath( (!isFoldedFolder(pFolder, true, true)) ? pFolder : gInventory.getCategory(pFolder->getParentUUID()) );
2758 }
2759 }
2760 return RLV_RET_SUCCESS;
2614} 2761}
2615 2762
2616// ============================================================================ 2763// ============================================================================
diff --git a/linden/indra/newview/rlvhandler.h b/linden/indra/newview/rlvhandler.h
index 6821149..94962f9 100644
--- a/linden/indra/newview/rlvhandler.h
+++ b/linden/indra/newview/rlvhandler.h
@@ -1,23 +1,38 @@
1/**
2 *
3 * Copyright (c) 2009-2010, Kitty Barnett
4 *
5 * The source code in this file is provided to you under the terms of the
6 * GNU General Public License, version 2.0, but WITHOUT ANY WARRANTY;
7 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
8 * PARTICULAR PURPOSE. Terms of the GPL can be found in doc/GPL-license.txt
9 * in this distribution, or online at http://www.gnu.org/licenses/gpl-2.0.txt
10 *
11 * By copying, modifying or distributing this software, you acknowledge that
12 * you have read and understood your obligations described above, and agree to
13 * abide by those obligations.
14 *
15 */
16
1#ifndef RLV_HANDLER_H 17#ifndef RLV_HANDLER_H
2#define RLV_HANDLER_H 18#define RLV_HANDLER_H
3 19
20#include <stack>
4#include "llagentconstants.h" 21#include "llagentconstants.h"
5#include "llappviewer.h" 22#include "llstartup.h"
6#include "llformat.h"
7#include "llversionviewer.h"
8#include "llviewerjointattachment.h" 23#include "llviewerjointattachment.h"
9#include "llviewerobject.h" 24#include "llviewerobject.h"
10#include "llwearable.h" 25#include "llwearable.h"
11 26
27#include "rlvcommon.h"
12#include "rlvhelper.h" 28#include "rlvhelper.h"
13#include "rlvevent.h"
14#include "rlvmultistringsearch.h" 29#include "rlvmultistringsearch.h"
15 30
16// ============================================================================ 31// ============================================================================
17 32
18typedef std::map<LLUUID, RlvObject> rlv_object_map_t; 33typedef std::map<LLUUID, RlvObject> rlv_object_map_t;
19typedef std::multimap<ERlvBehaviour, RlvException> rlv_exception_map_t; 34typedef std::multimap<ERlvBehaviour, RlvException> rlv_exception_map_t;
20typedef std::map<S32, LLUUID> rlv_attachlock_map_t; 35typedef std::multimap<S32, LLUUID> rlv_attachlock_map_t;
21 36
22class RlvHandler 37class RlvHandler
23{ 38{
@@ -35,10 +50,12 @@ public:
35 LLViewerJointAttachment* getAttachPoint(const std::string& strText, bool fExact) const; 50 LLViewerJointAttachment* getAttachPoint(const std::string& strText, bool fExact) const;
36 LLViewerJointAttachment* getAttachPoint(const LLInventoryItem* pItem, bool fStrict) const; 51 LLViewerJointAttachment* getAttachPoint(const LLInventoryItem* pItem, bool fStrict) const;
37 LLViewerJointAttachment* getAttachPoint(const LLInventoryCategory* pFolder, bool fStrict) const; 52 LLViewerJointAttachment* getAttachPoint(const LLInventoryCategory* pFolder, bool fStrict) const;
38 LLViewerJointAttachment* getAttachPointLegacy(const LLInventoryCategory* pFolder) const;
39 S32 getAttachPointIndex(std::string strText, bool fExact) const; 53 S32 getAttachPointIndex(std::string strText, bool fExact) const;
40 S32 getAttachPointIndex(LLViewerObject* pObj) const; 54 S32 getAttachPointIndex(LLViewerObject* pObj) const;
41 S32 getAttachPointIndex(const LLViewerJointAttachment* pObj) const; 55 S32 getAttachPointIndex(const LLViewerJointAttachment* pObj) const;
56 S32 getAttachPointIndex(const LLInventoryItem* pItem, bool fStrict) const;
57 S32 getAttachPointIndex(const LLInventoryCategory* pFolder, bool fStrict) const;
58 S32 getAttachPointIndexLegacy(const LLInventoryCategory* pFolder) const;
42 bool hasAttachPointName(const LLInventoryItem* pItem, bool fStrict) const; 59 bool hasAttachPointName(const LLInventoryItem* pItem, bool fStrict) const;
43 60
44 // -------------------------------- 61 // --------------------------------
@@ -62,6 +79,7 @@ public:
62 79
63 // Adds an eLock type lock (held by idRlvObj) for the specified attachment point 80 // Adds an eLock type lock (held by idRlvObj) for the specified attachment point
64 void addAttachmentLock(S32 idxAttachPt, const LLUUID& idRlvObj, ERlvLockMask eLock); 81 void addAttachmentLock(S32 idxAttachPt, const LLUUID& idRlvObj, ERlvLockMask eLock);
82 static void dumpAttachmentLocks(void*);
65 // Returns TRUE if there is at least 1 eLock type locked attachment (RLV_LOCK_ANY = RLV_LOCK_ADD *or* RLV_LOCK_REMOVE) 83 // Returns TRUE if there is at least 1 eLock type locked attachment (RLV_LOCK_ANY = RLV_LOCK_ADD *or* RLV_LOCK_REMOVE)
66 bool hasLockedAttachment(ERlvLockMask eLock) const; 84 bool hasLockedAttachment(ERlvLockMask eLock) const;
67 // Returns TRUE if there is at least 1 non-detachable HUD attachment 85 // Returns TRUE if there is at least 1 non-detachable HUD attachment
@@ -72,7 +90,8 @@ public:
72 bool isLockedAttachment(LLViewerJointAttachment* pAttachPt, ERlvLockMask eLock) const; 90 bool isLockedAttachment(LLViewerJointAttachment* pAttachPt, ERlvLockMask eLock) const;
73 bool isLockedAttachment(LLViewerObject* pObj, ERlvLockMask eLock) const; 91 bool isLockedAttachment(LLViewerObject* pObj, ERlvLockMask eLock) const;
74 // Returns TRUE if the specified attachment point is eLock type locked by anything other than pObj (or one of its children) 92 // Returns TRUE if the specified attachment point is eLock type locked by anything other than pObj (or one of its children)
75 bool isLockedAttachmentExcept(S32 idxAttachPt, ERlvLockMask eLock, LLViewerObject* pObj) const; 93 bool isLockedAttachmentExcept(S32 idxAttachPt, ERlvLockMask eLock, LLViewerObject* pExceptObj) const;
94 bool isLockedAttachmentExcept(LLViewerObject* pObj, ERlvLockMask eLock, LLViewerObject* pExceptObj) const;
76 // Adds an eLock type lock (held by idRlvObj) for the specified attachment point 95 // Adds an eLock type lock (held by idRlvObj) for the specified attachment point
77 void removeAttachmentLock(S32 idxAttachPt, const LLUUID& idRlovObj, ERlvLockMask eLock); 96 void removeAttachmentLock(S32 idxAttachPt, const LLUUID& idRlovObj, ERlvLockMask eLock);
78 97
@@ -93,18 +112,22 @@ public:
93 // Returns TRUE if the specified layer is wearable (use hasBehaviour(RLV_BHVR_ADDOUTFIT) for the general case) 112 // Returns TRUE if the specified layer is wearable (use hasBehaviour(RLV_BHVR_ADDOUTFIT) for the general case)
94 bool isWearable(EWearableType type) const { return (type < WT_COUNT) ? (0 == m_LayersAdd[type]) : true; } 113 bool isWearable(EWearableType type) const { return (type < WT_COUNT) ? (0 == m_LayersAdd[type]) : true; }
95 114
115 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
96 // Returns TRUE if the composite folder doesn't contain any "locked" items 116 // Returns TRUE if the composite folder doesn't contain any "locked" items
97 bool canTakeOffComposite(const LLInventoryCategory* pFolder) const; 117 bool canTakeOffComposite(const LLInventoryCategory* pFolder) const;
118 // Returns TRUE if the composite folder doesn't replace any "locked" items
119 bool canWearComposite(const LLInventoryCategory* pFolder) const;
98 // Returns TRUE if the folder is a composite folder and optionally returns the name 120 // Returns TRUE if the folder is a composite folder and optionally returns the name
99 bool getCompositeInfo(const LLInventoryCategory* pFolder, std::string* pstrName) const; 121 bool getCompositeInfo(const LLInventoryCategory* pFolder, std::string* pstrName) const;
100 // Returns TRUE if the inventory item belongs to a composite folder and optionally returns the name and composite folder 122 // Returns TRUE if the inventory item belongs to a composite folder and optionally returns the name and composite folder
101 bool getCompositeInfo(const LLUUID& idItem, std::string* pstrName, LLViewerInventoryCategory** ppFolder) const; 123 bool getCompositeInfo(const LLUUID& idItem, std::string* pstrName, LLViewerInventoryCategory** ppFolder) const;
102 // Returns TRUE if the folder is a composite folder 124 // Returns TRUE if the folder is a composite folder
103 bool isCompositeFolder(const LLInventoryCategory* pFolder) const; 125 bool isCompositeFolder(const LLInventoryCategory* pFolder) const { return getCompositeInfo(pFolder, NULL); }
104 // Returns TRUE if the inventory item belongs to a composite folder 126 // Returns TRUE if the inventory item belongs to a composite folder
105 bool isCompositeDescendent(const LLUUID& idItem) const; 127 bool isCompositeDescendent(const LLUUID& idItem) const { return getCompositeInfo(idItem, NULL, NULL); }
106 // Returns TRUE if the inventory item is part of a folded composite folder and should be hidden from @getoufit or @getattach 128 // Returns TRUE if the inventory item is part of a folded composite folder and should be hidden from @getoufit or @getattach
107 bool isHiddenCompositeItem(const LLUUID& idItem, const std::string& strItemType) const; 129 bool isHiddenCompositeItem(const LLUUID& idItem, const std::string& strItemType) const;
130 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
108 131
109 // -------------------------------- 132 // --------------------------------
110 133
@@ -113,29 +136,27 @@ public:
113 */ 136 */
114public: 137public:
115 // Accessors 138 // Accessors
116 bool getCanCancelTp() const { return m_fCanCancelTp; } // @accepttp and @tpto 139 bool getCanCancelTp() const { return m_fCanCancelTp; } // @accepttp and @tpto
117 void setCanCancelTp(bool fAllow) { m_fCanCancelTp = fAllow; } // @accepttp and @tpto 140 void setCanCancelTp(bool fAllow) { m_fCanCancelTp = fAllow; } // @accepttp and @tpto
118 141
119 // Command specific helper functions 142 // Command specific helper functions
120 bool canShowHoverText(LLViewerObject* pObj) const; // @showhovertext* command family 143 bool canShowHoverText(LLViewerObject* pObj) const; // @showhovertext* command family
121 void filterChat(std::string& strUTF8Text, bool fFilterEmote) const; // @sendchat, @recvchat and @redirchat 144 bool canSit(LLViewerObject* pObj, const LLVector3& posOffset = LLVector3::zero) const; //
122 void filterLocation(std::string& strUTF8Text) const; // @showloc 145 bool canTouch(LLViewerObject* pObj, const LLVector3& posOffset = LLVector3::zero) const; // @touch
123 void filterNames(std::string& strUTF8Text) const; // @shownames 146 void filterChat(std::string& strUTF8Text, bool fFilterEmote) const; // @sendchat, @recvchat and @redirchat
124 const std::string& getAnonym(const std::string& strName) const; // @shownames 147 void filterLocation(std::string& strUTF8Text) const; // @showloc
125 std::string getVersionString() const; // @version 148 void filterNames(std::string& strUTF8Text) const; // @shownames
126 std::string getVersionNumString() const; // @versionnum 149 bool isAgentNearby(const LLUUID& idAgent) const; // @shownames
127 BOOL isAgentNearby(const LLUUID& uuid) const; // @shownames 150 bool redirectChatOrEmote(const std::string& strUTF8Test) const; // @redirchat and @rediremote
128 bool redirectChatOrEmote(const std::string& strUTF8Test) const; // @redirchat and @rediremote
129 151
130 // Command processing helper functions 152 // Command processing helper functions
131 BOOL processCommand(const LLUUID& idObj, const std::string& strCommand, bool fFromObj); 153 ERlvCmdRet processCommand(const LLUUID& idObj, const std::string& strCommand, bool fFromObj);
132 void processRetainedCommands(); 154 void processRetainedCommands(ERlvBehaviour eBhvrFilter = RLV_BHVR_UNKNOWN, ERlvParamType eTypeFilter = RLV_TYPE_UNKNOWN);
133 void retainCommand(const std::string& strObj, const LLUUID& idObj, const std::string& strCmd);
134 155
135 // Returns a pointer to the currently executing command (do *not* save this pointer) 156 // Returns a pointer to the currently executing command (do *not* save this pointer)
136 const RlvCommand* getCurrentCommand() const { return m_pCurCommand; } 157 const RlvCommand* getCurrentCommand() const { return (!m_CurCommandStack.empty()) ? m_CurCommandStack.top() : NULL; }
137 // Returns the UUID of the object we're currently executing a command for 158 // Returns the UUID of the object we're currently executing a command for
138 const LLUUID& getCurrentObject() const { return m_idCurObject; } 159 const LLUUID& getCurrentObject() const { return (!m_CurObjectStack.empty()) ? m_CurObjectStack.top() : LLUUID::null; }
139 160
140 // Initialization 161 // Initialization
141 static BOOL canDisable(); 162 static BOOL canDisable();
@@ -155,16 +176,13 @@ public:
155 static void fetchSharedInventory(); 176 static void fetchSharedInventory();
156 // Returns the path of the supplied folder (relative to the shared root) 177 // Returns the path of the supplied folder (relative to the shared root)
157 std::string getSharedPath(const LLViewerInventoryCategory* pFolder) const; 178 std::string getSharedPath(const LLViewerInventoryCategory* pFolder) const;
158 std::string getSharedPath(const LLUUID& idFolder) const;
159 // Returns a pointer to the shared root folder (if there is one) 179 // Returns a pointer to the shared root folder (if there is one)
160 static LLViewerInventoryCategory* getSharedRoot(); 180 static LLViewerInventoryCategory* getSharedRoot();
161 // A "folded folder" is a folder whose items logically belong to the grandparent rather than the parent 181 // A "folded folder" is a folder whose items logically belong to the grandparent rather than the parent
162 bool isFoldedFolder(const LLInventoryCategory* pFolder, bool fAttach) const; 182 bool isFoldedFolder(const LLInventoryCategory* pFolder, bool fAttach, bool fCheckComposite) const;
163 bool isFoldedFolderLegacy(const LLInventoryCategory* pFolder, bool fAttach) const;
164protected: 183protected:
165 // Find all folders that match a supplied criteria (clears the supplied array) 184 // Find all folders that match a supplied criteria (clears the supplied array)
166 bool findSharedFolders(const std::string& strCriteria, LLInventoryModel::cat_array_t& folders) const; 185 bool findSharedFolders(const std::string& strCriteria, LLInventoryModel::cat_array_t& folders) const;
167
168 // Returns a subfolder of idParent that starts with name (exact match > partial match) 186 // Returns a subfolder of idParent that starts with name (exact match > partial match)
169 LLViewerInventoryCategory* getSharedFolder(const LLUUID& idParent, const std::string& strName) const; 187 LLViewerInventoryCategory* getSharedFolder(const LLUUID& idParent, const std::string& strName) const;
170 // Looks up a folder from a path (relative to the shared root) 188 // Looks up a folder from a path (relative to the shared root)
@@ -175,43 +193,55 @@ protected:
175 // -------------------------------- 193 // --------------------------------
176 194
177 /* 195 /*
178 * Event handling (forwards to registered observers if we don't handle the command) 196 * Event handling
179 */ 197 */
180public: 198public:
181 BOOL addObserver(RlvObserver* pObserver) { return m_Emitter.addObserver(pObserver); }
182 BOOL removeObserver(RlvObserver* pObserver) { return m_Emitter.remObserver(pObserver); }
183 void addBehaviourObserver(RlvBehaviourObserver* pBhvrObserver); 199 void addBehaviourObserver(RlvBehaviourObserver* pBhvrObserver);
200 void addCommandHandler(RlvCommandHandler* pHandler);
184 void removeBehaviourObserver(RlvBehaviourObserver* pBhvrObserver); 201 void removeBehaviourObserver(RlvBehaviourObserver* pBhvrObserver);
202 void removeCommandHandler(RlvCommandHandler* pHandler);
203protected:
204 void clearCommandHandlers();
185 void notifyBehaviourObservers(const RlvCommand& rlvCmd, bool fInternal); 205 void notifyBehaviourObservers(const RlvCommand& rlvCmd, bool fInternal);
206 bool notifyCommandHandlers(rlvCommandHandler f, const LLUUID& idObj, const RlvCommand& rlvCmd, ERlvCmdRet& eRet, bool fNotifyAll) const;
186 207
187 // Externally invoked event handlers 208 // Externally invoked event handlers
209public:
188 void onAttach(LLViewerJointAttachment* pAttachPt); // LLVOAvatar::attachObject() 210 void onAttach(LLViewerJointAttachment* pAttachPt); // LLVOAvatar::attachObject()
189 void onDetach(LLViewerJointAttachment* pAttachPt); // LLVOAvatar::detachObject() 211 void onDetach(LLViewerJointAttachment* pAttachPt); // LLVOAvatar::detachObject()
190 bool onGC(); // RlvGCTimer::tick() 212 bool onGC(); // RlvGCTimer::tick()
191 void onSavedAssetIntoInventory(const LLUUID& idItem) { if (m_pAttachMgr) m_pAttachMgr->onSavedAssetIntoInventory(idItem); } 213 void onSavedAssetIntoInventory(const LLUUID& idItem) { if (m_pAttachMgr) m_pAttachMgr->onSavedAssetIntoInventory(idItem); }
192 void onWearAttachment(const LLUUID& idItem) { if (m_pAttachMgr) m_pAttachMgr->onWearAttachment(idItem); } 214 void onWearAttachment(const LLUUID& idItem) { if (m_pAttachMgr) m_pAttachMgr->onWearAttachment(idItem); }
215 static void onIdleStartup(void* pParam);
216
217 /*
218 * Command processing
219 */
193protected: 220protected:
194 BOOL processAddCommand(const LLUUID& uuid, const RlvCommand& rlvCmd); 221 ERlvCmdRet processCommand(const LLUUID& idObj, const RlvCommand& rlvCmd, bool fFromObj);
195 BOOL processRemoveCommand(const LLUUID& uuid, const RlvCommand& rlvCmd); 222 ERlvCmdRet processClearCommand(const LLUUID& idObj, const RlvCommand& rlvCmd);
196 BOOL processClearCommand(const LLUUID idObj, const RlvCommand& rlvCmd); 223 ERlvCmdRet processReplyCommand(const LLUUID& idObj, const RlvCommand& rlvCmd) const;
197 BOOL processReplyCommand(const LLUUID& uuid, const RlvCommand& rlvCmd) const; 224 ERlvCmdRet processForceCommand(const LLUUID& idObj, const RlvCommand& rlvCmd) const;
198 BOOL processForceCommand(const LLUUID& uuid, const RlvCommand& rlvCmd) const;
199 225
200 // Command handlers (exist for no other reason than to keep the length of the processXXX functions down) 226 // Command handlers (RLV_TYPE_ADD and RLV_TYPE_CLEAR)
227 ERlvCmdRet processAddRemCommand(const LLUUID& idObj, const RlvCommand& rlvCmd);
201 ERlvCmdRet onAddRemAttach(const LLUUID& idObj, const RlvCommand& rlvCmd, bool& fRefCount); 228 ERlvCmdRet onAddRemAttach(const LLUUID& idObj, const RlvCommand& rlvCmd, bool& fRefCount);
202 ERlvCmdRet onAddRemDetach(const LLUUID& idObj, const RlvCommand& rlvCmd, bool& fRefCount); 229 ERlvCmdRet onAddRemDetach(const LLUUID& idObj, const RlvCommand& rlvCmd, bool& fRefCount);
203 ERlvCmdRet onAddRemOutfit(const LLUUID& idObj, const RlvCommand& rlvCmd, bool& fRefCount); 230 ERlvCmdRet onAddRemSetEnv(const LLUUID& idObj, const RlvCommand& rlvCmd, bool& fRefCount);
204 ERlvCmdRet onForceDetach(const LLUUID& idObj, const RlvCommand& rlvCmd) const; 231 // Command handlers (RLV_TYPE_FORCE)
205 ERlvCmdRet onForceRemAttach(const LLUUID& idObj, const RlvCommand& rlvCmd) const; 232 ERlvCmdRet onForceRemAttach(const LLUUID& idObj, const RlvCommand& rlvCmd) const;
206 ERlvCmdRet onForceRemOutfit(const LLUUID& idObj, const RlvCommand& rlvCmd) const; 233 ERlvCmdRet onForceRemOutfit(const LLUUID& idObj, const RlvCommand& rlvCmd) const;
207 ERlvCmdRet onGetAttach(const LLUUID& idObj, const RlvCommand& rlvCmd, std::string& strReply); 234 ERlvCmdRet onForceSit(const LLUUID& idObj, const RlvCommand& rlvCmd) const;
208 ERlvCmdRet onGetOutfit(const LLUUID& idObj, const RlvCommand& rlvCmd, std::string& strReply); 235 ERlvCmdRet onForceWear(const std::string& strPath, bool fAttach, bool fMatchAll) const;
209 // Old style command handlers (need to be updated to return ERlvCmdRet) 236 // Command handlers (RLV_TYPE_REPLY)
210 void onForceRemOutfit(const LLUUID& idObj, const std::string& strOption) const; 237 ERlvCmdRet onFindFolder(const LLUUID& idObj, const RlvCommand& rlvCmd, std::string& strReply) const;
211 bool onForceSit(const LLUUID& uuid, const std::string& strOption) const; 238 ERlvCmdRet onGetAttach(const LLUUID& idObj, const RlvCommand& rlvCmd, std::string& strReply) const;
212 void onForceWear(const std::string& strPath, bool fAttach, bool fMatchAll) const; 239 ERlvCmdRet onGetAttachNames(const LLUUID& idObj, const RlvCommand& rlvCmd, std::string& strReply) const;
213 bool onGetPath(const LLUUID& uuid, const std::string& strOption, std::string& strReply) const; 240 ERlvCmdRet onGetInv(const LLUUID& idObj, const RlvCommand& rlvCmd, std::string& strReply) const;
214 void onGetInvWorn(const std::string& strPath, std::string &strReply) const; 241 ERlvCmdRet onGetInvWorn(const LLUUID& idObj, const RlvCommand& rlvCmd, std::string& strReply) const;
242 ERlvCmdRet onGetOutfit(const LLUUID& idObj, const RlvCommand& rlvCmd, std::string& strReply) const;
243 ERlvCmdRet onGetOutfitNames(const LLUUID& idObj, const RlvCommand& rlvCmd, std::string& strReply) const;
244 ERlvCmdRet onGetPath(const LLUUID& idObj, const RlvCommand& rlvCmd, std::string& strReply) const;
215 245
216 // -------------------------------- 246 // --------------------------------
217 247
@@ -219,18 +249,7 @@ protected:
219 * Member variables 249 * Member variables
220 */ 250 */
221public: 251public:
222 static BOOL fNoSetEnv;
223 static BOOL fLegacyNaming;
224
225 static const std::string cstrSharedRoot; // Name of the shared root folder 252 static const std::string cstrSharedRoot; // Name of the shared root folder
226 static const std::string cstrBlockedRecvIM; // Stand-in text for incoming IM when recvim restricted
227 static const std::string cstrBlockedSendIM; // Stand-in text for outgoing IM when sendim restricted
228 static const std::string cstrHidden; // General purpose "this was censored" text
229 static const std::string cstrHiddenParcel;
230 static const std::string cstrHiddenRegion;
231 static const std::string cstrMsgRecvIM; // Message sent to IM sender when sendim restricted
232 static const std::string cstrMsgTpLure; // Message sent to tplure sender when tplure restricted
233 static const std::string cstrAnonyms[28];
234protected: 253protected:
235 rlv_object_map_t m_Objects; // Map of objects that have active restrictions (idObj -> RlvObject) 254 rlv_object_map_t m_Objects; // Map of objects that have active restrictions (idObj -> RlvObject)
236 rlv_exception_map_t m_Exceptions; // Map of currently active restriction exceptions (ERlvBehaviour -> RlvException) 255 rlv_exception_map_t m_Exceptions; // Map of currently active restriction exceptions (ERlvBehaviour -> RlvException)
@@ -245,16 +264,16 @@ protected:
245 RlvWLSnapshot* m_pWLSnapshot; 264 RlvWLSnapshot* m_pWLSnapshot;
246 RlvAttachmentManager* m_pAttachMgr; 265 RlvAttachmentManager* m_pAttachMgr;
247 266
248 RlvCommand* m_pCurCommand; // Convenience (see @tpto) 267 std::stack<const RlvCommand*> m_CurCommandStack;// Convenience (see @tpto)
249 LLUUID m_idCurObject; // Convenience (see @tpto) 268 std::stack<LLUUID> m_CurObjectStack; // Convenience (see @tpto)
250 269
251 mutable RlvEventEmitter<RlvObserver> m_Emitter;
252 mutable std::list<RlvBehaviourObserver*> m_BhvrObservers; 270 mutable std::list<RlvBehaviourObserver*> m_BhvrObservers;
271 mutable std::list<RlvCommandHandler*> m_CommandHandlers;
253 RlvBehaviourNotifyObserver* m_pBhvrNotify; 272 RlvBehaviourNotifyObserver* m_pBhvrNotify;
254 273
255 static BOOL m_fEnabled; // Use setEnabled() to toggle this 274 static BOOL m_fEnabled; // Use setEnabled() to toggle this
256 static BOOL m_fFetchStarted; // TRUE if we fired off an inventory fetch 275 static bool m_fFetchStarted; // TRUE if we fired off an inventory fetch
257 static BOOL m_fFetchComplete; // TRUE if everything was fetched 276 static bool m_fFetchComplete; // TRUE if everything was fetched
258 static RlvMultiStringSearch m_AttachLookup; // Lookup table for attachment names (lower case) 277 static RlvMultiStringSearch m_AttachLookup; // Lookup table for attachment names (lower case)
259 278
260 bool m_fCanCancelTp; 279 bool m_fCanCancelTp;
@@ -302,46 +321,108 @@ inline bool RlvHandler::canShowHoverText(LLViewerObject *pObj) const
302 (isException(RLV_BHVR_SHOWHOVERTEXT, pObj->getID(), RLV_CHECK_PERMISSIVE)) ) ); 321 (isException(RLV_BHVR_SHOWHOVERTEXT, pObj->getID(), RLV_CHECK_PERMISSIVE)) ) );
303} 322}
304 323
305// Checked: 2009-05-23 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d 324// Checked: 2009-12-21 (RLVa-1.1.0k) | Added: RLVa-1.1.0j
306inline S32 RlvHandler::getAttachPointIndex(std::string strText, bool fExact) const 325inline bool RlvHandler::canSit(LLViewerObject* pObj, const LLVector3& posOffset /*= LLVector3::zero*/) const
307{ 326{
308 U16 nParam; RlvMultiStringSearchMatch match; 327 // The user can sit on the specified object if:
309 LLStringUtil::toLower(strText); 328 // - not prevented from sitting
310 return (fExact) ? ((m_AttachLookup.getExactMatchParam(strText, nParam)) ? nParam : 0) 329 // - not prevented from standing up or not currently sitting
311 : ((m_AttachLookup.findLast(strText, match)) ? match.nParam : 0); 330 // - [regular sit] not @sittp=n or @fartouch=n restricted or if they clicked on a point within 1.5m of the avie's current position
331 // - [force sit] not @sittp=n restricted by a *different* object than the one that issued the command or the object is within 1.5m
332 return
333 ( (pObj) && (LL_PCODE_VOLUME == pObj->getPCode()) ) &&
334 (!hasBehaviour(RLV_BHVR_SIT)) &&
335 ( (!hasBehaviour(RLV_BHVR_UNSIT)) || ((gAgent.getAvatarObject()) && (!gAgent.getAvatarObject()->mIsSitting)) ) &&
336 ( ((NULL == getCurrentCommand() || (RLV_BHVR_SIT != getCurrentCommand()->getBehaviourType()))
337 ? ((!hasBehaviour(RLV_BHVR_SITTP)) && (!hasBehaviour(RLV_BHVR_FARTOUCH))) // [regular sit]
338 : (!hasBehaviourExcept(RLV_BHVR_SITTP, getCurrentObject()))) || // [force sit]
339 (dist_vec_squared(gAgent.getPositionGlobal(), pObj->getPositionGlobal() + LLVector3d(posOffset)) < 1.5f * 1.5f) );
312} 340}
313 341
314// Checked: 2009-05-23 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d 342// Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l
315inline S32 RlvHandler::getAttachPointIndex(LLViewerObject* pObj) const 343inline bool RlvHandler::canTouch(LLViewerObject* pObj, const LLVector3& posOffset /*=LLVector3::zero*/) const
316{ 344{
317 return (pObj) ? ATTACHMENT_ID_FROM_STATE(pObj->getState()) : 0; 345#ifdef RLV_EXTENSION_CMD_TOUCHXXX
346 bool fCanTouch = (pObj) &&
347 ( (!hasBehaviour(RLV_BHVR_TOUCH)) || (!isException(RLV_BHVR_TOUCH, pObj->getRootEdit()->getID(), RLV_CHECK_PERMISSIVE)) );
348
349 if (fCanTouch)
350 {
351 if ( (!pObj->isAttachment()) || (!pObj->permYouOwner()) )
352 {
353 // Rezzed prim or attachment worn by another avie
354 fCanTouch =
355 ( (!hasBehaviour(RLV_BHVR_TOUCHWORLD)) ||
356 (isException(RLV_BHVR_TOUCHWORLD, pObj->getRootEdit()->getID(), RLV_CHECK_PERMISSIVE)) ) &&
357 ( (!hasBehaviour(RLV_BHVR_FARTOUCH)) ||
358 (dist_vec_squared(gAgent.getPositionGlobal(), pObj->getPositionGlobal() + LLVector3d(posOffset)) <= 1.5f * 1.5f) );
359 }
360 else if (pObj->isHUDAttachment())
361 {
362 // HUD attachment
363 fCanTouch = (!hasBehaviour(RLV_BHVR_TOUCHHUD)) ||
364 (isException(RLV_BHVR_TOUCHHUD, pObj->getRootEdit()->getID(), RLV_CHECK_PERMISSIVE));
365 }
366 else
367 {
368 // Regular attachment worn by this avie
369 fCanTouch =
370 ( (!hasBehaviour(RLV_BHVR_TOUCHATTACH)) ||
371 (isException(RLV_BHVR_TOUCHATTACH, pObj->getRootEdit()->getID(), RLV_CHECK_PERMISSIVE)) );
372 }
373 }
374 return fCanTouch;
375#else
376 return (pObj) &&
377 (
378 ((pObj->isAttachment()) && (pObj->permYouOwner())) ||
379 ( (!hasBehaviour(RLV_BHVR_FARTOUCH)) ||
380 (dist_vec_squared(gAgent.getPositionGlobal(), pObj->getPositionGlobal() + LLVector3d(posOffset)) <= 1.5f * 1.5f) )
381 );
382#endif // RLV_EXTENSION_CMD_TOUCHXXX
383}
384
385// Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0d
386inline LLViewerJointAttachment* RlvHandler::getAttachPoint(const std::string& strText, bool fExact) const
387{
388 LLVOAvatar* pAvatar = gAgent.getAvatarObject();
389 return (pAvatar) ? get_if_there(pAvatar->mAttachmentPoints, getAttachPointIndex(strText, fExact), (LLViewerJointAttachment*)NULL)
390 : NULL;
391}
392
393// Checked: 2009-07-29 (RLVa-1.0.1b) | Modified: RLVa-1.0.1b
394inline LLViewerJointAttachment* RlvHandler::getAttachPoint(const LLInventoryCategory* pFolder, bool fStrict) const
395{
396 LLVOAvatar* pAvatar = gAgent.getAvatarObject();
397 return (pAvatar) ? get_if_there(pAvatar->mAttachmentPoints, getAttachPointIndex(pFolder, fStrict), (LLViewerJointAttachment*)NULL) : NULL;
318} 398}
319 399
320// Checked: 2009-06-02 (RLVa-0.2.0g) 400// Checked: 2009-07-29 (RLVa-1.0.1b) | Modified: RLVa-1.0.1b
321inline std::string RlvHandler::getSharedPath(const LLUUID& idFolder) const 401inline LLViewerJointAttachment* RlvHandler::getAttachPoint(const LLInventoryItem* pItem, bool fStrict) const
322{ 402{
323 return getSharedPath(gInventory.getCategory(idFolder)); // getSharedPath() has a NULL pointer check so this is safe 403 LLVOAvatar* pAvatar = gAgent.getAvatarObject();
404 return (pAvatar) ? get_if_there(pAvatar->mAttachmentPoints, getAttachPointIndex(pItem, fStrict), (LLViewerJointAttachment*)NULL) : NULL;
324} 405}
325 406
326// Checked: 2009-06-07 (RLVa-0.2.1c) 407// Checked: 2009-05-23 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d
327inline std::string RlvHandler::getVersionString() const 408inline S32 RlvHandler::getAttachPointIndex(std::string strText, bool fExact) const
328{ 409{
329 return llformat("RestrainedLife viewer v%d.%d.%d (%s %d.%d.%d.%d - RLVa %d.%d.%d)", 410 U16 nParam; RlvMultiStringSearchMatch match;
330 RLV_VERSION_MAJOR, RLV_VERSION_MINOR, RLV_VERSION_PATCH, 411 LLStringUtil::toLower(strText);
331 LLAppViewer::instance()->getSecondLifeTitle().c_str(), LL_VERSION_MAJOR, LL_VERSION_MINOR, LL_VERSION_PATCH, LL_VERSION_BUILD, 412 return (fExact) ? ((m_AttachLookup.getExactMatchParam(strText, nParam)) ? nParam : 0)
332 RLVa_VERSION_MAJOR, RLVa_VERSION_MINOR, RLVa_VERSION_PATCH); 413 : ((m_AttachLookup.findLast(strText, match)) ? match.nParam : 0);
333} 414}
334 415
335// Checked: 2009-10-04 (RLVa-1.0.4b) | Added: RLVa-1.0.4b 416// Checked: 2009-05-23 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d
336inline std::string RlvHandler::getVersionNumString() const 417inline S32 RlvHandler::getAttachPointIndex(LLViewerObject* pObj) const
337{ 418{
338 return llformat("%d%02d%02d%02d", RLV_VERSION_MAJOR, RLV_VERSION_MINOR, RLV_VERSION_PATCH, RLV_VERSION_BUILD); 419 return (pObj) ? ATTACHMENT_ID_FROM_STATE(pObj->getState()) : 0;
339} 420}
340 421
341// Checked: 2009-05-23 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d 422// Checked: 2009-05-23 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d
342inline bool RlvHandler::hasAttachPointName(const LLInventoryItem *pItem, bool fStrict) const 423inline bool RlvHandler::hasAttachPointName(const LLInventoryItem *pItem, bool fStrict) const
343{ 424{
344 return (getAttachPoint(pItem, fStrict) != NULL); // getAttachPoint() has a NULL pointer check so this is safe 425 return (0 != getAttachPointIndex(pItem, fStrict)); // getAttachPoint() has a NULL pointer check so this is safe
345} 426}
346 427
347// Checked: 428// Checked:
@@ -363,39 +444,23 @@ inline bool RlvHandler::hasLockedAttachment(ERlvLockMask eLock) const
363 return ( (eLock & RLV_LOCK_REMOVE) && (!m_AttachRem.empty()) ) || ( (eLock & RLV_LOCK_ADD) && (!m_AttachAdd.empty()) ); 444 return ( (eLock & RLV_LOCK_REMOVE) && (!m_AttachRem.empty()) ) || ( (eLock & RLV_LOCK_ADD) && (!m_AttachAdd.empty()) );
364} 445}
365 446
366#ifdef RLV_EXPERIMENTAL_COMPOSITES 447// Checked: 2009-12-18 (RLVa-1.1.0k) | Added: RLVa-1.1.0i
367 // Checked: 448inline bool RlvHandler::isFoldedFolder(const LLInventoryCategory* pFolder, bool fAttach, bool fCheckComposite) const
368 inline bool RlvHandler::isCompositeFolder(const LLInventoryCategory* pFolder) const
369 {
370 return getCompositeInfo(pFolder, NULL);
371 }
372
373 // Checked:
374 inline bool RlvHandler::isCompositeDescendent(const LLUUID& idItem) const
375 {
376 return getCompositeInfo(idItem, NULL, NULL);
377 }
378#endif // RLV_EXPERIMENTAL_COMPOSITES
379
380inline bool RlvHandler::isPermissive(ERlvBehaviour eBhvr) const
381{
382 return (RlvCommand::hasStrictVariant(eBhvr))
383 ? !((hasBehaviour(RLV_BHVR_PERMISSIVE)) || (isException(RLV_BHVR_PERMISSIVE, eBhvr, RLV_CHECK_PERMISSIVE)))
384 : true;
385}
386
387// Checked: 2009-07-29 (RLVa-1.0.1b) | Added: RLVa-1.0.1b
388inline bool RlvHandler::isFoldedFolder(const LLInventoryCategory* pFolder, bool fAttach) const
389{ 449{
390 return 450 return
391 ( 451 (
392 // .(<attachpt>) type folder (on detach we don't care about its children, but on attach there can only be 1 attachment) 452 // .(<attachpt>) type folder (on detach we don't care about its children, but on attach there can only be 1 attachment)
393 ( (gRlvHandler.getAttachPoint(pFolder, true)) && 453 ( (0 != gRlvHandler.getAttachPointIndex(pFolder, true)) &&
394 ( (!fAttach) || (1 == rlvGetDirectDescendentsCount(pFolder, LLAssetType::AT_OBJECT))) ) 454 ( (!fAttach) || (1 == rlvGetDirectDescendentsCount(pFolder, LLAssetType::AT_OBJECT))) )
395 #ifdef RLV_EXTENSION_FLAG_NOSTRIP 455 #ifdef RLV_EXTENSION_FLAG_NOSTRIP
396 // .(nostrip) folder 456 // .(nostrip) folder
397 || ( (pFolder) && (".("RLV_FOLDER_FLAG_NOSTRIP")" == pFolder->getName()) ) 457 || ( (pFolder) && (".("RLV_FOLDER_FLAG_NOSTRIP")" == pFolder->getName()) )
398 #endif // RLV_EXTENSION_FLAG_NOSTRIP 458 #endif // RLV_EXTENSION_FLAG_NOSTRIP
459 // .[Composite] folder (if composite folders are enabled and we're asked to look for them)
460 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
461 || ( (fCheckComposite) && (RlvSettings::getEnableComposites()) &&
462 (RLV_FOLDER_PREFIX_HIDDEN == pFolder->getName().at(0)) && (isCompositeFolder(pFolder)) )
463 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
399 ); 464 );
400} 465}
401 466
@@ -406,6 +471,12 @@ inline bool RlvHandler::isLockedAttachment(S32 idxAttachPt, ERlvLockMask eLock)
406 ( (eLock & RLV_LOCK_ADD) && (m_AttachAdd.find(idxAttachPt) != m_AttachAdd.end()) ); 471 ( (eLock & RLV_LOCK_ADD) && (m_AttachAdd.find(idxAttachPt) != m_AttachAdd.end()) );
407} 472}
408 473
474// Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a
475inline bool RlvHandler::isLockedAttachment(const LLInventoryItem* pItem, ERlvLockMask eLock) const
476{
477 LLVOAvatar* pAvatar = gAgent.getAvatarObject();
478 return (pItem) && (pAvatar) && (isLockedAttachment(pAvatar->getWornAttachment(pItem->getUUID()), eLock));
479}
409 480
410// Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a 481// Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a
411inline bool RlvHandler::isLockedAttachment(LLViewerJointAttachment *pAttachPt, ERlvLockMask eLock) const 482inline bool RlvHandler::isLockedAttachment(LLViewerJointAttachment *pAttachPt, ERlvLockMask eLock) const
@@ -422,6 +493,19 @@ inline bool RlvHandler::isLockedAttachment(LLViewerObject* pObj, ERlvLockMask eL
422 return (pObj != NULL) && (pObj->isAttachment()) && (isLockedAttachment(getAttachPointIndex(pObj), eLock)); 493 return (pObj != NULL) && (pObj->isAttachment()) && (isLockedAttachment(getAttachPointIndex(pObj), eLock));
423} 494}
424 495
496// Checked: 2009-11-24 (RLVa-1.1.0e) | Added: RLVa-1.1.0e
497inline bool RlvHandler::isLockedAttachmentExcept(LLViewerObject* pObj, ERlvLockMask eLock, LLViewerObject* pExceptObj) const
498{
499 return (pObj != NULL) && (pObj->isAttachment()) && (isLockedAttachmentExcept(getAttachPointIndex(pObj), eLock, pExceptObj));
500}
501
502inline bool RlvHandler::isPermissive(ERlvBehaviour eBhvr) const
503{
504 return (RlvCommand::hasStrictVariant(eBhvr))
505 ? !((hasBehaviour(RLV_BHVR_PERMISSIVE)) || (isException(RLV_BHVR_PERMISSIVE, eBhvr, RLV_CHECK_PERMISSIVE)))
506 : true;
507}
508
425// Checked: 2009-05-23 (RLVa-0.2.0d) | Added: RLVa-0.2.0d 509// Checked: 2009-05-23 (RLVa-0.2.0d) | Added: RLVa-0.2.0d
426inline bool RlvHandler::isRemovableExcept(EWearableType type, const LLUUID& idObj) const 510inline bool RlvHandler::isRemovableExcept(EWearableType type, const LLUUID& idObj) const
427{ 511{
@@ -431,8 +515,7 @@ inline bool RlvHandler::isRemovableExcept(EWearableType type, const LLUUID& idOb
431} 515}
432 516
433#ifndef RLV_EXTENSION_FLAG_NOSTRIP 517#ifndef RLV_EXTENSION_FLAG_NOSTRIP
434 // Checked: 2009-05-23 (RLVa-0.2.0d) | Added: RLVa-0.2.0d 518 inline bool RlvHandler::isStrippable(const LLUUID& idItem) const
435 bool RlvHandler::isStrippable(const LLUUID& idItem) const
436 { 519 {
437 return true; 520 return true;
438 } 521 }
@@ -452,13 +535,15 @@ inline void RlvHandler::removeException(const LLUUID& idObj, ERlvBehaviour eBhvr
452 } 535 }
453} 536}
454 537
455// Checked: 2009-08-05 (RLVa-1.0.1e) | Modified: RLVa-1.0.1e 538// Checked: 2009-11-25 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
456inline void RlvHandler::retainCommand(const std::string& strObj, const LLUUID& idObj, const std::string& strCmd) 539inline ERlvCmdRet RlvHandler::processCommand(const LLUUID& idObj, const std::string& strCommand, bool fFromObj)
457{ 540{
458 #ifdef RLV_DEBUG 541 if (STATE_STARTED != LLStartUp::getStartupState())
459 RLV_INFOS << "[" << idObj << "]: " << strCmd << " (retaining)" << LL_ENDL; 542 {
460 #endif // RLV_DEBUG 543 m_Retained.push_back(RlvRetainedCommand(idObj, RlvCommand(strCommand)));
461 m_Retained.push_back(RlvRetainedCommand(strObj, idObj, strCmd)); 544 return RLV_RET_RETAINED;
545 }
546 return processCommand(idObj, RlvCommand(strCommand), fFromObj);
462} 547}
463 548
464// ============================================================================ 549// ============================================================================
diff --git a/linden/indra/newview/rlvhelper.cpp b/linden/indra/newview/rlvhelper.cpp
index f509a43..9ef74ac 100644
--- a/linden/indra/newview/rlvhelper.cpp
+++ b/linden/indra/newview/rlvhelper.cpp
@@ -1,27 +1,31 @@
1#include "llviewerprecompiledheaders.h" 1#include "llviewerprecompiledheaders.h"
2#include "llagent.h"
3#include "llfloaterwindlight.h" 2#include "llfloaterwindlight.h"
3#include "llgesturemgr.h"
4#include "llinventoryview.h"
5#include "llinventorybridge.h"
4#include "llviewerobject.h" 6#include "llviewerobject.h"
7#include "llviewerobjectlist.h"
8#include "llviewerregion.h"
5#include "llviewerstats.h" 9#include "llviewerstats.h"
6#include "llviewerwindow.h" 10#include "llviewerwindow.h"
7#include "llvoavatar.h" 11#include "llvoavatar.h"
12#include "llwearablelist.h"
8#include "llwlparammanager.h" 13#include "llwlparammanager.h"
9 14
10#include "rlvhelper.h" 15#include "rlvhelper.h"
11#include "rlvevent.h"
12#include "rlvhandler.h" 16#include "rlvhandler.h"
13 17
14// ============================================================================ 18// Defined in llinventorybridge.cpp
15// Static variable initialization 19void wear_attachments_on_avatar(const LLInventoryModel::item_array_t& items, BOOL remove);
16// 20void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void*);
17
18RlvCommand::RlvBhvrTable RlvCommand::m_BhvrMap;
19 21
20// ============================================================================ 22// ============================================================================
21// RlvCommmand 23// RlvCommmand
22// 24//
23 25
24// Checked: 2009-09-10 (RLVa-1.0.3a) | Modified: RLVa-1.0.3a 26RlvCommand::RlvBhvrTable RlvCommand::m_BhvrMap;
27
28// Checked: 2009-12-27 (RLVa-1.1.0k) | Modified: RLVa-1.1.0k
25RlvCommand::RlvCommand(const std::string& strCommand) 29RlvCommand::RlvCommand(const std::string& strCommand)
26 : m_eBehaviour(RLV_BHVR_UNKNOWN), m_fStrict(false), m_eParamType(RLV_TYPE_UNKNOWN) 30 : m_eBehaviour(RLV_BHVR_UNKNOWN), m_fStrict(false), m_eParamType(RLV_TYPE_UNKNOWN)
27{ 31{
@@ -32,12 +36,12 @@ RlvCommand::RlvCommand(const std::string& strCommand)
32 m_eParamType = RLV_TYPE_ADD; 36 m_eParamType = RLV_TYPE_ADD;
33 else if ( ("y" == m_strParam) || ("rem" == m_strParam) ) 37 else if ( ("y" == m_strParam) || ("rem" == m_strParam) )
34 m_eParamType = RLV_TYPE_REMOVE; 38 m_eParamType = RLV_TYPE_REMOVE;
39 else if (m_strBehaviour == "clear") // clear is the odd one out so just make it its own type
40 m_eParamType = RLV_TYPE_CLEAR;
35 else if ("force" == m_strParam) 41 else if ("force" == m_strParam)
36 m_eParamType = RLV_TYPE_FORCE; 42 m_eParamType = RLV_TYPE_FORCE;
37 else if (LLStringUtil::convertToS32(m_strParam, nTemp)) // Assume it's a reply command if we can convert <param> to an S32 43 else if (LLStringUtil::convertToS32(m_strParam, nTemp)) // Assume it's a reply command if we can convert <param> to an S32
38 m_eParamType = RLV_TYPE_REPLY; 44 m_eParamType = RLV_TYPE_REPLY;
39 else if (m_strBehaviour == "clear") // clear is the odd one out so just make it its own type
40 m_eParamType = RLV_TYPE_CLEAR;
41 else 45 else
42 { 46 {
43 m_eParamType = RLV_TYPE_UNKNOWN; 47 m_eParamType = RLV_TYPE_UNKNOWN;
@@ -51,13 +55,7 @@ RlvCommand::RlvCommand(const std::string& strCommand)
51 return; 55 return;
52 } 56 }
53 57
54 // Check if this is the "strict" (aka "secure") variation of a behaviour 58 m_eBehaviour = getBehaviourFromString(m_strBehaviour, &m_fStrict);
55 std::string::size_type idxStrict = m_strBehaviour.find("_sec");
56 m_fStrict = (std::string::npos != idxStrict) && (idxStrict + 4 == m_strBehaviour.length());
57
58 RlvBhvrTable::const_iterator itBhvr = m_BhvrMap.find( (!m_fStrict) ? m_strBehaviour : m_strBehaviour.substr(0, idxStrict));
59 if ( (itBhvr != m_BhvrMap.end()) && ((!m_fStrict) || (hasStrictVariant(itBhvr->second))) )
60 m_eBehaviour = itBhvr->second;
61} 59}
62 60
63 61
@@ -95,6 +93,20 @@ bool RlvCommand::parseCommand(const std::string& strCommand, std::string& strBeh
95 return true; 93 return true;
96} 94}
97 95
96// Checked: 2009-12-05 (RLVa-1.1.0h) | Added: RLVa-1.1.0h
97ERlvBehaviour RlvCommand::getBehaviourFromString(const std::string& strBhvr, bool* pfStrict /*=NULL*/)
98{
99 std::string::size_type idxStrict = strBhvr.find("_sec");
100 bool fStrict = (std::string::npos != idxStrict) && (idxStrict + 4 == strBhvr.length());
101 if (pfStrict)
102 *pfStrict = fStrict;
103
104 RlvBhvrTable::const_iterator itBhvr = m_BhvrMap.find( (!fStrict) ? strBhvr : strBhvr.substr(0, idxStrict));
105 if ( (itBhvr != m_BhvrMap.end()) && ((!fStrict) || (hasStrictVariant(itBhvr->second))) )
106 return itBhvr->second;
107 return RLV_BHVR_UNKNOWN;
108}
109
98void RlvCommand::initLookupTable() 110void RlvCommand::initLookupTable()
99{ 111{
100 static bool fInitialized = false; 112 static bool fInitialized = false;
@@ -103,14 +115,16 @@ void RlvCommand::initLookupTable()
103 // NOTE: keep this matched with the enumeration at all times 115 // NOTE: keep this matched with the enumeration at all times
104 std::string arBehaviours[RLV_BHVR_COUNT] = 116 std::string arBehaviours[RLV_BHVR_COUNT] =
105 { 117 {
106 "version", "detach", "sendchat", "emote", "chatshout", "chatnormal", "chatwhisper", "redirchat", "rediremote", 118 "detach", "attach", "addattach", "remattach", "addoutfit", "remoutfit", "emote", "sendchat", "recvchat", "recvemote",
107 "sendim", "recvchat", "recvemote", "recvim", "tplm", "tploc", "tplure", "sittp", "edit", "rez", 119 "redirchat", "rediremote", "chatwhisper", "chatnormal", "chatshout", "sendchannel", "sendim", "recvim", "permissive",
108 "addoutfit", "remoutfit", "getoutfit", "addattach", "remattach", "getattach", "showinv", "viewnote", "unsit", "sit", 120 "notify", "showinv", "showminimap", "showworldmap", "showloc", "shownames", "showhovertext", "showhovertexthud",
109 "sendchannel", "getstatus", "getstatusall", "getinv", "getinvworn", "findfolder", "findfolders", 121 "showhovertextworld", "showhovertextall", "tplm", "tploc", "tplure", "viewnote", "viewscript", "viewtexture",
110 "attach", "attachall", "detachall", "getpath", "attachthis", "attachallthis", "detachthis", "detachallthis", 122 "acceptpermission", "accepttp", "defaultwear", "allowidle", "edit", "rez", "fartouch", "interact", "touch",
111 "fartouch", "showworldmap", "showminimap", "showloc", "tpto", "accepttp", "acceptpermission", "shownames", "fly", 123 "touchattach", "touchhud", "touchworld", "fly", "unsit", "sit", "sittp", "setdebug", "setenv", "detachme", "detachthis",
112 "getsitid", "setdebug", "setenv", "detachme", "showhovertextall", "showhovertextworld", "showhovertexthud", 124 "detachall", "detachallthis", "attachthis", "attachall", "attachallthis", "tpto", "version", "versionnew", "versionnum",
113 "showhovertext", "notify", "defaultwear", "versionnum", "permissive", "viewscript", "viewtexture" 125 "getattach", "getattachnames", "getaddattachnames", "getremattachnames", "getoutfit", "getoutfitnames",
126 "getaddoutfitnames", "getremoutfitnames", "findfolder", "findfolders", "getpath", "getinv", "getinvworn", "getsitid",
127 "getstatus", "getstatusall"
114 }; 128 };
115 129
116 for (int idxBvhr = 0; idxBvhr < RLV_BHVR_COUNT; idxBvhr++) 130 for (int idxBvhr = 0; idxBvhr < RLV_BHVR_COUNT; idxBvhr++)
@@ -133,9 +147,7 @@ RlvObject::RlvObject(const LLUUID& idObj) : m_UUID(idObj), m_nLookupMisses(0)
133 147
134bool RlvObject::addCommand(const RlvCommand& rlvCmd) 148bool RlvObject::addCommand(const RlvCommand& rlvCmd)
135{ 149{
136 // Sanity checking 150 RLV_ASSERT(RLV_TYPE_ADD == rlvCmd.getParamType());
137 if (RLV_TYPE_ADD != rlvCmd.getParamType())
138 return false;
139 151
140 // Don't add duplicate commands for this object (ie @detach=n followed by another @detach=n later on) 152 // Don't add duplicate commands for this object (ie @detach=n followed by another @detach=n later on)
141 for (rlv_command_list_t::iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) 153 for (rlv_command_list_t::iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd)
@@ -155,9 +167,7 @@ bool RlvObject::addCommand(const RlvCommand& rlvCmd)
155 167
156bool RlvObject::removeCommand(const RlvCommand& rlvCmd) 168bool RlvObject::removeCommand(const RlvCommand& rlvCmd)
157{ 169{
158 // Sanity checking 170 RLV_ASSERT(RLV_TYPE_REMOVE == rlvCmd.getParamType());
159 if (RLV_TYPE_REMOVE != rlvCmd.getParamType())
160 return false;
161 171
162 for (rlv_command_list_t::iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) 172 for (rlv_command_list_t::iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd)
163 { 173 {
@@ -188,7 +198,7 @@ bool RlvObject::hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOpt
188 return false; 198 return false;
189} 199}
190 200
191// Checked: 2009-06-07 (RLVa-0.2.1c) 201// Checked: 2009-11-27 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
192std::string RlvObject::getStatusString(const std::string& strMatch) const 202std::string RlvObject::getStatusString(const std::string& strMatch) const
193{ 203{
194 std::string strStatus, strCmd; 204 std::string strStatus, strCmd;
@@ -198,8 +208,7 @@ std::string RlvObject::getStatusString(const std::string& strMatch) const
198 strCmd = itCmd->asString(); 208 strCmd = itCmd->asString();
199 if ( (strMatch.empty()) || (std::string::npos != strCmd.find(strMatch)) ) 209 if ( (strMatch.empty()) || (std::string::npos != strCmd.find(strMatch)) )
200 { 210 {
201 if (!strStatus.empty()) 211 strStatus.push_back('/');
202 strStatus.push_back('/');
203 strStatus += strCmd; 212 strStatus += strCmd;
204 } 213 }
205 } 214 }
@@ -212,7 +221,7 @@ std::string RlvObject::getStatusString(const std::string& strMatch) const
212// 221//
213 222
214// Checked: 2009-10-12 (RLVa-1.0.5b) | Modified: RLVa-1.0.5b 223// Checked: 2009-10-12 (RLVa-1.0.5b) | Modified: RLVa-1.0.5b
215void RlvAttachmentManager::forceAttach(const LLUUID& idItem, S32 idxAttachPt) 224void RlvAttachmentManager::attach(const LLUUID& idItem, S32 idxAttachPt)
216{ 225{
217 #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 226 #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11
218 LLAttachmentRezAction* rez_action = new LLAttachmentRezAction(); 227 LLAttachmentRezAction* rez_action = new LLAttachmentRezAction();
@@ -224,18 +233,15 @@ void RlvAttachmentManager::forceAttach(const LLUUID& idItem, S32 idxAttachPt)
224 LLSD payload; 233 LLSD payload;
225 payload["item_id"] = idItem; 234 payload["item_id"] = idItem;
226 payload["attachment_point"] = idxAttachPt; 235 payload["attachment_point"] = idxAttachPt;
227 236 LLNotifications::instance().forceResponse(LLNotification::Params("ReplaceAttachment").payload(payload), 0/*YES*/);
228 LLNotifications::instance().forceResponse(
229 LLNotification::Params("ReplaceAttachment").payload(payload), 0/*YES*/);
230 #endif 237 #endif
231} 238}
232 239
233// Checked: 2009-10-12 (RLVa-1.0.5b) | Modified: RLVa-1.0.5b 240// Checked: 2009-11-24 (RLVa-1.1.0k) | Added: RLVa-1.1.0e
234void RlvAttachmentManager::forceDetach(LLViewerJointAttachment* pAttachPt) 241void RlvAttachmentManager::detach(LLViewerJointAttachment* pAttachPt)
235{ 242{
236 // Copy/paste from handle_detach_from_avatar() 243 // [See handle_detach_from_avatar()]
237 LLViewerObject* attached_object = pAttachPt->getObject(); 244 if ( (pAttachPt) && (pAttachPt->getObject()) )
238 if (attached_object)
239 { 245 {
240 gMessageSystem->newMessage("ObjectDetach"); 246 gMessageSystem->newMessage("ObjectDetach");
241 gMessageSystem->nextBlockFast(_PREHASH_AgentData); 247 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
@@ -243,7 +249,7 @@ void RlvAttachmentManager::forceDetach(LLViewerJointAttachment* pAttachPt)
243 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 249 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
244 250
245 gMessageSystem->nextBlockFast(_PREHASH_ObjectData); 251 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
246 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, attached_object->getLocalID()); 252 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, pAttachPt->getObject()->getLocalID());
247 gMessageSystem->sendReliable( gAgent.getRegionHost() ); 253 gMessageSystem->sendReliable( gAgent.getRegionHost() );
248 } 254 }
249} 255}
@@ -278,7 +284,7 @@ void RlvAttachmentManager::onAttach(LLViewerJointAttachment* pAttachPt)
278 // If it was empty we need to force detach the new attachment; if it wasn't we need to reattach the old one 284 // If it was empty we need to force detach the new attachment; if it wasn't we need to reattach the old one
279 if (itAttachPrev->second.isNull()) 285 if (itAttachPrev->second.isNull())
280 { 286 {
281 forceDetach(pAttachPt); 287 detach(pAttachPt);
282 m_PendingDetach.insert(std::pair<S32, LLUUID>(idxAttachPt, pAttachPt->getItemID())); 288 m_PendingDetach.insert(std::pair<S32, LLUUID>(idxAttachPt, pAttachPt->getItemID()));
283 } 289 }
284 else if (m_PendingAttach.find(idxAttachPt) == m_PendingAttach.end()) // (only if we're not reattaching something else there) 290 else if (m_PendingAttach.find(idxAttachPt) == m_PendingAttach.end()) // (only if we're not reattaching something else there)
@@ -321,7 +327,7 @@ void RlvAttachmentManager::onSavedAssetIntoInventory(const LLUUID& idItem)
321 { 327 {
322 if ( (!itAttach->second.fAssetSaved) && (idItem == itAttach->second.idItem) ) 328 if ( (!itAttach->second.fAssetSaved) && (idItem == itAttach->second.idItem) )
323 { 329 {
324 forceAttach(itAttach->second.idItem, itAttach->first); 330 attach(itAttach->second.idItem, itAttach->first);
325 itAttach->second.tsAttach = LLFrameTimer::getElapsedSeconds(); 331 itAttach->second.tsAttach = LLFrameTimer::getElapsedSeconds();
326 } 332 }
327 } 333 }
@@ -368,7 +374,7 @@ BOOL RlvAttachmentManager::onTimer()
368 374
369 if (fAttach) 375 if (fAttach)
370 { 376 {
371 forceAttach(itAttach->second.idItem, itAttach->first); 377 attach(itAttach->second.idItem, itAttach->first);
372 itAttach->second.tsAttach = tsCurrent; 378 itAttach->second.tsAttach = tsCurrent;
373 } 379 }
374 380
@@ -421,7 +427,7 @@ const LLUUID& RlvWearableItemCollector::getFoldedParent(const LLUUID& idFolder)
421 return (m_Folding.end() == itFolder) ? idFolder : itFolder->second; 427 return (m_Folding.end() == itFolder) ? idFolder : itFolder->second;
422} 428}
423 429
424// Checked: 2009-07-29 (RLVa-1.0.1b) | Modified: RLVa-1.0.1b 430// Checked: 2009-12-18 (RLVa-1.1.0k) | Modified: RLVa-1.1.0i
425bool RlvWearableItemCollector::onCollectFolder(const LLInventoryCategory* pFolder) 431bool RlvWearableItemCollector::onCollectFolder(const LLInventoryCategory* pFolder)
426{ 432{
427 const LLUUID& idParent = pFolder->getParentUUID(); 433 const LLUUID& idParent = pFolder->getParentUUID();
@@ -437,25 +443,35 @@ bool RlvWearableItemCollector::onCollectFolder(const LLInventoryCategory* pFolde
437 return false; 443 return false;
438 #endif // RLV_EXTENSION_FLAG_NOSTRIP 444 #endif // RLV_EXTENSION_FLAG_NOSTRIP
439 445
440 if (gRlvHandler.isFoldedFolder(pFolder, m_fAttach)) // Check for folder that should get folded under its parent 446 if (gRlvHandler.isFoldedFolder(pFolder, m_fAttach, false)) // Check for folder that should get folded under its parent
441 { 447 {
442 m_Tentative.push_front(pFolder->getUUID()); 448 m_Tentative.push_front(pFolder->getUUID());
443 m_Folding.insert(std::pair<LLUUID, LLUUID>(pFolder->getUUID(), idParent)); 449 m_Folding.insert(std::pair<LLUUID, LLUUID>(pFolder->getUUID(), idParent));
444 } 450 }
445 else if ( (RLV_FOLDER_PREFIX_HIDDEN != strFolder[0]) && (m_fMatchAll) ) // Collect from any non-hidden child folder for *all 451 else if ( (RLV_FOLDER_PREFIX_HIDDEN != strFolder[0]) && (m_fMatchAll) ) // Collect from any non-hidden child folder for *all
446 { 452 {
447 m_Wearable.push_front(pFolder->getUUID()); 453 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
454 if ( (!RlvSettings::getEnableComposites()) || // ... if we're not checking composite folders
455 (!gRlvHandler.isCompositeFolder(pFolder)) || // ... or if it's not a composite folder
456 ((m_fAttach) && (gRlvHandler.canWearComposite(pFolder))) || // ... or if we're attaching and can attach it OR
457 (!m_fAttach) && (gRlvHandler.canTakeOffComposite(pFolder)) ) // ... or if we're detaching and can detach it
458 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
459 {
460 m_Wearable.push_front(pFolder->getUUID());
461 }
448 return (idParent == m_idFolder); // (Convenience for @getinvworn) 462 return (idParent == m_idFolder); // (Convenience for @getinvworn)
449 } 463 }
450 #ifdef RLV_EXPERIMENTAL_COMPOSITES 464 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
451 else if ( (RLV_FOLDER_PREFIX_HIDDEN == strFolder[0]) && // Hidden folder that's a... 465 else if ( (RlvSettings::getEnableComposites()) &&
466 (RLV_FOLDER_PREFIX_HIDDEN == strFolder[0]) && // Hidden folder that's a...
452 (gRlvHandler.isCompositeFolder(pFolder)) && // ... composite folder which we... 467 (gRlvHandler.isCompositeFolder(pFolder)) && // ... composite folder which we...
453 ((m_fAttach) || (gRlvHandler.canTakeOffComposite(pFolder))) ) // ... attach or can detach (see composite locking) 468 ( ((m_fAttach) && (gRlvHandler.canWearComposite(pFolder))) || // ... are attaching and can attach OR
469 (!m_fAttach) && (gRlvHandler.canTakeOffComposite(pFolder)) ) ) // ... are detaching and can detach
454 { 470 {
455 m_Wearable.push_front(pFolder->getUUID()); 471 m_Wearable.push_front(pFolder->getUUID());
456 m_Folding.insert(std::pair<LLUUID, LLUUID>(pFolder->getUUID(), idParent)); 472 m_Folding.insert(std::pair<LLUUID, LLUUID>(pFolder->getUUID(), idParent));
457 } 473 }
458 #endif // RLV_EXPERIMENTAL_COMPOSITES 474 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
459 475
460 return false; 476 return false;
461} 477}
@@ -486,13 +502,13 @@ bool RlvWearableItemCollector::onCollectItem(const LLInventoryItem* pItem)
486 case LLAssetType::AT_OBJECT: 502 case LLAssetType::AT_OBJECT:
487 fRet = ( (m_Wearable.end() != std::find(m_Wearable.begin(), m_Wearable.end(), idParent)) || 503 fRet = ( (m_Wearable.end() != std::find(m_Wearable.begin(), m_Wearable.end(), idParent)) ||
488 (m_Tentative.end() != std::find(m_Tentative.begin(), m_Tentative.end(), idParent)) ) && 504 (m_Tentative.end() != std::find(m_Tentative.begin(), m_Tentative.end(), idParent)) ) &&
489 ( (!m_fAttach) || (gRlvHandler.hasAttachPointName(pItem, true)) ); // Only care about attach point on attach* 505 ( (!m_fAttach) || (gRlvHandler.hasAttachPointName(pItem, true)) || (RlvSettings::getEnableSharedWear()) );
490 break; 506 break;
491 #ifdef RLV_EXPERIMENTAL_FORCEWEAR_GESTURES 507 #ifdef RLV_EXTENSION_FORCEWEAR_GESTURES
492 case LLAssetType::AT_GESTURE: 508 case LLAssetType::AT_GESTURE:
493 fRet = (m_Wearable.end() != std::find(m_Wearable.begin(), m_Wearable.end(), idParent)); 509 fRet = (m_Wearable.end() != std::find(m_Wearable.begin(), m_Wearable.end(), idParent));
494 break; 510 break;
495 #endif // RLV_EXPERIMENTAL_FORCEWEAR_GESTURES 511 #endif // RLV_EXTENSION_FORCEWEAR_GESTURES
496 default: 512 default:
497 break; 513 break;
498 } 514 }
@@ -507,6 +523,431 @@ bool RlvWearableItemCollector::operator()(LLInventoryCategory* pFolder, LLInvent
507} 523}
508 524
509// ============================================================================ 525// ============================================================================
526// RlvForceWear
527//
528
529// Checked: 2010-02-17 (RLVa-1.1.0o) | Modified: RLVa-1.1.0o
530void RlvForceWear::forceFolder(const LLViewerInventoryCategory* pFolder, eWearAction eAction, eWearFlags eFlags)
531{
532 // [See LLWearableBridge::wearOnAvatar(): don't wear anything until initial wearables are loaded, can destroy clothing items]
533 if (!gAgent.areWearablesLoaded())
534 {
535 LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded");
536 return;
537 }
538 // Sanity check - getAvatarObject() can't be NULL [see RlvForceWear::isWearingItem()]
539 LLVOAvatar* pAvatar = gAgent.getAvatarObject();
540 if (!pAvatar)
541 return;
542
543 LLInventoryModel::cat_array_t folders;
544 LLInventoryModel::item_array_t items;
545 RlvWearableItemCollector functor(pFolder->getUUID(), (ACTION_ATTACH == eAction), (FLAG_MATCHALL & eFlags));
546
547 // Grab a list of all the items we'll be wearing/attaching
548 gInventory.collectDescendentsIf(pFolder->getUUID(), folders, items, FALSE, functor);
549
550 for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++)
551 {
552 LLViewerInventoryItem* pItem = items.get(idxItem);
553
554 // If it's wearable it should be worn on detach
555 if ( (ACTION_DETACH == eAction) && (isWearableItem(pItem)) && (!isWearingItem(pItem)) )
556 continue;
557
558 // NOTES: * if there are composite items then RlvWearableItemCollector made sure they can be worn (or taken off depending)
559 // * some scripts issue @remattach=force,attach:worn-items=force so we need to attach items even if they're currently worn
560 switch (pItem->getType())
561 {
562 case LLAssetType::AT_BODYPART:
563 RLV_ASSERT(ACTION_ATTACH == eAction); // RlvWearableItemCollector shouldn't be supplying us with body parts on detach
564 case LLAssetType::AT_CLOTHING:
565 if (ACTION_ATTACH == eAction)
566 {
567 // The check for whether we're replacing a currently worn composite item happens in onWearableArrived()
568 if (std::find(m_addWearables.begin(), m_addWearables.end(), pItem) == m_addWearables.end())
569 m_addWearables.push_back(pItem);
570 }
571 else
572 {
573 LLWearable* pWearable = gAgent.getWearableFromWearableItem(pItem->getUUID());
574 if ( (pWearable) && (isForceRemovable(pWearable->getType(), false)) )
575 {
576 if (std::find(m_remWearables.begin(), m_remWearables.end(), pWearable->getType()) == m_remWearables.end())
577 m_remWearables.push_back(pWearable->getType());
578 }
579 }
580 break;
581
582 case LLAssetType::AT_OBJECT:
583 if (ACTION_ATTACH == eAction)
584 {
585 LLViewerJointAttachment* pAttachPt = gRlvHandler.getAttachPoint(pItem, true);
586 if ( ( (pAttachPt) && // Need a specific attach pt that
587 (!gRlvHandler.isLockedAttachment(pAttachPt->getObject(), RLV_LOCK_REMOVE)) && // doesn't have a locked object
588 (!gRlvHandler.isLockedAttachment(pAttachPt, RLV_LOCK_ADD)) ) || // and that can be attached to
589 (RlvSettings::getEnableSharedWear()) )
590 {
591 if (std::find(m_addAttachments.begin(), m_addAttachments.end(), pItem) == m_addAttachments.end())
592 {
593 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
594 // We still need to check whether we're about to replace a currently worn composite item
595 // (which we're not if we're just reattaching an attachment we're already wearing)
596 LLViewerInventoryCategory* pCompositeFolder = NULL;
597 if ( (pAttachPt->getObject()) && (RlvSettings::getEnableComposites()) &&
598 (pAttachPt->getItemID() != pItem->getUUID()) &&
599 (gRlvHandler.getCompositeInfo(pAttachPt->getItemID(), NULL, &pCompositeFolder)) )
600 {
601 // If we can't take off the composite folder this item would replace then don't allow it to get attached
602 if (gRlvHandler.canTakeOffComposite(pCompositeFolder))
603 {
604 forceFolder(pCompositeFolder, ACTION_DETACH, FLAG_DEFAULT);
605 m_addAttachments.push_back(pItem);
606 }
607 }
608 else
609 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
610 {
611 m_addAttachments.push_back(pItem);
612 }
613 }
614 }
615 }
616 else
617 {
618 LLViewerJointAttachment* pAttachPt = pAvatar->getWornAttachmentPoint(pItem->getUUID());
619 if ( (pAttachPt) && (isForceDetachable(pAttachPt, false)) )
620 {
621 if (std::find(m_remAttachments.begin(), m_remAttachments.end(), pAttachPt) == m_remAttachments.end())
622 m_remAttachments.push_back(pAttachPt);
623 }
624 }
625 break;
626
627 #ifdef RLV_EXTENSION_FORCEWEAR_GESTURES
628 case LLAssetType::AT_GESTURE:
629 if (ACTION_ATTACH == eAction)
630 {
631 if (std::find(m_addGestures.begin(), m_addGestures.end(), pItem) == m_addGestures.end())
632 m_addGestures.push_back(pItem);
633 }
634 else
635 {
636 if (std::find(m_remGestures.begin(), m_remGestures.end(), pItem) == m_remGestures.end())
637 m_remGestures.push_back(pItem);
638 }
639 break;
640 #endif // RLV_EXTENSION_FORCEWEAR_GESTURES
641
642 default:
643 break;
644 }
645 }
646}
647
648// Checked: 2009-12-18 (RLVa-1.1.0k) | Added: RLVa-1.1.0i
649bool RlvForceWear::isForceDetachable(LLViewerJointAttachment* pAttachPt, bool fCheckComposite /*=true*/, LLViewerObject* pExceptObj /*=NULL*/)
650{
651 // Attachment point can be detached by an RLV command if:
652 // - something is worn on the attachment point
653 // - what's worn isn't "remove locked" by anything (or anything except the object specified by pExceptObj)
654 // - what's worn is strippable
655 // - composite folders are disabled *or* what's worn isn't part of a composite folder that has at least one item locked
656 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
657 LLViewerInventoryCategory* pFolder = NULL;
658 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
659 return
660 (
661 (pAttachPt) && (pAttachPt->getObject()) &&
662 ( (!pExceptObj) ? (!gRlvHandler.isLockedAttachment(pAttachPt->getObject(), RLV_LOCK_REMOVE))
663 : (!gRlvHandler.isLockedAttachmentExcept(pAttachPt->getObject(), RLV_LOCK_REMOVE, pExceptObj)) )
664 #ifdef RLV_EXTENSION_FLAG_NOSTRIP
665 && (gRlvHandler.isStrippable(pAttachPt->getItemID()))
666 #endif // RLV_EXTENSION_FLAG_NOSTRIP
667 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
668 && ( (!fCheckComposite) || (!RlvSettings::getEnableComposites()) ||
669 (!gRlvHandler.getCompositeInfo(pAttachPt->getItemID(), NULL, &pFolder)) || (gRlvHandler.canTakeOffComposite(pFolder)) )
670 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
671 );
672}
673
674// Checked: 2009-12-18 (RLVa-1.1.0k) | Added: RLVa-1.1.0i
675void RlvForceWear::forceDetach(LLViewerJointAttachment* pAttachPt)
676{
677 // Sanity check - no need to process duplicate removes
678 if ( (!pAttachPt) || (std::find(m_remAttachments.begin(), m_remAttachments.end(), pAttachPt) != m_remAttachments.end()) )
679 return;
680
681 if (isForceDetachable(pAttachPt))
682 {
683 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
684 LLViewerInventoryCategory* pFolder = NULL;
685 if ( (RlvSettings::getEnableComposites()) &&
686 (gRlvHandler.getCompositeInfo(pAttachPt->getItemID(), NULL, &pFolder)) )
687 {
688 // Attachment belongs to a composite folder so detach the entire folder (if we can take it off)
689 if (gRlvHandler.canTakeOffComposite(pFolder))
690 forceFolder(pFolder, ACTION_DETACH, FLAG_DEFAULT);
691 }
692 else
693 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
694 {
695 m_remAttachments.push_back(pAttachPt);
696 }
697 }
698}
699
700// Checked: 2009-12-18 (RLVa-1.1.0k) | Added: RLVa-1.1.0i
701bool RlvForceWear::isForceRemovable(EWearableType wtType, bool fCheckComposite /*=true*/, const LLUUID& idExcept /*=LLUUID::null*/)
702{
703 // Wearable type can be removed by an RLV command if:
704 // - something is worn on that layer
705 // - its asset type is AT_CLOTHING
706 // - what's worn isn't "remove locked" by anything (or anything except the object specified by idExcept)
707 // - what's worn is strippable
708 // - composite folders are disabled *or* what's worn isn't part of a composite folder that has at least one item locked
709 LLWearable* pWearable = gAgent.getWearable(wtType);
710 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
711 LLViewerInventoryCategory* pFolder = NULL;
712 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
713 return
714 (
715 (pWearable) &&
716 (LLAssetType::AT_CLOTHING == LLWearable::typeToAssetType(wtType)) &&
717 ( (idExcept.notNull()) ? (gRlvHandler.isRemovable(wtType))
718 : (gRlvHandler.isRemovableExcept(wtType, idExcept)) )
719 #ifdef RLV_EXTENSION_FLAG_NOSTRIP
720 && (gRlvHandler.isStrippable(gAgent.getWearableItem(wtType)))
721 #endif // RLV_EXTENSION_FLAG_NOSTRIP
722 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
723 && ( (!fCheckComposite) || (!RlvSettings::getEnableComposites()) ||
724 (!gRlvHandler.getCompositeInfo(gAgent.getWearableItem(wtType), NULL, &pFolder)) || (gRlvHandler.canTakeOffComposite(pFolder)) )
725 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
726 );
727}
728
729// Checked: 2009-12-18 (RLVa-1.1.0k) | Added: RLVa-1.1.0i
730void RlvForceWear::forceRemove(EWearableType wtType)
731{
732 // Sanity check - no need to process duplicate removes
733 if ( (WT_INVALID == wtType) || (std::find(m_remWearables.begin(), m_remWearables.end(), wtType) != m_remWearables.end()) )
734 return;
735
736 if (isForceRemovable(wtType))
737 {
738 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
739 LLViewerInventoryCategory* pFolder = NULL;
740 if ( (RlvSettings::getEnableComposites()) &&
741 (gRlvHandler.getCompositeInfo(gAgent.getWearableItem(wtType), NULL, &pFolder)) )
742 {
743 // Wearable belongs to a composite folder so detach the entire folder (if we can take it off)
744 if (gRlvHandler.canTakeOffComposite(pFolder))
745 forceFolder(pFolder, ACTION_DETACH, FLAG_DEFAULT);
746 }
747 else
748 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
749 {
750 m_remWearables.push_back(wtType);
751 }
752 }
753}
754
755// Checked: 2009-12-18 (RLVa-1.1.0k) | Added: RLVa-1.1.0i
756void RlvForceWear::processAdd()
757{
758 // Process attachments
759 if (m_addAttachments.size())
760 {
761 // Workaround for RezMultipleAttachmentsFromInv bug (see http://jira.secondlife.com/browse/SVC-5383)
762 #ifndef RLV_WORKAROUND_REZMULTIPLEATTACH
763 wear_attachments_on_avatar(m_addAttachments, FALSE);
764 #else
765 for (S32 idxItem = 0, cntItem = m_addAttachments.count(); idxItem < cntItem; idxItem++)
766 {
767 LLViewerInventoryItem* pItem = m_addAttachments.get(idxItem);
768
769 S32 idxAttachPt = gRlvHandler.getAttachPointIndex(pItem, true);
770 if (0 != idxAttachPt)
771 {
772 #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11
773 LLAttachmentRezAction* rez_action = new LLAttachmentRezAction();
774 rez_action->mItemID = pItem->getUUID();
775 rez_action->mAttachPt = idxAttachPt;
776
777 confirm_replace_attachment_rez(0/*YES*/, (void*)rez_action); // (Will call delete on rez_action)
778 #else // Version: 1.23.4
779 LLSD payload;
780 payload["item_id"] = pItem->getUUID();
781 payload["attachment_point"] = idxAttachPt;
782
783 LLNotifications::instance().forceResponse(LLNotification::Params("ReplaceAttachment").payload(payload), 0/*YES*/);
784 #endif
785 }
786 }
787 #endif // RLV_WORKAROUND_REZMULTIPLEATTACH
788
789 m_addAttachments.clear();
790 }
791
792 // Process wearables
793 if (m_addWearables.size())
794 {
795 // [See wear_inventory_category_on_avatar_step2()]
796 LLWearableHoldingPattern* pWearData = new LLWearableHoldingPattern(TRUE);
797
798 // We need to populate 'pWearData->mFoundList' before doing anything else because (some of) the assets might already be available
799 for (S32 idxItem = 0, cntItem = m_addWearables.count(); idxItem < cntItem; idxItem++)
800 {
801 LLViewerInventoryItem* pItem = m_addWearables.get(idxItem);
802 if ( (pItem) && ((LLAssetType::AT_BODYPART == pItem->getType()) || (LLAssetType::AT_CLOTHING == pItem->getType())) )
803 {
804 LLFoundData* pFound = new LLFoundData(pItem->getUUID(), pItem->getAssetUUID(), pItem->getName(), pItem->getType());
805 pWearData->mFoundList.push_front(pFound);
806 }
807 }
808
809 if (!pWearData->mFoundList.size())
810 {
811 delete pWearData;
812 return;
813 }
814
815 // If all the assets are available locally then "pWearData" will be freed *before* the last "gWearableList.getAsset()" call returns
816 bool fContinue = true; LLWearableHoldingPattern::found_list_t::const_iterator itWearable = pWearData->mFoundList.begin();
817 while ( (fContinue) && (itWearable != pWearData->mFoundList.end()) )
818 {
819 const LLFoundData* pFound = *itWearable;
820 ++itWearable;
821 fContinue = (itWearable != pWearData->mFoundList.end());
822 gWearableList.getAsset(pFound->mAssetID, pFound->mName, pFound->mAssetType, onWearableArrived, (void*)pWearData);
823 }
824
825 m_addWearables.clear();
826 }
827
828 // Process gestures
829 if (m_addGestures.size())
830 {
831 gGestureManager.activateGestures(m_addGestures);
832 for (S32 idxGesture = 0, cntGesture = m_addGestures.count(); idxGesture < cntGesture; idxGesture++)
833 gInventory.updateItem(m_addGestures.get(idxGesture));
834 gInventory.notifyObservers();
835
836 m_addGestures.clear();
837 }
838}
839
840// Checked: 2009-12-18 (RLVa-1.1.0k) | Added: RLVa-1.1.0i
841void RlvForceWear::processRem()
842{
843 // Process attachments
844 if (m_remAttachments.size())
845 {
846 // [See LLAgent::userRemoveAllAttachments()]
847 gMessageSystem->newMessage("ObjectDetach");
848 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
849 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
850 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
851
852 for (std::list<LLViewerJointAttachment*>::const_iterator itAttachPt = m_remAttachments.begin();
853 itAttachPt != m_remAttachments.end(); ++itAttachPt)
854 {
855 LLViewerJointAttachment* pAttachPt = *itAttachPt;
856 if (pAttachPt->getObject())
857 {
858 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
859 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, pAttachPt->getObject()->getLocalID());
860 }
861 }
862
863 gMessageSystem->sendReliable(gAgent.getRegionHost());
864
865 m_remAttachments.clear();
866 }
867
868 // Process wearables
869 if (m_remWearables.size())
870 {
871 for (std::list<EWearableType>::const_iterator itWearable = m_remWearables.begin(); itWearable != m_remWearables.end(); ++itWearable)
872 gAgent.removeWearable(*itWearable);
873
874 m_remWearables.clear();
875 }
876
877 // Process gestures
878 if (m_remGestures.size())
879 {
880 for (S32 idxGesture = 0, cntGesture = m_remGestures.count(); idxGesture < cntGesture; idxGesture++)
881 {
882 LLViewerInventoryItem* pItem = m_remGestures.get(idxGesture);
883 gGestureManager.deactivateGesture(pItem->getUUID());
884 gInventory.updateItem(pItem);
885 gInventory.notifyObservers();
886 }
887
888 m_remGestures.clear();
889 }
890}
891
892// Checked: 2010-02-17 (RLVa-1.1.0o) | Modified: RLVa-1.1.0o
893void RlvForceWear::onWearableArrived(LLWearable* pWearable, void* pParam)
894{
895 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
896 // If this wearable will end up replacing a currently worn one that belongs to a composite folder then we need to detach the composite
897 LLViewerInventoryCategory* pFolder = NULL;
898 if ( (RlvSettings::getEnableComposites()) && (pWearable) && (gAgent.getWearable(pWearable->getType())) )
899 {
900 // If we're just rewearing the same item we're already wearing then we're not replacing a composite folder
901 LLWearableHoldingPattern* pWearData = (LLWearableHoldingPattern*)pParam; LLUUID idItem;
902 for (LLWearableHoldingPattern::found_list_t::const_iterator itWearable = pWearData->mFoundList.begin();
903 itWearable != pWearData->mFoundList.end(); ++itWearable)
904 {
905 LLFoundData* pFound = *itWearable;
906 if (pWearable->getID() == pFound->mAssetID)
907 {
908 idItem = pFound->mItemID;
909 break;
910 }
911 }
912 if ( (idItem.notNull()) && (idItem != gAgent.getWearableItem(pWearable->getType())) &&
913 (gRlvHandler.getCompositeInfo(gAgent.getWearableItem(pWearable->getType()), NULL, &pFolder)) )
914 {
915 RlvForceWear rlvWear;
916 rlvWear.forceFolder(pFolder, ACTION_DETACH, FLAG_DEFAULT);
917 rlvWear.done();
918 }
919 }
920 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
921
922 wear_inventory_category_on_avatar_loop(pWearable, pParam);
923}
924
925// ============================================================================
926// RlvBehaviourNotifyObserver
927//
928
929void RlvBehaviourNotifyObserver::changed(const RlvCommand& rlvCmd, bool fInternal)
930{
931 if (fInternal)
932 return;
933
934 std::string strCmd = rlvCmd.asString(), strNotify; ERlvParamType eCmdType = rlvCmd.getParamType();
935 if ( (RLV_TYPE_ADD == eCmdType) || (RLV_TYPE_REMOVE == eCmdType) )
936 strNotify = llformat("/%s=%s", strCmd.c_str(), rlvCmd.getParam().c_str());
937 else if (RLV_TYPE_CLEAR == eCmdType)
938 strNotify = llformat("/%s", strCmd.c_str());
939 else
940 return;
941
942 for (std::multimap<LLUUID, notifyData>::const_iterator itNotify = m_Notifications.begin();
943 itNotify != m_Notifications.end(); ++itNotify)
944 {
945 if ( (itNotify->second.strFilter.empty()) || (std::string::npos != strCmd.find(itNotify->second.strFilter)) )
946 rlvSendChatReply(itNotify->second.nChannel, strNotify);
947 }
948}
949
950// ============================================================================
510// RlvWLSnapshot 951// RlvWLSnapshot
511// 952//
512 953
@@ -546,38 +987,6 @@ RlvWLSnapshot* RlvWLSnapshot::takeSnapshot()
546} 987}
547 988
548// ========================================================================= 989// =========================================================================
549// RlvSettings
550//
551
552BOOL RlvSettings::fShowNameTags = FALSE;
553
554BOOL RlvSettings::getEnableWear()
555{
556 return
557 rlvGetSettingBOOL(RLV_SETTING_ENABLEWEAR, TRUE) && // "Enable Wear" is toggled on and...
558 (!gRlvHandler.hasBehaviour(RLV_BHVR_DEFAULTWEAR)) && // not restricted and...
559 (!gRlvHandler.hasBehaviour(RLV_BHVR_ADDATTACH)); // we have attach points we can attach to [see RlvHandler::onAddRemAttach()]
560}
561
562#ifdef RLV_EXTENSION_STARTLOCATION
563 // Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.1d
564 void RlvSettings::updateLoginLastLocation()
565 {
566 if (gSavedPerAccountSettings.controlExists(RLV_SETTING_LOGINLASTLOCATION))
567 {
568 BOOL fValue = (gRlvHandler.hasBehaviour(RLV_BHVR_TPLOC)) ||
569 ( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) &&
570 (gAgent.getAvatarObject()) && (!gAgent.getAvatarObject()->mIsSitting) );
571 if (gSavedPerAccountSettings.getBOOL(RLV_SETTING_LOGINLASTLOCATION) != fValue)
572 {
573 gSavedPerAccountSettings.setBOOL(RLV_SETTING_LOGINLASTLOCATION, fValue);
574 gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE);
575 }
576 }
577 }
578#endif // RLV_EXTENSION_STARTLOCATION
579
580// =========================================================================
581// Various helper classes/timers/functors 990// Various helper classes/timers/functors
582// 991//
583 992
@@ -618,39 +1027,40 @@ void RlvCurrentlyWorn::fetchWorn()
618 f.fetchItems(idItems); 1027 f.fetchItems(idItems);
619} 1028}
620 1029
621// Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-0.2.0f 1030void RlvGiveToRLVAgentOffer::done()
622bool RlvSelectHasLockedAttach::apply(LLSelectNode* pNode)
623{
624 return (pNode->getObject()) ? gRlvHandler.isLockedAttachment(pNode->getObject(), m_eLock) : false;
625}
626
627// Checked: 2009-07-05 (RLVa-1.0.0b) | Modified: RLVa-0.2.0f
628bool RlvSelectIsOwnedByOrGroupOwned::apply(LLSelectNode* pNode)
629{ 1031{
630 return (pNode->mPermissions->isGroupOwned()) || (pNode->mPermissions->getOwner() == m_idAgent); 1032 LLViewerInventoryCategory* pRlvRoot = gRlvHandler.getSharedRoot();
631} 1033 LLViewerInventoryCategory* pFolder = (mCompleteFolders.size()) ? gInventory.getCategory(mCompleteFolders[0]) : NULL;
1034 if ( (pRlvRoot) && (pFolder) )
1035 {
1036 std::string strName = pFolder->getName();
1037 if (strName.find(RLV_PUTINV_PREFIX) == 0)
1038 {
1039 LLInventoryModel::update_list_t update;
1040 LLInventoryModel::LLCategoryUpdate updOldParent(pFolder->getParentUUID(), -1);
1041 update.push_back(updOldParent);
1042 LLInventoryModel::LLCategoryUpdate updNewParent(pRlvRoot->getUUID(), 1);
1043 update.push_back(updNewParent);
1044 gInventory.accountForUpdate(update);
1045
1046 LLPointer<LLViewerInventoryCategory> pNewFolder = new LLViewerInventoryCategory(pFolder);
1047 pNewFolder->setParent(pRlvRoot->getUUID());
1048 pNewFolder->updateParentOnServer(FALSE);
1049 pNewFolder->rename(strName.erase(0, strName.find(RLV_FOLDER_PREFIX_PUTINV)));
1050 pNewFolder->updateServer(FALSE);
1051 gInventory.updateCategory(pNewFolder);
1052 }
1053 }
632 1054
633// Checked: 2009-05-31 (RLVa-0.2.0f) | Modified: RLVa-0.2.0f 1055 gInventory.removeObserver(this);
634bool RlvSelectIsSittingOn::apply(LLSelectNode* pNode) 1056 gInventory.notifyObservers();
635{ 1057 delete this;
636 return (pNode->getObject()) && (pNode->getObject()->getRootEdit() == m_pObject);
637} 1058}
638 1059
639// ============================================================================ 1060// ============================================================================
640// Various helper functions 1061// Various helper functions
641// 1062//
642 1063
643// Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a
644BOOL rlvAttachToEnabler(void* pParam)
645{
646 // Disable an option on the "Attach to (HUD)" submenu if:
647 // - the attachment point is locked non-detachable with an object attached
648 // - the attachment point is locked non-attachable
649 return (pParam != NULL) &&
650 (!gRlvHandler.isLockedAttachment(((LLViewerJointAttachment*)pParam)->getObject(), RLV_LOCK_REMOVE)) &&
651 (!gRlvHandler.isLockedAttachment((LLViewerJointAttachment*)pParam, RLV_LOCK_ADD));
652}
653
654// Checked: 2009-07-05 (RLVa-1.0.0b) | Modified: RLVa-0.2.0g 1064// Checked: 2009-07-05 (RLVa-1.0.0b) | Modified: RLVa-0.2.0g
655bool rlvCanDeleteOrReturn() 1065bool rlvCanDeleteOrReturn()
656{ 1066{
@@ -677,13 +1087,6 @@ bool rlvCanDeleteOrReturn()
677 return fIsAllowed; 1087 return fIsAllowed;
678} 1088}
679 1089
680// Checked: 2009-10-04 (RLVa-1.0.4b) | Modified: RLVa-1.0.4b
681BOOL rlvEnableWearEnabler(void* pParam)
682{
683 // Visually disables the "Enable Wear" option when restricted from toggling it
684 return (!gRlvHandler.hasBehaviour(RLV_BHVR_DEFAULTWEAR));
685}
686
687// Checked: 2009-05-26 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d 1090// Checked: 2009-05-26 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d
688S32 rlvGetDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType::EType type) 1091S32 rlvGetDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType::EType type)
689{ 1092{
@@ -712,12 +1115,12 @@ S32 rlvGetDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType
712 1115
713 #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 1116 #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11
714 LLStringUtil::format_map_t args; 1117 LLStringUtil::format_map_t args;
715 args["[MESSAGE]"] = llformat("Restrained Life Support will be %s after you restart", 1118 args["[MESSAGE]"] = llformat("RestrainedLove Support will be %s after you restart",
716 (rlv_handler_t::isEnabled()) ? "disabled" : "enabled" ); 1119 (rlv_handler_t::isEnabled()) ? "disabled" : "enabled" );
717 gViewerWindow->alertXml("GenericAlert", args); 1120 gViewerWindow->alertXml("GenericAlert", args);
718 #else // Version: 1.23.4 1121 #else // Version: 1.23.4
719 LLSD args; 1122 LLSD args;
720 args["MESSAGE"] = llformat("Restrained Life Support will be %s after you restart", 1123 args["MESSAGE"] = llformat("RestrainedLove Support will be %s after you restart",
721 (rlv_handler_t::isEnabled()) ? "disabled" : "enabled" ); 1124 (rlv_handler_t::isEnabled()) ? "disabled" : "enabled" );
722 LLNotifications::instance().add("GenericAlert", args); 1125 LLNotifications::instance().add("GenericAlert", args);
723 #endif 1126 #endif
diff --git a/linden/indra/newview/rlvhelper.h b/linden/indra/newview/rlvhelper.h
index 25d8174..1204146 100644
--- a/linden/indra/newview/rlvhelper.h
+++ b/linden/indra/newview/rlvhelper.h
@@ -1,13 +1,15 @@
1#ifndef RLV_HELPER_H 1#ifndef RLV_HELPER_H
2#define RLV_HELPER_H 2#define RLV_HELPER_H
3 3
4#include "llagent.h"
4#include "llboost.h" 5#include "llboost.h"
6#include "llgesturemgr.h"
5#include "llinventorymodel.h" 7#include "llinventorymodel.h"
6#include "llselectmgr.h" 8#include "llviewerinventory.h"
7#include "llviewercontrol.h" 9#include "llvoavatar.h"
8#include "llviewerobjectlist.h"
9#include "llwlparamset.h" 10#include "llwlparamset.h"
10#include "rlvdefines.h" 11#include "rlvdefines.h"
12#include "rlvcommon.h"
11 13
12#ifdef LL_WINDOWS 14#ifdef LL_WINDOWS
13 #pragma warning (push) 15 #pragma warning (push)
@@ -40,7 +42,7 @@ public:
40 bool isStrict() const { return m_fStrict; } 42 bool isStrict() const { return m_fStrict; }
41 bool isValid() const { return m_fValid; } 43 bool isValid() const { return m_fValid; }
42 44
43 static ERlvBehaviour getBehaviourFromString(const std::string& strBhvr); 45 static ERlvBehaviour getBehaviourFromString(const std::string& strBhvr, bool* pfStrict = NULL);
44 static const std::string& getStringFromBehaviour(ERlvBehaviour eBhvr); 46 static const std::string& getStringFromBehaviour(ERlvBehaviour eBhvr);
45 static bool hasStrictVariant(ERlvBehaviour eBhvr); 47 static bool hasStrictVariant(ERlvBehaviour eBhvr);
46 48
@@ -122,8 +124,9 @@ public:
122 * Member functions 124 * Member functions
123 */ 125 */
124public: 126public:
125 static void forceAttach(const LLUUID& idItem, S32 idxAttachPt); 127 // NOTE: the following two do *not* respect attachment locks so use with care
126 static void forceDetach(LLViewerJointAttachment* pAttachPt); 128 static void attach(const LLUUID& idItem, S32 idxAttachPt);
129 static void detach(LLViewerJointAttachment* pAttachPt);
127protected: 130protected:
128 void startTimer() { if (!m_pTimer) m_pTimer = new RlvAttachmentManagerTimer(this); } 131 void startTimer() { if (!m_pTimer) m_pTimer = new RlvAttachmentManagerTimer(this); }
129 132
@@ -212,8 +215,12 @@ public:
212 std::string strFolderName = pFolder->getName(); 215 std::string strFolderName = pFolder->getName();
213 LLStringUtil::toLower(strFolderName); 216 LLStringUtil::toLower(strFolderName);
214 217
215 if ( (strFolderName.empty()) || (RLV_FOLDER_PREFIX_HIDDEN == strFolderName[0]) ) 218 // NOTE: hidden or "give to #RLV" folders can never be a match
219 if ( (strFolderName.empty()) ||
220 (RLV_FOLDER_PREFIX_HIDDEN == strFolderName[0]) || (RLV_FOLDER_PREFIX_PUTINV == strFolderName[0]) )
221 {
216 return false; 222 return false;
223 }
217 224
218 for (std::list<std::string>::const_iterator itCrit = m_Criteria.begin(); itCrit != m_Criteria.end(); ++itCrit) 225 for (std::list<std::string>::const_iterator itCrit = m_Criteria.begin(); itCrit != m_Criteria.end(); ++itCrit)
219 if (std::string::npos == strFolderName.find(*itCrit)) // Return false on the first mismatch 226 if (std::string::npos == strFolderName.find(*itCrit)) // Return false on the first mismatch
@@ -257,17 +264,97 @@ protected:
257}; 264};
258 265
259// ============================================================================ 266// ============================================================================
267// RlvForceWear
268//
269
270class RlvForceWear
271{
272public:
273 // Folders
274 enum eWearAction { ACTION_ATTACH, ACTION_DETACH };
275 enum eWearFlags { FLAG_NONE = 0x00, FLAG_MATCHALL = 0x01, FLAG_DEFAULT = FLAG_NONE };
276 void forceFolder(const LLViewerInventoryCategory* pFolder, eWearAction eAction, eWearFlags eFlags);
277
278 // Attachments
279 static bool isForceDetachable(LLViewerJointAttachment* pAttachPt, bool fCheckComposite = true, LLViewerObject* pExceptObj = NULL);
280 void forceDetach(LLViewerJointAttachment* ptAttachPt);
281
282 // Wearables
283 static bool isForceRemovable(EWearableType wtType, bool fCheckComposite = true, const LLUUID& idExcept = LLUUID::null);
284 void forceRemove(EWearableType wtType);
285
286 // General purpose
287 static bool isWearableItem(const LLInventoryItem* pItem);
288 static bool isWearingItem(const LLInventoryItem* pItem);
289
290public:
291 void done() { processRem(); processAdd(); }
292protected:
293 void processAdd();
294 void processRem();
295 static void onWearableArrived(LLWearable* pWearable, void* pParam);
296
297protected:
298 LLInventoryModel::item_array_t m_addAttachments, m_addWearables, m_addGestures, m_remGestures;
299 std::list<LLViewerJointAttachment*> m_remAttachments;
300 std::list<EWearableType> m_remWearables;
301};
302
303// ============================================================================
304// RlvBehaviourNotifyObserver
305//
306
307class RlvBehaviourNotifyObserver : public RlvBehaviourObserver
308{
309public:
310 virtual ~RlvBehaviourNotifyObserver() { }
311 virtual void changed(const RlvCommand& rlvCmd, bool fInternal);
312
313 void addNotify(const LLUUID& idObj, S32 nChannel, const std::string& strFilter)
314 {
315 m_Notifications.insert(std::pair<LLUUID, notifyData>(idObj, notifyData(nChannel, strFilter)));
316 }
317 void clearNotify(const LLUUID& idObj)
318 {
319 m_Notifications.erase(idObj);
320 }
321 bool hasNotify()
322 {
323 return (m_Notifications.size() != 0);
324 }
325 void removeNotify(const LLUUID& idObj, S32 nChannel, const std::string& strFilter)
326 {
327 for (std::multimap<LLUUID, notifyData>::iterator itNotify = m_Notifications.lower_bound(idObj),
328 endNotify = m_Notifications.upper_bound(idObj); itNotify != endNotify; ++itNotify)
329 {
330 if ( (itNotify->second.nChannel == nChannel) && (itNotify->second.strFilter == strFilter) )
331 {
332 m_Notifications.erase(itNotify);
333 break;
334 }
335 }
336 }
337protected:
338 struct notifyData
339 {
340 S32 nChannel;
341 std::string strFilter;
342 notifyData(S32 channel, const std::string& filter) : nChannel(channel), strFilter(filter) {}
343 };
344 std::multimap<LLUUID, notifyData> m_Notifications;
345};
346
347// ============================================================================
260// RlvRetainedCommand 348// RlvRetainedCommand
261// 349//
262 350
263struct RlvRetainedCommand 351struct RlvRetainedCommand
264{ 352{
265public: 353public:
266 std::string strObject;
267 LLUUID idObject; 354 LLUUID idObject;
268 std::string strCmd; 355 RlvCommand rlvCmd;
269 356
270 RlvRetainedCommand(const std::string obj, const LLUUID& uuid, const std::string& cmd) : strObject(obj), idObject(uuid), strCmd(cmd) {} 357 RlvRetainedCommand(const LLUUID& uuid, const RlvCommand& cmd) : idObject(uuid), rlvCmd(cmd) {}
271private: 358private:
272 RlvRetainedCommand(); 359 RlvRetainedCommand();
273}; 360};
@@ -309,43 +396,6 @@ private:
309}; 396};
310 397
311// ============================================================================ 398// ============================================================================
312// RlvSettings
313//
314
315inline BOOL rlvGetSettingBOOL(const std::string& strSetting, BOOL fDefault)
316{
317 return (gSavedSettings.controlExists(strSetting)) ? gSavedSettings.getBOOL(strSetting) : fDefault;
318}
319inline BOOL rlvGetPerUserSettingsBOOL(const std::string& strSetting, BOOL fDefault)
320{
321 return (gSavedPerAccountSettings.controlExists(strSetting)) ? gSavedPerAccountSettings.getBOOL(strSetting) : fDefault;
322}
323
324class RlvSettings
325{
326public:
327 static BOOL getDebug() { return rlvGetSettingBOOL(RLV_SETTING_DEBUG, FALSE); }
328 static BOOL getForbidGiveToRLV() { return rlvGetSettingBOOL(RLV_SETTING_FORBIDGIVETORLV, TRUE); }
329
330 static BOOL getEnableWear();
331 static BOOL getHideLockedLayers() { return rlvGetSettingBOOL(RLV_SETTING_HIDELOCKEDLAYER, FALSE); }
332 static BOOL getHideLockedAttach() { return rlvGetSettingBOOL(RLV_SETTING_HIDELOCKEDATTACH, FALSE); }
333 static BOOL getHideLockedInventory() { return rlvGetSettingBOOL(RLV_SETTING_HIDELOCKEDINVENTORY, FALSE); }
334 static BOOL getShowNameTags() { return fShowNameTags; }
335
336 #ifdef RLV_EXTENSION_STARTLOCATION
337 static BOOL getLoginLastLocation() { return rlvGetPerUserSettingsBOOL(RLV_SETTING_LOGINLASTLOCATION, TRUE); }
338 static void updateLoginLastLocation();
339 #endif // RLV_EXTENSION_STARTLOCATION
340
341 static BOOL fShowNameTags;
342};
343
344// ============================================================================
345// State keeping classes/structure
346//
347
348// ============================================================================
349// Various helper classes/timers/functors 399// Various helper classes/timers/functors
350// 400//
351 401
@@ -367,39 +417,21 @@ public:
367 void fetchItem(const LLUUID& idItem); 417 void fetchItem(const LLUUID& idItem);
368}; 418};
369 419
370struct RlvSelectHasLockedAttach : public LLSelectedNodeFunctor 420class RlvGiveToRLVAgentOffer : public LLInventoryFetchDescendentsObserver
371{
372 RlvSelectHasLockedAttach(ERlvLockMask eLock) : m_eLock(eLock) {}
373 virtual bool apply(LLSelectNode* pNode);
374protected:
375 ERlvLockMask m_eLock;
376};
377
378struct RlvSelectIsOwnedByOrGroupOwned : public LLSelectedNodeFunctor
379{ 421{
380 RlvSelectIsOwnedByOrGroupOwned(const LLUUID& uuid) : m_idAgent(uuid) {} 422public:
381 virtual bool apply(LLSelectNode* pNode); 423 RlvGiveToRLVAgentOffer() {}
382 LLUUID m_idAgent; 424 virtual void done();
383};
384
385struct RlvSelectIsSittingOn : public LLSelectedNodeFunctor
386{
387 RlvSelectIsSittingOn(LLXform* pObject) : m_pObject(pObject) {}
388 virtual bool apply(LLSelectNode* pNode);
389 LLXform* m_pObject;
390}; 425};
391 426
392// ============================================================================ 427// ============================================================================
393// Various helper functions 428// Various helper functions
394// 429//
395 430
396BOOL rlvAttachToEnabler(void* pParam);
397bool rlvCanDeleteOrReturn(); 431bool rlvCanDeleteOrReturn();
398BOOL rlvEnableWearEnabler(void* pParam);
399S32 rlvGetDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType::EType type); 432S32 rlvGetDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType::EType type);
400bool rlvIsEmote(const std::string& strUTF8Text); 433bool rlvIsEmote(const std::string& strUTF8Text);
401bool rlvIsValidReplyChannel(S32 nChannel); 434bool rlvIsValidReplyChannel(S32 nChannel);
402bool rlvIsWearingItem(const LLInventoryItem* pItem);
403 435
404void rlvSendBusyMessage(const LLUUID& idTo, const std::string& strMsg, const LLUUID& idSession = LLUUID::null); 436void rlvSendBusyMessage(const LLUUID& idTo, const std::string& strMsg, const LLUUID& idSession = LLUUID::null);
405bool rlvSendChatReply(const std::string& strChannel, const std::string& strReply); 437bool rlvSendChatReply(const std::string& strChannel, const std::string& strReply);
@@ -439,16 +471,6 @@ inline bool RlvCommand::operator ==(const RlvCommand& rhs) const
439 ( (RLV_TYPE_UNKNOWN != m_eParamType) ? (m_eParamType == rhs.m_eParamType) : (m_strParam == rhs.m_strParam) ); 471 ( (RLV_TYPE_UNKNOWN != m_eParamType) ? (m_eParamType == rhs.m_eParamType) : (m_strParam == rhs.m_strParam) );
440} 472}
441 473
442inline void RlvCurrentlyWorn::fetchItem(const LLUUID& idItem)
443{
444 if (idItem.notNull())
445 {
446 LLInventoryFetchObserver::item_ref_t idItems;
447 idItems.push_back(idItem);
448 fetchItems(idItems);
449 }
450}
451
452inline bool RlvCommand::hasStrictVariant(ERlvBehaviour eBhvr) 474inline bool RlvCommand::hasStrictVariant(ERlvBehaviour eBhvr)
453{ 475{
454 switch (eBhvr) 476 switch (eBhvr)
@@ -465,6 +487,32 @@ inline bool RlvCommand::hasStrictVariant(ERlvBehaviour eBhvr)
465 } 487 }
466} 488}
467 489
490inline void RlvCurrentlyWorn::fetchItem(const LLUUID& idItem)
491{
492 if (idItem.notNull())
493 {
494 LLInventoryFetchObserver::item_ref_t idItems;
495 idItems.push_back(idItem);
496 fetchItems(idItems);
497 }
498}
499
500// Checked: 2009-12-18 (RLVa-1.1.0k) | Added: RLVa-1.1.0i
501inline bool RlvForceWear::isWearableItem(const LLInventoryItem* pItem)
502{
503 return (LLAssetType::AT_OBJECT == pItem->getType()) || (LLAssetType::AT_GESTURE == pItem->getType()) ||
504 (LLAssetType::AT_BODYPART == pItem->getType()) || (LLAssetType::AT_CLOTHING == pItem->getType());
505}
506
507// Checked: 2009-12-18 (RLVa-1.1.0k) | Modified: RLVa-1.1.0i
508inline bool RlvForceWear::isWearingItem(const LLInventoryItem* pItem)
509{
510 return
511 ((LLAssetType::AT_OBJECT == pItem->getType()) && (gAgent.getAvatarObject()->isWearingAttachment(pItem->getUUID()))) ||
512 ((LLAssetType::AT_GESTURE == pItem->getType()) && (gGestureManager.isGestureActive(pItem->getUUID()))) ||
513 (gAgent.isWearingItem(pItem->getUUID()));
514}
515
468// ============================================================================ 516// ============================================================================
469// Inlined helper functions 517// Inlined helper functions
470// 518//
diff --git a/linden/indra/newview/rlvmultistringsearch.cpp b/linden/indra/newview/rlvmultistringsearch.cpp
index 0aa9889..f8bb1c1 100644
--- a/linden/indra/newview/rlvmultistringsearch.cpp
+++ b/linden/indra/newview/rlvmultistringsearch.cpp
@@ -1,3 +1,19 @@
1/**
2 *
3 * Copyright (c) 2009-2010, Kitty Barnett
4 *
5 * The source code in this file is provided to you under the terms of the
6 * GNU General Public License, version 2.0, but WITHOUT ANY WARRANTY;
7 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
8 * PARTICULAR PURPOSE. Terms of the GPL can be found in doc/GPL-license.txt
9 * in this distribution, or online at http://www.gnu.org/licenses/gpl-2.0.txt
10 *
11 * By copying, modifying or distributing this software, you acknowledge that
12 * you have read and understood your obligations described above, and agree to
13 * abide by those obligations.
14 *
15 */
16
1#include "llviewerprecompiledheaders.h" 17#include "llviewerprecompiledheaders.h"
2 18
3#include "rlvmultistringsearch.h" 19#include "rlvmultistringsearch.h"
diff --git a/linden/indra/newview/rlvmultistringsearch.h b/linden/indra/newview/rlvmultistringsearch.h
index 43b0172..120117d 100644
--- a/linden/indra/newview/rlvmultistringsearch.h
+++ b/linden/indra/newview/rlvmultistringsearch.h
@@ -1,3 +1,19 @@
1/**
2 *
3 * Copyright (c) 2009-2010, Kitty Barnett
4 *
5 * The source code in this file is provided to you under the terms of the
6 * GNU General Public License, version 2.0, but WITHOUT ANY WARRANTY;
7 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
8 * PARTICULAR PURPOSE. Terms of the GPL can be found in doc/GPL-license.txt
9 * in this distribution, or online at http://www.gnu.org/licenses/gpl-2.0.txt
10 *
11 * By copying, modifying or distributing this software, you acknowledge that
12 * you have read and understood your obligations described above, and agree to
13 * abide by those obligations.
14 *
15 */
16
1#ifndef RLV_MULTISTRINGSEARCH_H 17#ifndef RLV_MULTISTRINGSEARCH_H
2#define RLV_MULTISTRINGSEARCH_H 18#define RLV_MULTISTRINGSEARCH_H
3 19
diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml b/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml
index 66d78bd..c85dd47 100644
--- a/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml
+++ b/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml
@@ -1467,8 +1467,8 @@
1467 1467
1468 <menu_item_check name="Show Debug Messages" 1468 <menu_item_check name="Show Debug Messages"
1469 label="Show Debug Messages"> 1469 label="Show Debug Messages">
1470 <on_click function="ToggleControl" userdata="RestrainedLifeDebug" /> 1470 <on_click function="ToggleControl" userdata="RestrainedLoveDebug" />
1471 <on_check control="RestrainedLifeDebug" /> 1471 <on_check control="RestrainedLoveDebug" />
1472 </menu_item_check> 1472 </menu_item_check>
1473 1473
1474 <menu_item_separator /> 1474 <menu_item_separator />
@@ -1515,8 +1515,8 @@
1515 1515
1516 <menu_item_check name="Forbid Give to #RLV" label="Forbid Give to #RLV"> 1516 <menu_item_check name="Forbid Give to #RLV" label="Forbid Give to #RLV">
1517 <on_click function="ToggleControl" 1517 <on_click function="ToggleControl"
1518 userdata="RestrainedLifeForbidGiveToRLV" /> 1518 userdata="RestrainedLoveForbidGiveToRLV" />
1519 <on_check control="RestrainedLifeForbidGiveToRLV" /> 1519 <on_check control="RestrainedLoveForbidGiveToRLV" />
1520 </menu_item_check> 1520 </menu_item_check>
1521 1521
1522 <menu_item_check name="Show Name Tags" label="Show Name Tags"> 1522 <menu_item_check name="Show Name Tags" label="Show Name Tags">