diff options
Diffstat (limited to 'linden')
91 files changed, 10021 insertions, 144 deletions
diff --git a/linden/indra/llcommon/llchat.h b/linden/indra/llcommon/llchat.h index ec86450..6c75a25 100644 --- a/linden/indra/llcommon/llchat.h +++ b/linden/indra/llcommon/llchat.h | |||
@@ -72,6 +72,10 @@ public: | |||
72 | : mText(text), | 72 | : mText(text), |
73 | mFromName(), | 73 | mFromName(), |
74 | mFromID(), | 74 | mFromID(), |
75 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
76 | mRlvLocFiltered(FALSE), | ||
77 | mRlvNamesFiltered(FALSE), | ||
78 | // [/RLVa:KB] | ||
75 | mSourceType(CHAT_SOURCE_AGENT), | 79 | mSourceType(CHAT_SOURCE_AGENT), |
76 | mChatType(CHAT_TYPE_NORMAL), | 80 | mChatType(CHAT_TYPE_NORMAL), |
77 | mAudible(CHAT_AUDIBLE_FULLY), | 81 | mAudible(CHAT_AUDIBLE_FULLY), |
@@ -84,6 +88,10 @@ public: | |||
84 | std::string mText; // UTF-8 line of text | 88 | std::string mText; // UTF-8 line of text |
85 | std::string mFromName; // agent or object name | 89 | std::string mFromName; // agent or object name |
86 | LLUUID mFromID; // agent id or object id | 90 | LLUUID mFromID; // agent id or object id |
91 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
92 | BOOL mRlvLocFiltered; | ||
93 | BOOL mRlvNamesFiltered; | ||
94 | // [/RLVa:KB] | ||
87 | EChatSourceType mSourceType; | 95 | EChatSourceType mSourceType; |
88 | EChatType mChatType; | 96 | EChatType mChatType; |
89 | EChatAudible mAudible; | 97 | EChatAudible mAudible; |
diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index 6f54a41..bb07922 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt | |||
@@ -435,6 +435,12 @@ set(viewer_SOURCE_FILES | |||
435 | llxmlrpctransaction.cpp | 435 | llxmlrpctransaction.cpp |
436 | noise.cpp | 436 | noise.cpp |
437 | pipeline.cpp | 437 | pipeline.cpp |
438 | primbackup.cpp | ||
439 | rlvhandler.cpp | ||
440 | rlvhelper.cpp | ||
441 | rlvmultistringsearch.cpp | ||
442 | rlvextensions.cpp | ||
443 | rlvfloaterbehaviour.cpp | ||
438 | ) | 444 | ) |
439 | 445 | ||
440 | set(VIEWER_BINARY_NAME "imprudence-bin" CACHE STRING | 446 | set(VIEWER_BINARY_NAME "imprudence-bin" CACHE STRING |
@@ -839,9 +845,16 @@ set(viewer_HEADER_FILES | |||
839 | macmain.h | 845 | macmain.h |
840 | noise.h | 846 | noise.h |
841 | pipeline.h | 847 | pipeline.h |
848 | primbackup.h | ||
842 | randgauss.h | 849 | randgauss.h |
843 | VertexCache.h | 850 | VertexCache.h |
844 | VorbisFramework.h | 851 | VorbisFramework.h |
852 | rlvevent.h | ||
853 | rlvhandler.h | ||
854 | rlvhelper.h | ||
855 | rlvmultistringsearch.h | ||
856 | rlvextensions.h | ||
857 | rlvfloaterbehaviour.h | ||
845 | ) | 858 | ) |
846 | 859 | ||
847 | source_group("CMake Rules" FILES ViewerInstall.cmake) | 860 | source_group("CMake Rules" FILES ViewerInstall.cmake) |
diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index 149eefa..6d2f0c5 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml | |||
@@ -1,7 +1,106 @@ | |||
1 | <?xml version="1.0" ?> | 1 | <?xml version="1.0" ?> |
2 | <llsd> | 2 | <llsd> |
3 | <map> | 3 | <map> |
4 | <key>AFKTimeout</key> | 4 | <key>RestrainedLife</key> |
5 | <map> | ||
6 | <key>Comment</key> | ||
7 | <string>Toggles the RestrainedLife features (BDSM lockable toys support). Needs a restart of the viewer.</string> | ||
8 | <key>Persist</key> | ||
9 | <integer>1</integer> | ||
10 | <key>Type</key> | ||
11 | <string>Boolean</string> | ||
12 | <key>Value</key> | ||
13 | <integer>0</integer> | ||
14 | </map> | ||
15 | <key>RestrainedLifeDebug</key> | ||
16 | <map> | ||
17 | <key>Comment</key> | ||
18 | <string>Toggles the RestrainedLife debug mode (displays the commands when in debug mode).</string> | ||
19 | <key>Persist</key> | ||
20 | <integer>1</integer> | ||
21 | <key>Type</key> | ||
22 | <string>Boolean</string> | ||
23 | <key>Value</key> | ||
24 | <integer>0</integer> | ||
25 | </map> | ||
26 | <key>RestrainedLifeNoSetEnv</key> | ||
27 | <map> | ||
28 | <key>Comment</key> | ||
29 | <string>When TRUE, forbids to set the environment (time of day and Windlight settings) via RestrainedLife. Needs a restart of the viewer.</string> | ||
30 | <key>Persist</key> | ||
31 | <integer>1</integer> | ||
32 | <key>Type</key> | ||
33 | <string>Boolean</string> | ||
34 | <key>Value</key> | ||
35 | <integer>0</integer> | ||
36 | </map> | ||
37 | <key>RestrainedLifeForbidGiveToRLV</key> | ||
38 | <map> | ||
39 | <key>Comment</key> | ||
40 | <string>When FALSE, allows to give sub-folders to the #RLV RestrainedLife folder.</string> | ||
41 | <key>Persist</key> | ||
42 | <integer>1</integer> | ||
43 | <key>Type</key> | ||
44 | <string>Boolean</string> | ||
45 | <key>Value</key> | ||
46 | <integer>1</integer> | ||
47 | </map> | ||
48 | <key>RLVaEnableLegacyNaming</key> | ||
49 | <map> | ||
50 | <key>Comment</key> | ||
51 | <string>Enables legacy naming convention for folders</string> | ||
52 | <key>Persist</key> | ||
53 | <integer>1</integer> | ||
54 | <key>Type</key> | ||
55 | <string>Boolean</string> | ||
56 | <key>Value</key> | ||
57 | <integer>1</integer> | ||
58 | </map> | ||
59 | <key>RLVaEnableWear</key> | ||
60 | <map> | ||
61 | <key>Comment</key> | ||
62 | <string>When TRUE, enables the "Wear" option on the inventory item context menu for attachments.</string> | ||
63 | <key>Persist</key> | ||
64 | <integer>1</integer> | ||
65 | <key>Type</key> | ||
66 | <string>Boolean</string> | ||
67 | <key>Value</key> | ||
68 | <integer>0</integer> | ||
69 | </map> | ||
70 | <key>RLVaHideLockedLayers</key> | ||
71 | <map> | ||
72 | <key>Comment</key> | ||
73 | <string>When TRUE, hides worn but "remove outfit" restricted clothing layers from @getoufit</string> | ||
74 | <key>Persist</key> | ||
75 | <integer>1</integer> | ||
76 | <key>Type</key> | ||
77 | <string>Boolean</string> | ||
78 | <key>Value</key> | ||
79 | <integer>0</integer> | ||
80 | </map> | ||
81 | <key>RLVaHideLockedAttachments</key> | ||
82 | <map> | ||
83 | <key>Comment</key> | ||
84 | <string>When TRUE, hides worn but "no detach" restricted attachments from @getattach</string> | ||
85 | <key>Persist</key> | ||
86 | <integer>1</integer> | ||
87 | <key>Type</key> | ||
88 | <string>Boolean</string> | ||
89 | <key>Value</key> | ||
90 | <integer>0</integer> | ||
91 | </map> | ||
92 | <key>RLVaShowNameTags</key> | ||
93 | <map> | ||
94 | <key>Comment</key> | ||
95 | <string>Display of names above avatars is subject to the general "Show Names" setting when @shownames=n restricted</string> | ||
96 | <key>Persist</key> | ||
97 | <integer>1</integer> | ||
98 | <key>Type</key> | ||
99 | <string>Boolean</string> | ||
100 | <key>Value</key> | ||
101 | <integer>0</integer> | ||
102 | </map> | ||
103 | <key>AFKTimeout</key> | ||
5 | <map> | 104 | <map> |
6 | <key>Comment</key> | 105 | <key>Comment</key> |
7 | <string>Time before automatically setting AFK (away from keyboard) mode (seconds)</string> | 106 | <string>Time before automatically setting AFK (away from keyboard) mode (seconds)</string> |
@@ -3177,6 +3276,22 @@ | |||
3177 | <integer>0</integer> | 3276 | <integer>0</integer> |
3178 | </array> | 3277 | </array> |
3179 | </map> | 3278 | </map> |
3279 | <key>FloaterPrimImport</key> | ||
3280 | <map> | ||
3281 | <key>Comment</key> | ||
3282 | <string>Rectangle for import/export</string> | ||
3283 | <key>Persist</key> | ||
3284 | <integer>1</integer> | ||
3285 | <key>Type</key> | ||
3286 | <string>Rect</string> | ||
3287 | <key>Value</key> | ||
3288 | <array> | ||
3289 | <integer>0</integer> | ||
3290 | <integer>25</integer> | ||
3291 | <integer>400</integer> | ||
3292 | <integer>0</integer> | ||
3293 | </array> | ||
3294 | </map> | ||
3180 | <key>FloaterRegionInfo</key> | 3295 | <key>FloaterRegionInfo</key> |
3181 | <map> | 3296 | <map> |
3182 | <key>Comment</key> | 3297 | <key>Comment</key> |
diff --git a/linden/indra/newview/app_settings/settings_per_account.xml b/linden/indra/newview/app_settings/settings_per_account.xml index 90c7b11..59caac4 100644 --- a/linden/indra/newview/app_settings/settings_per_account.xml +++ b/linden/indra/newview/app_settings/settings_per_account.xml | |||
@@ -1,6 +1,17 @@ | |||
1 | <llsd> | 1 | <llsd> |
2 | <map> | 2 | <map> |
3 | <key>BusyModeResponse</key> | 3 | <key>RLVaLoginLastLocation</key> |
4 | <map> | ||
5 | <key>Comment</key> | ||
6 | <string>Determines whether the next login will be forced to the last logoff location (set by the viewer)</string> | ||
7 | <key>Persist</key> | ||
8 | <integer>1</integer> | ||
9 | <key>Type</key> | ||
10 | <string>Boolean</string> | ||
11 | <key>Value</key> | ||
12 | <integer>1</integer> | ||
13 | </map> | ||
14 | <key>BusyModeResponse</key> | ||
4 | <map> | 15 | <map> |
5 | <key>Comment</key> | 16 | <key>Comment</key> |
6 | <string>Auto response to instant messages while in busy mode.</string> | 17 | <string>Auto response to instant messages while in busy mode.</string> |
diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp index 7a70316..d73ddb6 100644 --- a/linden/indra/newview/llagent.cpp +++ b/linden/indra/newview/llagent.cpp | |||
@@ -758,6 +758,9 @@ void LLAgent::movePitch(S32 direction) | |||
758 | // Does this parcel allow you to fly? | 758 | // Does this parcel allow you to fly? |
759 | BOOL LLAgent::canFly() | 759 | BOOL LLAgent::canFly() |
760 | { | 760 | { |
761 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0c) | ||
762 | if (gRlvHandler.hasBehaviour(RLV_BHVR_FLY)) return FALSE; | ||
763 | // [/RLVa:KB] | ||
761 | if (isGodlike()) return TRUE; | 764 | if (isGodlike()) return TRUE; |
762 | 765 | ||
763 | LLViewerRegion* regionp = getRegion(); | 766 | LLViewerRegion* regionp = getRegion(); |
@@ -797,6 +800,13 @@ void LLAgent::setFlying(BOOL fly) | |||
797 | 800 | ||
798 | if (fly) | 801 | if (fly) |
799 | { | 802 | { |
803 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0c) | ||
804 | if (gRlvHandler.hasBehaviour(RLV_BHVR_FLY)) | ||
805 | { | ||
806 | return; | ||
807 | } | ||
808 | // [/RLVa:KB] | ||
809 | |||
800 | BOOL was_flying = getFlying(); | 810 | BOOL was_flying = getFlying(); |
801 | if (!canFly() && !was_flying) | 811 | if (!canFly() && !was_flying) |
802 | { | 812 | { |
@@ -4243,6 +4253,13 @@ void LLAgent::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_ani | |||
4243 | return; | 4253 | return; |
4244 | } | 4254 | } |
4245 | 4255 | ||
4256 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
4257 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (mAvatarObject.notNull()) && (mAvatarObject->mIsSitting) ) | ||
4258 | { | ||
4259 | return; | ||
4260 | } | ||
4261 | // [/RLVa:KB] | ||
4262 | |||
4246 | setControlFlags(AGENT_CONTROL_STAND_UP); // force stand up | 4263 | setControlFlags(AGENT_CONTROL_STAND_UP); // force stand up |
4247 | gViewerWindow->getWindow()->resetBusyCount(); | 4264 | gViewerWindow->getWindow()->resetBusyCount(); |
4248 | 4265 | ||
@@ -5037,6 +5054,14 @@ BOOL LLAgent::setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOO | |||
5037 | // utility to build a location string | 5054 | // utility to build a location string |
5038 | void LLAgent::buildLocationString(std::string& str) | 5055 | void LLAgent::buildLocationString(std::string& str) |
5039 | { | 5056 | { |
5057 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
5058 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
5059 | { | ||
5060 | str = rlv_handler_t::cstrHidden; | ||
5061 | return; | ||
5062 | } | ||
5063 | // [/RLVa:KB] | ||
5064 | |||
5040 | const LLVector3& agent_pos_region = getPositionAgent(); | 5065 | const LLVector3& agent_pos_region = getPositionAgent(); |
5041 | S32 pos_x = S32(agent_pos_region.mV[VX]); | 5066 | S32 pos_x = S32(agent_pos_region.mV[VX]); |
5042 | S32 pos_y = S32(agent_pos_region.mV[VY]); | 5067 | S32 pos_y = S32(agent_pos_region.mV[VY]); |
@@ -5919,6 +5944,15 @@ void LLAgent::teleportRequest( | |||
5919 | // Landmark ID = LLUUID::null means teleport home | 5944 | // Landmark ID = LLUUID::null means teleport home |
5920 | void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id) | 5945 | void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id) |
5921 | { | 5946 | { |
5947 | // [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) | ||
5948 | if ( (rlv_handler_t::isEnabled()) && | ||
5949 | ( (gRlvHandler.hasBehaviour("tplm")) || | ||
5950 | ((gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (mAvatarObject.notNull()) && (mAvatarObject->mIsSitting)) )) | ||
5951 | { | ||
5952 | return; | ||
5953 | } | ||
5954 | // [/RLVa:KB] | ||
5955 | |||
5922 | LLViewerRegion *regionp = getRegion(); | 5956 | LLViewerRegion *regionp = getRegion(); |
5923 | if(regionp && teleportCore()) | 5957 | if(regionp && teleportCore()) |
5924 | { | 5958 | { |
@@ -5983,6 +6017,17 @@ void LLAgent::teleportCancel() | |||
5983 | 6017 | ||
5984 | void LLAgent::teleportViaLocation(const LLVector3d& pos_global) | 6018 | void LLAgent::teleportViaLocation(const LLVector3d& pos_global) |
5985 | { | 6019 | { |
6020 | // [RLVa:KB] - Alternate: Snowglobe-1.0 | Checked: 2009-07-07 (RLVa-1.0.0d) | ||
6021 | // If we're getting teleported due to @tpto we should disregard any @tploc=n or @unsit=n restrictions from the same object | ||
6022 | if ( (rlv_handler_t::isEnabled()) && | ||
6023 | ( (gRlvHandler.hasBehaviourExcept("tploc", gRlvHandler.getCurrentObject())) || | ||
6024 | ( (mAvatarObject.notNull()) && (mAvatarObject->mIsSitting) && | ||
6025 | (gRlvHandler.hasBehaviourExcept(RLV_BHVR_UNSIT, gRlvHandler.getCurrentObject()))) ) ) | ||
6026 | { | ||
6027 | return; | ||
6028 | } | ||
6029 | // [/RLVa:KB] | ||
6030 | |||
5986 | LLViewerRegion* regionp = getRegion(); | 6031 | LLViewerRegion* regionp = getRegion(); |
5987 | LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global); | 6032 | LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global); |
5988 | if(regionp && info) | 6033 | if(regionp && info) |
@@ -6057,6 +6102,13 @@ void LLAgent::setTeleportState(ETeleportState state) | |||
6057 | // We're outa here. Save "back" slurl. | 6102 | // We're outa here. Save "back" slurl. |
6058 | mTeleportSourceSLURL = getSLURL(); | 6103 | mTeleportSourceSLURL = getSLURL(); |
6059 | } | 6104 | } |
6105 | |||
6106 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-07 (RLVa-1.0.0d) | Added: RLVa-0.2.0b | ||
6107 | if ( (rlv_handler_t::isEnabled()) && (TELEPORT_NONE == mTeleportState) ) | ||
6108 | { | ||
6109 | gRlvHandler.setCanCancelTp(true); | ||
6110 | } | ||
6111 | // [/RLVa:KB] | ||
6060 | } | 6112 | } |
6061 | 6113 | ||
6062 | void LLAgent::stopCurrentAnimations() | 6114 | void LLAgent::stopCurrentAnimations() |
@@ -6684,10 +6736,17 @@ void LLAgent::processAgentInitialWearablesUpdate( LLMessageSystem* mesgsys, void | |||
6684 | } | 6736 | } |
6685 | 6737 | ||
6686 | // now that we have the asset ids...request the wearable assets | 6738 | // now that we have the asset ids...request the wearable assets |
6739 | // [RLVa:KB] - Checked: 2009-08-08 (RLVa-1.0.1g) | Added: RLVa-1.0.1g | ||
6740 | LLInventoryFetchObserver::item_ref_t rlvItems; | ||
6741 | // [/RLVa:KB] | ||
6687 | for( i = 0; i < WT_COUNT; i++ ) | 6742 | for( i = 0; i < WT_COUNT; i++ ) |
6688 | { | 6743 | { |
6689 | if( !gAgent.mWearableEntry[i].mItemID.isNull() ) | 6744 | if( !gAgent.mWearableEntry[i].mItemID.isNull() ) |
6690 | { | 6745 | { |
6746 | // [RLVa:KB] - Checked: 2009-08-08 (RLVa-1.0.1g) | Added: RLVa-1.0.1g | ||
6747 | if (rlv_handler_t::isEnabled()) | ||
6748 | rlvItems.push_back(gAgent.mWearableEntry[i].mItemID); | ||
6749 | // [/RLVa:KB] | ||
6691 | gWearableList.getAsset( | 6750 | gWearableList.getAsset( |
6692 | asset_id_array[i], | 6751 | asset_id_array[i], |
6693 | LLStringUtil::null, | 6752 | LLStringUtil::null, |
@@ -6695,6 +6754,15 @@ void LLAgent::processAgentInitialWearablesUpdate( LLMessageSystem* mesgsys, void | |||
6695 | LLAgent::onInitialWearableAssetArrived, (void*)(intptr_t)i ); | 6754 | LLAgent::onInitialWearableAssetArrived, (void*)(intptr_t)i ); |
6696 | } | 6755 | } |
6697 | } | 6756 | } |
6757 | |||
6758 | // [RLVa:KB] - Checked: 2009-08-08 (RLVa-1.0.1g) | Added: RLVa-1.0.1g | ||
6759 | // TODO-RLVa: checking that we're in STATE_STARTED is probably not needed, but leave it until we can be absolutely sure | ||
6760 | if ( (rlv_handler_t::isEnabled()) && (LLStartUp::getStartupState() == STATE_STARTED) ) | ||
6761 | { | ||
6762 | RlvCurrentlyWorn f; | ||
6763 | f.fetchItems(rlvItems); | ||
6764 | } | ||
6765 | // [/RLVa:KB] | ||
6698 | } | 6766 | } |
6699 | } | 6767 | } |
6700 | 6768 | ||
@@ -7192,6 +7260,13 @@ void LLAgent::removeWearable( EWearableType type ) | |||
7192 | return; | 7260 | return; |
7193 | } | 7261 | } |
7194 | 7262 | ||
7263 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-07 (RLVa-1.0.0d) | ||
7264 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isRemovable(type)) ) | ||
7265 | { | ||
7266 | return; | ||
7267 | } | ||
7268 | // [/RLVa:KB] | ||
7269 | |||
7195 | if( old_wearable ) | 7270 | if( old_wearable ) |
7196 | { | 7271 | { |
7197 | if( old_wearable->isDirty() ) | 7272 | if( old_wearable->isDirty() ) |
@@ -7314,15 +7389,17 @@ void LLAgent::setWearableOutfit( | |||
7314 | wearables_to_remove[WT_SKIN] = FALSE; | 7389 | wearables_to_remove[WT_SKIN] = FALSE; |
7315 | wearables_to_remove[WT_HAIR] = FALSE; | 7390 | wearables_to_remove[WT_HAIR] = FALSE; |
7316 | wearables_to_remove[WT_EYES] = FALSE; | 7391 | wearables_to_remove[WT_EYES] = FALSE; |
7317 | wearables_to_remove[WT_SHIRT] = remove; | 7392 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Added: RLVa-0.2.2a |
7318 | wearables_to_remove[WT_PANTS] = remove; | 7393 | wearables_to_remove[WT_SHIRT] = remove && gRlvHandler.isRemovable(WT_SHIRT); |
7319 | wearables_to_remove[WT_SHOES] = remove; | 7394 | wearables_to_remove[WT_PANTS] = remove && gRlvHandler.isRemovable(WT_PANTS); |
7320 | wearables_to_remove[WT_SOCKS] = remove; | 7395 | wearables_to_remove[WT_SHOES] = remove && gRlvHandler.isRemovable(WT_SHOES); |
7321 | wearables_to_remove[WT_JACKET] = remove; | 7396 | wearables_to_remove[WT_SOCKS] = remove && gRlvHandler.isRemovable(WT_SOCKS); |
7322 | wearables_to_remove[WT_GLOVES] = remove; | 7397 | wearables_to_remove[WT_JACKET] = remove && gRlvHandler.isRemovable(WT_JACKET); |
7323 | wearables_to_remove[WT_UNDERSHIRT] = (!gAgent.isTeen()) & remove; | 7398 | wearables_to_remove[WT_GLOVES] = remove && gRlvHandler.isRemovable(WT_GLOVES); |
7324 | wearables_to_remove[WT_UNDERPANTS] = (!gAgent.isTeen()) & remove; | 7399 | wearables_to_remove[WT_UNDERSHIRT] = (!gAgent.isTeen()) && remove && gRlvHandler.isRemovable(WT_UNDERSHIRT); |
7325 | wearables_to_remove[WT_SKIRT] = remove; | 7400 | wearables_to_remove[WT_UNDERPANTS] = (!gAgent.isTeen()) && remove && gRlvHandler.isRemovable(WT_UNDERPANTS); |
7401 | wearables_to_remove[WT_SKIRT] = remove && gRlvHandler.isRemovable(WT_SKIRT); | ||
7402 | // [/RLVa:KB] | ||
7326 | 7403 | ||
7327 | S32 count = wearables.count(); | 7404 | S32 count = wearables.count(); |
7328 | llassert( items.count() == count ); | 7405 | llassert( items.count() == count ); |
@@ -7414,6 +7491,15 @@ void LLAgent::setWearable( LLInventoryItem* new_item, LLWearable* new_wearable ) | |||
7414 | EWearableType type = new_wearable->getType(); | 7491 | EWearableType type = new_wearable->getType(); |
7415 | 7492 | ||
7416 | LLWearable* old_wearable = mWearableEntry[ type ].mWearable; | 7493 | LLWearable* old_wearable = mWearableEntry[ type ].mWearable; |
7494 | |||
7495 | // [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) | ||
7496 | // Block if: we can't wear on that layer; or we're already wearing something there we can't take off | ||
7497 | if ( (rlv_handler_t::isEnabled()) && ((!gRlvHandler.isWearable(type)) || ((old_wearable) && (!gRlvHandler.isRemovable(type)))) ) | ||
7498 | { | ||
7499 | return; | ||
7500 | } | ||
7501 | // [/RLVa:KB] | ||
7502 | |||
7417 | if( old_wearable ) | 7503 | if( old_wearable ) |
7418 | { | 7504 | { |
7419 | const LLUUID& old_item_id = mWearableEntry[ type ].mItemID; | 7505 | const LLUUID& old_item_id = mWearableEntry[ type ].mItemID; |
@@ -7622,10 +7708,13 @@ void LLAgent::userRemoveAllAttachments( void* userdata ) | |||
7622 | return; | 7708 | return; |
7623 | } | 7709 | } |
7624 | 7710 | ||
7625 | gMessageSystem->newMessage("ObjectDetach"); | 7711 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Added: RLVa-0.2.0c |
7626 | gMessageSystem->nextBlockFast(_PREHASH_AgentData); | 7712 | // NOTE-RLVa: This function is called from inside RlvHandler as well, hence the rather heavy modifications |
7627 | gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); | 7713 | std::list<U32> rlvAttachments; |
7628 | gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | 7714 | // TODO-RLVa: Once we have the improved "removeWearable" logic implemented we can just get rid of the whole "rlvCompFolders" hassle |
7715 | #ifdef RLV_EXPERIMENTAL_COMPOSITES | ||
7716 | std::list<LLUUID> rlvCompFolders; | ||
7717 | #endif // RLV_EXPERIMENTAL_COMPOSITES | ||
7629 | 7718 | ||
7630 | for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); | 7719 | for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); |
7631 | iter != avatarp->mAttachmentPoints.end(); ) | 7720 | iter != avatarp->mAttachmentPoints.end(); ) |
@@ -7635,11 +7724,78 @@ void LLAgent::userRemoveAllAttachments( void* userdata ) | |||
7635 | LLViewerObject* objectp = attachment->getObject(); | 7724 | LLViewerObject* objectp = attachment->getObject(); |
7636 | if (objectp) | 7725 | if (objectp) |
7637 | { | 7726 | { |
7727 | if (rlv_handler_t::isEnabled()) | ||
7728 | { | ||
7729 | if (!gRlvHandler.isDetachable(curiter->first)) | ||
7730 | continue; | ||
7731 | |||
7732 | // Check if we're being called in response to an RLV command (that would be @detach=force) | ||
7733 | if ( (gRlvHandler.getCurrentCommand()) && (attachment->getItemID().notNull()) ) | ||
7734 | { | ||
7735 | if (!gRlvHandler.isStrippable(attachment->getItemID())) // "nostrip" can be taken off by the user but not @detach | ||
7736 | continue; | ||
7737 | |||
7738 | #ifdef RLV_EXPERIMENTAL_COMPOSITES | ||
7739 | LLViewerInventoryCategory* pFolder; | ||
7740 | if (gRlvHandler.getCompositeInfo(attachment->getItemID(), NULL, &pFolder)) | ||
7741 | { | ||
7742 | #ifdef RLV_EXPERIMENTAL_COMPOSITE_LOCKING | ||
7743 | if (!gRlvHandler.canTakeOffComposite(pFolder)) | ||
7744 | continue; | ||
7745 | #endif // RLV_EXPERIMENTAL_COMPOSITE_LOCKING | ||
7746 | |||
7747 | // The attachment belongs to a composite folder so there may be additional things we need to take off | ||
7748 | if (std::find(rlvCompFolders.begin(), rlvCompFolders.end(), pFolder->getUUID()) != rlvCompFolders.end()) | ||
7749 | rlvCompFolders.push_back(pFolder->getUUID()); | ||
7750 | } | ||
7751 | #endif // RLV_EXPERIMENTAL_COMPOSITES | ||
7752 | } | ||
7753 | } | ||
7754 | rlvAttachments.push_back(objectp->getLocalID()); | ||
7755 | } | ||
7756 | } | ||
7757 | |||
7758 | // Only send the message if we actually have something to detach | ||
7759 | if (rlvAttachments.size() > 0) | ||
7760 | { | ||
7761 | gMessageSystem->newMessage("ObjectDetach"); | ||
7762 | gMessageSystem->nextBlockFast(_PREHASH_AgentData); | ||
7763 | gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); | ||
7764 | gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | ||
7765 | |||
7766 | for (std::list<U32>::const_iterator itAttach = rlvAttachments.begin(); itAttach != rlvAttachments.end(); ++itAttach) | ||
7767 | { | ||
7638 | gMessageSystem->nextBlockFast(_PREHASH_ObjectData); | 7768 | gMessageSystem->nextBlockFast(_PREHASH_ObjectData); |
7639 | gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, objectp->getLocalID()); | 7769 | gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, *itAttach); |
7640 | } | 7770 | } |
7771 | |||
7772 | gMessageSystem->sendReliable( gAgent.getRegionHost() ); | ||
7641 | } | 7773 | } |
7642 | gMessageSystem->sendReliable( gAgent.getRegionHost() ); | 7774 | |
7775 | #ifdef RLV_EXPERIMENTAL_COMPOSITES | ||
7776 | if (rlv_handler_t::isEnabled) | ||
7777 | { | ||
7778 | // If we encountered any composite folders then we need to @detach all of them | ||
7779 | for (std::list<LLUUID>::const_iterator itFolder = rlvCompFolders.begin(); itFolder != rlvCompFolders.end(); ++itFolder) | ||
7780 | { | ||
7781 | std::string strFolder = gRlvHandler.getSharedPath(*itFolder); | ||
7782 | |||
7783 | // It shouldn't happen but make absolutely sure that we don't issue @detach:=force and reenter this function | ||
7784 | if (!strFolder.empty()) | ||
7785 | { | ||
7786 | std::string strCmd = "detach:" + strFolder + "=force"; | ||
7787 | #ifdef RLV_DEBUG | ||
7788 | RLV_INFOS << "\t- detaching composite folder: @" << strCmd << LL_ENDL; | ||
7789 | #endif // RLV_DEBUG | ||
7790 | |||
7791 | // HACK-RLV: executing a command while another command is currently executing isn't the best thing to do, however | ||
7792 | // in this specific case it is safe (and still better than making processForceCommand public) | ||
7793 | gRlvHandler.processCommand(gRlvHandler.getCurrentObject(), strCmd); | ||
7794 | } | ||
7795 | } | ||
7796 | } | ||
7797 | #endif // RLV_EXPERIMENTAL_COMPOSITES | ||
7798 | // [/RLVa:KB] | ||
7643 | } | 7799 | } |
7644 | 7800 | ||
7645 | void LLAgent::observeFriends() | 7801 | void LLAgent::observeFriends() |
diff --git a/linden/indra/newview/llagent.h b/linden/indra/newview/llagent.h index 0b8463f..d6854e4 100644 --- a/linden/indra/newview/llagent.h +++ b/linden/indra/newview/llagent.h | |||
@@ -67,6 +67,10 @@ | |||
67 | #include "llfollowcam.h" | 67 | #include "llfollowcam.h" |
68 | // end Ventrella | 68 | // end Ventrella |
69 | 69 | ||
70 | // [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) | ||
71 | #include "rlvhandler.h" | ||
72 | // [/RLVa:KB] | ||
73 | |||
70 | const U8 AGENT_STATE_TYPING = 0x04; // Typing indication | 74 | const U8 AGENT_STATE_TYPING = 0x04; // Typing indication |
71 | const U8 AGENT_STATE_EDITING = 0x10; // Set when agent has objects selected | 75 | const U8 AGENT_STATE_EDITING = 0x10; // Set when agent has objects selected |
72 | 76 | ||
diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index 0f1bfb4..ab4d8a9 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp | |||
@@ -3834,4 +3834,21 @@ void LLAppViewer::handleLoginComplete() | |||
3834 | gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState(); | 3834 | gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState(); |
3835 | } | 3835 | } |
3836 | writeDebugInfo(); | 3836 | writeDebugInfo(); |
3837 | |||
3838 | // [RLVa:KB] - Alternate: Snowglobe-1.0 | Checked: 2009-08-05 (RLVa-1.0.1e) | Modified: RLVa-1.0.1e | ||
3839 | // TODO-RLVa: find some way to initialize the lookup table when we need them *and* support toggling RLVa at runtime | ||
3840 | gRlvHandler.initLookupTables(); | ||
3841 | |||
3842 | if (rlv_handler_t::isEnabled()) | ||
3843 | { | ||
3844 | RlvCurrentlyWorn::fetchWorn(); | ||
3845 | rlv_handler_t::fetchSharedInventory(); | ||
3846 | |||
3847 | #ifdef RLV_EXTENSION_STARTLOCATION | ||
3848 | RlvSettings::updateLoginLastLocation(); | ||
3849 | #endif // RLV_EXTENSION_STARTLOCATION | ||
3850 | |||
3851 | gRlvHandler.processRetainedCommands(); | ||
3852 | } | ||
3853 | // [/RLVa:KB] | ||
3837 | } | 3854 | } |
diff --git a/linden/indra/newview/llchatbar.cpp b/linden/indra/newview/llchatbar.cpp index 1dffae3..1de3690 100644 --- a/linden/indra/newview/llchatbar.cpp +++ b/linden/indra/newview/llchatbar.cpp | |||
@@ -79,7 +79,10 @@ LLChatBar *gChatBar = NULL; | |||
79 | 79 | ||
80 | // legacy calllback glue | 80 | // legacy calllback glue |
81 | void toggleChatHistory(void* user_data); | 81 | void toggleChatHistory(void* user_data); |
82 | void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel); | 82 | //void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel); |
83 | // [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) | Modified: RLVa-0.2.2a | ||
84 | void send_chat_from_viewer(std::string utf8_out_text, EChatType type, S32 channel); | ||
85 | // [/RLVa:KB] | ||
83 | 86 | ||
84 | 87 | ||
85 | class LLChatBarGestureObserver : public LLGestureManagerObserver | 88 | class LLChatBarGestureObserver : public LLGestureManagerObserver |
@@ -516,7 +519,10 @@ void LLChatBar::onInputEditorKeystroke( LLLineEditor* caller, void* userdata ) | |||
516 | 519 | ||
517 | S32 length = raw_text.length(); | 520 | S32 length = raw_text.length(); |
518 | 521 | ||
519 | if( (length > 0) && (raw_text[0] != '/') ) // forward slash is used for escape (eg. emote) sequences | 522 | //if( (length > 0) && (raw_text[0] != '/') ) // forward slash is used for escape (eg. emote) sequences |
523 | // [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) | ||
524 | if ( (length > 0) && (raw_text[0] != '/') && (!gRlvHandler.hasBehaviour(RLV_BHVR_REDIRCHAT)) ) | ||
525 | // [/RLVa:KB] | ||
520 | { | 526 | { |
521 | gAgent.startTyping(); | 527 | gAgent.startTyping(); |
522 | } | 528 | } |
@@ -621,6 +627,21 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL | |||
621 | utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1); | 627 | utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1); |
622 | } | 628 | } |
623 | 629 | ||
630 | // [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) | Modified: RLVa-0.2.0b | ||
631 | if ( (0 == channel) && (rlv_handler_t::isEnabled()) ) | ||
632 | { | ||
633 | // Adjust the (public) chat "volume" on chat and gestures (also takes care of playing the proper animation) | ||
634 | if ( ((CHAT_TYPE_SHOUT == type) || (CHAT_TYPE_NORMAL == type)) && (gRlvHandler.hasBehaviour("chatnormal")) ) | ||
635 | type = CHAT_TYPE_WHISPER; | ||
636 | else if ( (CHAT_TYPE_SHOUT == type) && (gRlvHandler.hasBehaviour("chatshout")) ) | ||
637 | type = CHAT_TYPE_NORMAL; | ||
638 | else if ( (CHAT_TYPE_WHISPER == type) && (gRlvHandler.hasBehaviour("chatwhisper")) ) | ||
639 | type = CHAT_TYPE_NORMAL; | ||
640 | |||
641 | animate &= !gRlvHandler.hasBehaviour(RLV_BHVR_REDIRCHAT); | ||
642 | } | ||
643 | // [/RLVa:KB] | ||
644 | |||
624 | // Don't animate for chats people can't hear (chat to scripts) | 645 | // Don't animate for chats people can't hear (chat to scripts) |
625 | if (animate && (channel == 0)) | 646 | if (animate && (channel == 0)) |
626 | { | 647 | { |
@@ -656,8 +677,57 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL | |||
656 | send_chat_from_viewer(utf8_out_text, type, channel); | 677 | send_chat_from_viewer(utf8_out_text, type, channel); |
657 | } | 678 | } |
658 | 679 | ||
659 | void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel) | 680 | // void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel) |
681 | // [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) | Modified: RLVa-0.2.2a | ||
682 | void send_chat_from_viewer(std::string utf8_out_text, EChatType type, S32 channel) | ||
683 | // [/RLVa:KB] | ||
660 | { | 684 | { |
685 | // [RLVa:KB] - Checked: 2009-08-05 (RLVa-1.0.1e) | Modified: RLVa-1.0.1e | ||
686 | // Only process chat messages (ie not CHAT_TYPE_START, CHAT_TYPE_STOP, etc) | ||
687 | if ( (rlv_handler_t::isEnabled()) && ( (CHAT_TYPE_WHISPER == type) || (CHAT_TYPE_NORMAL == type) || (CHAT_TYPE_SHOUT == type) ) ) | ||
688 | { | ||
689 | if (0 == channel) | ||
690 | { | ||
691 | // (We already did this before, but LLChatHandler::handle() calls this directly) | ||
692 | if ( ((CHAT_TYPE_SHOUT == type) || (CHAT_TYPE_NORMAL == type)) && (gRlvHandler.hasBehaviour("chatnormal")) ) | ||
693 | type = CHAT_TYPE_WHISPER; | ||
694 | else if ( (CHAT_TYPE_SHOUT == type) && (gRlvHandler.hasBehaviour("chatshout")) ) | ||
695 | type = CHAT_TYPE_NORMAL; | ||
696 | else if ( (CHAT_TYPE_WHISPER == type) && (gRlvHandler.hasBehaviour("chatwhisper")) ) | ||
697 | type = CHAT_TYPE_NORMAL; | ||
698 | |||
699 | // Redirect chat if needed | ||
700 | if ( ( (gRlvHandler.hasBehaviour(RLV_BHVR_REDIRCHAT) || (gRlvHandler.hasBehaviour(RLV_BHVR_REDIREMOTE)) ) && | ||
701 | (gRlvHandler.redirectChatOrEmote(utf8_out_text)) ) ) | ||
702 | { | ||
703 | return; | ||
704 | } | ||
705 | |||
706 | // Filter public chat if sendchat restricted (and filter anything that redirchat didn't redirect) | ||
707 | if ( (gRlvHandler.hasBehaviour("sendchat")) || (gRlvHandler.hasBehaviour(RLV_BHVR_REDIRCHAT)) ) | ||
708 | gRlvHandler.filterChat(utf8_out_text, true); | ||
709 | } | ||
710 | else | ||
711 | { | ||
712 | // Don't allow chat on a non-public channel if sendchannel restricted (unless the channel is an exception) | ||
713 | if ( (gRlvHandler.hasBehaviour("sendchannel")) && (!gRlvHandler.hasBehaviour("sendchannel", llformat("%d", channel))) ) | ||
714 | return; | ||
715 | |||
716 | // Don't allow chat on debug channel if @sendchat, @redirchat or @rediremote restricted (shows as public chat on viewers) | ||
717 | if (channel >= CHAT_CHANNEL_DEBUG) | ||
718 | { | ||
719 | bool fIsEmote = rlvIsEmote(utf8_out_text); | ||
720 | if ( (gRlvHandler.hasBehaviour("sendchat")) || | ||
721 | ((!fIsEmote) && (gRlvHandler.hasBehaviour(RLV_BHVR_REDIRCHAT))) || | ||
722 | ((fIsEmote) && (gRlvHandler.hasBehaviour(RLV_BHVR_REDIREMOTE))) ) | ||
723 | { | ||
724 | return; | ||
725 | } | ||
726 | } | ||
727 | } | ||
728 | } | ||
729 | // [/RLVa:KB] | ||
730 | |||
661 | LLMessageSystem* msg = gMessageSystem; | 731 | LLMessageSystem* msg = gMessageSystem; |
662 | msg->newMessageFast(_PREHASH_ChatFromViewer); | 732 | msg->newMessageFast(_PREHASH_ChatFromViewer); |
663 | msg->nextBlockFast(_PREHASH_AgentData); | 733 | msg->nextBlockFast(_PREHASH_AgentData); |
diff --git a/linden/indra/newview/llfloaterabout.cpp b/linden/indra/newview/llfloaterabout.cpp index 0954a70..57c5339 100644 --- a/linden/indra/newview/llfloaterabout.cpp +++ b/linden/indra/newview/llfloaterabout.cpp | |||
@@ -126,7 +126,15 @@ LLFloaterAbout::LLFloaterAbout() | |||
126 | 126 | ||
127 | // Position | 127 | // Position |
128 | LLViewerRegion* region = gAgent.getRegion(); | 128 | LLViewerRegion* region = gAgent.getRegion(); |
129 | if (region) | 129 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-04 (RLVa-1.0.0a) |
130 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
131 | { | ||
132 | support.append(rlv_handler_t::cstrHidden); | ||
133 | support.append("\n\n"); | ||
134 | } | ||
135 | else if (region) | ||
136 | // [/RLVa:KB] | ||
137 | // if (region) | ||
130 | { | 138 | { |
131 | LLStyleSP server_link_style(new LLStyle); | 139 | LLStyleSP server_link_style(new LLStyle); |
132 | server_link_style->setVisible(true); | 140 | server_link_style->setVisible(true); |
diff --git a/linden/indra/newview/llfloateractivespeakers.cpp b/linden/indra/newview/llfloateractivespeakers.cpp index a8f3f91..b4d402a 100644 --- a/linden/indra/newview/llfloateractivespeakers.cpp +++ b/linden/indra/newview/llfloateractivespeakers.cpp | |||
@@ -98,6 +98,11 @@ void LLSpeaker::onAvatarNameLookup(const LLUUID& id, const std::string& first, c | |||
98 | if (speaker_ptr) | 98 | if (speaker_ptr) |
99 | { | 99 | { |
100 | speaker_ptr->mDisplayName = first + " " + last; | 100 | speaker_ptr->mDisplayName = first + " " + last; |
101 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-1.0.0g | ||
102 | // TODO-RLVa: this seems to get called per frame which is very likely an LL bug that will eventuall get fixed | ||
103 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
104 | speaker_ptr->mDisplayName = gRlvHandler.getAnonym(speaker_ptr->mDisplayName); | ||
105 | // [/RLVa:KB] | ||
101 | } | 106 | } |
102 | } | 107 | } |
103 | 108 | ||
@@ -710,6 +715,13 @@ void LLPanelActiveSpeakers::onVolumeChange(LLUICtrl* source, void* user_data) | |||
710 | //static | 715 | //static |
711 | void LLPanelActiveSpeakers::onClickProfile(void* user_data) | 716 | void LLPanelActiveSpeakers::onClickProfile(void* user_data) |
712 | { | 717 | { |
718 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-1.0.0g | ||
719 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
720 | { | ||
721 | return; | ||
722 | } | ||
723 | // [/RLVa:KB] | ||
724 | |||
713 | LLPanelActiveSpeakers* panelp = (LLPanelActiveSpeakers*)user_data; | 725 | LLPanelActiveSpeakers* panelp = (LLPanelActiveSpeakers*)user_data; |
714 | LLUUID speaker_id = panelp->mSpeakerList->getValue().asUUID(); | 726 | LLUUID speaker_id = panelp->mSpeakerList->getValue().asUUID(); |
715 | 727 | ||
@@ -719,6 +731,13 @@ void LLPanelActiveSpeakers::onClickProfile(void* user_data) | |||
719 | //static | 731 | //static |
720 | void LLPanelActiveSpeakers::onDoubleClickSpeaker(void* user_data) | 732 | void LLPanelActiveSpeakers::onDoubleClickSpeaker(void* user_data) |
721 | { | 733 | { |
734 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-1.0.0g | ||
735 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
736 | { | ||
737 | return; | ||
738 | } | ||
739 | // [/RLVa:KB] | ||
740 | |||
722 | LLPanelActiveSpeakers* panelp = (LLPanelActiveSpeakers*)user_data; | 741 | LLPanelActiveSpeakers* panelp = (LLPanelActiveSpeakers*)user_data; |
723 | LLUUID speaker_id = panelp->mSpeakerList->getValue().asUUID(); | 742 | LLUUID speaker_id = panelp->mSpeakerList->getValue().asUUID(); |
724 | 743 | ||
diff --git a/linden/indra/newview/llfloaterbeacons.cpp b/linden/indra/newview/llfloaterbeacons.cpp index d636776..7403df2 100644 --- a/linden/indra/newview/llfloaterbeacons.cpp +++ b/linden/indra/newview/llfloaterbeacons.cpp | |||
@@ -37,6 +37,9 @@ | |||
37 | #include "llcheckboxctrl.h" | 37 | #include "llcheckboxctrl.h" |
38 | #include "pipeline.h" | 38 | #include "pipeline.h" |
39 | 39 | ||
40 | // [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) | ||
41 | #include "llagent.h" | ||
42 | // [/RLVa:KB] | ||
40 | 43 | ||
41 | LLFloaterBeacons::LLFloaterBeacons(const LLSD& seed) | 44 | LLFloaterBeacons::LLFloaterBeacons(const LLSD& seed) |
42 | { | 45 | { |
@@ -72,6 +75,13 @@ BOOL LLFloaterBeacons::postBuild() | |||
72 | // Too bad we can't just add control_name="BeaconsEnabled" to the XML. | 75 | // Too bad we can't just add control_name="BeaconsEnabled" to the XML. |
73 | void LLFloaterBeacons::open() | 76 | void LLFloaterBeacons::open() |
74 | { | 77 | { |
78 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0b) | ||
79 | if (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) | ||
80 | { | ||
81 | return; | ||
82 | } | ||
83 | // [/RLVa:KB] | ||
84 | |||
75 | LLFloater::open(); | 85 | LLFloater::open(); |
76 | gSavedSettings.setBOOL( "BeaconsEnabled", TRUE); | 86 | gSavedSettings.setBOOL( "BeaconsEnabled", TRUE); |
77 | } | 87 | } |
diff --git a/linden/indra/newview/llfloaterchat.cpp b/linden/indra/newview/llfloaterchat.cpp index d0713bc..1f51a21 100644 --- a/linden/indra/newview/llfloaterchat.cpp +++ b/linden/indra/newview/llfloaterchat.cpp | |||
@@ -202,7 +202,10 @@ void add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4& | |||
202 | // If the msg is from an agent (not yourself though), | 202 | // If the msg is from an agent (not yourself though), |
203 | // extract out the sender name and replace it with the hotlinked name. | 203 | // extract out the sender name and replace it with the hotlinked name. |
204 | if (chat.mSourceType == CHAT_SOURCE_AGENT && | 204 | if (chat.mSourceType == CHAT_SOURCE_AGENT && |
205 | chat.mFromID != LLUUID::null) | 205 | chat.mFromID != LLUUID::null && |
206 | // [RLVa] - Version: 1.22.11 | Checked: 2009-07-08 (RLVa-1.0.0e) | ||
207 | (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ) | ||
208 | // [/RLVa] | ||
206 | { | 209 | { |
207 | chat.mURL = llformat("secondlife:///app/agent/%s/about",chat.mFromID.asString().c_str()); | 210 | chat.mURL = llformat("secondlife:///app/agent/%s/about",chat.mFromID.asString().c_str()); |
208 | } | 211 | } |
@@ -261,6 +264,30 @@ void LLFloaterChat::toggleHistoryChannelControl() | |||
261 | // static | 264 | // static |
262 | void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file) | 265 | void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file) |
263 | { | 266 | { |
267 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
268 | if (rlv_handler_t::isEnabled()) | ||
269 | { | ||
270 | // TODO-RLVa: we might cast too broad a net by filtering here, needs testing | ||
271 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) && (!chat.mRlvLocFiltered) && (CHAT_SOURCE_AGENT != chat.mSourceType) ) | ||
272 | { | ||
273 | LLChat& rlvChat = const_cast<LLChat&>(chat); | ||
274 | gRlvHandler.filterLocation(rlvChat.mText); | ||
275 | rlvChat.mRlvLocFiltered = TRUE; | ||
276 | } | ||
277 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (!chat.mRlvNamesFiltered) ) | ||
278 | { | ||
279 | // NOTE: this will also filter inventory accepted/declined text in the chat history | ||
280 | LLChat& rlvChat = const_cast<LLChat&>(chat); | ||
281 | if (CHAT_SOURCE_AGENT != chat.mSourceType) | ||
282 | { | ||
283 | // Filter object and system chat (names are filtered elsewhere to save ourselves an gObjectList lookup) | ||
284 | gRlvHandler.filterNames(rlvChat.mText); | ||
285 | } | ||
286 | rlvChat.mRlvNamesFiltered = TRUE; | ||
287 | } | ||
288 | } | ||
289 | // [/RLVa:KB] | ||
290 | |||
264 | if ( gSavedPerAccountSettings.getBOOL("LogChat") && log_to_file) | 291 | if ( gSavedPerAccountSettings.getBOOL("LogChat") && log_to_file) |
265 | { | 292 | { |
266 | log_chat_text(chat); | 293 | log_chat_text(chat); |
@@ -391,6 +418,30 @@ void LLFloaterChat::addChat(const LLChat& chat, | |||
391 | chat.mChatType == CHAT_TYPE_DEBUG_MSG | 418 | chat.mChatType == CHAT_TYPE_DEBUG_MSG |
392 | && !gSavedSettings.getBOOL("ScriptErrorsAsChat"); | 419 | && !gSavedSettings.getBOOL("ScriptErrorsAsChat"); |
393 | 420 | ||
421 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
422 | if (rlv_handler_t::isEnabled()) | ||
423 | { | ||
424 | // TODO-RLVa: we might cast too broad a net by filtering here, needs testing | ||
425 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) && (!chat.mRlvLocFiltered) && (CHAT_SOURCE_AGENT != chat.mSourceType) ) | ||
426 | { | ||
427 | LLChat& rlvChat = const_cast<LLChat&>(chat); | ||
428 | if (!from_instant_message) | ||
429 | gRlvHandler.filterLocation(rlvChat.mText); | ||
430 | rlvChat.mRlvLocFiltered = TRUE; | ||
431 | } | ||
432 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (!chat.mRlvNamesFiltered) ) | ||
433 | { | ||
434 | LLChat& rlvChat = const_cast<LLChat&>(chat); | ||
435 | if ( (!from_instant_message) && (CHAT_SOURCE_AGENT != chat.mSourceType) ) | ||
436 | { | ||
437 | // Filter object and system chat (names are filtered elsewhere to save ourselves an gObjectList lookup) | ||
438 | gRlvHandler.filterNames(rlvChat.mText); | ||
439 | } | ||
440 | rlvChat.mRlvNamesFiltered = TRUE; | ||
441 | } | ||
442 | } | ||
443 | // [/RLVa:KB] | ||
444 | |||
394 | #if LL_LCD_COMPILE | 445 | #if LL_LCD_COMPILE |
395 | // add into LCD displays | 446 | // add into LCD displays |
396 | if (!invisible_script_debug_chat) | 447 | if (!invisible_script_debug_chat) |
@@ -548,7 +599,11 @@ void LLFloaterChat::onClickToggleActiveSpeakers(void* userdata) | |||
548 | { | 599 | { |
549 | LLFloaterChat* self = (LLFloaterChat*)userdata; | 600 | LLFloaterChat* self = (LLFloaterChat*)userdata; |
550 | 601 | ||
551 | self->childSetVisible("active_speakers_panel", !self->childIsVisible("active_speakers_panel")); | 602 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) |
603 | self->childSetVisible("active_speakers_panel", | ||
604 | (!self->childIsVisible("active_speakers_panel")) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ); | ||
605 | // [/RLVa:KB] | ||
606 | //self->childSetVisible("active_speakers_panel", !self->childIsVisible("active_speakers_panel")); | ||
552 | } | 607 | } |
553 | 608 | ||
554 | //static | 609 | //static |
diff --git a/linden/indra/newview/llfloaterinspect.cpp b/linden/indra/newview/llfloaterinspect.cpp index e1d3c4a..2367b48 100644 --- a/linden/indra/newview/llfloaterinspect.cpp +++ b/linden/indra/newview/llfloaterinspect.cpp | |||
@@ -42,6 +42,10 @@ | |||
42 | #include "llviewerobject.h" | 42 | #include "llviewerobject.h" |
43 | #include "lluictrlfactory.h" | 43 | #include "lluictrlfactory.h" |
44 | 44 | ||
45 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
46 | #include "rlvhandler.h" | ||
47 | // [/RLVa:KB] | ||
48 | |||
45 | LLFloaterInspect* LLFloaterInspect::sInstance = NULL; | 49 | LLFloaterInspect* LLFloaterInspect::sInstance = NULL; |
46 | 50 | ||
47 | LLFloaterInspect::LLFloaterInspect(void) : | 51 | LLFloaterInspect::LLFloaterInspect(void) : |
@@ -145,7 +149,13 @@ void LLFloaterInspect::onClickOwnerProfile(void* ctrl) | |||
145 | if(node) | 149 | if(node) |
146 | { | 150 | { |
147 | const LLUUID& owner_id = node->mPermissions->getOwner(); | 151 | const LLUUID& owner_id = node->mPermissions->getOwner(); |
148 | LLFloaterAvatarInfo::showFromDirectory(owner_id); | 152 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) |
153 | if (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
154 | { | ||
155 | LLFloaterAvatarInfo::showFromDirectory(owner_id); | ||
156 | } | ||
157 | // [/RLVa:KB] | ||
158 | // LLFloaterAvatarInfo::showFromDirectory(owner_id); | ||
149 | } | 159 | } |
150 | } | 160 | } |
151 | } | 161 | } |
@@ -163,7 +173,10 @@ void LLFloaterInspect::onSelectObject(LLUICtrl* ctrl, void* user_data) | |||
163 | { | 173 | { |
164 | if(LLFloaterInspect::getSelectedUUID() != LLUUID::null) | 174 | if(LLFloaterInspect::getSelectedUUID() != LLUUID::null) |
165 | { | 175 | { |
166 | sInstance->childSetEnabled("button owner", true); | 176 | //sInstance->childSetEnabled("button owner", true); |
177 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-1.0.0e | ||
178 | sInstance->childSetEnabled("button owner", !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)); | ||
179 | // [/RLVa:KB] | ||
167 | sInstance->childSetEnabled("button creator", true); | 180 | sInstance->childSetEnabled("button creator", true); |
168 | } | 181 | } |
169 | } | 182 | } |
@@ -223,6 +236,13 @@ void LLFloaterInspect::refresh() | |||
223 | LLStringUtil::copy(time, ctime(×tamp), MAX_STRING); | 236 | LLStringUtil::copy(time, ctime(×tamp), MAX_STRING); |
224 | time[24] = '\0'; | 237 | time[24] = '\0'; |
225 | gCacheName->getFullName(obj->mPermissions->getOwner(), owner_name); | 238 | gCacheName->getFullName(obj->mPermissions->getOwner(), owner_name); |
239 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
240 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
241 | { | ||
242 | // TODO-RLVa: shouldn't filter if this is a group-owned prim (will show "(nobody)") | ||
243 | owner_name = gRlvHandler.getAnonym(owner_name); | ||
244 | } | ||
245 | // [/RLVa:KB] | ||
226 | gCacheName->getFullName(obj->mPermissions->getCreator(), creator_name); | 246 | gCacheName->getFullName(obj->mPermissions->getCreator(), creator_name); |
227 | row["id"] = obj->getObject()->getID(); | 247 | row["id"] = obj->getObject()->getID(); |
228 | row["columns"][0]["column"] = "object_name"; | 248 | row["columns"][0]["column"] = "object_name"; |
diff --git a/linden/indra/newview/llfloaterland.cpp b/linden/indra/newview/llfloaterland.cpp index 9707184..75c5782 100644 --- a/linden/indra/newview/llfloaterland.cpp +++ b/linden/indra/newview/llfloaterland.cpp | |||
@@ -813,6 +813,12 @@ void LLPanelLandGeneral::setGroup(const LLUUID& group_id) | |||
813 | // static | 813 | // static |
814 | void LLPanelLandGeneral::onClickBuyLand(void* data) | 814 | void LLPanelLandGeneral::onClickBuyLand(void* data) |
815 | { | 815 | { |
816 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
817 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) | ||
818 | { | ||
819 | return; | ||
820 | } | ||
821 | // [/RLVa:KB] | ||
816 | BOOL* for_group = (BOOL*)data; | 822 | BOOL* for_group = (BOOL*)data; |
817 | LLViewerParcelMgr::getInstance()->startBuyLand(*for_group); | 823 | LLViewerParcelMgr::getInstance()->startBuyLand(*for_group); |
818 | } | 824 | } |
@@ -2779,3 +2785,41 @@ void LLPanelLandCovenant::updateEstateOwnerName(const std::string& name) | |||
2779 | if (editor) editor->setText(name); | 2785 | if (editor) editor->setText(name); |
2780 | } | 2786 | } |
2781 | } | 2787 | } |
2788 | |||
2789 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
2790 | void LLFloaterLand::open() | ||
2791 | { | ||
2792 | // We'll allow "About Land" as long as you have the ability to return prims (through ownership or through group powers) | ||
2793 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
2794 | { | ||
2795 | LLParcelSelection* pParcelSel = LLViewerParcelMgr::getInstance()->getFloatingParcelSelection(); | ||
2796 | if ( (!pParcelSel) || (pParcelSel->hasOthersSelected()) ) | ||
2797 | return; | ||
2798 | LLParcel* pParcel = pParcelSel->getParcel(); | ||
2799 | if (!pParcel) | ||
2800 | return; | ||
2801 | |||
2802 | // Ideally we could just use LLViewerParcelMgr::isParcelOwnedByAgent(), but that has that sneaky exemption | ||
2803 | // for fake god like (aka View Admin Options) | ||
2804 | const LLUUID& idOwner = pParcel->getOwnerID(); | ||
2805 | if ( (idOwner != gAgent.getID()) ) | ||
2806 | { | ||
2807 | // *sighs* LLAgent::hasPowerInGroup() has it too so copy/paste from there | ||
2808 | S32 count = gAgent.mGroups.count(); bool fShow = false; | ||
2809 | for (S32 i = 0; i < count; ++i) | ||
2810 | { | ||
2811 | if (gAgent.mGroups.get(i).mID == idOwner) | ||
2812 | { | ||
2813 | fShow |= ((gAgent.mGroups.get(i).mPowers & GP_LAND_RETURN) > 0); | ||
2814 | break; | ||
2815 | } | ||
2816 | } | ||
2817 | |||
2818 | if (!fShow) | ||
2819 | return; | ||
2820 | } | ||
2821 | } | ||
2822 | |||
2823 | LLFloater::open(); | ||
2824 | } | ||
2825 | // [/RLVa:KB] | ||
diff --git a/linden/indra/newview/llfloaterland.h b/linden/indra/newview/llfloaterland.h index 5f2b970..6e26b93 100644 --- a/linden/indra/newview/llfloaterland.h +++ b/linden/indra/newview/llfloaterland.h | |||
@@ -82,6 +82,10 @@ public: | |||
82 | virtual void onOpen(); | 82 | virtual void onOpen(); |
83 | virtual BOOL postBuild(); | 83 | virtual BOOL postBuild(); |
84 | 84 | ||
85 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
86 | virtual void open(); | ||
87 | // [/RLVa:KB] | ||
88 | |||
85 | protected: | 89 | protected: |
86 | 90 | ||
87 | // Does its own instance management, so clients not allowed | 91 | // Does its own instance management, so clients not allowed |
diff --git a/linden/indra/newview/llfloatermap.cpp b/linden/indra/newview/llfloatermap.cpp index 6115404..8714d4f 100644 --- a/linden/indra/newview/llfloatermap.cpp +++ b/linden/indra/newview/llfloatermap.cpp | |||
@@ -122,3 +122,13 @@ void LLFloaterMap::draw() | |||
122 | } | 122 | } |
123 | } | 123 | } |
124 | 124 | ||
125 | |||
126 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-05 (RLVa-1.0.0c) | ||
127 | void LLFloaterMap::open() | ||
128 | { | ||
129 | if (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWMINIMAP)) | ||
130 | { | ||
131 | LLFloater::open(); | ||
132 | } | ||
133 | } | ||
134 | // [/RLVa:KB] | ||
diff --git a/linden/indra/newview/llfloatermap.h b/linden/indra/newview/llfloatermap.h index dd1cba8..857b1ed 100644 --- a/linden/indra/newview/llfloatermap.h +++ b/linden/indra/newview/llfloatermap.h | |||
@@ -52,6 +52,10 @@ public: | |||
52 | /*virtual*/ void onOpen(); | 52 | /*virtual*/ void onOpen(); |
53 | /*virtual*/ void onClose(bool app_quitting); | 53 | /*virtual*/ void onClose(bool app_quitting); |
54 | /*virtual*/ BOOL canClose(); | 54 | /*virtual*/ BOOL canClose(); |
55 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-05 (RLVa-1.0.0c) | ||
56 | /*virtual*/ void open(); | ||
57 | // [/RLVa:KB] | ||
58 | |||
55 | 59 | ||
56 | private: | 60 | private: |
57 | LLFloaterMap(const LLSD& key = LLSD()); | 61 | LLFloaterMap(const LLSD& key = LLSD()); |
diff --git a/linden/indra/newview/llfloateropenobject.cpp b/linden/indra/newview/llfloateropenobject.cpp index a83b0c9..fd4f9c6 100644 --- a/linden/indra/newview/llfloateropenobject.cpp +++ b/linden/indra/newview/llfloateropenobject.cpp | |||
@@ -207,7 +207,18 @@ void LLFloaterOpenObject::onClickMoveToInventory(void* data) | |||
207 | void LLFloaterOpenObject::onClickMoveAndWear(void* data) | 207 | void LLFloaterOpenObject::onClickMoveAndWear(void* data) |
208 | { | 208 | { |
209 | LLFloaterOpenObject* self = (LLFloaterOpenObject*)data; | 209 | LLFloaterOpenObject* self = (LLFloaterOpenObject*)data; |
210 | self->moveToInventory(true); | 210 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Deprecated: RLVa-0.2.2a |
211 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment()) ) | ||
212 | { | ||
213 | // TODO-RLVa: once we have "Add to Outfit" and "Replace Outfit" working we don't need this anymore | ||
214 | self->moveToInventory(false); | ||
215 | } | ||
216 | else | ||
217 | { | ||
218 | self->moveToInventory(true); | ||
219 | } | ||
220 | // [/RLVa:KB] | ||
221 | // self->moveToInventory(true); | ||
211 | self->close(); | 222 | self->close(); |
212 | } | 223 | } |
213 | 224 | ||
diff --git a/linden/indra/newview/llfloaterproperties.cpp b/linden/indra/newview/llfloaterproperties.cpp index eddd56a..0af8ec3 100644 --- a/linden/indra/newview/llfloaterproperties.cpp +++ b/linden/indra/newview/llfloaterproperties.cpp | |||
@@ -354,8 +354,17 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) | |||
354 | else | 354 | else |
355 | { | 355 | { |
356 | gCacheName->getFullName(perm.getOwner(), name); | 356 | gCacheName->getFullName(perm.getOwner(), name); |
357 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
358 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
359 | { | ||
360 | name = gRlvHandler.getAnonym(name); | ||
361 | } | ||
362 | // [/RLVa:KB] | ||
357 | } | 363 | } |
358 | childSetEnabled("BtnOwner",TRUE); | 364 | //childSetEnabled("BtnOwner",TRUE); |
365 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-1.0.0e | ||
366 | childSetEnabled("BtnOwner", !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)); | ||
367 | // [/RLVa:KB] | ||
359 | childSetEnabled("LabelOwnerTitle",TRUE); | 368 | childSetEnabled("LabelOwnerTitle",TRUE); |
360 | childSetEnabled("LabelOwnerName",TRUE); | 369 | childSetEnabled("LabelOwnerName",TRUE); |
361 | childSetText("LabelOwnerName",name); | 370 | childSetText("LabelOwnerName",name); |
@@ -602,7 +611,10 @@ void LLFloaterProperties::onClickOwner(void* data) | |||
602 | } | 611 | } |
603 | else | 612 | else |
604 | { | 613 | { |
605 | if(!item->getPermissions().getOwner().isNull()) | 614 | // if(!item->getPermissions().getOwner().isNull()) |
615 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
616 | if ( (!item->getPermissions().getOwner().isNull()) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ) | ||
617 | // [/RLVa:KB] | ||
606 | { | 618 | { |
607 | LLFloaterAvatarInfo::showFromObject(item->getPermissions().getOwner()); | 619 | LLFloaterAvatarInfo::showFromObject(item->getPermissions().getOwner()); |
608 | } | 620 | } |
diff --git a/linden/indra/newview/llfloaterregioninfo.cpp b/linden/indra/newview/llfloaterregioninfo.cpp index 6e0dba1..40907eb 100644 --- a/linden/indra/newview/llfloaterregioninfo.cpp +++ b/linden/indra/newview/llfloaterregioninfo.cpp | |||
@@ -3192,3 +3192,22 @@ bool LLDispatchSetEstateAccess::operator()( | |||
3192 | 3192 | ||
3193 | return true; | 3193 | return true; |
3194 | } | 3194 | } |
3195 | |||
3196 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
3197 | void LLFloaterRegionInfo::open() | ||
3198 | { | ||
3199 | // We'll allow access to the estate tools for estate managers (and for the sim owner) | ||
3200 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
3201 | { | ||
3202 | LLViewerRegion* pRegion = gAgent.getRegion(); | ||
3203 | if (!pRegion) | ||
3204 | return; | ||
3205 | |||
3206 | // Should be able to call LLRegion::canManageEstate() but then we can fake god like | ||
3207 | if ( (!pRegion->isEstateManager()) && (pRegion->getOwner() != gAgent.getID()) ) | ||
3208 | return; | ||
3209 | } | ||
3210 | |||
3211 | LLFloater::open(); | ||
3212 | } | ||
3213 | // [/RLVa:KB] | ||
diff --git a/linden/indra/newview/llfloaterregioninfo.h b/linden/indra/newview/llfloaterregioninfo.h index 41a94ce..7b675de 100644 --- a/linden/indra/newview/llfloaterregioninfo.h +++ b/linden/indra/newview/llfloaterregioninfo.h | |||
@@ -66,6 +66,9 @@ public: | |||
66 | 66 | ||
67 | /*virtual*/ void onOpen(); | 67 | /*virtual*/ void onOpen(); |
68 | /*virtual*/ BOOL postBuild(); | 68 | /*virtual*/ BOOL postBuild(); |
69 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
70 | /*virtual*/ void open(); | ||
71 | // [/RLVa:KB] | ||
69 | 72 | ||
70 | static void processEstateOwnerRequest(LLMessageSystem* msg, void**); | 73 | static void processEstateOwnerRequest(LLMessageSystem* msg, void**); |
71 | 74 | ||
diff --git a/linden/indra/newview/llfloaterreporter.cpp b/linden/indra/newview/llfloaterreporter.cpp index d2fcf01..0d3b101 100644 --- a/linden/indra/newview/llfloaterreporter.cpp +++ b/linden/indra/newview/llfloaterreporter.cpp | |||
@@ -132,6 +132,23 @@ LLFloaterReporter::LLFloaterReporter( | |||
132 | 132 | ||
133 | childSetText("abuse_location_edit", gAgent.getSLURL() ); | 133 | childSetText("abuse_location_edit", gAgent.getSLURL() ); |
134 | 134 | ||
135 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-1.0.0a | ||
136 | if (rlv_handler_t::isEnabled()) | ||
137 | { | ||
138 | // Can't filter these since they get sent as part of the report so just hide them instead | ||
139 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
140 | { | ||
141 | childSetVisible("abuse_location_edit", false); | ||
142 | childSetVisible("pos_field", false); | ||
143 | } | ||
144 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
145 | { | ||
146 | childSetVisible("owner_name", false); | ||
147 | childSetVisible("abuser_name_edit", false); | ||
148 | } | ||
149 | } | ||
150 | // [/RLVa:KB] | ||
151 | |||
135 | LLButton* pick_btn = getChild<LLButton>("pick_btn"); | 152 | LLButton* pick_btn = getChild<LLButton>("pick_btn"); |
136 | if (pick_btn) | 153 | if (pick_btn) |
137 | { | 154 | { |
@@ -299,6 +316,12 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id) | |||
299 | if (regionp) | 316 | if (regionp) |
300 | { | 317 | { |
301 | childSetText("sim_field", regionp->getName()); | 318 | childSetText("sim_field", regionp->getName()); |
319 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
320 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) | ||
321 | { | ||
322 | childSetText("sim_field", rlv_handler_t::cstrHiddenRegion); | ||
323 | } | ||
324 | // [/RLVa:KB] | ||
302 | LLVector3d global_pos; | 325 | LLVector3d global_pos; |
303 | global_pos.setVec(objectp->getPositionRegion()); | 326 | global_pos.setVec(objectp->getPositionRegion()); |
304 | setPosBox(global_pos); | 327 | setPosBox(global_pos); |
@@ -322,6 +345,12 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id) | |||
322 | object_owner.append("Unknown"); | 345 | object_owner.append("Unknown"); |
323 | } | 346 | } |
324 | childSetText("object_name", object_owner); | 347 | childSetText("object_name", object_owner); |
348 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RVLa-1.0.0e | ||
349 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
350 | { | ||
351 | childSetVisible("object_name", false); // Hide the object name if the picked object represents an avataz | ||
352 | } | ||
353 | // [/RLVa:KB] | ||
325 | childSetText("owner_name", object_owner); | 354 | childSetText("owner_name", object_owner); |
326 | childSetText("abuser_name_edit", object_owner); | 355 | childSetText("abuser_name_edit", object_owner); |
327 | mAbuserID = object_id; | 356 | mAbuserID = object_id; |
@@ -594,6 +623,12 @@ LLFloaterReporter* LLFloaterReporter::createNewBugReporter() | |||
594 | void LLFloaterReporter::setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id) | 623 | void LLFloaterReporter::setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id) |
595 | { | 624 | { |
596 | childSetText("object_name", object_name); | 625 | childSetText("object_name", object_name); |
626 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RVLa-1.0.0e | ||
627 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
628 | { | ||
629 | childSetVisible("object_name", true); // Show the object name if the picked object is actually an object | ||
630 | } | ||
631 | // [/RLVa:KB] | ||
597 | childSetText("owner_name", owner_name); | 632 | childSetText("owner_name", owner_name); |
598 | childSetText("abuser_name_edit", owner_name); | 633 | childSetText("abuser_name_edit", owner_name); |
599 | mAbuserID = owner_id; | 634 | mAbuserID = owner_id; |
diff --git a/linden/indra/newview/llfloatersettingsdebug.cpp b/linden/indra/newview/llfloatersettingsdebug.cpp index e440c4a..58f37c5 100644 --- a/linden/indra/newview/llfloatersettingsdebug.cpp +++ b/linden/indra/newview/llfloatersettingsdebug.cpp | |||
@@ -39,6 +39,11 @@ | |||
39 | #include "llcolorswatch.h" | 39 | #include "llcolorswatch.h" |
40 | #include "llviewercontrol.h" | 40 | #include "llviewercontrol.h" |
41 | 41 | ||
42 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0g) | ||
43 | #include "rlvhandler.h" | ||
44 | #include "rlvextensions.h" | ||
45 | // [/RLVa:KB] | ||
46 | |||
42 | LLFloaterSettingsDebug* LLFloaterSettingsDebug::sInstance = NULL; | 47 | LLFloaterSettingsDebug* LLFloaterSettingsDebug::sInstance = NULL; |
43 | 48 | ||
44 | LLFloaterSettingsDebug::LLFloaterSettingsDebug() : LLFloater(std::string("Configuration Editor")) | 49 | LLFloaterSettingsDebug::LLFloaterSettingsDebug() : LLFloater(std::string("Configuration Editor")) |
@@ -239,6 +244,32 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp) | |||
239 | 244 | ||
240 | if (controlp) | 245 | if (controlp) |
241 | { | 246 | { |
247 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.1d | ||
248 | if (rlv_handler_t::isEnabled()) | ||
249 | { | ||
250 | // Don't allow changing DBG_WRITE debug settings under @setdebug=n | ||
251 | bool fEnable = !( (gRlvHandler.hasBehaviour(RLV_BHVR_SETDEBUG)) && | ||
252 | (RlvExtGetSet::getDebugSettingFlags(controlp->getName()) & RlvExtGetSet::DBG_WRITE) ); | ||
253 | // Don't allow toggling "Basic Shaders" and/or "Atmopsheric Shaders" through the debug settings under @setenv=n | ||
254 | fEnable &= !((gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)) && | ||
255 | (("VertexShaderEnable" == controlp->getName()) || ("WindLightUseAtmosShaders" == controlp->getName()))); | ||
256 | #ifdef RLV_EXTENSION_STARTLOCATION | ||
257 | // Don't allow toggling RestrainedLifeLoginLastLocation | ||
258 | fEnable &= !(RLV_SETTING_LOGINLASTLOCATION == controlp->getName()); | ||
259 | #endif // RLV_EXTENSION_STARTLOCATION | ||
260 | |||
261 | // NOTE: this runs per-frame so there's no need to explictly handle onCommitSettings() or onClickDefault() | ||
262 | spinner1->setEnabled(fEnable); | ||
263 | spinner2->setEnabled(fEnable); | ||
264 | spinner3->setEnabled(fEnable); | ||
265 | spinner4->setEnabled(fEnable); | ||
266 | color_swatch->setEnabled(fEnable); | ||
267 | childSetEnabled("val_text", fEnable); | ||
268 | childSetEnabled("boolean_combo", fEnable); | ||
269 | childSetEnabled("default_btn", fEnable); | ||
270 | } | ||
271 | // [/RLVa:KB] | ||
272 | |||
242 | eControlType type = controlp->type(); | 273 | eControlType type = controlp->type(); |
243 | 274 | ||
244 | //hide combo box only for non booleans, otherwise this will result in the combo box closing every frame | 275 | //hide combo box only for non booleans, otherwise this will result in the combo box closing every frame |
diff --git a/linden/indra/newview/llfloaterwindlight.cpp b/linden/indra/newview/llfloaterwindlight.cpp index 914513b..9936f3b 100644 --- a/linden/indra/newview/llfloaterwindlight.cpp +++ b/linden/indra/newview/llfloaterwindlight.cpp | |||
@@ -322,12 +322,14 @@ void LLFloaterWindLight::syncMenu() | |||
322 | LLWLParamSet& currentParams = param_mgr->mCurParams; | 322 | LLWLParamSet& currentParams = param_mgr->mCurParams; |
323 | //std::map<std::string, LLVector4> & currentParams = param_mgr->mCurParams.mParamValues; | 323 | //std::map<std::string, LLVector4> & currentParams = param_mgr->mCurParams.mParamValues; |
324 | 324 | ||
325 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
325 | // Fixes LL "bug" (preset name isn't kept synchronized) | 326 | // Fixes LL "bug" (preset name isn't kept synchronized) |
326 | LLComboBox* comboBox = getChild<LLComboBox>("WLPresetsCombo"); | 327 | LLComboBox* comboBox = getChild<LLComboBox>("WLPresetsCombo"); |
327 | if (comboBox->getSelectedItemLabel() != currentParams.mName) | 328 | if (comboBox->getSelectedItemLabel() != currentParams.mName) |
328 | { | 329 | { |
329 | comboBox->setSimple(currentParams.mName); | 330 | comboBox->setSimple(currentParams.mName); |
330 | } | 331 | } |
332 | // [/RLVa:KB] | ||
331 | 333 | ||
332 | // blue horizon | 334 | // blue horizon |
333 | param_mgr->mBlueHorizon = currentParams.getVector(param_mgr->mBlueHorizon.mName, err); | 335 | param_mgr->mBlueHorizon = currentParams.getVector(param_mgr->mBlueHorizon.mName, err); |
diff --git a/linden/indra/newview/llfloaterworldmap.cpp b/linden/indra/newview/llfloaterworldmap.cpp index bc61d8a..a31dde5 100644 --- a/linden/indra/newview/llfloaterworldmap.cpp +++ b/linden/indra/newview/llfloaterworldmap.cpp | |||
@@ -280,6 +280,13 @@ void LLFloaterWorldMap::onClose(bool app_quitting) | |||
280 | // static | 280 | // static |
281 | void LLFloaterWorldMap::show(void*, BOOL center_on_target) | 281 | void LLFloaterWorldMap::show(void*, BOOL center_on_target) |
282 | { | 282 | { |
283 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0c) | ||
284 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWWORLDMAP)) | ||
285 | { | ||
286 | return; | ||
287 | } | ||
288 | // [/RLVa:KB] | ||
289 | |||
283 | BOOL was_visible = gFloaterWorldMap->getVisible(); | 290 | BOOL was_visible = gFloaterWorldMap->getVisible(); |
284 | 291 | ||
285 | gFloaterWorldMap->mIsClosing = FALSE; | 292 | gFloaterWorldMap->mIsClosing = FALSE; |
@@ -641,7 +648,10 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global) | |||
641 | F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS ); | 648 | F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS ); |
642 | F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS ); | 649 | F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS ); |
643 | std::string full_name = llformat("%s (%d, %d, %d)", | 650 | std::string full_name = llformat("%s (%d, %d, %d)", |
644 | sim_name.c_str(), | 651 | // sim_name.c_str(), |
652 | // [RLVa:KB] - Alternate: Snowglobe-1.0 | Checked: 2009-07-04 (RLVa-1.0.0a) | ||
653 | (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? sim_name.c_str() : rlv_handler_t::cstrHiddenRegion.c_str(), | ||
654 | // [/RLVa:KB] | ||
645 | llround(region_x), | 655 | llround(region_x), |
646 | llround(region_y), | 656 | llround(region_y), |
647 | llround((F32)pos_global.mdV[VZ])); | 657 | llround((F32)pos_global.mdV[VZ])); |
@@ -695,6 +705,14 @@ void LLFloaterWorldMap::updateLocation() | |||
695 | 705 | ||
696 | // Set the current SLURL | 706 | // Set the current SLURL |
697 | mSLURL = LLURLDispatcher::buildSLURL(agent_sim_name, agent_x, agent_y, agent_z); | 707 | mSLURL = LLURLDispatcher::buildSLURL(agent_sim_name, agent_x, agent_y, agent_z); |
708 | |||
709 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
710 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
711 | { | ||
712 | childSetValue("location", rlv_handler_t::cstrHiddenRegion); | ||
713 | mSLURL.clear(); | ||
714 | } | ||
715 | // [/RLVa:KB] | ||
698 | } | 716 | } |
699 | } | 717 | } |
700 | 718 | ||
@@ -737,6 +755,14 @@ void LLFloaterWorldMap::updateLocation() | |||
737 | { // Empty SLURL will disable the "Copy SLURL to clipboard" button | 755 | { // Empty SLURL will disable the "Copy SLURL to clipboard" button |
738 | mSLURL = ""; | 756 | mSLURL = ""; |
739 | } | 757 | } |
758 | |||
759 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
760 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
761 | { | ||
762 | childSetValue("location", rlv_handler_t::cstrHiddenRegion); | ||
763 | mSLURL.clear(); | ||
764 | } | ||
765 | // [/RLVa:KB] | ||
740 | } | 766 | } |
741 | } | 767 | } |
742 | 768 | ||
diff --git a/linden/indra/newview/llglsandbox.cpp b/linden/indra/newview/llglsandbox.cpp index 2b51948..296cdaa 100644 --- a/linden/indra/newview/llglsandbox.cpp +++ b/linden/indra/newview/llglsandbox.cpp | |||
@@ -166,6 +166,13 @@ extern BOOL gDebugSelect; | |||
166 | // Returns true if you got at least one object | 166 | // Returns true if you got at least one object |
167 | void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) | 167 | void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) |
168 | { | 168 | { |
169 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0b) | ||
170 | if (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) | ||
171 | { | ||
172 | return; | ||
173 | } | ||
174 | // [/RLVa:KB] | ||
175 | |||
169 | LLVector3 av_pos = gAgent.getPositionAgent(); | 176 | LLVector3 av_pos = gAgent.getPositionAgent(); |
170 | F32 select_dist_squared = gSavedSettings.getF32("MaxSelectDistance"); | 177 | F32 select_dist_squared = gSavedSettings.getF32("MaxSelectDistance"); |
171 | select_dist_squared = select_dist_squared * select_dist_squared; | 178 | select_dist_squared = select_dist_squared * select_dist_squared; |
@@ -230,6 +237,27 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) | |||
230 | LLViewerCamera::getInstance()->setFar(new_far); | 237 | LLViewerCamera::getInstance()->setFar(new_far); |
231 | LLViewerCamera::getInstance()->setNear(new_near); | 238 | LLViewerCamera::getInstance()->setNear(new_near); |
232 | } | 239 | } |
240 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
241 | if (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) | ||
242 | { | ||
243 | // We'll allow drag selection under fartouch, but only within the fartouch range | ||
244 | // (just copy/paste the code above us to make that work, thank you Lindens!) | ||
245 | LLVector3 relative_av_pos = av_pos; | ||
246 | relative_av_pos -= LLViewerCamera::getInstance()->getOrigin(); | ||
247 | |||
248 | F32 new_far = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() + 1.5f; | ||
249 | F32 new_near = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() - 1.5f; | ||
250 | |||
251 | new_near = llmax(new_near, 0.1f); | ||
252 | |||
253 | LLViewerCamera::getInstance()->setFar(new_far); | ||
254 | LLViewerCamera::getInstance()->setNear(new_near); | ||
255 | |||
256 | // Usurp these two | ||
257 | limit_select_distance = TRUE; | ||
258 | select_dist_squared = 1.5f * 1.5f; | ||
259 | } | ||
260 | // [/RLVa:KB] | ||
233 | LLViewerCamera::getInstance()->setPerspective(FOR_SELECTION, | 261 | LLViewerCamera::getInstance()->setPerspective(FOR_SELECTION, |
234 | center_x-width/2, center_y-height/2, width, height, | 262 | center_x-width/2, center_y-height/2, width, height, |
235 | limit_select_distance); | 263 | limit_select_distance); |
diff --git a/linden/indra/newview/llhoverview.cpp b/linden/indra/newview/llhoverview.cpp index 8d033b2..e40ae10 100644 --- a/linden/indra/newview/llhoverview.cpp +++ b/linden/indra/newview/llhoverview.cpp | |||
@@ -244,14 +244,25 @@ void LLHoverView::updateText() | |||
244 | LLNameValue* lastname = hit_object->getNVPair("LastName"); | 244 | LLNameValue* lastname = hit_object->getNVPair("LastName"); |
245 | if (firstname && lastname) | 245 | if (firstname && lastname) |
246 | { | 246 | { |
247 | if (title) | 247 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) |
248 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
248 | { | 249 | { |
249 | line.append(title->getString()); | 250 | line = gRlvHandler.getAnonym(line.append(firstname->getString()).append(1, ' ').append(lastname->getString())); |
251 | } | ||
252 | else | ||
253 | { | ||
254 | // [/RLVa:KB] | ||
255 | if (title) | ||
256 | { | ||
257 | line.append(title->getString()); | ||
258 | line.append(1, ' '); | ||
259 | } | ||
260 | line.append(firstname->getString()); | ||
250 | line.append(1, ' '); | 261 | line.append(1, ' '); |
262 | line.append(lastname->getString()); | ||
263 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
251 | } | 264 | } |
252 | line.append(firstname->getString()); | 265 | // [/RLVa:KB] |
253 | line.append(1, ' '); | ||
254 | line.append(lastname->getString()); | ||
255 | } | 266 | } |
256 | else | 267 | else |
257 | { | 268 | { |
@@ -307,6 +318,13 @@ void LLHoverView::updateText() | |||
307 | } | 318 | } |
308 | else if(gCacheName->getFullName(owner, name)) | 319 | else if(gCacheName->getFullName(owner, name)) |
309 | { | 320 | { |
321 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
322 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
323 | { | ||
324 | name = gRlvHandler.getAnonym(name); | ||
325 | } | ||
326 | // [/RLVa:KB] | ||
327 | |||
310 | line.append(name); | 328 | line.append(name); |
311 | } | 329 | } |
312 | else | 330 | else |
@@ -468,7 +486,10 @@ void LLHoverView::updateText() | |||
468 | line.append(LLTrans::getString("TooltipLand")); | 486 | line.append(LLTrans::getString("TooltipLand")); |
469 | if (hover_parcel) | 487 | if (hover_parcel) |
470 | { | 488 | { |
471 | line.append(hover_parcel->getName()); | 489 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | Added: RLVa-0.2.0b |
490 | line.append( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? hover_parcel->getName() : rlv_handler_t::cstrHiddenParcel ); | ||
491 | // [/RLVa:KB] | ||
492 | //line.append(hover_parcel->getName()); | ||
472 | } | 493 | } |
473 | mText.push_back(line); | 494 | mText.push_back(line); |
474 | 495 | ||
@@ -497,7 +518,10 @@ void LLHoverView::updateText() | |||
497 | } | 518 | } |
498 | else if(gCacheName->getFullName(owner, name)) | 519 | else if(gCacheName->getFullName(owner, name)) |
499 | { | 520 | { |
500 | line.append(name); | 521 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.0b |
522 | line.append( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? name : gRlvHandler.getAnonym(name)); | ||
523 | // [/RLVa:KB] | ||
524 | //line.append(name); | ||
501 | } | 525 | } |
502 | else | 526 | else |
503 | { | 527 | { |
diff --git a/linden/indra/newview/llhudtext.cpp b/linden/indra/newview/llhudtext.cpp index 32323dc..ac48c6b 100644 --- a/linden/indra/newview/llhudtext.cpp +++ b/linden/indra/newview/llhudtext.cpp | |||
@@ -565,6 +565,30 @@ void LLHUDText::renderText(BOOL for_select) | |||
565 | 565 | ||
566 | void LLHUDText::setStringUTF8(const std::string &wtext) | 566 | void LLHUDText::setStringUTF8(const std::string &wtext) |
567 | { | 567 | { |
568 | // [RLVa:KB] - Checked: 2009-07-09 (RLVa-1.0.0f) | ||
569 | // NOTE: setString() is only called for debug beacons and the floating name tags (which we don't want to censor | ||
570 | // because you'd see "(Region hidden) LastName" if you happen to go to a sim who's name is your first name :p | ||
571 | if (rlv_handler_t::isEnabled()) | ||
572 | { | ||
573 | std::string text(wtext); | ||
574 | |||
575 | if (gRlvHandler.canShowHoverText(mSourceObject)) | ||
576 | { | ||
577 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
578 | gRlvHandler.filterLocation(text); | ||
579 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
580 | gRlvHandler.filterNames(text); | ||
581 | } | ||
582 | else | ||
583 | { | ||
584 | text = ""; | ||
585 | } | ||
586 | |||
587 | setString(utf8str_to_wstring(text)); | ||
588 | return; | ||
589 | } | ||
590 | // [/RLVa:KB] | ||
591 | |||
568 | setString(utf8str_to_wstring(wtext)); | 592 | setString(utf8str_to_wstring(wtext)); |
569 | } | 593 | } |
570 | 594 | ||
@@ -1147,3 +1171,18 @@ F32 LLHUDText::LLHUDTextSegment::getWidth(const LLFontGL* font) | |||
1147 | return width; | 1171 | return width; |
1148 | } | 1172 | } |
1149 | } | 1173 | } |
1174 | |||
1175 | // [RLVa:KB] - Checked: 2009-07-09 (RLVa-1.0.0f) | Added: RLVa-1.0.0f | ||
1176 | void LLHUDText::refreshAllObjectText() | ||
1177 | { | ||
1178 | for (TextObjectIterator itText = sTextObjects.begin(); itText != sTextObjects.end(); itText++) | ||
1179 | { | ||
1180 | LLHUDText* pText = *itText; | ||
1181 | if ( (pText) && (!pText->mObjText.empty() && ("" != pText->mObjText) ) && | ||
1182 | (pText->mSourceObject) && (LL_PCODE_VOLUME == pText->mSourceObject->getPCode()) ) | ||
1183 | { | ||
1184 | pText->setStringUTF8(pText->mObjText); | ||
1185 | } | ||
1186 | } | ||
1187 | } | ||
1188 | // [/RLVa:KB] | ||
diff --git a/linden/indra/newview/llhudtext.h b/linden/indra/newview/llhudtext.h index 6e29d9d..c68a975 100644 --- a/linden/indra/newview/llhudtext.h +++ b/linden/indra/newview/llhudtext.h | |||
@@ -130,6 +130,11 @@ public: | |||
130 | static void addPickable(std::set<LLViewerObject*> &pick_list); | 130 | static void addPickable(std::set<LLViewerObject*> &pick_list); |
131 | static void reshape(); | 131 | static void reshape(); |
132 | static void setDisplayText(BOOL flag) { sDisplayText = flag ; } | 132 | static void setDisplayText(BOOL flag) { sDisplayText = flag ; } |
133 | // [RLVa:KB] - Checked: 2009-07-09 (RLVa-1.0.0f) | Added: RLVa-1.0.0f | ||
134 | const std::string& getObjectText() const { return mObjText; } | ||
135 | void setObjectText(const std::string &utf8string) { mObjText = utf8string; } | ||
136 | static void refreshAllObjectText(); | ||
137 | // [/RLVa:KB] | ||
133 | protected: | 138 | protected: |
134 | LLHUDText(const U8 type); | 139 | LLHUDText(const U8 type); |
135 | 140 | ||
@@ -175,6 +180,9 @@ private: | |||
175 | EVertAlignment mVertAlignment; | 180 | EVertAlignment mVertAlignment; |
176 | S32 mLOD; | 181 | S32 mLOD; |
177 | BOOL mHidden; | 182 | BOOL mHidden; |
183 | // [RLVa:KB] - Checked: 2009-07-09 (RLVa-1.0.0f) | Added: RLVa-1.0.0f | ||
184 | std::string mObjText; | ||
185 | // [/RLVa:KB] | ||
178 | 186 | ||
179 | static BOOL sDisplayText ; | 187 | static BOOL sDisplayText ; |
180 | static std::set<LLPointer<LLHUDText> > sTextObjects; | 188 | static std::set<LLPointer<LLHUDText> > sTextObjects; |
diff --git a/linden/indra/newview/llimpanel.cpp b/linden/indra/newview/llimpanel.cpp index 16b0388..014c050 100644 --- a/linden/indra/newview/llimpanel.cpp +++ b/linden/indra/newview/llimpanel.cpp | |||
@@ -2009,6 +2009,42 @@ void LLFloaterIMPanel::sendMsg() | |||
2009 | std::string utf8_text = wstring_to_utf8str(text); | 2009 | std::string utf8_text = wstring_to_utf8str(text); |
2010 | utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1); | 2010 | utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1); |
2011 | 2011 | ||
2012 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-1.0.0g | ||
2013 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM)) | ||
2014 | { | ||
2015 | if (IM_NOTHING_SPECIAL == mDialog) // One-on-one IM: allow if recipient is a sendim exception | ||
2016 | { | ||
2017 | if (!gRlvHandler.isException(RLV_BHVR_SENDIM, mOtherParticipantUUID)) | ||
2018 | utf8_text = rlv_handler_t::cstrBlockedSendIM; | ||
2019 | } | ||
2020 | else if (gAgent.isInGroup(mSessionUUID)) // Group chat: allow if recipient is a sendim exception | ||
2021 | { | ||
2022 | if (!gRlvHandler.isException(RLV_BHVR_SENDIM, mSessionUUID)) | ||
2023 | utf8_text = rlv_handler_t::cstrBlockedSendIM; | ||
2024 | } | ||
2025 | else if (mSpeakers) // Conference chat: allow if all participants are sendim exceptions | ||
2026 | { | ||
2027 | LLSpeakerMgr::speaker_list_t speakers; | ||
2028 | mSpeakers->getSpeakerList(&speakers, TRUE); | ||
2029 | |||
2030 | for (LLSpeakerMgr::speaker_list_t::const_iterator itSpeaker = speakers.begin(); | ||
2031 | itSpeaker != speakers.end(); ++itSpeaker) | ||
2032 | { | ||
2033 | LLSpeaker* pSpeaker = *itSpeaker; | ||
2034 | if ( (gAgent.getID() != pSpeaker->mID) && (!gRlvHandler.isException(RLV_BHVR_SENDIM, pSpeaker->mID)) ) | ||
2035 | { | ||
2036 | utf8_text = rlv_handler_t::cstrBlockedSendIM; | ||
2037 | break; | ||
2038 | } | ||
2039 | } | ||
2040 | } | ||
2041 | else // Catch all fall-through | ||
2042 | { | ||
2043 | utf8_text = rlv_handler_t::cstrBlockedSendIM; | ||
2044 | } | ||
2045 | } | ||
2046 | // [/RLVa:KB] | ||
2047 | |||
2012 | if ( mSessionInitialized ) | 2048 | if ( mSessionInitialized ) |
2013 | { | 2049 | { |
2014 | deliver_message(utf8_text, | 2050 | deliver_message(utf8_text, |
diff --git a/linden/indra/newview/llimview.cpp b/linden/indra/newview/llimview.cpp index 1072b21..20de43e 100644 --- a/linden/indra/newview/llimview.cpp +++ b/linden/indra/newview/llimview.cpp | |||
@@ -1550,6 +1550,19 @@ public: | |||
1550 | { | 1550 | { |
1551 | return; | 1551 | return; |
1552 | } | 1552 | } |
1553 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
1554 | // TODO-RLVa: duplicate from process_improved_im()? | ||
1555 | if (gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM)) | ||
1556 | { | ||
1557 | if (gAgent.isInGroup(session_id)) | ||
1558 | { | ||
1559 | if (!gRlvHandler.isException(RLV_BHVR_RECVIM, session_id)) | ||
1560 | return; | ||
1561 | } | ||
1562 | else if (!gRlvHandler.isException(RLV_BHVR_RECVIM, from_id)) | ||
1563 | message = message.substr(0, message_offset) + rlv_handler_t::cstrBlockedRecvIM; | ||
1564 | } | ||
1565 | // [/RLVa:KB] | ||
1553 | 1566 | ||
1554 | // standard message, not from system | 1567 | // standard message, not from system |
1555 | std::string saved; | 1568 | std::string saved; |
diff --git a/linden/indra/newview/llinventorybridge.cpp b/linden/indra/newview/llinventorybridge.cpp index 3505bd3..19a5ade 100644 --- a/linden/indra/newview/llinventorybridge.cpp +++ b/linden/indra/newview/llinventorybridge.cpp | |||
@@ -1923,6 +1923,12 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) | |||
1923 | LLUUID trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH); | 1923 | LLUUID trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH); |
1924 | LLUUID lost_and_found_id = model->findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND); | 1924 | LLUUID lost_and_found_id = model->findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND); |
1925 | 1925 | ||
1926 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
1927 | // Fixes LL bug | ||
1928 | mItems.clear(); | ||
1929 | mDisabledItems.clear(); | ||
1930 | // [/RLVa:KB] | ||
1931 | |||
1926 | if (lost_and_found_id == mUUID) | 1932 | if (lost_and_found_id == mUUID) |
1927 | { | 1933 | { |
1928 | // This is the lost+found folder. | 1934 | // This is the lost+found folder. |
@@ -2936,6 +2942,13 @@ void open_notecard(LLViewerInventoryItem* inv_item, | |||
2936 | const LLUUID& source_id, | 2942 | const LLUUID& source_id, |
2937 | BOOL take_focus) | 2943 | BOOL take_focus) |
2938 | { | 2944 | { |
2945 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
2946 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour("viewnote")) ) | ||
2947 | { | ||
2948 | return; | ||
2949 | } | ||
2950 | // [/RLVa:KB] | ||
2951 | |||
2939 | // See if we can bring an existing preview to the front | 2952 | // See if we can bring an existing preview to the front |
2940 | if(!LLPreview::show(inv_item->getUUID(), take_focus)) | 2953 | if(!LLPreview::show(inv_item->getUUID(), take_focus)) |
2941 | { | 2954 | { |
@@ -3261,7 +3274,14 @@ void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model | |||
3261 | item = (LLViewerInventoryItem*)gInventory.getItem(object_id); | 3274 | item = (LLViewerInventoryItem*)gInventory.getItem(object_id); |
3262 | if(item && gInventory.isObjectDescendentOf(object_id, gAgent.getInventoryRootID())) | 3275 | if(item && gInventory.isObjectDescendentOf(object_id, gAgent.getInventoryRootID())) |
3263 | { | 3276 | { |
3264 | rez_attachment(item, NULL); | 3277 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) |
3278 | // User picked "Wear" so either nothing is locked, or we need to look up the specific attach point from its name | ||
3279 | // (NOTE: rez_attachment will take care of deciding whether or not we *can* attach) | ||
3280 | rez_attachment(item, | ||
3281 | ((!rlv_handler_t::isEnabled()) || (!gRlvHandler.hasLockedAttachment()) || (RlvSettings::getEnableWear())) | ||
3282 | ? NULL : gRlvHandler.getAttachPoint(item, true)); | ||
3283 | // [/RLVa:KB] | ||
3284 | // rez_attachment(item, NULL); | ||
3265 | } | 3285 | } |
3266 | else if(item && item->isComplete()) | 3286 | else if(item && item->isComplete()) |
3267 | { | 3287 | { |
@@ -3280,6 +3300,15 @@ void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model | |||
3280 | else if ("detach" == action) | 3300 | else if ("detach" == action) |
3281 | { | 3301 | { |
3282 | LLInventoryItem* item = gInventory.getItem(mUUID); | 3302 | LLInventoryItem* item = gInventory.getItem(mUUID); |
3303 | |||
3304 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
3305 | // Fall-through: if there's a "Detach from yourself" code path we missed then we'll still disallow the detach here | ||
3306 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isDetachable(item)) ) | ||
3307 | { | ||
3308 | return; | ||
3309 | } | ||
3310 | // [/RLVa:KB] | ||
3311 | |||
3283 | if( item ) | 3312 | if( item ) |
3284 | { | 3313 | { |
3285 | gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv); | 3314 | gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv); |
@@ -3369,11 +3398,24 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach | |||
3369 | rez_action->mAttachPt = attach_pt; | 3398 | rez_action->mAttachPt = attach_pt; |
3370 | if (attachment && attachment->getObject()) | 3399 | if (attachment && attachment->getObject()) |
3371 | { | 3400 | { |
3372 | gViewerWindow->alertXml("ReplaceAttachment", confirm_replace_attachment_rez, (void*)rez_action); | 3401 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-06 (RLVa-1.0.0c) |
3402 | if ( (!rlv_handler_t::isEnabled()) || (gRlvHandler.isDetachable(attach_pt)) ) | ||
3403 | gViewerWindow->alertXml("ReplaceAttachment", confirm_replace_attachment_rez, (void*)rez_action); | ||
3404 | else | ||
3405 | delete rez_action; | ||
3406 | // [/RLVa] | ||
3407 | // gViewerWindow->alertXml("ReplaceAttachment", confirm_replace_attachment_rez, (void*)rez_action); | ||
3373 | } | 3408 | } |
3374 | else | 3409 | else |
3375 | { | 3410 | { |
3376 | confirm_replace_attachment_rez(0/*YES*/, (void*)rez_action); | 3411 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-06 (RLVa-1.0.0c) |
3412 | // Don't allow wear to default attach point if there are any locked attachments | ||
3413 | if ( (!rlv_handler_t::isEnabled()) || (0 != attach_pt) || (!gRlvHandler.hasLockedAttachment()) || (RlvSettings::getEnableWear()) ) | ||
3414 | confirm_replace_attachment_rez(0/*YES*/, (void*)rez_action); | ||
3415 | else | ||
3416 | delete rez_action; | ||
3417 | // [/RLVa] | ||
3418 | // confirm_replace_attachment_rez(0/*YES*/, (void*)rez_action); | ||
3377 | } | 3419 | } |
3378 | } | 3420 | } |
3379 | 3421 | ||
@@ -3442,6 +3484,11 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) | |||
3442 | if( avatarp->isWearingAttachment( mUUID ) ) | 3484 | if( avatarp->isWearingAttachment( mUUID ) ) |
3443 | { | 3485 | { |
3444 | items.push_back(std::string("Detach From Yourself")); | 3486 | items.push_back(std::string("Detach From Yourself")); |
3487 | |||
3488 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
3489 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isDetachable(item)) ) | ||
3490 | disabled_items.push_back(std::string("Detach From Yourself")); | ||
3491 | // [/RLVa:KB] | ||
3445 | } | 3492 | } |
3446 | else | 3493 | else |
3447 | if( !isInTrash() ) | 3494 | if( !isInTrash() ) |
@@ -3453,6 +3500,16 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) | |||
3453 | items.push_back(std::string("RestoreToWorld Separator")); | 3500 | items.push_back(std::string("RestoreToWorld Separator")); |
3454 | items.push_back(std::string("Restore to Last Position")); | 3501 | items.push_back(std::string("Restore to Last Position")); |
3455 | 3502 | ||
3503 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-0.2.0c | ||
3504 | // Only enable "Wear" if there is an attach point name *and* there isn't a worn attachment there that's currently locked | ||
3505 | if ( (rlv_handler_t::isEnabled()) && (!RlvSettings::getEnableWear()) && (gRlvHandler.hasLockedAttachment()) ) | ||
3506 | { | ||
3507 | LLViewerJointAttachment* pAttachPt = gRlvHandler.getAttachPoint(item, true); | ||
3508 | if ( (!pAttachPt) || (!gRlvHandler.isDetachable(pAttachPt->getObject())) ) | ||
3509 | disabled_items.push_back(std::string("Object Wear")); | ||
3510 | } | ||
3511 | // [/RLVa:KB] | ||
3512 | |||
3456 | LLMenuGL* attach_menu = menu.getChildMenuByName("Attach To", TRUE); | 3513 | LLMenuGL* attach_menu = menu.getChildMenuByName("Attach To", TRUE); |
3457 | LLMenuGL* attach_hud_menu = menu.getChildMenuByName("Attach To HUD", TRUE); | 3514 | LLMenuGL* attach_hud_menu = menu.getChildMenuByName("Attach To HUD", TRUE); |
3458 | LLVOAvatar *avatarp = gAgent.getAvatarObject(); | 3515 | LLVOAvatar *avatarp = gAgent.getAvatarObject(); |
@@ -3468,15 +3525,27 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) | |||
3468 | LLMenuItemCallGL *new_item; | 3525 | LLMenuItemCallGL *new_item; |
3469 | if (attachment->getIsHUDAttachment()) | 3526 | if (attachment->getIsHUDAttachment()) |
3470 | { | 3527 | { |
3528 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
3471 | attach_hud_menu->append(new_item = new LLMenuItemCallGL(attachment->getName(), | 3529 | attach_hud_menu->append(new_item = new LLMenuItemCallGL(attachment->getName(), |
3472 | NULL, //&LLObjectBridge::attachToAvatar, | 3530 | NULL, //&LLObjectBridge::attachToAvatar, |
3473 | NULL, &attach_label, (void*)attachment)); | 3531 | (rlv_handler_t::isEnabled()) ? &rlvAttachToEnabler : NULL, |
3532 | &attach_label, (void*)attachment)); | ||
3533 | // [/RLVa:KB] | ||
3534 | //attach_hud_menu->append(new_item = new LLMenuItemCallGL(attachment->getName(), | ||
3535 | // NULL, //&LLObjectBridge::attachToAvatar, | ||
3536 | // NULL, &attach_label, (void*)attachment)); | ||
3474 | } | 3537 | } |
3475 | else | 3538 | else |
3476 | { | 3539 | { |
3540 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
3477 | attach_menu->append(new_item = new LLMenuItemCallGL(attachment->getName(), | 3541 | attach_menu->append(new_item = new LLMenuItemCallGL(attachment->getName(), |
3478 | NULL, //&LLObjectBridge::attachToAvatar, | 3542 | NULL, //&LLObjectBridge::attachToAvatar, |
3479 | NULL, &attach_label, (void*)attachment)); | 3543 | (rlv_handler_t::isEnabled()) ? &rlvAttachToEnabler : NULL, |
3544 | &attach_label, (void*)attachment)); | ||
3545 | // [/RLVa:KB] | ||
3546 | //attach_menu->append(new_item = new LLMenuItemCallGL(attachment->getName(), | ||
3547 | // NULL, //&LLObjectBridge::attachToAvatar, | ||
3548 | // NULL, &attach_label, (void*)attachment)); | ||
3480 | } | 3549 | } |
3481 | 3550 | ||
3482 | LLSimpleListener* callback = mInventoryPanel->getListenerByName("Inventory.AttachObject"); | 3551 | LLSimpleListener* callback = mInventoryPanel->getListenerByName("Inventory.AttachObject"); |
@@ -3981,6 +4050,20 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, void* userdata ) | |||
3981 | is_gesture); | 4050 | is_gesture); |
3982 | S32 gest_count = gest_item_array.count(); | 4051 | S32 gest_count = gest_item_array.count(); |
3983 | 4052 | ||
4053 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-1.0.0c | ||
4054 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment()) && (!RlvSettings::getEnableWear()) ) | ||
4055 | { | ||
4056 | // Filter anything that doesn't specify an attachment point (or that specifies one that's currently locked) | ||
4057 | for (S32 idxObj = obj_item_array.count() - 1; idxObj >= 0; idxObj--) | ||
4058 | { | ||
4059 | LLViewerJointAttachment* pAttachPt = gRlvHandler.getAttachPoint(obj_item_array.get(idxObj).get(), true); | ||
4060 | if ( ((!pAttachPt) || (!gRlvHandler.isDetachable(pAttachPt->getObject()))) ) | ||
4061 | obj_item_array.remove(idxObj); | ||
4062 | } | ||
4063 | obj_count = obj_item_array.count(); | ||
4064 | } | ||
4065 | // [/RLVa:KB] | ||
4066 | |||
3984 | if( !wearable_count && !obj_count && !gest_count) | 4067 | if( !wearable_count && !obj_count && !gest_count) |
3985 | { | 4068 | { |
3986 | gViewerWindow->alertXml("CouldNotPutOnOutfit"); | 4069 | gViewerWindow->alertXml("CouldNotPutOnOutfit"); |
@@ -4118,6 +4201,13 @@ void wear_inventory_category_on_avatar_step3(LLWearableHoldingPattern* holder, B | |||
4118 | // item->setAssetUUID(wearable->getID()); | 4201 | // item->setAssetUUID(wearable->getID()); |
4119 | // item->updateAssetOnServer(); | 4202 | // item->updateAssetOnServer(); |
4120 | // } | 4203 | // } |
4204 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-1.0.0c | ||
4205 | if ( (!gRlvHandler.isWearable(wearable->getType())) || | ||
4206 | ( (!gRlvHandler.isRemovable(wearable->getType())) && (gAgent.getWearable(wearable->getType())) ) ) | ||
4207 | { | ||
4208 | continue; | ||
4209 | } | ||
4210 | // [/RLVa:KB] | ||
4121 | items.put(item); | 4211 | items.put(item); |
4122 | wearables.put(wearable); | 4212 | wearables.put(wearable); |
4123 | } | 4213 | } |
@@ -4210,14 +4300,24 @@ void wear_attachments_on_avatar(const LLInventoryModel::item_array_t& items, BOO | |||
4210 | msg->nextBlockFast(_PREHASH_HeaderData); | 4300 | msg->nextBlockFast(_PREHASH_HeaderData); |
4211 | msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id ); | 4301 | msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id ); |
4212 | msg->addU8Fast(_PREHASH_TotalObjects, count ); | 4302 | msg->addU8Fast(_PREHASH_TotalObjects, count ); |
4213 | msg->addBOOLFast(_PREHASH_FirstDetachAll, remove ); | 4303 | // msg->addBOOLFast(_PREHASH_FirstDetachAll, remove ); |
4214 | } | 4304 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Added: RLVa-0.2.2a |
4305 | // This really should just *always* be FALSE since TRUE can result in loss of the current asset state | ||
4306 | msg->addBOOLFast(_PREHASH_FirstDetachAll, remove && (!gRlvHandler.hasLockedAttachment()) ); | ||
4307 | // [/RLVa:KB] | ||
4308 | } | ||
4215 | 4309 | ||
4216 | LLInventoryItem* item = items.get(i); | 4310 | LLInventoryItem* item = items.get(i); |
4217 | msg->nextBlockFast(_PREHASH_ObjectData ); | 4311 | msg->nextBlockFast(_PREHASH_ObjectData ); |
4218 | msg->addUUIDFast(_PREHASH_ItemID, item->getUUID() ); | 4312 | msg->addUUIDFast(_PREHASH_ItemID, item->getUUID() ); |
4219 | msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner()); | 4313 | msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner()); |
4220 | msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point | 4314 | // msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point |
4315 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Added: RLVa-0.2.2a | ||
4316 | msg->addU8Fast(_PREHASH_AttachmentPt, | ||
4317 | ( (!rlv_handler_t::isEnabled()) || (RlvSettings::getEnableWear()) || (!gRlvHandler.hasLockedAttachment()) ) | ||
4318 | ? 0 | ||
4319 | : gRlvHandler.getAttachPointIndex(gRlvHandler.getAttachPoint(item, true))); | ||
4320 | // [/RLVa:KB] | ||
4221 | pack_permissions_slam(msg, item->getFlags(), item->getPermissions()); | 4321 | pack_permissions_slam(msg, item->getFlags(), item->getPermissions()); |
4222 | msg->addStringFast(_PREHASH_Name, item->getName()); | 4322 | msg->addStringFast(_PREHASH_Name, item->getName()); |
4223 | msg->addStringFast(_PREHASH_Description, item->getDescription()); | 4323 | msg->addStringFast(_PREHASH_Description, item->getDescription()); |
@@ -4299,7 +4399,11 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata) | |||
4299 | { | 4399 | { |
4300 | for(i = 0; i < wearable_count; ++i) | 4400 | for(i = 0; i < wearable_count; ++i) |
4301 | { | 4401 | { |
4302 | if( gAgent.isWearingItem (item_array.get(i)->getUUID()) ) | 4402 | // if( gAgent.isWearingItem (item_array.get(i)->getUUID()) ) |
4403 | // [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) | Modified: RLVa-0.2.2a | ||
4404 | LLWearable* pWearable = gAgent.getWearableFromWearableItem(item_array.get(i)->getUUID()); | ||
4405 | if ( (pWearable) && ( (!rlv_handler_t::isEnabled()) || (gRlvHandler.isRemovable(pWearable->getType()))) ) | ||
4406 | // [/RLVa:KB] | ||
4303 | { | 4407 | { |
4304 | gWearableList.getAsset(item_array.get(i)->getAssetUUID(), | 4408 | gWearableList.getAsset(item_array.get(i)->getAssetUUID(), |
4305 | item_array.get(i)->getName(), | 4409 | item_array.get(i)->getName(), |
@@ -4316,6 +4420,18 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata) | |||
4316 | { | 4420 | { |
4317 | for(i = 0; i < obj_count; ++i) | 4421 | for(i = 0; i < obj_count; ++i) |
4318 | { | 4422 | { |
4423 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-0.2.2a | ||
4424 | // TODO-RLVa: is there a reason why LL doesn't bother checking to see if you're actually wearing the object? | ||
4425 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment()) ) | ||
4426 | { | ||
4427 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | ||
4428 | if ( (!pAvatar) || (!pAvatar->isWearingAttachment(obj_item_array.get(i)->getUUID())) || | ||
4429 | (!gRlvHandler.isDetachable(obj_item_array.get(i).get())) ) // Why does LLPointer have a cast to BOOL aka S32??? | ||
4430 | { | ||
4431 | continue; | ||
4432 | } | ||
4433 | } | ||
4434 | // [/RVLa:KB] | ||
4319 | gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv); | 4435 | gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv); |
4320 | gMessageSystem->nextBlockFast(_PREHASH_ObjectData ); | 4436 | gMessageSystem->nextBlockFast(_PREHASH_ObjectData ); |
4321 | gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); | 4437 | gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); |
@@ -4708,8 +4824,11 @@ void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable, | |||
4708 | { | 4824 | { |
4709 | EWearableType type = wearable->getType(); | 4825 | EWearableType type = wearable->getType(); |
4710 | 4826 | ||
4711 | if( !(type==WT_SHAPE || type==WT_SKIN || type==WT_HAIR ) ) //&& | 4827 | //if( !(type==WT_SHAPE || type==WT_SKIN || type==WT_HAIR ) ) //&& |
4712 | //!((!gAgent.isTeen()) && ( type==WT_UNDERPANTS || type==WT_UNDERSHIRT )) ) | 4828 | //!((!gAgent.isTeen()) && ( type==WT_UNDERPANTS || type==WT_UNDERSHIRT )) ) |
4829 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.2a | SL big fix | ||
4830 | if( !(type==WT_SHAPE || type==WT_SKIN || type==WT_HAIR || type==WT_EYES) ) | ||
4831 | // [/RLVa:KB] | ||
4713 | { | 4832 | { |
4714 | gAgent.removeWearable( type ); | 4833 | gAgent.removeWearable( type ); |
4715 | } | 4834 | } |
diff --git a/linden/indra/newview/llinventorymodel.cpp b/linden/indra/newview/llinventorymodel.cpp index 1029a3c..e662058 100644 --- a/linden/indra/newview/llinventorymodel.cpp +++ b/linden/indra/newview/llinventorymodel.cpp | |||
@@ -2876,6 +2876,14 @@ void LLInventoryModel::processSaveAssetIntoInventory(LLMessageSystem* msg, | |||
2876 | llinfos << "LLInventoryModel::processSaveAssetIntoInventory item" | 2876 | llinfos << "LLInventoryModel::processSaveAssetIntoInventory item" |
2877 | " not found: " << item_id << llendl; | 2877 | " not found: " << item_id << llendl; |
2878 | } | 2878 | } |
2879 | |||
2880 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-0.2.0e | ||
2881 | if (rlv_handler_t::isEnabled()) | ||
2882 | { | ||
2883 | gRlvHandler.onSavedAssetIntoInventory(item_id); | ||
2884 | } | ||
2885 | // [/RLVa:KB] | ||
2886 | |||
2879 | if(gViewerWindow) | 2887 | if(gViewerWindow) |
2880 | { | 2888 | { |
2881 | gViewerWindow->getWindow()->decBusyCount(); | 2889 | gViewerWindow->getWindow()->decBusyCount(); |
@@ -2918,6 +2926,23 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**) | |||
2918 | // << llendl; | 2926 | // << llendl; |
2919 | if(tfolder->getUUID().notNull()) | 2927 | if(tfolder->getUUID().notNull()) |
2920 | { | 2928 | { |
2929 | // [RLVa:KB] - Checked: 2009-08-07 (RLVa-1.0.1f) | Added: RLVa-1.0.0f | ||
2930 | // TODO-RLVa: this really shouldn't go here, but if the inventory offer spans multiple BulkUpdateInventory messages | ||
2931 | // then the second message will cause the viewer to show the folder under its original name even though | ||
2932 | // it is renamed properly on the inventory server | ||
2933 | if ( (rlv_handler_t::isEnabled()) && (!RlvSettings::getForbidGiveToRLV()) ) | ||
2934 | { | ||
2935 | LLViewerInventoryCategory* pRlvRoot = gRlvHandler.getSharedRoot(); | ||
2936 | std::string strName = tfolder->getName(); | ||
2937 | if ((pRlvRoot) && (pRlvRoot->getUUID() == tfolder->getParentUUID() ) && (strName.find(RLV_PUTINV_PREFIX) == 0)) | ||
2938 | { | ||
2939 | strName.erase(0, strName.find(RLV_FOLDER_PREFIX_PUTINV)); // Strips the prefix while retaining while the '~' | ||
2940 | tfolder->rename(strName); | ||
2941 | tfolder->updateServer(FALSE); | ||
2942 | } | ||
2943 | } | ||
2944 | // [/RLVa:KB] | ||
2945 | |||
2921 | folders.push_back(tfolder); | 2946 | folders.push_back(tfolder); |
2922 | LLViewerInventoryCategory* folderp = gInventory.getCategory(tfolder->getUUID()); | 2947 | LLViewerInventoryCategory* folderp = gInventory.getCategory(tfolder->getUUID()); |
2923 | if(folderp) | 2948 | if(folderp) |
diff --git a/linden/indra/newview/llinventoryview.cpp b/linden/indra/newview/llinventoryview.cpp index cc89ee1..a8d5045 100644 --- a/linden/indra/newview/llinventoryview.cpp +++ b/linden/indra/newview/llinventoryview.cpp | |||
@@ -774,7 +774,17 @@ void LLInventoryView::setVisible( BOOL visible ) | |||
774 | // Destroy all but the last floater, which is made invisible. | 774 | // Destroy all but the last floater, which is made invisible. |
775 | void LLInventoryView::onClose(bool app_quitting) | 775 | void LLInventoryView::onClose(bool app_quitting) |
776 | { | 776 | { |
777 | S32 count = sActiveViews.count(); | 777 | // S32 count = sActiveViews.count(); |
778 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
779 | // See LLInventoryView::closeAll() on why we're doing it this way | ||
780 | S32 count = 0; | ||
781 | for (S32 idx = 0, cnt = sActiveViews.count(); idx < cnt; idx++) | ||
782 | { | ||
783 | if (!sActiveViews.get(idx)->isDead()) | ||
784 | count++; | ||
785 | } | ||
786 | // [/RLVa:KB] | ||
787 | |||
778 | if (count > 1) | 788 | if (count > 1) |
779 | { | 789 | { |
780 | destroy(); | 790 | destroy(); |
@@ -852,6 +862,13 @@ LLInventoryView* LLInventoryView::showAgentInventory(BOOL take_keyboard_focus) | |||
852 | return NULL; | 862 | return NULL; |
853 | } | 863 | } |
854 | 864 | ||
865 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
866 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWINV)) | ||
867 | { | ||
868 | return NULL; | ||
869 | } | ||
870 | // [/RLVa:KB] | ||
871 | |||
855 | LLInventoryView* iv = LLInventoryView::getActiveInventory(); | 872 | LLInventoryView* iv = LLInventoryView::getActiveInventory(); |
856 | #if 0 && !LL_RELEASE_FOR_DOWNLOAD | 873 | #if 0 && !LL_RELEASE_FOR_DOWNLOAD |
857 | if (sActiveViews.count() == 1) | 874 | if (sActiveViews.count() == 1) |
diff --git a/linden/indra/newview/llinventoryview.h b/linden/indra/newview/llinventoryview.h index bdc24e0..1762165 100644 --- a/linden/indra/newview/llinventoryview.h +++ b/linden/indra/newview/llinventoryview.h | |||
@@ -225,6 +225,34 @@ public: | |||
225 | static void toggleVisibility(); | 225 | static void toggleVisibility(); |
226 | static void toggleVisibility(void*) { toggleVisibility(); } | 226 | static void toggleVisibility(void*) { toggleVisibility(); } |
227 | 227 | ||
228 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
229 | static void closeAll() | ||
230 | { | ||
231 | // If there are mulitple inventory floaters open then clicking the "Inventory" button will close | ||
232 | // them one by one (see LLToolBar::onClickInventory() => toggleVisibility() ) until we get to the | ||
233 | // last one which will just be hidden instead of closed/destroyed (see LLInventoryView::onClose) | ||
234 | // | ||
235 | // However the view isn't removed from sActiveViews until its destructor is called and since | ||
236 | // 'LLMortician::sDestroyImmediate == FALSE' while the viewer is running the destructor won't be | ||
237 | // called right away | ||
238 | // | ||
239 | // Result: we can't call close() on the last (sActiveViews.count() will still be > 1) because | ||
240 | // onClose() would take the wrong branch and destroy() it as well | ||
241 | // | ||
242 | // Workaround: "fix" onClose() to count only views that aren't marked as "dead" | ||
243 | |||
244 | LLInventoryView* pView; U8 flagsSound; | ||
245 | for (S32 idx = sActiveViews.count() - 1; idx >= 0; idx--) | ||
246 | { | ||
247 | pView = sActiveViews.get(idx); | ||
248 | flagsSound = pView->getSoundFlags(); | ||
249 | pView->setSoundFlags(LLView::SILENT); // Suppress the window close sound | ||
250 | pView->close(); // onClose() protects against closing the last inventory floater | ||
251 | pView->setSoundFlags(flagsSound); // One view won't be destroy()'ed so it needs its sound flags restored | ||
252 | } | ||
253 | } | ||
254 | // [/RLVa:KB] | ||
255 | |||
228 | // Final cleanup, destroy all open inventory views. | 256 | // Final cleanup, destroy all open inventory views. |
229 | static void cleanup(); | 257 | static void cleanup(); |
230 | 258 | ||
diff --git a/linden/indra/newview/llmaniptranslate.cpp b/linden/indra/newview/llmaniptranslate.cpp index fd02be6..fa66b05 100644 --- a/linden/indra/newview/llmaniptranslate.cpp +++ b/linden/indra/newview/llmaniptranslate.cpp | |||
@@ -463,8 +463,15 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) | |||
463 | if (mask == MASK_COPY) | 463 | if (mask == MASK_COPY) |
464 | { | 464 | { |
465 | // ...we're trying to make a copy | 465 | // ...we're trying to make a copy |
466 | LLSelectMgr::getInstance()->selectDuplicate(LLVector3::zero, FALSE); | 466 | // LLSelectMgr::getInstance()->selectDuplicate(LLVector3::zero, FALSE); |
467 | mCopyMadeThisDrag = TRUE; | 467 | // mCopyMadeThisDrag = TRUE; |
468 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | ||
469 | if (!gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) | ||
470 | { | ||
471 | LLSelectMgr::getInstance()->selectDuplicate(LLVector3::zero, FALSE); | ||
472 | mCopyMadeThisDrag = TRUE; | ||
473 | } | ||
474 | // [/RLVa:KB] | ||
468 | 475 | ||
469 | // When we make the copy, we don't want to do any other processing. | 476 | // When we make the copy, we don't want to do any other processing. |
470 | // If so, the object will also be moved, and the copy will be offset. | 477 | // If so, the object will also be moved, and the copy will be offset. |
diff --git a/linden/indra/newview/llnetmap.cpp b/linden/indra/newview/llnetmap.cpp index 6fa6745..8f5d90d 100644 --- a/linden/indra/newview/llnetmap.cpp +++ b/linden/indra/newview/llnetmap.cpp | |||
@@ -355,6 +355,16 @@ void LLNetMap::draw() | |||
355 | glyph_color = avatar_color; | 355 | glyph_color = avatar_color; |
356 | } | 356 | } |
357 | 357 | ||
358 | // [RLVa:KB] | ||
359 | if ( !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES) ) | ||
360 | { | ||
361 | // User is not allowed to see who it is, or even if it's a friend, | ||
362 | // due to RLV settings. | ||
363 | glyph_color = avatar_color; | ||
364 | } | ||
365 | // [/RLVa:KB] | ||
366 | |||
367 | |||
358 | LLWorldMapView::drawAvatar( | 368 | LLWorldMapView::drawAvatar( |
359 | pos_map.mV[VX], pos_map.mV[VY], | 369 | pos_map.mV[VX], pos_map.mV[VY], |
360 | glyph_color, | 370 | glyph_color, |
@@ -551,11 +561,33 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rec | |||
551 | std::string fullname; | 561 | std::string fullname; |
552 | if(mClosestAgentToCursor.notNull() && gCacheName->getFullName(mClosestAgentToCursor, fullname)) | 562 | if(mClosestAgentToCursor.notNull() && gCacheName->getFullName(mClosestAgentToCursor, fullname)) |
553 | { | 563 | { |
554 | msg.append(fullname); | 564 | // [RLVa:KB] |
555 | msg.append("\n"); | 565 | if ( !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES) ) |
566 | { | ||
567 | // User is not allowed to see who it is, due to RLV settings. | ||
568 | msg.append(rlv_handler_t::cstrHidden); | ||
569 | } | ||
570 | else | ||
571 | { | ||
572 | msg.append(fullname); | ||
573 | msg.append("\n"); | ||
574 | } | ||
575 | // [/RLVa:KB] | ||
556 | } | 576 | } |
557 | msg.append( region->getName() ); | ||
558 | 577 | ||
578 | // [RLVa:KB] | ||
579 | if (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
580 | { | ||
581 | // User is not allowed to see where they are, due to RLV settings. | ||
582 | msg.append( rlv_handler_t::cstrHidden ); | ||
583 | } | ||
584 | else | ||
585 | { | ||
586 | msg.append( region->getName() ); | ||
587 | } | ||
588 | // [/RLVa:KB] | ||
589 | |||
590 | |||
559 | msg.append("\n"); | 591 | msg.append("\n"); |
560 | gSavedSettings.getBOOL( "MiniMapTeleport" ) ? | 592 | gSavedSettings.getBOOL( "MiniMapTeleport" ) ? |
561 | msg.append(getString("tooltip_tp")) : msg.append(getString("tooltip_map")); | 593 | msg.append(getString("tooltip_tp")) : msg.append(getString("tooltip_map")); |
diff --git a/linden/indra/newview/llnotify.cpp b/linden/indra/newview/llnotify.cpp index 9e837a6..5590ab1 100644 --- a/linden/indra/newview/llnotify.cpp +++ b/linden/indra/newview/llnotify.cpp | |||
@@ -54,6 +54,10 @@ | |||
54 | #include "lloverlaybar.h" // for gOverlayBar | 54 | #include "lloverlaybar.h" // for gOverlayBar |
55 | #include "lluictrlfactory.h" | 55 | #include "lluictrlfactory.h" |
56 | 56 | ||
57 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-10 (RLVa-1.0.0e) | Added: RLVa-0.2.0b | ||
58 | #include "rlvhandler.h" | ||
59 | // [/RLVa:KB] | ||
60 | |||
57 | // Globals | 61 | // Globals |
58 | LLNotifyBoxView* gNotifyBoxView = NULL; | 62 | LLNotifyBoxView* gNotifyBoxView = NULL; |
59 | 63 | ||
@@ -328,6 +332,13 @@ LLNotifyBox::LLNotifyBox(LLPointer<LLNotifyBoxTemplate> xml_template, const LLSt | |||
328 | // TODO: Make a separate archive for these. | 332 | // TODO: Make a separate archive for these. |
329 | LLChat chat(mMessage); | 333 | LLChat chat(mMessage); |
330 | chat.mSourceType = CHAT_SOURCE_SYSTEM; | 334 | chat.mSourceType = CHAT_SOURCE_SYSTEM; |
335 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0e) | Added: RLVa-0.2.0b | ||
336 | if (rlv_handler_t::isEnabled()) | ||
337 | { | ||
338 | // Notices should already have their contents filtered where necessary | ||
339 | chat.mRlvLocFiltered = chat.mRlvNamesFiltered = TRUE; | ||
340 | } | ||
341 | // [/RLVa:KB] | ||
331 | LLFloaterChat::getInstance(LLSD())->addChatHistory(chat); | 342 | LLFloaterChat::getInstance(LLSD())->addChatHistory(chat); |
332 | } | 343 | } |
333 | else | 344 | else |
diff --git a/linden/indra/newview/lloverlaybar.cpp b/linden/indra/newview/lloverlaybar.cpp index 6b51b3a..12c001e 100644 --- a/linden/indra/newview/lloverlaybar.cpp +++ b/linden/indra/newview/lloverlaybar.cpp | |||
@@ -266,7 +266,10 @@ void LLOverlayBar::refresh() | |||
266 | BOOL sitting = FALSE; | 266 | BOOL sitting = FALSE; |
267 | if (gAgent.getAvatarObject()) | 267 | if (gAgent.getAvatarObject()) |
268 | { | 268 | { |
269 | sitting = gAgent.getAvatarObject()->mIsSitting; | 269 | // sitting = gAgent.getAvatarObject()->mIsSitting; |
270 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
271 | sitting = gAgent.getAvatarObject()->mIsSitting && !gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT); | ||
272 | // [/RLVa:KB] | ||
270 | } | 273 | } |
271 | button = getChild<LLButton>("Stand Up"); | 274 | button = getChild<LLButton>("Stand Up"); |
272 | 275 | ||
@@ -349,6 +352,13 @@ void LLOverlayBar::onClickMouselook(void*) | |||
349 | //static | 352 | //static |
350 | void LLOverlayBar::onClickStandUp(void*) | 353 | void LLOverlayBar::onClickStandUp(void*) |
351 | { | 354 | { |
355 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
356 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (gAgent.getAvatarObject()) && (gAgent.getAvatarObject()->mIsSitting) ) | ||
357 | { | ||
358 | return; | ||
359 | } | ||
360 | // [/RLVa:KB] | ||
361 | |||
352 | LLSelectMgr::getInstance()->deselectAllForStandingUp(); | 362 | LLSelectMgr::getInstance()->deselectAllForStandingUp(); |
353 | gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); | 363 | gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); |
354 | } | 364 | } |
diff --git a/linden/indra/newview/llpanelavatar.cpp b/linden/indra/newview/llpanelavatar.cpp index fa1883d..e101ea2 100644 --- a/linden/indra/newview/llpanelavatar.cpp +++ b/linden/indra/newview/llpanelavatar.cpp | |||
@@ -792,6 +792,9 @@ void LLPanelAvatarClassified::refresh() | |||
792 | S32 tab_count = tabs ? tabs->getTabCount() : 0; | 792 | S32 tab_count = tabs ? tabs->getTabCount() : 0; |
793 | 793 | ||
794 | bool allow_new = tab_count < MAX_CLASSIFIEDS; | 794 | bool allow_new = tab_count < MAX_CLASSIFIEDS; |
795 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
796 | allow_new &= !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC); | ||
797 | // [/RLVa:KB] | ||
795 | bool allow_delete = (tab_count > 0); | 798 | bool allow_delete = (tab_count > 0); |
796 | bool show_help = (tab_count == 0); | 799 | bool show_help = (tab_count == 0); |
797 | 800 | ||
@@ -927,6 +930,12 @@ void LLPanelAvatarClassified::processAvatarClassifiedReply(LLMessageSystem* msg, | |||
927 | // static | 930 | // static |
928 | void LLPanelAvatarClassified::onClickNew(void* data) | 931 | void LLPanelAvatarClassified::onClickNew(void* data) |
929 | { | 932 | { |
933 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-04 (RLVa-1.0.0a) | ||
934 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
935 | { | ||
936 | return; | ||
937 | } | ||
938 | // [/RLVa:KB] | ||
930 | LLPanelAvatarClassified* self = (LLPanelAvatarClassified*)data; | 939 | LLPanelAvatarClassified* self = (LLPanelAvatarClassified*)data; |
931 | 940 | ||
932 | gViewerWindow->alertXml("AddClassified",callbackNew,self); | 941 | gViewerWindow->alertXml("AddClassified",callbackNew,self); |
@@ -1023,7 +1032,10 @@ void LLPanelAvatarPicks::refresh() | |||
1023 | BOOL self = (gAgent.getID() == getPanelAvatar()->getAvatarID()); | 1032 | BOOL self = (gAgent.getID() == getPanelAvatar()->getAvatarID()); |
1024 | LLTabContainer* tabs = getChild<LLTabContainer>("picks tab"); | 1033 | LLTabContainer* tabs = getChild<LLTabContainer>("picks tab"); |
1025 | S32 tab_count = tabs ? tabs->getTabCount() : 0; | 1034 | S32 tab_count = tabs ? tabs->getTabCount() : 0; |
1026 | childSetEnabled("New...", self && tab_count < MAX_AVATAR_PICKS); | 1035 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) |
1036 | childSetEnabled("New...", self && tab_count < MAX_AVATAR_PICKS && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ); | ||
1037 | // [/RLVa:KB] | ||
1038 | //childSetEnabled("New...", self && tab_count < MAX_AVATAR_PICKS); | ||
1027 | childSetEnabled("Delete...", self && tab_count > 0); | 1039 | childSetEnabled("Delete...", self && tab_count > 0); |
1028 | childSetVisible("New...", self && getPanelAvatar()->isEditable()); | 1040 | childSetVisible("New...", self && getPanelAvatar()->isEditable()); |
1029 | childSetVisible("Delete...", self && getPanelAvatar()->isEditable()); | 1041 | childSetVisible("Delete...", self && getPanelAvatar()->isEditable()); |
@@ -1101,6 +1113,12 @@ void LLPanelAvatarPicks::processAvatarPicksReply(LLMessageSystem* msg, void**) | |||
1101 | // static | 1113 | // static |
1102 | void LLPanelAvatarPicks::onClickNew(void* data) | 1114 | void LLPanelAvatarPicks::onClickNew(void* data) |
1103 | { | 1115 | { |
1116 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
1117 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
1118 | { | ||
1119 | return; | ||
1120 | } | ||
1121 | // [/RLVa:KB] | ||
1104 | LLPanelAvatarPicks* self = (LLPanelAvatarPicks*)data; | 1122 | LLPanelAvatarPicks* self = (LLPanelAvatarPicks*)data; |
1105 | LLPanelPick* panel_pick = new LLPanelPick(FALSE); | 1123 | LLPanelPick* panel_pick = new LLPanelPick(FALSE); |
1106 | LLTabContainer* tabs = self->getChild<LLTabContainer>("picks tab"); | 1124 | LLTabContainer* tabs = self->getChild<LLTabContainer>("picks tab"); |
diff --git a/linden/indra/newview/llpanelclassified.cpp b/linden/indra/newview/llpanelclassified.cpp index 4d28be5..3760815 100644 --- a/linden/indra/newview/llpanelclassified.cpp +++ b/linden/indra/newview/llpanelclassified.cpp | |||
@@ -760,7 +760,10 @@ void LLPanelClassified::refresh() | |||
760 | mClickThroughText->setVisible(is_self); | 760 | mClickThroughText->setVisible(is_self); |
761 | 761 | ||
762 | mSetBtn->setVisible(is_self); | 762 | mSetBtn->setVisible(is_self); |
763 | mSetBtn->setEnabled(is_self); | 763 | //mSetBtn->setEnabled(is_self); |
764 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
765 | mSetBtn->setEnabled(is_self && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ); | ||
766 | // [/RLVa:KB] | ||
764 | 767 | ||
765 | mUpdateBtn->setEnabled(is_self && checkDirty()); | 768 | mUpdateBtn->setEnabled(is_self && checkDirty()); |
766 | mUpdateBtn->setVisible(is_self); | 769 | mUpdateBtn->setVisible(is_self); |
@@ -964,6 +967,12 @@ void LLPanelClassified::onClickLandmark(void* data) | |||
964 | // static | 967 | // static |
965 | void LLPanelClassified::onClickSet(void* data) | 968 | void LLPanelClassified::onClickSet(void* data) |
966 | { | 969 | { |
970 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
971 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
972 | { | ||
973 | return; | ||
974 | } | ||
975 | // [/RLVa:KB] | ||
967 | LLPanelClassified* self = (LLPanelClassified*)data; | 976 | LLPanelClassified* self = (LLPanelClassified*)data; |
968 | 977 | ||
969 | // Save location for later. | 978 | // Save location for later. |
diff --git a/linden/indra/newview/llpanelcontents.cpp b/linden/indra/newview/llpanelcontents.cpp index d91790e..e13ec46 100644 --- a/linden/indra/newview/llpanelcontents.cpp +++ b/linden/indra/newview/llpanelcontents.cpp | |||
@@ -66,6 +66,10 @@ | |||
66 | #include "lltoolcomp.h" | 66 | #include "lltoolcomp.h" |
67 | #include "llpanelinventory.h" | 67 | #include "llpanelinventory.h" |
68 | 68 | ||
69 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
70 | #include "llvoavatar.h" | ||
71 | // [/RLVa:KB] | ||
72 | |||
69 | // | 73 | // |
70 | // Imported globals | 74 | // Imported globals |
71 | // | 75 | // |
@@ -117,6 +121,24 @@ void LLPanelContents::getState(LLViewerObject *objectp ) | |||
117 | && ( objectp->permYouOwner() || ( !group_id.isNull() && gAgent.isInGroup(group_id) ))); // solves SL-23488 | 121 | && ( objectp->permYouOwner() || ( !group_id.isNull() && gAgent.isInGroup(group_id) ))); // solves SL-23488 |
118 | BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ); | 122 | BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ); |
119 | 123 | ||
124 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-0.2.0g | ||
125 | if ( (rlv_handler_t::isEnabled()) && (editable) ) | ||
126 | { | ||
127 | // Don't allow creation of new scripts if it's undetachable | ||
128 | editable = gRlvHandler.isDetachable(objectp); | ||
129 | |||
130 | // Don't allow creation of new scripts if we're @unsit=n or @sittp=n restricted and we're sitting on the selection | ||
131 | if ( (editable) && ((gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SITTP))) ) | ||
132 | { | ||
133 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | ||
134 | // Only check the first (non-)root object because nothing else would result in enabling the button (see below) | ||
135 | LLViewerObject* pObj = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(TRUE); | ||
136 | |||
137 | editable = (pObj) && (pAvatar) && ((!pAvatar->mIsSitting) || (pAvatar->getRoot() != pObj->getRootEdit())); | ||
138 | } | ||
139 | } | ||
140 | // [/RLVa:KB] | ||
141 | |||
120 | // Edit script button - ok if object is editable and there's an | 142 | // Edit script button - ok if object is editable and there's an |
121 | // unambiguous destination for the object. | 143 | // unambiguous destination for the object. |
122 | if( editable && | 144 | if( editable && |
@@ -160,6 +182,22 @@ void LLPanelContents::onClickNewScript(void *userdata) | |||
160 | LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(children_ok); | 182 | LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(children_ok); |
161 | if(object) | 183 | if(object) |
162 | { | 184 | { |
185 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
186 | if (rlv_handler_t::isEnabled()) // Fallback code [see LLPanelContents::getState()] | ||
187 | { | ||
188 | if (!gRlvHandler.isDetachable(object)) | ||
189 | { | ||
190 | return; // Disallow creating new scripts in a locked attachment | ||
191 | } | ||
192 | else if ( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SITTP)) ) | ||
193 | { | ||
194 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | ||
195 | if ( (pAvatar) && (pAvatar->mIsSitting) && (pAvatar->getRoot() == object->getRootEdit()) ) | ||
196 | return; // .. or in a linkset the avie is sitting on under @unsit=n/@sittp=n | ||
197 | } | ||
198 | } | ||
199 | // [/RLVa:KB] | ||
200 | |||
163 | LLPermissions perm; | 201 | LLPermissions perm; |
164 | perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); | 202 | perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); |
165 | perm.initMasks( | 203 | perm.initMasks( |
diff --git a/linden/indra/newview/llpaneldisplay.cpp b/linden/indra/newview/llpaneldisplay.cpp index 308f3df..e3da12a 100644 --- a/linden/indra/newview/llpaneldisplay.cpp +++ b/linden/indra/newview/llpaneldisplay.cpp | |||
@@ -478,7 +478,12 @@ void LLPanelDisplay::refreshEnabledState() | |||
478 | } | 478 | } |
479 | 479 | ||
480 | // Vertex Shaders | 480 | // Vertex Shaders |
481 | mCtrlShaderEnable->setEnabled(LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable")); | 481 | // mCtrlShaderEnable->setEnabled(LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable")); |
482 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0a | ||
483 | // "Basic Shaders" can't be disabled - but can be enabled - under @setenv=n | ||
484 | bool fCtrlShaderEnable = LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable"); | ||
485 | mCtrlShaderEnable->setEnabled(fCtrlShaderEnable && (!gRlvHandler.hasBehaviour(RLV_BHVR_SETENV) || !mShaderEnable)); | ||
486 | // [/RLVa:KB] | ||
482 | 487 | ||
483 | BOOL shaders = mCtrlShaderEnable->get(); | 488 | BOOL shaders = mCtrlShaderEnable->get(); |
484 | if (shaders) | 489 | if (shaders) |
@@ -493,7 +498,12 @@ void LLPanelDisplay::refreshEnabledState() | |||
493 | 498 | ||
494 | // *HACK just checks to see if we can use shaders... | 499 | // *HACK just checks to see if we can use shaders... |
495 | // maybe some cards that use shaders, but don't support windlight | 500 | // maybe some cards that use shaders, but don't support windlight |
496 | mCtrlWindLight->setEnabled(mCtrlShaderEnable->getEnabled() && shaders); | 501 | // mCtrlWindLight->setEnabled(mCtrlShaderEnable->getEnabled() && shaders); |
502 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0a | ||
503 | // "Atmospheric Shaders" can't be disabled - but can be enabled - under @setenv=n | ||
504 | bool fCtrlWindLightEnable = fCtrlShaderEnable && shaders; | ||
505 | mCtrlWindLight->setEnabled(fCtrlWindLightEnable && (!gRlvHandler.hasBehaviour(RLV_BHVR_SETENV) || !mWindLight)); | ||
506 | // [/RLVa:KB] | ||
497 | 507 | ||
498 | // turn off sky detail if atmostpherics isn't on | 508 | // turn off sky detail if atmostpherics isn't on |
499 | mCtrlSkyFactor->setEnabled(gSavedSettings.getBOOL("WindLightUseAtmosShaders")); | 509 | mCtrlSkyFactor->setEnabled(gSavedSettings.getBOOL("WindLightUseAtmosShaders")); |
diff --git a/linden/indra/newview/llpanelinventory.cpp b/linden/indra/newview/llpanelinventory.cpp index c53395d..7ab850f 100644 --- a/linden/indra/newview/llpanelinventory.cpp +++ b/linden/indra/newview/llpanelinventory.cpp | |||
@@ -81,6 +81,10 @@ | |||
81 | #include "llviewerwindow.h" | 81 | #include "llviewerwindow.h" |
82 | #include "llwearable.h" | 82 | #include "llwearable.h" |
83 | 83 | ||
84 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
85 | #include "llvoavatar.h" | ||
86 | // [/RLVa:KB] | ||
87 | |||
84 | ///---------------------------------------------------------------------------- | 88 | ///---------------------------------------------------------------------------- |
85 | /// Local function declarations, constants, enums, and typedefs | 89 | /// Local function declarations, constants, enums, and typedefs |
86 | ///---------------------------------------------------------------------------- | 90 | ///---------------------------------------------------------------------------- |
@@ -364,8 +368,16 @@ void LLTaskInvFVBridge::previewItem() | |||
364 | 368 | ||
365 | BOOL LLTaskInvFVBridge::isItemRenameable() const | 369 | BOOL LLTaskInvFVBridge::isItemRenameable() const |
366 | { | 370 | { |
367 | if(gAgent.isGodlike()) return TRUE; | 371 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) |
368 | LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); | 372 | LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); |
373 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isDetachable(object)) ) | ||
374 | { | ||
375 | return FALSE; | ||
376 | } | ||
377 | // [/RLVa:KB] | ||
378 | |||
379 | if(gAgent.isGodlike()) return TRUE; | ||
380 | // LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); | ||
369 | if(object) | 381 | if(object) |
370 | { | 382 | { |
371 | LLInventoryItem* item; | 383 | LLInventoryItem* item; |
@@ -382,6 +394,12 @@ BOOL LLTaskInvFVBridge::isItemRenameable() const | |||
382 | BOOL LLTaskInvFVBridge::renameItem(const std::string& new_name) | 394 | BOOL LLTaskInvFVBridge::renameItem(const std::string& new_name) |
383 | { | 395 | { |
384 | LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); | 396 | LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); |
397 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
398 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isDetachable(object)) ) | ||
399 | { | ||
400 | return TRUE; // Fallback code [see LLTaskInvFVBridge::isItemRenameable()] | ||
401 | } | ||
402 | // [/RLVa:KB] | ||
385 | if(object) | 403 | if(object) |
386 | { | 404 | { |
387 | LLViewerInventoryItem* item = NULL; | 405 | LLViewerInventoryItem* item = NULL; |
@@ -408,12 +426,47 @@ BOOL LLTaskInvFVBridge::isItemMovable() | |||
408 | // return TRUE; | 426 | // return TRUE; |
409 | //} | 427 | //} |
410 | //return FALSE; | 428 | //return FALSE; |
429 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-0.2.0g | ||
430 | if (rlv_handler_t::isEnabled()) | ||
431 | { | ||
432 | LLViewerObject* pObj = gObjectList.findObject(mPanel->getTaskUUID()); | ||
433 | if (pObj) | ||
434 | { | ||
435 | if (!gRlvHandler.isDetachable(pObj)) | ||
436 | { | ||
437 | return FALSE; | ||
438 | } | ||
439 | else if ( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SITTP)) ) | ||
440 | { | ||
441 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | ||
442 | if ( (pAvatar) && (pAvatar->mIsSitting) && (pAvatar->getRoot() == pObj->getRootEdit()) ) | ||
443 | return FALSE; | ||
444 | } | ||
445 | } | ||
446 | } | ||
447 | // [/RLVa:KB] | ||
411 | return TRUE; | 448 | return TRUE; |
412 | } | 449 | } |
413 | 450 | ||
414 | BOOL LLTaskInvFVBridge::isItemRemovable() | 451 | BOOL LLTaskInvFVBridge::isItemRemovable() |
415 | { | 452 | { |
416 | LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); | 453 | LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); |
454 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-0.2.0g | ||
455 | if ( (object) && (rlv_handler_t::isEnabled()) ) | ||
456 | { | ||
457 | if (!gRlvHandler.isDetachable(object)) | ||
458 | { | ||
459 | return FALSE; | ||
460 | } | ||
461 | else if ( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SITTP)) ) | ||
462 | { | ||
463 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | ||
464 | if ( (pAvatar) && (pAvatar->mIsSitting) && (pAvatar->getRoot() == object->getRootEdit()) ) | ||
465 | return FALSE; | ||
466 | } | ||
467 | } | ||
468 | // [/RLVa:KB] | ||
469 | |||
417 | if(object | 470 | if(object |
418 | && (object->permModify() || object->permYouOwner())) | 471 | && (object->permModify() || object->permYouOwner())) |
419 | { | 472 | { |
@@ -558,6 +611,13 @@ BOOL LLTaskInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const | |||
558 | const LLPermissions& perm = inv->getPermissions(); | 611 | const LLPermissions& perm = inv->getPermissions(); |
559 | bool can_copy = gAgent.allowOperation(PERM_COPY, perm, | 612 | bool can_copy = gAgent.allowOperation(PERM_COPY, perm, |
560 | GP_OBJECT_MANIPULATE); | 613 | GP_OBJECT_MANIPULATE); |
614 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
615 | // Kind of redundant due to the note below, but in case that ever gets fixed | ||
616 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isDetachable(object)) ) | ||
617 | { | ||
618 | return FALSE; | ||
619 | } | ||
620 | // [/RLVa:KB] | ||
561 | if (object->isAttachment() && !can_copy) | 621 | if (object->isAttachment() && !can_copy) |
562 | { | 622 | { |
563 | //RN: no copy contents of attachments cannot be dragged out | 623 | //RN: no copy contents of attachments cannot be dragged out |
@@ -675,6 +735,14 @@ void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) | |||
675 | { | 735 | { |
676 | disabled_items.push_back(std::string("Task Open")); | 736 | disabled_items.push_back(std::string("Task Open")); |
677 | } | 737 | } |
738 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
739 | else if ( (rlv_handler_t::isEnabled()) && | ||
740 | ((LLAssetType::AT_LSL_TEXT == item->getType()) || (LLAssetType::AT_NOTECARD == item->getType())) && | ||
741 | (!gRlvHandler.isDetachable(gObjectList.findObject(mPanel->getTaskUUID()))) ) | ||
742 | { | ||
743 | disabled_items.push_back(std::string("Task Open")); | ||
744 | } | ||
745 | // [/RLVa:KB] | ||
678 | } | 746 | } |
679 | items.push_back(std::string("Task Properties")); | 747 | items.push_back(std::string("Task Properties")); |
680 | if(isItemRenameable()) | 748 | if(isItemRenameable()) |
@@ -1180,12 +1248,20 @@ LLTaskLSLBridge::LLTaskLSLBridge( | |||
1180 | 1248 | ||
1181 | void LLTaskLSLBridge::openItem() | 1249 | void LLTaskLSLBridge::openItem() |
1182 | { | 1250 | { |
1251 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
1252 | LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); | ||
1253 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isDetachable(object)) ) | ||
1254 | { | ||
1255 | return; | ||
1256 | } | ||
1257 | // [/RLVa:KB] | ||
1258 | |||
1183 | llinfos << "LLTaskLSLBridge::openItem() " << mUUID << llendl; | 1259 | llinfos << "LLTaskLSLBridge::openItem() " << mUUID << llendl; |
1184 | if(LLLiveLSLEditor::show(mUUID, mPanel->getTaskUUID())) | 1260 | if(LLLiveLSLEditor::show(mUUID, mPanel->getTaskUUID())) |
1185 | { | 1261 | { |
1186 | return; | 1262 | return; |
1187 | } | 1263 | } |
1188 | LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); | 1264 | // LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); |
1189 | if(!object || object->isInventoryPending()) | 1265 | if(!object || object->isInventoryPending()) |
1190 | { | 1266 | { |
1191 | return; | 1267 | return; |
@@ -1300,6 +1376,12 @@ void LLTaskNotecardBridge::openItem() | |||
1300 | { | 1376 | { |
1301 | return; | 1377 | return; |
1302 | } | 1378 | } |
1379 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
1380 | if ( (rlv_handler_t::isEnabled()) && ((gRlvHandler.hasBehaviour("viewnote")) || (!gRlvHandler.isDetachable(object))) ) | ||
1381 | { | ||
1382 | return; | ||
1383 | } | ||
1384 | // [/RLVa:KB] | ||
1303 | if(object->permModify() || gAgent.isGodlike()) | 1385 | if(object->permModify() || gAgent.isGodlike()) |
1304 | { | 1386 | { |
1305 | S32 left, top; | 1387 | S32 left, top; |
diff --git a/linden/indra/newview/llpanelland.cpp b/linden/indra/newview/llpanelland.cpp index b40450c..c0b8e24 100644 --- a/linden/indra/newview/llpanelland.cpp +++ b/linden/indra/newview/llpanelland.cpp | |||
@@ -230,6 +230,12 @@ void LLPanelLandInfo::refresh() | |||
230 | //static | 230 | //static |
231 | void LLPanelLandInfo::onClickClaim(void*) | 231 | void LLPanelLandInfo::onClickClaim(void*) |
232 | { | 232 | { |
233 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
234 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
235 | { | ||
236 | return; | ||
237 | } | ||
238 | // [/RLVa:KB] | ||
233 | LLViewerParcelMgr::getInstance()->startBuyLand(); | 239 | LLViewerParcelMgr::getInstance()->startBuyLand(); |
234 | } | 240 | } |
235 | 241 | ||
diff --git a/linden/indra/newview/llpanellogin.cpp b/linden/indra/newview/llpanellogin.cpp index c26f70f..325fcbc 100644 --- a/linden/indra/newview/llpanellogin.cpp +++ b/linden/indra/newview/llpanellogin.cpp | |||
@@ -74,6 +74,10 @@ | |||
74 | 74 | ||
75 | #include "llglheaders.h" | 75 | #include "llglheaders.h" |
76 | 76 | ||
77 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-08 (RLVa-1.0.0e) | ||
78 | #include "rlvhandler.h" | ||
79 | // [/RLVa:KB] | ||
80 | |||
77 | #define USE_VIEWER_AUTH 0 | 81 | #define USE_VIEWER_AUTH 0 |
78 | 82 | ||
79 | std::string load_password_from_disk(void); | 83 | std::string load_password_from_disk(void); |
@@ -797,6 +801,18 @@ void LLPanelLogin::refreshLocation( bool force_visible ) | |||
797 | if ( ! force_visible ) | 801 | if ( ! force_visible ) |
798 | show_start = gSavedSettings.getBOOL("ShowStartLocation"); | 802 | show_start = gSavedSettings.getBOOL("ShowStartLocation"); |
799 | 803 | ||
804 | |||
805 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
806 | // TODO-RLVa: figure out some way to make this work with RLV_EXTENSION_STARTLOCATION | ||
807 | #ifndef RLV_EXTENSION_STARTLOCATION | ||
808 | if (rlv_handler_t::isEnabled()) | ||
809 | { | ||
810 | show_start = FALSE; | ||
811 | } | ||
812 | #endif // RLV_EXTENSION_STARTLOCATION | ||
813 | // [/RLVa:KB] | ||
814 | |||
815 | |||
800 | sInstance->childSetVisible("start_location_combo", show_start); | 816 | sInstance->childSetVisible("start_location_combo", show_start); |
801 | sInstance->childSetVisible("start_location_text", show_start); | 817 | sInstance->childSetVisible("start_location_text", show_start); |
802 | 818 | ||
diff --git a/linden/indra/newview/llpanelobject.cpp b/linden/indra/newview/llpanelobject.cpp index 5c70590..dd71a0e 100644 --- a/linden/indra/newview/llpanelobject.cpp +++ b/linden/indra/newview/llpanelobject.cpp | |||
@@ -75,6 +75,10 @@ | |||
75 | 75 | ||
76 | #include "lldrawpool.h" | 76 | #include "lldrawpool.h" |
77 | 77 | ||
78 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
79 | #include "llvoavatar.h" | ||
80 | // [/RLVa:KB] | ||
81 | |||
78 | // | 82 | // |
79 | // Constants | 83 | // Constants |
80 | // | 84 | // |
@@ -385,6 +389,15 @@ void LLPanelObject::getState( ) | |||
385 | enable_rotate = FALSE; | 389 | enable_rotate = FALSE; |
386 | } | 390 | } |
387 | 391 | ||
392 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
393 | if ( (rlv_handler_t::isEnabled()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SITTP))) ) | ||
394 | { | ||
395 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | ||
396 | if ( (pAvatar) && (pAvatar->mIsSitting) && (pAvatar->getRoot() == objectp->getRootEdit()) ) | ||
397 | enable_move = enable_scale = enable_rotate = FALSE; | ||
398 | } | ||
399 | // [/RLVa:KB] | ||
400 | |||
388 | LLVector3 vec; | 401 | LLVector3 vec; |
389 | if (enable_move) | 402 | if (enable_move) |
390 | { | 403 | { |
diff --git a/linden/indra/newview/llpanelpermissions.cpp b/linden/indra/newview/llpanelpermissions.cpp index 439d8b4..24bbab6 100644 --- a/linden/indra/newview/llpanelpermissions.cpp +++ b/linden/indra/newview/llpanelpermissions.cpp | |||
@@ -327,9 +327,26 @@ void LLPanelPermissions::refresh() | |||
327 | } | 327 | } |
328 | } | 328 | } |
329 | 329 | ||
330 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
331 | bool fRlvEnableOwner = true; | ||
332 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ) | ||
333 | { | ||
334 | // Only filter the owner name if: the selection is all owned by the same avie and not group owned | ||
335 | if ( (owners_identical) && (!LLSelectMgr::getInstance()->selectIsGroupOwned()) ) | ||
336 | { | ||
337 | owner_name = gRlvHandler.getAnonym(owner_name); | ||
338 | fRlvEnableOwner = false; | ||
339 | } | ||
340 | } | ||
341 | // [/RLVa:KB] | ||
342 | |||
330 | childSetText("Owner Name",owner_name); | 343 | childSetText("Owner Name",owner_name); |
331 | childSetEnabled("Owner Name",TRUE); | 344 | childSetEnabled("Owner Name",TRUE); |
332 | childSetEnabled("button owner profile",owners_identical && (mOwnerID.notNull() || LLSelectMgr::getInstance()->selectIsGroupOwned())); | 345 | // childSetEnabled("button owner profile",owners_identical && (mOwnerID.notNull() || LLSelectMgr::getInstance()->selectIsGroupOwned())); |
346 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
347 | childSetEnabled("button owner profile", | ||
348 | fRlvEnableOwner && owners_identical && (mOwnerID.notNull() || LLSelectMgr::getInstance()->selectIsGroupOwned())); | ||
349 | // [/RLVa:KB] | ||
333 | 350 | ||
334 | if (owner_name != last_owner_name) | 351 | if (owner_name != last_owner_name) |
335 | { | 352 | { |
@@ -852,7 +869,13 @@ void LLPanelPermissions::onClickOwner(void *data) | |||
852 | } | 869 | } |
853 | else | 870 | else |
854 | { | 871 | { |
855 | LLFloaterAvatarInfo::showFromObject(self->mOwnerID); | 872 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) |
873 | if (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
874 | { | ||
875 | LLFloaterAvatarInfo::showFromObject(self->mOwnerID); | ||
876 | } | ||
877 | // [/RLVa:KB] | ||
878 | // LLFloaterAvatarInfo::showFromObject(self->mOwnerID); | ||
856 | } | 879 | } |
857 | } | 880 | } |
858 | 881 | ||
diff --git a/linden/indra/newview/llpanelpick.cpp b/linden/indra/newview/llpanelpick.cpp index 480f703..57ce6d5 100644 --- a/linden/indra/newview/llpanelpick.cpp +++ b/linden/indra/newview/llpanelpick.cpp | |||
@@ -400,7 +400,10 @@ void LLPanelPick::refresh() | |||
400 | mEnabledCheck->setEnabled(godlike); | 400 | mEnabledCheck->setEnabled(godlike); |
401 | 401 | ||
402 | mSetBtn->setVisible(godlike); | 402 | mSetBtn->setVisible(godlike); |
403 | mSetBtn->setEnabled(godlike); | 403 | //mSetBtn->setEnabled(godlike); |
404 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
405 | mSetBtn->setEnabled(godlike && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ); | ||
406 | // [/RLVa:KB] | ||
404 | } | 407 | } |
405 | else | 408 | else |
406 | { | 409 | { |
@@ -417,7 +420,10 @@ void LLPanelPick::refresh() | |||
417 | mEnabledCheck->setEnabled(FALSE); | 420 | mEnabledCheck->setEnabled(FALSE); |
418 | 421 | ||
419 | mSetBtn->setVisible(is_self); | 422 | mSetBtn->setVisible(is_self); |
420 | mSetBtn->setEnabled(is_self); | 423 | //mSetBtn->setEnabled(is_self); |
424 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
425 | mSetBtn->setEnabled(is_self && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ); | ||
426 | // [/RLVa] | ||
421 | } | 427 | } |
422 | } | 428 | } |
423 | 429 | ||
@@ -455,6 +461,12 @@ void LLPanelPick::onClickLandmark(void* data) | |||
455 | // static | 461 | // static |
456 | void LLPanelPick::onClickSet(void* data) | 462 | void LLPanelPick::onClickSet(void* data) |
457 | { | 463 | { |
464 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
465 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
466 | { | ||
467 | return; | ||
468 | } | ||
469 | // [/RLVa:KB] | ||
458 | LLPanelPick* self = (LLPanelPick*)data; | 470 | LLPanelPick* self = (LLPanelPick*)data; |
459 | 471 | ||
460 | // Save location for later. | 472 | // Save location for later. |
diff --git a/linden/indra/newview/llprefsim.cpp b/linden/indra/newview/llprefsim.cpp index 6115074..5cb14fc 100644 --- a/linden/indra/newview/llprefsim.cpp +++ b/linden/indra/newview/llprefsim.cpp | |||
@@ -259,6 +259,12 @@ void LLPrefsIMImpl::setPersonalInfo(const std::string& visibility, bool im_via_e | |||
259 | LLWStringUtil::replaceChar(busy_response, '^', '\n'); | 259 | LLWStringUtil::replaceChar(busy_response, '^', '\n'); |
260 | LLWStringUtil::replaceChar(busy_response, '%', ' '); | 260 | LLWStringUtil::replaceChar(busy_response, '%', ' '); |
261 | childSetText("busy_response", wstring_to_utf8str(busy_response)); | 261 | childSetText("busy_response", wstring_to_utf8str(busy_response)); |
262 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
263 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM)) | ||
264 | { | ||
265 | childDisable("busy_response"); | ||
266 | } | ||
267 | // [/RLVa:KB] | ||
262 | 268 | ||
263 | enableHistory(); | 269 | enableHistory(); |
264 | 270 | ||
diff --git a/linden/indra/newview/llpreviewscript.cpp b/linden/indra/newview/llpreviewscript.cpp index af52a4b..1e9def3 100644 --- a/linden/indra/newview/llpreviewscript.cpp +++ b/linden/indra/newview/llpreviewscript.cpp | |||
@@ -1925,6 +1925,12 @@ void LLLiveLSLEditor::onRunningCheckboxClicked( LLUICtrl*, void* userdata ) | |||
1925 | LLCheckBoxCtrl* runningCheckbox = self->getChild<LLCheckBoxCtrl>("running"); | 1925 | LLCheckBoxCtrl* runningCheckbox = self->getChild<LLCheckBoxCtrl>("running"); |
1926 | BOOL running = runningCheckbox->get(); | 1926 | BOOL running = runningCheckbox->get(); |
1927 | //self->mRunningCheckbox->get(); | 1927 | //self->mRunningCheckbox->get(); |
1928 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
1929 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isDetachable(object)) ) | ||
1930 | { | ||
1931 | return; | ||
1932 | } | ||
1933 | // [/RLVa:KB] | ||
1928 | if( object ) | 1934 | if( object ) |
1929 | { | 1935 | { |
1930 | LLMessageSystem* msg = gMessageSystem; | 1936 | LLMessageSystem* msg = gMessageSystem; |
@@ -1950,6 +1956,12 @@ void LLLiveLSLEditor::onReset(void *userdata) | |||
1950 | LLLiveLSLEditor* self = (LLLiveLSLEditor*) userdata; | 1956 | LLLiveLSLEditor* self = (LLLiveLSLEditor*) userdata; |
1951 | 1957 | ||
1952 | LLViewerObject* object = gObjectList.findObject( self->mObjectID ); | 1958 | LLViewerObject* object = gObjectList.findObject( self->mObjectID ); |
1959 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
1960 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isDetachable(object)) ) | ||
1961 | { | ||
1962 | return; | ||
1963 | } | ||
1964 | // [/RLV:KB] | ||
1953 | if(object) | 1965 | if(object) |
1954 | { | 1966 | { |
1955 | LLMessageSystem* msg = gMessageSystem; | 1967 | LLMessageSystem* msg = gMessageSystem; |
@@ -2371,6 +2383,14 @@ void LLLiveLSLEditor::onLoad(void* userdata) | |||
2371 | void LLLiveLSLEditor::onSave(void* userdata, BOOL close_after_save) | 2383 | void LLLiveLSLEditor::onSave(void* userdata, BOOL close_after_save) |
2372 | { | 2384 | { |
2373 | LLLiveLSLEditor* self = (LLLiveLSLEditor*)userdata; | 2385 | LLLiveLSLEditor* self = (LLLiveLSLEditor*)userdata; |
2386 | |||
2387 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
2388 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isDetachable(gObjectList.findObject(self->mObjectID))) ) | ||
2389 | { | ||
2390 | return; | ||
2391 | } | ||
2392 | // [/RLV:KB] | ||
2393 | |||
2374 | self->mCloseAfterSave = close_after_save; | 2394 | self->mCloseAfterSave = close_after_save; |
2375 | self->saveIfNeeded(); | 2395 | self->saveIfNeeded(); |
2376 | } | 2396 | } |
diff --git a/linden/indra/newview/llselectmgr.cpp b/linden/indra/newview/llselectmgr.cpp index f46f104..af97e2e 100644 --- a/linden/indra/newview/llselectmgr.cpp +++ b/linden/indra/newview/llselectmgr.cpp | |||
@@ -3451,12 +3451,20 @@ void LLSelectMgr::deselectAllIfTooFar() | |||
3451 | } | 3451 | } |
3452 | 3452 | ||
3453 | LLVector3d selectionCenter = getSelectionCenterGlobal(); | 3453 | LLVector3d selectionCenter = getSelectionCenterGlobal(); |
3454 | if (gSavedSettings.getBOOL("LimitSelectDistance") | 3454 | |
3455 | // if (gSavedSettings.getBOOL("LimitSelectDistance") | ||
3456 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f | ||
3457 | BOOL fRlvFartouch = gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH) && gFloaterTools->getVisible(); | ||
3458 | if ( (gSavedSettings.getBOOL("LimitSelectDistance") || (fRlvFartouch) ) | ||
3459 | // [/RLVa:KB] | ||
3455 | && (!mSelectedObjects->getPrimaryObject() || !mSelectedObjects->getPrimaryObject()->isAvatar()) | 3460 | && (!mSelectedObjects->getPrimaryObject() || !mSelectedObjects->getPrimaryObject()->isAvatar()) |
3456 | && !mSelectedObjects->isAttachment() | 3461 | && !mSelectedObjects->isAttachment() |
3457 | && !selectionCenter.isExactlyZero()) | 3462 | && !selectionCenter.isExactlyZero()) |
3458 | { | 3463 | { |
3459 | F32 deselect_dist = gSavedSettings.getF32("MaxSelectDistance"); | 3464 | // F32 deselect_dist = gSavedSettings.getF32("MaxSelectDistance"); |
3465 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f | ||
3466 | F32 deselect_dist = (!fRlvFartouch) ? gSavedSettings.getF32("MaxSelectDistance") : 1.5f; | ||
3467 | // [/RLVa:KB] | ||
3460 | F32 deselect_dist_sq = deselect_dist * deselect_dist; | 3468 | F32 deselect_dist_sq = deselect_dist * deselect_dist; |
3461 | 3469 | ||
3462 | LLVector3d select_delta = gAgent.getPositionGlobal() - selectionCenter; | 3470 | LLVector3d select_delta = gAgent.getPositionGlobal() - selectionCenter; |
diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index fdc0182..8d5aa9e 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp | |||
@@ -384,6 +384,11 @@ bool idle_startup() | |||
384 | // Initialize stuff that doesn't need data from simulators | 384 | // Initialize stuff that doesn't need data from simulators |
385 | // | 385 | // |
386 | 386 | ||
387 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.1d | ||
388 | if ( (gSavedSettings.controlExists(RLV_SETTING_MAIN)) && (gSavedSettings.getBOOL(RLV_SETTING_MAIN)) ) | ||
389 | rlv_handler_t::setEnabled(TRUE); | ||
390 | // [/RLVa:KB] | ||
391 | |||
387 | if (LLFeatureManager::getInstance()->isSafe()) | 392 | if (LLFeatureManager::getInstance()->isSafe()) |
388 | { | 393 | { |
389 | gViewerWindow->alertXml("DisplaySetToSafe"); | 394 | gViewerWindow->alertXml("DisplaySetToSafe"); |
@@ -924,6 +929,23 @@ bool idle_startup() | |||
924 | // their last location, or some URL "-url //sim/x/y[/z]" | 929 | // their last location, or some URL "-url //sim/x/y[/z]" |
925 | // All accounts have both a home and a last location, and we don't support | 930 | // All accounts have both a home and a last location, and we don't support |
926 | // more locations than that. Choose the appropriate one. JC | 931 | // more locations than that. Choose the appropriate one. JC |
932 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.1d | ||
933 | #ifndef RLV_EXTENSION_STARTLOCATION | ||
934 | if (rlv_handler_t::isEnabled()) | ||
935 | #else | ||
936 | if ( (rlv_handler_t::isEnabled()) && (RlvSettings::getLoginLastLocation()) ) | ||
937 | #endif // RLV_EXTENSION_STARTLOCATION | ||
938 | { | ||
939 | // Force login at the last location | ||
940 | agent_location_id = START_LOCATION_ID_LAST; | ||
941 | location_which = START_LOCATION_ID_LAST; | ||
942 | gSavedSettings.setBOOL("LoginLastLocation", FALSE); | ||
943 | |||
944 | // Clear some things that would cause us to divert to a user-specified location | ||
945 | LLURLSimString::setString(LLURLSimString::sLocationStringLast); | ||
946 | LLStartUp::sSLURLCommand.clear(); | ||
947 | } else | ||
948 | // [/RLVa:KB] | ||
927 | if (LLURLSimString::parse()) | 949 | if (LLURLSimString::parse()) |
928 | { | 950 | { |
929 | // a startup URL was specified | 951 | // a startup URL was specified |
diff --git a/linden/indra/newview/llstatusbar.cpp b/linden/indra/newview/llstatusbar.cpp index b0ef61f..012db6f 100644 --- a/linden/indra/newview/llstatusbar.cpp +++ b/linden/indra/newview/llstatusbar.cpp | |||
@@ -568,6 +568,15 @@ void LLStatusBar::refresh() | |||
568 | mRegionDetails.mTraffic = 0.0f; | 568 | mRegionDetails.mTraffic = 0.0f; |
569 | } | 569 | } |
570 | 570 | ||
571 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | Modified: RLVa-1.0.0a | ||
572 | if ( (region) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) // region == NULL if we loose our connection to the grid | ||
573 | { | ||
574 | // TODO-RLVa: find out whether the LCD code is still used because if so then we need to filter that as well | ||
575 | location_name = llformat("%s (%s) - %s", | ||
576 | rlv_handler_t::cstrHiddenRegion.c_str(), region->getSimAccessString().c_str(), rlv_handler_t::cstrHidden.c_str()); | ||
577 | } | ||
578 | // [/RLVa:KB] | ||
579 | |||
571 | mTextParcelName->setText(location_name); | 580 | mTextParcelName->setText(location_name); |
572 | 581 | ||
573 | 582 | ||
@@ -814,6 +823,12 @@ static void onClickScripts(void*) | |||
814 | 823 | ||
815 | static void onClickBuyLand(void*) | 824 | static void onClickBuyLand(void*) |
816 | { | 825 | { |
826 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
827 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) | ||
828 | { | ||
829 | return; | ||
830 | } | ||
831 | // [/RLVa:KB] | ||
817 | LLViewerParcelMgr::getInstance()->selectParcelAt(gAgent.getPositionGlobal()); | 832 | LLViewerParcelMgr::getInstance()->selectParcelAt(gAgent.getPositionGlobal()); |
818 | LLViewerParcelMgr::getInstance()->startBuyLand(); | 833 | LLViewerParcelMgr::getInstance()->startBuyLand(); |
819 | } | 834 | } |
diff --git a/linden/indra/newview/lltoolbar.cpp b/linden/indra/newview/lltoolbar.cpp index 8202191..6d04294 100644 --- a/linden/indra/newview/lltoolbar.cpp +++ b/linden/indra/newview/lltoolbar.cpp | |||
@@ -307,6 +307,20 @@ void LLToolBar::refresh() | |||
307 | } | 307 | } |
308 | gSavedSettings.setBOOL("BuildBtnState", build_mode); | 308 | gSavedSettings.setBOOL("BuildBtnState", build_mode); |
309 | 309 | ||
310 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-10 (RLVa-1.0.0g) | ||
311 | // Called per-frame so this really can't be slow | ||
312 | if (rlv_handler_t::isEnabled()) | ||
313 | { | ||
314 | // If we're rez-restricted, we can still edit => allow build floater | ||
315 | // If we're edit-restricted, we can still rez => allow build floater | ||
316 | childSetEnabled("build_btn", !(gRlvHandler.hasBehaviour(RLV_BHVR_REZ) && gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) ); | ||
317 | |||
318 | childSetEnabled("map_btn", !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWWORLDMAP) ); | ||
319 | childSetEnabled("radar_btn", !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWMINIMAP) ); | ||
320 | childSetEnabled("inventory_btn", !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWINV) ); | ||
321 | } | ||
322 | // [/RLVa:KB] | ||
323 | |||
310 | updateCommunicateList(); | 324 | updateCommunicateList(); |
311 | } | 325 | } |
312 | 326 | ||
@@ -479,6 +493,14 @@ void LLToolBar::onClickSit(void*) | |||
479 | } | 493 | } |
480 | else | 494 | else |
481 | { | 495 | { |
496 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
497 | // NOTE-RLVa: dead code? | ||
498 | if (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) | ||
499 | { | ||
500 | return; | ||
501 | } | ||
502 | // [/RLVa:KB] | ||
503 | |||
482 | // stand up | 504 | // stand up |
483 | gAgent.setFlying(FALSE); | 505 | gAgent.setFlying(FALSE); |
484 | gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); | 506 | gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); |
diff --git a/linden/indra/newview/lltooldraganddrop.cpp b/linden/indra/newview/lltooldraganddrop.cpp index efd8060..c99ccbf 100644 --- a/linden/indra/newview/lltooldraganddrop.cpp +++ b/linden/indra/newview/lltooldraganddrop.cpp | |||
@@ -1267,6 +1267,15 @@ void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target, | |||
1267 | return; | 1267 | return; |
1268 | } | 1268 | } |
1269 | 1269 | ||
1270 | |||
1271 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | ||
1272 | // Fallback in case there's a new code path that leads here (see behaviour notes) | ||
1273 | if (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) | ||
1274 | { | ||
1275 | return; | ||
1276 | } | ||
1277 | // [/RLVa:KB] | ||
1278 | |||
1270 | //llinfos << "Rezzing object" << llendl; | 1279 | //llinfos << "Rezzing object" << llendl; |
1271 | make_ui_sound("UISndObjectRezIn"); | 1280 | make_ui_sound("UISndObjectRezIn"); |
1272 | LLViewerInventoryItem* item; | 1281 | LLViewerInventoryItem* item; |
@@ -1933,6 +1942,23 @@ EAcceptance LLToolDragAndDrop::willObjectAcceptInventory(LLViewerObject* obj, LL | |||
1933 | BOOL volume = (LL_PCODE_VOLUME == obj->getPCode()); | 1942 | BOOL volume = (LL_PCODE_VOLUME == obj->getPCode()); |
1934 | BOOL attached = obj->isAttachment(); | 1943 | BOOL attached = obj->isAttachment(); |
1935 | BOOL unrestricted = ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) ? TRUE : FALSE; | 1944 | BOOL unrestricted = ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) ? TRUE : FALSE; |
1945 | |||
1946 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
1947 | if (rlv_handler_t::isEnabled()) | ||
1948 | { | ||
1949 | if (!gRlvHandler.isDetachable(obj)) | ||
1950 | { | ||
1951 | return ACCEPT_NO_LOCKED; // Disallow inventory drops on a locked attachment | ||
1952 | } | ||
1953 | else if ( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SITTP)) ) | ||
1954 | { | ||
1955 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | ||
1956 | if ( (pAvatar) && (pAvatar->mIsSitting) && (pAvatar->getRoot() == obj->getRootEdit()) ) | ||
1957 | return ACCEPT_NO_LOCKED; // ... or on a linkset the avie is sitting on under @unsit=n/@sittp=n | ||
1958 | } | ||
1959 | } | ||
1960 | // [/RLVa:KB] | ||
1961 | |||
1936 | if(attached && !unrestricted) | 1962 | if(attached && !unrestricted) |
1937 | { | 1963 | { |
1938 | return ACCEPT_NO_LOCKED; | 1964 | return ACCEPT_NO_LOCKED; |
@@ -1988,6 +2014,15 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv( | |||
1988 | return ACCEPT_NO; | 2014 | return ACCEPT_NO; |
1989 | } | 2015 | } |
1990 | 2016 | ||
2017 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-1.0.0c | ||
2018 | LLViewerJointAttachment* pAttachPt = NULL; | ||
2019 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment()) && (!RlvSettings::getEnableWear()) && | ||
2020 | ( ((pAttachPt = gRlvHandler.getAttachPoint(item, true)) == NULL) || (!gRlvHandler.isDetachable(pAttachPt->getObject())) ) ) | ||
2021 | { | ||
2022 | return ACCEPT_NO_LOCKED; | ||
2023 | } | ||
2024 | // [/RLVa:KB] | ||
2025 | |||
1991 | if( drop ) | 2026 | if( drop ) |
1992 | { | 2027 | { |
1993 | if(mSource == SOURCE_LIBRARY) | 2028 | if(mSource == SOURCE_LIBRARY) |
@@ -2003,7 +2038,10 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv( | |||
2003 | } | 2038 | } |
2004 | else | 2039 | else |
2005 | { | 2040 | { |
2006 | rez_attachment(item, 0); | 2041 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Added: RLVa-1.0.0c |
2042 | rez_attachment(item, pAttachPt); | ||
2043 | // [/RLVa:KB] | ||
2044 | //rez_attachment(item, 0); | ||
2007 | } | 2045 | } |
2008 | } | 2046 | } |
2009 | return ACCEPT_YES_SINGLE; | 2047 | return ACCEPT_YES_SINGLE; |
@@ -2013,6 +2051,13 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv( | |||
2013 | EAcceptance LLToolDragAndDrop::dad3dRezObjectOnLand( | 2051 | EAcceptance LLToolDragAndDrop::dad3dRezObjectOnLand( |
2014 | LLViewerObject* obj, S32 face, MASK mask, BOOL drop) | 2052 | LLViewerObject* obj, S32 face, MASK mask, BOOL drop) |
2015 | { | 2053 | { |
2054 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | ||
2055 | if (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) | ||
2056 | { | ||
2057 | return ACCEPT_NO_LOCKED; | ||
2058 | } | ||
2059 | // [/RLVa:KB] | ||
2060 | |||
2016 | if (mSource == SOURCE_WORLD) | 2061 | if (mSource == SOURCE_WORLD) |
2017 | { | 2062 | { |
2018 | return dad3dRezFromObjectOnLand(obj, face, mask, drop); | 2063 | return dad3dRezFromObjectOnLand(obj, face, mask, drop); |
@@ -2076,6 +2121,14 @@ EAcceptance LLToolDragAndDrop::dad3dRezObjectOnLand( | |||
2076 | EAcceptance LLToolDragAndDrop::dad3dRezObjectOnObject( | 2121 | EAcceptance LLToolDragAndDrop::dad3dRezObjectOnObject( |
2077 | LLViewerObject* obj, S32 face, MASK mask, BOOL drop) | 2122 | LLViewerObject* obj, S32 face, MASK mask, BOOL drop) |
2078 | { | 2123 | { |
2124 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | ||
2125 | // NOTE: if (mask & MASK_CONTROL) then it's a drop rather than a rez, so we let that pass through | ||
2126 | if ( !(mask & MASK_CONTROL) && (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) ) | ||
2127 | { | ||
2128 | return ACCEPT_NO_LOCKED; | ||
2129 | } | ||
2130 | // [/RLVa:KB] | ||
2131 | |||
2079 | // handle objects coming from object inventory | 2132 | // handle objects coming from object inventory |
2080 | if (mSource == SOURCE_WORLD) | 2133 | if (mSource == SOURCE_WORLD) |
2081 | { | 2134 | { |
@@ -2281,6 +2334,20 @@ EAcceptance LLToolDragAndDrop::dad3dWearItem( | |||
2281 | return ACCEPT_NO; | 2334 | return ACCEPT_NO; |
2282 | } | 2335 | } |
2283 | 2336 | ||
2337 | // [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) | ||
2338 | // (See behaviour notes for the "code path", this is just to give a visual indication on whether or not the drop is allowed) | ||
2339 | if (rlv_handler_t::isEnabled()) | ||
2340 | { | ||
2341 | EWearableType type = (EWearableType)item->getFlags(); | ||
2342 | |||
2343 | // Block if: 1) we can't wear on that layer; 2) or if we're already wearing something there we can't take off | ||
2344 | if ( (!gRlvHandler.isWearable(type)) || ((gAgent.getWearable(type)) && (!gRlvHandler.isRemovable(type))) ) | ||
2345 | { | ||
2346 | return ACCEPT_NO_LOCKED; | ||
2347 | } | ||
2348 | } | ||
2349 | // [/RLVa:KB] | ||
2350 | |||
2284 | if( drop ) | 2351 | if( drop ) |
2285 | { | 2352 | { |
2286 | // Don't wear anything until initial wearables are loaded, can | 2353 | // Don't wear anything until initial wearables are loaded, can |
@@ -2645,6 +2712,14 @@ EAcceptance LLToolDragAndDrop::dad3dGiveInventoryCategory( | |||
2645 | EAcceptance LLToolDragAndDrop::dad3dRezFromObjectOnLand( | 2712 | EAcceptance LLToolDragAndDrop::dad3dRezFromObjectOnLand( |
2646 | LLViewerObject* obj, S32 face, MASK mask, BOOL drop) | 2713 | LLViewerObject* obj, S32 face, MASK mask, BOOL drop) |
2647 | { | 2714 | { |
2715 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | ||
2716 | // NOTE: it looks like this is only ever called from LLToolDragAndDrop::dad3dRezObjectOnLand() making this a bit redundant | ||
2717 | if (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) | ||
2718 | { | ||
2719 | return ACCEPT_NO_LOCKED; | ||
2720 | } | ||
2721 | // [/RLVa:KB] | ||
2722 | |||
2648 | lldebugs << "LLToolDragAndDrop::dad3dRezFromObjectOnLand()" << llendl; | 2723 | lldebugs << "LLToolDragAndDrop::dad3dRezFromObjectOnLand()" << llendl; |
2649 | LLViewerInventoryItem* item = NULL; | 2724 | LLViewerInventoryItem* item = NULL; |
2650 | LLViewerInventoryCategory* cat = NULL; | 2725 | LLViewerInventoryCategory* cat = NULL; |
@@ -2666,6 +2741,14 @@ EAcceptance LLToolDragAndDrop::dad3dRezFromObjectOnLand( | |||
2666 | EAcceptance LLToolDragAndDrop::dad3dRezFromObjectOnObject( | 2741 | EAcceptance LLToolDragAndDrop::dad3dRezFromObjectOnObject( |
2667 | LLViewerObject* obj, S32 face, MASK mask, BOOL drop) | 2742 | LLViewerObject* obj, S32 face, MASK mask, BOOL drop) |
2668 | { | 2743 | { |
2744 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | ||
2745 | // NOTE: it looks like this is only ever called from LLToolDragAndDrop::dad3dRezObjectOnObject) making this a bit redundant | ||
2746 | if (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) | ||
2747 | { | ||
2748 | return ACCEPT_NO_LOCKED; | ||
2749 | } | ||
2750 | // [/RLVa:KB] | ||
2751 | |||
2669 | lldebugs << "LLToolDragAndDrop::dad3dRezFromObjectOnObject()" << llendl; | 2752 | lldebugs << "LLToolDragAndDrop::dad3dRezFromObjectOnObject()" << llendl; |
2670 | LLViewerInventoryItem* item; | 2753 | LLViewerInventoryItem* item; |
2671 | LLViewerInventoryCategory* cat; | 2754 | LLViewerInventoryCategory* cat; |
diff --git a/linden/indra/newview/lltoolface.cpp b/linden/indra/newview/lltoolface.cpp index d5e4f81..41f2b0d 100644 --- a/linden/indra/newview/lltoolface.cpp +++ b/linden/indra/newview/lltoolface.cpp | |||
@@ -99,6 +99,16 @@ void LLToolFace::pickCallback(const LLPickInfo& pick_info) | |||
99 | return; | 99 | return; |
100 | } | 100 | } |
101 | 101 | ||
102 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f | ||
103 | if ( (rlv_handler_t::isEnabled()) && | ||
104 | ( (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) || | ||
105 | ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && ((!hit_obj->isAttachment()) || (!hit_obj->permYouOwner())) && | ||
106 | (dist_vec_squared(gAgent.getPositionAgent(), hit_obj->getPositionRegion() + pick_info.mObjectOffset) > 1.5f * 1.5f) ))) | ||
107 | { | ||
108 | return; | ||
109 | } | ||
110 | // [/RLVa:KB] | ||
111 | |||
102 | // ...clicked on a world object, try to pick the appropriate face | 112 | // ...clicked on a world object, try to pick the appropriate face |
103 | 113 | ||
104 | if (pick_info.mKeyMask & MASK_SHIFT) | 114 | if (pick_info.mKeyMask & MASK_SHIFT) |
diff --git a/linden/indra/newview/lltoolgrab.cpp b/linden/indra/newview/lltoolgrab.cpp index a6695f9..6c0a557 100644 --- a/linden/indra/newview/lltoolgrab.cpp +++ b/linden/indra/newview/lltoolgrab.cpp | |||
@@ -185,7 +185,12 @@ BOOL LLToolGrab::handleObjectHit(const LLPickInfo& info) | |||
185 | return FALSE; | 185 | return FALSE; |
186 | } | 186 | } |
187 | 187 | ||
188 | if (objectp->isAvatar()) | 188 | //if (objectp->isAvatar()) |
189 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f | ||
190 | if ( (objectp->isAvatar()) || | ||
191 | ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && ((!objectp->isAttachment()) || (!objectp->permYouOwner())) && | ||
192 | (dist_vec_squared(gAgent.getPositionAgent(), mGrabPick.mIntersection) > 1.5f * 1.5f) ) ) | ||
193 | // [/RLVa:KB] | ||
189 | { | 194 | { |
190 | if (gGrabTransientTool) | 195 | if (gGrabTransientTool) |
191 | { | 196 | { |
@@ -420,6 +425,23 @@ BOOL LLToolGrab::handleHover(S32 x, S32 y, MASK mask) | |||
420 | return TRUE; | 425 | return TRUE; |
421 | } | 426 | } |
422 | 427 | ||
428 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-0.2.0f | ||
429 | // Don't allow dragging beyond 1.5m under @fartouch=n | ||
430 | LLViewerObject* pObj; | ||
431 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && (GRAB_INACTIVE != mMode) && (hasMouseCapture()) && | ||
432 | ((pObj = mGrabPick.getObject()) != NULL) && (!pObj->isDead()) && (!pObj->isHUDAttachment()) && | ||
433 | (dist_vec_squared(gAgent.getPositionAgent(), pObj->getPositionRegion() + mGrabPick.mObjectOffset) > 1.5f * 1.5f) ) | ||
434 | { | ||
435 | if (gGrabTransientTool) | ||
436 | { | ||
437 | // Prevent the grab tool from popping up as soon as we kill the drag operation | ||
438 | gBasicToolset->selectTool(gGrabTransientTool); | ||
439 | gGrabTransientTool = NULL; | ||
440 | } | ||
441 | setMouseCapture(FALSE); | ||
442 | } | ||
443 | // [/RLVa:KB] | ||
444 | |||
423 | // Do the right hover based on mode | 445 | // Do the right hover based on mode |
424 | switch( mMode ) | 446 | switch( mMode ) |
425 | { | 447 | { |
diff --git a/linden/indra/newview/lltoolpie.cpp b/linden/indra/newview/lltoolpie.cpp index b660b8d..b32169d 100644 --- a/linden/indra/newview/lltoolpie.cpp +++ b/linden/indra/newview/lltoolpie.cpp | |||
@@ -165,6 +165,15 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show) | |||
165 | // If it's a left-click, and we have a special action, do it. | 165 | // If it's a left-click, and we have a special action, do it. |
166 | if (useClickAction(always_show, mask, object, parent)) | 166 | if (useClickAction(always_show, mask, object, parent)) |
167 | { | 167 | { |
168 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f | ||
169 | // Block left-click special actions (fallback code really since LLToolSelect::handleObjectSelection() wouldn't select it anyway) | ||
170 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && | ||
171 | (dist_vec_squared(gAgent.getPositionAgent(), mPick.mIntersection) > 1.5f * 1.5f) ) | ||
172 | { | ||
173 | return TRUE; | ||
174 | } | ||
175 | // [/RLVa:KB] | ||
176 | |||
168 | mClickAction = 0; | 177 | mClickAction = 0; |
169 | if (object && object->getClickAction()) | 178 | if (object && object->getClickAction()) |
170 | { | 179 | { |
@@ -344,7 +353,22 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show) | |||
344 | //gMutePieMenu->setLabel("Mute"); | 353 | //gMutePieMenu->setLabel("Mute"); |
345 | } | 354 | } |
346 | 355 | ||
347 | gPieAvatar->show(x, y, mPieMouseButtonDown); | 356 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-0.2.0f |
357 | #ifdef RLV_EXPERIMENTAL_FARTOUCH_FEEDBACK | ||
358 | // If we have an empty selection under @fartouch=n don't show the pie menu but play the "operation block" sound | ||
359 | if ( (!gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) || (!LLSelectMgr::getInstance()->getSelection()->isEmpty()) ) | ||
360 | { | ||
361 | #endif // RLV_EXPERIMENTAL_FARTOUCH_FEEDBACK | ||
362 | gPieAvatar->show(x, y, mPieMouseButtonDown); | ||
363 | #ifdef RLV_EXPERIMENTAL_FARTOUCH_FEEDBACK | ||
364 | } | ||
365 | else | ||
366 | { | ||
367 | make_ui_sound("UISndInvalidOp"); | ||
368 | } | ||
369 | #endif // RLV_EXPERIMENTAL_FARTOUCH_FEEDBACK | ||
370 | // [/RLVa:KB] | ||
371 | |||
348 | } | 372 | } |
349 | else if (object->isAttachment() && !object->isHUDAttachment()) | 373 | else if (object->isAttachment() && !object->isHUDAttachment()) |
350 | { | 374 | { |
@@ -374,15 +398,32 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show) | |||
374 | //gMuteObjectPieMenu->setLabel("Mute"); | 398 | //gMuteObjectPieMenu->setLabel("Mute"); |
375 | } | 399 | } |
376 | 400 | ||
377 | gPieObject->show(x, y, mPieMouseButtonDown); | 401 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-0.2.0f |
378 | 402 | #ifdef RLV_EXPERIMENTAL_FARTOUCH_FEEDBACK | |
379 | // VEFFECT: ShowPie object | 403 | // If we have an empty selection under @fartouch=n don't show the pie menu but play the "operation block" sound |
380 | // Don't show when you click on someone else, it freaks them | 404 | // (not entirely accurate in case of Tools / Select Only XXX [see LLToolSelect::handleObjectSelection()] |
381 | // out. | 405 | if ( (!gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) || (!LLSelectMgr::getInstance()->getSelection()->isEmpty()) ) |
382 | LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_SPHERE, TRUE); | 406 | { |
383 | effectp->setPositionGlobal(mPick.mPosGlobal); | 407 | #endif // RLV_EXPERIMENTAL_FARTOUCH_FEEDBACK |
384 | effectp->setColor(LLColor4U(gAgent.getEffectColor())); | 408 | // [/RLVa:KB] |
385 | effectp->setDuration(0.25f); | 409 | gPieObject->show(x, y, mPieMouseButtonDown); |
410 | |||
411 | // VEFFECT: ShowPie object | ||
412 | // Don't show when you click on someone else, it freaks them | ||
413 | // out. | ||
414 | LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_SPHERE, TRUE); | ||
415 | effectp->setPositionGlobal(mPick.mPosGlobal); | ||
416 | effectp->setColor(LLColor4U(gAgent.getEffectColor())); | ||
417 | effectp->setDuration(0.25f); | ||
418 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-0.2.0f | ||
419 | #ifdef RLV_EXPERIMENTAL_FARTOUCH_FEEDBACK | ||
420 | } | ||
421 | else | ||
422 | { | ||
423 | make_ui_sound("UISndInvalidOp"); | ||
424 | } | ||
425 | #endif // RLV_EXPERIMENTAL_FARTOUCH_FEEDBACK | ||
426 | // [/RLVa:KB] | ||
386 | } | 427 | } |
387 | } | 428 | } |
388 | 429 | ||
diff --git a/linden/indra/newview/lltoolplacer.cpp b/linden/indra/newview/lltoolplacer.cpp index 297556e..840de23 100644 --- a/linden/indra/newview/lltoolplacer.cpp +++ b/linden/indra/newview/lltoolplacer.cpp | |||
@@ -124,6 +124,14 @@ BOOL LLToolPlacer::raycastForNewObjPos( S32 x, S32 y, LLViewerObject** hit_obj, | |||
124 | return FALSE; | 124 | return FALSE; |
125 | } | 125 | } |
126 | 126 | ||
127 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f | ||
128 | // NOTE: don't use surface_pos_global since for prims it will be the center of the prim while we need center + offset | ||
129 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && (dist_vec_squared(gAgent.getPositionGlobal(), pick.mPosGlobal) > 1.5f * 1.5f) ) | ||
130 | { | ||
131 | return FALSE; | ||
132 | } | ||
133 | // [/RLVa:KB] | ||
134 | |||
127 | // Find the sim where the surface lives. | 135 | // Find the sim where the surface lives. |
128 | LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(surface_pos_global); | 136 | LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(surface_pos_global); |
129 | if (!regionp) | 137 | if (!regionp) |
@@ -255,7 +263,10 @@ BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics ) | |||
255 | { | 263 | { |
256 | flags |= FLAGS_USE_PHYSICS; | 264 | flags |= FLAGS_USE_PHYSICS; |
257 | } | 265 | } |
258 | if (create_selected) | 266 | //if (create_selected) |
267 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0b) | Added: RLVa-1.0.0b | ||
268 | if ( (create_selected) && (!gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) ) | ||
269 | // [/RLVa:KB] | ||
259 | { | 270 | { |
260 | flags |= FLAGS_CREATE_SELECTED; | 271 | flags |= FLAGS_CREATE_SELECTED; |
261 | } | 272 | } |
@@ -513,6 +524,13 @@ BOOL LLToolPlacer::placeObject(S32 x, S32 y, MASK mask) | |||
513 | { | 524 | { |
514 | BOOL added = TRUE; | 525 | BOOL added = TRUE; |
515 | 526 | ||
527 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | ||
528 | if (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) | ||
529 | { | ||
530 | return TRUE; // Callers seem to expect a "did you handle it?" so we return TRUE rather than FALSE | ||
531 | } | ||
532 | // [/RLVa:KB] | ||
533 | |||
516 | if (gSavedSettings.getBOOL("CreateToolCopySelection")) | 534 | if (gSavedSettings.getBOOL("CreateToolCopySelection")) |
517 | { | 535 | { |
518 | added = addDuplicate(x, y); | 536 | added = addDuplicate(x, y); |
diff --git a/linden/indra/newview/lltoolselect.cpp b/linden/indra/newview/lltoolselect.cpp index b4e9562..389ae59 100644 --- a/linden/indra/newview/lltoolselect.cpp +++ b/linden/indra/newview/lltoolselect.cpp | |||
@@ -50,6 +50,10 @@ | |||
50 | #include "llvoavatar.h" | 50 | #include "llvoavatar.h" |
51 | #include "llworld.h" | 51 | #include "llworld.h" |
52 | 52 | ||
53 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
54 | #include "llfloatertools.h" | ||
55 | // [/RLVa:KB] | ||
56 | |||
53 | // Globals | 57 | // Globals |
54 | extern BOOL gAllowSelectAvatar; | 58 | extern BOOL gAllowSelectAvatar; |
55 | 59 | ||
@@ -82,6 +86,51 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi | |||
82 | { | 86 | { |
83 | object = object->getRootEdit(); | 87 | object = object->getRootEdit(); |
84 | } | 88 | } |
89 | |||
90 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f | ||
91 | if (rlv_handler_t::isEnabled()) | ||
92 | { | ||
93 | if (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) | ||
94 | { | ||
95 | if (!temp_select) | ||
96 | { | ||
97 | return LLSelectMgr::getInstance()->getSelection(); | ||
98 | } | ||
99 | else | ||
100 | { | ||
101 | // Temporary selection, but if the build floater is open then it'll be permanent so get rid of the floater | ||
102 | if (gFloaterTools->getVisible()) | ||
103 | { | ||
104 | // Copy/paste from toggle_build_mode() | ||
105 | gAgent.resetView(false); | ||
106 | gFloaterTools->close(); | ||
107 | gViewerWindow->showCursor(); | ||
108 | } | ||
109 | } | ||
110 | } | ||
111 | |||
112 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && (object) && ((!object->isAttachment()) || (!object->permYouOwner())) && | ||
113 | (dist_vec_squared(gAgent.getPositionAgent(), object->getPositionRegion()) > 1.5f * 1.5f) ) | ||
114 | { | ||
115 | // NOTE-RLVa: see behaviour notes for a rather lengthy explanation of why we're doing things this way | ||
116 | //if (dist_vec_squared(gAgent.getPositionAgent(), object->getPositionRegion() + pick.mObjectOffset) > 1.5f * 1.5f) | ||
117 | if (dist_vec_squared(gAgent.getPositionAgent(), pick.mIntersection) > 1.5f * 1.5f) | ||
118 | { | ||
119 | if ( (gFloaterTools->getVisible()) && (pick.mKeyMask != MASK_SHIFT) && (pick.mKeyMask != MASK_CONTROL) ) | ||
120 | LLSelectMgr::getInstance()->deselectAll(); | ||
121 | return LLSelectMgr::getInstance()->getSelection(); | ||
122 | } | ||
123 | else if (gFloaterTools->getVisible()) | ||
124 | { | ||
125 | // Copy/paste from toggle_build_mode() | ||
126 | gAgent.resetView(false); | ||
127 | gFloaterTools->close(); | ||
128 | gViewerWindow->showCursor(); | ||
129 | } | ||
130 | } | ||
131 | } | ||
132 | // [/RLVa:KB] | ||
133 | |||
85 | BOOL select_owned = gSavedSettings.getBOOL("SelectOwnedOnly"); | 134 | BOOL select_owned = gSavedSettings.getBOOL("SelectOwnedOnly"); |
86 | BOOL select_movable = gSavedSettings.getBOOL("SelectMovableOnly"); | 135 | BOOL select_movable = gSavedSettings.getBOOL("SelectMovableOnly"); |
87 | 136 | ||
diff --git a/linden/indra/newview/lltracker.cpp b/linden/indra/newview/lltracker.cpp index bd2f659..cf98c7a 100644 --- a/linden/indra/newview/lltracker.cpp +++ b/linden/indra/newview/lltracker.cpp | |||
@@ -180,8 +180,12 @@ void LLTracker::render3D() | |||
180 | } | 180 | } |
181 | else | 181 | else |
182 | { | 182 | { |
183 | renderBeacon( instance()->mTrackedPositionGlobal, gTrackColor, | 183 | //renderBeacon( instance()->mTrackedPositionGlobal, gTrackColor, |
184 | instance()->mBeaconText, instance()->mTrackedLocationName ); | 184 | // instance()->mBeaconText, instance()->mTrackedLocationName ); |
185 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | Added: RLVa-1.0.0a | ||
186 | renderBeacon(instance()->mTrackedPositionGlobal, gTrackColor, instance()->mBeaconText, | ||
187 | (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? instance()->mTrackedLocationName : rlv_handler_t::cstrHidden); | ||
188 | // [/RLVa:KB] | ||
185 | } | 189 | } |
186 | } | 190 | } |
187 | 191 | ||
@@ -222,8 +226,12 @@ void LLTracker::render3D() | |||
222 | // and back again | 226 | // and back again |
223 | instance()->mHasReachedLandmark = FALSE; | 227 | instance()->mHasReachedLandmark = FALSE; |
224 | } | 228 | } |
225 | renderBeacon( instance()->mTrackedPositionGlobal, gTrackColor, | 229 | //renderBeacon( instance()->mTrackedPositionGlobal, gTrackColor, |
226 | instance()->mBeaconText, instance()->mTrackedLandmarkName ); | 230 | // instance()->mBeaconText, instance()->mTrackedLandmarkName ); |
231 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | Added: RLVa-1.0.0a | ||
232 | renderBeacon( instance()->mTrackedPositionGlobal, gTrackColor, instance()->mBeaconText, | ||
233 | (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? instance()->mTrackedLandmarkName : rlv_handler_t::cstrHidden); | ||
234 | // [/RLVa:KB] | ||
227 | } | 235 | } |
228 | } | 236 | } |
229 | else | 237 | else |
@@ -251,8 +259,12 @@ void LLTracker::render3D() | |||
251 | } | 259 | } |
252 | else | 260 | else |
253 | { | 261 | { |
254 | renderBeacon( av_tracker.getGlobalPos(), gTrackColor, | 262 | //renderBeacon( av_tracker.getGlobalPos(), gTrackColor, |
255 | instance()->mBeaconText, av_tracker.getName() ); | 263 | // instance()->mBeaconText, av_tracker.getName() ); |
264 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | Added: RLVa-1.0.0a | ||
265 | renderBeacon( av_tracker.getGlobalPos(), gTrackColor, instance()->mBeaconText, | ||
266 | (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? av_tracker.getName() : rlv_handler_t::cstrHidden); | ||
267 | // [/RLVa:KB] | ||
256 | } | 268 | } |
257 | } | 269 | } |
258 | else | 270 | else |
diff --git a/linden/indra/newview/llviewercontrol.cpp b/linden/indra/newview/llviewercontrol.cpp index 89ae973..eb8b1d5 100644 --- a/linden/indra/newview/llviewercontrol.cpp +++ b/linden/indra/newview/llviewercontrol.cpp | |||
@@ -423,6 +423,20 @@ bool handleVoiceClientPrefsChanged(const LLSD& newvalue) | |||
423 | return true; | 423 | return true; |
424 | } | 424 | } |
425 | 425 | ||
426 | // [RLVa:KB] - Checked: 2009-08-11 (RLVa-1.0.1h) | Added: RLVa-1.0.1h | ||
427 | bool rlvHandleEnableLegacyNamingChanged(const LLSD& newvalue) | ||
428 | { | ||
429 | rlv_handler_t::fLegacyNaming = newvalue.asBoolean(); | ||
430 | return true; | ||
431 | } | ||
432 | |||
433 | bool rlvHandleShowNameTagsChanged(const LLSD& newvalue) | ||
434 | { | ||
435 | RlvSettings::fShowNameTags = newvalue.asBoolean(); | ||
436 | return true; | ||
437 | } | ||
438 | // [/RLVa:KB] | ||
439 | |||
426 | bool handleMediaDebugLevelChanged(const LLSD& newvalue) | 440 | bool handleMediaDebugLevelChanged(const LLSD& newvalue) |
427 | { | 441 | { |
428 | LLMediaManager *mgr = LLMediaManager::getInstance(); | 442 | LLMediaManager *mgr = LLMediaManager::getInstance(); |
@@ -566,6 +580,13 @@ void settings_setup_listeners() | |||
566 | gSavedSettings.getControl("AudioLevelMic")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1)); | 580 | gSavedSettings.getControl("AudioLevelMic")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1)); |
567 | gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1)); | 581 | gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1)); |
568 | gSavedSettings.getControl("MediaDebugLevel")->getSignal()->connect(boost::bind(&handleMediaDebugLevelChanged, _1)); | 582 | gSavedSettings.getControl("MediaDebugLevel")->getSignal()->connect(boost::bind(&handleMediaDebugLevelChanged, _1)); |
583 | |||
584 | // [RLVa:KB] - Checked: 2009-08-11 (RLVa-1.0.1h) | Added: RLVa-1.0.1h | ||
585 | if (gSavedSettings.controlExists(RLV_SETTING_ENABLELEGACYNAMING)) | ||
586 | gSavedSettings.getControl(RLV_SETTING_ENABLELEGACYNAMING)->getSignal()->connect(boost::bind(&rlvHandleEnableLegacyNamingChanged, _1)); | ||
587 | if (gSavedSettings.controlExists(RLV_SETTING_SHOWNAMETAGS)) | ||
588 | gSavedSettings.getControl(RLV_SETTING_SHOWNAMETAGS)->getSignal()->connect(boost::bind(&rlvHandleShowNameTagsChanged, _1)); | ||
589 | // [/RLVa:KB] | ||
569 | } | 590 | } |
570 | 591 | ||
571 | template <> eControlType get_control_type<U32>(const U32& in, LLSD& out) | 592 | template <> 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 96591a2..4b352a4 100644 --- a/linden/indra/newview/llviewerdisplay.cpp +++ b/linden/indra/newview/llviewerdisplay.cpp | |||
@@ -675,7 +675,10 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) | |||
675 | gSky.updateSky(); | 675 | gSky.updateSky(); |
676 | } | 676 | } |
677 | 677 | ||
678 | if(gUseWireframe) | 678 | // if(gUseWireframe) |
679 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
680 | if ( (gUseWireframe) && ( (!rlv_handler_t::isEnabled()) || (!gRlvHandler.hasLockedAttachment()) ) ) | ||
681 | // [/RLVa:KB] | ||
679 | { | 682 | { |
680 | glClearColor(0.5f, 0.5f, 0.5f, 0.f); | 683 | glClearColor(0.5f, 0.5f, 0.5f, 0.f); |
681 | glClear(GL_COLOR_BUFFER_BIT); | 684 | glClear(GL_COLOR_BUFFER_BIT); |
@@ -802,7 +805,12 @@ void render_hud_attachments() | |||
802 | glh::matrix4f current_mod = glh_get_current_modelview(); | 805 | glh::matrix4f current_mod = glh_get_current_modelview(); |
803 | 806 | ||
804 | // clamp target zoom level to reasonable values | 807 | // clamp target zoom level to reasonable values |
805 | gAgent.mHUDTargetZoom = llclamp(gAgent.mHUDTargetZoom, 0.1f, 1.f); | 808 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) |
809 | // TODO-RLVa: while hasLockedHUD() isn't slow this is called per frame so find a better way | ||
810 | gAgent.mHUDTargetZoom = llclamp(gAgent.mHUDTargetZoom, | ||
811 | ( (!rlv_handler_t::isEnabled()) || (!gRlvHandler.hasLockedHUD()) ) ? 0.1f : 0.85f, 1.f); | ||
812 | // [/RLVa:KB] | ||
813 | //gAgent.mHUDTargetZoom = llclamp(gAgent.mHUDTargetZoom, 0.1f, 1.f); | ||
806 | // smoothly interpolate current zoom level | 814 | // smoothly interpolate current zoom level |
807 | gAgent.mHUDCurZoom = lerp(gAgent.mHUDCurZoom, gAgent.mHUDTargetZoom, LLCriticalDamp::getInterpolant(0.03f)); | 815 | gAgent.mHUDCurZoom = lerp(gAgent.mHUDCurZoom, gAgent.mHUDTargetZoom, LLCriticalDamp::getInterpolant(0.03f)); |
808 | 816 | ||
diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp index ddebd97..8a92963 100644 --- a/linden/indra/newview/llviewermenu.cpp +++ b/linden/indra/newview/llviewermenu.cpp | |||
@@ -209,6 +209,7 @@ | |||
209 | #include "llwaterparammanager.h" | 209 | #include "llwaterparammanager.h" |
210 | 210 | ||
211 | #include "lltexlayer.h" | 211 | #include "lltexlayer.h" |
212 | #include "primbackup.h" | ||
212 | 213 | ||
213 | #include "jcfloater_animation_list.h" | 214 | #include "jcfloater_animation_list.h" |
214 | #include "llfloaterassetbrowser.h" | 215 | #include "llfloaterassetbrowser.h" |
@@ -222,6 +223,13 @@ void init_debug_ui_menu(LLMenuGL* menu); | |||
222 | void init_debug_xui_menu(LLMenuGL* menu); | 223 | void init_debug_xui_menu(LLMenuGL* menu); |
223 | void init_debug_avatar_menu(LLMenuGL* menu); | 224 | void init_debug_avatar_menu(LLMenuGL* menu); |
224 | void init_debug_baked_texture_menu(LLMenuGL* menu); | 225 | void init_debug_baked_texture_menu(LLMenuGL* menu); |
226 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
227 | #ifdef RLV_DEBUG_TESTS | ||
228 | #include "rlvtest.h" | ||
229 | #endif // RLV_DEBUG_TESTS | ||
230 | #include "rlvfloaterbehaviour.h" | ||
231 | void init_debug_rlva_menu(LLMenuGL* menu); | ||
232 | // [/RLVa:KB] | ||
225 | 233 | ||
226 | BOOL enable_land_build(void*); | 234 | BOOL enable_land_build(void*); |
227 | BOOL enable_object_build(void*); | 235 | BOOL enable_object_build(void*); |
@@ -828,6 +836,19 @@ void init_client_menu(LLMenuGL* menu) | |||
828 | init_debug_world_menu(sub_menu); | 836 | init_debug_world_menu(sub_menu); |
829 | menu->appendMenu(sub_menu); | 837 | menu->appendMenu(sub_menu); |
830 | 838 | ||
839 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.1b | ||
840 | #ifdef RLV_ADVANCED_MENU | ||
841 | if (rlv_handler_t::isEnabled()) | ||
842 | { | ||
843 | sub_menu = new LLMenuGL("RLVa"); | ||
844 | init_debug_rlva_menu(sub_menu); | ||
845 | menu->appendMenu(sub_menu); | ||
846 | sub_menu->setVisible(rlv_handler_t::isEnabled()); | ||
847 | sub_menu->setEnabled(rlv_handler_t::isEnabled()); | ||
848 | } | ||
849 | #endif // RLV_ADVANCED_MENU | ||
850 | // [/RLVa:KB] | ||
851 | |||
831 | sub_menu = new LLMenuGL("UI"); | 852 | sub_menu = new LLMenuGL("UI"); |
832 | init_debug_ui_menu(sub_menu); | 853 | init_debug_ui_menu(sub_menu); |
833 | menu->appendMenu(sub_menu); | 854 | menu->appendMenu(sub_menu); |
@@ -922,6 +943,13 @@ void init_client_menu(LLMenuGL* menu) | |||
922 | &menu_check_control, | 943 | &menu_check_control, |
923 | (void*)"ShowConsoleWindow")); | 944 | (void*)"ShowConsoleWindow")); |
924 | 945 | ||
946 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-1.0.0e | ||
947 | #ifdef RLV_ADVANCED_TOGGLE_RLVA | ||
948 | if (gSavedSettings.controlExists(RLV_SETTING_MAIN)) | ||
949 | menu->append(new LLMenuItemCheckGL("Restrained Life API", &rlvDbgToggleEnabled, NULL, &rlvDbgGetEnabled, NULL)); | ||
950 | #endif // RLV_ADVANCED_TOGGLE_RLVA | ||
951 | // [/RLVa:KB] | ||
952 | |||
925 | if(gSavedSettings.getBOOL("QAMode")) | 953 | if(gSavedSettings.getBOOL("QAMode")) |
926 | { | 954 | { |
927 | LLMenuGL* sub = NULL; | 955 | LLMenuGL* sub = NULL; |
@@ -1369,6 +1397,53 @@ void init_debug_baked_texture_menu(LLMenuGL* menu) | |||
1369 | menu->createJumpKeys(); | 1397 | menu->createJumpKeys(); |
1370 | } | 1398 | } |
1371 | 1399 | ||
1400 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-1.0.0g | ||
1401 | void init_debug_rlva_menu(LLMenuGL* menu) | ||
1402 | { | ||
1403 | // Experimental feature toggles | ||
1404 | { | ||
1405 | /* | ||
1406 | #ifdef RLV_EXPERIMENTAL | ||
1407 | LLMenuGL* sub_menu = new LLMenuGL("Experimental"); | ||
1408 | |||
1409 | menu->appendMenu(sub_menu); | ||
1410 | #endif // RLV_EXPERIMENTAL | ||
1411 | */ | ||
1412 | } | ||
1413 | |||
1414 | // Unit tests | ||
1415 | { | ||
1416 | #ifdef RLV_DEBUG_TESTS | ||
1417 | init_debug_rlva_tests_menu(menu); | ||
1418 | #endif // RLV_DEBUG_TESTS | ||
1419 | } | ||
1420 | |||
1421 | #ifdef RLV_EXTENSION_ENABLE_WEAR | ||
1422 | if (gSavedSettings.controlExists(RLV_SETTING_ENABLEWEAR)) | ||
1423 | { | ||
1424 | menu->append(new LLMenuItemCheckGL("Enable Wear", menu_toggle_control, NULL, menu_check_control, (void*)RLV_SETTING_ENABLEWEAR)); | ||
1425 | menu->appendSeparator(); | ||
1426 | } | ||
1427 | #endif // RLV_EXTENSION_ENABLE_WEAR | ||
1428 | |||
1429 | #ifdef RLV_EXTENSION_HIDELOCKED | ||
1430 | if ( (gSavedSettings.controlExists(RLV_SETTING_HIDELOCKEDLAYER)) && | ||
1431 | (gSavedSettings.controlExists(RLV_SETTING_HIDELOCKEDATTACH)) ) | ||
1432 | { | ||
1433 | menu->append(new LLMenuItemCheckGL("Hide locked layers", menu_toggle_control, NULL, menu_check_control, (void*)RLV_SETTING_HIDELOCKEDLAYER)); | ||
1434 | menu->append(new LLMenuItemCheckGL("Hide locked attachments", menu_toggle_control, NULL, menu_check_control, (void*)RLV_SETTING_HIDELOCKEDATTACH)); | ||
1435 | //sub_menu->append(new LLMenuItemToggleGL("Hide locked inventory", &rlv_handler_t::fHideLockedInventory)); | ||
1436 | menu->appendSeparator(); | ||
1437 | } | ||
1438 | #endif // RLV_EXTENSION_HIDELOCKED | ||
1439 | |||
1440 | #ifdef RLV_EXTENSION_FLOATER_RESTRICTIONS | ||
1441 | // TODO-RLVa: figure out a way to tell if floater_rlv_behaviour.xml exists | ||
1442 | menu->append(new LLMenuItemCallGL("Restrictions...", RlvFloaterBehaviour::show, NULL, NULL)); | ||
1443 | #endif // RLV_EXTENSION_FLOATER_RESTRICTIONS | ||
1444 | } | ||
1445 | // [/RLVa:KB] | ||
1446 | |||
1372 | void init_server_menu(LLMenuGL* menu) | 1447 | void init_server_menu(LLMenuGL* menu) |
1373 | { | 1448 | { |
1374 | { | 1449 | { |
@@ -1521,6 +1596,16 @@ class LLObjectTouch : public view_listener_t | |||
1521 | 1596 | ||
1522 | LLPickInfo pick = LLToolPie::getInstance()->getPick(); | 1597 | LLPickInfo pick = LLToolPie::getInstance()->getPick(); |
1523 | 1598 | ||
1599 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-0.2.0f | ||
1600 | // TODO-RLVa: this code is rather redundant since we'll never get an active selection to show a pie menu for | ||
1601 | // [msg->addVector3("Position", pick.mIntersection) <- see llDetectedTouchPos()] | ||
1602 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && ((!object->isAttachment()) || (!object->permYouOwner())) && | ||
1603 | (dist_vec_squared(gAgent.getPositionAgent(), pick.mIntersection) > 1.5f * 1.5f) ) | ||
1604 | { | ||
1605 | return true; // Can't touch in-world objects (or other avie's attachments) farther than 1.5m away under @fartouch=n | ||
1606 | } | ||
1607 | // [/RLVa:KB] | ||
1608 | |||
1524 | LLMessageSystem *msg = gMessageSystem; | 1609 | LLMessageSystem *msg = gMessageSystem; |
1525 | 1610 | ||
1526 | msg->newMessageFast(_PREHASH_ObjectGrab); | 1611 | msg->newMessageFast(_PREHASH_ObjectGrab); |
@@ -1569,6 +1654,14 @@ class LLObjectEnableTouch : public view_listener_t | |||
1569 | { | 1654 | { |
1570 | LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); | 1655 | LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); |
1571 | bool new_value = obj && obj->flagHandleTouch(); | 1656 | bool new_value = obj && obj->flagHandleTouch(); |
1657 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-0.2.0f | ||
1658 | // TODO-RLVa: this code is rather redundant since we'll never get an active selection to show a pie menu for | ||
1659 | if ( (new_value) && (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && ((!obj->isAttachment()) || (!obj->permYouOwner())) && | ||
1660 | (dist_vec_squared(gAgent.getPositionAgent(), LLToolPie::getInstance()->getPick().mIntersection) > 1.5f * 1.5f) ) | ||
1661 | { | ||
1662 | new_value = false; // Can't touch in-world objects (or other avie's attachments) farther than 1.5m away under @fartouch=n | ||
1663 | } | ||
1664 | // [/RLVa:KB] | ||
1572 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); | 1665 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); |
1573 | 1666 | ||
1574 | // Update label based on the node touch name if available. | 1667 | // Update label based on the node touch name if available. |
@@ -1637,6 +1730,14 @@ class LLObjectOpen : public view_listener_t | |||
1637 | { | 1730 | { |
1638 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 1731 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
1639 | { | 1732 | { |
1733 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0b) | ||
1734 | // TODO-RLVa: shouldn't we be checking for fartouch here as well? | ||
1735 | if (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) | ||
1736 | { | ||
1737 | return true; | ||
1738 | } | ||
1739 | // [/RLVa:KB] | ||
1740 | |||
1640 | return handle_object_open(); | 1741 | return handle_object_open(); |
1641 | } | 1742 | } |
1642 | }; | 1743 | }; |
@@ -1655,6 +1756,12 @@ class LLObjectEnableOpen : public view_listener_t | |||
1655 | if (!root) new_value = false; | 1756 | if (!root) new_value = false; |
1656 | else new_value = root->allowOpen(); | 1757 | else new_value = root->allowOpen(); |
1657 | } | 1758 | } |
1759 | |||
1760 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0b) | Modified: RLVa-1.0.0b | ||
1761 | // TODO-RLV: shouldn't we be checking for fartouch here as well? (and LLViewerObject::allowOpen() makes this redundant?) | ||
1762 | new_value &= !gRlvHandler.hasBehaviour(RLV_BHVR_EDIT); | ||
1763 | // [/RLVa:KB] | ||
1764 | |||
1658 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); | 1765 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); |
1659 | return true; | 1766 | return true; |
1660 | } | 1767 | } |
@@ -1716,7 +1823,13 @@ bool toggle_build_mode() | |||
1716 | } | 1823 | } |
1717 | } | 1824 | } |
1718 | 1825 | ||
1719 | 1826 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | |
1827 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) && (LLSelectMgr::getInstance()) ) | ||
1828 | { | ||
1829 | LLSelectMgr::getInstance()->deselectAll(); | ||
1830 | } | ||
1831 | // [/RLVa:KB] | ||
1832 | |||
1720 | LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); | 1833 | LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); |
1721 | LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() ); | 1834 | LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() ); |
1722 | 1835 | ||
@@ -1816,6 +1929,23 @@ class LLObjectEdit : public view_listener_t | |||
1816 | { | 1929 | { |
1817 | LLViewerParcelMgr::getInstance()->deselectLand(); | 1930 | LLViewerParcelMgr::getInstance()->deselectLand(); |
1818 | 1931 | ||
1932 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f | ||
1933 | if (rlv_handler_t::isEnabled()) | ||
1934 | { | ||
1935 | if (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) | ||
1936 | { | ||
1937 | return true; // Can't edit any object under @edit=n | ||
1938 | } | ||
1939 | else if ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && | ||
1940 | (SELECT_TYPE_WORLD == LLSelectMgr::getInstance()->getSelection()->getSelectType()) && | ||
1941 | (dist_vec_squared(gAgent.getPositionAgent(), LLToolPie::getInstance()->getPick().mIntersection) > 1.5f * 1.5f) ) | ||
1942 | { | ||
1943 | // TODO-RLVa: this code is rather redundant since we'll never get an active selection to show a pie menu for | ||
1944 | return true; // Can't edit in-world objects farther than 1.5m away under @fartouch=n | ||
1945 | } | ||
1946 | } | ||
1947 | // [/RLVa:KB] | ||
1948 | |||
1819 | if (gAgent.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit()) | 1949 | if (gAgent.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit()) |
1820 | { | 1950 | { |
1821 | LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); | 1951 | LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); |
@@ -1965,6 +2095,22 @@ class LLEnableEdit : public view_listener_t | |||
1965 | enable = LLViewerParcelMgr::getInstance()->agentCanBuild() | 2095 | enable = LLViewerParcelMgr::getInstance()->agentCanBuild() |
1966 | || LLSelectMgr::getInstance()->getSelection()->isAttachment(); | 2096 | || LLSelectMgr::getInstance()->getSelection()->isAttachment(); |
1967 | } | 2097 | } |
2098 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | ||
2099 | // TODO-RLV: include fartouch here? | ||
2100 | if ( (rlv_handler_t::isEnabled()) && (enable) ) | ||
2101 | { | ||
2102 | // We have no way of knowing whether we're being called for "Create" or for "Edit", but we can | ||
2103 | // make an educated guess based on the currently active selection which puts us halfway there. | ||
2104 | BOOL fActiveSelection = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); | ||
2105 | |||
2106 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) && (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) ) | ||
2107 | enable = false; // Edit and rez restricted, disable them both | ||
2108 | else if ( (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) && (fActiveSelection) ) | ||
2109 | enable = false; // Edit restricted and there's an active selection => disable Edit and Create | ||
2110 | else if ( (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) && (!fActiveSelection) ) | ||
2111 | enable = false; // Rez restricted and there's no active selection => disable Create | ||
2112 | } | ||
2113 | // [/RLVa:KB] | ||
1968 | gMenuHolder->findControl(userdata["control"].asString())->setValue(enable); | 2114 | gMenuHolder->findControl(userdata["control"].asString())->setValue(enable); |
1969 | return true; | 2115 | return true; |
1970 | } | 2116 | } |
@@ -1992,7 +2138,10 @@ class LLSelfEnableRemoveAllAttachments : public view_listener_t | |||
1992 | { | 2138 | { |
1993 | LLVOAvatar::attachment_map_t::iterator curiter = iter++; | 2139 | LLVOAvatar::attachment_map_t::iterator curiter = iter++; |
1994 | LLViewerJointAttachment* attachment = curiter->second; | 2140 | LLViewerJointAttachment* attachment = curiter->second; |
1995 | if (attachment->getObject()) | 2141 | // if (attachment->getObject()) |
2142 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-0.2.0c | ||
2143 | if ( (attachment->getObject()) && ( (!rlv_handler_t::isEnabled()) || (gRlvHandler.isDetachable(curiter->first)) ) ) | ||
2144 | // [/RLVa:KB] | ||
1996 | { | 2145 | { |
1997 | new_value = true; | 2146 | new_value = true; |
1998 | break; | 2147 | break; |
@@ -2039,6 +2188,9 @@ class LLObjectEnableMute : public view_listener_t | |||
2039 | BOOL is_linden = lastname && !LLStringUtil::compareStrings(lastname->getString(), "Linden"); | 2188 | BOOL is_linden = lastname && !LLStringUtil::compareStrings(lastname->getString(), "Linden"); |
2040 | BOOL is_self = avatar->isSelf(); | 2189 | BOOL is_self = avatar->isSelf(); |
2041 | new_value = !is_linden && !is_self; | 2190 | new_value = !is_linden && !is_self; |
2191 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
2192 | new_value &= (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)); | ||
2193 | // [/RLVa:KB] | ||
2042 | } | 2194 | } |
2043 | } | 2195 | } |
2044 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); | 2196 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); |
@@ -2059,6 +2211,12 @@ class LLObjectMute : public view_listener_t | |||
2059 | LLVOAvatar* avatar = find_avatar_from_object(object); | 2211 | LLVOAvatar* avatar = find_avatar_from_object(object); |
2060 | if (avatar) | 2212 | if (avatar) |
2061 | { | 2213 | { |
2214 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-1.0.0e | ||
2215 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
2216 | { | ||
2217 | return true; // Fallback code [see LLObjectEnableMute::handleEvent()] | ||
2218 | } | ||
2219 | // [/RLVa:KB] | ||
2062 | id = avatar->getID(); | 2220 | id = avatar->getID(); |
2063 | 2221 | ||
2064 | LLNameValue *firstname = avatar->getNVPair("FirstName"); | 2222 | LLNameValue *firstname = avatar->getNVPair("FirstName"); |
@@ -2107,8 +2265,155 @@ class LLObjectMute : public view_listener_t | |||
2107 | } | 2265 | } |
2108 | }; | 2266 | }; |
2109 | 2267 | ||
2268 | class LLObjectEnableCopyUUID : public view_listener_t | ||
2269 | { | ||
2270 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | ||
2271 | { | ||
2272 | LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); | ||
2273 | bool new_value = (object != NULL); | ||
2274 | |||
2275 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); | ||
2276 | return true; | ||
2277 | } | ||
2278 | }; | ||
2279 | |||
2280 | class LLObjectCopyUUID : public view_listener_t | ||
2281 | { | ||
2282 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | ||
2283 | { | ||
2284 | LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); | ||
2285 | if (!object) return true; | ||
2286 | |||
2287 | LLUUID id = object->getID(); | ||
2288 | |||
2289 | char buffer[UUID_STR_LENGTH]; | ||
2290 | id.toString(buffer); | ||
2291 | |||
2292 | |||
2293 | gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(buffer)); | ||
2294 | |||
2295 | LLSelectMgr::getInstance()->deselectAll(); | ||
2296 | return true; | ||
2297 | } | ||
2298 | }; | ||
2299 | |||
2300 | |||
2301 | class LLObjectEnableExport : public view_listener_t | ||
2302 | { | ||
2303 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | ||
2304 | { | ||
2305 | LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); | ||
2306 | bool new_value = (object != NULL); | ||
2307 | if (new_value) | ||
2308 | { | ||
2309 | LLVOAvatar* avatar = find_avatar_from_object(object); | ||
2310 | new_value = (avatar == NULL); | ||
2311 | } | ||
2312 | if(new_value) | ||
2313 | { | ||
2314 | |||
2315 | struct ff : public LLSelectedNodeFunctor | ||
2316 | { | ||
2317 | ff(const LLSD& data) : LLSelectedNodeFunctor() | ||
2318 | ,userdata(data) | ||
2319 | { | ||
2320 | |||
2321 | } | ||
2322 | const LLSD& userdata; | ||
2323 | virtual bool apply(LLSelectNode* node) | ||
2324 | { | ||
2325 | if(gAgent.getID()!=node->mPermissions->getCreator()) | ||
2326 | { | ||
2327 | llwarns<<"Incorrect permission to export"<<llendl; | ||
2328 | return false; | ||
2329 | } | ||
2330 | return true; | ||
2331 | } | ||
2332 | }; | ||
2333 | |||
2334 | #ifdef LL_GRID_PERMISSIONS | ||
2335 | |||
2336 | ff * the_ff=new ff(userdata); | ||
2337 | if(LLSelectMgr::getInstance()->getSelection()->applyToNodes(the_ff,false)) | ||
2338 | { | ||
2339 | gMenuHolder->findControl(userdata["control"].asString())->setValue(true); | ||
2340 | } | ||
2341 | else | ||
2342 | { | ||
2343 | gMenuHolder->findControl(userdata["control"].asString())->setValue(false); | ||
2344 | } | ||
2345 | return true; | ||
2346 | } | ||
2347 | |||
2348 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); | ||
2349 | return true; | ||
2350 | #else | ||
2351 | } | ||
2352 | gMenuHolder->findControl(userdata["control"].asString())->setValue(true); | ||
2353 | return true; | ||
2354 | #endif | ||
2355 | |||
2356 | } | ||
2357 | }; | ||
2358 | |||
2359 | class LLObjectExport : public view_listener_t | ||
2360 | { | ||
2361 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | ||
2362 | { | ||
2363 | LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); | ||
2364 | if (!object) return true; | ||
2365 | |||
2366 | LLVOAvatar* avatar = find_avatar_from_object(object); | ||
2367 | |||
2368 | if (!avatar) | ||
2369 | { | ||
2370 | primbackup::getInstance()->pre_export_object(); | ||
2371 | } | ||
2372 | |||
2373 | return true; | ||
2374 | } | ||
2375 | }; | ||
2376 | |||
2377 | |||
2378 | class LLObjectEnableImport : public view_listener_t | ||
2379 | { | ||
2380 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | ||
2381 | { | ||
2382 | gMenuHolder->findControl(userdata["control"].asString())->setValue(TRUE); | ||
2383 | return true; | ||
2384 | } | ||
2385 | }; | ||
2386 | |||
2387 | class LLObjectImport : public view_listener_t | ||
2388 | { | ||
2389 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | ||
2390 | { | ||
2391 | primbackup::getInstance()->import_object(FALSE); | ||
2392 | return true; | ||
2393 | } | ||
2394 | }; | ||
2395 | |||
2396 | class LLObjectImportUpload : public view_listener_t | ||
2397 | { | ||
2398 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | ||
2399 | { | ||
2400 | primbackup::getInstance()->import_object(TRUE); | ||
2401 | return true; | ||
2402 | } | ||
2403 | }; | ||
2404 | |||
2110 | bool handle_go_to() | 2405 | bool handle_go_to() |
2111 | { | 2406 | { |
2407 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
2408 | if ( (rlv_handler_t::isEnabled()) && gAgent.forwardGrabbed() && (gRlvHandler.hasLockedAttachment()) ) | ||
2409 | { | ||
2410 | return true; | ||
2411 | } | ||
2412 | // [/RLVa:KB] | ||
2413 | |||
2414 | // JAMESDEBUG try simulator autopilot | ||
2415 | std::vector<std::string> strings; | ||
2416 | std::string val; | ||
2112 | LLVector3d pos = LLToolPie::getInstance()->getPick().mPosGlobal; | 2417 | LLVector3d pos = LLToolPie::getInstance()->getPick().mPosGlobal; |
2113 | if (gSavedSettings.getBOOL("DoubleClickTeleport")) | 2418 | if (gSavedSettings.getBOOL("DoubleClickTeleport")) |
2114 | { | 2419 | { |
@@ -2200,6 +2505,12 @@ class LLAvatarFreeze : public view_listener_t | |||
2200 | { | 2505 | { |
2201 | LLUUID* avatar_id = new LLUUID( avatar->getID() ); | 2506 | LLUUID* avatar_id = new LLUUID( avatar->getID() ); |
2202 | std::string fullname = avatar->getFullname(); | 2507 | std::string fullname = avatar->getFullname(); |
2508 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-08 (RLVa-1.0.0e) | ||
2509 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (!fullname.empty()) ) | ||
2510 | { | ||
2511 | fullname = gRlvHandler.getAnonym(fullname); | ||
2512 | } | ||
2513 | // [/RLVa:KB] | ||
2203 | 2514 | ||
2204 | if (!fullname.empty()) | 2515 | if (!fullname.empty()) |
2205 | { | 2516 | { |
@@ -2225,7 +2536,11 @@ class LLAvatarVisibleDebug : public view_listener_t | |||
2225 | { | 2536 | { |
2226 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 2537 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
2227 | { | 2538 | { |
2228 | bool new_value = gAgent.isGodlike(); | 2539 | //bool new_value = gAgent.isGodlike(); |
2540 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
2541 | // TODO-RLVa: can you actually use this to cheat anything? | ||
2542 | bool new_value = gAgent.isGodlike() && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)); | ||
2543 | // [/RLVa:KB] | ||
2229 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); | 2544 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); |
2230 | return true; | 2545 | return true; |
2231 | } | 2546 | } |
@@ -2337,6 +2652,12 @@ class LLAvatarEject : public view_listener_t | |||
2337 | MenuCallbackData *data = new MenuCallbackData; | 2652 | MenuCallbackData *data = new MenuCallbackData; |
2338 | (*data).avatar_id = avatar->getID(); | 2653 | (*data).avatar_id = avatar->getID(); |
2339 | std::string fullname = avatar->getFullname(); | 2654 | std::string fullname = avatar->getFullname(); |
2655 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-08 (RLVa-1.0.0e) | ||
2656 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (!fullname.empty()) ) | ||
2657 | { | ||
2658 | fullname = gRlvHandler.getAnonym(fullname); | ||
2659 | } | ||
2660 | // [/RLVa:KB] | ||
2340 | 2661 | ||
2341 | const LLVector3d& pos = avatar->getPositionGlobal(); | 2662 | const LLVector3d& pos = avatar->getPositionGlobal(); |
2342 | LLParcel* parcel = LLViewerParcelMgr::getInstance()->selectParcelAt(pos)->getParcel(); | 2663 | LLParcel* parcel = LLViewerParcelMgr::getInstance()->selectParcelAt(pos)->getParcel(); |
@@ -2418,6 +2739,13 @@ class LLAvatarGiveCard : public view_listener_t | |||
2418 | { | 2739 | { |
2419 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 2740 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
2420 | { | 2741 | { |
2742 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
2743 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
2744 | { | ||
2745 | return true; | ||
2746 | } | ||
2747 | // [/RLVa:KB] | ||
2748 | |||
2421 | llinfos << "handle_give_card()" << llendl; | 2749 | llinfos << "handle_give_card()" << llendl; |
2422 | LLViewerObject* dest = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); | 2750 | LLViewerObject* dest = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); |
2423 | if(dest && dest->isAvatar()) | 2751 | if(dest && dest->isAvatar()) |
@@ -2667,6 +2995,13 @@ class LLSelfStandUp : public view_listener_t | |||
2667 | { | 2995 | { |
2668 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 2996 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
2669 | { | 2997 | { |
2998 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
2999 | if (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) | ||
3000 | { | ||
3001 | return true; | ||
3002 | } | ||
3003 | // [/RLVa:KB] | ||
3004 | |||
2670 | gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); | 3005 | gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); |
2671 | return true; | 3006 | return true; |
2672 | } | 3007 | } |
@@ -2676,7 +3011,10 @@ class LLSelfEnableStandUp : public view_listener_t | |||
2676 | { | 3011 | { |
2677 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 3012 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
2678 | { | 3013 | { |
2679 | bool new_value = gAgent.getAvatarObject() && gAgent.getAvatarObject()->mIsSitting; | 3014 | // bool new_value = gAgent.getAvatarObject() && gAgent.getAvatarObject()->mIsSitting; |
3015 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
3016 | bool new_value = gAgent.getAvatarObject() && gAgent.getAvatarObject()->mIsSitting && !gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT); | ||
3017 | // [/RLVa:KB] | ||
2680 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); | 3018 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); |
2681 | return true; | 3019 | return true; |
2682 | } | 3020 | } |
@@ -2851,6 +3189,11 @@ class LLAvatarEnableAddFriend : public view_listener_t | |||
2851 | { | 3189 | { |
2852 | LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); | 3190 | LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); |
2853 | bool new_value = avatar && !is_agent_friend(avatar->getID()); | 3191 | bool new_value = avatar && !is_agent_friend(avatar->getID()); |
3192 | |||
3193 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
3194 | new_value &= (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)); | ||
3195 | // [/RLVa:KB] | ||
3196 | |||
2854 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); | 3197 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); |
2855 | return true; | 3198 | return true; |
2856 | } | 3199 | } |
@@ -2909,6 +3252,15 @@ bool handle_sit_or_stand() | |||
2909 | return true; | 3252 | return true; |
2910 | } | 3253 | } |
2911 | 3254 | ||
3255 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0c) | ||
3256 | if ( (rlv_handler_t::isEnabled()) && | ||
3257 | ( ((gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (gAgent.getAvatarObject()) && (gAgent.getAvatarObject()->mIsSitting)) || | ||
3258 | (gRlvHandler.hasBehaviour(RLV_BHVR_SIT)) ) ) | ||
3259 | { | ||
3260 | return true; | ||
3261 | } | ||
3262 | // [/RLVa:KB] | ||
3263 | |||
2912 | if (sitting_on_selection()) | 3264 | if (sitting_on_selection()) |
2913 | { | 3265 | { |
2914 | gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); | 3266 | gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); |
@@ -2919,6 +3271,15 @@ bool handle_sit_or_stand() | |||
2919 | 3271 | ||
2920 | if (object && object->getPCode() == LL_PCODE_VOLUME) | 3272 | if (object && object->getPCode() == LL_PCODE_VOLUME) |
2921 | { | 3273 | { |
3274 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0g | ||
3275 | if ( (rlv_handler_t::isEnabled()) && | ||
3276 | ((gRlvHandler.hasBehaviour(RLV_BHVR_SITTP)) || (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH))) && | ||
3277 | (dist_vec_squared(gAgent.getPositionGlobal(), object->getPositionGlobal() + LLVector3d(pick.mObjectOffset)) > 1.5f * 1.5f) ) | ||
3278 | { | ||
3279 | return true; // Don't allow sitting farther away than 1.5m under @sittp=n or @fartouch=n | ||
3280 | } | ||
3281 | // [/RLVa:KB] | ||
3282 | |||
2922 | gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit); | 3283 | gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit); |
2923 | gMessageSystem->nextBlockFast(_PREHASH_AgentData); | 3284 | gMessageSystem->nextBlockFast(_PREHASH_AgentData); |
2924 | gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); | 3285 | gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); |
@@ -2956,6 +3317,13 @@ class LLLandSit : public view_listener_t | |||
2956 | { | 3317 | { |
2957 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 3318 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
2958 | { | 3319 | { |
3320 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
3321 | if (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) | ||
3322 | { | ||
3323 | return true; | ||
3324 | } | ||
3325 | // [/RLVa:KB] | ||
3326 | |||
2959 | gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); | 3327 | gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); |
2960 | LLViewerParcelMgr::getInstance()->deselectLand(); | 3328 | LLViewerParcelMgr::getInstance()->deselectLand(); |
2961 | 3329 | ||
@@ -3266,6 +3634,14 @@ class LLEditDuplicate : public view_listener_t | |||
3266 | { | 3634 | { |
3267 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 3635 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
3268 | { | 3636 | { |
3637 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | ||
3638 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) && | ||
3639 | (LLEditMenuHandler::gEditMenuHandler == LLSelectMgr::getInstance()) ) | ||
3640 | { | ||
3641 | return true; | ||
3642 | } | ||
3643 | // [/RLVa:KB] | ||
3644 | |||
3269 | if(LLEditMenuHandler::gEditMenuHandler) | 3645 | if(LLEditMenuHandler::gEditMenuHandler) |
3270 | { | 3646 | { |
3271 | LLEditMenuHandler::gEditMenuHandler->duplicate(); | 3647 | LLEditMenuHandler::gEditMenuHandler->duplicate(); |
@@ -3279,6 +3655,13 @@ class LLEditEnableDuplicate : public view_listener_t | |||
3279 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 3655 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
3280 | { | 3656 | { |
3281 | bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDuplicate(); | 3657 | bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDuplicate(); |
3658 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | ||
3659 | if ( (new_value) && (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) && | ||
3660 | (LLEditMenuHandler::gEditMenuHandler == LLSelectMgr::getInstance()) ) | ||
3661 | { | ||
3662 | new_value = false; | ||
3663 | } | ||
3664 | // [/RLVa:KB] | ||
3282 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); | 3665 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); |
3283 | return true; | 3666 | return true; |
3284 | } | 3667 | } |
@@ -3664,6 +4047,11 @@ class LLToolsTakeCopy : public view_listener_t | |||
3664 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 4047 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
3665 | { | 4048 | { |
3666 | if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return true; | 4049 | if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return true; |
4050 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | Modified: RLVa-1.0.0b | ||
4051 | // NOTE: we need to handle "Take Copy" because it will force a sim-side unsit if we're sitting on the selection, | ||
4052 | // but we do want to allow "Take Copy" under @rez=n so that's why we explicitly check for @unsit=n here | ||
4053 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (!rlvCanDeleteOrReturn()) ) return true; | ||
4054 | // [/RLVa:KB] | ||
3667 | 4055 | ||
3668 | const LLUUID& category_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_OBJECT); | 4056 | const LLUUID& category_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_OBJECT); |
3669 | derez_objects(DRD_ACQUIRE_TO_AGENT_INVENTORY, category_id); | 4057 | derez_objects(DRD_ACQUIRE_TO_AGENT_INVENTORY, category_id); |
@@ -3679,6 +4067,9 @@ class LLObjectReturn : public view_listener_t | |||
3679 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 4067 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
3680 | { | 4068 | { |
3681 | if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return true; | 4069 | if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return true; |
4070 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-05 (RLVa-1.0.0b) | ||
4071 | if ( (rlv_handler_t::isEnabled()) && (!rlvCanDeleteOrReturn()) ) return true; | ||
4072 | // [/RLVa:KB] | ||
3682 | 4073 | ||
3683 | mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); | 4074 | mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); |
3684 | 4075 | ||
@@ -3748,6 +4139,14 @@ class LLObjectEnableReturn : public view_listener_t | |||
3748 | } | 4139 | } |
3749 | } | 4140 | } |
3750 | #endif | 4141 | #endif |
4142 | |||
4143 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | ||
4144 | if ( (new_value) && (rlv_handler_t::isEnabled()) ) | ||
4145 | { | ||
4146 | new_value = rlvCanDeleteOrReturn(); | ||
4147 | } | ||
4148 | // [/RLVa:KB] | ||
4149 | |||
3751 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); | 4150 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); |
3752 | return true; | 4151 | return true; |
3753 | } | 4152 | } |
@@ -3769,6 +4168,13 @@ void handle_take() | |||
3769 | return; | 4168 | return; |
3770 | } | 4169 | } |
3771 | 4170 | ||
4171 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | ||
4172 | if ( (rlv_handler_t::isEnabled()) && (!rlvCanDeleteOrReturn()) ) | ||
4173 | { | ||
4174 | return; | ||
4175 | } | ||
4176 | // [/RLVa:KB] | ||
4177 | |||
3772 | BOOL you_own_everything = TRUE; | 4178 | BOOL you_own_everything = TRUE; |
3773 | BOOL locked_but_takeable_object = FALSE; | 4179 | BOOL locked_but_takeable_object = FALSE; |
3774 | LLUUID category_id; | 4180 | LLUUID category_id; |
@@ -3890,6 +4296,13 @@ BOOL enable_take() | |||
3890 | return FALSE; | 4296 | return FALSE; |
3891 | } | 4297 | } |
3892 | 4298 | ||
4299 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | ||
4300 | if ( (rlv_handler_t::isEnabled()) && (!rlvCanDeleteOrReturn()) ) | ||
4301 | { | ||
4302 | return FALSE; | ||
4303 | } | ||
4304 | // [/RLVa:KB] | ||
4305 | |||
3893 | for (LLObjectSelection::valid_root_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_root_begin(); | 4306 | for (LLObjectSelection::valid_root_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_root_begin(); |
3894 | iter != LLSelectMgr::getInstance()->getSelection()->valid_root_end(); iter++) | 4307 | iter != LLSelectMgr::getInstance()->getSelection()->valid_root_end(); iter++) |
3895 | { | 4308 | { |
@@ -4212,6 +4625,21 @@ class LLToolsEnableUnlink : public view_listener_t | |||
4212 | new_value = true; | 4625 | new_value = true; |
4213 | } | 4626 | } |
4214 | } | 4627 | } |
4628 | |||
4629 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0g | ||
4630 | // The user might not be allowed to unlink this object due to RLV settings, | ||
4631 | // because it would unsit them if they are sitting on the object. | ||
4632 | if ( (new_value) && (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && | ||
4633 | (gAgent.getAvatarObject()) && (gAgent.getAvatarObject()->mIsSitting) ) | ||
4634 | { | ||
4635 | // Allow if the avie isn't sitting on any of the selected objects | ||
4636 | LLObjectSelectionHandle handleSel = LLSelectMgr::getInstance()->getSelection(); | ||
4637 | RlvSelectIsSittingOn func(gAgent.getAvatarObject()->getRoot()); | ||
4638 | if (handleSel->getFirstRootNode(&func, TRUE)) | ||
4639 | new_value = false; | ||
4640 | } | ||
4641 | // [/RLVa:KB] | ||
4642 | |||
4215 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); | 4643 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); |
4216 | return true; | 4644 | return true; |
4217 | } | 4645 | } |
@@ -4221,6 +4649,19 @@ class LLToolsUnlink : public view_listener_t | |||
4221 | { | 4649 | { |
4222 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 4650 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
4223 | { | 4651 | { |
4652 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0g | ||
4653 | // The user might not be allowed to unlink this object due to RLV settings, | ||
4654 | // because it would unsit them if they are sitting on the object. | ||
4655 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (gAgent.getAvatarObject()) && (gAgent.getAvatarObject()->mIsSitting) ) | ||
4656 | { | ||
4657 | // Allow if the avie isn't sitting on any of the selected objects | ||
4658 | LLObjectSelectionHandle handleSel = LLSelectMgr::getInstance()->getSelection(); | ||
4659 | RlvSelectIsSittingOn func(gAgent.getAvatarObject()->getRoot()); | ||
4660 | if (handleSel->getFirstRootNode(&func, TRUE)) | ||
4661 | return true; | ||
4662 | } | ||
4663 | // [/RLVa:KB] | ||
4664 | |||
4224 | LLSelectMgr::getInstance()->sendDelink(); | 4665 | LLSelectMgr::getInstance()->sendDelink(); |
4225 | return true; | 4666 | return true; |
4226 | } | 4667 | } |
@@ -4240,6 +4681,13 @@ class LLToolsReleaseKeys : public view_listener_t | |||
4240 | { | 4681 | { |
4241 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 4682 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
4242 | { | 4683 | { |
4684 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
4685 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment()) ) | ||
4686 | { | ||
4687 | return true; | ||
4688 | } | ||
4689 | // [/RLVa:KB] | ||
4690 | |||
4243 | gAgent.forceReleaseControls(); | 4691 | gAgent.forceReleaseControls(); |
4244 | 4692 | ||
4245 | return true; | 4693 | return true; |
@@ -4250,7 +4698,11 @@ class LLToolsEnableReleaseKeys : public view_listener_t | |||
4250 | { | 4698 | { |
4251 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 4699 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
4252 | { | 4700 | { |
4253 | gMenuHolder->findControl(userdata["control"].asString())->setValue( gAgent.anyControlGrabbed() ); | 4701 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) |
4702 | gMenuHolder->findControl(userdata["control"].asString())->setValue( | ||
4703 | gAgent.anyControlGrabbed() && ( (!rlv_handler_t::isEnabled()) || (!gRlvHandler.hasLockedAttachment() ) ) ); | ||
4704 | // [/RLVa:KB] | ||
4705 | //gMenuHolder->findControl(userdata["control"].asString())->setValue( gAgent.anyControlGrabbed() ); | ||
4254 | return true; | 4706 | return true; |
4255 | } | 4707 | } |
4256 | }; | 4708 | }; |
@@ -4358,6 +4810,15 @@ class LLEditEnableDelete : public view_listener_t | |||
4358 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 4810 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
4359 | { | 4811 | { |
4360 | bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDoDelete(); | 4812 | bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDoDelete(); |
4813 | |||
4814 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | ||
4815 | // NOTE: we want to disable delete on objects but not disable delete on text | ||
4816 | if ( (new_value) && (rlv_handler_t::isEnabled()) && (LLEditMenuHandler::gEditMenuHandler == LLSelectMgr::getInstance()) ) | ||
4817 | { | ||
4818 | new_value = rlvCanDeleteOrReturn(); | ||
4819 | } | ||
4820 | // [/RLVa:KB] | ||
4821 | |||
4361 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); | 4822 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); |
4362 | return true; | 4823 | return true; |
4363 | } | 4824 | } |
@@ -4367,6 +4828,15 @@ class LLEditDelete : public view_listener_t | |||
4367 | { | 4828 | { |
4368 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 4829 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
4369 | { | 4830 | { |
4831 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | ||
4832 | // NOTE: we want to disable delete on objects but not disable delete on text | ||
4833 | if ( (rlv_handler_t::isEnabled()) && (LLEditMenuHandler::gEditMenuHandler == LLSelectMgr::getInstance()) && | ||
4834 | (!rlvCanDeleteOrReturn()) ) | ||
4835 | { | ||
4836 | return true; | ||
4837 | } | ||
4838 | // [/RLVa:KB] | ||
4839 | |||
4370 | // If a text field can do a deletion, it gets precedence over deleting | 4840 | // If a text field can do a deletion, it gets precedence over deleting |
4371 | // an object in the world. | 4841 | // an object in the world. |
4372 | if( LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDoDelete()) | 4842 | if( LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDoDelete()) |
@@ -4398,6 +4868,12 @@ class LLObjectEnableDelete : public view_listener_t | |||
4398 | # endif | 4868 | # endif |
4399 | LLSelectMgr::getInstance()->canDoDelete(); | 4869 | LLSelectMgr::getInstance()->canDoDelete(); |
4400 | #endif | 4870 | #endif |
4871 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | ||
4872 | if ( (new_value) && (rlv_handler_t::isEnabled()) ) | ||
4873 | { | ||
4874 | new_value = rlvCanDeleteOrReturn(); | ||
4875 | } | ||
4876 | // [/RLVa:KB] | ||
4401 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); | 4877 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); |
4402 | return true; | 4878 | return true; |
4403 | } | 4879 | } |
@@ -4416,6 +4892,13 @@ class LLObjectDelete : public view_listener_t | |||
4416 | { | 4892 | { |
4417 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 4893 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
4418 | { | 4894 | { |
4895 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | ||
4896 | if ( (rlv_handler_t::isEnabled()) && (!rlvCanDeleteOrReturn()) ) | ||
4897 | { | ||
4898 | return true; | ||
4899 | } | ||
4900 | // [/RLVa:KB] | ||
4901 | |||
4419 | if (LLSelectMgr::getInstance()) | 4902 | if (LLSelectMgr::getInstance()) |
4420 | { | 4903 | { |
4421 | LLSelectMgr::getInstance()->doDelete(); | 4904 | LLSelectMgr::getInstance()->doDelete(); |
@@ -4765,6 +5248,12 @@ class LLWorldCreateLandmark : public view_listener_t | |||
4765 | { | 5248 | { |
4766 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 5249 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
4767 | { | 5250 | { |
5251 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
5252 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
5253 | { | ||
5254 | return true; | ||
5255 | } | ||
5256 | // [/RLVa:KB] | ||
4768 | LLViewerRegion* agent_region = gAgent.getRegion(); | 5257 | LLViewerRegion* agent_region = gAgent.getRegion(); |
4769 | if(!agent_region) | 5258 | if(!agent_region) |
4770 | { | 5259 | { |
@@ -4872,6 +5361,13 @@ class LLAvatarInviteToGroup : public view_listener_t | |||
4872 | { | 5361 | { |
4873 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 5362 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
4874 | { | 5363 | { |
5364 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
5365 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
5366 | { | ||
5367 | return true; | ||
5368 | } | ||
5369 | // [/RLVa:KB] | ||
5370 | |||
4875 | LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); | 5371 | LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); |
4876 | if(avatar) | 5372 | if(avatar) |
4877 | { | 5373 | { |
@@ -4885,6 +5381,13 @@ class LLAvatarAddFriend : public view_listener_t | |||
4885 | { | 5381 | { |
4886 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 5382 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
4887 | { | 5383 | { |
5384 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
5385 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
5386 | { | ||
5387 | return true; // Fallback code [see LLAvatarEnableAddFriend::handleEvent()] | ||
5388 | } | ||
5389 | // [/RLVa:KB] | ||
5390 | |||
4888 | LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); | 5391 | LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); |
4889 | if(avatar && !is_agent_friend(avatar->getID())) | 5392 | if(avatar && !is_agent_friend(avatar->getID())) |
4890 | { | 5393 | { |
@@ -4972,6 +5475,12 @@ class LLEnablePayObject : public view_listener_t | |||
4972 | } | 5475 | } |
4973 | } | 5476 | } |
4974 | } | 5477 | } |
5478 | |||
5479 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
5480 | // Don't enable "Pay..." on the avatar pie menu under @shownames=n | ||
5481 | new_value &= (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) || (avatar == NULL); | ||
5482 | // [/RLVa:KB] | ||
5483 | |||
4975 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); | 5484 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); |
4976 | return true; | 5485 | return true; |
4977 | } | 5486 | } |
@@ -5160,6 +5669,12 @@ class LLShowFloater : public view_listener_t | |||
5160 | } | 5669 | } |
5161 | else if (floater_name == "buy land") | 5670 | else if (floater_name == "buy land") |
5162 | { | 5671 | { |
5672 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
5673 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
5674 | { | ||
5675 | return true; | ||
5676 | } | ||
5677 | // [/RLVa:KB] | ||
5163 | if (LLViewerParcelMgr::getInstance()->selectionEmpty()) | 5678 | if (LLViewerParcelMgr::getInstance()->selectionEmpty()) |
5164 | { | 5679 | { |
5165 | LLViewerParcelMgr::getInstance()->selectParcelAt(gAgent.getPositionGlobal()); | 5680 | LLViewerParcelMgr::getInstance()->selectParcelAt(gAgent.getPositionGlobal()); |
@@ -5341,6 +5856,13 @@ class LLShowAgentProfile : public view_listener_t | |||
5341 | } | 5856 | } |
5342 | else if (userdata.asString() == "hit object") | 5857 | else if (userdata.asString() == "hit object") |
5343 | { | 5858 | { |
5859 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
5860 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
5861 | { | ||
5862 | return true; | ||
5863 | } | ||
5864 | // [/RLVa:KB] | ||
5865 | |||
5344 | LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); | 5866 | LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); |
5345 | if (objectp) | 5867 | if (objectp) |
5346 | { | 5868 | { |
@@ -5400,6 +5922,13 @@ class LLLandEdit : public view_listener_t | |||
5400 | { | 5922 | { |
5401 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 5923 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
5402 | { | 5924 | { |
5925 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0b) | ||
5926 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) ) | ||
5927 | { | ||
5928 | return true; | ||
5929 | } | ||
5930 | // [/RLVa:KB] | ||
5931 | |||
5403 | if (gAgent.getFocusOnAvatar() && gSavedSettings.getBOOL("EditCameraMovement") ) | 5932 | if (gAgent.getFocusOnAvatar() && gSavedSettings.getBOOL("EditCameraMovement") ) |
5404 | { | 5933 | { |
5405 | // zoom in if we're looking at the avatar | 5934 | // zoom in if we're looking at the avatar |
@@ -5484,6 +6013,18 @@ private: | |||
5484 | LLViewerJointAttachment* attachment_point = NULL; | 6013 | LLViewerJointAttachment* attachment_point = NULL; |
5485 | if (index > 0) | 6014 | if (index > 0) |
5486 | attachment_point = get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, index, (LLViewerJointAttachment*)NULL); | 6015 | attachment_point = get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, index, (LLViewerJointAttachment*)NULL); |
6016 | |||
6017 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
6018 | if ( (rlv_handler_t::isEnabled()) && | ||
6019 | ( ((index == 0) && (gRlvHandler.hasLockedAttachment())) || // Can't wear on default attach point | ||
6020 | ((index > 0) && (!gRlvHandler.isDetachable(attachment_point->getObject()))) || // Can't replace locked attachment | ||
6021 | (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) ) ) // Attach on rezzed object == "Take" | ||
6022 | { | ||
6023 | setObjectSelection(NULL); // Clear the selection or it'll get stuck | ||
6024 | return true; | ||
6025 | } | ||
6026 | // [/RLVa:KB] | ||
6027 | |||
5487 | confirm_replace_attachment(0, attachment_point); | 6028 | confirm_replace_attachment(0, attachment_point); |
5488 | } | 6029 | } |
5489 | return true; | 6030 | return true; |
@@ -5591,6 +6132,24 @@ class LLAttachmentDrop : public view_listener_t | |||
5591 | return true; | 6132 | return true; |
5592 | } | 6133 | } |
5593 | 6134 | ||
6135 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
6136 | if (rlv_handler_t::isEnabled()) | ||
6137 | { | ||
6138 | if (gRlvHandler.hasLockedAttachment()) | ||
6139 | { | ||
6140 | // NOTE: copy/paste of the code in enable_detach() | ||
6141 | LLObjectSelectionHandle hSelect = LLSelectMgr::getInstance()->getSelection(); | ||
6142 | RlvSelectHasLockedAttach functor; | ||
6143 | if ( (hSelect->isAttachment()) && (hSelect->getFirstRootNode(&functor, FALSE)) ) | ||
6144 | return true; | ||
6145 | } | ||
6146 | else if (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) | ||
6147 | { | ||
6148 | return true; | ||
6149 | } | ||
6150 | } | ||
6151 | // [/RLVa:KB] | ||
6152 | |||
5594 | // The sendDropAttachment() method works on the list of selected | 6153 | // The sendDropAttachment() method works on the list of selected |
5595 | // objects. Thus we need to clear the list, make sure it only | 6154 | // objects. Thus we need to clear the list, make sure it only |
5596 | // contains the object the user clicked, send the message, | 6155 | // contains the object the user clicked, send the message, |
@@ -5609,6 +6168,13 @@ void handle_detach_from_avatar(void* user_data) | |||
5609 | 6168 | ||
5610 | if (attached_object) | 6169 | if (attached_object) |
5611 | { | 6170 | { |
6171 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-0.2.0d | ||
6172 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isDetachable(attached_object)) ) | ||
6173 | { | ||
6174 | return; | ||
6175 | } | ||
6176 | // [/RLVa:KB] | ||
6177 | |||
5612 | gMessageSystem->newMessage("ObjectDetach"); | 6178 | gMessageSystem->newMessage("ObjectDetach"); |
5613 | gMessageSystem->nextBlockFast(_PREHASH_AgentData); | 6179 | gMessageSystem->nextBlockFast(_PREHASH_AgentData); |
5614 | gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); | 6180 | gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); |
@@ -5691,6 +6257,17 @@ class LLAttachmentDetach : public view_listener_t | |||
5691 | return true; | 6257 | return true; |
5692 | } | 6258 | } |
5693 | 6259 | ||
6260 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
6261 | // NOTE: copy/paste of the code in enable_detach() | ||
6262 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment()) ) | ||
6263 | { | ||
6264 | LLObjectSelectionHandle hSelect = LLSelectMgr::getInstance()->getSelection(); | ||
6265 | RlvSelectHasLockedAttach functor; | ||
6266 | if ( (hSelect->isAttachment()) && (hSelect->getFirstRootNode(&functor, FALSE)) ) | ||
6267 | return FALSE; | ||
6268 | } | ||
6269 | // [/RLVa:KB] | ||
6270 | |||
5694 | // The sendDetach() method works on the list of selected | 6271 | // The sendDetach() method works on the list of selected |
5695 | // objects. Thus we need to clear the list, make sure it only | 6272 | // objects. Thus we need to clear the list, make sure it only |
5696 | // contains the object the user clicked, send the message, | 6273 | // contains the object the user clicked, send the message, |
@@ -5774,7 +6351,10 @@ class LLAttachmentEnableDrop : public view_listener_t | |||
5774 | } | 6351 | } |
5775 | 6352 | ||
5776 | //now check to make sure that the item is actually in the inventory before we enable dropping it | 6353 | //now check to make sure that the item is actually in the inventory before we enable dropping it |
5777 | bool new_value = enable_detach(NULL) && can_build && item; | 6354 | // bool new_value = enable_detach(NULL) && can_build && item; |
6355 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | ||
6356 | bool new_value = enable_detach(NULL) && can_build && item && (!gRlvHandler.hasBehaviour(RLV_BHVR_REZ)); | ||
6357 | // [/RLVa:KB] | ||
5778 | 6358 | ||
5779 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); | 6359 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); |
5780 | return true; | 6360 | return true; |
@@ -5794,6 +6374,20 @@ BOOL enable_detach(void*) | |||
5794 | // ...if it's you, good to detach | 6374 | // ...if it's you, good to detach |
5795 | if (avatar->getID() == gAgent.getID()) | 6375 | if (avatar->getID() == gAgent.getID()) |
5796 | { | 6376 | { |
6377 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
6378 | // NOTE: this code is reused as-is in LLAttachmentDetach::handleEvent() and LLAttachmentDrop::handleEvent() | ||
6379 | // so any changes here should be reflected there as well (I think it's in a number of other places as well by now) | ||
6380 | |||
6381 | // RELEASE-RLVa: LLSelectMgr::sendDetach() and LLSelectMgr::sendDropAttachment() call sendListToRegions with | ||
6382 | // SEND_ONLY_ROOTS so we only need to examine the roots which saves us time | ||
6383 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment()) ) | ||
6384 | { | ||
6385 | LLObjectSelectionHandle hSelect = LLSelectMgr::getInstance()->getSelection(); | ||
6386 | RlvSelectHasLockedAttach functor; | ||
6387 | if ( (hSelect->isAttachment()) && (hSelect->getFirstRootNode(&functor, FALSE)) ) | ||
6388 | return FALSE; | ||
6389 | } | ||
6390 | // [/RLVa:KB] | ||
5797 | return TRUE; | 6391 | return TRUE; |
5798 | } | 6392 | } |
5799 | 6393 | ||
@@ -5816,6 +6410,25 @@ class LLAttachmentEnableDetach : public view_listener_t | |||
5816 | // Used to tell if the selected object can be attached to your avatar. | 6410 | // Used to tell if the selected object can be attached to your avatar. |
5817 | BOOL object_selected_and_point_valid(void *user_data) | 6411 | BOOL object_selected_and_point_valid(void *user_data) |
5818 | { | 6412 | { |
6413 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | ||
6414 | if (rlv_handler_t::isEnabled()) | ||
6415 | { | ||
6416 | // RELEASE-RLVa: look at the caller graph for this function on every new release | ||
6417 | // -> 1.22.11 and 1.23.4 | ||
6418 | // - object_is_wearable() => dead code [user_data == NULL => default attach point => OK!] | ||
6419 | // - LLObjectEnableWear::handleEvent() => Rezzed prim / right-click / "Wear" [user_data == NULL => see above] | ||
6420 | // - enabler set up in LLVOAvatar::buildCharacter() => Rezzed prim / right-click / "Attach >" [user_data == pAttachPt] | ||
6421 | // - enabler set up in LLVOAvatar::buildCharacter() => Rezzed prim / Edit menu / "Attach Object" [user_data == pAttachPt] | ||
6422 | LLViewerJointAttachment* pAttachPt = (LLViewerJointAttachment*)user_data; | ||
6423 | if ( ((!pAttachPt) && (gRlvHandler.hasLockedAttachment())) || // Don't allow attach to default attach point | ||
6424 | ((pAttachPt) && (!gRlvHandler.isDetachable(pAttachPt->getObject()))) || // Don't allow replacing of locked attachment | ||
6425 | (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) ) // Attaching a rezzed object == "Take" | ||
6426 | { | ||
6427 | return FALSE; | ||
6428 | } | ||
6429 | } | ||
6430 | // [/RLVa:KB] | ||
6431 | |||
5819 | //LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data; | 6432 | //LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data; |
5820 | LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); | 6433 | LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); |
5821 | for (LLObjectSelection::root_iterator iter = selection->root_begin(); | 6434 | for (LLObjectSelection::root_iterator iter = selection->root_begin(); |
@@ -5883,7 +6496,13 @@ BOOL object_attached(void *user_data) | |||
5883 | { | 6496 | { |
5884 | LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data; | 6497 | LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data; |
5885 | 6498 | ||
5886 | return attachment->getObject() != NULL; | 6499 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) |
6500 | return ( | ||
6501 | (attachment->getObject() != NULL) && | ||
6502 | ( (!rlv_handler_t::isEnabled()) || (gRlvHandler.isDetachable(attachment->getObject())) ) | ||
6503 | ); | ||
6504 | // [/RLVa:KB] | ||
6505 | // return attachment->getObject() != NULL; | ||
5887 | } | 6506 | } |
5888 | 6507 | ||
5889 | class LLAvatarSendIM : public view_listener_t | 6508 | class LLAvatarSendIM : public view_listener_t |
@@ -5891,6 +6510,12 @@ class LLAvatarSendIM : public view_listener_t | |||
5891 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 6510 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
5892 | { | 6511 | { |
5893 | LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); | 6512 | LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); |
6513 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
6514 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
6515 | { | ||
6516 | return true; | ||
6517 | } | ||
6518 | // [/RLVa:KB] | ||
5894 | if(avatar) | 6519 | if(avatar) |
5895 | { | 6520 | { |
5896 | std::string name("IM"); | 6521 | std::string name("IM"); |
@@ -6026,6 +6651,16 @@ class LLToolsSelectedScriptAction : public view_listener_t | |||
6026 | { | 6651 | { |
6027 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 6652 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
6028 | { | 6653 | { |
6654 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
6655 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment()) ) | ||
6656 | { | ||
6657 | LLObjectSelectionHandle selectHandle = LLSelectMgr::getInstance()->getSelection(); | ||
6658 | RlvSelectHasLockedAttach functor; | ||
6659 | if ( (selectHandle->isAttachment()) && (selectHandle->getFirstNode(&functor)) ) | ||
6660 | return true; | ||
6661 | } | ||
6662 | // [/RLVa:KB] | ||
6663 | |||
6029 | std::string action = userdata.asString(); | 6664 | std::string action = userdata.asString(); |
6030 | if (action == "compile mono") | 6665 | if (action == "compile mono") |
6031 | { | 6666 | { |
@@ -6110,12 +6745,30 @@ void handle_dump_image_list(void*) | |||
6110 | 6745 | ||
6111 | void handle_test_male(void*) | 6746 | void handle_test_male(void*) |
6112 | { | 6747 | { |
6748 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
6749 | if ( (rlv_handler_t::isEnabled()) && | ||
6750 | ( (gRlvHandler.hasLockedAttachment()) || | ||
6751 | (gRlvHandler.hasBehaviour(RLV_BHVR_ADDOUTFIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_REMOUTFIT)) ) ) | ||
6752 | { | ||
6753 | return; | ||
6754 | } | ||
6755 | // [/RLVa:KB] | ||
6756 | |||
6113 | wear_outfit_by_name("Male Shape & Outfit"); | 6757 | wear_outfit_by_name("Male Shape & Outfit"); |
6114 | //gGestureList.requestResetFromServer( TRUE ); | 6758 | //gGestureList.requestResetFromServer( TRUE ); |
6115 | } | 6759 | } |
6116 | 6760 | ||
6117 | void handle_test_female(void*) | 6761 | void handle_test_female(void*) |
6118 | { | 6762 | { |
6763 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
6764 | if ( (rlv_handler_t::isEnabled()) && | ||
6765 | ( (gRlvHandler.hasLockedAttachment()) || | ||
6766 | (gRlvHandler.hasBehaviour(RLV_BHVR_ADDOUTFIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_REMOUTFIT)) ) ) | ||
6767 | { | ||
6768 | return; | ||
6769 | } | ||
6770 | // [/RLVa:KB] | ||
6771 | |||
6119 | wear_outfit_by_name("Female Shape & Outfit"); | 6772 | wear_outfit_by_name("Female Shape & Outfit"); |
6120 | //gGestureList.requestResetFromServer( FALSE ); | 6773 | //gGestureList.requestResetFromServer( FALSE ); |
6121 | } | 6774 | } |
@@ -6258,6 +6911,22 @@ BOOL enable_more_than_one_selected(void* ) | |||
6258 | 6911 | ||
6259 | static bool is_editable_selected() | 6912 | static bool is_editable_selected() |
6260 | { | 6913 | { |
6914 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-1.0.0c | ||
6915 | // RELEASE-RLVa: check that this still isn't called by anything but script actions in the Tools menu | ||
6916 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment()) ) | ||
6917 | { | ||
6918 | LLObjectSelectionHandle selectHandle = LLSelectMgr::getInstance()->getSelection(); | ||
6919 | |||
6920 | // NOTE: this is called for 5 different menu items so we'll trade accuracy for efficiency and only | ||
6921 | // examine root nodes (LLToolsSelectedScriptAction::handleEvent() will catch what we miss) | ||
6922 | RlvSelectHasLockedAttach functor; | ||
6923 | if ( (selectHandle->isAttachment()) && (selectHandle->getFirstRootNode(&functor)) ) | ||
6924 | { | ||
6925 | return false; | ||
6926 | } | ||
6927 | } | ||
6928 | // [/RLVa:KB] | ||
6929 | |||
6261 | return (LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject() != NULL); | 6930 | return (LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject() != NULL); |
6262 | } | 6931 | } |
6263 | 6932 | ||
@@ -6304,7 +6973,12 @@ class LLToolsEnableTakeCopy : public view_listener_t | |||
6304 | { | 6973 | { |
6305 | virtual bool apply(LLViewerObject* obj) | 6974 | virtual bool apply(LLViewerObject* obj) |
6306 | { | 6975 | { |
6307 | return (!obj->permCopy() || obj->isAttachment()); | 6976 | // return (!obj->permCopy() || obj->isAttachment()); |
6977 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
6978 | return (!obj->permCopy() || obj->isAttachment()) || | ||
6979 | ( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (gAgent.getAvatarObject()) && | ||
6980 | (gAgent.getAvatarObject()->getRoot() == obj) ); | ||
6981 | // [/RLVa:KB] | ||
6308 | } | 6982 | } |
6309 | } func; | 6983 | } func; |
6310 | const bool firstonly = true; | 6984 | const bool firstonly = true; |
@@ -6507,6 +7181,9 @@ class LLWorldEnableCreateLandmark : public view_listener_t | |||
6507 | { | 7181 | { |
6508 | bool new_value = gAgent.isGodlike() || | 7182 | bool new_value = gAgent.isGodlike() || |
6509 | (gAgent.getRegion() && gAgent.getRegion()->getAllowLandmark()); | 7183 | (gAgent.getRegion() && gAgent.getRegion()->getAllowLandmark()); |
7184 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
7185 | new_value &= !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC); | ||
7186 | // [/RLVa:KB] | ||
6510 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); | 7187 | gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); |
6511 | return true; | 7188 | return true; |
6512 | } | 7189 | } |
@@ -6559,7 +7236,11 @@ BOOL enable_god_customer_service(void*) | |||
6559 | 7236 | ||
6560 | BOOL enable_god_basic(void*) | 7237 | BOOL enable_god_basic(void*) |
6561 | { | 7238 | { |
6562 | return gAgent.getGodLevel() > GOD_NOT; | 7239 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) |
7240 | // RELEASE-RLVa: check that this function isn't used for anything other than to enable/disable showing the "God Tools..." floater | ||
7241 | return (gAgent.getGodLevel() > GOD_NOT) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)); | ||
7242 | // [/RLVa:KB] | ||
7243 | //return gAgent.getGodLevel() > GOD_NOT; | ||
6563 | } | 7244 | } |
6564 | 7245 | ||
6565 | #if 0 // 1.9.2 | 7246 | #if 0 // 1.9.2 |
@@ -7070,6 +7751,13 @@ class LLViewHighlightTransparent : public view_listener_t | |||
7070 | { | 7751 | { |
7071 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 7752 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
7072 | { | 7753 | { |
7754 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0b) | ||
7755 | if (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) | ||
7756 | { | ||
7757 | return true; | ||
7758 | } | ||
7759 | // [/RLVa:KB] | ||
7760 | |||
7073 | LLDrawPoolAlpha::sShowDebugAlpha = !LLDrawPoolAlpha::sShowDebugAlpha; | 7761 | LLDrawPoolAlpha::sShowDebugAlpha = !LLDrawPoolAlpha::sShowDebugAlpha; |
7074 | return true; | 7762 | return true; |
7075 | } | 7763 | } |
@@ -7117,6 +7805,13 @@ class LLViewShowHUDAttachments : public view_listener_t | |||
7117 | { | 7805 | { |
7118 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 7806 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
7119 | { | 7807 | { |
7808 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
7809 | if ( (LLPipeline::sShowHUDAttachments) && (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedHUD()) ) | ||
7810 | { | ||
7811 | return true; | ||
7812 | } | ||
7813 | // [/RLVa:KB] | ||
7814 | |||
7120 | LLPipeline::sShowHUDAttachments = !LLPipeline::sShowHUDAttachments; | 7815 | LLPipeline::sShowHUDAttachments = !LLPipeline::sShowHUDAttachments; |
7121 | return true; | 7816 | return true; |
7122 | } | 7817 | } |
@@ -7175,6 +7870,15 @@ class LLEditEnableTakeOff : public view_listener_t | |||
7175 | { | 7870 | { |
7176 | new_value = LLAgent::selfHasWearable((void *)WT_SKIRT); | 7871 | new_value = LLAgent::selfHasWearable((void *)WT_SKIRT); |
7177 | } | 7872 | } |
7873 | |||
7874 | // [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) | ||
7875 | // Why aren't they using LLWearable::typeNameToType()? *confuzzled* | ||
7876 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isRemovable(LLWearable::typeNameToType(clothing))) ) | ||
7877 | { | ||
7878 | new_value = false; | ||
7879 | } | ||
7880 | // [/RLVa:KB] | ||
7881 | |||
7178 | gMenuHolder->findControl(control_name)->setValue(new_value); | 7882 | gMenuHolder->findControl(control_name)->setValue(new_value); |
7179 | return true; | 7883 | return true; |
7180 | } | 7884 | } |
@@ -7272,6 +7976,13 @@ class LLWorldEnvSettings : public view_listener_t | |||
7272 | { | 7976 | { |
7273 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 7977 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
7274 | { | 7978 | { |
7979 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
7980 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)) | ||
7981 | { | ||
7982 | return true; | ||
7983 | } | ||
7984 | // [/RLVa:KB] | ||
7985 | |||
7275 | std::string tod = userdata.asString(); | 7986 | std::string tod = userdata.asString(); |
7276 | LLVector3 sun_direction; | 7987 | LLVector3 sun_direction; |
7277 | 7988 | ||
@@ -7349,6 +8060,13 @@ class LLWorldWaterSettings : public view_listener_t | |||
7349 | { | 8060 | { |
7350 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 8061 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
7351 | { | 8062 | { |
8063 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
8064 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)) | ||
8065 | { | ||
8066 | return true; | ||
8067 | } | ||
8068 | // [/RLVa:KB] | ||
8069 | |||
7352 | // if not there or is hidden, show it | 8070 | // if not there or is hidden, show it |
7353 | if( !LLFloaterWater::isOpen() || | 8071 | if( !LLFloaterWater::isOpen() || |
7354 | !LLFloaterWater::instance()->getVisible()) { | 8072 | !LLFloaterWater::instance()->getVisible()) { |
@@ -7379,6 +8097,13 @@ class LLWorldDayCycle : public view_listener_t | |||
7379 | { | 8097 | { |
7380 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 8098 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
7381 | { | 8099 | { |
8100 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
8101 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)) | ||
8102 | { | ||
8103 | return true; | ||
8104 | } | ||
8105 | // [/RLVa:KB] | ||
8106 | |||
7382 | LLFloaterDayCycle::show(); | 8107 | LLFloaterDayCycle::show(); |
7383 | return true; | 8108 | return true; |
7384 | } | 8109 | } |
@@ -9613,6 +10338,49 @@ class LLAvatarReportAbuse : public view_listener_t | |||
9613 | 10338 | ||
9614 | 10339 | ||
9615 | 10340 | ||
10341 | /////////////// | ||
10342 | // RLVa Main // | ||
10343 | /////////////// | ||
10344 | |||
10345 | |||
10346 | class RLVaMainToggle : public view_listener_t | ||
10347 | { | ||
10348 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | ||
10349 | { | ||
10350 | rlvDbgToggleEnabled(NULL); | ||
10351 | return true; | ||
10352 | } | ||
10353 | }; | ||
10354 | |||
10355 | class RLVaMainCheck : public view_listener_t | ||
10356 | { | ||
10357 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | ||
10358 | { | ||
10359 | bool new_value = rlvDbgGetEnabled(NULL); | ||
10360 | std::string control_name = userdata["control"].asString(); | ||
10361 | gMenuHolder->findControl(control_name)->setValue(new_value); | ||
10362 | return true; | ||
10363 | } | ||
10364 | }; | ||
10365 | |||
10366 | |||
10367 | |||
10368 | //////////////////// | ||
10369 | // RLVa BEHAVIORS // | ||
10370 | //////////////////// | ||
10371 | |||
10372 | |||
10373 | class RLVaBehaviorsShow : public view_listener_t | ||
10374 | { | ||
10375 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | ||
10376 | { | ||
10377 | RlvFloaterBehaviour::show(NULL); | ||
10378 | return true; | ||
10379 | } | ||
10380 | }; | ||
10381 | |||
10382 | |||
10383 | |||
9616 | static void addMenu(view_listener_t *menu, const char *name) | 10384 | static void addMenu(view_listener_t *menu, const char *name) |
9617 | { | 10385 | { |
9618 | sMenus.push_back(menu); | 10386 | sMenus.push_back(menu); |
@@ -9778,6 +10546,10 @@ void initialize_menus() | |||
9778 | addMenu(new LLObjectBuy(), "Object.Buy"); | 10546 | addMenu(new LLObjectBuy(), "Object.Buy"); |
9779 | addMenu(new LLObjectEdit(), "Object.Edit"); | 10547 | addMenu(new LLObjectEdit(), "Object.Edit"); |
9780 | addMenu(new LLObjectInspect(), "Object.Inspect"); | 10548 | addMenu(new LLObjectInspect(), "Object.Inspect"); |
10549 | addMenu(new LLObjectCopyUUID(), "Object.CopyUUID"); | ||
10550 | addMenu(new LLObjectExport(), "Object.Export"); | ||
10551 | addMenu(new LLObjectImport(), "Object.Import"); | ||
10552 | addMenu(new LLObjectImportUpload(), "Object.ImportUpload"); | ||
9781 | 10553 | ||
9782 | addMenu(new LLObjectEnableOpen(), "Object.EnableOpen"); | 10554 | addMenu(new LLObjectEnableOpen(), "Object.EnableOpen"); |
9783 | addMenu(new LLObjectEnableTouch(), "Object.EnableTouch"); | 10555 | addMenu(new LLObjectEnableTouch(), "Object.EnableTouch"); |
@@ -9788,6 +10560,9 @@ void initialize_menus() | |||
9788 | addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse"); | 10560 | addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse"); |
9789 | addMenu(new LLObjectEnableMute(), "Object.EnableMute"); | 10561 | addMenu(new LLObjectEnableMute(), "Object.EnableMute"); |
9790 | addMenu(new LLObjectEnableBuy(), "Object.EnableBuy"); | 10562 | addMenu(new LLObjectEnableBuy(), "Object.EnableBuy"); |
10563 | addMenu(new LLObjectEnableCopyUUID(), "Object.EnableCopyUUID"); | ||
10564 | addMenu(new LLObjectEnableExport(), "Object.EnableExport"); | ||
10565 | addMenu(new LLObjectEnableImport(), "Object.EnableImport"); | ||
9791 | 10566 | ||
9792 | /*addMenu(new LLObjectVisibleTouch(), "Object.VisibleTouch"); | 10567 | /*addMenu(new LLObjectVisibleTouch(), "Object.VisibleTouch"); |
9793 | addMenu(new LLObjectVisibleCustomTouch(), "Object.VisibleCustomTouch"); | 10568 | addMenu(new LLObjectVisibleCustomTouch(), "Object.VisibleCustomTouch"); |
@@ -9988,4 +10763,11 @@ void initialize_menus() | |||
9988 | addMenu(new LLAdvancedCheckViewAdminOptions(), "Advanced.CheckViewAdminOptions"); | 10763 | addMenu(new LLAdvancedCheckViewAdminOptions(), "Advanced.CheckViewAdminOptions"); |
9989 | addMenu(new LLAdvancedRequestAdminStatus(), "Advanced.RequestAdminStatus"); | 10764 | addMenu(new LLAdvancedRequestAdminStatus(), "Advanced.RequestAdminStatus"); |
9990 | addMenu(new LLAdvancedLeaveAdminStatus(), "Advanced.LeaveAdminStatus"); | 10765 | addMenu(new LLAdvancedLeaveAdminStatus(), "Advanced.LeaveAdminStatus"); |
10766 | |||
10767 | |||
10768 | // RLVa | ||
10769 | addMenu(new RLVaMainToggle(), "RLVa.Main.Toggle"); | ||
10770 | addMenu(new RLVaMainCheck(), "RLVa.Main.Enabled"); | ||
10771 | addMenu(new RLVaBehaviorsShow(), "RLVa.Behaviors.Show"); | ||
10772 | |||
9991 | } | 10773 | } |
diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp index 815dc49..e326dac 100644 --- a/linden/indra/newview/llviewermessage.cpp +++ b/linden/indra/newview/llviewermessage.cpp | |||
@@ -140,6 +140,11 @@ | |||
140 | #include "llwindebug.h" // For the invalid message handler | 140 | #include "llwindebug.h" // For the invalid message handler |
141 | #endif | 141 | #endif |
142 | 142 | ||
143 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
144 | #include "llfloateravatarinfo.h" | ||
145 | extern LLMap< const LLUUID, LLFloaterAvatarInfo* > gAvatarInfoInstances; // Only defined in llfloateravatarinfo.cpp | ||
146 | // [/RLVa:KB] | ||
147 | |||
143 | // | 148 | // |
144 | // Constants | 149 | // Constants |
145 | // | 150 | // |
@@ -1007,8 +1012,17 @@ void inventory_offer_callback(S32 button, void* user_data) | |||
1007 | std::string first_name, last_name; | 1012 | std::string first_name, last_name; |
1008 | if (gCacheName->getName(info->mFromID, first_name, last_name)) | 1013 | if (gCacheName->getName(info->mFromID, first_name, last_name)) |
1009 | { | 1014 | { |
1010 | from_string = std::string("An object named '") + info->mFromName + "' owned by " + first_name + " " + last_name; | 1015 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-08 (RLVa-1.0.0e) |
1011 | chatHistory_string = info->mFromName + " owned by " + first_name + " " + last_name; | 1016 | std::string full_name = first_name + " " + last_name; |
1017 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (gRlvHandler.isAgentNearby(info->mFromID)) ) | ||
1018 | { | ||
1019 | full_name = gRlvHandler.getAnonym(full_name); | ||
1020 | } | ||
1021 | from_string = std::string("An object named '") + info->mFromName + "' owned by " + full_name; | ||
1022 | chatHistory_string = info->mFromName + " owned by " + full_name; | ||
1023 | // [/RLVa:KB] | ||
1024 | //from_string = std::string("An object named '") + info->mFromName + "' owned by " + first_name + " " + last_name; | ||
1025 | //chatHistory_string = info->mFromName + " owned by " + first_name + " " + last_name; | ||
1012 | } | 1026 | } |
1013 | else | 1027 | else |
1014 | { | 1028 | { |
@@ -1027,6 +1041,21 @@ void inventory_offer_callback(S32 button, void* user_data) | |||
1027 | switch(button) | 1041 | switch(button) |
1028 | { | 1042 | { |
1029 | case IOR_ACCEPT: | 1043 | case IOR_ACCEPT: |
1044 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-0.2.2a | ||
1045 | // Only change the inventory offer's destination folder to the shared root if: | ||
1046 | // - the user has enabled the feature | ||
1047 | // - the inventory offer came from a script (and specifies a folder) | ||
1048 | // - the name starts with the prefix [mDesc format (quotes are part of the string): "[OBJECTNAME] ( http://slurl.com/... )"] | ||
1049 | if ( (rlv_handler_t::isEnabled()) && (!RlvSettings::getForbidGiveToRLV()) && | ||
1050 | (IM_TASK_INVENTORY_OFFERED == info->mIM) && (LLAssetType::AT_CATEGORY == info->mType) && (info->mDesc.find(RLV_PUTINV_PREFIX) == 1) ) | ||
1051 | { | ||
1052 | LLViewerInventoryCategory* pRlvRoot = gRlvHandler.getSharedRoot(); | ||
1053 | if (pRlvRoot) | ||
1054 | { | ||
1055 | info->mFolderID = pRlvRoot->getUUID(); | ||
1056 | } | ||
1057 | } | ||
1058 | // [/RLVa:KB] | ||
1030 | // ACCEPT. The math for the dialog works, because the accept | 1059 | // ACCEPT. The math for the dialog works, because the accept |
1031 | // for inventory_offered, task_inventory_offer or | 1060 | // for inventory_offered, task_inventory_offer or |
1032 | // group_notice_inventory is 1 greater than the offer integer value. | 1061 | // group_notice_inventory is 1 greater than the offer integer value. |
@@ -1189,6 +1218,13 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task) | |||
1189 | if(indx >= 0) | 1218 | if(indx >= 0) |
1190 | { | 1219 | { |
1191 | LLStringUtil::truncate(msg, indx); | 1220 | LLStringUtil::truncate(msg, indx); |
1221 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-04 (RLVa-1.0.0a) | Added: RLVa-1.0.0a | ||
1222 | // TODO-RLVa: needs revisiting when LL saves open notifications to disk to accept them on the next relog | ||
1223 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
1224 | { | ||
1225 | gRlvHandler.filterLocation(info->mDesc); | ||
1226 | } | ||
1227 | // [/RLVa:KB] | ||
1192 | } | 1228 | } |
1193 | 1229 | ||
1194 | LLStringUtil::format_map_t args; | 1230 | LLStringUtil::format_map_t args; |
@@ -1229,6 +1265,13 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task) | |||
1229 | std::string first_name, last_name; | 1265 | std::string first_name, last_name; |
1230 | if (gCacheName->getName(info->mFromID, first_name, last_name)) | 1266 | if (gCacheName->getName(info->mFromID, first_name, last_name)) |
1231 | { | 1267 | { |
1268 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-08 (RLVa-1.0.0e) | ||
1269 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (gRlvHandler.isAgentNearby(info->mFromID)) ) | ||
1270 | { | ||
1271 | first_name = gRlvHandler.getAnonym(first_name.append(" ").append(last_name)); | ||
1272 | last_name.clear(); | ||
1273 | } | ||
1274 | // [/RLVa:KB] | ||
1232 | args["[FIRST]"] = first_name; | 1275 | args["[FIRST]"] = first_name; |
1233 | args["[LAST]"] = last_name; | 1276 | args["[LAST]"] = last_name; |
1234 | name_found = TRUE; | 1277 | name_found = TRUE; |
@@ -1243,7 +1286,13 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task) | |||
1243 | else | 1286 | else |
1244 | { | 1287 | { |
1245 | // *TODO:translate -> [FIRST] [LAST] | 1288 | // *TODO:translate -> [FIRST] [LAST] |
1246 | args["[NAME]"] = info->mFromName; | 1289 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-08 (RLVa-1.0.0e) |
1290 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (gRlvHandler.isAgentNearby(info->mFromID)) ) | ||
1291 | { | ||
1292 | args["[NAME]"] = gRlvHandler.getAnonym(info->mFromName); | ||
1293 | } | ||
1294 | // [/RLVa:KB] | ||
1295 | //args["[NAME]"] = info->mFromName; | ||
1247 | LLNotifyBox::showXml("UserGiveItem", args, | 1296 | LLNotifyBox::showXml("UserGiveItem", args, |
1248 | &inventory_offer_callback, (void*)info); | 1297 | &inventory_offer_callback, (void*)info); |
1249 | } | 1298 | } |
@@ -1411,7 +1460,20 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) | |||
1411 | // do nothing -- don't distract newbies in | 1460 | // do nothing -- don't distract newbies in |
1412 | // Prelude with global IMs | 1461 | // Prelude with global IMs |
1413 | } | 1462 | } |
1414 | else if (offline == IM_ONLINE && !is_linden && is_busy && name != SYSTEM_FROM) | 1463 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) |
1464 | else if ( (rlv_handler_t::isEnabled()) && (offline == IM_ONLINE) && ("@version" == message) ) | ||
1465 | { | ||
1466 | rlvSendBusyMessage(from_id, gRlvHandler.getVersionString(), session_id); | ||
1467 | // We won't receive a typing stop message, so do that manually (see comment at the end of LLFloaterIMPanel::sendMsg) | ||
1468 | LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem); | ||
1469 | gIMMgr->processIMTypingStop(im_info); | ||
1470 | } | ||
1471 | // [/RLVa:KB] | ||
1472 | // else if (offline == IM_ONLINE && !is_linden && is_busy && name != SYSTEM_FROM) | ||
1473 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
1474 | else if ( (offline == IM_ONLINE && !is_linden && is_busy && name != SYSTEM_FROM) && | ||
1475 | ( (!gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM)) || (gRlvHandler.isException(RLV_BHVR_RECVIM, from_id))) ) | ||
1476 | // [/RLVa:KB] | ||
1415 | { | 1477 | { |
1416 | // return a standard "busy" message, but only do it to online IM | 1478 | // return a standard "busy" message, but only do it to online IM |
1417 | // (i.e. not other auto responses and not store-and-forward IM) | 1479 | // (i.e. not other auto responses and not store-and-forward IM) |
@@ -1468,6 +1530,21 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) | |||
1468 | } | 1530 | } |
1469 | else if (to_id.isNull()) | 1531 | else if (to_id.isNull()) |
1470 | { | 1532 | { |
1533 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-08 (RLVa-1.0.0e) | ||
1534 | // Filter region messages that weren't sent by a Linden | ||
1535 | if ( (rlv_handler_t::isEnabled()) && (LLMuteList::getInstance()) && | ||
1536 | (!LLMuteList::getInstance()->isLinden(name)) && (from_id != gAgent.getID()) ) | ||
1537 | { | ||
1538 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
1539 | gRlvHandler.filterLocation(message); | ||
1540 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
1541 | { | ||
1542 | name = gRlvHandler.getAnonym(name); | ||
1543 | gRlvHandler.filterNames(message); | ||
1544 | } | ||
1545 | } | ||
1546 | // [/RLVa:KB] | ||
1547 | |||
1471 | // Message to everyone from GOD | 1548 | // Message to everyone from GOD |
1472 | args["[NAME]"] = name; | 1549 | args["[NAME]"] = name; |
1473 | args["[MESSAGE]"] = message; | 1550 | args["[MESSAGE]"] = message; |
@@ -1483,6 +1560,15 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) | |||
1483 | else | 1560 | else |
1484 | { | 1561 | { |
1485 | // standard message, not from system | 1562 | // standard message, not from system |
1563 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
1564 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM)) && (!gRlvHandler.isException(RLV_BHVR_RECVIM, from_id)) ) | ||
1565 | { | ||
1566 | rlvSendBusyMessage(from_id, rlv_handler_t::cstrMsgRecvIM, session_id); | ||
1567 | |||
1568 | message = message.substr(0, message_offset) + rlv_handler_t::cstrBlockedRecvIM; | ||
1569 | } | ||
1570 | // [/RLVa:KB] | ||
1571 | |||
1486 | std::string saved; | 1572 | std::string saved; |
1487 | if(offline == IM_OFFLINE) | 1573 | if(offline == IM_OFFLINE) |
1488 | { | 1574 | { |
@@ -1688,6 +1774,13 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) | |||
1688 | bucketp = (struct offer_agent_bucket_t*) &binary_bucket[0]; | 1774 | bucketp = (struct offer_agent_bucket_t*) &binary_bucket[0]; |
1689 | info->mType = (LLAssetType::EType) bucketp->asset_type; | 1775 | info->mType = (LLAssetType::EType) bucketp->asset_type; |
1690 | info->mObjectID = bucketp->object_id; | 1776 | info->mObjectID = bucketp->object_id; |
1777 | |||
1778 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | ||
1779 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (gRlvHandler.isAgentNearby(from_id)) ) | ||
1780 | { | ||
1781 | name = gRlvHandler.getAnonym(name); | ||
1782 | } | ||
1783 | // [/RLVa:KB] | ||
1691 | } | 1784 | } |
1692 | else | 1785 | else |
1693 | { | 1786 | { |
@@ -1732,13 +1825,23 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) | |||
1732 | 1825 | ||
1733 | case IM_INVENTORY_ACCEPTED: | 1826 | case IM_INVENTORY_ACCEPTED: |
1734 | { | 1827 | { |
1735 | args["[NAME]"] = name; | 1828 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.0b |
1829 | bool fRlvObfuscate = (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && | ||
1830 | (gRlvHandler.isAgentNearby(from_id)) && (!gAvatarInfoInstances.checkData(from_id)); | ||
1831 | args["[NAME]"] = (!fRlvObfuscate) ? name : gRlvHandler.getAnonym(name); | ||
1832 | // [/RLVa:KB] | ||
1833 | // args["[NAME]"] = name; | ||
1736 | LLNotifyBox::showXml("InventoryAccepted", args); | 1834 | LLNotifyBox::showXml("InventoryAccepted", args); |
1737 | break; | 1835 | break; |
1738 | } | 1836 | } |
1739 | case IM_INVENTORY_DECLINED: | 1837 | case IM_INVENTORY_DECLINED: |
1740 | { | 1838 | { |
1741 | args["[NAME]"] = name; | 1839 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.0b |
1840 | bool fRlvObfuscate = (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && | ||
1841 | (gRlvHandler.isAgentNearby(from_id)) && (!gAvatarInfoInstances.checkData(from_id)); | ||
1842 | args["[NAME]"] = (!fRlvObfuscate) ? name : gRlvHandler.getAnonym(name); | ||
1843 | // [/RLVa:KB] | ||
1844 | // args["[NAME]"] = name; | ||
1742 | LLNotifyBox::showXml("InventoryDeclined", args); | 1845 | LLNotifyBox::showXml("InventoryDeclined", args); |
1743 | break; | 1846 | break; |
1744 | } | 1847 | } |
@@ -1772,6 +1875,22 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) | |||
1772 | return; | 1875 | return; |
1773 | } | 1876 | } |
1774 | 1877 | ||
1878 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
1879 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM)) ) | ||
1880 | { | ||
1881 | if (gAgent.isInGroup(session_id)) | ||
1882 | { | ||
1883 | if (!gRlvHandler.isException(RLV_BHVR_RECVIM, session_id)) | ||
1884 | return; | ||
1885 | } | ||
1886 | else | ||
1887 | { | ||
1888 | if ( (from_id != gAgent.getID()) && (!gRlvHandler.isException(RLV_BHVR_RECVIM, from_id)) ) | ||
1889 | message = message.substr(0, message_offset) + rlv_handler_t::cstrBlockedRecvIM; | ||
1890 | } | ||
1891 | } | ||
1892 | // [/RLVa:KB] | ||
1893 | |||
1775 | // standard message, not from system | 1894 | // standard message, not from system |
1776 | std::string saved; | 1895 | std::string saved; |
1777 | if(offline == IM_OFFLINE) | 1896 | if(offline == IM_OFFLINE) |
@@ -1854,6 +1973,17 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) | |||
1854 | return; | 1973 | return; |
1855 | } | 1974 | } |
1856 | { | 1975 | { |
1976 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-08 (RLVa-1.0.0e) | ||
1977 | // TODO-RLVa: what actually generates this? | ||
1978 | if (rlv_handler_t::isEnabled()) | ||
1979 | { | ||
1980 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
1981 | gRlvHandler.filterLocation(message); | ||
1982 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
1983 | gRlvHandler.filterNames(message); | ||
1984 | } | ||
1985 | // [/RLVa:KB] | ||
1986 | |||
1857 | // Construct a viewer alert for this message. | 1987 | // Construct a viewer alert for this message. |
1858 | args["[NAME]"] = name; | 1988 | args["[NAME]"] = name; |
1859 | args["[MESSAGE]"] = message; | 1989 | args["[MESSAGE]"] = message; |
@@ -1886,12 +2016,48 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) | |||
1886 | } | 2016 | } |
1887 | else | 2017 | else |
1888 | { | 2018 | { |
1889 | // *TODO:translate -> [FIRST] [LAST] (maybe) | 2019 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-07 (RLVa-1.0.0d) |
1890 | LLLureInfo* info = new LLLureInfo(from_id, session_id, FALSE); | 2020 | if (rlv_handler_t::isEnabled()) |
1891 | args["[NAME]"] = name; | 2021 | { |
1892 | args["[MESSAGE]"] = message; | 2022 | // Disallow if: 1) @tplure=n restricted (sender isn't an exception), or 2) @unsit=n restricted and currently sitting |
1893 | LLNotifyBox::showXml("OfferTeleport", args, | 2023 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); |
1894 | lure_callback, (void*)info); | 2024 | if ( ( (gRlvHandler.hasBehaviour(RLV_BHVR_TPLURE)) && (!gRlvHandler.isException(RLV_BHVR_TPLURE, from_id)) ) || |
2025 | ( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (pAvatar) && (pAvatar->mIsSitting) ) ) | ||
2026 | { | ||
2027 | rlvSendBusyMessage(from_id, rlv_handler_t::cstrMsgTpLure); | ||
2028 | return; | ||
2029 | } | ||
2030 | |||
2031 | // Censor teleport message if: 1) @revcim=n restricted (sender isn't an exception), or 2) @showloc=n restricted | ||
2032 | if ( ( (gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM)) && (!gRlvHandler.isException(RLV_BHVR_RECVIM, from_id)) ) || | ||
2033 | (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) | ||
2034 | { | ||
2035 | message = rlv_handler_t::cstrHidden; | ||
2036 | } | ||
2037 | } | ||
2038 | // [/RLVa:KB] | ||
2039 | |||
2040 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-07 (RLVa-1.0.0d) | Modified: RLVa-0.2.0b | ||
2041 | if ( (rlv_handler_t::isEnabled()) && | ||
2042 | ((gRlvHandler.hasBehaviour(RLV_BHVR_ACCEPTTP)) || (gRlvHandler.isException(RLV_BHVR_ACCEPTTP, from_id))) ) | ||
2043 | { | ||
2044 | gRlvHandler.setCanCancelTp(false); | ||
2045 | // (see IM_GODLIKE_LURE_USER below) | ||
2046 | LLLureInfo* info = new LLLureInfo(from_id, session_id, TRUE); | ||
2047 | lure_callback(0, (void*)info); | ||
2048 | } | ||
2049 | else | ||
2050 | { | ||
2051 | // [/RLVa:KB] | ||
2052 | // *TODO:translate -> [FIRST] [LAST] (maybe) | ||
2053 | LLLureInfo* info = new LLLureInfo(from_id, session_id, FALSE); | ||
2054 | args["[NAME]"] = name; | ||
2055 | args["[MESSAGE]"] = message; | ||
2056 | LLNotifyBox::showXml("OfferTeleport", args, | ||
2057 | lure_callback, (void*)info); | ||
2058 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-07 (RLVa-1.0.0d) | Modified: RLVa-0.2.0b | ||
2059 | } | ||
2060 | // [/RLVa:KB] | ||
1895 | } | 2061 | } |
1896 | } | 2062 | } |
1897 | break; | 2063 | break; |
@@ -2236,8 +2402,13 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) | |||
2236 | chat.mPosAgent = chatter->getPositionAgent(); | 2402 | chat.mPosAgent = chatter->getPositionAgent(); |
2237 | 2403 | ||
2238 | // Make swirly things only for talking objects. (not script debug messages, though) | 2404 | // Make swirly things only for talking objects. (not script debug messages, though) |
2239 | if (chat.mSourceType == CHAT_SOURCE_OBJECT | 2405 | // if (chat.mSourceType == CHAT_SOURCE_OBJECT |
2240 | && chat.mChatType != CHAT_TYPE_DEBUG_MSG) | 2406 | // && chat.mChatType != CHAT_TYPE_DEBUG_MSG) |
2407 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
2408 | // Don't show swirly things for llOwnerSay() chat here because we handle those further down | ||
2409 | if ( (chat.mSourceType == CHAT_SOURCE_OBJECT && chat.mChatType != CHAT_TYPE_DEBUG_MSG) && | ||
2410 | ((!rlv_handler_t::isEnabled()) || (CHAT_TYPE_OWNER != chat.mChatType)) ) | ||
2411 | // [/RLVa:KB] | ||
2241 | { | 2412 | { |
2242 | LLPointer<LLViewerPartSourceChat> psc = new LLViewerPartSourceChat(chatter->getPositionAgent()); | 2413 | LLPointer<LLViewerPartSourceChat> psc = new LLViewerPartSourceChat(chatter->getPositionAgent()); |
2243 | psc->setSourceObject(chatter); | 2414 | psc->setSourceObject(chatter); |
@@ -2270,6 +2441,50 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) | |||
2270 | color.setVec(1.f,1.f,1.f,1.f); | 2441 | color.setVec(1.f,1.f,1.f,1.f); |
2271 | msg->getStringFast(_PREHASH_ChatData, _PREHASH_Message, mesg); | 2442 | msg->getStringFast(_PREHASH_ChatData, _PREHASH_Message, mesg); |
2272 | 2443 | ||
2444 | // [RLVa:KB] - Checked: 2009-08-04 (RLVa-1.0.1d) | Modified: RLVa-1.0.1d | ||
2445 | if ( (rlv_handler_t::isEnabled()) && | ||
2446 | (CHAT_TYPE_START != chat.mChatType) && (CHAT_TYPE_STOP != chat.mChatType) && (CHAT_TYPE_OWNER != chat.mChatType) ) | ||
2447 | { | ||
2448 | // NOTE: chatter can be NULL (may not have rezzed yet, or could be another avie's HUD attachment) | ||
2449 | BOOL is_attachment = (chatter) ? chatter->isAttachment() : FALSE; | ||
2450 | |||
2451 | // Filtering "rules": | ||
2452 | // avatar => filter all avie text (unless it's this avie or they're an exemption) | ||
2453 | // objects => filter everything except attachments this avie owns | ||
2454 | if ( ((CHAT_SOURCE_AGENT == chat.mSourceType) && (from_id != gAgent.getID())) || (!is_owned_by_me) || (!is_attachment) ) | ||
2455 | { | ||
2456 | if (!rlvIsEmote(mesg)) | ||
2457 | { | ||
2458 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_RECVCHAT)) && (!gRlvHandler.isException(RLV_BHVR_RECVCHAT, from_id)) ) | ||
2459 | gRlvHandler.filterChat(mesg, false); | ||
2460 | } | ||
2461 | else if ( (gRlvHandler.hasBehaviour(RLV_BHVR_RECVEMOTE)) && (!gRlvHandler.isException(RLV_BHVR_RECVEMOTE, from_id)) ) | ||
2462 | { | ||
2463 | mesg = "/me ..."; | ||
2464 | } | ||
2465 | } | ||
2466 | |||
2467 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
2468 | { | ||
2469 | // Filtering "rules": | ||
2470 | // avatar => filter only their name (unless it's this avie) | ||
2471 | // other => filter everything except attachments this avie owns but then we still do filter their text | ||
2472 | if (CHAT_SOURCE_AGENT == chat.mSourceType) | ||
2473 | { | ||
2474 | if (chat.mFromID != gAgent.getID()) | ||
2475 | from_name = gRlvHandler.getAnonym(from_name); | ||
2476 | } | ||
2477 | else | ||
2478 | { | ||
2479 | if ( (!is_owned_by_me) || (!is_attachment) ) | ||
2480 | gRlvHandler.filterNames(from_name); | ||
2481 | gRlvHandler.filterNames(mesg); | ||
2482 | } | ||
2483 | chat.mRlvNamesFiltered = true; | ||
2484 | } | ||
2485 | } | ||
2486 | // [/RLVa:KB] | ||
2487 | |||
2273 | BOOL ircstyle = FALSE; | 2488 | BOOL ircstyle = FALSE; |
2274 | 2489 | ||
2275 | // Look for IRC-style emotes here so chatbubbles work | 2490 | // Look for IRC-style emotes here so chatbubbles work |
@@ -2334,8 +2549,76 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) | |||
2334 | case CHAT_TYPE_WHISPER: | 2549 | case CHAT_TYPE_WHISPER: |
2335 | verb = " " + LLTrans::getString("whisper") + " "; | 2550 | verb = " " + LLTrans::getString("whisper") + " "; |
2336 | break; | 2551 | break; |
2337 | case CHAT_TYPE_DEBUG_MSG: | ||
2338 | case CHAT_TYPE_OWNER: | 2552 | case CHAT_TYPE_OWNER: |
2553 | // [RLVa:KB] - Checked: 2009-08-05 (RLVa-1.0.1e) | Modified: RLVa-1.0.1e | ||
2554 | if ( (rlv_handler_t::isEnabled()) && (mesg.length() > 3) && (RLV_CMD_PREFIX == mesg[0]) ) | ||
2555 | { | ||
2556 | mesg.erase(0, 1); | ||
2557 | LLStringUtil::toLower(mesg); | ||
2558 | |||
2559 | std::string strExecuted, strFailed, strRetained, *pstr; | ||
2560 | |||
2561 | typedef boost::tokenizer<boost::char_separator<char> > tokenizer; | ||
2562 | boost::char_separator<char> sep(",", "", boost::drop_empty_tokens); | ||
2563 | tokenizer tokens(mesg, sep); | ||
2564 | for (tokenizer::iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken) | ||
2565 | { | ||
2566 | if (LLStartUp::getStartupState() == STATE_STARTED) | ||
2567 | { | ||
2568 | if (gRlvHandler.processCommand(from_id, *itToken, true)) | ||
2569 | pstr = &strExecuted; | ||
2570 | else | ||
2571 | pstr = &strFailed; | ||
2572 | } | ||
2573 | else | ||
2574 | { | ||
2575 | gRlvHandler.retainCommand(from_name, from_id, *itToken); | ||
2576 | pstr = &strRetained; | ||
2577 | } | ||
2578 | |||
2579 | if (!pstr->empty()) | ||
2580 | pstr->push_back(','); | ||
2581 | pstr->append(*itToken); | ||
2582 | } | ||
2583 | |||
2584 | if (!RlvSettings::getDebug()) | ||
2585 | return; | ||
2586 | |||
2587 | // Silly people want comprehensive debug messages, blah :p | ||
2588 | if ( (!strExecuted.empty()) && (strFailed.empty()) && (strRetained.empty()) ) | ||
2589 | verb = " executes: @"; | ||
2590 | else if ( (strExecuted.empty()) && (!strFailed.empty()) && (strRetained.empty()) ) | ||
2591 | verb = " failed: @"; | ||
2592 | else if ( (strExecuted.empty()) && (strFailed.empty()) && (!strRetained.empty()) ) | ||
2593 | verb = " retained: @"; | ||
2594 | else | ||
2595 | { | ||
2596 | verb = ": @"; | ||
2597 | if (!strExecuted.empty()) | ||
2598 | mesg += "\n - executed: @" + strExecuted; | ||
2599 | if (!strFailed.empty()) | ||
2600 | mesg += "\n - failed: @" + strFailed; | ||
2601 | if (!strRetained.empty()) | ||
2602 | mesg += "\n - retained: @" + strRetained; | ||
2603 | } | ||
2604 | |||
2605 | break; | ||
2606 | } | ||
2607 | // [/RLVa:KB] | ||
2608 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
2609 | // Copy/paste from above | ||
2610 | if ( (chatter) && (chat.mChatType != CHAT_TYPE_DEBUG_MSG) ) | ||
2611 | { | ||
2612 | LLPointer<LLViewerPartSourceChat> psc = new LLViewerPartSourceChat(chatter->getPositionAgent()); | ||
2613 | psc->setSourceObject(chatter); | ||
2614 | psc->setColor(color); | ||
2615 | //We set the particles to be owned by the object's owner, | ||
2616 | //just in case they should be muted by the mute list | ||
2617 | psc->setOwnerUUID(owner_id); | ||
2618 | LLViewerPartSim::getInstance()->addPartSource(psc); | ||
2619 | } | ||
2620 | // [/RLVa:KB] | ||
2621 | case CHAT_TYPE_DEBUG_MSG: | ||
2339 | case CHAT_TYPE_NORMAL: | 2622 | case CHAT_TYPE_NORMAL: |
2340 | verb = ": "; | 2623 | verb = ": "; |
2341 | break; | 2624 | break; |
@@ -2404,7 +2687,10 @@ void process_teleport_start(LLMessageSystem *msg, void**) | |||
2404 | U32 teleport_flags = 0x0; | 2687 | U32 teleport_flags = 0x0; |
2405 | msg->getU32("Info", "TeleportFlags", teleport_flags); | 2688 | msg->getU32("Info", "TeleportFlags", teleport_flags); |
2406 | 2689 | ||
2407 | if (teleport_flags & TELEPORT_FLAGS_DISABLE_CANCEL) | 2690 | //if (teleport_flags & TELEPORT_FLAGS_DISABLE_CANCEL) |
2691 | // [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) | Added: RLVa-0.2.0b | ||
2692 | if ( (teleport_flags & TELEPORT_FLAGS_DISABLE_CANCEL) || (!gRlvHandler.getCanCancelTp()) ) | ||
2693 | // [/RLVa:KB] | ||
2408 | { | 2694 | { |
2409 | gViewerWindow->setProgressCancelButtonVisible(FALSE); | 2695 | gViewerWindow->setProgressCancelButtonVisible(FALSE); |
2410 | } | 2696 | } |
@@ -2439,7 +2725,10 @@ void process_teleport_progress(LLMessageSystem* msg, void**) | |||
2439 | } | 2725 | } |
2440 | U32 teleport_flags = 0x0; | 2726 | U32 teleport_flags = 0x0; |
2441 | msg->getU32("Info", "TeleportFlags", teleport_flags); | 2727 | msg->getU32("Info", "TeleportFlags", teleport_flags); |
2442 | if (teleport_flags & TELEPORT_FLAGS_DISABLE_CANCEL) | 2728 | //if (teleport_flags & TELEPORT_FLAGS_DISABLE_CANCEL) |
2729 | // [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) | Added: RLVa-0.2.0b | ||
2730 | if ( (teleport_flags & TELEPORT_FLAGS_DISABLE_CANCEL) || (!gRlvHandler.getCanCancelTp()) ) | ||
2731 | // [/RLVa:KB] | ||
2443 | { | 2732 | { |
2444 | gViewerWindow->setProgressCancelButtonVisible(FALSE); | 2733 | gViewerWindow->setProgressCancelButtonVisible(FALSE); |
2445 | } | 2734 | } |
@@ -2780,7 +3069,10 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**) | |||
2780 | // know what you look like. | 3069 | // know what you look like. |
2781 | gAgent.sendAgentSetAppearance(); | 3070 | gAgent.sendAgentSetAppearance(); |
2782 | 3071 | ||
2783 | if (avatarp) | 3072 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) |
3073 | if ( (avatarp) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) | ||
3074 | // [/RLVa:KB] | ||
3075 | // if (avatarp) | ||
2784 | { | 3076 | { |
2785 | // Chat the "back" SLURL. (DEV-4907) | 3077 | // Chat the "back" SLURL. (DEV-4907) |
2786 | LLChat chat("Teleport completed from " + gAgent.getTeleportSourceSLURL()); | 3078 | LLChat chat("Teleport completed from " + gAgent.getTeleportSourceSLURL()); |
@@ -4360,7 +4652,13 @@ void notify_cautioned_script_question(LLScriptQuestionCBData* cbdata, S32 orig_q | |||
4360 | if (viewregion) | 4652 | if (viewregion) |
4361 | { | 4653 | { |
4362 | // got the region, so include the region and 3d coordinates of the object | 4654 | // got the region, so include the region and 3d coordinates of the object |
4363 | notice.setArg("[REGIONNAME]", viewregion->getName()); | 4655 | notice.setArg("[REGIONNAME]", viewregion->getName()); |
4656 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | ||
4657 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) | ||
4658 | { | ||
4659 | notice.setArg("[REGIONNAME]", rlv_handler_t::cstrHiddenRegion); | ||
4660 | } | ||
4661 | // [/RLVa:KB] | ||
4364 | std::string formatpos = llformat("%.1f, %.1f,%.1f", objpos[VX], objpos[VY], objpos[VZ]); | 4662 | std::string formatpos = llformat("%.1f, %.1f,%.1f", objpos[VX], objpos[VY], objpos[VZ]); |
4365 | notice.setArg("[REGIONPOS]", formatpos); | 4663 | notice.setArg("[REGIONPOS]", formatpos); |
4366 | 4664 | ||
@@ -4565,8 +4863,31 @@ void process_script_question(LLMessageSystem *msg, void **user_data) | |||
4565 | 4863 | ||
4566 | LLScriptQuestionCBData *cbdata = new LLScriptQuestionCBData(taskid, itemid, sender, questions, object_name, owner_name); | 4864 | LLScriptQuestionCBData *cbdata = new LLScriptQuestionCBData(taskid, itemid, sender, questions, object_name, owner_name); |
4567 | 4865 | ||
4866 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0e | ||
4867 | S32 rlvQuestionsOther = questions; | ||
4868 | |||
4869 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour("acceptpermission")) ) | ||
4870 | { | ||
4871 | LLViewerObject* pObj = gObjectList.findObject(taskid); | ||
4872 | if (pObj) | ||
4873 | { | ||
4874 | if (pObj->permYouOwner()) | ||
4875 | { | ||
4876 | // PERMISSION_TAKE_CONTROLS and PERMISSION_ATTACH are only auto-granted to objects this avie owns | ||
4877 | rlvQuestionsOther &= ~(LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_TAKE_CONTROLS] | | ||
4878 | LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_ATTACH]); | ||
4879 | } | ||
4880 | } | ||
4881 | } | ||
4882 | |||
4883 | if ( (!caution) && (!rlvQuestionsOther) ) | ||
4884 | { | ||
4885 | script_question_cb(0, cbdata); | ||
4886 | } | ||
4887 | else if (gSavedSettings.getBOOL("PermissionsCautionEnabled")) | ||
4888 | // [/RLVa:KB] | ||
4568 | // check whether cautions are even enabled or not | 4889 | // check whether cautions are even enabled or not |
4569 | if (gSavedSettings.getBOOL("PermissionsCautionEnabled")) | 4890 | //if (gSavedSettings.getBOOL("PermissionsCautionEnabled")) |
4570 | { | 4891 | { |
4571 | if (caution) | 4892 | if (caution) |
4572 | { | 4893 | { |
@@ -4858,6 +5179,21 @@ void handle_lure_callback(S32 option, const std::string& text, void* userdata) | |||
4858 | 5179 | ||
4859 | if(0 == option) | 5180 | if(0 == option) |
4860 | { | 5181 | { |
5182 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0b | ||
5183 | bool fRlvCensorMessage = false; | ||
5184 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM)) | ||
5185 | { | ||
5186 | for (LLDynamicArray<LLUUID>::iterator it = invitees->begin(); it != invitees->end(); ++it) | ||
5187 | { | ||
5188 | if (!gRlvHandler.isException(RLV_BHVR_SENDIM, *it)) | ||
5189 | { | ||
5190 | fRlvCensorMessage = true; | ||
5191 | break; | ||
5192 | } | ||
5193 | } | ||
5194 | } | ||
5195 | // [/RLVa:KB] | ||
5196 | |||
4861 | LLMessageSystem* msg = gMessageSystem; | 5197 | LLMessageSystem* msg = gMessageSystem; |
4862 | msg->newMessageFast(_PREHASH_StartLure); | 5198 | msg->newMessageFast(_PREHASH_StartLure); |
4863 | msg->nextBlockFast(_PREHASH_AgentData); | 5199 | msg->nextBlockFast(_PREHASH_AgentData); |
@@ -4865,7 +5201,10 @@ void handle_lure_callback(S32 option, const std::string& text, void* userdata) | |||
4865 | msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | 5201 | msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); |
4866 | msg->nextBlockFast(_PREHASH_Info); | 5202 | msg->nextBlockFast(_PREHASH_Info); |
4867 | msg->addU8Fast(_PREHASH_LureType, (U8)0); // sim will fill this in. | 5203 | msg->addU8Fast(_PREHASH_LureType, (U8)0); // sim will fill this in. |
4868 | msg->addStringFast(_PREHASH_Message, text); | 5204 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0b |
5205 | msg->addStringFast(_PREHASH_Message, (!fRlvCensorMessage) ? text : rlv_handler_t::cstrHidden); | ||
5206 | // [/RLVa:KB] | ||
5207 | //msg->addStringFast(_PREHASH_Message, text); | ||
4869 | for(LLDynamicArray<LLUUID>::iterator itr = invitees->begin(); itr != invitees->end(); ++itr) | 5208 | for(LLDynamicArray<LLUUID>::iterator itr = invitees->begin(); itr != invitees->end(); ++itr) |
4870 | { | 5209 | { |
4871 | msg->nextBlockFast(_PREHASH_TargetData); | 5210 | msg->nextBlockFast(_PREHASH_TargetData); |
@@ -4895,8 +5234,28 @@ void handle_lure(LLDynamicArray<LLUUID>& ids) | |||
4895 | { | 5234 | { |
4896 | LLDynamicArray<LLUUID>* userdata = new LLDynamicArray<LLUUID>(ids); | 5235 | LLDynamicArray<LLUUID>* userdata = new LLDynamicArray<LLUUID>(ids); |
4897 | 5236 | ||
5237 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-07 (RLVa-1.0.0d) | Modified: RLVa-1.0.0a | ||
5238 | // Only allow offering teleports if everyone is a @tplure exception or able to map this avie under @showloc=n | ||
5239 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
5240 | { | ||
5241 | for (LLDynamicArray<LLUUID>::iterator it = ids.begin(); it != ids.end(); ++it) | ||
5242 | { | ||
5243 | const LLRelationship* pBuddyInfo = LLAvatarTracker::instance().getBuddyInfo(*it); | ||
5244 | if ( (!gRlvHandler.isException(RLV_BHVR_TPLURE, *it)) && | ||
5245 | ((!pBuddyInfo) || (!pBuddyInfo->isOnline()) || (!pBuddyInfo->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION))) ) | ||
5246 | { | ||
5247 | delete userdata; | ||
5248 | return; | ||
5249 | } | ||
5250 | } | ||
5251 | } | ||
5252 | // [/RLVa:KB] | ||
5253 | |||
4898 | LLStringUtil::format_map_t edit_args; | 5254 | LLStringUtil::format_map_t edit_args; |
4899 | edit_args["[REGION]"] = gAgent.getRegion()->getName(); | 5255 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-07 (RLVa-1.0.0d) | Modified: RLVa-1.0.0a |
5256 | edit_args["[REGION]"] = (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? gAgent.getRegion()->getName() : rlv_handler_t::cstrHidden; | ||
5257 | // [/RLVa:KB] | ||
5258 | //edit_args["[REGION]"] = gAgent.getRegion()->getName(); | ||
4900 | if (gAgent.isGodlike()) | 5259 | if (gAgent.isGodlike()) |
4901 | { | 5260 | { |
4902 | gViewerWindow->alertXmlEditText("OfferTeleportFromGod", edit_args, | 5261 | gViewerWindow->alertXmlEditText("OfferTeleportFromGod", edit_args, |
diff --git a/linden/indra/newview/llviewerobject.cpp b/linden/indra/newview/llviewerobject.cpp index ca7055a..102b135 100644 --- a/linden/indra/newview/llviewerobject.cpp +++ b/linden/indra/newview/llviewerobject.cpp | |||
@@ -1006,6 +1006,12 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, | |||
1006 | coloru.mV[3] = 255 - coloru.mV[3]; | 1006 | coloru.mV[3] = 255 - coloru.mV[3]; |
1007 | mText->setColor(LLColor4(coloru)); | 1007 | mText->setColor(LLColor4(coloru)); |
1008 | mText->setStringUTF8(temp_string); | 1008 | mText->setStringUTF8(temp_string); |
1009 | // [RLVa:KB] - Checked: 2009-07-09 (RLVa-1.0.0f) | Added: RLVa-1.0.0f | ||
1010 | if (rlv_handler_t::isEnabled()) | ||
1011 | { | ||
1012 | mText->setObjectText(temp_string); | ||
1013 | } | ||
1014 | // [/RLVa:KB] | ||
1009 | 1015 | ||
1010 | if (mDrawable.notNull()) | 1016 | if (mDrawable.notNull()) |
1011 | { | 1017 | { |
@@ -1423,6 +1429,12 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, | |||
1423 | coloru.mV[3] = 255 - coloru.mV[3]; | 1429 | coloru.mV[3] = 255 - coloru.mV[3]; |
1424 | mText->setColor(LLColor4(coloru)); | 1430 | mText->setColor(LLColor4(coloru)); |
1425 | mText->setStringUTF8(temp_string); | 1431 | mText->setStringUTF8(temp_string); |
1432 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-09 (RLVa-1.0.0f) | Added: RLVa-1.0.0f | ||
1433 | if (rlv_handler_t::isEnabled()) | ||
1434 | { | ||
1435 | mText->setObjectText(temp_string); | ||
1436 | } | ||
1437 | // [/RLVa:KB] | ||
1426 | 1438 | ||
1427 | setChanged(TEXTURE); | 1439 | setChanged(TEXTURE); |
1428 | } | 1440 | } |
@@ -4795,7 +4807,10 @@ BOOL LLViewerObject::permTransfer() const | |||
4795 | // given you modify rights to. JC | 4807 | // given you modify rights to. JC |
4796 | BOOL LLViewerObject::allowOpen() const | 4808 | BOOL LLViewerObject::allowOpen() const |
4797 | { | 4809 | { |
4798 | return !flagInventoryEmpty() && (permYouOwner() || permModify()); | 4810 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0b) |
4811 | return !flagInventoryEmpty() && (permYouOwner() || permModify()) && (!gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)); | ||
4812 | // [/RLVa:KB] | ||
4813 | // return !flagInventoryEmpty() && (permYouOwner() || permModify()); | ||
4799 | } | 4814 | } |
4800 | 4815 | ||
4801 | LLViewerObject::LLInventoryCallbackInfo::~LLInventoryCallbackInfo() | 4816 | LLViewerObject::LLInventoryCallbackInfo::~LLInventoryCallbackInfo() |
diff --git a/linden/indra/newview/llviewerobjectlist.cpp b/linden/indra/newview/llviewerobjectlist.cpp index 9ccbf99..78c1730 100644 --- a/linden/indra/newview/llviewerobjectlist.cpp +++ b/linden/indra/newview/llviewerobjectlist.cpp | |||
@@ -74,6 +74,8 @@ | |||
74 | 74 | ||
75 | #include "llappviewer.h" | 75 | #include "llappviewer.h" |
76 | 76 | ||
77 | #include "primbackup.h" | ||
78 | |||
77 | extern F32 gMinObjectDistance; | 79 | extern F32 gMinObjectDistance; |
78 | extern BOOL gAnimateTextures; | 80 | extern BOOL gAnimateTextures; |
79 | 81 | ||
@@ -163,8 +165,6 @@ U64 LLViewerObjectList::getIndex(const U32 local_id, | |||
163 | 165 | ||
164 | BOOL LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject &object) | 166 | BOOL LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject &object) |
165 | { | 167 | { |
166 | if(object.getRegion()) | ||
167 | { | ||
168 | U32 local_id = object.mLocalID; | 168 | U32 local_id = object.mLocalID; |
169 | LLHost region_host = object.getRegion()->getHost(); | 169 | LLHost region_host = object.getRegion()->getHost(); |
170 | U32 ip = region_host.getAddress(); | 170 | U32 ip = region_host.getAddress(); |
@@ -176,9 +176,6 @@ BOOL LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject &object) | |||
176 | return sIndexAndLocalIDToUUID.erase(indexid) > 0 ? TRUE : FALSE; | 176 | return sIndexAndLocalIDToUUID.erase(indexid) > 0 ? TRUE : FALSE; |
177 | } | 177 | } |
178 | 178 | ||
179 | return FALSE ; | ||
180 | } | ||
181 | |||
182 | void LLViewerObjectList::setUUIDAndLocal(const LLUUID &id, | 179 | void LLViewerObjectList::setUUIDAndLocal(const LLUUID &id, |
183 | const U32 local_id, | 180 | const U32 local_id, |
184 | const U32 ip, | 181 | const U32 ip, |
@@ -222,6 +219,11 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, | |||
222 | 219 | ||
223 | updateActive(objectp); | 220 | updateActive(objectp); |
224 | 221 | ||
222 | if(!just_created) | ||
223 | primbackup::getInstance()->prim_update(objectp); | ||
224 | |||
225 | |||
226 | |||
225 | if (just_created) | 227 | if (just_created) |
226 | { | 228 | { |
227 | gPipeline.addObject(objectp); | 229 | gPipeline.addObject(objectp); |
@@ -251,6 +253,9 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, | |||
251 | objectp->mCreateSelected = false; | 253 | objectp->mCreateSelected = false; |
252 | gViewerWindow->getWindow()->decBusyCount(); | 254 | gViewerWindow->getWindow()->decBusyCount(); |
253 | gViewerWindow->getWindow()->setCursor( UI_CURSOR_ARROW ); | 255 | gViewerWindow->getWindow()->setCursor( UI_CURSOR_ARROW ); |
256 | |||
257 | primbackup::getInstance()->newprim(objectp); | ||
258 | |||
254 | } | 259 | } |
255 | } | 260 | } |
256 | 261 | ||
@@ -827,17 +832,10 @@ void LLViewerObjectList::removeDrawable(LLDrawable* drawablep) | |||
827 | 832 | ||
828 | for (S32 i = 0; i < drawablep->getNumFaces(); i++) | 833 | for (S32 i = 0; i < drawablep->getNumFaces(); i++) |
829 | { | 834 | { |
830 | LLFace* facep = drawablep->getFace(i) ; | 835 | LLViewerObject* objectp = drawablep->getFace(i)->getViewerObject(); |
831 | if(facep) | ||
832 | { | ||
833 | LLViewerObject* objectp = facep->getViewerObject(); | ||
834 | if(objectp) | ||
835 | { | ||
836 | mSelectPickList.erase(objectp); | 836 | mSelectPickList.erase(objectp); |
837 | } | 837 | } |
838 | } | 838 | } |
839 | } | ||
840 | } | ||
841 | 839 | ||
842 | BOOL LLViewerObjectList::killObject(LLViewerObject *objectp) | 840 | BOOL LLViewerObjectList::killObject(LLViewerObject *objectp) |
843 | { | 841 | { |
@@ -914,7 +912,7 @@ void LLViewerObjectList::killAllObjects() | |||
914 | if (!mMapObjects.empty()) | 912 | if (!mMapObjects.empty()) |
915 | { | 913 | { |
916 | llwarns << "Some objects still on map object list!" << llendl; | 914 | llwarns << "Some objects still on map object list!" << llendl; |
917 | mMapObjects.clear(); | 915 | mActiveObjects.clear(); |
918 | } | 916 | } |
919 | } | 917 | } |
920 | 918 | ||
diff --git a/linden/indra/newview/llviewertexteditor.cpp b/linden/indra/newview/llviewertexteditor.cpp index 54b7743..76b752c 100644 --- a/linden/indra/newview/llviewertexteditor.cpp +++ b/linden/indra/newview/llviewertexteditor.cpp | |||
@@ -95,6 +95,13 @@ public: | |||
95 | } | 95 | } |
96 | else | 96 | else |
97 | { | 97 | { |
98 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
99 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour("viewnote")) ) | ||
100 | { | ||
101 | return; | ||
102 | } | ||
103 | // [/RLVa:KB] | ||
104 | |||
98 | // See if we can bring an existing preview to the front | 105 | // See if we can bring an existing preview to the front |
99 | if(!LLPreview::show(item->getUUID(), true)) | 106 | if(!LLPreview::show(item->getUUID(), true)) |
100 | { | 107 | { |
diff --git a/linden/indra/newview/llviewerwindow.cpp b/linden/indra/newview/llviewerwindow.cpp index 3b23bb9..2240d44 100644 --- a/linden/indra/newview/llviewerwindow.cpp +++ b/linden/indra/newview/llviewerwindow.cpp | |||
@@ -2993,6 +2993,16 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, | |||
2993 | { | 2993 | { |
2994 | moveable_object_selected = TRUE; | 2994 | moveable_object_selected = TRUE; |
2995 | this_object_movable = TRUE; | 2995 | this_object_movable = TRUE; |
2996 | |||
2997 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0g | ||
2998 | if ( (rlv_handler_t::isEnabled()) && | ||
2999 | ((gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SITTP))) ) | ||
3000 | { | ||
3001 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | ||
3002 | if ( (pAvatar) && (pAvatar->mIsSitting) && (pAvatar->getRoot() == object->getRootEdit()) ) | ||
3003 | moveable_object_selected = this_object_movable = FALSE; | ||
3004 | } | ||
3005 | // [/RLVa:KB] | ||
2996 | } | 3006 | } |
2997 | all_selected_objects_move = all_selected_objects_move && this_object_movable; | 3007 | all_selected_objects_move = all_selected_objects_move && this_object_movable; |
2998 | all_selected_objects_modify = all_selected_objects_modify && object->permModify(); | 3008 | all_selected_objects_modify = all_selected_objects_modify && object->permModify(); |
diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp index 3d2523e..158977e 100644 --- a/linden/indra/newview/llvoavatar.cpp +++ b/linden/indra/newview/llvoavatar.cpp | |||
@@ -125,6 +125,10 @@ | |||
125 | #include "llvoicevisualizer.h" | 125 | #include "llvoicevisualizer.h" |
126 | #include "llvoiceclient.h" | 126 | #include "llvoiceclient.h" |
127 | 127 | ||
128 | // [RLVa:KB] | ||
129 | #include "llstartup.h" | ||
130 | // [/RLVa:KB] | ||
131 | |||
128 | LLXmlTree LLVOAvatar::sXMLTree; | 132 | LLXmlTree LLVOAvatar::sXMLTree; |
129 | LLXmlTree LLVOAvatar::sSkeletonXMLTree; | 133 | LLXmlTree LLVOAvatar::sSkeletonXMLTree; |
130 | LLVOAvatarSkeletonInfo* LLVOAvatar::sSkeletonInfo = NULL; | 134 | LLVOAvatarSkeletonInfo* LLVOAvatar::sSkeletonInfo = NULL; |
@@ -2093,9 +2097,15 @@ void LLVOAvatar::buildCharacter() | |||
2093 | if (attachment->getGroup() == i) | 2097 | if (attachment->getGroup() == i) |
2094 | { | 2098 | { |
2095 | LLMenuItemCallGL* item; | 2099 | LLMenuItemCallGL* item; |
2100 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
2101 | // We need the userdata param to disable options in this pie menu later on (Left Hand / Right Hand option) | ||
2096 | item = new LLMenuItemCallGL(attachment->getName(), | 2102 | item = new LLMenuItemCallGL(attachment->getName(), |
2097 | NULL, | 2103 | NULL, |
2098 | object_selected_and_point_valid); | 2104 | object_selected_and_point_valid, attachment); |
2105 | // [/RLVa:KB] | ||
2106 | // item = new LLMenuItemCallGL(attachment->getName(), | ||
2107 | // NULL, | ||
2108 | // object_selected_and_point_valid); | ||
2099 | item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", curiter->first); | 2109 | item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", curiter->first); |
2100 | 2110 | ||
2101 | gAttachPieMenu->append(item); | 2111 | gAttachPieMenu->append(item); |
@@ -2150,9 +2160,15 @@ void LLVOAvatar::buildCharacter() | |||
2150 | if (attachment->getGroup() == 8) | 2160 | if (attachment->getGroup() == 8) |
2151 | { | 2161 | { |
2152 | LLMenuItemCallGL* item; | 2162 | LLMenuItemCallGL* item; |
2163 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
2164 | // We need the userdata param to disable options in this pie menu later on | ||
2153 | item = new LLMenuItemCallGL(attachment->getName(), | 2165 | item = new LLMenuItemCallGL(attachment->getName(), |
2154 | NULL, | 2166 | NULL, |
2155 | object_selected_and_point_valid); | 2167 | object_selected_and_point_valid, attachment); |
2168 | // [/RLVa:KB] | ||
2169 | // item = new LLMenuItemCallGL(attachment->getName(), | ||
2170 | // NULL, | ||
2171 | // object_selected_and_point_valid); | ||
2156 | item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", curiter->first); | 2172 | item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", curiter->first); |
2157 | gAttachScreenPieMenu->append(item); | 2173 | gAttachScreenPieMenu->append(item); |
2158 | gDetachScreenPieMenu->append(new LLMenuItemCallGL(attachment->getName(), | 2174 | gDetachScreenPieMenu->append(new LLMenuItemCallGL(attachment->getName(), |
@@ -2171,6 +2187,7 @@ void LLVOAvatar::buildCharacter() | |||
2171 | { | 2187 | { |
2172 | continue; | 2188 | continue; |
2173 | } | 2189 | } |
2190 | // RELEASE-RLVa: random comment because we want know if LL ever changes this to not include "attachment" as userdata | ||
2174 | LLMenuItemCallGL* item = new LLMenuItemCallGL(attachment->getName(), | 2191 | LLMenuItemCallGL* item = new LLMenuItemCallGL(attachment->getName(), |
2175 | NULL, &object_selected_and_point_valid, | 2192 | NULL, &object_selected_and_point_valid, |
2176 | &attach_label, attachment); | 2193 | &attach_label, attachment); |
@@ -2230,8 +2247,13 @@ void LLVOAvatar::buildCharacter() | |||
2230 | LLViewerJointAttachment* attachment = get_if_there(mAttachmentPoints, attach_index, (LLViewerJointAttachment*)NULL); | 2247 | LLViewerJointAttachment* attachment = get_if_there(mAttachmentPoints, attach_index, (LLViewerJointAttachment*)NULL); |
2231 | if (attachment) | 2248 | if (attachment) |
2232 | { | 2249 | { |
2250 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
2251 | // We need the userdata param to disable options in this pie menu later on | ||
2233 | LLMenuItemCallGL* item = new LLMenuItemCallGL(attachment->getName(), | 2252 | LLMenuItemCallGL* item = new LLMenuItemCallGL(attachment->getName(), |
2234 | NULL, object_selected_and_point_valid); | 2253 | NULL, object_selected_and_point_valid, attachment); |
2254 | // [/RLVa:KB] | ||
2255 | // LLMenuItemCallGL* item = new LLMenuItemCallGL(attachment->getName(), | ||
2256 | // NULL, object_selected_and_point_valid); | ||
2235 | gAttachBodyPartPieMenus[group]->append(item); | 2257 | gAttachBodyPartPieMenus[group]->append(item); |
2236 | item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", attach_index); | 2258 | item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", attach_index); |
2237 | gDetachBodyPartPieMenus[group]->append(new LLMenuItemCallGL(attachment->getName(), | 2259 | gDetachBodyPartPieMenus[group]->append(new LLMenuItemCallGL(attachment->getName(), |
@@ -3089,10 +3111,16 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) | |||
3089 | const F32 time_visible = mTimeVisible.getElapsedTimeF32(); | 3111 | const F32 time_visible = mTimeVisible.getElapsedTimeF32(); |
3090 | const F32 NAME_SHOW_TIME = gSavedSettings.getF32("RenderNameShowTime"); // seconds | 3112 | const F32 NAME_SHOW_TIME = gSavedSettings.getF32("RenderNameShowTime"); // seconds |
3091 | const F32 FADE_DURATION = gSavedSettings.getF32("RenderNameFadeDuration"); // seconds | 3113 | const F32 FADE_DURATION = gSavedSettings.getF32("RenderNameFadeDuration"); // seconds |
3114 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.0b | ||
3115 | bool fRlvShowNames = gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES); | ||
3116 | // [/RLVa:KB] | ||
3092 | BOOL visible_avatar = isVisible() || mNeedsAnimUpdate; | 3117 | BOOL visible_avatar = isVisible() || mNeedsAnimUpdate; |
3093 | BOOL visible_chat = gSavedSettings.getBOOL("UseChatBubbles") && (mChats.size() || mTyping); | 3118 | BOOL visible_chat = gSavedSettings.getBOOL("UseChatBubbles") && (mChats.size() || mTyping); |
3094 | BOOL render_name = visible_chat || | 3119 | BOOL render_name = visible_chat || |
3095 | (visible_avatar && | 3120 | (visible_avatar && |
3121 | // [RLVa:KB] - Checked: 2009-08-11 (RLVa-1.0.1h) | Added: RLVa-1.0.0h | ||
3122 | ( (!fRlvShowNames) || (RlvSettings::fShowNameTags) ) && | ||
3123 | // [/RLVa:KB] | ||
3096 | ((sRenderName == RENDER_NAME_ALWAYS) || | 3124 | ((sRenderName == RENDER_NAME_ALWAYS) || |
3097 | (sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME))); | 3125 | (sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME))); |
3098 | // If it's your own avatar, don't draw in mouselook, and don't | 3126 | // If it's your own avatar, don't draw in mouselook, and don't |
@@ -3113,7 +3141,18 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) | |||
3113 | new_name = TRUE; | 3141 | new_name = TRUE; |
3114 | } | 3142 | } |
3115 | 3143 | ||
3116 | if (sRenderGroupTitles != mRenderGroupTitles) | 3144 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.0b |
3145 | if (fRlvShowNames) | ||
3146 | { | ||
3147 | if (mRenderGroupTitles) | ||
3148 | { | ||
3149 | mRenderGroupTitles = FALSE; | ||
3150 | new_name = TRUE; | ||
3151 | } | ||
3152 | } | ||
3153 | else if (sRenderGroupTitles != mRenderGroupTitles) | ||
3154 | // [/RLVa] | ||
3155 | //if (sRenderGroupTitles != mRenderGroupTitles) | ||
3117 | { | 3156 | { |
3118 | mRenderGroupTitles = sRenderGroupTitles; | 3157 | mRenderGroupTitles = sRenderGroupTitles; |
3119 | new_name = TRUE; | 3158 | new_name = TRUE; |
@@ -3218,6 +3257,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) | |||
3218 | || is_appearance != mNameAppearance) | 3257 | || is_appearance != mNameAppearance) |
3219 | { | 3258 | { |
3220 | std::string line; | 3259 | std::string line; |
3260 | |||
3221 | if (title && title->getString() && title->getString()[0] != '\0') | 3261 | if (title && title->getString() && title->getString()[0] != '\0') |
3222 | { | 3262 | { |
3223 | line += title->getString(); | 3263 | line += title->getString(); |
@@ -3232,6 +3272,15 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) | |||
3232 | 3272 | ||
3233 | line += " "; | 3273 | line += " "; |
3234 | line += lastname->getString(); | 3274 | line += lastname->getString(); |
3275 | |||
3276 | // [RLVa:KB] | ||
3277 | if (fRlvShowNames) | ||
3278 | { | ||
3279 | // User is not allowed to see who it is, due to RLV settings. | ||
3280 | line = gRlvHandler.getAnonym(line); | ||
3281 | } | ||
3282 | // [/RLVa:KB] | ||
3283 | |||
3235 | BOOL need_comma = FALSE; | 3284 | BOOL need_comma = FALSE; |
3236 | 3285 | ||
3237 | if (is_away || is_muted || is_busy) | 3286 | if (is_away || is_muted || is_busy) |
@@ -6328,6 +6377,40 @@ BOOL LLVOAvatar::attachObject(LLViewerObject *viewer_object) | |||
6328 | { | 6377 | { |
6329 | updateAttachmentVisibility(gAgent.getCameraMode()); | 6378 | updateAttachmentVisibility(gAgent.getCameraMode()); |
6330 | 6379 | ||
6380 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
6381 | if (rlv_handler_t::isEnabled()) | ||
6382 | { | ||
6383 | static bool fRlvFullyLoaded = false; | ||
6384 | static LLFrameTimer* pRlvFullyLoadedTimer = NULL; | ||
6385 | |||
6386 | // There's no way to know when we're done reattaching what was attached at log-off but this ugly evil bad hack tries anyway | ||
6387 | if (!fRlvFullyLoaded) | ||
6388 | { | ||
6389 | if (pRlvFullyLoadedTimer) | ||
6390 | { | ||
6391 | if (pRlvFullyLoadedTimer->getElapsedTimeF32() > 30.0f) | ||
6392 | { | ||
6393 | fRlvFullyLoaded = true; | ||
6394 | delete pRlvFullyLoadedTimer; | ||
6395 | pRlvFullyLoadedTimer = NULL; | ||
6396 | } | ||
6397 | else | ||
6398 | { | ||
6399 | pRlvFullyLoadedTimer->reset(); | ||
6400 | } | ||
6401 | } | ||
6402 | else if ( (!pRlvFullyLoadedTimer) && | ||
6403 | ( (0 == mPendingAttachment.size()) || | ||
6404 | ((1 == mPendingAttachment.size()) && (mPendingAttachment[0] == viewer_object)) ) ) | ||
6405 | { | ||
6406 | pRlvFullyLoadedTimer = new LLFrameTimer(); | ||
6407 | } | ||
6408 | } | ||
6409 | |||
6410 | gRlvHandler.onAttach(attachment, fRlvFullyLoaded); | ||
6411 | } | ||
6412 | // [/RLVa:KB] | ||
6413 | |||
6331 | // Then make sure the inventory is in sync with the avatar. | 6414 | // Then make sure the inventory is in sync with the avatar. |
6332 | gInventory.addChangedMask( LLInventoryObserver::LABEL, attachment->getItemID() ); | 6415 | gInventory.addChangedMask( LLInventoryObserver::LABEL, attachment->getItemID() ); |
6333 | gInventory.notifyObservers(); | 6416 | gInventory.notifyObservers(); |
@@ -6383,6 +6466,14 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) | |||
6383 | // only one object per attachment point for now | 6466 | // only one object per attachment point for now |
6384 | if (attachment->getObject() == viewer_object) | 6467 | if (attachment->getObject() == viewer_object) |
6385 | { | 6468 | { |
6469 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | ||
6470 | // URGENT-RLV: it looks like LLApp::isExiting() isn't always accurate so find something better (if it exists) | ||
6471 | if ( (rlv_handler_t::isEnabled()) && (!LLApp::isExiting()) && (mIsSelf) ) | ||
6472 | { | ||
6473 | gRlvHandler.onDetach(attachment); | ||
6474 | } | ||
6475 | // [/RLVa:KB] | ||
6476 | |||
6386 | LLUUID item_id = attachment->getItemID(); | 6477 | LLUUID item_id = attachment->getItemID(); |
6387 | attachment->removeObject(viewer_object); | 6478 | attachment->removeObject(viewer_object); |
6388 | if (mIsSelf) | 6479 | if (mIsSelf) |
@@ -6441,6 +6532,14 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object) | |||
6441 | 6532 | ||
6442 | gPipeline.markMoved(mDrawable, TRUE); | 6533 | gPipeline.markMoved(mDrawable, TRUE); |
6443 | mIsSitting = TRUE; | 6534 | mIsSitting = TRUE; |
6535 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.1d | ||
6536 | #ifdef RLV_EXTENSION_STARTLOCATION | ||
6537 | if (rlv_handler_t::isEnabled()) | ||
6538 | { | ||
6539 | RlvSettings::updateLoginLastLocation(); | ||
6540 | } | ||
6541 | #endif // RLV_EXTENSION_STARTLOCATION | ||
6542 | // [/RLVa:KB] | ||
6444 | mRoot.getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject | 6543 | mRoot.getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject |
6445 | mRoot.setPosition(getPosition()); | 6544 | mRoot.setPosition(getPosition()); |
6446 | mRoot.updateWorldMatrixChildren(); | 6545 | mRoot.updateWorldMatrixChildren(); |
@@ -6502,6 +6601,14 @@ void LLVOAvatar::getOffObject() | |||
6502 | gPipeline.markMoved(mDrawable, TRUE); | 6601 | gPipeline.markMoved(mDrawable, TRUE); |
6503 | 6602 | ||
6504 | mIsSitting = FALSE; | 6603 | mIsSitting = FALSE; |
6604 | // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.1d | ||
6605 | #ifdef RLV_EXTENSION_STARTLOCATION | ||
6606 | if (rlv_handler_t::isEnabled()) | ||
6607 | { | ||
6608 | RlvSettings::updateLoginLastLocation(); | ||
6609 | } | ||
6610 | #endif // RLV_EXTENSION_STARTLOCATION | ||
6611 | // [/RLVa:KB] | ||
6505 | mRoot.getXform()->setParent(NULL); // LLVOAvatar::getOffObject | 6612 | mRoot.getXform()->setParent(NULL); // LLVOAvatar::getOffObject |
6506 | mRoot.setPosition(cur_position_world); | 6613 | mRoot.setPosition(cur_position_world); |
6507 | mRoot.setRotation(cur_rotation_world); | 6614 | mRoot.setRotation(cur_rotation_world); |
diff --git a/linden/indra/newview/llvovolume.cpp b/linden/indra/newview/llvovolume.cpp index ad44356..adf82cd 100644 --- a/linden/indra/newview/llvovolume.cpp +++ b/linden/indra/newview/llvovolume.cpp | |||
@@ -1942,7 +1942,11 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e | |||
1942 | 1942 | ||
1943 | { | 1943 | { |
1944 | if (!mbCanSelect || | 1944 | if (!mbCanSelect || |
1945 | (gHideSelectedObjects && isSelected()) || | 1945 | // (gHideSelectedObjects && isSelected()) || |
1946 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
1947 | ( (gHideSelectedObjects && isSelected()) && | ||
1948 | ((!rlv_handler_t::isEnabled()) || (!isHUDAttachment()) || (gRlvHandler.isDetachable(this))) ) || | ||
1949 | // [/RLVa:KB] | ||
1946 | mDrawable->isDead() || | 1950 | mDrawable->isDead() || |
1947 | !gPipeline.hasRenderType(mDrawable->getRenderType())) | 1951 | !gPipeline.hasRenderType(mDrawable->getRenderType())) |
1948 | { | 1952 | { |
@@ -2084,10 +2088,18 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, | |||
2084 | { | 2088 | { |
2085 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 2089 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
2086 | 2090 | ||
2087 | if (facep->getViewerObject()->isSelected() && gHideSelectedObjects) | 2091 | // if (facep->getViewerObject()->isSelected() && gHideSelectedObjects) |
2092 | // { | ||
2093 | // return; | ||
2094 | // } | ||
2095 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
2096 | LLViewerObject* pObj = facep->getViewerObject(); | ||
2097 | if ( (pObj->isSelected() && gHideSelectedObjects) && | ||
2098 | ((!rlv_handler_t::isEnabled()) || (!pObj->isHUDAttachment()) || (gRlvHandler.isDetachable(pObj))) ) | ||
2088 | { | 2099 | { |
2089 | return; | 2100 | return; |
2090 | } | 2101 | } |
2102 | // [/RVLa:KB] | ||
2091 | 2103 | ||
2092 | //add face to drawmap | 2104 | //add face to drawmap |
2093 | LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[type]; | 2105 | LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[type]; |
diff --git a/linden/indra/newview/llworldmapview.cpp b/linden/indra/newview/llworldmapview.cpp index 77833c3..5e51e6f 100644 --- a/linden/indra/newview/llworldmapview.cpp +++ b/linden/indra/newview/llworldmapview.cpp | |||
@@ -640,7 +640,14 @@ void LLWorldMapView::draw() | |||
640 | // info->mAgents, | 640 | // info->mAgents, |
641 | // info->mName.c_str(), | 641 | // info->mName.c_str(), |
642 | // LLViewerRegion::accessToShortString(info->mAccess).c_str() ); | 642 | // LLViewerRegion::accessToShortString(info->mAccess).c_str() ); |
643 | if (info->mAccess == SIM_ACCESS_DOWN) | 643 | // [RLVa:KB] - Alternate: Snowglobe-1.0 | Checked: 2009-07-04 (RLVa-1.0.0a) |
644 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) | ||
645 | { | ||
646 | mesg = rlv_handler_t::cstrHidden; | ||
647 | } | ||
648 | else if (info->mAccess == SIM_ACCESS_DOWN) | ||
649 | // [/RLVa:KB] | ||
650 | // if (info->mAccess == SIM_ACCESS_DOWN) | ||
644 | { | 651 | { |
645 | mesg = llformat( "%s (%s)", info->mName.c_str(), sStringsMap["offline"].c_str()); | 652 | mesg = llformat( "%s (%s)", info->mName.c_str(), sStringsMap["offline"].c_str()); |
646 | } | 653 | } |
@@ -1069,7 +1076,10 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4& | |||
1069 | text_x = llclamp(text_x, half_text_width + TEXT_PADDING, getRect().getWidth() - half_text_width - TEXT_PADDING); | 1076 | text_x = llclamp(text_x, half_text_width + TEXT_PADDING, getRect().getWidth() - half_text_width - TEXT_PADDING); |
1070 | text_y = llclamp(text_y + vert_offset, TEXT_PADDING + vert_offset, getRect().getHeight() - llround(font->getLineHeight()) - TEXT_PADDING - vert_offset); | 1077 | text_y = llclamp(text_y + vert_offset, TEXT_PADDING + vert_offset, getRect().getHeight() - llround(font->getLineHeight()) - TEXT_PADDING - vert_offset); |
1071 | 1078 | ||
1072 | if (label != "") | 1079 | //if (label != "") |
1080 | // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | Added: RLVa-1.0.0a | ||
1081 | if ( (label != "") && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) | ||
1082 | // [/RLVa:KB] | ||
1073 | { | 1083 | { |
1074 | font->renderUTF8( | 1084 | font->renderUTF8( |
1075 | label, 0, | 1085 | label, 0, |
@@ -1129,7 +1139,10 @@ BOOL LLWorldMapView::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* stic | |||
1129 | 1139 | ||
1130 | std::string message = | 1140 | std::string message = |
1131 | llformat("%s (%s)", | 1141 | llformat("%s (%s)", |
1132 | info->mName.c_str(), | 1142 | //info->mName.c_str(), |
1143 | // [RLVa:KB] - Alternate: Snowglobe-1.0 | Checked: 2009-07-04 (RLVa-1.0.0a) | ||
1144 | (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? info->mName.c_str() : rlv_handler_t::cstrHidden.c_str(), | ||
1145 | // [/RLVa:KB] | ||
1133 | LLViewerRegion::accessToString(info->mAccess).c_str()); | 1146 | LLViewerRegion::accessToString(info->mAccess).c_str()); |
1134 | 1147 | ||
1135 | if (info->mAccess != SIM_ACCESS_DOWN) | 1148 | if (info->mAccess != SIM_ACCESS_DOWN) |
diff --git a/linden/indra/newview/pipeline.cpp b/linden/indra/newview/pipeline.cpp index 87b810c..67af961 100644 --- a/linden/indra/newview/pipeline.cpp +++ b/linden/indra/newview/pipeline.cpp | |||
@@ -1795,8 +1795,13 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) | |||
1795 | 1795 | ||
1796 | if (gHideSelectedObjects) | 1796 | if (gHideSelectedObjects) |
1797 | { | 1797 | { |
1798 | if (drawablep->getVObj().notNull() && | 1798 | // if (drawablep->getVObj().notNull() && |
1799 | drawablep->getVObj()->isSelected()) | 1799 | // drawablep->getVObj()->isSelected()) |
1800 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | ||
1801 | LLViewerObject* pObj = drawablep->getVObj(); | ||
1802 | if ( (pObj) && (pObj->isSelected()) && | ||
1803 | ((!rlv_handler_t::isEnabled()) || (!pObj->isHUDAttachment()) || (gRlvHandler.isDetachable(pObj))) ) | ||
1804 | // [/RVLa:KB] | ||
1800 | { | 1805 | { |
1801 | return; | 1806 | return; |
1802 | } | 1807 | } |
diff --git a/linden/indra/newview/primbackup.cpp b/linden/indra/newview/primbackup.cpp new file mode 100644 index 0000000..78fd482 --- /dev/null +++ b/linden/indra/newview/primbackup.cpp | |||
@@ -0,0 +1,1105 @@ | |||
1 | |||
2 | #include "llviewerprecompiledheaders.h" | ||
3 | #include "llviewermenu.h" | ||
4 | |||
5 | |||
6 | // system library includes | ||
7 | #include <iostream> | ||
8 | #include <fstream> | ||
9 | #include <sstream> | ||
10 | |||
11 | // linden library includes | ||
12 | #include "llfilepicker.h" | ||
13 | #include "indra_constants.h" | ||
14 | #include "llsdserialize.h" | ||
15 | #include "llsdutil.h" | ||
16 | |||
17 | #include "llcallbacklist.h" | ||
18 | |||
19 | // newview includes | ||
20 | #include "llagent.h" | ||
21 | #include "llselectmgr.h" | ||
22 | #include "lltoolplacer.h" | ||
23 | |||
24 | #include "lltexturecache.h" | ||
25 | |||
26 | #include "llnotify.h" | ||
27 | |||
28 | #include "llapr.h" | ||
29 | #include "lldir.h" | ||
30 | #include "llimage.h" | ||
31 | #include "lllfsthread.h" | ||
32 | #include "llviewercontrol.h" | ||
33 | #include "llassetuploadresponders.h" | ||
34 | #include "lleconomy.h" | ||
35 | #include "llhttpclient.h" | ||
36 | #include "lluploaddialog.h" | ||
37 | #include "lldir.h" | ||
38 | #include "llinventorymodel.h" // gInventory | ||
39 | #include "llviewercontrol.h" // gSavedSettings | ||
40 | #include "llviewermenu.h" // gMenuHolder | ||
41 | #include "llagent.h" | ||
42 | #include "llfilepicker.h" | ||
43 | #include "llfloateranimpreview.h" | ||
44 | #include "llfloaterbuycurrency.h" | ||
45 | #include "llfloaterimagepreview.h" | ||
46 | #include "llfloaternamedesc.h" | ||
47 | #include "llfloatersnapshot.h" | ||
48 | #include "llinventorymodel.h" // gInventory | ||
49 | #include "llresourcedata.h" | ||
50 | #include "llstatusbar.h" | ||
51 | #include "llviewercontrol.h" // gSavedSettings | ||
52 | #include "llviewerimagelist.h" | ||
53 | #include "lluictrlfactory.h" | ||
54 | #include "llviewermenu.h" // gMenuHolder | ||
55 | #include "llviewerregion.h" | ||
56 | #include "llviewerstats.h" | ||
57 | #include "llviewerwindow.h" | ||
58 | #include "llappviewer.h" | ||
59 | #include "lluploaddialog.h" | ||
60 | // Included to allow LLTextureCache::purgeTextures() to pause watchdog timeout | ||
61 | #include "llappviewer.h" | ||
62 | #include "lltransactiontypes.h" | ||
63 | |||
64 | #include "primbackup.h" | ||
65 | |||
66 | #include "llviewerobjectlist.h" | ||
67 | |||
68 | primbackup* primbackup::sInstance = 0; | ||
69 | |||
70 | class importResponder: public LLNewAgentInventoryResponder | ||
71 | { | ||
72 | public: | ||
73 | |||
74 | importResponder(const LLSD& post_data, | ||
75 | const LLUUID& vfile_id, | ||
76 | LLAssetType::EType asset_type) | ||
77 | : LLNewAgentInventoryResponder(post_data, vfile_id, asset_type) | ||
78 | { | ||
79 | } | ||
80 | |||
81 | |||
82 | //virtual | ||
83 | virtual void uploadComplete(const LLSD& content) | ||
84 | { | ||
85 | lldebugs << "LLNewAgentInventoryResponder::result from capabilities" << llendl; | ||
86 | |||
87 | LLAssetType::EType asset_type = LLAssetType::lookup(mPostData["asset_type"].asString()); | ||
88 | LLInventoryType::EType inventory_type = LLInventoryType::lookup(mPostData["inventory_type"].asString()); | ||
89 | |||
90 | // Update L$ and ownership credit information | ||
91 | // since it probably changed on the server | ||
92 | if (asset_type == LLAssetType::AT_TEXTURE || | ||
93 | asset_type == LLAssetType::AT_SOUND || | ||
94 | asset_type == LLAssetType::AT_ANIMATION) | ||
95 | { | ||
96 | gMessageSystem->newMessageFast(_PREHASH_MoneyBalanceRequest); | ||
97 | gMessageSystem->nextBlockFast(_PREHASH_AgentData); | ||
98 | gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); | ||
99 | gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | ||
100 | gMessageSystem->nextBlockFast(_PREHASH_MoneyData); | ||
101 | gMessageSystem->addUUIDFast(_PREHASH_TransactionID, LLUUID::null ); | ||
102 | gAgent.sendReliableMessage(); | ||
103 | |||
104 | // LLStringUtil::format_map_t args; | ||
105 | // args["[AMOUNT]"] = llformat("%d",LLGlobalEconomy::Singleton::getInstance()->getPriceUpload()); | ||
106 | // LLNotifyBox::showXml("UploadPayment", args); | ||
107 | } | ||
108 | |||
109 | // Actually add the upload to viewer inventory | ||
110 | llinfos << "Adding " << content["new_inventory_item"].asUUID() << " " | ||
111 | << content["new_asset"].asUUID() << " to inventory." << llendl; | ||
112 | if(mPostData["folder_id"].asUUID().notNull()) | ||
113 | { | ||
114 | LLPermissions perm; | ||
115 | U32 next_owner_perm; | ||
116 | perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); | ||
117 | if (mPostData["inventory_type"].asString() == "snapshot") | ||
118 | { | ||
119 | next_owner_perm = PERM_ALL; | ||
120 | } | ||
121 | else | ||
122 | { | ||
123 | next_owner_perm = PERM_MOVE | PERM_TRANSFER; | ||
124 | } | ||
125 | perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, next_owner_perm); | ||
126 | S32 creation_date_now = time_corrected(); | ||
127 | LLPointer<LLViewerInventoryItem> item | ||
128 | = new LLViewerInventoryItem(content["new_inventory_item"].asUUID(), | ||
129 | mPostData["folder_id"].asUUID(), | ||
130 | perm, | ||
131 | content["new_asset"].asUUID(), | ||
132 | asset_type, | ||
133 | inventory_type, | ||
134 | mPostData["name"].asString(), | ||
135 | mPostData["description"].asString(), | ||
136 | LLSaleInfo::DEFAULT, | ||
137 | LLInventoryItem::II_FLAGS_NONE, | ||
138 | creation_date_now); | ||
139 | gInventory.updateItem(item); | ||
140 | gInventory.notifyObservers(); | ||
141 | } | ||
142 | else | ||
143 | { | ||
144 | llwarns << "Can't find a folder to put it in" << llendl; | ||
145 | } | ||
146 | |||
147 | // remove the "Uploading..." message | ||
148 | LLUploadDialog::modalUploadFinished(); | ||
149 | |||
150 | primbackup::getInstance()->update_map(content["new_asset"].asUUID()); | ||
151 | primbackup::getInstance()->upload_next_asset(); | ||
152 | |||
153 | } | ||
154 | |||
155 | }; | ||
156 | |||
157 | |||
158 | |||
159 | class CacheReadResponder : public LLTextureCache::ReadResponder | ||
160 | { | ||
161 | public: | ||
162 | CacheReadResponder(const LLUUID& id, LLImageFormatted* image) | ||
163 | : mFormattedImage(image), mID(id) | ||
164 | { | ||
165 | setImage(image); | ||
166 | } | ||
167 | void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal) | ||
168 | { | ||
169 | if(imageformat==IMG_CODEC_TGA && mFormattedImage->getCodec()==IMG_CODEC_J2C) | ||
170 | { | ||
171 | llwarns<<"Bleh its a tga not saving"<<llendl; | ||
172 | mFormattedImage=NULL; | ||
173 | mImageSize=0; | ||
174 | return; | ||
175 | } | ||
176 | |||
177 | if (mFormattedImage.notNull()) | ||
178 | { | ||
179 | llassert_always(mFormattedImage->getCodec() == imageformat); | ||
180 | mFormattedImage->appendData(data, datasize); | ||
181 | } | ||
182 | else | ||
183 | { | ||
184 | mFormattedImage = LLImageFormatted::createFromType(imageformat); | ||
185 | mFormattedImage->setData(data,datasize); | ||
186 | } | ||
187 | mImageSize = imagesize; | ||
188 | mImageLocal = imagelocal; | ||
189 | } | ||
190 | |||
191 | virtual void completed(bool success) | ||
192 | { | ||
193 | if(success && (mFormattedImage.notNull()) && mImageSize>0) | ||
194 | { | ||
195 | |||
196 | llinfos << "SUCCESS getting texture "<<mID<< llendl; | ||
197 | |||
198 | std::string name; | ||
199 | mID.toString(name); | ||
200 | llinfos << "Saving to "<<(primbackup::getInstance()->getfolder()+"//"+name)<<llendl; | ||
201 | if(!mFormattedImage->save(primbackup::getInstance()->getfolder()+"//"+name)) | ||
202 | { | ||
203 | llinfos << "FAIL saving texture "<<mID<< llendl; | ||
204 | } | ||
205 | |||
206 | } | ||
207 | else | ||
208 | { | ||
209 | if(!success) | ||
210 | llwarns << "FAIL NOT SUCCESSFUL getting texture "<<mID<< llendl; | ||
211 | if(mFormattedImage.isNull()) | ||
212 | llwarns << "FAIL image is NULL "<<mID<< llendl; | ||
213 | } | ||
214 | |||
215 | primbackup::getInstance()->m_nexttextureready=true; | ||
216 | //JUST SAY NO TO APR DEADLOCKING | ||
217 | //primbackup::getInstance()->export_next_texture(); | ||
218 | } | ||
219 | private: | ||
220 | LLPointer<LLImageFormatted> mFormattedImage; | ||
221 | LLUUID mID; | ||
222 | }; | ||
223 | |||
224 | |||
225 | |||
226 | primbackup::primbackup() | ||
227 | : LLFloater( std::string("Prim Import Floater") ) | ||
228 | { | ||
229 | LLUICtrlFactory::getInstance()->buildFloater( this, "floater_prim_import.xml" ); | ||
230 | |||
231 | // reposition floater from saved settings | ||
232 | //LLRect rect = gSavedSettings.getRect( "FloaterPrimImport" ); | ||
233 | //reshape( rect.getWidth(), rect.getHeight(), FALSE ); | ||
234 | //setRect( rect ); | ||
235 | |||
236 | running=false; | ||
237 | textures.clear(); | ||
238 | assetmap.clear(); | ||
239 | current_asset=LLUUID::null; | ||
240 | m_retexture=false; | ||
241 | close(); | ||
242 | } | ||
243 | |||
244 | |||
245 | //////////////////////////////////////////////////////////////////////////////// | ||
246 | // | ||
247 | primbackup* primbackup::getInstance() | ||
248 | { | ||
249 | if ( ! sInstance ) | ||
250 | sInstance = new primbackup(); | ||
251 | |||
252 | return sInstance; | ||
253 | } | ||
254 | |||
255 | primbackup::~primbackup() | ||
256 | { | ||
257 | // save position of floater | ||
258 | gSavedSettings.setRect( "FloaterPrimImport", getRect() ); | ||
259 | sInstance = 0; | ||
260 | } | ||
261 | |||
262 | void primbackup::draw() | ||
263 | { | ||
264 | LLFloater::draw(); | ||
265 | } | ||
266 | |||
267 | void primbackup::show() | ||
268 | { | ||
269 | // set the title | ||
270 | setTitle( "stuff" ); | ||
271 | m_curobject=1; | ||
272 | m_curprim=0; | ||
273 | m_objects=0; | ||
274 | m_prims=0; | ||
275 | m_textures=0; | ||
276 | m_curtexture=0; | ||
277 | rezcount=0; | ||
278 | |||
279 | // make floater appear | ||
280 | setVisibleAndFrontmost(); | ||
281 | } | ||
282 | |||
283 | |||
284 | void primbackup::onClose( bool app_quitting ) | ||
285 | { | ||
286 | setVisible( false ); | ||
287 | // HACK for fast XML iteration replace with: | ||
288 | // destroy(); | ||
289 | } | ||
290 | |||
291 | void primbackup::updateexportnumbers() | ||
292 | { | ||
293 | |||
294 | std::stringstream sstr; | ||
295 | LLUICtrl * ctrl=this->getChild<LLUICtrl>("name_label"); | ||
296 | |||
297 | sstr<<"Export Progress \n"; | ||
298 | |||
299 | sstr << "Remaining Textures "<<textures.size()<<"\n"; | ||
300 | ctrl->setValue(LLSD("Text")=sstr.str()); | ||
301 | |||
302 | } | ||
303 | |||
304 | |||
305 | void primbackup::updateimportnumbers() | ||
306 | { | ||
307 | std::stringstream sstr; | ||
308 | LLUICtrl * ctrl=this->getChild<LLUICtrl>("name_label"); | ||
309 | |||
310 | if(m_retexture) | ||
311 | { | ||
312 | sstr << " Textures uploads remaining : "<<textures.size()<<"\n"; | ||
313 | ctrl->setValue(LLSD("Text")=sstr.str()); | ||
314 | } | ||
315 | else | ||
316 | { | ||
317 | sstr << " Textures uploads N/A \n"; | ||
318 | ctrl->setValue(LLSD("Text")=sstr.str()); | ||
319 | } | ||
320 | sstr << " Objects "<<this->m_curobject<<"/"<<this->m_objects<<"\n"; | ||
321 | ctrl->setValue(LLSD("Text")=sstr.str()); | ||
322 | |||
323 | sstr << " Rez "<<this->rezcount<<"/"<<this->m_prims; | ||
324 | ctrl->setValue(LLSD("Text")=sstr.str()); | ||
325 | |||
326 | sstr << " Build "<<this->m_curprim<<"/"<<this->m_prims; | ||
327 | ctrl->setValue(LLSD("Text")=sstr.str()); | ||
328 | |||
329 | |||
330 | } | ||
331 | |||
332 | void primbackup::pre_export_object() | ||
333 | { | ||
334 | textures.clear(); | ||
335 | llsd.clear(); | ||
336 | this_group.clear(); | ||
337 | |||
338 | // Open the file save dialog | ||
339 | LLFilePicker& file_picker = LLFilePicker::instance(); | ||
340 | if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_XML ) ) | ||
341 | { | ||
342 | // User canceled save. | ||
343 | return; | ||
344 | } | ||
345 | |||
346 | file_name = file_picker.getCurFile(); | ||
347 | folder = gDirUtilp->getDirName(file_name); | ||
348 | |||
349 | export_state=EXPORT_INIT; | ||
350 | gIdleCallbacks.addFunction(exportworker, NULL); | ||
351 | } | ||
352 | |||
353 | void primbackup::exportworker(void *userdata) | ||
354 | { | ||
355 | primbackup::getInstance()->updateexportnumbers(); | ||
356 | |||
357 | switch(primbackup::getInstance()->export_state) | ||
358 | { | ||
359 | case EXPORT_INIT: | ||
360 | { | ||
361 | primbackup::getInstance()->show(); | ||
362 | LLSelectMgr::getInstance()->getSelection()->ref(); | ||
363 | |||
364 | struct ff : public LLSelectedNodeFunctor | ||
365 | { | ||
366 | virtual bool apply(LLSelectNode* node) | ||
367 | { | ||
368 | if(gAgent.getID()!=node->mPermissions->getOwner()) | ||
369 | { | ||
370 | #ifdef LL_GRID_PERMISSIONS | ||
371 | return false; | ||
372 | #else | ||
373 | return true; | ||
374 | #endif | ||
375 | } | ||
376 | else if(581632==node->mPermissions->getMaskOwner() || 2147483647==node->mPermissions->getMaskOwner()) | ||
377 | { | ||
378 | return true; | ||
379 | } | ||
380 | return false; | ||
381 | } | ||
382 | } func; | ||
383 | |||
384 | if(LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func,false)) | ||
385 | primbackup::getInstance()->export_state=EXPORT_STRUCTURE; | ||
386 | else | ||
387 | { | ||
388 | llwarns<<"Incorrect permission to export"<<llendl; | ||
389 | primbackup::getInstance()->export_state=EXPORT_DONE; | ||
390 | primbackup::getInstance()->close(); | ||
391 | gIdleCallbacks.deleteFunction(exportworker); | ||
392 | LLSelectMgr::getInstance()->getSelection()->unref(); | ||
393 | |||
394 | } | ||
395 | break; | ||
396 | } | ||
397 | |||
398 | break; | ||
399 | case EXPORT_STRUCTURE: | ||
400 | { | ||
401 | struct ff : public LLSelectedObjectFunctor | ||
402 | { | ||
403 | virtual bool apply(LLViewerObject* object) | ||
404 | { | ||
405 | object->boostTexturePriority(TRUE); | ||
406 | LLViewerObject::child_list_t children = object->getChildren(); | ||
407 | children.push_front(object); //push root onto list | ||
408 | LLSD prim_llsd=primbackup::getInstance()->prims_to_llsd(children); | ||
409 | LLSD stuff; | ||
410 | stuff["root_position"] = object->getPosition().getValue(); | ||
411 | stuff["root_rotation"] = ll_sd_from_quaternion(object->getRotation()); | ||
412 | stuff["group_body"] = prim_llsd; | ||
413 | primbackup::getInstance()->llsd["data"].append(stuff); | ||
414 | return true; | ||
415 | } | ||
416 | } func; | ||
417 | |||
418 | primbackup::getInstance()->export_state=EXPORT_LLSD; | ||
419 | LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func,false); | ||
420 | LLSelectMgr::getInstance()->getSelection()->unref(); | ||
421 | |||
422 | break; | ||
423 | } | ||
424 | case EXPORT_TEXTURES: | ||
425 | if(primbackup::getInstance()->m_nexttextureready==false) | ||
426 | return; | ||
427 | |||
428 | //Ok we got work to do | ||
429 | primbackup::getInstance()->m_nexttextureready=false; | ||
430 | |||
431 | if(primbackup::getInstance()->textures.empty()) | ||
432 | { | ||
433 | primbackup::getInstance()->export_state=EXPORT_DONE; | ||
434 | return; | ||
435 | } | ||
436 | |||
437 | primbackup::getInstance()->export_next_texture(); | ||
438 | break; | ||
439 | |||
440 | case EXPORT_LLSD: | ||
441 | { | ||
442 | // Create a file stream and write to it | ||
443 | llofstream export_file(primbackup::getInstance()->file_name); | ||
444 | LLSDSerialize::toPrettyXML(primbackup::getInstance()->llsd, export_file); | ||
445 | export_file.close(); | ||
446 | primbackup::getInstance()->m_nexttextureready=true; | ||
447 | primbackup::getInstance()->export_state=EXPORT_TEXTURES; | ||
448 | } | ||
449 | break; | ||
450 | case EXPORT_DONE: | ||
451 | llinfos<<"Backup complete"<<llendl | ||
452 | gIdleCallbacks.deleteFunction(exportworker); | ||
453 | primbackup::getInstance()->close(); | ||
454 | break; | ||
455 | } | ||
456 | } | ||
457 | |||
458 | LLSD primbackup::prims_to_llsd(LLViewerObject::child_list_t child_list) | ||
459 | { | ||
460 | |||
461 | LLViewerObject* object; | ||
462 | LLSD llsd; | ||
463 | |||
464 | char localid[16]; | ||
465 | |||
466 | for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i) | ||
467 | { | ||
468 | object=(*i); | ||
469 | LLUUID id = object->getID(); | ||
470 | |||
471 | llinfos << "Exporting prim " << object->getID().asString() << llendl; | ||
472 | |||
473 | // Create an LLSD object that represents this prim. It will be injected in to the overall LLSD | ||
474 | // tree structure | ||
475 | LLSD prim_llsd; | ||
476 | |||
477 | if (!object->isRoot()) | ||
478 | { | ||
479 | |||
480 | // Parent id | ||
481 | snprintf(localid, sizeof(localid), "%u", object->getSubParent()->getLocalID()); | ||
482 | prim_llsd["parent"] = localid; | ||
483 | } | ||
484 | |||
485 | // Transforms | ||
486 | prim_llsd["position"] = object->getPosition().getValue(); | ||
487 | prim_llsd["scale"] = object->getScale().getValue(); | ||
488 | prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotation()); | ||
489 | |||
490 | // Flags | ||
491 | prim_llsd["shadows"] = object->flagCastShadows(); | ||
492 | prim_llsd["phantom"] = object->flagPhantom(); | ||
493 | prim_llsd["physical"] = (BOOL)(object->mFlags & FLAGS_USE_PHYSICS); | ||
494 | |||
495 | // Volume params | ||
496 | LLVolumeParams params = object->getVolume()->getParams(); | ||
497 | prim_llsd["volume"] = params.asLLSD(); | ||
498 | |||
499 | // Extra paramsb6fab961-af18-77f8-cf08-f021377a7244 | ||
500 | if (object->isFlexible()) | ||
501 | { | ||
502 | // Flexible | ||
503 | LLFlexibleObjectData* flex = (LLFlexibleObjectData*)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); | ||
504 | prim_llsd["flexible"] = flex->asLLSD(); | ||
505 | } | ||
506 | if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT)) | ||
507 | { | ||
508 | // Light | ||
509 | LLLightParams* light = (LLLightParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT); | ||
510 | prim_llsd["light"] = light->asLLSD(); | ||
511 | } | ||
512 | if (object->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT)) | ||
513 | { | ||
514 | // Sculpt | ||
515 | LLSculptParams* sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT); | ||
516 | prim_llsd["sculpt"] = sculpt->asLLSD(); | ||
517 | |||
518 | LLUUID sculpt_texture=sculpt->getSculptTexture(); | ||
519 | bool alreadyseen=false; | ||
520 | std::list<LLUUID>::iterator iter; | ||
521 | for(iter = textures.begin(); iter != textures.end() ; iter++) | ||
522 | { | ||
523 | if( (*iter)==sculpt_texture) | ||
524 | alreadyseen=true; | ||
525 | } | ||
526 | if(alreadyseen==false) | ||
527 | { | ||
528 | llinfos << "Found a sculpt texture, adding to list "<<sculpt_texture<<llendl; | ||
529 | textures.push_back(sculpt_texture); | ||
530 | } | ||
531 | } | ||
532 | |||
533 | // Textures | ||
534 | LLSD te_llsd; | ||
535 | U8 te_count = object->getNumTEs(); | ||
536 | for (U8 i = 0; i < te_count; i++) | ||
537 | { | ||
538 | bool alreadyseen=false; | ||
539 | te_llsd.append(object->getTE(i)->asLLSD()); | ||
540 | std::list<LLUUID>::iterator iter; | ||
541 | for(iter = textures.begin(); iter != textures.end() ; iter++) | ||
542 | { | ||
543 | if( (*iter)==object->getTE(i)->getID()) | ||
544 | alreadyseen=true; | ||
545 | } | ||
546 | if(alreadyseen==false) | ||
547 | textures.push_back(object->getTE(i)->getID()); | ||
548 | } | ||
549 | prim_llsd["textures"] = te_llsd; | ||
550 | |||
551 | // The keys in the primitive maps do not have to be localids, they can be any | ||
552 | // string. We simply use localids because they are a unique identifier | ||
553 | snprintf(localid, sizeof(localid), "%u", object->getLocalID()); | ||
554 | llsd[(const char*)localid] = prim_llsd; | ||
555 | } | ||
556 | |||
557 | updateexportnumbers(); | ||
558 | |||
559 | return llsd; | ||
560 | } | ||
561 | |||
562 | |||
563 | void primbackup::export_next_texture() | ||
564 | { | ||
565 | if(textures.empty()) | ||
566 | { | ||
567 | llinfos << "Finished exporting textures "<<llendl; | ||
568 | return; | ||
569 | } | ||
570 | |||
571 | std::list<LLUUID>::iterator iter; | ||
572 | iter = textures.begin(); | ||
573 | |||
574 | LLUUID id; | ||
575 | |||
576 | while(1) | ||
577 | { | ||
578 | if(iter==textures.end()) | ||
579 | { | ||
580 | m_nexttextureready=true; | ||
581 | return; | ||
582 | } | ||
583 | |||
584 | id=(*iter); | ||
585 | |||
586 | LLViewerImage * imagep = gImageList.hasImage(id); | ||
587 | if(imagep!=NULL) | ||
588 | { | ||
589 | S32 cur_discard = imagep->getDiscardLevel(); | ||
590 | if(cur_discard>0) | ||
591 | { | ||
592 | if(imagep->getBoostLevel()!=LLViewerImage::BOOST_PREVIEW) | ||
593 | imagep->setBoostLevel(LLViewerImage::BOOST_PREVIEW); //we want to force discard 0 this one does this. | ||
594 | } | ||
595 | else | ||
596 | { | ||
597 | break; | ||
598 | } | ||
599 | } | ||
600 | else | ||
601 | { | ||
602 | llwarns<<" We *DONT* have the texture "<<llendl; | ||
603 | } | ||
604 | iter++; | ||
605 | } | ||
606 | |||
607 | textures.remove(id); | ||
608 | |||
609 | llinfos<<"Requesting texture "<<id<<llendl; | ||
610 | LLImageJ2C * mFormattedImage = new LLImageJ2C; | ||
611 | CacheReadResponder* responder = new CacheReadResponder(id, mFormattedImage); | ||
612 | LLAppViewer::getTextureCache()->readFromCache(id,LLWorkerThread::PRIORITY_HIGH,0,999999,responder); | ||
613 | } | ||
614 | |||
615 | |||
616 | |||
617 | void primbackup::import_object(bool upload) | ||
618 | { | ||
619 | textures.clear(); | ||
620 | assetmap.clear(); | ||
621 | current_asset=LLUUID::null; | ||
622 | |||
623 | this->m_retexture=upload; | ||
624 | |||
625 | // Open the file open dialog | ||
626 | LLFilePicker& file_picker = LLFilePicker::instance(); | ||
627 | if( !file_picker.getOpenFile( LLFilePicker::FFLOAD_XML ) ) | ||
628 | { | ||
629 | // User canceled save. | ||
630 | return; | ||
631 | } | ||
632 | std::string file_name = file_picker.getFirstFile().c_str(); | ||
633 | folder = gDirUtilp->getDirName(file_name); | ||
634 | |||
635 | llifstream import_file(file_name); | ||
636 | LLSDSerialize::fromXML(llsd, import_file); | ||
637 | import_file.close(); | ||
638 | |||
639 | show(); | ||
640 | |||
641 | //Get the texture map | ||
642 | |||
643 | LLSD::map_const_iterator prim_it; | ||
644 | LLSD::array_const_iterator prim_arr_it; | ||
645 | |||
646 | this->m_curobject=1; | ||
647 | this->m_curprim=1; | ||
648 | this->m_objects=llsd["data"].size(); | ||
649 | this->m_prims=0; | ||
650 | rezcount=0; | ||
651 | |||
652 | updateimportnumbers(); | ||
653 | |||
654 | for( prim_arr_it = llsd["data"].beginArray(); prim_arr_it != llsd["data"].endArray(); prim_arr_it++) | ||
655 | { | ||
656 | |||
657 | LLSD llsd2; | ||
658 | llsd2=(*prim_arr_it)["group_body"]; | ||
659 | |||
660 | for( prim_it = llsd2.beginMap(); prim_it != llsd2.endMap(); prim_it++) | ||
661 | { | ||
662 | LLSD prim_llsd; | ||
663 | prim_llsd=llsd2[prim_it->first]; | ||
664 | LLSD::array_iterator text_it; | ||
665 | std::list<LLUUID>::iterator iter; | ||
666 | |||
667 | if(prim_llsd.has("sculpt")) | ||
668 | { | ||
669 | LLSculptParams* sculpt=new LLSculptParams(); | ||
670 | sculpt->fromLLSD(prim_llsd["sculpt"]); | ||
671 | LLUUID orig=sculpt->getSculptTexture(); | ||
672 | bool alreadyseen=false; | ||
673 | for(iter = textures.begin(); iter != textures.end() ; iter++) | ||
674 | { | ||
675 | if( (*iter)==orig) | ||
676 | alreadyseen=true; | ||
677 | } | ||
678 | if(alreadyseen==false) | ||
679 | { | ||
680 | llinfos << "Found a new SCULPT texture to upload "<<orig<<llendl; | ||
681 | textures.push_back(orig); | ||
682 | } | ||
683 | } | ||
684 | |||
685 | |||
686 | LLSD te_llsd; | ||
687 | te_llsd=prim_llsd["textures"]; | ||
688 | |||
689 | |||
690 | for(text_it=te_llsd.beginArray(); text_it !=te_llsd.endArray(); text_it++) | ||
691 | { | ||
692 | LLSD the_te; | ||
693 | the_te=(*text_it); | ||
694 | LLTextureEntry te; | ||
695 | te.fromLLSD(the_te); | ||
696 | |||
697 | te.getID(); | ||
698 | bool alreadyseen=false; | ||
699 | |||
700 | for(iter = textures.begin(); iter != textures.end() ; iter++) | ||
701 | { | ||
702 | if( (*iter)==te.getID()) | ||
703 | alreadyseen=true; | ||
704 | } | ||
705 | if(alreadyseen==false) | ||
706 | { | ||
707 | llinfos << "Found a new texture to upload "<<te.getID()<<llendl; | ||
708 | textures.push_back(te.getID()); | ||
709 | } | ||
710 | } | ||
711 | |||
712 | } | ||
713 | } | ||
714 | |||
715 | if(m_retexture==TRUE) | ||
716 | upload_next_asset(); | ||
717 | else | ||
718 | import_object1a(); | ||
719 | } | ||
720 | |||
721 | LLVector3 primbackup::offset_agent(LLVector3 offset) | ||
722 | { | ||
723 | LLVector3 pos= gAgent.getPositionAgent(); | ||
724 | LLQuaternion agent_rot=LLQuaternion(gAgent.getAtAxis(),gAgent.getLeftAxis(),gAgent.getUpAxis()); | ||
725 | pos=(offset*agent_rot+pos); | ||
726 | return pos; | ||
727 | } | ||
728 | |||
729 | void primbackup::rez_agent_offset(LLVector3 offset) | ||
730 | { | ||
731 | // This will break for a sitting agent | ||
732 | LLToolPlacer* mPlacer = new LLToolPlacer(); | ||
733 | mPlacer->setObjectType(LL_PCODE_CUBE); | ||
734 | //LLVector3 pos=offset_agent(offset); | ||
735 | mPlacer->placeObject((S32)(offset.mV[0]), (S32)(offset.mV[1]), 0); | ||
736 | } | ||
737 | |||
738 | void primbackup::import_object1a() | ||
739 | { | ||
740 | running=true; | ||
741 | |||
742 | show(); | ||
743 | |||
744 | group_prim_import_iter=llsd["data"].beginArray(); | ||
745 | root_root_pos=(*group_prim_import_iter)["root_position"]; | ||
746 | |||
747 | this->m_objects=llsd["data"].size(); | ||
748 | this->m_curobject=1; | ||
749 | import_next_object(); | ||
750 | } | ||
751 | |||
752 | void primbackup::import_next_object() | ||
753 | { | ||
754 | toselect.clear(); | ||
755 | rezcount=0; | ||
756 | |||
757 | this_group=(*group_prim_import_iter)["group_body"]; | ||
758 | prim_import_iter=this_group.beginMap(); | ||
759 | |||
760 | m_curprim=0; | ||
761 | m_prims=this_group.size(); | ||
762 | updateimportnumbers(); | ||
763 | LLVector3 lgpos=(*group_prim_import_iter)["root_position"]; | ||
764 | |||
765 | group_offset=lgpos-root_root_pos; | ||
766 | root_pos=offset_agent(LLVector3(2.0,0,0)); | ||
767 | root_rot=ll_quaternion_from_sd((*group_prim_import_iter)["root_rotation"]); | ||
768 | |||
769 | rez_agent_offset(LLVector3(0.0,2.0,0.0)); | ||
770 | // Now we must wait for the callback when ViewerObjectList gets the new objects and we have the correct number selected | ||
771 | } | ||
772 | |||
773 | // This function takes a pointer to a viewerobject and applys the prim definition that prim_llsd has | ||
774 | void primbackup::xmltoprim(LLSD prim_llsd,LLViewerObject * object) | ||
775 | { | ||
776 | LLUUID id = object->getID(); | ||
777 | expecting_update = object->getID(); | ||
778 | LLSelectMgr::getInstance()->selectObjectAndFamily(object); | ||
779 | |||
780 | if(prim_llsd.has("parent")) | ||
781 | { | ||
782 | //we are not the root node. | ||
783 | LLVector3 pos=prim_llsd["position"]; | ||
784 | LLQuaternion rot=ll_quaternion_from_sd(prim_llsd["rotation"]); | ||
785 | object->setPositionRegion((pos*root_rot)+(root_pos+group_offset)); | ||
786 | object->setRotation(rot*root_rot); | ||
787 | } | ||
788 | else | ||
789 | { | ||
790 | object->setPositionRegion(root_pos+group_offset); | ||
791 | LLQuaternion rot=ll_quaternion_from_sd(prim_llsd["rotation"]); | ||
792 | object->setRotation(rot); | ||
793 | } | ||
794 | |||
795 | object->setScale(prim_llsd["scale"]); | ||
796 | |||
797 | if(prim_llsd.has("shadows")) | ||
798 | if(prim_llsd["shadows"].asInteger()==1) | ||
799 | object->setFlags(FLAGS_CAST_SHADOWS,true); | ||
800 | |||
801 | if(prim_llsd.has("phantom")) | ||
802 | if(prim_llsd["phantom"].asInteger()==1) | ||
803 | object->setFlags(FLAGS_PHANTOM,true); | ||
804 | |||
805 | if(prim_llsd.has("physical")) | ||
806 | if(prim_llsd["physical"].asInteger()==1) | ||
807 | object->setFlags(FLAGS_USE_PHYSICS,true); | ||
808 | |||
809 | // Volume params | ||
810 | LLVolumeParams volume_params = object->getVolume()->getParams(); | ||
811 | volume_params.fromLLSD(prim_llsd["volume"]) ; | ||
812 | object->updateVolume(volume_params); | ||
813 | |||
814 | if(prim_llsd.has("sculpt")) | ||
815 | { | ||
816 | LLSculptParams* sculpt=new LLSculptParams(); | ||
817 | sculpt->fromLLSD(prim_llsd["sculpt"]); | ||
818 | |||
819 | //TODO check if map is valid and only set texture is map is valid and changes | ||
820 | |||
821 | if(assetmap[sculpt->getSculptTexture()].notNull()) | ||
822 | { | ||
823 | LLUUID replacment=assetmap[sculpt->getSculptTexture()]; | ||
824 | sculpt->setSculptTexture(replacment); | ||
825 | } | ||
826 | |||
827 | object->setParameterEntry(LLNetworkData::PARAMS_SCULPT,(LLNetworkData&)(*sculpt),true); | ||
828 | } | ||
829 | |||
830 | if(prim_llsd.has("light")) | ||
831 | { | ||
832 | LLLightParams * light=new LLLightParams(); | ||
833 | light->fromLLSD(prim_llsd["light"]); | ||
834 | object->setParameterEntry(LLNetworkData::PARAMS_LIGHT,(LLNetworkData&)(*light),true); | ||
835 | } | ||
836 | |||
837 | if(prim_llsd.has("flexible")) | ||
838 | { | ||
839 | LLFlexibleObjectData* flex=new LLFlexibleObjectData(); | ||
840 | flex->fromLLSD(prim_llsd["flexible"]); | ||
841 | object->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE,(LLNetworkData&)(*flex),true); | ||
842 | } | ||
843 | |||
844 | |||
845 | // Textures | ||
846 | LLSD te_llsd; | ||
847 | llinfos << "Processing textures for prim" << llendl; | ||
848 | |||
849 | te_llsd=prim_llsd["textures"]; | ||
850 | |||
851 | LLSD::array_iterator text_it; | ||
852 | U8 i=0; | ||
853 | i=0; | ||
854 | |||
855 | for(text_it=te_llsd.beginArray(); text_it !=te_llsd.endArray(); text_it++) | ||
856 | { | ||
857 | LLSD the_te; | ||
858 | the_te=(*text_it); | ||
859 | LLTextureEntry te; | ||
860 | te.fromLLSD(the_te); | ||
861 | |||
862 | if(assetmap[te.getID()].notNull()) | ||
863 | { | ||
864 | LLUUID replacment=assetmap[te.getID()]; | ||
865 | te.setID(replacment); | ||
866 | } | ||
867 | |||
868 | object->setTE(i,te); // | ||
869 | i++; | ||
870 | } | ||
871 | |||
872 | llinfos << "Textures done!" << llendl; | ||
873 | |||
874 | //bump the iterator now so the callbacks hook together nicely | ||
875 | //if(prim_import_iter!=this_group.endMap()) | ||
876 | // prim_import_iter++; | ||
877 | |||
878 | object->sendRotationUpdate(); | ||
879 | object->sendTEUpdate(); | ||
880 | object->sendShapeUpdate(); | ||
881 | LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_SCALE |UPD_POSITION); | ||
882 | |||
883 | LLSelectMgr::getInstance()->deselectAll(); | ||
884 | } | ||
885 | |||
886 | //This is fired when the update packet is processed so we know the prim settings have stuck | ||
887 | void primbackup::prim_update(LLViewerObject* object) | ||
888 | { | ||
889 | if(!running) | ||
890 | return; | ||
891 | |||
892 | if(object!=NULL) | ||
893 | if(object->mID!=expecting_update) | ||
894 | return; | ||
895 | |||
896 | m_curprim++; | ||
897 | updateimportnumbers(); | ||
898 | |||
899 | prim_import_iter++; | ||
900 | |||
901 | LLUUID x; | ||
902 | expecting_update=x.null; | ||
903 | |||
904 | if(prim_import_iter==this_group.endMap()) | ||
905 | { | ||
906 | llinfos<<"Trying to link"<<llendl; | ||
907 | |||
908 | if(toselect.size()>1) | ||
909 | { | ||
910 | std::reverse(toselect.begin(),toselect.end()); | ||
911 | //Now link | ||
912 | LLSelectMgr::getInstance()->deselectAll(); | ||
913 | LLSelectMgr::getInstance()->selectObjectAndFamily(toselect,true); | ||
914 | LLSelectMgr::getInstance()->sendLink(); | ||
915 | LLViewerObject * root=toselect.back(); | ||
916 | root->setRotation(root_rot); | ||
917 | } | ||
918 | |||
919 | this->m_curobject++; | ||
920 | group_prim_import_iter++; | ||
921 | if(group_prim_import_iter!=llsd["data"].endArray()) | ||
922 | { | ||
923 | import_next_object(); | ||
924 | return; | ||
925 | } | ||
926 | |||
927 | running=false; | ||
928 | this->close(); | ||
929 | return; | ||
930 | } | ||
931 | |||
932 | LLSD prim_llsd; | ||
933 | prim_llsd=this_group[prim_import_iter->first]; | ||
934 | |||
935 | if(toselect.empty()) | ||
936 | { | ||
937 | llwarns << "error: ran out of objects to mod" << llendl; | ||
938 | return; | ||
939 | } | ||
940 | |||
941 | if(prim_import_iter!=this_group.endMap()) | ||
942 | { | ||
943 | //rez_agent_offset(LLVector3(1.0,0,0)); | ||
944 | LLSD prim_llsd=this_group[prim_import_iter->first]; | ||
945 | process_iter++; | ||
946 | xmltoprim(prim_llsd,(*process_iter)); | ||
947 | } | ||
948 | } | ||
949 | |||
950 | // Callback when we rez a new object when the importer is running. | ||
951 | bool primbackup::newprim(LLViewerObject * pobject) | ||
952 | { | ||
953 | if(running) | ||
954 | { | ||
955 | rezcount++; | ||
956 | toselect.push_back(pobject); | ||
957 | updateimportnumbers(); | ||
958 | prim_import_iter++; | ||
959 | |||
960 | if(prim_import_iter!=this_group.endMap()) | ||
961 | { | ||
962 | |||
963 | pobject->setPosition(this->offset_agent(LLVector3(0,1.0,0))); | ||
964 | LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION); | ||
965 | |||
966 | rez_agent_offset(LLVector3(1.0,0,0)); | ||
967 | } | ||
968 | else | ||
969 | { | ||
970 | llinfos << "All prims rezed, moving to build stage" <<llendl; | ||
971 | prim_import_iter=this_group.beginMap(); | ||
972 | LLSD prim_llsd=this_group[prim_import_iter->first]; | ||
973 | process_iter=toselect.begin(); | ||
974 | xmltoprim(prim_llsd,(*process_iter)); | ||
975 | } | ||
976 | } | ||
977 | |||
978 | return true; | ||
979 | } | ||
980 | |||
981 | void primbackup::update_map(LLUUID uploaded_asset) | ||
982 | { | ||
983 | if(current_asset.isNull()) | ||
984 | return; | ||
985 | |||
986 | assetmap.insert(std::pair<LLUUID,LLUUID>(current_asset,uploaded_asset)); | ||
987 | llinfos << "Mapping "<<current_asset<<" to "<<uploaded_asset<<llendl; | ||
988 | |||
989 | } | ||
990 | |||
991 | |||
992 | void myupload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_type, | ||
993 | std::string name, | ||
994 | std::string desc, S32 compression_info, | ||
995 | LLAssetType::EType destination_folder_type, | ||
996 | LLInventoryType::EType inv_type, | ||
997 | U32 next_owner_perm, | ||
998 | const std::string& display_name, | ||
999 | LLAssetStorage::LLStoreAssetCallback callback, | ||
1000 | void *userdata) | ||
1001 | { | ||
1002 | if(gDisconnected) | ||
1003 | { | ||
1004 | return ; | ||
1005 | } | ||
1006 | |||
1007 | LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID()); | ||
1008 | |||
1009 | // At this point, we're ready for the upload. | ||
1010 | std::string upload_message = "Uploading...\n\n"; | ||
1011 | upload_message.append(display_name); | ||
1012 | LLUploadDialog::modalUploadDialog(upload_message); | ||
1013 | |||
1014 | std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory"); | ||
1015 | if (!url.empty()) | ||
1016 | { | ||
1017 | LLSD body; | ||
1018 | body["folder_id"] = gInventory.findCategoryUUIDForType((destination_folder_type == LLAssetType::AT_NONE) ? asset_type : destination_folder_type); | ||
1019 | body["asset_type"] = LLAssetType::lookup(asset_type); | ||
1020 | body["inventory_type"] = LLInventoryType::lookup(inv_type); | ||
1021 | body["name"] = name; | ||
1022 | body["description"] = desc; | ||
1023 | |||
1024 | std::ostringstream llsdxml; | ||
1025 | LLSDSerialize::toXML(body, llsdxml); | ||
1026 | lldebugs << "posting body to capability: " << llsdxml.str() << llendl; | ||
1027 | //LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, uuid, asset_type)); | ||
1028 | LLHTTPClient::post(url, body, new importResponder(body, uuid, asset_type)); | ||
1029 | |||
1030 | } | ||
1031 | else | ||
1032 | { | ||
1033 | llinfos << "NewAgentInventory capability not found, FUCK!" << llendl; | ||
1034 | } | ||
1035 | } | ||
1036 | |||
1037 | |||
1038 | |||
1039 | void primbackup::upload_next_asset() | ||
1040 | { | ||
1041 | if(textures.empty()) | ||
1042 | { | ||
1043 | llinfos<<" Texture list is empty, moving to rez statge"<< llendl; | ||
1044 | current_asset=LLUUID::null; | ||
1045 | import_object1a(); | ||
1046 | return; | ||
1047 | } | ||
1048 | |||
1049 | this->updateimportnumbers(); | ||
1050 | |||
1051 | std::list<LLUUID>::iterator iter; | ||
1052 | iter=textures.begin(); | ||
1053 | LLUUID id=(*iter); | ||
1054 | textures.pop_front(); | ||
1055 | |||
1056 | llinfos<<"Got texture ID "<<id<< "trying to upload"<<llendl; | ||
1057 | |||
1058 | current_asset=id; | ||
1059 | std::string struid; | ||
1060 | id.toString(struid); | ||
1061 | std::string filename=folder+"//"+struid; | ||
1062 | |||
1063 | |||
1064 | LLAssetID uuid; | ||
1065 | LLTransactionID tid; | ||
1066 | |||
1067 | // gen a new transaction ID for this asset | ||
1068 | tid.generate(); | ||
1069 | uuid = tid.makeAssetID(gAgent.getSecureSessionID()); | ||
1070 | |||
1071 | S32 file_size; | ||
1072 | apr_file_t* fp = ll_apr_file_open(filename, LL_APR_RB, &file_size); | ||
1073 | if (fp) | ||
1074 | { | ||
1075 | const S32 buf_size = 65536; | ||
1076 | U8 copy_buf[buf_size]; | ||
1077 | LLVFile file(gVFS, uuid, LLAssetType::AT_TEXTURE, LLVFile::WRITE); | ||
1078 | file.setMaxSize(file_size); | ||
1079 | |||
1080 | while ((file_size = ll_apr_file_read(fp, copy_buf, buf_size))) | ||
1081 | { | ||
1082 | file.write(copy_buf, file_size); | ||
1083 | } | ||
1084 | apr_file_close(fp); | ||
1085 | } | ||
1086 | else | ||
1087 | { | ||
1088 | llwarns<<"Unable to access output file "<<filename<<llendl; | ||
1089 | upload_next_asset(); | ||
1090 | return; | ||
1091 | } | ||
1092 | |||
1093 | myupload_new_resource( | ||
1094 | tid, LLAssetType::AT_TEXTURE, struid, | ||
1095 | struid, 0, | ||
1096 | LLAssetType::AT_TEXTURE, | ||
1097 | LLInventoryType::defaultForAssetType(LLAssetType::AT_TEXTURE), | ||
1098 | 0x0, | ||
1099 | "Uploaded texture", | ||
1100 | NULL, | ||
1101 | NULL); | ||
1102 | |||
1103 | |||
1104 | } | ||
1105 | |||
diff --git a/linden/indra/newview/primbackup.h b/linden/indra/newview/primbackup.h new file mode 100644 index 0000000..fddc35f --- /dev/null +++ b/linden/indra/newview/primbackup.h | |||
@@ -0,0 +1,132 @@ | |||
1 | |||
2 | #include "llviewerinventory.h" | ||
3 | |||
4 | #define LL_GRID_PERMISSIONS 1 | ||
5 | |||
6 | enum export_states {EXPORT_INIT,EXPORT_STRUCTURE,EXPORT_TEXTURES,EXPORT_LLSD,EXPORT_DONE}; | ||
7 | |||
8 | class primbackup : public LLFloater | ||
9 | |||
10 | { | ||
11 | public: | ||
12 | //Export state machine | ||
13 | enum export_states export_state; | ||
14 | |||
15 | //Export idle callback | ||
16 | static void exportworker(void *userdata); | ||
17 | |||
18 | //Static accessor | ||
19 | static primbackup* getInstance(); | ||
20 | |||
21 | virtual ~primbackup(); | ||
22 | |||
23 | //Floater stuff | ||
24 | virtual void show(); | ||
25 | virtual void draw(); | ||
26 | virtual void onClose( bool app_quitting ); | ||
27 | |||
28 | //Import entry point | ||
29 | void import_object(bool upload=FALSE); | ||
30 | |||
31 | //Export entry point | ||
32 | void pre_export_object(); | ||
33 | |||
34 | //Update map from texture worker | ||
35 | void update_map(LLUUID uploaded_asset); | ||
36 | |||
37 | //Move to next texture upload | ||
38 | void upload_next_asset(); | ||
39 | |||
40 | // is ready for next texture? | ||
41 | bool m_nexttextureready; | ||
42 | |||
43 | //Folder public geter | ||
44 | std::string getfolder() {return folder;}; | ||
45 | |||
46 | //Prim updated callback | ||
47 | void prim_update(LLViewerObject* object); | ||
48 | |||
49 | //New prim call back | ||
50 | bool newprim(LLViewerObject * pobject); | ||
51 | |||
52 | private: | ||
53 | |||
54 | //Static singleton stuff | ||
55 | primbackup(); | ||
56 | static primbackup* sInstance; | ||
57 | |||
58 | // are we active flag | ||
59 | bool running; | ||
60 | |||
61 | //file and folder name control | ||
62 | std::string file_name; | ||
63 | std::string folder; | ||
64 | |||
65 | // True if we need to rebase the assets | ||
66 | bool m_retexture; | ||
67 | |||
68 | //Counts of import and export objects and textures and prims | ||
69 | int m_objects,m_curobject; | ||
70 | int m_prims,m_curprim; | ||
71 | int m_textures,m_curtexture; | ||
72 | |||
73 | // No prims rezed | ||
74 | int rezcount; | ||
75 | |||
76 | // Update the floater with status numbers | ||
77 | void updateimportnumbers(); | ||
78 | void updateexportnumbers(); | ||
79 | |||
80 | //Convert a selection list of objects to LLSD | ||
81 | LLSD prims_to_llsd(LLViewerObject::child_list_t child_list); | ||
82 | |||
83 | // Start the import process | ||
84 | void import_object1a(); | ||
85 | |||
86 | //Export the next texture in list | ||
87 | void export_next_texture(); | ||
88 | |||
89 | //apply LLSD to object | ||
90 | void xmltoprim(LLSD prim_llsd,LLViewerObject * pobject); | ||
91 | |||
92 | |||
93 | //rez a prim at a given position (note not agent offset X/Y screen for raycast) | ||
94 | void rez_agent_offset(LLVector3 offset); | ||
95 | |||
96 | //Move to the next import group | ||
97 | void import_next_object(); | ||
98 | |||
99 | //Get an offset from the agent based on rotation and current pos | ||
100 | LLVector3 offset_agent(LLVector3 offset); | ||
101 | |||
102 | // Rebase map | ||
103 | std::map<LLUUID,LLUUID> assetmap; | ||
104 | |||
105 | //Export texture list | ||
106 | std::list<LLUUID> textures; | ||
107 | |||
108 | //Import object tracking | ||
109 | std::vector<LLViewerObject *> toselect; | ||
110 | std::vector<LLViewerObject *>::iterator process_iter; | ||
111 | |||
112 | //Working LLSD holders | ||
113 | LLUUID current_asset; | ||
114 | LLSD llsd; | ||
115 | LLSD this_group; | ||
116 | LLUUID expecting_update; | ||
117 | |||
118 | //working llsd itterators for objects and linksets | ||
119 | LLSD::map_const_iterator prim_import_iter; | ||
120 | LLSD::array_const_iterator group_prim_import_iter; | ||
121 | |||
122 | // Root pos and central root pos for link set | ||
123 | LLVector3 root_pos; | ||
124 | LLVector3 root_root_pos; | ||
125 | LLVector3 group_offset; | ||
126 | |||
127 | //Agent inital pos and rot when starting import | ||
128 | LLQuaternion root_rot; | ||
129 | LLQuaternion agent_rot; | ||
130 | |||
131 | }; | ||
132 | |||
diff --git a/linden/indra/newview/rlvevent.h b/linden/indra/newview/rlvevent.h new file mode 100644 index 0000000..c3d9c45 --- /dev/null +++ b/linden/indra/newview/rlvevent.h | |||
@@ -0,0 +1,224 @@ | |||
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 | /* | ||
14 | * RlvEvent | ||
15 | * ======== | ||
16 | * Passed to observer event handlers (contains the same paramaters as RlvHandler::processXXXCommand) | ||
17 | */ | ||
18 | |||
19 | class RlvEvent | ||
20 | { | ||
21 | public: | ||
22 | RlvEvent(const LLUUID& uuid, const RlvCommand& rlvCmd) : m_UUID(uuid), m_rlvCmd(rlvCmd) {} | ||
23 | virtual ~RlvEvent() {} | ||
24 | |||
25 | const LLUUID& getSenderID() const { return m_UUID; }; | ||
26 | const RlvCommand& getCommand() const { return m_rlvCmd; }; | ||
27 | |||
28 | protected: | ||
29 | LLUUID m_UUID; | ||
30 | RlvCommand m_rlvCmd; | ||
31 | }; | ||
32 | |||
33 | // ============================================================================ | ||
34 | /* | ||
35 | * RlvObserver | ||
36 | * =========== | ||
37 | * Provides a way to extend the existing command set without changing the main RlvHandler class | ||
38 | * | ||
39 | * Steps: | ||
40 | * - derive your class from RlvObserver | ||
41 | * - override any of the event functions you need | ||
42 | * - add it as an observer: gRlvHandler.addObserver(new RlbObserverDerivedClass()); | ||
43 | * - done | ||
44 | * | ||
45 | * Notes: | ||
46 | * - as long as you don't call gRlvHandler.remObserver() your class will be cleaned up from | ||
47 | * RlvEventEmitter destructor (see below) | ||
48 | * - event handlers are called only if RlvHandler didn't handle it so while you can | ||
49 | * add a new command @foobar=n, you won't get called for @detach=n | ||
50 | * - event handlers are called *after* the command is added so a call to | ||
51 | * RlvHandler::hasBehaviour("foobar") would return TRUE | ||
52 | * - return TRUE if you handled the command (won't get passed on to the next observer) | ||
53 | * return FALSE if you didn't handle the command (gets passed on to the next observer) | ||
54 | * | ||
55 | */ | ||
56 | |||
57 | class RlvObserver | ||
58 | { | ||
59 | public: | ||
60 | virtual ~RlvObserver() {} | ||
61 | |||
62 | typedef RlvEvent EventType; | ||
63 | |||
64 | virtual BOOL onAddCommand(const EventType& rlvEvent) { return FALSE; } | ||
65 | virtual BOOL onRemoveCommand(const EventType& rlvEvent) { return FALSE; } | ||
66 | virtual BOOL onReplyCommand(const EventType& rlvEvent) { return FALSE; } | ||
67 | virtual BOOL onForceCommand(const EventType& rlvEvent) { return FALSE; } | ||
68 | }; | ||
69 | |||
70 | // ============================================================================ | ||
71 | /* | ||
72 | * RlvEventEmitter | ||
73 | * =============== | ||
74 | * Essentially a slightly modified eventEmitter (see lleventemitter.h) | ||
75 | * | ||
76 | * Changes: | ||
77 | * - if an event handler returns TRUE then no further observers are notified | ||
78 | * - cleans up the (remaining) observers in the destructor | ||
79 | */ | ||
80 | |||
81 | template < class T > | ||
82 | class RlvEventEmitter | ||
83 | { | ||
84 | public: | ||
85 | typedef typename T::EventType EventType; | ||
86 | typedef std::list< T* > ObserverContainer; | ||
87 | typedef BOOL ( T::*observerMethod )( const EventType& ); | ||
88 | |||
89 | protected: | ||
90 | ObserverContainer observers; | ||
91 | |||
92 | public: | ||
93 | RlvEventEmitter() { }; | ||
94 | |||
95 | ~RlvEventEmitter() | ||
96 | { | ||
97 | clearObservers(); | ||
98 | } | ||
99 | |||
100 | BOOL addObserver ( T* observerIn ) | ||
101 | { | ||
102 | if ( ! observerIn ) | ||
103 | return FALSE; | ||
104 | |||
105 | // check if observer already exists | ||
106 | if ( std::find ( observers.begin (), observers.end (), observerIn ) != observers.end () ) | ||
107 | return FALSE; | ||
108 | |||
109 | // save it | ||
110 | observers.push_back ( observerIn ); | ||
111 | |||
112 | return true; | ||
113 | } | ||
114 | |||
115 | BOOL remObserver ( T* observerIn ) | ||
116 | { | ||
117 | if ( ! observerIn ) | ||
118 | return FALSE; | ||
119 | |||
120 | observers.remove ( observerIn ); | ||
121 | |||
122 | return TRUE; | ||
123 | } | ||
124 | |||
125 | void clearObservers() | ||
126 | { | ||
127 | typename std::list< T* >::iterator iter = observers.begin (); | ||
128 | |||
129 | while (iter != observers.end ()) | ||
130 | { | ||
131 | delete *iter; | ||
132 | ++iter; | ||
133 | }; | ||
134 | |||
135 | observers.clear(); | ||
136 | } | ||
137 | |||
138 | BOOL update ( observerMethod method, const EventType& msgIn ) | ||
139 | { | ||
140 | typename std::list< T* >::iterator iter = observers.begin (); | ||
141 | |||
142 | BOOL fContinue = TRUE; | ||
143 | while ( (iter != observers.end ()) && (fContinue) ) | ||
144 | { | ||
145 | fContinue = !( ( ( *iter )->*method ) ( msgIn ) ); | ||
146 | ++iter; | ||
147 | }; | ||
148 | |||
149 | return !fContinue; | ||
150 | } | ||
151 | }; | ||
152 | |||
153 | // ============================================================================ | ||
154 | |||
155 | class RlvBehaviourObserver | ||
156 | { | ||
157 | public: | ||
158 | virtual ~RlvBehaviourObserver() {} | ||
159 | virtual void changed(const RlvCommand& rlvCmd, bool fInternal) = 0; | ||
160 | }; | ||
161 | |||
162 | // ============================================================================ | ||
163 | |||
164 | class RlvBehaviourNotifyObserver : public RlvBehaviourObserver | ||
165 | { | ||
166 | public: | ||
167 | virtual ~RlvBehaviourNotifyObserver() { } | ||
168 | |||
169 | void changed(const RlvCommand& rlvCmd, bool fInternal) | ||
170 | { | ||
171 | if ( (fInternal) || ((RLV_TYPE_ADD != rlvCmd.getParamType()) && (RLV_TYPE_REMOVE != rlvCmd.getParamType())) ) | ||
172 | return; | ||
173 | |||
174 | std::string strCmd = rlvCmd.asString(); | ||
175 | std::string strNotify = llformat("/%s=%c", strCmd.c_str(), (RLV_TYPE_ADD == rlvCmd.getParamType()) ? 'n' : 'y'); | ||
176 | |||
177 | for (std::multimap<LLUUID, notifyData>::const_iterator itNotify = m_Notifications.begin(); | ||
178 | itNotify != m_Notifications.end(); ++itNotify) | ||
179 | { | ||
180 | if ( (itNotify->second.strFilter.empty()) || (std::string::npos != strCmd.find(itNotify->second.strFilter)) ) | ||
181 | rlvSendChatReply(itNotify->second.nChannel, strNotify); | ||
182 | } | ||
183 | } | ||
184 | |||
185 | void addNotify(const LLUUID& idObj, S32 nChannel, const std::string& strFilter) | ||
186 | { | ||
187 | m_Notifications.insert(std::pair<LLUUID, notifyData>(idObj, notifyData(nChannel, strFilter))); | ||
188 | } | ||
189 | |||
190 | void clearNotify(const LLUUID& idObj) | ||
191 | { | ||
192 | m_Notifications.erase(idObj); | ||
193 | } | ||
194 | |||
195 | bool hasNotify() | ||
196 | { | ||
197 | return (m_Notifications.size() != 0); | ||
198 | } | ||
199 | |||
200 | void removeNotify(const LLUUID& idObj, S32 nChannel, const std::string& strFilter) | ||
201 | { | ||
202 | for (std::multimap<LLUUID, notifyData>::iterator itNotify = m_Notifications.lower_bound(idObj), | ||
203 | endNotify = m_Notifications.upper_bound(idObj); itNotify != endNotify; ++itNotify) | ||
204 | { | ||
205 | if ( (itNotify->second.nChannel == nChannel) && (itNotify->second.strFilter == strFilter) ) | ||
206 | { | ||
207 | m_Notifications.erase(itNotify); | ||
208 | break; | ||
209 | } | ||
210 | } | ||
211 | } | ||
212 | protected: | ||
213 | struct notifyData | ||
214 | { | ||
215 | S32 nChannel; | ||
216 | std::string strFilter; | ||
217 | notifyData(S32 channel, const std::string& filter) : nChannel(channel), strFilter(filter) {} | ||
218 | }; | ||
219 | std::multimap<LLUUID, notifyData> m_Notifications; | ||
220 | }; | ||
221 | |||
222 | // ============================================================================ | ||
223 | |||
224 | #endif // RLV_EVENTEMITTER_H | ||
diff --git a/linden/indra/newview/rlvextensions.cpp b/linden/indra/newview/rlvextensions.cpp new file mode 100644 index 0000000..6f79636 --- /dev/null +++ b/linden/indra/newview/rlvextensions.cpp | |||
@@ -0,0 +1,454 @@ | |||
1 | #include "llviewerprecompiledheaders.h" | ||
2 | #include "llagent.h" | ||
3 | #include "llviewercontrol.h" | ||
4 | #include "llviewerwindow.h" | ||
5 | #include "llvoavatar.h" | ||
6 | #include "llwlparammanager.h" | ||
7 | |||
8 | #include "rlvextensions.h" | ||
9 | #include "rlvhandler.h" | ||
10 | |||
11 | // ============================================================================ | ||
12 | |||
13 | std::map<std::string, S16> RlvExtGetSet::m_DbgAllowed; | ||
14 | |||
15 | // Checked: 2009-06-03 (RLVa-0.2.0h) | Modified: RLVa-0.2.0h | ||
16 | RlvExtGetSet::RlvExtGetSet() | ||
17 | { | ||
18 | if (!m_DbgAllowed.size()) // m_DbgAllowed is static and should only be initialized once | ||
19 | { | ||
20 | m_DbgAllowed.insert(std::pair<std::string, S16>("AvatarSex", DBG_READ | DBG_PSEUDO)); | ||
21 | m_DbgAllowed.insert(std::pair<std::string, S16>("RenderResolutionDivisor", DBG_READ | DBG_WRITE)); | ||
22 | #ifdef RLV_EXTENSION_CMD_GETSETDEBUG_EX | ||
23 | m_DbgAllowed.insert(std::pair<std::string, S16>(RLV_SETTING_FORBIDGIVETORLV, DBG_READ)); | ||
24 | m_DbgAllowed.insert(std::pair<std::string, S16>(RLV_SETTING_NOSETENV, DBG_READ)); | ||
25 | m_DbgAllowed.insert(std::pair<std::string, S16>("WindLightUseAtmosShaders", DBG_READ)); | ||
26 | #endif // RLV_EXTENSION_CMD_GETSETDEBUG_EX | ||
27 | |||
28 | // Cache persistance of every setting | ||
29 | LLControlVariable* pSetting; | ||
30 | for (std::map<std::string, S16>::iterator itDbg = m_DbgAllowed.begin(); itDbg != m_DbgAllowed.end(); ++itDbg) | ||
31 | { | ||
32 | if ( ((pSetting = gSavedSettings.getControl(itDbg->first)) != NULL) && (pSetting->isPersisted()) ) | ||
33 | itDbg->second |= DBG_PERSIST; | ||
34 | } | ||
35 | } | ||
36 | } | ||
37 | |||
38 | // Checked: 2009-05-17 (RLVa-0.2.0a) | ||
39 | BOOL RlvExtGetSet::onForceCommand(const RlvEvent& rlvEvent) | ||
40 | { | ||
41 | return processCommand(rlvEvent.getSenderID(), rlvEvent.getCommand()); | ||
42 | } | ||
43 | |||
44 | // Checked: 2009-05-17 (RLVa-0.2.0a) | ||
45 | BOOL RlvExtGetSet::onReplyCommand(const EventType& rlvEvent) | ||
46 | { | ||
47 | return processCommand(rlvEvent.getSenderID(), rlvEvent.getCommand()); | ||
48 | } | ||
49 | |||
50 | // Checked: 2009-06-18 (RLVa-0.2.1d) | Modified: RLVa-0.2.1d | ||
51 | BOOL RlvExtGetSet::processCommand(const LLUUID& idObj, const RlvCommand& rlvCmd) | ||
52 | { | ||
53 | std::string strBehaviour = rlvCmd.getBehaviour(), strGetSet, strSetting; | ||
54 | int idxSetting = strBehaviour.find('_'); | ||
55 | if ( (strBehaviour.length() >= 6) && (-1 != idxSetting) && ((int)strBehaviour.length() > idxSetting + 1) ) | ||
56 | { | ||
57 | strSetting = strBehaviour.substr(idxSetting + 1); | ||
58 | strBehaviour.erase(idxSetting); // Get rid of "_<setting>" | ||
59 | |||
60 | strGetSet = strBehaviour.substr(0, 3); | ||
61 | strBehaviour.erase(0, 3); // Get rid of get/set | ||
62 | |||
63 | if ("debug" == strBehaviour) | ||
64 | { | ||
65 | if ( ("get" == strGetSet) && (RLV_TYPE_REPLY == rlvCmd.getParamType()) ) | ||
66 | { | ||
67 | rlvSendChatReply(rlvCmd.getParam(), onGetDebug(strSetting)); | ||
68 | return TRUE; | ||
69 | } | ||
70 | else if ( ("set" == strGetSet) && (RLV_TYPE_FORCE == rlvCmd.getParamType()) ) | ||
71 | { | ||
72 | if (!gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETDEBUG, idObj)) | ||
73 | onSetDebug(strSetting, rlvCmd.getOption()); | ||
74 | return TRUE; | ||
75 | } | ||
76 | } | ||
77 | else if ("env" == strBehaviour) | ||
78 | { | ||
79 | if ( ("get" == strGetSet) && (RLV_TYPE_REPLY == rlvCmd.getParamType()) ) | ||
80 | { | ||
81 | rlvSendChatReply(rlvCmd.getParam(), onGetEnv(strSetting)); | ||
82 | return TRUE; | ||
83 | } | ||
84 | else if ( ("set" == strGetSet) && (RLV_TYPE_FORCE == rlvCmd.getParamType()) ) | ||
85 | { | ||
86 | if (!gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETENV, idObj)) | ||
87 | onSetEnv(strSetting, rlvCmd.getOption()); | ||
88 | return TRUE; | ||
89 | } | ||
90 | } | ||
91 | } | ||
92 | else if ("setrot" == rlvCmd.getBehaviour()) | ||
93 | { | ||
94 | // NOTE: if <option> is invalid (or missing) altogether then RLV-1.17 will rotate to 0.0 (which is actually PI / 4) | ||
95 | F32 nAngle = 0.0f; | ||
96 | if (LLStringUtil::convertToF32(rlvCmd.getOption(), nAngle)) | ||
97 | { | ||
98 | nAngle += RLV_SETROT_OFFSET; | ||
99 | |||
100 | gAgent.startCameraAnimation(); | ||
101 | |||
102 | LLVector3 at(LLVector3::x_axis); | ||
103 | at.rotVec(nAngle, LLVector3::z_axis); | ||
104 | at.normalize(); | ||
105 | gAgent.resetAxes(at); | ||
106 | |||
107 | return TRUE; | ||
108 | } | ||
109 | } | ||
110 | return FALSE; | ||
111 | } | ||
112 | |||
113 | // Checked: 2009-06-03 (RLVa-0.2.0h) | Modified: RLVa-0.2.0h | ||
114 | bool RlvExtGetSet::findDebugSetting(std::string& strSetting, S16& flags) | ||
115 | { | ||
116 | LLStringUtil::toLower(strSetting); // Convenience for non-RLV calls | ||
117 | |||
118 | std::string strTemp; | ||
119 | for (std::map<std::string, S16>::const_iterator itSetting = m_DbgAllowed.begin(); itSetting != m_DbgAllowed.end(); ++itSetting) | ||
120 | { | ||
121 | strTemp = itSetting->first; | ||
122 | LLStringUtil::toLower(strTemp); | ||
123 | |||
124 | if (strSetting == strTemp) | ||
125 | { | ||
126 | strSetting = itSetting->first; | ||
127 | flags = itSetting->second; | ||
128 | return true; | ||
129 | } | ||
130 | } | ||
131 | return false; | ||
132 | } | ||
133 | |||
134 | // Checked: 2009-06-03 (RLVa-0.2.0h) | Added: RLVa-0.2.0h | ||
135 | S16 RlvExtGetSet::getDebugSettingFlags(const std::string& strSetting) | ||
136 | { | ||
137 | std::map<std::string, S16>::const_iterator itSetting = m_DbgAllowed.find(strSetting); | ||
138 | return (itSetting != m_DbgAllowed.end()) ? itSetting->second : 0; | ||
139 | } | ||
140 | |||
141 | // Checked: 2009-06-03 (RLVa-0.2.0h) | Modified: RLVa-0.2.0h | ||
142 | std::string RlvExtGetSet::onGetDebug(std::string strSetting) | ||
143 | { | ||
144 | S16 dbgFlags; | ||
145 | if ( (findDebugSetting(strSetting, dbgFlags)) && ((dbgFlags & DBG_READ) == DBG_READ) ) | ||
146 | { | ||
147 | if ((dbgFlags & DBG_PSEUDO) == 0) | ||
148 | { | ||
149 | LLControlVariable* pSetting = gSavedSettings.getControl(strSetting); | ||
150 | if (pSetting) | ||
151 | { | ||
152 | switch (pSetting->type()) | ||
153 | { | ||
154 | case TYPE_U32: | ||
155 | return llformat("%u", gSavedSettings.getU32(strSetting)); | ||
156 | case TYPE_S32: | ||
157 | return llformat("%d", gSavedSettings.getS32(strSetting)); | ||
158 | case TYPE_BOOLEAN: | ||
159 | return llformat("%d", gSavedSettings.getBOOL(strSetting)); | ||
160 | default: | ||
161 | RLV_ERRS << "Unexpected debug setting type" << LL_ENDL; | ||
162 | break; | ||
163 | } | ||
164 | } | ||
165 | } | ||
166 | else | ||
167 | { | ||
168 | return onGetPseudoDebug(strSetting); | ||
169 | } | ||
170 | } | ||
171 | return std::string(); | ||
172 | } | ||
173 | |||
174 | // Checked: 2009-06-03 (RLVa-0.2.0h) | Added: RLVa-0.2.0h | ||
175 | std::string RlvExtGetSet::onGetPseudoDebug(const std::string& strSetting) | ||
176 | { | ||
177 | // Skip sanity checking because it's all done in RlvExtGetSet::onGetDebug() already | ||
178 | if ("AvatarSex" == strSetting) | ||
179 | { | ||
180 | if (gAgent.getAvatarObject()) | ||
181 | return llformat("%d", (gAgent.getAvatarObject()->getSex() == SEX_MALE)); // [See LLFloaterCustomize::LLFloaterCustomize()] | ||
182 | } | ||
183 | return std::string(); | ||
184 | } | ||
185 | |||
186 | // Checked: 2009-06-03 (RLVa-0.2.0h) | Modified: RLVa-0.2.0h | ||
187 | void RlvExtGetSet::onSetDebug(std::string strSetting, const std::string& strValue) | ||
188 | { | ||
189 | S16 dbgFlags; | ||
190 | if ( (findDebugSetting(strSetting, dbgFlags)) && ((dbgFlags & DBG_WRITE) == DBG_WRITE) ) | ||
191 | { | ||
192 | if ((dbgFlags & DBG_PSEUDO) == 0) | ||
193 | { | ||
194 | LLControlVariable* pSetting = gSavedSettings.getControl(strSetting); | ||
195 | if (pSetting) | ||
196 | { | ||
197 | U32 u32Value; S32 s32Value; BOOL fValue; | ||
198 | switch (pSetting->type()) | ||
199 | { | ||
200 | case TYPE_U32: | ||
201 | if (LLStringUtil::convertToU32(strValue, u32Value)) | ||
202 | gSavedSettings.setU32(strSetting, u32Value); | ||
203 | break; | ||
204 | case TYPE_S32: | ||
205 | if (LLStringUtil::convertToS32(strValue, s32Value)) | ||
206 | gSavedSettings.setS32(strSetting, s32Value); | ||
207 | break; | ||
208 | case TYPE_BOOLEAN: | ||
209 | if (LLStringUtil::convertToBOOL(strValue, fValue)) | ||
210 | gSavedSettings.setBOOL(strSetting, fValue); | ||
211 | break; | ||
212 | default: | ||
213 | RLV_ERRS << "Unexpected debug setting type" << LL_ENDL; | ||
214 | break; | ||
215 | } | ||
216 | |||
217 | // Default settings should persist if they were marked that way, but non-default settings should never persist | ||
218 | pSetting->setPersist( (pSetting->isDefault()) ? ((dbgFlags & DBG_PERSIST) == DBG_PERSIST) : false ); | ||
219 | } | ||
220 | } | ||
221 | } | ||
222 | } | ||
223 | |||
224 | std::string RlvExtGetSet::onGetEnv(std::string strSetting) | ||
225 | { | ||
226 | LLWLParamManager* pWLParams = LLWLParamManager::instance(); | ||
227 | |||
228 | F32 nValue = 0.0f; | ||
229 | if ("daytime" == strSetting) | ||
230 | { | ||
231 | nValue = (pWLParams->mAnimator.mIsRunning && pWLParams->mAnimator.mUseLindenTime) ? -1.0f : pWLParams->mAnimator.getDayTime(); | ||
232 | } | ||
233 | else if ("preset" == strSetting) | ||
234 | { | ||
235 | return (pWLParams->mAnimator.mIsRunning && pWLParams->mAnimator.mUseLindenTime) ? std::string() : pWLParams->mCurParams.mName; | ||
236 | } | ||
237 | else if ("cloudcoverage" == strSetting) nValue = pWLParams->mCloudCoverage; | ||
238 | else if ("cloudscale" == strSetting) nValue = pWLParams->mCloudScale; | ||
239 | else if ("cloudscrollx" == strSetting) nValue = pWLParams->mCurParams.getCloudScrollX() - 10.0f; | ||
240 | else if ("cloudscrolly" == strSetting) nValue = pWLParams->mCurParams.getCloudScrollY() - 10.0f; | ||
241 | else if ("densitymultiplier" == strSetting) nValue = pWLParams->mDensityMult * 1000; | ||
242 | else if ("distancemultiplier" == strSetting) nValue = pWLParams->mDistanceMult; | ||
243 | else if ("eastangle" == strSetting) nValue = pWLParams->mCurParams.getEastAngle() / F_TWO_PI; | ||
244 | else if ("hazedensity" == strSetting) nValue = pWLParams->mHazeDensity.r; | ||
245 | else if ("hazehorizon" == strSetting) nValue = pWLParams->mHazeHorizon.r; | ||
246 | else if ("maxaltitude" == strSetting) nValue = pWLParams->mMaxAlt; | ||
247 | else if ("scenegamma" == strSetting) nValue = pWLParams->mWLGamma; | ||
248 | else if ("starbrightness" == strSetting) nValue = pWLParams->mCurParams.getStarBrightness(); | ||
249 | else if ("sunglowfocus" == strSetting) nValue = -pWLParams->mGlow.b / 5.0f; | ||
250 | else if ("sunglowsize" == strSetting) nValue = 2 - pWLParams->mGlow.r / 20.0f; | ||
251 | else if ("sunmoonposition" == strSetting) nValue = pWLParams->mCurParams.getSunAngle() / F_TWO_PI; | ||
252 | else | ||
253 | { | ||
254 | char ch = strSetting[strSetting.length() - 1]; | ||
255 | // HACK-RLVa: not entirely proper (creates new synonyms) | ||
256 | if ('x' == ch) ch = 'r'; | ||
257 | else if ('y' == ch) ch = 'g'; | ||
258 | else if ('d' == ch) ch = 'b'; | ||
259 | |||
260 | if ( ('r' == ch) || ('g' == ch) || ('b' == ch) || ('i' == ch) ) | ||
261 | { | ||
262 | WLColorControl* pColour = NULL; | ||
263 | strSetting.erase(strSetting.length() - 2, 1); | ||
264 | |||
265 | if ("ambient" == strSetting) pColour = &pWLParams->mAmbient; | ||
266 | else if ("bluedensity" == strSetting) pColour = &pWLParams->mBlueDensity; | ||
267 | else if ("bluehorizon" == strSetting) pColour = &pWLParams->mBlueHorizon; | ||
268 | else if ("sunmooncolor" == strSetting) pColour = &pWLParams->mSunlight; | ||
269 | else if ("cloudcolor" == strSetting) pColour = &pWLParams->mCloudColor; | ||
270 | else if ("cloud" == strSetting) pColour = &pWLParams->mCloudMain; | ||
271 | else if ("clouddetail" == strSetting) pColour = &pWLParams->mCloudDetail; | ||
272 | |||
273 | if (pColour) | ||
274 | { | ||
275 | if ('r' == ch) nValue = pColour->b; | ||
276 | else if ('g' == ch) nValue = pColour->b; | ||
277 | else if ('b' == ch) nValue = pColour->b; | ||
278 | else if (('i' == ch) && (pColour->hasSliderName)) nValue = pColour->i; | ||
279 | |||
280 | if (pColour->isBlueHorizonOrDensity) nValue /= 2.0f; | ||
281 | else if (pColour->isSunOrAmbientColor) nValue /= 3.0f; | ||
282 | } | ||
283 | } | ||
284 | } | ||
285 | |||
286 | return llformat("%f", nValue); | ||
287 | } | ||
288 | |||
289 | void RlvExtGetSet::onSetEnv(std::string strSetting, const std::string& strValue) | ||
290 | { | ||
291 | LLWLParamManager* pWLParams = LLWLParamManager::instance(); | ||
292 | WLFloatControl* pFloat = NULL; | ||
293 | WLColorControl* pColour = NULL; | ||
294 | |||
295 | F32 nValue = 0.0f; | ||
296 | // Sanity check - make sure strValue specifies a number for all settings except "preset" | ||
297 | if ( (rlv_handler_t::fNoSetEnv) || ( (!LLStringUtil::convertToF32(strValue, nValue)) && ("preset" != strSetting) )) | ||
298 | return; | ||
299 | |||
300 | // Not quite correct, but RLV-1.16.0 will halt the default daytime cycle on invalid commands so we need to as well | ||
301 | pWLParams->mAnimator.mIsRunning = false; | ||
302 | pWLParams->mAnimator.mUseLindenTime = false; | ||
303 | |||
304 | // See LLWorldEnvSettings::handleEvent() | ||
305 | if ("daytime" == strSetting) | ||
306 | { | ||
307 | if (0.0f <= nValue) | ||
308 | { | ||
309 | pWLParams->mAnimator.setDayTime(llmin(nValue, 1.0f)); | ||
310 | pWLParams->mAnimator.update(pWLParams->mCurParams); | ||
311 | } | ||
312 | else | ||
313 | { | ||
314 | pWLParams->mAnimator.mIsRunning = true; | ||
315 | pWLParams->mAnimator.mUseLindenTime = true; | ||
316 | } | ||
317 | return; | ||
318 | } | ||
319 | // See LLFloaterWindLight::onChangePresetName() | ||
320 | else if ("preset" == strSetting) | ||
321 | { | ||
322 | pWLParams->loadPreset(strValue, true); | ||
323 | return; | ||
324 | } | ||
325 | // See LLFloaterWindLight::onStarAlphaMoved | ||
326 | else if ("starbrightness" == strSetting) | ||
327 | { | ||
328 | pWLParams->mCurParams.setStarBrightness(nValue); | ||
329 | return; | ||
330 | } | ||
331 | // See LLFloaterWindLight::onGlowRMoved() / LLFloaterWindLight::onGlowBMoved() | ||
332 | else if ( ("sunglowfocus" == strSetting) || ("sunglowsize" == strSetting) ) | ||
333 | { | ||
334 | WLColorControl *pColour = &pWLParams->mGlow; | ||
335 | if ("sunglowfocus" == strSetting) | ||
336 | pColour->b = -nValue * 5; | ||
337 | else | ||
338 | pColour->r = (2 - nValue) * 20; | ||
339 | |||
340 | pColour->update(pWLParams->mCurParams); | ||
341 | pWLParams->propagateParameters(); | ||
342 | return; | ||
343 | } | ||
344 | // See LLFloaterWindLight::onSunMoved() | ||
345 | else if ( ("eastangle" == strSetting) || ("sunmoonposition" == strSetting) ) | ||
346 | { | ||
347 | if ("eastangle" == strSetting) | ||
348 | pWLParams->mCurParams.setEastAngle(F_TWO_PI * nValue); | ||
349 | else | ||
350 | pWLParams->mCurParams.setSunAngle(F_TWO_PI * nValue); | ||
351 | |||
352 | // TODO-RLVa: it looks like propagateParameters() will actually take care of this for us, making this redundant? | ||
353 | WLColorControl* pColour = &pWLParams->mLightnorm; | ||
354 | pColour->r = -sin(pWLParams->mCurParams.getEastAngle()) * cos(pWLParams->mCurParams.getSunAngle()); | ||
355 | pColour->g = sin(pWLParams->mCurParams.getSunAngle()); | ||
356 | pColour->b = cos(pWLParams->mCurParams.getEastAngle()) * cos(pWLParams->mCurParams.getSunAngle()); | ||
357 | pColour->i = 1.f; | ||
358 | |||
359 | pColour->update(pWLParams->mCurParams); | ||
360 | pWLParams->propagateParameters(); | ||
361 | return; | ||
362 | } | ||
363 | // See LLFloaterWindLight::onCloudScrollXMoved() / LLFloaterWindLight::onCloudScrollYMoved() | ||
364 | else if ("cloudscrollx" == strSetting) | ||
365 | { | ||
366 | pWLParams->mCurParams.setCloudScrollX(nValue + 10.0f); | ||
367 | return; | ||
368 | } | ||
369 | else if ("cloudscrolly" == strSetting) | ||
370 | { | ||
371 | pWLParams->mCurParams.setCloudScrollY(nValue + 10.0f); | ||
372 | return; | ||
373 | } | ||
374 | // See LLFloaterWindLight::onFloatControlMoved() | ||
375 | else if ("cloudcoverage" == strSetting) pFloat = &pWLParams->mCloudCoverage; | ||
376 | else if ("cloudscale" == strSetting) pFloat = &pWLParams->mCloudScale; | ||
377 | else if ("densitymultiplier" == strSetting) pFloat = &pWLParams->mDensityMult; | ||
378 | else if ("distancemultiplier" == strSetting) pFloat = &pWLParams->mDistanceMult; | ||
379 | else if ("maxaltitude" == strSetting) pFloat = &pWLParams->mMaxAlt; | ||
380 | else if ("scenegamma" == strSetting) pFloat = &pWLParams->mWLGamma; | ||
381 | // See LLFloaterWindLight::onColorControlRMoved() | ||
382 | else if ("hazedensity" == strSetting) pColour = &pWLParams->mHazeDensity; | ||
383 | else if ("hazehorizon" == strSetting) pColour = &pWLParams->mHazeHorizon; | ||
384 | |||
385 | if (pFloat) | ||
386 | { | ||
387 | pFloat->x = nValue / pFloat->mult; | ||
388 | pFloat->update(pWLParams->mCurParams); | ||
389 | pWLParams->propagateParameters(); | ||
390 | return; | ||
391 | } | ||
392 | else if (pColour) | ||
393 | { | ||
394 | pColour->r = nValue; | ||
395 | pColour->update(pWLParams->mCurParams); | ||
396 | pWLParams->propagateParameters(); | ||
397 | return; | ||
398 | } | ||
399 | |||
400 | // RGBI settings | ||
401 | char ch = strSetting[strSetting.length() - 1]; | ||
402 | if ('x' == ch) ch = 'r'; | ||
403 | else if ('y' == ch) ch = 'g'; | ||
404 | else if ('d' == ch) ch = 'b'; | ||
405 | |||
406 | if ( ('r' == ch) || ('g' == ch) || ('b' == ch) || ('i' == ch) ) | ||
407 | { | ||
408 | strSetting.erase(strSetting.length() - 2, 1); | ||
409 | |||
410 | if ("ambient" == strSetting) pColour = &pWLParams->mAmbient; | ||
411 | else if ("bluedensity" == strSetting) pColour = &pWLParams->mBlueDensity; | ||
412 | else if ("bluehorizon" == strSetting) pColour = &pWLParams->mBlueHorizon; | ||
413 | else if ("sunmooncolor" == strSetting) pColour = &pWLParams->mSunlight; | ||
414 | else if ("cloudcolor" == strSetting) pColour = &pWLParams->mCloudColor; | ||
415 | else if ("cloud" == strSetting) pColour = &pWLParams->mCloudMain; | ||
416 | else if ("clouddetail" == strSetting) pColour = &pWLParams->mCloudDetail; | ||
417 | |||
418 | if (pColour) | ||
419 | { | ||
420 | if (pColour->isBlueHorizonOrDensity) nValue *= 2.0f; | ||
421 | else if (pColour->isSunOrAmbientColor) nValue *= 3.0f; | ||
422 | |||
423 | if ('i' == ch) // (See: LLFloaterWindLight::onColorControlIMoved) | ||
424 | { | ||
425 | if (!pColour->hasSliderName) | ||
426 | return; | ||
427 | |||
428 | F32 curMax = llmax(pColour->r, pColour->g, pColour->b); | ||
429 | if ( (0.0f == nValue) || (0.0f == curMax) ) | ||
430 | pColour->r = pColour->g = pColour->b = pColour->i = nValue; | ||
431 | else | ||
432 | { | ||
433 | F32 nDelta = (nValue - curMax) / curMax; | ||
434 | pColour->r *= (1.0f + nDelta); | ||
435 | pColour->g *= (1.0f + nDelta); | ||
436 | pColour->b *= (1.0f + nDelta); | ||
437 | pColour->i = nValue; | ||
438 | } | ||
439 | } | ||
440 | else // (See: LLFloaterWindLight::onColorControlRMoved) | ||
441 | { | ||
442 | F32* pnValue = ('r' == ch) ? &pColour->r : ('g' == ch) ? &pColour->g : ('b' == ch) ? &pColour->b : NULL; | ||
443 | if (pnValue) | ||
444 | *pnValue = nValue; | ||
445 | pColour->i = llmax(pColour->r, pColour->g, pColour->b); | ||
446 | } | ||
447 | |||
448 | pColour->update(pWLParams->mCurParams); | ||
449 | pWLParams->propagateParameters(); | ||
450 | } | ||
451 | } | ||
452 | } | ||
453 | |||
454 | // ============================================================================ | ||
diff --git a/linden/indra/newview/rlvextensions.h b/linden/indra/newview/rlvextensions.h new file mode 100644 index 0000000..5c10c58 --- /dev/null +++ b/linden/indra/newview/rlvextensions.h | |||
@@ -0,0 +1,43 @@ | |||
1 | #ifndef RLV_EXTENSIONS_H | ||
2 | #define RLV_EXTENSIONS_H | ||
3 | |||
4 | #include "rlvhelper.h" | ||
5 | #include "rlvevent.h" | ||
6 | |||
7 | // ============================================================================ | ||
8 | /* | ||
9 | * RlvExtGetSet | ||
10 | * ============ | ||
11 | * Implements @get_XXX:<option>=<channel> and @set_XXX:<option>=force | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | class RlvExtGetSet : public RlvObserver | ||
16 | { | ||
17 | public: | ||
18 | RlvExtGetSet(); | ||
19 | virtual ~RlvExtGetSet() {} | ||
20 | |||
21 | virtual BOOL onForceCommand(const RlvEvent& rlvEvent); | ||
22 | virtual BOOL onReplyCommand(const RlvEvent& rlvEvent); | ||
23 | protected: | ||
24 | std::string onGetDebug(std::string strSetting); | ||
25 | std::string onGetPseudoDebug(const std::string& strSetting); | ||
26 | void onSetDebug(std::string strSetting, const std::string& strValue); | ||
27 | |||
28 | std::string onGetEnv(std::string strSetting); | ||
29 | void onSetEnv(std::string strSetting, const std::string& strValue); | ||
30 | |||
31 | BOOL processCommand(const LLUUID& idObj, const RlvCommand& rlvCmd); | ||
32 | |||
33 | public: | ||
34 | enum { DBG_READ = 0x01, DBG_WRITE = 0x02, DBG_PERSIST = 0x04, DBG_PSEUDO = 0x08 }; | ||
35 | static std::map<std::string, S16> m_DbgAllowed; | ||
36 | |||
37 | static bool findDebugSetting(/*[in,out]*/ std::string& strSetting, /*[out]*/ S16& flags); | ||
38 | static S16 getDebugSettingFlags(const std::string& strSetting); | ||
39 | }; | ||
40 | |||
41 | // ============================================================================ | ||
42 | |||
43 | #endif // RLV_EXTENSIONS_H | ||
diff --git a/linden/indra/newview/rlvfloaterbehaviour.cpp b/linden/indra/newview/rlvfloaterbehaviour.cpp new file mode 100644 index 0000000..39fcf12 --- /dev/null +++ b/linden/indra/newview/rlvfloaterbehaviour.cpp | |||
@@ -0,0 +1,152 @@ | |||
1 | #include "llviewerprecompiledheaders.h" | ||
2 | |||
3 | #include "llagent.h" | ||
4 | #include "llcachename.h" | ||
5 | #include "llscrolllistctrl.h" | ||
6 | #include "lluictrlfactory.h" | ||
7 | #include "llviewerinventory.h" | ||
8 | #include "llviewerobjectlist.h" | ||
9 | #include "llvoavatar.h" | ||
10 | |||
11 | #include "rlvfloaterbehaviour.h" | ||
12 | |||
13 | // ============================================================================ | ||
14 | |||
15 | RlvFloaterBehaviour::RlvFloaterBehaviour(const LLSD& key) | ||
16 | : LLFloater(std::string("rlvBehaviours")) | ||
17 | { | ||
18 | LLUICtrlFactory::getInstance()->buildFloater(this, "floater_rlv_behaviour.xml"); | ||
19 | } | ||
20 | |||
21 | |||
22 | void RlvFloaterBehaviour::show(void*) | ||
23 | { | ||
24 | RlvFloaterBehaviour::showInstance(); | ||
25 | } | ||
26 | |||
27 | void RlvFloaterBehaviour::refreshAll() | ||
28 | { | ||
29 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | ||
30 | LLCtrlListInterface* pList = childGetListInterface("behaviour_list"); | ||
31 | const rlv_object_map_t* pRlvObjects = gRlvHandler.getObjectMap(); | ||
32 | if ( (!pAvatar) || (!pList) || (!pRlvObjects) ) | ||
33 | return; | ||
34 | |||
35 | pList->operateOnAll(LLCtrlListInterface::OP_DELETE); | ||
36 | |||
37 | for (rlv_object_map_t::const_iterator itObj = pRlvObjects->begin(), endObj = pRlvObjects->end(); itObj != endObj; ++itObj) | ||
38 | { | ||
39 | std::string strName = itObj->first.asString(); | ||
40 | |||
41 | LLViewerInventoryItem* pItem = NULL; | ||
42 | LLViewerObject* pObj = gObjectList.findObject(itObj->first); | ||
43 | if (pObj) | ||
44 | { | ||
45 | LLViewerJointAttachment* pAttachPt = | ||
46 | get_if_there(pAvatar->mAttachmentPoints, gRlvHandler.getAttachPointIndex(pObj), (LLViewerJointAttachment*)NULL); | ||
47 | if (pAttachPt) | ||
48 | { | ||
49 | pItem = gInventory.getItem(pAttachPt->getItemID()); | ||
50 | } | ||
51 | } | ||
52 | |||
53 | if (pItem) | ||
54 | strName = pItem->getName(); | ||
55 | |||
56 | const rlv_command_list_t* pCommands = itObj->second.getCommandList(); | ||
57 | for (rlv_command_list_t::const_iterator itCmd = pCommands->begin(), endCmd = pCommands->end(); itCmd != endCmd; ++itCmd) | ||
58 | { | ||
59 | std::string strBhvr = itCmd->asString(); LLUUID uuid(itCmd->getOption()); | ||
60 | if (uuid.notNull()) | ||
61 | { | ||
62 | std::string strLookup; | ||
63 | if ( (gCacheName->getFullName(uuid, strLookup)) || (gCacheName->getGroupName(uuid, strLookup)) ) | ||
64 | { | ||
65 | if (strLookup.find("???") == std::string::npos) | ||
66 | strBhvr.assign(itCmd->getBehaviour()).append(":").append(strLookup); | ||
67 | } | ||
68 | else if (m_PendingLookup.end() == std::find(m_PendingLookup.begin(), m_PendingLookup.end(), uuid)) | ||
69 | { | ||
70 | gCacheName->get(uuid, FALSE, onAvatarNameLookup, this); | ||
71 | m_PendingLookup.push_back(uuid); | ||
72 | } | ||
73 | } | ||
74 | |||
75 | LLSD element; | ||
76 | |||
77 | // Restriction column | ||
78 | element["columns"][0]["column"] = "behaviour"; | ||
79 | element["columns"][0]["value"] = strBhvr; | ||
80 | element["columns"][0]["font"] = "SANSSERIF"; | ||
81 | element["columns"][0]["font-style"] = "NORMAL"; | ||
82 | |||
83 | // Object Name column | ||
84 | element["columns"][1]["column"] = "name"; | ||
85 | element["columns"][1]["value"] = strName; | ||
86 | element["columns"][1]["font"] = "SANSSERIF"; | ||
87 | element["columns"][1]["font-style"] = "NORMAL"; | ||
88 | |||
89 | pList->addElement(element, ADD_BOTTOM); | ||
90 | } | ||
91 | } | ||
92 | } | ||
93 | |||
94 | // ============================================================================ | ||
95 | /* | ||
96 | * LLFloater overrides | ||
97 | */ | ||
98 | |||
99 | BOOL RlvFloaterBehaviour::canClose() | ||
100 | { | ||
101 | return !LLApp::isExiting(); | ||
102 | } | ||
103 | |||
104 | void RlvFloaterBehaviour::onOpen() | ||
105 | { | ||
106 | gRlvHandler.addBehaviourObserver(this); | ||
107 | |||
108 | refreshAll(); | ||
109 | } | ||
110 | |||
111 | void RlvFloaterBehaviour::onClose(bool fQuitting) | ||
112 | { | ||
113 | LLFloater::setVisible(FALSE); | ||
114 | |||
115 | gRlvHandler.removeBehaviourObserver(this); | ||
116 | |||
117 | for (std::list<LLUUID>::const_iterator itLookup = m_PendingLookup.begin(); itLookup != m_PendingLookup.end(); ++itLookup) | ||
118 | { | ||
119 | gCacheName->cancelCallback(*itLookup, onAvatarNameLookup, this); | ||
120 | } | ||
121 | m_PendingLookup.clear(); | ||
122 | } | ||
123 | |||
124 | BOOL RlvFloaterBehaviour::postBuild() | ||
125 | { | ||
126 | return TRUE; | ||
127 | } | ||
128 | |||
129 | // ============================================================================ | ||
130 | /* | ||
131 | * RlvBehaviourObserver overrides | ||
132 | */ | ||
133 | |||
134 | void RlvFloaterBehaviour::changed(const RlvCommand& /*rlvCmd*/, bool /*fInternal*/) | ||
135 | { | ||
136 | refreshAll(); | ||
137 | } | ||
138 | |||
139 | // ============================================================================ | ||
140 | |||
141 | void RlvFloaterBehaviour::onAvatarNameLookup(const LLUUID& uuid, const std::string& strFirst, const std::string& strLast, BOOL fGroup, void* pParam) | ||
142 | { | ||
143 | RlvFloaterBehaviour* pSelf = (RlvFloaterBehaviour*)pParam; | ||
144 | |||
145 | std::list<LLUUID>::iterator itLookup = std::find(pSelf->m_PendingLookup.begin(), pSelf->m_PendingLookup.end(), uuid); | ||
146 | if (itLookup != pSelf->m_PendingLookup.end()) | ||
147 | pSelf->m_PendingLookup.erase(itLookup); | ||
148 | |||
149 | pSelf->refreshAll(); | ||
150 | } | ||
151 | |||
152 | // ============================================================================ | ||
diff --git a/linden/indra/newview/rlvfloaterbehaviour.h b/linden/indra/newview/rlvfloaterbehaviour.h new file mode 100644 index 0000000..1410dd5 --- /dev/null +++ b/linden/indra/newview/rlvfloaterbehaviour.h | |||
@@ -0,0 +1,49 @@ | |||
1 | #ifndef RLV_FLOATER_BEHAVIOUR | ||
2 | #define RLV_FLOATER_BEHAVIOUR | ||
3 | |||
4 | #include "llfloater.h" | ||
5 | #include "rlvevent.h" | ||
6 | |||
7 | // ============================================================================ | ||
8 | |||
9 | class RlvFloaterBehaviour : | ||
10 | public LLFloater, | ||
11 | public LLFloaterSingleton<RlvFloaterBehaviour>, | ||
12 | public RlvBehaviourObserver | ||
13 | { | ||
14 | friend class LLUISingleton<RlvFloaterBehaviour, VisibilityPolicy<LLFloater> >; | ||
15 | public: | ||
16 | virtual ~RlvFloaterBehaviour() {} | ||
17 | |||
18 | /* | ||
19 | * LLFloater overrides | ||
20 | */ | ||
21 | public: | ||
22 | /*virtual*/ BOOL canClose(); | ||
23 | /*virtual*/ void onOpen(); | ||
24 | /*virtual*/ void onClose(bool app_quitting); | ||
25 | /*virtual*/ BOOL postBuild(); | ||
26 | |||
27 | /* | ||
28 | * RlvBehaviourObserver overrides | ||
29 | */ | ||
30 | public: | ||
31 | /*virtual*/ void changed(const RlvCommand& rlvCmd, bool fInternal); | ||
32 | |||
33 | /* | ||
34 | * Member functions | ||
35 | */ | ||
36 | public: | ||
37 | static void show(void*); | ||
38 | static void onAvatarNameLookup(const LLUUID& uuid, const std::string& strFirst, const std::string& strLast, BOOL fGroup, void* pParam); | ||
39 | protected: | ||
40 | void refreshAll(); | ||
41 | private: | ||
42 | RlvFloaterBehaviour(const LLSD& key = LLSD()); | ||
43 | |||
44 | std::list<LLUUID> m_PendingLookup; | ||
45 | }; | ||
46 | |||
47 | // ============================================================================ | ||
48 | |||
49 | #endif // RLV_FLOATER_BEHAVIOUR | ||
diff --git a/linden/indra/newview/rlvhandler.cpp b/linden/indra/newview/rlvhandler.cpp new file mode 100644 index 0000000..2915002 --- /dev/null +++ b/linden/indra/newview/rlvhandler.cpp | |||
@@ -0,0 +1,2549 @@ | |||
1 | #include "llviewerprecompiledheaders.h" | ||
2 | #include "llagent.h" | ||
3 | #include "lldrawpoolalpha.h" | ||
4 | #include "llfloaterbeacons.h" | ||
5 | #include "llfloaterchat.h" | ||
6 | #include "llfloaterdaycycle.h" | ||
7 | #include "llfloaterenvsettings.h" | ||
8 | #include "llfloatergodtools.h" | ||
9 | #include "llfloaterland.h" | ||
10 | #include "llfloatermap.h" | ||
11 | #include "llfloaterregioninfo.h" | ||
12 | #include "llfloatertools.h" | ||
13 | #include "llfloaterwater.h" | ||
14 | #include "llfloaterwindlight.h" | ||
15 | #include "llfloaterworldmap.h" | ||
16 | #include "llgesturemgr.h" | ||
17 | #include "llinventoryview.h" | ||
18 | #include "llstartup.h" | ||
19 | #include "llviewermenu.h" | ||
20 | #include "llviewermessage.h" | ||
21 | #include "llviewerparcelmgr.h" | ||
22 | #include "llviewerregion.h" | ||
23 | #include "llviewerwindow.h" | ||
24 | #include "llvoavatar.h" | ||
25 | #include "llworld.h" | ||
26 | #include "pipeline.h" | ||
27 | |||
28 | #include "rlvhelper.h" | ||
29 | #include "rlvevent.h" | ||
30 | #include "rlvextensions.h" | ||
31 | #include "rlvhandler.h" | ||
32 | |||
33 | // Only defined in llinventorybridge.cpp | ||
34 | #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 | ||
35 | #include "llinventorybridge.h" | ||
36 | void confirm_replace_attachment_rez(S32 option, void* user_data); | ||
37 | #endif | ||
38 | // Only defined in llinventorymodel.cpp | ||
39 | extern const char* NEW_CATEGORY_NAME; | ||
40 | |||
41 | // ============================================================================ | ||
42 | // Static variable initialization | ||
43 | // | ||
44 | |||
45 | BOOL RlvHandler::m_fEnabled = FALSE; | ||
46 | BOOL RlvHandler::fNoSetEnv = FALSE; | ||
47 | BOOL RlvHandler::fLegacyNaming = FALSE; | ||
48 | BOOL RlvHandler::m_fFetchStarted = FALSE; | ||
49 | BOOL RlvHandler::m_fFetchComplete = FALSE; | ||
50 | RlvMultiStringSearch RlvHandler::m_AttachLookup; | ||
51 | |||
52 | const std::string RlvHandler::cstrSharedRoot = RLV_ROOT_FOLDER; | ||
53 | |||
54 | // Keep these consistent with regular RLV | ||
55 | const std::string RlvHandler::cstrBlockedRecvIM = "*** IM blocked by your viewer"; | ||
56 | const std::string RlvHandler::cstrBlockedSendIM = "*** IM blocked by sender's viewer"; | ||
57 | const std::string RlvHandler::cstrHidden = "(Hidden)"; | ||
58 | const std::string RlvHandler::cstrHiddenParcel = "(Hidden parcel)"; | ||
59 | const std::string RlvHandler::cstrHiddenRegion = "(Hidden region)"; | ||
60 | const std::string RlvHandler::cstrMsgRecvIM = | ||
61 | "The Resident you messaged is prevented from reading your instant messages at the moment, please try again later."; | ||
62 | const std::string RlvHandler::cstrMsgTpLure = | ||
63 | "The Resident you invited is prevented from accepting teleport offers. Please try again later."; | ||
64 | |||
65 | const 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 human being", "This human being", | ||
69 | "That human 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 | |||
73 | rlv_handler_t gRlvHandler; | ||
74 | |||
75 | // ============================================================================ | ||
76 | // Helper functions | ||
77 | // | ||
78 | |||
79 | // Checked: 2009-07-12 (RLVa-1.0.0h) | Added: RLVa-0.2.0e | ||
80 | inline bool rlvIsWearingItem(const LLInventoryItem* pItem) | ||
81 | { | ||
82 | return | ||
83 | ((LLAssetType::AT_OBJECT == pItem->getType()) && (gAgent.getAvatarObject()->isWearingAttachment(pItem->getUUID()))) || | ||
84 | ((LLAssetType::AT_GESTURE == pItem->getType()) && (gGestureManager.isGestureActive(pItem->getUUID()))) || | ||
85 | (gAgent.isWearingItem(pItem->getUUID())); | ||
86 | } | ||
87 | |||
88 | // ============================================================================ | ||
89 | // Command specific helper functions | ||
90 | // | ||
91 | |||
92 | // Checked: 2009-08-04 (RLVa-1.0.1d) | Added: RLVa-1.0.1d | ||
93 | static bool rlvParseNotifyOption(const std::string& strOption, S32& nChannel, std::string& strFilter) | ||
94 | { | ||
95 | boost_tokenizer tokens(strOption, boost::char_separator<char>(";", "", boost::keep_empty_tokens)); | ||
96 | boost_tokenizer::iterator itTok = tokens.begin(); | ||
97 | |||
98 | // Extract and sanity check the first token (required) which is the channel | ||
99 | if ( (itTok == tokens.end()) || (!LLStringUtil::convertToS32(*itTok, nChannel)) || (!rlvIsValidChannel(nChannel)) ) | ||
100 | return false; | ||
101 | |||
102 | // Second token (optional) is the filter | ||
103 | strFilter.clear(); | ||
104 | if (++itTok != tokens.end()) | ||
105 | { | ||
106 | strFilter = *itTok; | ||
107 | ++itTok; | ||
108 | } | ||
109 | |||
110 | return (itTok == tokens.end()); | ||
111 | } | ||
112 | |||
113 | // ============================================================================ | ||
114 | // Constructor/destructor | ||
115 | // | ||
116 | |||
117 | // Checked: 2009-08-04 (RLVa-1.0.1d) | Modified: RLVa-1.0.1d | ||
118 | RlvHandler::RlvHandler() | ||
119 | : m_fCanCancelTp(false), m_idCurObject(LLUUID::null), m_pCurCommand(NULL), m_pGCTimer(NULL), m_pWLSnapshot(NULL), m_pBhvrNotify(NULL) | ||
120 | { | ||
121 | // Array auto-initialization to 0 is non-standard? (Compiler warning in VC-8.0) | ||
122 | memset(m_LayersAdd, 0, sizeof(S16) * WT_COUNT); | ||
123 | memset(m_LayersRem, 0, sizeof(S16) * WT_COUNT); | ||
124 | memset(m_Behaviours, 0, sizeof(S16) * RLV_BHVR_COUNT); | ||
125 | } | ||
126 | |||
127 | // Checked: 2009-08-04 (RLVa-1.0.1d) | Modified: RLVa-1.0.1d | ||
128 | RlvHandler::~RlvHandler() | ||
129 | { | ||
130 | //delete m_pGCTimer; // <- deletes itself | ||
131 | delete m_pWLSnapshot; // <- delete on NULL is harmless | ||
132 | delete m_pBhvrNotify; | ||
133 | } | ||
134 | |||
135 | // ============================================================================ | ||
136 | // Attachment related functions | ||
137 | // | ||
138 | |||
139 | // Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0d | ||
140 | inline LLViewerJointAttachment* RlvHandler::getAttachPoint(const std::string& strText, bool fExact) const | ||
141 | { | ||
142 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | ||
143 | return (pAvatar) ? get_if_there(pAvatar->mAttachmentPoints, getAttachPointIndex(strText, fExact), (LLViewerJointAttachment*)NULL) | ||
144 | : NULL; | ||
145 | } | ||
146 | |||
147 | // Checked: 2009-07-29 (RLVa-1.0.1b) | Modified: RLVa-1.0.1b | ||
148 | LLViewerJointAttachment* RlvHandler::getAttachPoint(const LLInventoryCategory* pFolder, bool /*fStrict*/) const | ||
149 | { | ||
150 | if (!pFolder) | ||
151 | return NULL; | ||
152 | |||
153 | // RLVa-1.0.1 added support for legacy matching (See http://rlva.catznip.com/blog/2009/07/attachment-point-naming-convention/) | ||
154 | if (fLegacyNaming) | ||
155 | return getAttachPointLegacy(pFolder); | ||
156 | |||
157 | // Otherwise the only valid way to specify an attachment point in a folder name is: ^\.\(\s+attachpt\s+\) | ||
158 | std::string::size_type idxMatch; | ||
159 | std::string strAttachPt = rlvGetFirstParenthesisedText(pFolder->getName(), &idxMatch); | ||
160 | LLStringUtil::trim(strAttachPt); | ||
161 | |||
162 | return ( (1 == idxMatch) && (RLV_FOLDER_PREFIX_HIDDEN == pFolder->getName().at(0)) ) ? getAttachPoint(strAttachPt, true) : NULL; | ||
163 | } | ||
164 | |||
165 | // Checked: 2009-07-29 (RLVa-1.0.1b) | Modified: RLVa-1.0.1b | ||
166 | LLViewerJointAttachment* RlvHandler::getAttachPoint(const LLInventoryItem* pItem, bool fStrict) const | ||
167 | { | ||
168 | // Sanity check - if it's not an object then it can't have an attachment point | ||
169 | if ( (!pItem) || (LLAssetType::AT_OBJECT != pItem->getType()) ) | ||
170 | return NULL; | ||
171 | |||
172 | // The attachment point should be placed at the end of the item's name, surrounded by parenthesis | ||
173 | // (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) | ||
174 | std::string strAttachPt = rlvGetLastParenthesisedText(pItem->getName()); | ||
175 | LLStringUtil::trim(strAttachPt); | ||
176 | |||
177 | // If the item is modify : we look at the item's name first and only then at the containing folder | ||
178 | // If the item is no modify: we look at the containing folder's name first and only then at the item itself | ||
179 | LLViewerJointAttachment* pAttachPt; | ||
180 | if (pItem->getPermissions().allowModifyBy(gAgent.getID())) | ||
181 | { | ||
182 | pAttachPt = (!strAttachPt.empty()) ? getAttachPoint(strAttachPt, true) : NULL; | ||
183 | if (!pAttachPt) | ||
184 | pAttachPt = getAttachPoint(gInventory.getCategory(pItem->getParentUUID()), fStrict); | ||
185 | } | ||
186 | else | ||
187 | { | ||
188 | pAttachPt = getAttachPoint(gInventory.getCategory(pItem->getParentUUID()), fStrict); | ||
189 | if ( (!pAttachPt) && (!strAttachPt.empty()) ) | ||
190 | pAttachPt = getAttachPoint(strAttachPt, true); | ||
191 | } | ||
192 | return pAttachPt; | ||
193 | } | ||
194 | |||
195 | // Checked: 2009-07-12 (RLVa-1.0.0h) | Added: RLVa-0.2.2a | ||
196 | S32 RlvHandler::getAttachPointIndex(const LLViewerJointAttachment* pAttachPt) const | ||
197 | { | ||
198 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | ||
199 | if (pAvatar) | ||
200 | { | ||
201 | for (LLVOAvatar::attachment_map_t::const_iterator itAttach = pAvatar->mAttachmentPoints.begin(); | ||
202 | itAttach != pAvatar->mAttachmentPoints.end(); ++itAttach) | ||
203 | { | ||
204 | if (itAttach->second == pAttachPt) | ||
205 | return itAttach->first; | ||
206 | } | ||
207 | } | ||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | // Checked: 2009-07-29 (RLVa-1.0.1b) | Added: RLVa-1.0.1b | ||
212 | LLViewerJointAttachment* RlvHandler::getAttachPointLegacy(const LLInventoryCategory* pFolder) const | ||
213 | { | ||
214 | // Hopefully some day this can just be deprecated (see http://rlva.catznip.com/blog/2009/07/attachment-point-naming-convention/) | ||
215 | if ( (!pFolder) || (pFolder->getName().empty()) ) | ||
216 | return NULL; | ||
217 | |||
218 | // Check for a (...) block *somewhere* in the name | ||
219 | std::string::size_type idxMatch; | ||
220 | std::string strAttachPt = rlvGetFirstParenthesisedText(pFolder->getName(), &idxMatch); | ||
221 | if (!strAttachPt.empty()) | ||
222 | { | ||
223 | // Could be "(attachpt)", ".(attachpt)" or "Folder name (attachpt)" | ||
224 | if ( (0 != idxMatch) && ((1 != idxMatch) || (RLV_FOLDER_PREFIX_HIDDEN == pFolder->getName().at(0)) ) && // No '(' or '.(' start | ||
225 | (idxMatch + strAttachPt.length() + 1 != pFolder->getName().length()) ) // or there's extra text | ||
226 | { | ||
227 | // It's definitely not one of the first two so assume it's the last form (in which case we need the last paranthesised block) | ||
228 | strAttachPt = rlvGetLastParenthesisedText(pFolder->getName()); | ||
229 | } | ||
230 | } | ||
231 | else | ||
232 | { | ||
233 | // There's no paranthesised block, but it could still be "attachpt" or ".attachpt" (just strip away the '.' from the last one) | ||
234 | strAttachPt = pFolder->getName(); | ||
235 | if (RLV_FOLDER_PREFIX_HIDDEN == strAttachPt[0]) | ||
236 | strAttachPt.erase(0, 1); | ||
237 | } | ||
238 | return getAttachPoint(strAttachPt, true); | ||
239 | } | ||
240 | |||
241 | bool RlvHandler::hasLockedHUD() const | ||
242 | { | ||
243 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | ||
244 | if (!pAvatar) | ||
245 | return false; | ||
246 | |||
247 | LLViewerJointAttachment* pAttachPt; | ||
248 | for (rlv_detach_map_t::const_iterator itAttachPt = m_Attachments.begin(); itAttachPt != m_Attachments.end(); ++itAttachPt) | ||
249 | { | ||
250 | pAttachPt = get_if_there(pAvatar->mAttachmentPoints, (S32)itAttachPt->first, (LLViewerJointAttachment*)NULL); | ||
251 | if ( (pAttachPt) && (pAttachPt->getIsHUDAttachment()) ) | ||
252 | return true; // At least one of our locked attachments is a HUD | ||
253 | } | ||
254 | return false; // None of our locked attachments is a HUD | ||
255 | } | ||
256 | |||
257 | bool RlvHandler::isDetachable(const LLInventoryItem* pItem) const | ||
258 | { | ||
259 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | ||
260 | return ( (pItem) && (pAvatar) ) ? isDetachable(pAvatar->getWornAttachment(pItem->getUUID())) : true; | ||
261 | } | ||
262 | |||
263 | // Checked: 2009-08-11 (RLVa-1.0.1h) | Added: RLVa-1.0.1h | ||
264 | bool RlvHandler::isDetachableExcept(S32 idxAttachPt, LLViewerObject *pObj) const | ||
265 | { | ||
266 | // Loop over every object that marked the specific attachment point undetachable (but ignore pObj and any of its children) | ||
267 | for (rlv_detach_map_t::const_iterator itAttach = m_Attachments.lower_bound(idxAttachPt), | ||
268 | endAttach = m_Attachments.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach) | ||
269 | { | ||
270 | LLViewerObject* pTempObj = gObjectList.findObject(itAttach->second); | ||
271 | if ( (!pTempObj) || (pTempObj->getRootEdit()->getID() != pObj->getID()) ) | ||
272 | return false; | ||
273 | } | ||
274 | return true; | ||
275 | } | ||
276 | |||
277 | // Checked: 2009-05-31 (RLVa-0.2.0e) | Modified: RLVa-0.2.0e | ||
278 | bool RlvHandler::setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDetachable) | ||
279 | { | ||
280 | // Sanity check - make sure it's an object we know about | ||
281 | rlv_object_map_t::const_iterator itObj = m_Objects.find(idRlvObj); | ||
282 | if ( (itObj == m_Objects.end()) || (!idxAttachPt) ) | ||
283 | return false; // If (idxAttachPt) == 0 then: (pObj == NULL) || (pObj->isAttachment() == FALSE) | ||
284 | |||
285 | if (!fDetachable) | ||
286 | { | ||
287 | // Sanity check - make sure it's not already marked undetachable by this object (NOTE: m_Attachments is a *multimap*, not a map) | ||
288 | for (rlv_detach_map_t::const_iterator itAttach = m_Attachments.lower_bound(idxAttachPt), | ||
289 | endAttach = m_Attachments.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach) | ||
290 | { | ||
291 | if (itObj->second.m_UUID == itAttach->second) | ||
292 | return false; | ||
293 | } | ||
294 | |||
295 | m_Attachments.insert(std::pair<S32, LLUUID>(idxAttachPt, itObj->second.m_UUID)); | ||
296 | return true; | ||
297 | } | ||
298 | else | ||
299 | { | ||
300 | // NOTE: m_Attachments is a *multimap*, not a map | ||
301 | for (rlv_detach_map_t::iterator itAttach = m_Attachments.lower_bound(idxAttachPt), | ||
302 | endAttach = m_Attachments.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach) | ||
303 | { | ||
304 | if (itObj->second.m_UUID == itAttach->second) | ||
305 | { | ||
306 | m_Attachments.erase(itAttach); | ||
307 | return true; | ||
308 | } | ||
309 | } | ||
310 | } | ||
311 | return false; // Fall-through for (fDetachable == TRUE) - if the object wasn't undetachable then we consider it a failure | ||
312 | } | ||
313 | |||
314 | |||
315 | |||
316 | #ifdef RLV_EXTENSION_FLAG_NOSTRIP | ||
317 | // Checked: 2009-05-26 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d | ||
318 | bool RlvHandler::isStrippable(const LLUUID& idItem) const | ||
319 | { | ||
320 | // An item is exempt from @detach or @remoutfit if: | ||
321 | // - its name contains "nostrip" (anywhere in the name) | ||
322 | // - its parent folder contains "nostrip" (anywhere in the name) | ||
323 | if (idItem.notNull()) | ||
324 | { | ||
325 | LLViewerInventoryItem* pItem = gInventory.getItem(idItem); | ||
326 | if (pItem) | ||
327 | { | ||
328 | if (-1 != pItem->getName().find(RLV_FOLDER_FLAG_NOSTRIP)) | ||
329 | return false; | ||
330 | |||
331 | LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID()); | ||
332 | if ( (pFolder) && (-1 != pFolder->getName().find(RLV_FOLDER_FLAG_NOSTRIP)) ) | ||
333 | return false; | ||
334 | } | ||
335 | } | ||
336 | return true; | ||
337 | } | ||
338 | #endif // RLV_EXTENSION_FLAG_NOSTRIP | ||
339 | |||
340 | // ============================================================================ | ||
341 | // Behaviour related functions | ||
342 | // | ||
343 | |||
344 | bool RlvHandler::hasBehaviourExcept(const std::string& strBehaviour, const LLUUID& idObj) const | ||
345 | { | ||
346 | for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj) | ||
347 | if ( (idObj != itObj->second.m_UUID) && (itObj->second.hasBehaviour(strBehaviour)) ) | ||
348 | return true; | ||
349 | return false; | ||
350 | } | ||
351 | |||
352 | bool RlvHandler::hasBehaviourExcept(ERlvBehaviour eBehaviour, const std::string& strOption, const LLUUID& idObj) const | ||
353 | { | ||
354 | for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj) | ||
355 | if ( (idObj != itObj->second.m_UUID) && (itObj->second.hasBehaviour(eBehaviour, strOption)) ) | ||
356 | return true; | ||
357 | return false; | ||
358 | } | ||
359 | |||
360 | bool RlvHandler::hasBehaviourExcept(const std::string& strBehaviour, const std::string& strOption, const LLUUID& idObj) const | ||
361 | { | ||
362 | for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj) | ||
363 | if ( (idObj != itObj->second.m_UUID) && (itObj->second.hasBehaviour(strBehaviour, strOption)) ) | ||
364 | return true; | ||
365 | return false; | ||
366 | } | ||
367 | |||
368 | // ============================================================================ | ||
369 | // Command processing functions | ||
370 | // | ||
371 | |||
372 | // Checked: 2009-06-03 (RLVa-0.2.0h) | ||
373 | void RlvHandler::addBehaviourObserver(RlvBehaviourObserver* pBhvrObserver) | ||
374 | { | ||
375 | std::list<RlvBehaviourObserver*>::iterator itBhvrObserver = std::find(m_BhvrObservers.begin(), m_BhvrObservers.end(), pBhvrObserver); | ||
376 | if (itBhvrObserver == m_BhvrObservers.end()) | ||
377 | m_BhvrObservers.push_back(pBhvrObserver); | ||
378 | } | ||
379 | |||
380 | // Checked: 2009-06-03 (RLVa-0.2.0h) | ||
381 | void RlvHandler::removeBehaviourObserver(RlvBehaviourObserver* pBhvrObserver) | ||
382 | { | ||
383 | std::list<RlvBehaviourObserver*>::iterator itBhvrObserver = std::find(m_BhvrObservers.begin(), m_BhvrObservers.end(), pBhvrObserver); | ||
384 | if (itBhvrObserver != m_BhvrObservers.end()) | ||
385 | m_BhvrObservers.erase(itBhvrObserver); | ||
386 | } | ||
387 | |||
388 | // Checked: 2009-06-03 (RLVa-0.2.0h) | ||
389 | void RlvHandler::notifyBehaviourObservers(const RlvCommand& rlvCmd, bool fInternal) | ||
390 | { | ||
391 | for (std::list<RlvBehaviourObserver*>::const_iterator itBhvrObserver = m_BhvrObservers.begin(); | ||
392 | itBhvrObserver != m_BhvrObservers.end(); ++itBhvrObserver) | ||
393 | { | ||
394 | (*itBhvrObserver)->changed(rlvCmd, fInternal); | ||
395 | } | ||
396 | } | ||
397 | |||
398 | // Checked: | ||
399 | BOOL RlvHandler::processCommand(const LLUUID& uuid, const std::string& strCmd, bool fFromObj) | ||
400 | { | ||
401 | #ifdef RLV_DEBUG | ||
402 | RLV_INFOS << "[" << uuid << "]: " << strCmd << LL_ENDL; | ||
403 | #endif // RLV_DEBUG | ||
404 | |||
405 | RlvCommand rlvCmd(strCmd); | ||
406 | if (!rlvCmd.isValid()) | ||
407 | { | ||
408 | #ifdef RLV_DEBUG | ||
409 | RLV_INFOS << "\t-> invalid command: " << strCmd << LL_ENDL; | ||
410 | #endif // RLV_DEBUG | ||
411 | return FALSE; | ||
412 | } | ||
413 | m_pCurCommand = &rlvCmd; m_idCurObject = uuid; | ||
414 | |||
415 | BOOL fRet = FALSE; | ||
416 | switch (rlvCmd.getParamType()) | ||
417 | { | ||
418 | case RLV_TYPE_ADD: // Checked: 2009-06-03 (RLVa-0.2.0h) | Modified: RLVa-0.2.0h | ||
419 | { | ||
420 | if ( (m_Behaviours[rlvCmd.getBehaviourType()]) && | ||
421 | ( (RLV_BHVR_SETDEBUG == rlvCmd.getBehaviourType()) || (RLV_BHVR_SETENV == rlvCmd.getBehaviourType()) ) ) | ||
422 | { | ||
423 | // Some restrictions can only be held by one single object to avoid deadlocks | ||
424 | #ifdef RLV_DEBUG | ||
425 | RLV_INFOS << "\t- " << rlvCmd.getBehaviour() << " is already set by another object => discarding" << LL_ENDL; | ||
426 | #endif // RLV_DEBUG | ||
427 | break; | ||
428 | } | ||
429 | |||
430 | rlv_object_map_t::iterator itObj = m_Objects.find(uuid); | ||
431 | if (itObj != m_Objects.end()) | ||
432 | { | ||
433 | RlvObject& rlvObj = itObj->second; | ||
434 | fRet = rlvObj.addCommand(rlvCmd); | ||
435 | } | ||
436 | else | ||
437 | { | ||
438 | RlvObject rlvObj(uuid); | ||
439 | fRet = rlvObj.addCommand(rlvCmd); | ||
440 | m_Objects.insert(std::pair<LLUUID, RlvObject>(uuid, rlvObj)); | ||
441 | } | ||
442 | |||
443 | #ifdef RLV_DEBUG | ||
444 | RLV_INFOS << "\t- " << ( (fRet) ? "adding behaviour" : "skipping duplicate") << LL_ENDL; | ||
445 | #endif // RLV_DEBUG | ||
446 | |||
447 | if (fRet) { // If FALSE then this was a duplicate, there's no need to handle those | ||
448 | if (!m_pGCTimer) | ||
449 | m_pGCTimer = new RlvGCTimer(); | ||
450 | processAddCommand(uuid, rlvCmd); | ||
451 | notifyBehaviourObservers(rlvCmd, !fFromObj); | ||
452 | } | ||
453 | } | ||
454 | break; | ||
455 | case RLV_TYPE_REMOVE: // Checked: | ||
456 | { | ||
457 | rlv_object_map_t::iterator itObj = m_Objects.find(uuid); | ||
458 | if (itObj != m_Objects.end()) | ||
459 | fRet = itObj->second.removeCommand(rlvCmd); | ||
460 | |||
461 | #ifdef RLV_DEBUG | ||
462 | RLV_INFOS << "\t- " << ( (fRet) ? "removing behaviour" | ||
463 | : "skipping remove (unset behaviour or unknown object)") << LL_ENDL; | ||
464 | #endif // RLV_DEBUG | ||
465 | |||
466 | if (fRet) { // Don't handle non-sensical removes | ||
467 | processRemoveCommand(uuid, rlvCmd); | ||
468 | notifyBehaviourObservers(rlvCmd, !fFromObj); | ||
469 | |||
470 | if (0 == itObj->second.m_Commands.size()) | ||
471 | { | ||
472 | #ifdef RLV_DEBUG | ||
473 | RLV_INFOS << "\t- command list empty => removing " << uuid << LL_ENDL; | ||
474 | #endif // RLV_DEBUG | ||
475 | m_Objects.erase(itObj); | ||
476 | } | ||
477 | } | ||
478 | } | ||
479 | break; | ||
480 | case RLV_TYPE_FORCE: // Checked: | ||
481 | fRet = processForceCommand(uuid, rlvCmd); | ||
482 | break; | ||
483 | case RLV_TYPE_REPLY: // Checked: | ||
484 | fRet = processReplyCommand(uuid, rlvCmd); | ||
485 | break; | ||
486 | case RLV_TYPE_UNKNOWN: // Checked: | ||
487 | { | ||
488 | if ("clear" == rlvCmd.getBehaviour()) | ||
489 | { | ||
490 | const std::string& strFilter = rlvCmd.getParam(); std::string strCmdRem; | ||
491 | |||
492 | rlv_object_map_t::const_iterator itObj = m_Objects.find(uuid); | ||
493 | if (itObj != m_Objects.end()) // No sense in @clear'ing if we don't have any commands for this object | ||
494 | { | ||
495 | const RlvObject& rlvObj = itObj->second; bool fContinue = true; | ||
496 | for (rlv_command_list_t::const_iterator itCmd = rlvObj.m_Commands.begin(), itCurCmd; | ||
497 | ((fContinue) && (itCmd != rlvObj.m_Commands.end())); ) | ||
498 | { | ||
499 | itCurCmd = itCmd++; // Point itCmd ahead so it won't get invalidated if/when we erase a command | ||
500 | |||
501 | const RlvCommand& rlvCmdRem = *itCurCmd; | ||
502 | if ( (strFilter.empty()) || (-1 != rlvCmdRem.asString().find(strFilter)) ) | ||
503 | { | ||
504 | fContinue = (rlvObj.m_Commands.size() > 1); // rlvObj will become invalid once we remove the last command | ||
505 | strCmdRem = rlvCmdRem.getBehaviour() + ":" + rlvCmdRem.getOption() + "=y"; | ||
506 | processCommand(uuid, strCmdRem, false); | ||
507 | } | ||
508 | } | ||
509 | fRet = TRUE; | ||
510 | } | ||
511 | } | ||
512 | } | ||
513 | break; | ||
514 | #ifdef LL_GNUC | ||
515 | default: | ||
516 | break; | ||
517 | #endif // LL_GNUC | ||
518 | } | ||
519 | |||
520 | #ifdef RLV_DEBUG | ||
521 | RLV_INFOS << "\t--> command " << ((fRet) ? "succeeded" : "failed") << LL_ENDL; | ||
522 | #endif // RLV_DEBUG | ||
523 | |||
524 | m_pCurCommand = NULL; m_idCurObject.setNull(); | ||
525 | return fRet; | ||
526 | } | ||
527 | |||
528 | BOOL RlvHandler::processAddCommand(const LLUUID& uuid, const RlvCommand& rlvCmd) | ||
529 | { | ||
530 | // NOTE: - at this point the command has already been added to the corresponding RlvObject instance | ||
531 | // - the object's UUID may or may not exist in gObjectList (see handling of @detach=n) | ||
532 | |||
533 | ERlvBehaviour eBehaviour = rlvCmd.getBehaviourType(); | ||
534 | const std::string& strOption = rlvCmd.getOption(); | ||
535 | |||
536 | if ( (RLV_BHVR_UNKNOWN != eBehaviour) && (strOption.empty()) ) | ||
537 | m_Behaviours[eBehaviour]++; | ||
538 | |||
539 | switch (eBehaviour) | ||
540 | { | ||
541 | case RLV_BHVR_DETACH: // @detach[:<option>]=n - Checked: 2009-08-04 (RLVa-1.0.1d) | Modified: RLVa-1.0.1d | ||
542 | { | ||
543 | LLViewerObject* pObj = NULL; S32 idxAttachPt = 0; | ||
544 | if (strOption.empty()) // @detach=n | ||
545 | { | ||
546 | // If the object rezzed before we received @detach=n from it then we can just do our thing here | ||
547 | // If the object hasn't rezzed yet then we need to wait until RlvHandler::onAttach() | ||
548 | // If @detach=n were possible for non-attachments another copy/paste would be needed in RlvHandler::onGC() | ||
549 | if ((pObj = gObjectList.findObject(uuid)) != NULL) | ||
550 | setDetachable(pObj, uuid, false); | ||
551 | } | ||
552 | else if ((idxAttachPt = getAttachPointIndex(strOption, true)) != 0) // @detach:<attachpt>=n | ||
553 | { | ||
554 | setDetachable(idxAttachPt, uuid, false); | ||
555 | |||
556 | // (See below) | ||
557 | LLViewerJointAttachment* pAttachPt = getAttachPoint(strOption, true); | ||
558 | if (pAttachPt) | ||
559 | pObj = pAttachPt->getObject(); | ||
560 | } | ||
561 | |||
562 | // When at least one HUD attachment is locked we want to make sure they're all visible (ie prevent hiding a blindfold HUD) | ||
563 | // However, since @detach:<attachpt>=n might lock a HUD attachment point that doesn't currently have an object we | ||
564 | // have to do this here *and* in RlvHandler::onAttach() | ||
565 | if ( (pObj) && (pObj->isHUDAttachment()) ) | ||
566 | LLPipeline::sShowHUDAttachments = TRUE; | ||
567 | } | ||
568 | break; | ||
569 | case RLV_BHVR_REDIRCHAT: // @redirchat:<option>=n - Checked: 2009-07-07 (RLVa-1.0.0d) | ||
570 | case RLV_BHVR_REDIREMOTE: // @rediremote:<option>=n - Checked: 2009-07-07 (RLVa-1.0.0d) | Added: RLVa-0.2.2a | ||
571 | { | ||
572 | if (!strOption.empty()) | ||
573 | m_Behaviours[eBehaviour]++; // @redirchat and @rediremote don't have an optionless version so keep track of it here | ||
574 | else | ||
575 | m_Behaviours[eBehaviour]--; // @redirchat=n and @rediremote=n are undefined, don't keep track of them | ||
576 | } | ||
577 | break; | ||
578 | case RLV_BHVR_SHOWWORLDMAP: // @showworldmap=n - Checked: 2009-07-05 (RLVa-1.0.0c) | ||
579 | { | ||
580 | // Simulate clicking the Map button [see LLToolBar::onClickMap()] | ||
581 | if (gFloaterWorldMap->getVisible()) | ||
582 | LLFloaterWorldMap::toggle(NULL); | ||
583 | } | ||
584 | break; | ||
585 | case RLV_BHVR_SHOWMINIMAP: // @showminimap=n - Checked: 2009-07-05 (RLVa-1.0.0c) | ||
586 | { | ||
587 | // Simulate clicking the Minimap button [see LLToolBar::onClickRadar()] | ||
588 | if (LLFloaterMap::instanceVisible()) | ||
589 | LLFloaterMap::hideInstance(); | ||
590 | } | ||
591 | break; | ||
592 | #ifdef RLV_EXTENSION_STARTLOCATION | ||
593 | case RLV_BHVR_TPLOC: // @tploc=n - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.1d | ||
594 | case RLV_BHVR_UNSIT: // @unsit=n - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.1d | ||
595 | { | ||
596 | if (strOption.empty()) | ||
597 | RlvSettings::updateLoginLastLocation(); | ||
598 | } | ||
599 | break; | ||
600 | #endif // RLV_EXTENSION_STARTLOCATION | ||
601 | case RLV_BHVR_EDIT: // @edit=n - Checked: 2009-07-04 (RLVa-1.0.0b) | ||
602 | { | ||
603 | // Turn off "View / Highlight Transparent" | ||
604 | LLDrawPoolAlpha::sShowDebugAlpha = FALSE; | ||
605 | |||
606 | // Close the Beacons floater if it's open | ||
607 | if (LLFloaterBeacons::instanceVisible()) | ||
608 | LLFloaterBeacons::toggleInstance(); | ||
609 | |||
610 | // Get rid of the build floater if it's open [copy/paste from toggle_build_mode()] | ||
611 | if (gFloaterTools->getVisible()) | ||
612 | { | ||
613 | gAgent.resetView(FALSE); | ||
614 | gFloaterTools->close(); | ||
615 | gViewerWindow->showCursor(); | ||
616 | } | ||
617 | } | ||
618 | break; | ||
619 | case RLV_BHVR_ADDOUTFIT: // @addoutfit[:<layer>]=n - Checked: 2009-07-07 (RLVa-1.0.0d) | ||
620 | case RLV_BHVR_REMOUTFIT: // @remoutfit[:<layer>]=n - Checked: 2009-07-07 (RLVa-1.0.0d) | ||
621 | { | ||
622 | S16* pLayers = (eBehaviour == RLV_BHVR_ADDOUTFIT) ? m_LayersAdd : m_LayersRem; | ||
623 | |||
624 | if (strOption.empty()) | ||
625 | { | ||
626 | for (int idx = 0; idx < WT_COUNT; idx++) | ||
627 | pLayers[idx]++; | ||
628 | } | ||
629 | else | ||
630 | { | ||
631 | EWearableType type = LLWearable::typeNameToType(strOption); | ||
632 | if (WT_INVALID != type) | ||
633 | { | ||
634 | pLayers[type]++; | ||
635 | m_Behaviours[eBehaviour]++; | ||
636 | } | ||
637 | } | ||
638 | } | ||
639 | break; | ||
640 | case RLV_BHVR_SHOWINV: // @showinv=n - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-1.0.0g | ||
641 | { | ||
642 | // Close all open inventory windows | ||
643 | LLInventoryView::closeAll(); | ||
644 | } | ||
645 | break; | ||
646 | case RLV_BHVR_SHOWLOC: // @showloc=n - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f | ||
647 | { | ||
648 | // If we're the first @showloc=n restriction refresh all object text so we can filter it if necessary | ||
649 | if (1 == m_Behaviours[RLV_BHVR_SHOWLOC]) | ||
650 | LLHUDText::refreshAllObjectText(); | ||
651 | |||
652 | // Close the "About Land" floater if it's currently visible | ||
653 | if (LLFloaterLand::instanceVisible()) | ||
654 | LLFloaterLand::hideInstance(); | ||
655 | |||
656 | // Close the "Estate Tools" floater is it's currently visible | ||
657 | if (LLFloaterRegionInfo::instanceVisible()) | ||
658 | LLFloaterRegionInfo::hideInstance(); | ||
659 | |||
660 | // NOTE: we should close the "God Tools" floater as well, but since calling LLFloaterGodTools::instance() always | ||
661 | // creates a new instance of the floater and since it's very unlikely to be open it's just better not to | ||
662 | } | ||
663 | break; | ||
664 | case RLV_BHVR_SHOWNAMES: // @shownames=n - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f | ||
665 | { | ||
666 | // If we're the first @shownames=n restriction refresh all object text so we can filter it if necessary | ||
667 | if (1 == m_Behaviours[RLV_BHVR_SHOWNAMES]) | ||
668 | LLHUDText::refreshAllObjectText(); | ||
669 | |||
670 | // Close the "Active Speakers" panel if it's currently visible | ||
671 | LLFloaterChat::getInstance()->childSetVisible("active_speakers_panel", false); | ||
672 | } | ||
673 | break; | ||
674 | case RLV_BHVR_FLY: // @fly=n - Checked: 2009-07-05 (RLVa-1.0.0c) | ||
675 | { | ||
676 | // If currently flying, simulate clicking the Fly button [see LLToolBar::onClickFly()] | ||
677 | if (gAgent.getFlying()) | ||
678 | gAgent.toggleFlying(); | ||
679 | } | ||
680 | break; | ||
681 | case RLV_BHVR_SETENV: // @setenv=n - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0a | ||
682 | { | ||
683 | if (!fNoSetEnv) | ||
684 | { | ||
685 | // Only close the floaters if their instance exists and they're actually visible | ||
686 | if ( (LLFloaterEnvSettings::isOpen()) && (LLFloaterEnvSettings::instance()->getVisible()) ) | ||
687 | LLFloaterEnvSettings::instance()->close(); | ||
688 | if ( (LLFloaterWindLight::isOpen()) && (LLFloaterWindLight::instance()->getVisible()) ) | ||
689 | LLFloaterWindLight::instance()->close(); | ||
690 | if ( (LLFloaterWater::isOpen()) && (LLFloaterWater::instance()->getVisible()) ) | ||
691 | LLFloaterWater::instance()->close(); | ||
692 | if ( (LLFloaterDayCycle::isOpen()) && (LLFloaterDayCycle::instance()->getVisible()) ) | ||
693 | LLFloaterDayCycle::instance()->close(); | ||
694 | |||
695 | // Save the current WindLight params so we can restore them on @setenv=y | ||
696 | if (m_pWLSnapshot) | ||
697 | { | ||
698 | RLV_ERRS << "m_pWLSnapshot != NULL" << LL_ENDL; // Safety net in case we set @setenv=n for more than 1 object | ||
699 | delete m_pWLSnapshot; | ||
700 | } | ||
701 | m_pWLSnapshot = RlvWLSnapshot::takeSnapshot(); | ||
702 | } | ||
703 | } | ||
704 | break; | ||
705 | case RLV_BHVR_SHOWHOVERTEXTALL: // @showhovertextal=n - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f | ||
706 | case RLV_BHVR_SHOWHOVERTEXTWORLD: // @showhovertextworld=n - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f | ||
707 | case RLV_BHVR_SHOWHOVERTEXTHUD: // @showhovertexthud=n - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f | ||
708 | { | ||
709 | // Refresh all hover text (LLHUDText::setStringUTF8() will decide what needs clearing and what doesn't) | ||
710 | LLHUDText::refreshAllObjectText(); | ||
711 | } | ||
712 | break; | ||
713 | case RLV_BHVR_SHOWHOVERTEXT: // @showhovertext:<uuid>=n - Checked: 2009-07-09 (RLVa-0.2.2a) | Modified: RLVa-1.0.0f | ||
714 | { | ||
715 | LLUUID idException(strOption); | ||
716 | if (!idException.isNull()) // If there's an option it should be a valid UUID | ||
717 | { | ||
718 | addException(eBehaviour, LLUUID(strOption)); | ||
719 | |||
720 | // Clear the object's hover text | ||
721 | LLViewerObject* pObj = gObjectList.findObject(idException); | ||
722 | if ( (pObj) && (pObj->mText.notNull()) && (!pObj->mText->getObjectText().empty()) ) | ||
723 | pObj->mText->setStringUTF8(""); | ||
724 | } | ||
725 | } | ||
726 | break; | ||
727 | case RLV_BHVR_NOTIFY: // @notify:<option>=add - Checked: 2009-08-04 (RLVa-1.0.1d) | Modified: RLVa-1.0.1d | ||
728 | { | ||
729 | S32 nChannel; std::string strFilter; | ||
730 | if ( (!strOption.empty()) && (rlvParseNotifyOption(strOption, nChannel, strFilter)) ) | ||
731 | { | ||
732 | if (!m_pBhvrNotify) | ||
733 | addBehaviourObserver(m_pBhvrNotify = new RlvBehaviourNotifyObserver()); | ||
734 | m_pBhvrNotify->addNotify(uuid, nChannel, strFilter); | ||
735 | } | ||
736 | } | ||
737 | break; | ||
738 | case RLV_BHVR_RECVCHAT: // @recvchat:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f | ||
739 | case RLV_BHVR_RECVEMOTE: // @recvemote:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f | ||
740 | case RLV_BHVR_RECVIM: // @recvim:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f | ||
741 | case RLV_BHVR_SENDIM: // @sendim:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f | ||
742 | case RLV_BHVR_TPLURE: // @tplure:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f | ||
743 | case RLV_BHVR_ACCEPTTP: // @accepttp:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f | ||
744 | { | ||
745 | addException(eBehaviour, LLUUID(strOption)); | ||
746 | } | ||
747 | break; | ||
748 | default: | ||
749 | { | ||
750 | // Give our observers a chance to handle any command we don't | ||
751 | RlvEvent rlvEvent(uuid, rlvCmd); | ||
752 | m_Emitter.update(&RlvObserver::onAddCommand, rlvEvent); | ||
753 | } | ||
754 | break; | ||
755 | } | ||
756 | return TRUE; // Add command success/failure is decided by RlvObject::addCommand() | ||
757 | } | ||
758 | |||
759 | // Checked: 2009-08-05 (RLVa-1.0.1e) | Added: RLVa-1.0.1e | ||
760 | void RlvHandler::processRetainedCommands() | ||
761 | { | ||
762 | for (rlv_retained_list_t::const_iterator itCmd = m_Retained.begin(); itCmd != m_Retained.end(); ++itCmd) | ||
763 | { | ||
764 | const RlvRetainedCommand& cmd = *itCmd; | ||
765 | processCommand(cmd.idObject, cmd.strCmd, true); | ||
766 | } | ||
767 | m_Retained.clear(); | ||
768 | } | ||
769 | |||
770 | BOOL RlvHandler::processRemoveCommand(const LLUUID& uuid, const RlvCommand& rlvCmd) | ||
771 | { | ||
772 | // NOTE: - the RlvObject instance still exists at this point, but the viewer might already have removed it from its object list | ||
773 | ERlvBehaviour eBehaviour = rlvCmd.getBehaviourType(); | ||
774 | const std::string& strOption = rlvCmd.getOption(); | ||
775 | |||
776 | if ( (RLV_BHVR_UNKNOWN != eBehaviour) && (strOption.empty()) ) | ||
777 | m_Behaviours[eBehaviour]--; | ||
778 | |||
779 | switch (eBehaviour) | ||
780 | { | ||
781 | case RLV_BHVR_DETACH: // @detach[:<option>]=y - Checked: 2009-08-04 (RLVa-1.0.1d) | Modified: RLVa-1.0.1d | ||
782 | { | ||
783 | S32 idxAttachPt; | ||
784 | if (strOption.empty()) // @detach=y | ||
785 | { | ||
786 | // The object may or may not (if it got detached) still exist so clean up the hard way | ||
787 | if (m_Objects.find(uuid) != m_Objects.end()) | ||
788 | { | ||
789 | for (rlv_detach_map_t::const_iterator itAttach = m_Attachments.begin(), endAttach = m_Attachments.end(); | ||
790 | itAttach != endAttach; ++itAttach) | ||
791 | { | ||
792 | if (itAttach->second == uuid) | ||
793 | { | ||
794 | setDetachable(itAttach->first, uuid, true); // <- invalidates our iterators on return | ||
795 | break; | ||
796 | } | ||
797 | } | ||
798 | } | ||
799 | } | ||
800 | else if ((idxAttachPt = getAttachPointIndex(strOption, true))) // @detach:<attachpt>=y | ||
801 | { | ||
802 | setDetachable(idxAttachPt, uuid, true); | ||
803 | } | ||
804 | } | ||
805 | break; | ||
806 | case RLV_BHVR_REDIRCHAT: // @redirchat:<option>=y - Checked: 2009-07-07 (RLVa-1.0.0d) | ||
807 | case RLV_BHVR_REDIREMOTE: // @rediremote:<option>=y - Checked: 2009-07-07 (RLVa-1.0.0d) | Added: RLVa-0.2.2a | ||
808 | { | ||
809 | if (!strOption.empty()) | ||
810 | m_Behaviours[eBehaviour]--; // @redirchat and @rediremote don't have an optionless version so keep track of it here | ||
811 | else | ||
812 | m_Behaviours[eBehaviour]++; // @redirchat=n and @rediremote=n are undefined, don't keep track of them | ||
813 | } | ||
814 | break; | ||
815 | #ifdef RLV_EXTENSION_STARTLOCATION | ||
816 | case RLV_BHVR_TPLOC: // @tploc=y - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.1d | ||
817 | case RLV_BHVR_UNSIT: // @unsit=y - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.1d | ||
818 | { | ||
819 | if (strOption.empty()) | ||
820 | RlvSettings::updateLoginLastLocation(); | ||
821 | } | ||
822 | break; | ||
823 | #endif // RLV_EXTENSION_STARTLOCATION | ||
824 | case RLV_BHVR_ADDOUTFIT: // @addoutfit[:<layer>]=y - Checked: 2009-07-07 (RLVa-1.0.0d) | ||
825 | case RLV_BHVR_REMOUTFIT: // @remoutfit[:<layer>]=y - Checked: 2009-07-07 (RLVa-1.0.0d) | ||
826 | { | ||
827 | S16* pLayers = (eBehaviour == RLV_BHVR_ADDOUTFIT) ? m_LayersAdd : m_LayersRem; | ||
828 | |||
829 | if (strOption.empty()) | ||
830 | { | ||
831 | for (int idx = 0; idx < WT_COUNT; idx++) | ||
832 | pLayers[idx]--; | ||
833 | } | ||
834 | else | ||
835 | { | ||
836 | EWearableType type = LLWearable::typeNameToType(strOption); | ||
837 | if (WT_INVALID != type) | ||
838 | { | ||
839 | pLayers[type]--; | ||
840 | m_Behaviours[eBehaviour]--; | ||
841 | } | ||
842 | } | ||
843 | } | ||
844 | break; | ||
845 | case RLV_BHVR_SETENV: // @setenv=y - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-0.2.0h | ||
846 | { | ||
847 | if (!fNoSetEnv) | ||
848 | { | ||
849 | // Restore WindLight parameters to what they were before @setenv=n was issued | ||
850 | RlvWLSnapshot::restoreSnapshot(m_pWLSnapshot); | ||
851 | delete m_pWLSnapshot; | ||
852 | m_pWLSnapshot = NULL; | ||
853 | } | ||
854 | } | ||
855 | break; | ||
856 | case RLV_BHVR_SHOWLOC: // @showloc=y - Checked: 2009-07-09 (RLVa-1.0.0f) | Added: RLVa-1.0.0f | ||
857 | case RLV_BHVR_SHOWNAMES: // @shownames=y - Checked: 2009-07-09 (RLVa-1.0.0f) | Added: RLVa-1.0.0f | ||
858 | case RLV_BHVR_SHOWHOVERTEXTALL: // @showhovertextal=y - Checked: 2009-07-09 (RLVa-1.0.0f) | Added: RLVa-1.0.0f | ||
859 | case RLV_BHVR_SHOWHOVERTEXTWORLD: // @showhovertextworld=y - Checked: 2009-07-09 (RLVa-1.0.0f) | Added: RLVa-1.0.0f | ||
860 | case RLV_BHVR_SHOWHOVERTEXTHUD: // @showhovertexthud=y - Checked: 2009-07-09 (RLVa-1.0.0f) | Added: RLVa-1.0.0f | ||
861 | { | ||
862 | // If this was the last of any of the five restrictions we should refresh all hover text in case anything needs restoring | ||
863 | if (!m_Behaviours[eBehaviour]) | ||
864 | LLHUDText::refreshAllObjectText(); | ||
865 | } | ||
866 | break; | ||
867 | case RLV_BHVR_SHOWHOVERTEXT: // @showhovertext:<uuid>=y - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f | ||
868 | { | ||
869 | LLUUID idException(strOption); | ||
870 | if (!idException.isNull()) // If there's an option it should be a valid UUID | ||
871 | { | ||
872 | removeException(eBehaviour, LLUUID(strOption)); | ||
873 | |||
874 | // Restore the object's hover text | ||
875 | LLViewerObject* pObj = gObjectList.findObject(idException); | ||
876 | if ( (pObj) && (pObj->mText.notNull()) && (!pObj->mText->getObjectText().empty()) ) | ||
877 | pObj->mText->setStringUTF8(pObj->mText->getObjectText()); | ||
878 | } | ||
879 | } | ||
880 | break; | ||
881 | case RLV_BHVR_NOTIFY: // @notify:<option>=rem - Checked: 2009-08-04 (RLVa-1.0.1d) | Modified: RLVa-1.0.1d | ||
882 | { | ||
883 | S32 nChannel; std::string strFilter; | ||
884 | if ( (m_pBhvrNotify) && (!strOption.empty()) && (rlvParseNotifyOption(strOption, nChannel, strFilter)) ) | ||
885 | { | ||
886 | m_pBhvrNotify->removeNotify(uuid, nChannel, strFilter); | ||
887 | |||
888 | if (!m_pBhvrNotify->hasNotify()) | ||
889 | { | ||
890 | removeBehaviourObserver(m_pBhvrNotify); | ||
891 | delete m_pBhvrNotify; | ||
892 | m_pBhvrNotify = NULL; | ||
893 | } | ||
894 | } | ||
895 | } | ||
896 | break; | ||
897 | case RLV_BHVR_RECVCHAT: // @recvchat:<uuid>=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f | ||
898 | case RLV_BHVR_RECVEMOTE: // @recvemote:<uui>=red - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f | ||
899 | case RLV_BHVR_RECVIM: // @recvim:<uuid>=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f | ||
900 | case RLV_BHVR_SENDIM: // @sendim:<uuid>=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f | ||
901 | case RLV_BHVR_TPLURE: // @recvim:<uuid>=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f | ||
902 | case RLV_BHVR_ACCEPTTP: // @accepttp:<uuid>=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f | ||
903 | { | ||
904 | removeException(eBehaviour, LLUUID(strOption)); | ||
905 | } | ||
906 | break; | ||
907 | default: | ||
908 | { | ||
909 | // Give our observers a chance to handle any command we don't | ||
910 | RlvEvent rlvEvent(uuid, rlvCmd); | ||
911 | m_Emitter.update(&RlvObserver::onRemoveCommand, rlvEvent); | ||
912 | } | ||
913 | break; | ||
914 | } | ||
915 | return TRUE; // Remove commands don't fail, doesn't matter what we return here | ||
916 | } | ||
917 | |||
918 | BOOL RlvHandler::processForceCommand(const LLUUID& idObj, const RlvCommand& rlvCmd) const | ||
919 | { | ||
920 | const std::string& strOption = rlvCmd.getOption(); | ||
921 | BOOL fHandled = TRUE; | ||
922 | |||
923 | switch (rlvCmd.getBehaviourType()) | ||
924 | { | ||
925 | case RLV_BHVR_DETACH: // @detach[:<option>]=force - Checked: | ||
926 | onForceDetach(idObj, strOption); | ||
927 | break; | ||
928 | case RLV_BHVR_REMOUTFIT: // @remoutfit:<option>=force - Checked: | ||
929 | onForceRemOutfit(idObj, strOption); | ||
930 | break; | ||
931 | case RLV_BHVR_UNSIT: // @unsit=force - Checked: 2009-06-02 (RLVa-0.2.0g) | ||
932 | { | ||
933 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | ||
934 | if ( (pAvatar) && (pAvatar->mIsSitting) && (!hasBehaviourExcept(RLV_BHVR_UNSIT, idObj)) ) | ||
935 | { | ||
936 | // See behaviour notes on why we have to force an agent update here | ||
937 | gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); | ||
938 | send_agent_update(TRUE, TRUE); | ||
939 | } | ||
940 | } | ||
941 | break; | ||
942 | case RLV_BHVR_TPTO: // @tpto:<option>=force - Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-1.0.0h | ||
943 | { | ||
944 | fHandled = FALSE; | ||
945 | if ( (!strOption.empty()) && (-1 == strOption.find_first_not_of("0123456789/.")) ) | ||
946 | { | ||
947 | LLVector3d posGlobal; | ||
948 | |||
949 | typedef boost::tokenizer<boost::char_separator<char> > tokenizer; | ||
950 | boost::char_separator<char> sep("/", "", boost::keep_empty_tokens); | ||
951 | tokenizer tokens(strOption, sep); int idx = 0; | ||
952 | for (tokenizer::iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken) | ||
953 | { | ||
954 | if (idx < 3) | ||
955 | LLStringUtil::convertToF64(*itToken, posGlobal[idx++]); | ||
956 | } | ||
957 | |||
958 | if (idx == 3) | ||
959 | { | ||
960 | gAgent.teleportViaLocation(posGlobal); | ||
961 | fHandled = TRUE; | ||
962 | } | ||
963 | } | ||
964 | } | ||
965 | break; | ||
966 | case RLV_BHVR_SIT: // @sit:<option>=force - Checked: 2009-06-02 (RLVa-0.2.0g) | ||
967 | fHandled = onForceSit(idObj, rlvCmd.getOption()); | ||
968 | break; | ||
969 | case RLV_BHVR_ADDOUTFIT: // @addoutfit:<option>=force <- synonym of @attach:<option>=force | ||
970 | case RLV_BHVR_ATTACH: // @attach:<option>=force - Checked: | ||
971 | onForceWear(rlvCmd.getOption(), true, false); // Force attach single folder | ||
972 | break; | ||
973 | case RLV_BHVR_ATTACHALL: // @attachall:<option>=force - Checked: | ||
974 | onForceWear(rlvCmd.getOption(), true, true); // Force attach nested folders | ||
975 | break; | ||
976 | case RLV_BHVR_DETACHALL: // @detachall:<option>=force - Checked: | ||
977 | onForceWear(rlvCmd.getOption(), false, true); // Force detach nested folders | ||
978 | break; | ||
979 | case RLV_BHVR_ATTACHTHIS: | ||
980 | case RLV_BHVR_ATTACHALLTHIS: | ||
981 | case RLV_BHVR_DETACHTHIS: | ||
982 | case RLV_BHVR_DETACHALLTHIS: | ||
983 | { | ||
984 | ERlvBehaviour eBehaviour = rlvCmd.getBehaviourType(); | ||
985 | std::string strReply; | ||
986 | if (onGetPath(idObj, strOption, strReply)) | ||
987 | { | ||
988 | LLStringUtil::toLower(strReply); | ||
989 | onForceWear(strReply, | ||
990 | (RLV_BHVR_ATTACHTHIS == eBehaviour) || (RLV_BHVR_ATTACHALLTHIS == eBehaviour), | ||
991 | (RLV_BHVR_ATTACHALLTHIS == eBehaviour) || (RLV_BHVR_DETACHALLTHIS == eBehaviour)); | ||
992 | } | ||
993 | } | ||
994 | break; | ||
995 | case RLV_BHVR_DETACHME: // @detachme=force - Checked: 2009-06-07 (RLVa-0.2.1c) | ||
996 | { | ||
997 | // NOTE: @detachme=force could be seen as a @detach:<attachpt>=force but RLV implements it as a "detach by UUID" | ||
998 | LLViewerObject* pObj; LLVOAvatar* pAvatar; LLViewerJointAttachment* pAttachPt; | ||
999 | if ( ((pObj = gObjectList.findObject(idObj)) != NULL) && (pObj->isAttachment()) && | ||
1000 | ((pAvatar = gAgent.getAvatarObject()) != NULL) && | ||
1001 | ((pAttachPt = pAvatar->getTargetAttachmentPoint(pObj->getRootEdit())) != NULL) ) | ||
1002 | { | ||
1003 | handle_detach_from_avatar(pAttachPt); | ||
1004 | } | ||
1005 | } | ||
1006 | break; | ||
1007 | default: | ||
1008 | { | ||
1009 | // Give our observers a chance to handle any command we don't | ||
1010 | RlvEvent rlvEvent(idObj, rlvCmd); | ||
1011 | fHandled = m_Emitter.update(&RlvObserver::onForceCommand, rlvEvent); | ||
1012 | } | ||
1013 | break; | ||
1014 | } | ||
1015 | return fHandled; // If we handled it then it'll still be TRUE; if an observer doesn't handle it'll be FALSE | ||
1016 | } | ||
1017 | |||
1018 | // Checked: 2009-07-12 (RLVa-1.0.0h) | ||
1019 | BOOL RlvHandler::processReplyCommand(const LLUUID& uuid, const RlvCommand& rlvCmd) const | ||
1020 | { | ||
1021 | const std::string& strOption = rlvCmd.getOption(); | ||
1022 | const std::string& strChannel = rlvCmd.getParam(); | ||
1023 | std::string strReply; | ||
1024 | |||
1025 | BOOL fHandled = TRUE; | ||
1026 | switch (rlvCmd.getBehaviourType()) | ||
1027 | { | ||
1028 | case RLV_BHVR_VERSION: // @version=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h) | ||
1029 | strReply = getVersionString(); | ||
1030 | break; | ||
1031 | case RLV_BHVR_GETOUTFIT: // @getoufit[:<layer>]=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0d | ||
1032 | { | ||
1033 | // (Quirk: RLV 1.16.1 will execute @getoutfit=<channel> if <layer> is invalid, so we need to as well) | ||
1034 | EWearableType layerType = LLWearable::typeNameToType(strOption); | ||
1035 | |||
1036 | const EWearableType layerTypes[] = | ||
1037 | { | ||
1038 | WT_GLOVES, WT_JACKET, WT_PANTS, WT_SHIRT, WT_SHOES, WT_SKIRT, WT_SOCKS, | ||
1039 | WT_UNDERPANTS, WT_UNDERSHIRT, WT_SKIN, WT_EYES, WT_HAIR, WT_SHAPE | ||
1040 | }; | ||
1041 | |||
1042 | #ifdef RLV_EXPERIMENTAL_COMPOSITE_FOLDING | ||
1043 | for (int idx = 0, cnt = sizeof(layerTypes) / sizeof(EWearableType); idx < cnt; idx++) | ||
1044 | { | ||
1045 | if ( (WT_INVALID == layerType) || (layerTypes[idx] == layerType) ) | ||
1046 | { | ||
1047 | // TODO-RLVa: add support for 'fHideLockedLayers' | ||
1048 | bool fWorn = (gAgent.getWearable(layerTypes[idx])) && | ||
1049 | (!isHiddenCompositeItem(gAgent.getWearableItem(layerTypes[idx]), | ||
1050 | LLWearable::typeToTypeName(layerTypes[idx]))); | ||
1051 | strReply.push_back( (fWorn) ? '1' : '0' ); | ||
1052 | } | ||
1053 | } | ||
1054 | #else | ||
1055 | for (int idx = 0, cnt = sizeof(layerTypes) / sizeof(EWearableType); idx < cnt; idx++) | ||
1056 | if ( (WT_INVALID == layerType) || (layerTypes[idx] == layerType) ) | ||
1057 | { | ||
1058 | // We never hide body parts, even if they're "locked" and we're hiding locked layers | ||
1059 | // (nor do we hide a layer if the issuing object is the only one that has this layer locked) | ||
1060 | bool fWorn = (gAgent.getWearable(layerTypes[idx])) && | ||
1061 | ( (!RlvSettings::getHideLockedLayers()) || | ||
1062 | (LLAssetType::AT_BODYPART == LLWearable::typeToAssetType(layerTypes[idx])) || | ||
1063 | ( (isRemovableExcept(layerTypes[idx], uuid)) && | ||
1064 | (isStrippable(gAgent.getWearableItem(layerTypes[idx]))) ) ); | ||
1065 | strReply.push_back( (fWorn) ? '1' : '0' ); | ||
1066 | //strReply.push_back( (gAgent.getWearable(layerTypes[idx])) ? '1' : '0' ); | ||
1067 | } | ||
1068 | #endif // RLV_EXPERIMENTAL_COMPOSITE_FOLDING | ||
1069 | } | ||
1070 | break; | ||
1071 | case RLV_BHVR_GETATTACH: // @getattach[:<layer>]=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0d | ||
1072 | { | ||
1073 | // If we're fetching all worn attachments then the reply should start with 0 | ||
1074 | if (strOption.empty()) | ||
1075 | strReply.push_back('0'); | ||
1076 | |||
1077 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); std::string strAttachName; | ||
1078 | for (LLVOAvatar::attachment_map_t::const_iterator itAttach = pAvatar->mAttachmentPoints.begin(); | ||
1079 | itAttach != pAvatar->mAttachmentPoints.end(); ++itAttach) | ||
1080 | { | ||
1081 | LLViewerJointAttachment* pAttachment = itAttach->second; | ||
1082 | if (!pAttachment) | ||
1083 | continue; | ||
1084 | |||
1085 | strAttachName = pAttachment->getName(); // Capitalized (see avatar_lad.xml) | ||
1086 | LLStringUtil::toLower(strAttachName); | ||
1087 | |||
1088 | #ifdef RLV_EXPERIMENTAL_COMPOSITE_FOLDING | ||
1089 | if ( (strOption.empty()) || (strOption == strAttachName) ) | ||
1090 | { | ||
1091 | // TODO-RLVa: add support for 'fHideLockedAttach' | ||
1092 | bool fWorn = (pAttachment->getItemID().notNull()) && | ||
1093 | (!isHiddenCompositeItem(pAttachment->getItemID(), strAttachName)); | ||
1094 | strReply.push_back( (fWorn) ? '1' : '0' ); | ||
1095 | } | ||
1096 | #else | ||
1097 | if ( (strOption.empty()) || (strOption == strAttachName) ) | ||
1098 | { | ||
1099 | bool fWorn = (pAttachment->getItemID().notNull()) && | ||
1100 | ( (!RlvSettings::getHideLockedAttach()) || | ||
1101 | ( (isDetachable(itAttach->first)) && (isStrippable(pAttachment->getItemID())) ) ); | ||
1102 | strReply.push_back( (fWorn) ? '1' : '0' ); | ||
1103 | //strReply.push_back( (pAttachment->getItemID().notNull()) ? '1' : '0' ); | ||
1104 | } | ||
1105 | #endif // RLV_EXPERIMENTAL_COMPOSITE_FOLDING | ||
1106 | } | ||
1107 | } | ||
1108 | break; | ||
1109 | case RLV_BHVR_GETSTATUS: // @getstatus[:<option>]=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h) | ||
1110 | { | ||
1111 | // NOTE: specification says response should start with '/' but RLV-1.16.1 returns an empty string when no rules are set | ||
1112 | rlv_object_map_t::const_iterator itObj = m_Objects.find(uuid); | ||
1113 | if (itObj != m_Objects.end()) | ||
1114 | { | ||
1115 | std::string strObjStatus = itObj->second.getStatusString(strOption); | ||
1116 | if (!strObjStatus.empty()) | ||
1117 | { | ||
1118 | strReply.push_back('/'); | ||
1119 | strReply += strObjStatus; | ||
1120 | } | ||
1121 | } | ||
1122 | } | ||
1123 | break; | ||
1124 | case RLV_BHVR_GETSTATUSALL: // @getstatusall[:<option>]=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h) | ||
1125 | { | ||
1126 | // NOTE: specification says response should start with '/' but RLV-1.16.1 returns an empty string when no rules are set | ||
1127 | std::string strObjStatus; | ||
1128 | for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj) | ||
1129 | { | ||
1130 | strObjStatus = itObj->second.getStatusString(strOption); | ||
1131 | if (!strObjStatus.empty()) | ||
1132 | { | ||
1133 | strReply.push_back('/'); | ||
1134 | strReply += strObjStatus; | ||
1135 | } | ||
1136 | } | ||
1137 | } | ||
1138 | break; | ||
1139 | case RLV_BHVR_GETINV: // @getinv[:<path>]=<channel> - Checked: 2009-07-28 (RLVa-1.0.1b) | Modified: RLVa-1.0.1b | ||
1140 | { | ||
1141 | LLViewerInventoryCategory* pFolder = getSharedFolder(strOption); | ||
1142 | if (pFolder) | ||
1143 | { | ||
1144 | LLInventoryModel::cat_array_t* pFolders; | ||
1145 | LLInventoryModel::item_array_t* pItems; | ||
1146 | gInventory.getDirectDescendentsOf(pFolder->getUUID(), pFolders, pItems); | ||
1147 | |||
1148 | if (pFolders) | ||
1149 | { | ||
1150 | for (S32 idxFolder = 0, cntFolder = pFolders->count(); idxFolder < cntFolder; idxFolder++) | ||
1151 | { | ||
1152 | const std::string& strFolder = pFolders->get(idxFolder)->getName(); | ||
1153 | if ( (!strFolder.empty()) && (RLV_FOLDER_PREFIX_HIDDEN != strFolder[0]) && | ||
1154 | (!isFoldedFolder(pFolders->get(idxFolder).get(), true)) ) | ||
1155 | { | ||
1156 | if (!strReply.empty()) | ||
1157 | strReply.push_back(','); | ||
1158 | strReply += strFolder; | ||
1159 | } | ||
1160 | } | ||
1161 | } | ||
1162 | } | ||
1163 | } | ||
1164 | break; | ||
1165 | case RLV_BHVR_GETINVWORN: // @getinvworn[:path]=<channel> - Checked: | ||
1166 | onGetInvWorn(rlvCmd.getOption(), strReply); | ||
1167 | break; | ||
1168 | case RLV_BHVR_FINDFOLDER: // @findfolder:<criteria>=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h) | ||
1169 | { | ||
1170 | // COMPAT-RLV: RLV 1.16.1 returns the first random folder it finds (probably tries to match "" to a folder name?) | ||
1171 | // (just going to stick with what's there for now... no option => no folder) | ||
1172 | LLInventoryModel::cat_array_t folders; | ||
1173 | if ( (!strOption.empty()) && (findSharedFolders(strOption, folders)) ) | ||
1174 | { | ||
1175 | // We need to return an "in depth" result so whoever has the most '/' is our lucky winner | ||
1176 | int maxSlashes = 0, curSlashes; std::string strFolderName; | ||
1177 | for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++) | ||
1178 | { | ||
1179 | strFolderName = getSharedPath(folders.get(idxFolder)); | ||
1180 | |||
1181 | curSlashes = std::count(strFolderName.begin(), strFolderName.end(), '/'); | ||
1182 | if (curSlashes > maxSlashes) | ||
1183 | { | ||
1184 | maxSlashes = curSlashes; | ||
1185 | strReply = strFolderName; | ||
1186 | } | ||
1187 | } | ||
1188 | } | ||
1189 | } | ||
1190 | break; | ||
1191 | #ifdef RLV_EXTENSION_CMD_FINDFOLDERS | ||
1192 | case RLV_BHVR_FINDFOLDERS: // @findfolders:<criteria>=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h) | Added: RLVa-0.2.0b | ||
1193 | { | ||
1194 | LLInventoryModel::cat_array_t folders; | ||
1195 | if ( (!strOption.empty()) && (findSharedFolders(strOption, folders)) ) | ||
1196 | { | ||
1197 | for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++) | ||
1198 | { | ||
1199 | if (!strReply.empty()) | ||
1200 | strReply.push_back(','); | ||
1201 | strReply += getSharedPath(folders.get(idxFolder)); | ||
1202 | } | ||
1203 | } | ||
1204 | } | ||
1205 | break; | ||
1206 | #endif // RLV_EXTENSION_CMD_FINDFOLDERS | ||
1207 | case RLV_BHVR_GETPATH: // @getpath[:<option>]=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h) | ||
1208 | onGetPath(uuid, rlvCmd.getOption(), strReply); | ||
1209 | break; | ||
1210 | case RLV_BHVR_GETSITID: // @getsitid=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h) | ||
1211 | { | ||
1212 | // (Quirk: RLV 1.16.1 returns a NULL uuid if we're not sitting) | ||
1213 | LLVOAvatar* pAvatarObj = gAgent.getAvatarObject(); LLUUID uuid; | ||
1214 | if ( (pAvatarObj) && (pAvatarObj->mIsSitting) ) | ||
1215 | { | ||
1216 | // LLVOAvatar inherits from 2 classes so make sure we get the right vfptr | ||
1217 | LLViewerObject* pAvatar = dynamic_cast<LLViewerObject*>(pAvatarObj), *pParent; | ||
1218 | // (If there is a parent, we need to upcast it from LLXform to LLViewerObject to get its UUID) | ||
1219 | if ( (pAvatar) && ((pParent = static_cast<LLViewerObject*>(pAvatar->getRoot())) != pAvatar) ) | ||
1220 | uuid = pParent->getID(); | ||
1221 | } | ||
1222 | strReply = uuid.asString(); | ||
1223 | } | ||
1224 | break; | ||
1225 | default: | ||
1226 | { | ||
1227 | // Give our observers a chance to handle any command we don't | ||
1228 | RlvEvent rlvEvent(uuid, rlvCmd); | ||
1229 | return m_Emitter.update(&RlvObserver::onReplyCommand, rlvEvent); | ||
1230 | } | ||
1231 | break; | ||
1232 | } | ||
1233 | |||
1234 | if (fHandled) | ||
1235 | rlvSendChatReply(strChannel, strReply); | ||
1236 | return fHandled; | ||
1237 | } | ||
1238 | |||
1239 | // ============================================================================ | ||
1240 | // House keeping (see debug notes for test methodology, test script and last run) | ||
1241 | // | ||
1242 | |||
1243 | void RlvHandler::initLookupTables() | ||
1244 | { | ||
1245 | static bool fInitialized = false; | ||
1246 | if (!fInitialized) | ||
1247 | { | ||
1248 | // Initialize the attachment name lookup table | ||
1249 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | ||
1250 | if (pAvatar) | ||
1251 | { | ||
1252 | std::string strAttachPtName; | ||
1253 | for (LLVOAvatar::attachment_map_t::const_iterator itAttach = pAvatar->mAttachmentPoints.begin(); | ||
1254 | itAttach != pAvatar->mAttachmentPoints.end(); ++itAttach) | ||
1255 | { | ||
1256 | LLViewerJointAttachment* pAttachPt = itAttach->second; | ||
1257 | if (pAttachPt) | ||
1258 | { | ||
1259 | strAttachPtName = pAttachPt->getName(); | ||
1260 | LLStringUtil::toLower(strAttachPtName); | ||
1261 | m_AttachLookup.addKeyword(strAttachPtName, itAttach->first); | ||
1262 | } | ||
1263 | } | ||
1264 | fInitialized = true; | ||
1265 | } | ||
1266 | } | ||
1267 | } | ||
1268 | |||
1269 | // Checked: 2009-08-11 (RLVa-1.0.1h) | Modified: RLVa-1.0.1h | ||
1270 | void RlvHandler::onAttach(LLViewerJointAttachment* pAttachPt, bool fFullyLoaded) | ||
1271 | { | ||
1272 | // Sanity check - LLVOAvatar::attachObject() should call us *after* calling LLViewerJointAttachment::addObject() | ||
1273 | LLViewerObject* pObj = pAttachPt->getObject(); | ||
1274 | S32 idxAttachPt = getAttachPointIndex(pObj); // getAttachPointIndex() has a NULL pointer check so this is safe | ||
1275 | if ( (!pObj) || (!idxAttachPt) ) | ||
1276 | { | ||
1277 | RLV_ERRS << "pAttachPt->getObject() == NULL" << LL_ENDL; | ||
1278 | return; | ||
1279 | } | ||
1280 | |||
1281 | // Check if this attachment point has a pending "reattach-on-detach" | ||
1282 | rlv_reattach_map_t::iterator itReattach = m_AttachPending.find(idxAttachPt); | ||
1283 | if (itReattach != m_AttachPending.end()) | ||
1284 | { | ||
1285 | if (itReattach->second == pAttachPt->getItemID()) | ||
1286 | { | ||
1287 | RLV_INFOS << "Reattached " << pAttachPt->getItemID().asString() << " to " << idxAttachPt << LL_ENDL; | ||
1288 | m_AttachPending.erase(itReattach); | ||
1289 | } | ||
1290 | } | ||
1291 | else if ( (fFullyLoaded) && (!isDetachableExcept(idxAttachPt, pObj)) ) | ||
1292 | { | ||
1293 | // We're fully loaded with no pending reattach on this attach point but it's "undetachable" -> force detach the new attachment | ||
1294 | |||
1295 | // Assertion: the only way the attachment point could be locked at this point is if some object locked it with @detach:attachpt=n | ||
1296 | // - previous attachments on this attachment point might have issued @detach=n but those were all cleaned up at detach | ||
1297 | // - the new attachment might have issued @detach=n but that won't actually lock down the attachment point until further down | ||
1298 | // NOTE 1: "some object" may no longer exist if it was not an attachment and the GC hasn't cleaned it up yet (informative) | ||
1299 | // NOTE 2: "some object" may refer to the new attachment - ie @detach:spine=n from object on spine (problematic, causes reattach) | ||
1300 | // -> solved by using isDetachableExcept(idxAttachPt, pObj) instead of isDetachable(idxAttachPt) | ||
1301 | |||
1302 | m_DetachPending.insert(std::pair<S32, LLUUID>(idxAttachPt, pObj->getID())); | ||
1303 | rlvForceDetach(pAttachPt); | ||
1304 | } | ||
1305 | |||
1306 | // Check if we already have an RlvObject instance for this object (rezzed prim attached from in-world, or an attachment that rezzed in) | ||
1307 | rlv_object_map_t::iterator itObj = m_Objects.find(pObj->getID()); | ||
1308 | if (itObj != m_Objects.end()) | ||
1309 | { | ||
1310 | // If it's an attachment we processed commands for but that only just rezzed in we need to mark it as existing in gObjectList | ||
1311 | if (!itObj->second.m_fLookup) | ||
1312 | itObj->second.m_fLookup = true; | ||
1313 | |||
1314 | // In both cases we should check for "@detach=n" and actually lock down the attachment point it got attached to | ||
1315 | if (itObj->second.hasBehaviour(RLV_BHVR_DETACH)) | ||
1316 | { | ||
1317 | // (Copy/paste from processAddCommand) | ||
1318 | setDetachable(pObj, pObj->getID(), false); | ||
1319 | |||
1320 | if (pObj->isHUDAttachment()) | ||
1321 | LLPipeline::sShowHUDAttachments = TRUE; // Prevents hiding of locked HUD attachments | ||
1322 | } | ||
1323 | } | ||
1324 | |||
1325 | // Fetch the inventory item if we don't currently have it since we might need it for reattach-on-detach | ||
1326 | const LLUUID& idItem = pAttachPt->getItemID(); | ||
1327 | LLViewerInventoryItem* pItem = ( (idItem.notNull()) && (gInventory.isInventoryUsable()) ) ? gInventory.getItem(idItem) : NULL; | ||
1328 | if ( (STATE_STARTED == LLStartUp::getStartupState()) && (pItem != NULL) ) | ||
1329 | { | ||
1330 | RlvCurrentlyWorn f; | ||
1331 | f.fetchItem(idItem); | ||
1332 | } | ||
1333 | |||
1334 | // If what we're wearing is located under the shared root then append the attachment point name (if needed) | ||
1335 | LLViewerInventoryCategory* pRlvRoot = getSharedRoot(); | ||
1336 | if ( (STATE_STARTED == LLStartUp::getStartupState()) && (pRlvRoot) && (pItem) && (pItem->isComplete()) && | ||
1337 | (gInventory.isObjectDescendentOf(idItem, pRlvRoot->getUUID())) ) | ||
1338 | { | ||
1339 | std::string strAttachPt = pAttachPt->getName(); | ||
1340 | LLStringUtil::toLower(strAttachPt); | ||
1341 | |||
1342 | // If we can modify the item then it should contain the attach point name itself, otherwise its parent should | ||
1343 | if (pItem->getPermissions().allowModifyBy(gAgent.getID())) | ||
1344 | { | ||
1345 | if (!getAttachPoint(pItem, true)) | ||
1346 | { | ||
1347 | // It doesn't specify an attach point and we can rename it [see LLItemBridge::renameItem()] | ||
1348 | std::string strName = pItem->getName(); | ||
1349 | LLStringUtil::truncate(strName, DB_INV_ITEM_NAME_STR_LEN - strAttachPt.length() - 3); | ||
1350 | |||
1351 | strName += " (" + strAttachPt + ")"; | ||
1352 | |||
1353 | pItem->rename(strName); | ||
1354 | pItem->updateServer(FALSE); | ||
1355 | gInventory.updateItem(pItem); | ||
1356 | //gInventory.notifyObservers(); <- done further down in LLVOAvatar::attachObject() | ||
1357 | } | ||
1358 | } | ||
1359 | else | ||
1360 | { | ||
1361 | // Folder can't be the shared root, or be its direct descendant (= nested at least 2 levels deep) | ||
1362 | LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID()); | ||
1363 | if ( (pFolder) && | ||
1364 | (pFolder->getUUID() != pRlvRoot->getUUID()) && (pFolder->getParentUUID() != pRlvRoot->getUUID()) && | ||
1365 | (!getAttachPoint(pFolder, true)) ) | ||
1366 | { | ||
1367 | // It's no mod and its parent folder doesn't contain an attach point | ||
1368 | LLInventoryModel::cat_array_t* pFolders; | ||
1369 | LLInventoryModel::item_array_t* pItems; | ||
1370 | gInventory.getDirectDescendentsOf(pFolder->getUUID(), pFolders, pItems); | ||
1371 | |||
1372 | if (pItems) | ||
1373 | { | ||
1374 | int cntObjects = 0; | ||
1375 | for (S32 idxItem = 0, cntItem = pItems->size(); idxItem < cntItem; idxItem++) | ||
1376 | { | ||
1377 | if (LLAssetType::AT_OBJECT == pItems->get(idxItem)->getType()) | ||
1378 | cntObjects++; | ||
1379 | } | ||
1380 | |||
1381 | // Only rename if there's exactly 1 object/attachment inside of it [see LLFolderBridge::renameItem()] | ||
1382 | if ( (1 == cntObjects) && (NEW_CATEGORY_NAME == pFolder->getName()) ) | ||
1383 | { | ||
1384 | std::string strName = ".(" + strAttachPt + ")"; | ||
1385 | |||
1386 | pFolder->rename(strName); | ||
1387 | pFolder->updateServer(FALSE); | ||
1388 | gInventory.updateCategory(pFolder); | ||
1389 | //gInventory.notifyObservers(); <- done further down in LLVOAvatar::attachObject() | ||
1390 | } | ||
1391 | } | ||
1392 | } | ||
1393 | } | ||
1394 | } | ||
1395 | } | ||
1396 | |||
1397 | // Checked: 2009-05-31 (RLVa-0.2.0e) | Modified: RLVa-0.2.0e | ||
1398 | void RlvHandler::onDetach(LLViewerJointAttachment* pAttachPt) | ||
1399 | { | ||
1400 | LLViewerObject* pObj = pAttachPt->getObject(); | ||
1401 | if (!pObj) | ||
1402 | { | ||
1403 | // LLVOAvatar::detachObject() should call us *before* calling LLViewerJointAttachment::removeObject() | ||
1404 | RLV_ERRS << "pAttachPt->getObject() == NULL" << LL_ENDL; | ||
1405 | return; | ||
1406 | } | ||
1407 | S32 idxAttachPt = getAttachPointIndex(pObj); | ||
1408 | if (0 == idxAttachPt) | ||
1409 | { | ||
1410 | // If we ended up here then the user "Drop"'ed this attachment (which we can't recover from) | ||
1411 | return; | ||
1412 | } | ||
1413 | |||
1414 | #ifdef RLV_DEBUG | ||
1415 | // TODO-RLV: when we're exiting (for whatever reason) app state won't always reflect it but | ||
1416 | // gAgent.getAvatarObject()->mAttachmentPoints will be NULL so anywhere we use | ||
1417 | // "get_if_there" will call through a NULL pointer. One case is "idling out" -> test the rest | ||
1418 | //LLViewerJointAttachment* pDbgAttachmentPt = | ||
1419 | // get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, (S32)idxAttachPt, (LLViewerJointAttachment*)NULL); | ||
1420 | //RLV_INFOS << "Clean up for '" << pDbgAttachmentPt->getName() << "'" << LL_ENDL; | ||
1421 | #endif // RLV_DEBUG | ||
1422 | |||
1423 | // If the attachment was locked then we should reattach it (unless we're already trying to reattach to this attachment point) | ||
1424 | // (unless we forcefully detached it else in which case we do not want to reattach it) | ||
1425 | rlv_reattach_map_t::iterator itDetach = m_DetachPending.find(idxAttachPt); | ||
1426 | if (itDetach != m_DetachPending.end()) | ||
1427 | { | ||
1428 | // RLVa-TODO: we should really be comparing item UUIDs but is it even possible to end up here and not have them match? | ||
1429 | m_DetachPending.erase(itDetach); | ||
1430 | } | ||
1431 | else if ( (!isDetachable(idxAttachPt)) && (m_AttachPending.find(idxAttachPt) == m_AttachPending.end()) ) | ||
1432 | { | ||
1433 | // In an ideal world we would simply set up an LLInventoryObserver but there's no specific "asset updated" changed flag *sighs* | ||
1434 | // NOTE: attachments *always* know their "inventory item UUID" so we don't have to worry about fetched vs unfetched inventory | ||
1435 | m_AttachPending.insert(std::pair<S32, LLUUID>(idxAttachPt, pAttachPt->getItemID())); | ||
1436 | } | ||
1437 | |||
1438 | // We can't - easily - clean up child prims that never issued @detach=n but the GC will get those eventually | ||
1439 | rlv_detach_map_t::iterator itAttach = m_Attachments.find(idxAttachPt); | ||
1440 | while ( (itAttach != m_Attachments.upper_bound(idxAttachPt)) && (itAttach != m_Attachments.end()) ) | ||
1441 | { | ||
1442 | LLViewerObject* pTempObj = gObjectList.findObject(itAttach->second); | ||
1443 | if ( (pTempObj) && (pTempObj->getRootEdit()->getID() == pObj->getID()) ) | ||
1444 | { | ||
1445 | // Iterator points to the object (or to a child prim) so issue a clear on behalf of the object (there's the | ||
1446 | // possibility of going into an eternal loop, but that's ok since it indicates a bug in @clear that needs fixing) | ||
1447 | processCommand(itAttach->second, "clear", true); | ||
1448 | |||
1449 | itAttach = m_Attachments.find(idxAttachPt); // @clear will invalidate all iterators so we have to start anew | ||
1450 | } | ||
1451 | else | ||
1452 | { | ||
1453 | itAttach++; | ||
1454 | } | ||
1455 | } | ||
1456 | |||
1457 | // Clean up in case there was never a @detach=n (only works for the root prim - see above) | ||
1458 | rlv_object_map_t::iterator itObj = m_Objects.find(pObj->getID()); | ||
1459 | if (itObj != m_Objects.end()) | ||
1460 | processCommand(itObj->second.m_UUID, "clear", true); | ||
1461 | } | ||
1462 | |||
1463 | // Checked: 2009-07-30 (RLVa-1.0.1c) | Modified: RLVa-1.0.1c | ||
1464 | bool RlvHandler::onGC() | ||
1465 | { | ||
1466 | // We can't issue @clear on an object while we're in the loop below since that would invalidate our iterator | ||
1467 | // (and starting over would mean that some objects might get their "lookup misses" counter updated more than once per GC run) | ||
1468 | std::list<LLUUID> ExpiredObjects; | ||
1469 | |||
1470 | for (rlv_object_map_t::iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj) | ||
1471 | { | ||
1472 | LLViewerObject* pObj = gObjectList.findObject(itObj->second.m_UUID); | ||
1473 | if (!pObj) | ||
1474 | { | ||
1475 | // If the RlvObject once existed in the gObjectList and now doesn't then expire it right now | ||
1476 | // If the RlvObject never existed in the gObjectList and still doesn't then increase its "lookup misses" counter | ||
1477 | // but if that reaches 20 (we run every 30 seconds so that's about 10 minutes) then we'll expire it too | ||
1478 | if ( (itObj->second.m_fLookup) || (++itObj->second.m_nLookupMisses > 20) ) | ||
1479 | ExpiredObjects.push_back(itObj->first); | ||
1480 | } | ||
1481 | else | ||
1482 | { | ||
1483 | // Check if this is an RlvObject instance who's object never existed in gObjectList before (rezzed prim in-world) | ||
1484 | // (it could also be an attachment that only just rezzed in but RlvHandler::onAttach() should be handling those) | ||
1485 | if ( (!itObj->second.m_fLookup) && (!pObj->isAttachment()) ) | ||
1486 | itObj->second.m_fLookup = true; | ||
1487 | } | ||
1488 | } | ||
1489 | |||
1490 | for (std::list<LLUUID>::const_iterator itExpired = ExpiredObjects.begin(); itExpired != ExpiredObjects.end(); ++itExpired) | ||
1491 | { | ||
1492 | #ifdef RLV_DEBUG | ||
1493 | RLV_INFOS << "Garbage collecting " << *itExpired << LL_ENDL; | ||
1494 | #endif // RLV_DEBUG | ||
1495 | |||
1496 | processCommand(*itExpired, "clear", true); | ||
1497 | } | ||
1498 | |||
1499 | return (0 != m_Objects.size()); // GC will kill itself if it has nothing to do | ||
1500 | } | ||
1501 | |||
1502 | // Checked: 2009-08-08 (RLVa-1.0.1g) | Modified: RLVa-1.0.1g | ||
1503 | void RlvHandler::onSavedAssetIntoInventory(const LLUUID& idItem) | ||
1504 | { | ||
1505 | for (rlv_reattach_map_t::iterator itAttach = m_AttachPending.begin(); itAttach != m_AttachPending.end(); ++itAttach) | ||
1506 | { | ||
1507 | if (idItem == itAttach->second) | ||
1508 | { | ||
1509 | RLV_INFOS << "Reattaching " << idItem.asString() << " to " << itAttach->first << LL_ENDL; | ||
1510 | |||
1511 | #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 | ||
1512 | LLAttachmentRezAction* rez_action = new LLAttachmentRezAction; | ||
1513 | rez_action->mItemID = itAttach->second; | ||
1514 | rez_action->mAttachPt = itAttach->first; | ||
1515 | |||
1516 | confirm_replace_attachment_rez(0/*YES*/, (void*)rez_action); // (Will call delete on rez_action) | ||
1517 | #else // Version: 1.23.4 | ||
1518 | LLSD payload; | ||
1519 | payload["item_id"] = itAttach->second; | ||
1520 | payload["attachment_point"] = itAttach->first; | ||
1521 | |||
1522 | LLNotifications::instance().forceResponse(LLNotification::Params("ReplaceAttachment").payload(payload), 0/*YES*/); | ||
1523 | #endif | ||
1524 | } | ||
1525 | } | ||
1526 | } | ||
1527 | |||
1528 | // ============================================================================ | ||
1529 | // String/chat censoring functions | ||
1530 | // | ||
1531 | |||
1532 | // LL must have included an strlen for UTF8 *somewhere* but I can't seem to find it so this one is home grown | ||
1533 | size_t utf8str_strlen(const std::string& utf8) | ||
1534 | { | ||
1535 | const char* pUTF8 = utf8.c_str(); size_t length = 0; | ||
1536 | for (int idx = 0, cnt = utf8.length(); idx < cnt ;idx++) | ||
1537 | { | ||
1538 | // We're looking for characters that don't start with 10 as their high bits | ||
1539 | if ((pUTF8[idx] & 0xC0) != 0x80) | ||
1540 | length++; | ||
1541 | } | ||
1542 | return length; | ||
1543 | } | ||
1544 | |||
1545 | // TODO-RLV: works, but more testing won't hurt | ||
1546 | std::string utf8str_chtruncate(const std::string& utf8, size_t length) | ||
1547 | { | ||
1548 | if (0 == length) | ||
1549 | return std::string(); | ||
1550 | if (utf8.length() <= length) | ||
1551 | return utf8; | ||
1552 | |||
1553 | const char* pUTF8 = utf8.c_str(); int idx = 0; | ||
1554 | while ( (pUTF8[idx]) && (length > 0) ) | ||
1555 | { | ||
1556 | // We're looking for characters that don't start with 10 as their high bits | ||
1557 | if ((pUTF8[idx] & 0xC0) != 0x80) | ||
1558 | length--; | ||
1559 | idx++; | ||
1560 | } | ||
1561 | |||
1562 | return utf8.substr(0, idx); | ||
1563 | } | ||
1564 | |||
1565 | // Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f | ||
1566 | void RlvHandler::filterChat(std::string& strUTF8Text, bool fFilterEmote) const | ||
1567 | { | ||
1568 | if (strUTF8Text.empty()) | ||
1569 | return; | ||
1570 | |||
1571 | if (rlvIsEmote(strUTF8Text)) // Check if it's an emote | ||
1572 | { | ||
1573 | if (fFilterEmote) // Emote filtering depends on fFilterEmote | ||
1574 | { | ||
1575 | if ( (strUTF8Text.find_first_of("\"()*=^_?~") != -1) || | ||
1576 | (strUTF8Text.find(" -") != -1) || (strUTF8Text.find("- ") != -1) || (strUTF8Text.find("''") != -1) ) | ||
1577 | { | ||
1578 | strUTF8Text = "..."; // Emote contains illegal character (or character sequence) | ||
1579 | } | ||
1580 | else if (!hasBehaviour("emote")) | ||
1581 | { | ||
1582 | int idx = strUTF8Text.find('.'); // Truncate at 20 characters or at the dot (whichever is shorter) | ||
1583 | strUTF8Text = utf8str_chtruncate(strUTF8Text, ( (idx > 0) && (idx < 20) ) ? idx + 1 : 20); | ||
1584 | } | ||
1585 | } | ||
1586 | } | ||
1587 | else if (strUTF8Text[0] == '/') // Not an emote, but starts with a '/' | ||
1588 | { | ||
1589 | if (utf8str_strlen(strUTF8Text) > 7) // Allow as long if it's 6 characters or less | ||
1590 | strUTF8Text = "..."; | ||
1591 | } | ||
1592 | else if ((strUTF8Text.length() < 4) || (strUTF8Text.compare(0, 2, "((")) || (strUTF8Text.compare(strUTF8Text.length() - 2, 2, "))"))) | ||
1593 | { | ||
1594 | strUTF8Text = "..."; // Regular chat (not OOC) | ||
1595 | } | ||
1596 | } | ||
1597 | |||
1598 | // Checked: 2009-07-04 (RLVa-1.0.0a) | Modified: RLVa-1.0.0a | ||
1599 | void RlvHandler::filterLocation(std::string& strUTF8Text) const | ||
1600 | { | ||
1601 | // TODO-RLVa: if either the region or parcel name is a simple word such as "a" or "the" then confusion will ensue? | ||
1602 | // -> not sure how you would go about preventing this though :|... | ||
1603 | |||
1604 | // Filter any mention of the surrounding region names | ||
1605 | LLWorld::region_list_t regions = LLWorld::getInstance()->getRegionList(); | ||
1606 | for (LLWorld::region_list_t::const_iterator itRegion = regions.begin(); itRegion != regions.end(); ++itRegion) | ||
1607 | rlvStringReplace(strUTF8Text, (*itRegion)->getName(), rlv_handler_t::cstrHiddenRegion); | ||
1608 | |||
1609 | // Filter any mention of the parcel name | ||
1610 | LLViewerParcelMgr* pParcelMgr = LLViewerParcelMgr::getInstance(); | ||
1611 | if (pParcelMgr) | ||
1612 | rlvStringReplace(strUTF8Text, pParcelMgr->getAgentParcelName(), rlv_handler_t::cstrHiddenParcel); | ||
1613 | } | ||
1614 | |||
1615 | void RlvHandler::filterNames(std::string& strUTF8Text) const | ||
1616 | { | ||
1617 | std::string strFirstName, strLastName, strName; | ||
1618 | |||
1619 | // TODO-RLV: make this a bit more efficient (ie people with a large draw distance will have a load of active regions) | ||
1620 | // -> the cost of multi string matching them all at once seems to be about the same as calling rlvStringReplace | ||
1621 | // twice so that would be a tremendous gain (and we'd get first name and word matching for free) | ||
1622 | #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 | ||
1623 | for (LLWorld::region_list_t::const_iterator itRegion = LLWorld::getInstance()->getRegionList().begin(); | ||
1624 | itRegion != LLWorld::getInstance()->getRegionList().end(); ++itRegion) | ||
1625 | { | ||
1626 | LLViewerRegion* pRegion = *itRegion; | ||
1627 | |||
1628 | for (S32 idxAgent = 0, cntAgent = pRegion->mMapAvatars.count(); idxAgent < cntAgent; idxAgent++) | ||
1629 | { | ||
1630 | // LLCacheName::getName() will add the UUID to the lookup queue if we don't know it yet | ||
1631 | if (gCacheName->getName(pRegion->mMapAvatarIDs.get(idxAgent), strFirstName, strLastName)) | ||
1632 | { | ||
1633 | strName = strFirstName + " " + strLastName; | ||
1634 | |||
1635 | rlvStringReplace(strUTF8Text, strName, getAnonym(strName)); | ||
1636 | } | ||
1637 | } | ||
1638 | } | ||
1639 | #else // Version: trunk | ||
1640 | // TODO-RLV: should restrict this to a certain radius (probably 1-2 sim range?) | ||
1641 | std::vector<LLUUID> idAgents; | ||
1642 | LLWorld::getInstance()->getAvatars(&idAgents, NULL); | ||
1643 | |||
1644 | for (int idxAgent = 0, cntAgent = idAgents.size(); idxAgent < cntAgent; idxAgent++) | ||
1645 | { | ||
1646 | // LLCacheName::getName() will add the UUID to the lookup queue if we don't know it yet | ||
1647 | if (gCacheName->getName(idAgents[idxAgent], strFirstName, strLastName)) | ||
1648 | { | ||
1649 | strName = strFirstName + " " + strLastName; | ||
1650 | |||
1651 | rlvStringReplace(strUTF8Text, strName, getAnonym(strName)); | ||
1652 | } | ||
1653 | } | ||
1654 | #endif | ||
1655 | } | ||
1656 | |||
1657 | const std::string& RlvHandler::getAnonym(const std::string& strName) const | ||
1658 | { | ||
1659 | const char* pszName = strName.c_str(); | ||
1660 | U32 nHash = 0; | ||
1661 | |||
1662 | // Test with 11,264 SL names showed a 3.33% - 3.82% occurance for each so we *should* get a very even spread | ||
1663 | for (int idx = 0, cnt = strName.length(); idx < cnt; idx++) | ||
1664 | nHash += pszName[idx]; | ||
1665 | |||
1666 | return cstrAnonyms[nHash % 28]; | ||
1667 | } | ||
1668 | |||
1669 | // Checked: 2009-07-07 (RLVa-1.0.0d) | Modified: RLVa-0.2.2a | ||
1670 | bool RlvHandler::redirectChatOrEmote(const std::string& strUTF8Text) const | ||
1671 | { | ||
1672 | // Sanity check - @redirchat only for chat and @rediremote only for emotes | ||
1673 | bool fIsEmote = rlvIsEmote(strUTF8Text); | ||
1674 | if ( ((!fIsEmote) && (!hasBehaviour(RLV_BHVR_REDIRCHAT))) || ((fIsEmote) && (!hasBehaviour(RLV_BHVR_REDIREMOTE))) ) | ||
1675 | return false; | ||
1676 | |||
1677 | if (!fIsEmote) | ||
1678 | { | ||
1679 | std::string strText = strUTF8Text; | ||
1680 | filterChat(strText, true); | ||
1681 | if (strText != "...") | ||
1682 | return false; // @sendchat wouldn't filter it so @redirchat won't redirect it either | ||
1683 | } | ||
1684 | |||
1685 | bool fSendChannel = hasBehaviour("sendchannel"); | ||
1686 | for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj) | ||
1687 | { | ||
1688 | for (rlv_command_list_t::const_iterator itCmd = itObj->second.m_Commands.begin(), | ||
1689 | endCmd = itObj->second.m_Commands.end(); itCmd != endCmd; ++itCmd) | ||
1690 | { | ||
1691 | if ( ( ((!fIsEmote) && (RLV_BHVR_REDIRCHAT == itCmd->getBehaviourType())) || | ||
1692 | ((fIsEmote) && (RLV_BHVR_REDIREMOTE == itCmd->getBehaviourType())) ) && | ||
1693 | ( (!fSendChannel) || (hasBehaviour("sendchannel", itCmd->getOption())) ) ) | ||
1694 | { | ||
1695 | rlvSendChatReply(itCmd->getOption(), strUTF8Text); | ||
1696 | } | ||
1697 | } | ||
1698 | } | ||
1699 | return true; | ||
1700 | } | ||
1701 | |||
1702 | // ============================================================================ | ||
1703 | // Public service functions (called by the outside world or by extension handlers) | ||
1704 | // | ||
1705 | |||
1706 | BOOL RlvHandler::isAgentNearby(const LLUUID& uuid) const | ||
1707 | { | ||
1708 | #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 | ||
1709 | for (LLWorld::region_list_t::const_iterator itRegion = LLWorld::getInstance()->getRegionList().begin(); | ||
1710 | itRegion != LLWorld::getInstance()->getRegionList().end(); ++itRegion) | ||
1711 | { | ||
1712 | LLViewerRegion* pRegion = *itRegion; | ||
1713 | |||
1714 | for (S32 idxAgent = 0, cntAgent = pRegion->mMapAvatars.count(); idxAgent < cntAgent; idxAgent++) | ||
1715 | if (pRegion->mMapAvatarIDs.get(idxAgent) == uuid) | ||
1716 | return TRUE; | ||
1717 | } | ||
1718 | #else // Version: trunk | ||
1719 | // TODO-RLV: rewrite this to fit trunk, but still need the radius limited to a sane range | ||
1720 | std::vector<LLUUID> idAgents; | ||
1721 | LLWorld::getInstance()->getAvatars(&idAgents, NULL); | ||
1722 | |||
1723 | for (int idxAgent = 0, cntAgent = idAgents.size(); idxAgent < cntAgent; idxAgent++) | ||
1724 | { | ||
1725 | if (idAgents[idxAgent] == uuid) | ||
1726 | return TRUE; | ||
1727 | } | ||
1728 | #endif | ||
1729 | return FALSE; | ||
1730 | } | ||
1731 | |||
1732 | // ============================================================================ | ||
1733 | // General purpose inventory functions | ||
1734 | // | ||
1735 | |||
1736 | // Checked: 2009-07-12 (RLVa-1.0.0h) | ||
1737 | class RlvSharedRootFetcher : public LLInventoryFetchDescendentsObserver | ||
1738 | { | ||
1739 | public: | ||
1740 | RlvSharedRootFetcher() {} | ||
1741 | |||
1742 | virtual void done() | ||
1743 | { | ||
1744 | RLV_INFOS << "Shared folders fetch completed" << LL_ENDL; | ||
1745 | RlvHandler::m_fFetchComplete = TRUE; | ||
1746 | |||
1747 | gInventory.removeObserver(this); | ||
1748 | delete this; | ||
1749 | } | ||
1750 | }; | ||
1751 | |||
1752 | // Checked: 2009-07-12 (RLVa-1.0.0h) | ||
1753 | void RlvHandler::fetchSharedInventory() | ||
1754 | { | ||
1755 | // Sanity check - don't fetch if we're already fetching, or if we don't have a shared root | ||
1756 | LLViewerInventoryCategory* pRlvRoot = getSharedRoot(); | ||
1757 | if ( (m_fFetchStarted) || (!pRlvRoot) ) | ||
1758 | return; | ||
1759 | |||
1760 | // Grab all the folders under the shared root | ||
1761 | LLInventoryModel::cat_array_t folders; | ||
1762 | LLInventoryModel::item_array_t items; | ||
1763 | gInventory.collectDescendents(pRlvRoot->getUUID(), folders, items, FALSE); | ||
1764 | |||
1765 | /* | ||
1766 | * Add them to the "to fetch" list | ||
1767 | */ | ||
1768 | LLInventoryFetchDescendentsObserver::folder_ref_t fetchFolders; | ||
1769 | |||
1770 | fetchFolders.push_back(pRlvRoot->getUUID()); | ||
1771 | for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++) | ||
1772 | fetchFolders.push_back(folders.get(idxFolder)->getUUID()); | ||
1773 | |||
1774 | /* | ||
1775 | * Now fetch them all in one go | ||
1776 | */ | ||
1777 | RlvSharedRootFetcher* fetcher = new RlvSharedRootFetcher; | ||
1778 | |||
1779 | RLV_INFOS << "Starting fetch of " << fetchFolders.size() << " shared folders" << LL_ENDL; | ||
1780 | fetcher->fetchDescendents(fetchFolders); | ||
1781 | |||
1782 | if (fetcher->isEverythingComplete()) | ||
1783 | fetcher->done(); | ||
1784 | else | ||
1785 | gInventory.addObserver(fetcher); | ||
1786 | } | ||
1787 | |||
1788 | bool RlvHandler::findSharedFolders(const std::string& strCriteria, LLInventoryModel::cat_array_t& folders) const | ||
1789 | { | ||
1790 | // Sanity check - can't do anything without a shared root | ||
1791 | LLViewerInventoryCategory* pRlvRoot = getSharedRoot(); | ||
1792 | if (!pRlvRoot) | ||
1793 | return false; | ||
1794 | |||
1795 | folders.clear(); | ||
1796 | LLInventoryModel::item_array_t items; | ||
1797 | RlvCriteriaCategoryCollector functor(strCriteria); | ||
1798 | gInventory.collectDescendentsIf(pRlvRoot->getUUID(), folders, items, FALSE, functor); | ||
1799 | |||
1800 | return (folders.count() != 0); | ||
1801 | } | ||
1802 | |||
1803 | // Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0e | ||
1804 | LLViewerInventoryCategory* RlvHandler::getSharedRoot() | ||
1805 | { | ||
1806 | if (gInventory.isInventoryUsable()) | ||
1807 | { | ||
1808 | LLInventoryModel::cat_array_t* pFolders; | ||
1809 | LLInventoryModel::item_array_t* pItems; | ||
1810 | gInventory.getDirectDescendentsOf(gAgent.getInventoryRootID(), pFolders, pItems); | ||
1811 | if (pFolders) | ||
1812 | { | ||
1813 | // NOTE: we might have multiple #RLV folders so we'll just go with the first one we come across | ||
1814 | LLViewerInventoryCategory* pFolder; | ||
1815 | for (S32 idxFolder = 0, cntFolder = pFolders->count(); idxFolder < cntFolder; idxFolder++) | ||
1816 | { | ||
1817 | if ( ((pFolder = pFolders->get(idxFolder)) != NULL) && (RlvHandler::cstrSharedRoot == pFolder->getName()) ) | ||
1818 | return pFolder; | ||
1819 | } | ||
1820 | } | ||
1821 | } | ||
1822 | return NULL; | ||
1823 | } | ||
1824 | |||
1825 | // Checked: 2009-07-28 (RLVa-1.0.1a) | Modified: RLVa-1.0.1a | ||
1826 | LLViewerInventoryCategory* RlvHandler::getSharedFolder(const LLUUID& idParent, const std::string& strFolderName) const | ||
1827 | { | ||
1828 | LLInventoryModel::cat_array_t* pFolders; | ||
1829 | LLInventoryModel::item_array_t* pItems; | ||
1830 | gInventory.getDirectDescendentsOf(idParent, pFolders, pItems); | ||
1831 | if ( (!pFolders) || (strFolderName.empty()) ) | ||
1832 | return NULL; | ||
1833 | |||
1834 | // If we can't find an exact match then we'll settle for a "contains" match | ||
1835 | LLViewerInventoryCategory* pPartial = NULL; | ||
1836 | |||
1837 | //LLStringUtil::toLower(strFolderName); <- everything was already converted to lower case before | ||
1838 | |||
1839 | std::string strName; | ||
1840 | for (S32 idxFolder = 0, cntFolder = pFolders->count(); idxFolder < cntFolder; idxFolder++) | ||
1841 | { | ||
1842 | LLViewerInventoryCategory* pFolder = pFolders->get(idxFolder); | ||
1843 | |||
1844 | strName = pFolder->getName(); | ||
1845 | if (strName.empty()) | ||
1846 | continue; | ||
1847 | LLStringUtil::toLower(strName); | ||
1848 | |||
1849 | if (strFolderName == strName) | ||
1850 | return pFolder; // Found an exact match, no need to keep on going | ||
1851 | else if ( (!pPartial) && (RLV_FOLDER_PREFIX_HIDDEN != strName[0]) && (strName.find(strFolderName) != std::string::npos) ) | ||
1852 | pPartial = pFolder; // Found a partial (non-hidden) match, but we might still find an exact one (first partial match wins) | ||
1853 | } | ||
1854 | |||
1855 | return pPartial; | ||
1856 | } | ||
1857 | |||
1858 | // Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0e | ||
1859 | LLViewerInventoryCategory* RlvHandler::getSharedFolder(const std::string& strPath) const | ||
1860 | { | ||
1861 | // Sanity check - no shared root => no shared folder | ||
1862 | LLViewerInventoryCategory* pRlvRoot = getSharedRoot(), *pFolder = pRlvRoot; | ||
1863 | if (!pRlvRoot) | ||
1864 | return NULL; | ||
1865 | |||
1866 | // Walk the path (starting at the root) | ||
1867 | typedef boost::tokenizer<boost::char_separator<char> > tokenizer; | ||
1868 | boost::char_separator<char> sep("/", "", boost::drop_empty_tokens); | ||
1869 | tokenizer tokens(strPath, sep); | ||
1870 | for (tokenizer::iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken) | ||
1871 | { | ||
1872 | pFolder = getSharedFolder(pFolder->getUUID(), *itToken); | ||
1873 | if (!pFolder) | ||
1874 | return NULL; // No such folder | ||
1875 | } | ||
1876 | |||
1877 | return pFolder; // If strPath was empty or just a bunch of //// then: pFolder == pRlvRoot | ||
1878 | } | ||
1879 | |||
1880 | // Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0g | ||
1881 | std::string RlvHandler::getSharedPath(const LLViewerInventoryCategory* pFolder) const | ||
1882 | { | ||
1883 | LLViewerInventoryCategory* pRlvRoot = getSharedRoot(); | ||
1884 | // Sanity check - no shared root or no folder => no path | ||
1885 | if ( (!pRlvRoot) || (!pFolder) || (pRlvRoot->getUUID() == pFolder->getUUID()) ) | ||
1886 | return std::string(); | ||
1887 | |||
1888 | const LLUUID& idRLV = pRlvRoot->getUUID(); | ||
1889 | const LLUUID& idRoot = gAgent.getInventoryRootID(); | ||
1890 | std::string strPath; | ||
1891 | |||
1892 | // Walk up the tree until we reach the top | ||
1893 | while (pFolder) | ||
1894 | { | ||
1895 | strPath = "/" + pFolder->getName() + strPath; | ||
1896 | |||
1897 | const LLUUID& idParent = pFolder->getParentUUID(); | ||
1898 | if (idRLV == idParent) // Reached the shared root, we're done | ||
1899 | break; | ||
1900 | else if (idRoot == idParent) // We reached the agent's inventory root (indicative of a logic error elsewhere) | ||
1901 | { | ||
1902 | RLV_ERRS << "Reached agent's inventory root while building path for shared folder" << LL_ENDL; | ||
1903 | return std::string(); | ||
1904 | } | ||
1905 | else | ||
1906 | pFolder = gInventory.getCategory(idParent); | ||
1907 | } | ||
1908 | |||
1909 | return strPath.erase(0, 1); | ||
1910 | } | ||
1911 | |||
1912 | // ============================================================================ | ||
1913 | // Composite folders | ||
1914 | // | ||
1915 | |||
1916 | #ifdef RLV_EXPERIMENTAL_COMPOSITES | ||
1917 | // Checked: | ||
1918 | bool RlvHandler::getCompositeInfo(const LLInventoryCategory* pFolder, std::string* pstrName) const | ||
1919 | { | ||
1920 | if (pFolder) | ||
1921 | { | ||
1922 | // Composite folder naming: ^\.?[Folder] | ||
1923 | const std::string& cstrFolder = pFolder->getName(); | ||
1924 | int idxStart = cstrFolder.find('['), idxEnd = cstrFolder.find(']', idxStart); | ||
1925 | if ( ((0 == idxStart) || (1 == idxStart)) && (idxEnd - idxStart > 1) ) | ||
1926 | { | ||
1927 | if (pstrName) | ||
1928 | pstrName->assign(cstrFolder.substr(idxStart + 1, idxEnd - idxStart - 1)); | ||
1929 | return true; | ||
1930 | } | ||
1931 | } | ||
1932 | return false; | ||
1933 | } | ||
1934 | |||
1935 | // Checked: | ||
1936 | bool RlvHandler::getCompositeInfo(const LLUUID& idItem, std::string* pstrName, LLViewerInventoryCategory** ppFolder) const | ||
1937 | { | ||
1938 | LLViewerInventoryCategory* pRlvRoot; LLViewerInventoryItem* pItem; | ||
1939 | |||
1940 | if ( (idItem.notNull()) && ((pRlvRoot = getSharedRoot()) != NULL) && | ||
1941 | (gInventory.isObjectDescendentOf(idItem, pRlvRoot->getUUID())) && ((pItem = gInventory.getItem(idItem)) != NULL) ) | ||
1942 | { | ||
1943 | // We know it's an item in a folder under the shared root... | ||
1944 | LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID()); | ||
1945 | if (getAttachPoint(pFolder, true)) | ||
1946 | { | ||
1947 | // ... but it could be named ".(attachpt)" in which case we need its parent | ||
1948 | pFolder = gInventory.getCategory(pFolder->getParentUUID()); | ||
1949 | } | ||
1950 | |||
1951 | if ( (pFolder) && (getCompositeInfo(pFolder, pstrName)) ) | ||
1952 | { | ||
1953 | if (ppFolder) | ||
1954 | *ppFolder = pFolder; | ||
1955 | return true; | ||
1956 | } | ||
1957 | } | ||
1958 | return false; | ||
1959 | } | ||
1960 | #endif // RLV_EXPERIMENTAL_COMPOSITES | ||
1961 | |||
1962 | #ifdef RLV_EXPERIMENTAL_COMPOSITE_FOLDING | ||
1963 | // Checked: | ||
1964 | inline bool RlvHandler::isHiddenCompositeItem(const LLUUID& idItem, const std::string& cstrItemType) const | ||
1965 | { | ||
1966 | // An item that's part of a composite folder will be hidden from @getoutfit and @getattach if: | ||
1967 | // (1) the composite name specifies either a wearable layer or an attachment point | ||
1968 | // (2) the specified wearable layer or attachment point is worn and resides in the folder | ||
1969 | // (3) cstrItemType isn't the specified wearable layer or attach point | ||
1970 | // | ||
1971 | // Example: #RLV/Separates/Shoes/ChiChi Pumps/.[shoes] with items: "Shoe Base", "Shoe (left foot)" and "Shoe (right foot)" | ||
1972 | // -> as long as "Shoe Base" is worn, @getattach should not reflect "left foot", nor "right foot" | ||
1973 | std::string strComposite; LLViewerInventoryCategory* pFolder; | ||
1974 | EWearableType type; S32 idxAttachPt; | ||
1975 | if ( (getCompositeInfo(idItem, &strComposite, &pFolder)) && (cstrItemType != strComposite) ) | ||
1976 | { | ||
1977 | LLUUID idCompositeItem; | ||
1978 | if ((type = LLWearable::typeNameToType(strComposite)) != WT_INVALID) | ||
1979 | { | ||
1980 | idCompositeItem = gAgent.getWearableItem(type); | ||
1981 | } | ||
1982 | else if ((idxAttachPt = getAttachPointIndex(strComposite, true)) != 0) | ||
1983 | { | ||
1984 | LLVOAvatar* pAvatar; LLViewerJointAttachment* pAttachmentPt; | ||
1985 | if ( ((pAvatar = gAgent.getAvatarObject()) != NULL) && | ||
1986 | ((pAttachmentPt = get_if_there(pAvatar->mAttachmentPoints, idxAttachPt, (LLViewerJointAttachment*)NULL)) != NULL) ) | ||
1987 | { | ||
1988 | idCompositeItem = pAttachmentPt->getItemID(); | ||
1989 | } | ||
1990 | } | ||
1991 | |||
1992 | if ( (idCompositeItem.notNull()) && (gInventory.isObjectDescendentOf(idCompositeItem, pFolder->getUUID())) ) | ||
1993 | return true; | ||
1994 | } | ||
1995 | return false; | ||
1996 | } | ||
1997 | #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDING | ||
1998 | |||
1999 | #ifdef RLV_EXPERIMENTAL_COMPOSITE_LOCKING | ||
2000 | // Checked: | ||
2001 | bool RlvHandler::canTakeOffComposite(const LLInventoryCategory* pFolder) const | ||
2002 | { | ||
2003 | if (!pFolder) // If there's no folder then there is nothing to take off | ||
2004 | return false; | ||
2005 | |||
2006 | LLInventoryModel::cat_array_t folders; | ||
2007 | LLInventoryModel::item_array_t items; | ||
2008 | RlvWearableItemCollector functor(pFolder->getUUID(), true, false); | ||
2009 | |||
2010 | // Grab a list of all the items @detachthis would be detaching/unwearing | ||
2011 | gInventory.collectDescendentsIf(pFolder->getUUID(), folders, items, FALSE, functor); | ||
2012 | if (!items.count()) | ||
2013 | return false; // There are no wearable items in the folder so there is nothing to take off | ||
2014 | |||
2015 | LLViewerInventoryItem* pItem; | ||
2016 | for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++) | ||
2017 | { | ||
2018 | pItem = items.get(idxItem); | ||
2019 | |||
2020 | switch (pItem->getType()) | ||
2021 | { | ||
2022 | case LLAssetType::AT_CLOTHING: | ||
2023 | { | ||
2024 | LLWearable* pWearable = gAgent.getWearableFromWearableItem(pItem->getUUID()); | ||
2025 | if ( (pWearable) && (!isRemovable(pWearable->getType())) ) | ||
2026 | return false; // If one clothing layer in the composite folder is unremoveable then the entire folder is | ||
2027 | } | ||
2028 | break; | ||
2029 | case LLAssetType::AT_OBJECT: | ||
2030 | { | ||
2031 | LLVOAvatar* pAvatar; LLViewerObject* pObj; | ||
2032 | if ( ((pAvatar = gAgent.getAvatarObject()) != NULL) && | ||
2033 | ((pObj = pAvatar->getWornAttachment(pItem->getUUID())) != NULL) && (!isDetachable(pObj)) ) | ||
2034 | { | ||
2035 | return false; // If one attachment in the composite folder is undetachable then the entire folder is | ||
2036 | } | ||
2037 | } | ||
2038 | break; | ||
2039 | #ifdef LL_GNUC | ||
2040 | default: | ||
2041 | break; | ||
2042 | #endif // LL_GNUC | ||
2043 | } | ||
2044 | } | ||
2045 | return true; | ||
2046 | } | ||
2047 | #endif // RLV_EXPERIMENTAL_COMPOSITE_LOCKING | ||
2048 | |||
2049 | // ============================================================================ | ||
2050 | // Event handlers | ||
2051 | // | ||
2052 | |||
2053 | // Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0d | ||
2054 | void RlvHandler::onForceDetach(const LLUUID& idObj, const std::string& strOption) const | ||
2055 | { | ||
2056 | U16 nParam; | ||
2057 | if (strOption.empty()) | ||
2058 | { | ||
2059 | // Simulate right-click / Take Off > Detach All | ||
2060 | LLAgent::userRemoveAllAttachments(NULL); | ||
2061 | } | ||
2062 | else if (m_AttachLookup.getExactMatchParam(strOption, nParam)) | ||
2063 | { | ||
2064 | // Simulate right-click / Take Off > Detach > ... | ||
2065 | LLVOAvatar* pAvatar; LLViewerJointAttachment* pAttachmentPt; | ||
2066 | if ( ((pAvatar = gAgent.getAvatarObject()) != NULL) && // Make sure we're actually wearing something on the attachment point | ||
2067 | ((pAttachmentPt = get_if_there(pAvatar->mAttachmentPoints, (S32)nParam, (LLViewerJointAttachment*)NULL)) != NULL) && | ||
2068 | (isStrippable(pAttachmentPt->getItemID())) ) // ... and that it's not marked as "nostrip" | ||
2069 | { | ||
2070 | #ifdef RLV_EXPERIMENTAL_COMPOSITES | ||
2071 | // If we're stripping something that's part of a composite folder then we should @detachthis instead | ||
2072 | if (isCompositeDescendent(pAttachmentPt->getItemID())) | ||
2073 | { | ||
2074 | std::string strCmd = "detachthis:" + strOption + "=force"; | ||
2075 | #ifdef RLV_DEBUG | ||
2076 | RLV_INFOS << "\t- '" << strOption << "' belongs to composite folder: @" << strCmd << LL_ENDL; | ||
2077 | #endif // RLV_DEBUG | ||
2078 | processForceCommand(idObj, RlvCommand(strCmd)); | ||
2079 | } | ||
2080 | else | ||
2081 | #endif // RLV_EXPERIMENTAL_COMPOSITES | ||
2082 | { | ||
2083 | handle_detach_from_avatar(pAttachmentPt); | ||
2084 | } | ||
2085 | } | ||
2086 | } | ||
2087 | else | ||
2088 | { | ||
2089 | // Force detach single folder | ||
2090 | onForceWear(strOption, false, false); | ||
2091 | } | ||
2092 | } | ||
2093 | |||
2094 | // Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0d | ||
2095 | void RlvHandler::onForceRemOutfit(const LLUUID& idObj, const std::string& strOption) const | ||
2096 | { | ||
2097 | EWearableType typeOption = LLWearable::typeNameToType(strOption), type; | ||
2098 | if ( (WT_INVALID == typeOption) && (!strOption.empty()) ) | ||
2099 | return; | ||
2100 | |||
2101 | // Before we had an option and optionless branch, but with the addition of composites and nostrip there's less duplication this way | ||
2102 | for (int idxType = 0; idxType < WT_COUNT; idxType++) | ||
2103 | { | ||
2104 | type = (EWearableType)idxType; | ||
2105 | |||
2106 | // Only strip clothing (that's currently worn and not marked "nostrip") | ||
2107 | if ( (LLAssetType::AT_CLOTHING != LLWearable::typeToAssetType(type)) || | ||
2108 | (!gAgent.getWearable(type)) || (!isStrippable(gAgent.getWearableItem(type))) ) | ||
2109 | { | ||
2110 | continue; | ||
2111 | } | ||
2112 | |||
2113 | if ( (typeOption == type) || (strOption.empty()) ) | ||
2114 | { | ||
2115 | #ifdef RLV_EXPERIMENTAL_COMPOSITES | ||
2116 | // If we're stripping something that's part of a composite folder then we should @detachthis instead | ||
2117 | if (isCompositeDescendent(gAgent.getWearableItem(type))) | ||
2118 | { | ||
2119 | std::string strCmd = "detachthis:" + LLWearable::typeToTypeName(type) + "=force"; | ||
2120 | #ifdef RLV_DEBUG | ||
2121 | RLV_INFOS << "\t- '" << LLWearable::typeToTypeName(type) << "' is composite descendent: @" << strCmd << LL_ENDL; | ||
2122 | #endif // RLV_DEBUG | ||
2123 | processForceCommand(idObj, RlvCommand(strCmd)); | ||
2124 | } | ||
2125 | else | ||
2126 | #endif // RLV_EXPERIMENTAL_COMPOSITES | ||
2127 | { | ||
2128 | gAgent.removeWearable(type); | ||
2129 | } | ||
2130 | } | ||
2131 | } | ||
2132 | } | ||
2133 | |||
2134 | // Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0g | ||
2135 | bool RlvHandler::onForceSit(const LLUUID& idObj, const std::string& strOption) const | ||
2136 | { | ||
2137 | LLViewerObject* pObject = NULL; LLUUID idTarget(strOption); | ||
2138 | // Sanity checking - we need to know about the object and it should identify a prim/linkset | ||
2139 | if ( (idTarget.isNull()) || ((pObject = gObjectList.findObject(idTarget)) == NULL) || (LL_PCODE_VOLUME != pObject->getPCode()) ) | ||
2140 | return false; | ||
2141 | |||
2142 | // Don't force sit if: | ||
2143 | // 1) currently sitting and prevented from standing up | ||
2144 | // 2) prevented from sitting | ||
2145 | // 3) @sittp=n restricted (except if @sittp=n was issued by the same prim that's currently force sitting the avie) | ||
2146 | if ( ( (hasBehaviour(RLV_BHVR_UNSIT)) && (gAgent.getAvatarObject()) && (gAgent.getAvatarObject()->mIsSitting) ) || | ||
2147 | ( (hasBehaviour(RLV_BHVR_SIT)) ) || | ||
2148 | ( (hasBehaviourExcept(RLV_BHVR_SITTP, idObj)) && | ||
2149 | (dist_vec_squared(gAgent.getPositionGlobal(), pObject->getPositionGlobal()) > 1.5f * 1.5f) )) | ||
2150 | { | ||
2151 | return false; | ||
2152 | } | ||
2153 | |||
2154 | // Copy/paste from handle_sit_or_stand() [see http://wiki.secondlife.com/wiki/AgentRequestSit] | ||
2155 | gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit); | ||
2156 | gMessageSystem->nextBlockFast(_PREHASH_AgentData); | ||
2157 | gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); | ||
2158 | gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | ||
2159 | gMessageSystem->nextBlockFast(_PREHASH_TargetObject); | ||
2160 | gMessageSystem->addUUIDFast(_PREHASH_TargetID, pObject->mID); | ||
2161 | // Offset: "a rough position in local coordinates for the edge to sit on" | ||
2162 | // (we might not even be looking at the object so I don't think we can supply the offset to an edge) | ||
2163 | gMessageSystem->addVector3Fast(_PREHASH_Offset, LLVector3::zero); | ||
2164 | pObject->getRegion()->sendReliableMessage(); | ||
2165 | |||
2166 | return true; | ||
2167 | } | ||
2168 | |||
2169 | void RlvHandler::onForceWear(const std::string& strPath, bool fAttach, bool fMatchAll) const | ||
2170 | { | ||
2171 | // See LLWearableBridge::wearOnAvatar(): don't wear anything until initial wearables are loaded, can destroy clothing items | ||
2172 | if (!gAgent.areWearablesLoaded()) | ||
2173 | return; | ||
2174 | |||
2175 | LLViewerInventoryCategory* pFolder = getSharedFolder(strPath); | ||
2176 | if (!pFolder) // Folder not found = nothing to attach | ||
2177 | return; | ||
2178 | |||
2179 | LLInventoryModel::cat_array_t folders; | ||
2180 | LLInventoryModel::item_array_t items; | ||
2181 | RlvWearableItemCollector functor(pFolder->getUUID(), fAttach, fMatchAll); | ||
2182 | |||
2183 | // Grab a list of all the items we'll be wearing/attaching | ||
2184 | gInventory.collectDescendentsIf(pFolder->getUUID(), folders, items, FALSE, functor); | ||
2185 | |||
2186 | LLViewerInventoryItem* pItem; | ||
2187 | for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++) | ||
2188 | { | ||
2189 | pItem = items.get(idxItem); | ||
2190 | |||
2191 | switch (pItem->getType()) | ||
2192 | { | ||
2193 | case LLAssetType::AT_CLOTHING: | ||
2194 | case LLAssetType::AT_BODYPART: | ||
2195 | { | ||
2196 | LLWearable* pWearable = gAgent.getWearableFromWearableItem(pItem->getUUID()); | ||
2197 | |||
2198 | #ifdef RLV_EXPERIMENTAL_COMPOSITE_LOCKING | ||
2199 | // If we're already wearing something on this layer then we have to check if it isn't part of a composite | ||
2200 | // folder that has at least one unremovable item (in which case we can't wear or remove this item) | ||
2201 | LLViewerInventoryCategory* pCompositeFolder; | ||
2202 | if ( (!pWearable) || (!getCompositeInfo(pItem->getUUID(), NULL, &pCompositeFolder)) || | ||
2203 | (canTakeOffComposite(pFolder))) | ||
2204 | { | ||
2205 | #endif // RLV_EXPERIMENTAL_COMPOSITE_LOCKING | ||
2206 | if (fAttach) | ||
2207 | { | ||
2208 | // Simulate wearing a clothing item from inventory (right click / "Wear") | ||
2209 | // LLWearableBridge::performAction() => LLWearableBridge::wearOnAvatar() => wear_inventory_item_on_avatar() | ||
2210 | wear_inventory_item_on_avatar(pItem); | ||
2211 | } | ||
2212 | else | ||
2213 | { | ||
2214 | if ( (pWearable) && (LLAssetType::AT_CLOTHING == pItem->getType()) ) | ||
2215 | gAgent.removeWearable(pWearable->getType()); | ||
2216 | } | ||
2217 | #ifdef RLV_EXPERIMENTAL_COMPOSITE_LOCKING | ||
2218 | } | ||
2219 | #endif // RLV_EXPERIMENTAL_COMPOSITE_LOCKING | ||
2220 | } | ||
2221 | break; | ||
2222 | case LLAssetType::AT_OBJECT: | ||
2223 | { | ||
2224 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | ||
2225 | LLViewerObject* pObj; | ||
2226 | |||
2227 | #ifdef RLV_EXPERIMENTAL_COMPOSITE_LOCKING | ||
2228 | // If we're already wearing something on this attach point then we have to check if it isn't part of a composite | ||
2229 | // folder that has at least one unremovable item (in which case we can't attach or detach this item) | ||
2230 | LLViewerInventoryCategory* pCompositeFolder; | ||
2231 | if ( (pAvatar) && | ||
2232 | ( ((pObj = pAvatar->getWornAttachment(pItem->getUUID())) == NULL) || | ||
2233 | (!getCompositeInfo(pItem->getUUID(), NULL, &pCompositeFolder)) || (canTakeOffComposite(pFolder)) ) ) | ||
2234 | { | ||
2235 | #endif // RLV_EXPERIMENTAL_COMPOSITE_LOCKING | ||
2236 | if (fAttach) | ||
2237 | { | ||
2238 | // Simulate wearing an object to a specific attachment point (copy/paste to suppress replacement dialog) | ||
2239 | // LLAttachObject::handleEvent() => rez_attachment() | ||
2240 | LLViewerJointAttachment* pAttachPt = getAttachPoint(pItem, true); | ||
2241 | if ( (pAttachPt) && (isDetachable(pAttachPt->getObject())) ) | ||
2242 | { | ||
2243 | #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 | ||
2244 | LLAttachmentRezAction* rez_action = new LLAttachmentRezAction; | ||
2245 | rez_action->mItemID = pItem->getUUID(); | ||
2246 | rez_action->mAttachPt = getAttachPointIndex(pAttachPt->getName(), true); | ||
2247 | |||
2248 | confirm_replace_attachment_rez(0/*YES*/, (void*)rez_action); // (Will call delete on rez_action) | ||
2249 | #else // Version: 1.23.4 | ||
2250 | LLSD payload; | ||
2251 | payload["item_id"] = pItem->getUUID(); | ||
2252 | payload["attachment_point"] = getAttachPointIndex(pAttachPt->getName(), true); | ||
2253 | |||
2254 | LLNotifications::instance().forceResponse( | ||
2255 | LLNotification::Params("ReplaceAttachment").payload(payload), 0/*YES*/); | ||
2256 | #endif | ||
2257 | } | ||
2258 | } | ||
2259 | else | ||
2260 | { | ||
2261 | if ( (pAvatar) && ((pObj = pAvatar->getWornAttachment(pItem->getUUID())) != NULL) ) | ||
2262 | { | ||
2263 | LLViewerJointAttachment* pAttachment = pAvatar->getTargetAttachmentPoint(pObj); | ||
2264 | if (pAttachment) | ||
2265 | handle_detach_from_avatar(pAttachment); | ||
2266 | } | ||
2267 | } | ||
2268 | #ifdef RLV_EXPERIMENTAL_COMPOSITE_LOCKING | ||
2269 | } | ||
2270 | #endif // RLV_EXPERIMENTAL_COMPOSITE_LOCKING | ||
2271 | } | ||
2272 | break; | ||
2273 | #ifdef LL_GNUC | ||
2274 | default: | ||
2275 | break; | ||
2276 | #endif // LL_GNUC | ||
2277 | } | ||
2278 | } | ||
2279 | } | ||
2280 | |||
2281 | // Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0g | ||
2282 | bool RlvHandler::onGetPath(const LLUUID &uuid, const std::string& strOption, std::string& strReply) const | ||
2283 | { | ||
2284 | // Sanity check - no need to go through all this trouble if we don't have a shared root | ||
2285 | LLViewerInventoryCategory* pRlvRoot = getSharedRoot(); | ||
2286 | if (!pRlvRoot) | ||
2287 | return false; | ||
2288 | |||
2289 | LLUUID idItem; | ||
2290 | |||
2291 | // <option> can be a clothing layer | ||
2292 | EWearableType layerType = LLWearable::typeNameToType(strOption); | ||
2293 | if (WT_INVALID != layerType) | ||
2294 | { | ||
2295 | idItem = gAgent.getWearableItem(layerType); | ||
2296 | } | ||
2297 | else | ||
2298 | { | ||
2299 | LLViewerJointAttachment* pAttachPt = NULL; | ||
2300 | |||
2301 | // ... or it can be empty | ||
2302 | if (strOption.empty()) | ||
2303 | { | ||
2304 | // (in which case we act on the object that issued the command) | ||
2305 | LLViewerObject* pObj = gObjectList.findObject(uuid); | ||
2306 | if ( (pObj) && (pObj->isAttachment()) && (gAgent.getAvatarObject()) ) | ||
2307 | pAttachPt = gAgent.getAvatarObject()->getTargetAttachmentPoint(pObj); | ||
2308 | } | ||
2309 | else | ||
2310 | { | ||
2311 | // ... or it can specify an attach point | ||
2312 | pAttachPt = getAttachPoint(strOption, true); | ||
2313 | } | ||
2314 | |||
2315 | // If we found something, get its inventory item UUID | ||
2316 | if (pAttachPt) | ||
2317 | idItem = pAttachPt->getItemID(); | ||
2318 | } | ||
2319 | |||
2320 | // If we found something and it's under the shared root, then get its path | ||
2321 | if ( (!idItem.isNull()) && (gInventory.isObjectDescendentOf(idItem, pRlvRoot->getUUID())) ) | ||
2322 | { | ||
2323 | LLInventoryItem* pItem = gInventory.getItem(idItem); | ||
2324 | if (pItem) | ||
2325 | { | ||
2326 | // ... unless the containing folder's name specifies an attach point (or nostrip) in which case we need its parent | ||
2327 | LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID()); | ||
2328 | #ifdef RLV_EXTENSION_FLAG_NOSTRIP | ||
2329 | if ( (getAttachPoint(pFolder, true)) || (pFolder->getName() == ".("RLV_FOLDER_FLAG_NOSTRIP")") ) | ||
2330 | #else | ||
2331 | if (getAttachPoint(pFolder, true)) | ||
2332 | #endif // RLV_EXTENSION_FLAG_NOSTRIP | ||
2333 | strReply = getSharedPath(pFolder->getParentUUID()); | ||
2334 | else | ||
2335 | strReply = getSharedPath(pFolder); | ||
2336 | } | ||
2337 | } | ||
2338 | return !strReply.empty(); | ||
2339 | } | ||
2340 | |||
2341 | struct rlv_wear_info { U32 cntWorn, cntTotal, cntChildWorn, cntChildTotal; }; | ||
2342 | |||
2343 | // Checked: 2009-05-30 (RLVa-0.2.0e) | Modified: RLVa-0.2.0e | ||
2344 | void RlvHandler::onGetInvWorn(const std::string& strPath, std::string& strReply) const | ||
2345 | { | ||
2346 | // Sanity check - getAvatarObject() can't be NULL [see rlvIsWearingItem()] and the folder should exist and not be hidden | ||
2347 | LLViewerInventoryCategory* pFolder = getSharedFolder(strPath); | ||
2348 | if ((!gAgent.getAvatarObject()) || (!pFolder) || (pFolder->getName().empty()) || (RLV_FOLDER_PREFIX_HIDDEN == pFolder->getName()[0])) | ||
2349 | return; | ||
2350 | |||
2351 | // Collect everything @attachall would be attaching | ||
2352 | LLInventoryModel::cat_array_t folders; | ||
2353 | LLInventoryModel::item_array_t items; | ||
2354 | RlvWearableItemCollector functor(pFolder->getUUID(), true, true); | ||
2355 | gInventory.collectDescendentsIf(pFolder->getUUID(), folders, items, FALSE, functor); | ||
2356 | |||
2357 | rlv_wear_info wi = {0}; | ||
2358 | |||
2359 | // Add all the folders to a lookup map | ||
2360 | std::map<LLUUID, rlv_wear_info> mapFolders; | ||
2361 | mapFolders.insert(std::pair<LLUUID, rlv_wear_info>(pFolder->getUUID(), wi)); | ||
2362 | for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++) | ||
2363 | mapFolders.insert(std::pair<LLUUID, rlv_wear_info>(folders.get(idxFolder)->getUUID(), wi)); | ||
2364 | |||
2365 | // Iterate over all the found items | ||
2366 | LLViewerInventoryItem* pItem; std::map<LLUUID, rlv_wear_info>::iterator itFolder; | ||
2367 | for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++) | ||
2368 | { | ||
2369 | pItem = items.get(idxItem); | ||
2370 | |||
2371 | // The "folded parent" is the folder this item should be considered a direct descendent of (may or may not match actual parent) | ||
2372 | const LLUUID& idParent = functor.getFoldedParent(pItem->getParentUUID()); | ||
2373 | |||
2374 | // Walk up the tree: sooner or later one of the parents will be a folder in the map | ||
2375 | LLViewerInventoryCategory* pParent = gInventory.getCategory(idParent); | ||
2376 | while ( (itFolder = mapFolders.find(pParent->getUUID())) == mapFolders.end() ) | ||
2377 | pParent = gInventory.getCategory(pParent->getParentUUID()); | ||
2378 | |||
2379 | U32 &cntWorn = (idParent == pParent->getUUID()) ? itFolder->second.cntWorn : itFolder->second.cntChildWorn, | ||
2380 | &cntTotal = (idParent == pParent->getUUID()) ? itFolder->second.cntTotal : itFolder->second.cntChildTotal; | ||
2381 | |||
2382 | if (rlvIsWearingItem(pItem)) | ||
2383 | cntWorn++; | ||
2384 | cntTotal++; | ||
2385 | } | ||
2386 | |||
2387 | // Extract the result for the main folder | ||
2388 | itFolder = mapFolders.find(pFolder->getUUID()); | ||
2389 | wi.cntWorn = itFolder->second.cntWorn; | ||
2390 | wi.cntTotal = itFolder->second.cntTotal; | ||
2391 | mapFolders.erase(itFolder); | ||
2392 | |||
2393 | // Build the result for each child folder | ||
2394 | for (itFolder = mapFolders.begin(); itFolder != mapFolders.end(); ++itFolder) | ||
2395 | { | ||
2396 | rlv_wear_info& wiFolder = itFolder->second; | ||
2397 | |||
2398 | wi.cntChildWorn += wiFolder.cntWorn + wiFolder.cntChildWorn; | ||
2399 | wi.cntChildTotal += wiFolder.cntTotal + wiFolder.cntChildTotal; | ||
2400 | |||
2401 | strReply += llformat(",%s|%d%d", gInventory.getCategory(itFolder->first)->getName().c_str(), | ||
2402 | (0 == wiFolder.cntTotal) ? 0 : (0 == wiFolder.cntWorn) ? 1 : (wiFolder.cntWorn != wiFolder.cntTotal) ? 2 : 3, | ||
2403 | (0 == wiFolder.cntChildTotal) ? 0 : (0 == wiFolder.cntChildWorn) ? 1 : (wiFolder.cntChildWorn != wiFolder.cntChildTotal) ? 2 : 3 | ||
2404 | ); | ||
2405 | } | ||
2406 | |||
2407 | // Now just prepend the root and done | ||
2408 | strReply = llformat("|%d%d", (0 == wi.cntTotal) ? 0 : (0 == wi.cntWorn) ? 1 : (wi.cntWorn != wi.cntTotal) ? 2 : 3, | ||
2409 | (0 == wi.cntChildTotal) ? 0 : (0 == wi.cntChildWorn) ? 1 : (wi.cntChildWorn != wi.cntChildTotal) ? 2: 3) + strReply; | ||
2410 | } | ||
2411 | |||
2412 | // (In case anyone cares: this isn't used in public builds) | ||
2413 | bool RlvHandler::getWornInfo(const LLInventoryCategory* pFolder, U8& wiFolder, U8& wiChildren) const | ||
2414 | { | ||
2415 | // Sanity check - getAvatarObject() can't be NULL [see rlvIsWearingItem()] and the folder should exist and not be hidden | ||
2416 | if ((!gAgent.getAvatarObject()) || (!pFolder) || (pFolder->getName().empty()) || (RLV_FOLDER_PREFIX_HIDDEN == pFolder->getName()[0])) | ||
2417 | return false; | ||
2418 | |||
2419 | LLInventoryModel::cat_array_t folders; | ||
2420 | LLInventoryModel::item_array_t items; | ||
2421 | RlvWearableItemCollector functor(pFolder->getUUID(), true, true); | ||
2422 | gInventory.collectDescendentsIf(pFolder->getUUID(), folders, items, FALSE, functor); | ||
2423 | |||
2424 | LLViewerInventoryItem* pItem; | ||
2425 | U32 cntWorn = 0, cntTotal = 0, cntChildWorn = 0, cntChildTotal = 0; | ||
2426 | for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++) | ||
2427 | { | ||
2428 | pItem = items.get(idxItem); | ||
2429 | |||
2430 | bool fDirectDescendent = (pFolder->getUUID() == functor.getFoldedParent(pItem->getParentUUID())); | ||
2431 | U32 &refWorn = (fDirectDescendent) ? cntWorn : cntChildWorn, &refTotal = (fDirectDescendent) ? cntTotal : cntChildTotal; | ||
2432 | |||
2433 | if (rlvIsWearingItem(pItem)) | ||
2434 | refWorn++; | ||
2435 | refTotal++; | ||
2436 | } | ||
2437 | |||
2438 | wiFolder = (0 == cntTotal + cntChildTotal) ? 0 : (0 == cntWorn + cntChildWorn) ? 1 : | ||
2439 | (cntWorn + cntChildWorn != cntTotal + cntChildTotal) ? 2 : 3; | ||
2440 | wiChildren = (0 == cntChildTotal) ? 0 : (0 == cntChildWorn) ? 1 : (cntChildWorn != cntChildTotal) ? 2 : 3; | ||
2441 | |||
2442 | return true; | ||
2443 | } | ||
2444 | |||
2445 | // ============================================================================ | ||
2446 | // Initialization helper functions | ||
2447 | // | ||
2448 | |||
2449 | BOOL RlvHandler::setEnabled(BOOL fEnable) | ||
2450 | { | ||
2451 | if (m_fEnabled == fEnable) | ||
2452 | return fEnable; | ||
2453 | |||
2454 | if (fEnable) | ||
2455 | { | ||
2456 | if (gSavedSettings.controlExists(RLV_SETTING_NOSETENV)) | ||
2457 | fNoSetEnv = gSavedSettings.getBOOL(RLV_SETTING_NOSETENV); | ||
2458 | if (gSavedSettings.controlExists(RLV_SETTING_ENABLELEGACYNAMING)) | ||
2459 | fLegacyNaming = gSavedSettings.getBOOL(RLV_SETTING_ENABLELEGACYNAMING); | ||
2460 | if (gSavedSettings.controlExists(RLV_SETTING_SHOWNAMETAGS)) | ||
2461 | RlvSettings::fShowNameTags = gSavedSettings.getBOOL(RLV_SETTING_SHOWNAMETAGS); | ||
2462 | |||
2463 | RlvCommand::initLookupTable(); | ||
2464 | gRlvHandler.addObserver(new RlvExtGetSet()); | ||
2465 | |||
2466 | if (LLStartUp::getStartupState() >= STATE_CLEANUP) | ||
2467 | fetchSharedInventory(); | ||
2468 | |||
2469 | m_fEnabled = TRUE; | ||
2470 | } | ||
2471 | else if (canDisable()) | ||
2472 | { | ||
2473 | #ifdef RLV_DEBUG | ||
2474 | RLV_INFOS << "Disabling RLV:" << LL_ENDL; | ||
2475 | #endif // RLV_DEBUG | ||
2476 | |||
2477 | gRlvHandler.clearState(); | ||
2478 | |||
2479 | #ifdef RLV_DEBUG | ||
2480 | RLV_INFOS << "\t--> RLV disabled" << LL_ENDL; | ||
2481 | #endif // RLV_DEBUG | ||
2482 | |||
2483 | m_fEnabled = FALSE; | ||
2484 | } | ||
2485 | |||
2486 | #ifdef RLV_ADVANCED_MENU | ||
2487 | // RELEASE-RLVa: LL defines CLIENT_MENU_NAME but we can't get to it from here so we need to keep those two in sync manually | ||
2488 | LLMenuGL* pClientMenu = NULL; | ||
2489 | if ( (gMenuBarView) && ((pClientMenu = gMenuBarView->getChildMenuByName("Advanced", FALSE)) != NULL) ) | ||
2490 | { | ||
2491 | pClientMenu->setItemVisible("RLVa", m_fEnabled); | ||
2492 | pClientMenu->setItemEnabled("RLVa", m_fEnabled); | ||
2493 | } | ||
2494 | #endif // RLV_ADVANCED_MENU | ||
2495 | |||
2496 | return m_fEnabled; // Return enabled/disabled state | ||
2497 | } | ||
2498 | |||
2499 | BOOL RlvHandler::canDisable() | ||
2500 | { | ||
2501 | return TRUE; | ||
2502 | } | ||
2503 | |||
2504 | void RlvHandler::clearState() | ||
2505 | { | ||
2506 | // TODO-RLVa: should restore all RLV controlled debug variables to their defaults | ||
2507 | |||
2508 | // Issue @clear on behalf of every object that has a currently active RLV restriction (even if it's just an exception) | ||
2509 | LLUUID idObj; LLViewerObject* pObj; bool fDetachable; | ||
2510 | while (m_Objects.size()) | ||
2511 | { | ||
2512 | idObj = m_Objects.begin()->first; // Need a copy since after @clear the data it points to will no longer exist | ||
2513 | fDetachable = ((pObj = gObjectList.findObject(idObj)) != NULL) ? isDetachable(pObj) : true; | ||
2514 | |||
2515 | processCommand(idObj, "clear", false); | ||
2516 | if (!fDetachable) | ||
2517 | processCommand(idObj, "detachme=force", false); | ||
2518 | } | ||
2519 | |||
2520 | // Sanity check - these should all be empty after we issue @clear on the last object | ||
2521 | if ( (!m_Objects.empty()) || !(m_Exceptions.empty()) || (!m_Attachments.empty()) ) | ||
2522 | { | ||
2523 | RLV_ERRS << "Object, exception or attachment map not empty after clearing state!" << LL_ENDL; | ||
2524 | m_Objects.clear(); | ||
2525 | m_Exceptions.clear(); | ||
2526 | m_Attachments.clear(); | ||
2527 | } | ||
2528 | |||
2529 | // These all need manual clearing | ||
2530 | memset(m_LayersAdd, 0, sizeof(S16) * WT_COUNT); | ||
2531 | memset(m_LayersRem, 0, sizeof(S16) * WT_COUNT); | ||
2532 | memset(m_Behaviours, 0, sizeof(S16) * RLV_BHVR_COUNT); | ||
2533 | m_AttachPending.clear(); | ||
2534 | m_Emitter.clearObservers(); // <- calls delete on all active observers | ||
2535 | |||
2536 | // Clear dynamically allocated memory | ||
2537 | if (m_pGCTimer) | ||
2538 | { | ||
2539 | delete m_pGCTimer; | ||
2540 | m_pGCTimer = NULL; | ||
2541 | } | ||
2542 | if (m_pWLSnapshot) | ||
2543 | { | ||
2544 | delete m_pWLSnapshot; | ||
2545 | m_pWLSnapshot = NULL; | ||
2546 | } | ||
2547 | } | ||
2548 | |||
2549 | // ============================================================================ | ||
diff --git a/linden/indra/newview/rlvhandler.h b/linden/indra/newview/rlvhandler.h new file mode 100644 index 0000000..df3ff9b --- /dev/null +++ b/linden/indra/newview/rlvhandler.h | |||
@@ -0,0 +1,462 @@ | |||
1 | #ifndef RLV_HANDLER_H | ||
2 | #define RLV_HANDLER_H | ||
3 | |||
4 | #include "llagentconstants.h" | ||
5 | #include "llappviewer.h" | ||
6 | #include "llformat.h" | ||
7 | #include "llversionviewer.h" | ||
8 | #include "llviewerjointattachment.h" | ||
9 | #include "llviewerobject.h" | ||
10 | #include "llwearable.h" | ||
11 | |||
12 | #include "rlvhelper.h" | ||
13 | #include "rlvevent.h" | ||
14 | #include "rlvmultistringsearch.h" | ||
15 | |||
16 | // ============================================================================ | ||
17 | /* | ||
18 | * RlvHandler | ||
19 | * ========== | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | typedef std::map<LLUUID, RlvObject> rlv_object_map_t; | ||
24 | typedef std::multimap<S32, LLUUID> rlv_detach_map_t; | ||
25 | typedef std::map<S32, LLUUID> rlv_reattach_map_t; | ||
26 | typedef std::multimap<LLUUID, ERlvBehaviour> rlv_exception_map_t; | ||
27 | typedef std::map<S32, RlvRedirInfo> rlv_redir_map_t; | ||
28 | |||
29 | class RlvHandler | ||
30 | { | ||
31 | public: | ||
32 | RlvHandler(); | ||
33 | ~RlvHandler(); | ||
34 | |||
35 | // -------------------------------- | ||
36 | |||
37 | /* | ||
38 | * Rule checking functions | ||
39 | */ | ||
40 | public: | ||
41 | // Returns a pointer to the attachment point for a supplied parameter | ||
42 | LLViewerJointAttachment* getAttachPoint(const std::string& strText, bool fExact) const; | ||
43 | LLViewerJointAttachment* getAttachPoint(const LLInventoryItem* pItem, bool fStrict) const; | ||
44 | LLViewerJointAttachment* getAttachPoint(const LLInventoryCategory* pFolder, bool fStrict) const; | ||
45 | LLViewerJointAttachment* getAttachPointLegacy(const LLInventoryCategory* pFolder) const; | ||
46 | S32 getAttachPointIndex(std::string strText, bool fExact) const; | ||
47 | S32 getAttachPointIndex(LLViewerObject* pObj) const; | ||
48 | S32 getAttachPointIndex(const LLViewerJointAttachment* pObj) const; | ||
49 | bool hasAttachPointName(const LLInventoryItem* pItem, bool fStrict) const; | ||
50 | |||
51 | // Returns TRUE is at least one object contains the specified behaviour (and optional parameter) | ||
52 | // NOTE: - to check @detach=n -> hasLockedAttachment() / hasLockedHUD() / isDetachable() | ||
53 | // - to check @addoutfit=n -> isWearable() | ||
54 | // - to check @remoutfit=n -> isRemovable() | ||
55 | // - to check exceptions -> isException() | ||
56 | // (You *can* use hasBehaviour(); the specialized ones just don't have to iterate over all the objects) | ||
57 | bool hasBehaviour(ERlvBehaviour eBehaviour) const { return (eBehaviour < RLV_BHVR_COUNT) ? (0 != m_Behaviours[eBehaviour]) : false; } | ||
58 | bool hasBehaviour(const std::string& strBehaviour) const; | ||
59 | bool hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption) const; | ||
60 | bool hasBehaviour(const std::string& strBehaviour, const std::string& strOption) const; | ||
61 | |||
62 | // Returns TRUE if at least one object (except the specified one) contains the specified behaviour | ||
63 | bool hasBehaviourExcept(ERlvBehaviour eBehaviour, const LLUUID& idObj) const; | ||
64 | bool hasBehaviourExcept(const std::string& strBehaviour, const LLUUID& uuid) const; | ||
65 | bool hasBehaviourExcept(ERlvBehaviour eBehaviour, const std::string& strOption, const LLUUID& idObj) const; | ||
66 | bool hasBehaviourExcept(const std::string& strBehaviour, const std::string& strOption, const LLUUID& idObj) const; | ||
67 | |||
68 | // Returns TRUE if there is at least 1 undetachable attachment | ||
69 | bool hasLockedAttachment() const { return (0 != m_Attachments.size()); } | ||
70 | // Returns TRUE if there is at least 1 undetachable HUD attachment | ||
71 | bool hasLockedHUD() const; | ||
72 | |||
73 | // Returns TRUE if the specified attachment point is detachable | ||
74 | bool isDetachable(S32 idxAttachPt) const { return (idxAttachPt) && (m_Attachments.find(idxAttachPt) == m_Attachments.end()); } | ||
75 | bool isDetachable(const LLInventoryItem* pItem) const; | ||
76 | bool isDetachable(LLViewerObject* pObj) const; | ||
77 | // Returns TRUE if the specified attachment point is set undetachable by anything other than pObj (or one of its children) | ||
78 | bool isDetachableExcept(S32 idxAttachPt, LLViewerObject* pObj) const; | ||
79 | // Marks the specified attachment point as (un)detachable (return value indicates success ; used by unit tests) | ||
80 | bool setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDetachable); | ||
81 | bool setDetachable(LLViewerObject* pObj, const LLUUID& idRlvObj, bool fDetachable); | ||
82 | |||
83 | // Adds or removes an exception for the specified restriction | ||
84 | void addException(ERlvBehaviour eBehaviour, const LLUUID& uuid); | ||
85 | void removeException(ERlvBehaviour eBehaviour, const LLUUID& uuid); | ||
86 | // Returns TRUE is the specified UUID is exempt from a restriction (tplure/sendim/recvim/etc) | ||
87 | bool isException(ERlvBehaviour eBehaviour, const LLUUID& uuid) const; | ||
88 | bool isException(const std::string& strBehaviour, const LLUUID& uuid) const; | ||
89 | |||
90 | // Returns TRUE if the specified layer is removable (use hasBehaviour(RLV_BHVR_REMOUTFIT) for the general case) | ||
91 | bool isRemovable(EWearableType type) const { return (type < WT_COUNT) ? (0 == m_LayersRem[type]) : true; } | ||
92 | // Returns TRUE if the specified layer is not remoutfit blocked by any object (except the one specified by UUID) | ||
93 | bool isRemovableExcept(EWearableType type, const LLUUID& idObj) const; | ||
94 | // Returns TRUE if the inventory item is strippable by @detach or @remoutfit | ||
95 | bool isStrippable(const LLUUID& idItem) const; | ||
96 | // Returns TRUE if the specified layer is wearable (use hasBehaviour(RLV_BHVR_ADDOUTFIT) for the general case) | ||
97 | bool isWearable(EWearableType type) const { return (type < WT_COUNT) ? (0 == m_LayersAdd[type]) : true; } | ||
98 | |||
99 | // Returns TRUE if the composite folder doesn't contain any "locked" items | ||
100 | bool canTakeOffComposite(const LLInventoryCategory* pFolder) const; | ||
101 | // Returns TRUE if the folder is a composite folder and optionally returns the name | ||
102 | bool getCompositeInfo(const LLInventoryCategory* pFolder, std::string* pstrName) const; | ||
103 | // Returns TRUE if the inventory item belongs to a composite folder and optionally returns the name and composite folder | ||
104 | bool getCompositeInfo(const LLUUID& idItem, std::string* pstrName, LLViewerInventoryCategory** ppFolder) const; | ||
105 | // Returns TRUE if the folder is a composite folder | ||
106 | bool isCompositeFolder(const LLInventoryCategory* pFolder) const; | ||
107 | // Returns TRUE if the inventory item belongs to a composite folder | ||
108 | bool isCompositeDescendent(const LLUUID& idItem) const; | ||
109 | // Returns TRUE if the inventory item is part of a folded composite folder and should be hidden from @getoufit or @getattach | ||
110 | bool isHiddenCompositeItem(const LLUUID& idItem, const std::string& strItemType) const; | ||
111 | |||
112 | // -------------------------------- | ||
113 | |||
114 | /* | ||
115 | * Helper functions | ||
116 | */ | ||
117 | public: | ||
118 | // Accessors | ||
119 | bool getCanCancelTp() const { return m_fCanCancelTp; } // @accepttp and @tpto | ||
120 | void setCanCancelTp(bool fAllow) { m_fCanCancelTp = fAllow; } // @accepttp and @tpto | ||
121 | |||
122 | // Command specific helper functions | ||
123 | bool canShowHoverText(LLViewerObject* pObj) const; // @showhovertext* command family | ||
124 | void filterChat(std::string& strUTF8Text, bool fFilterEmote) const; // @sendchat, @recvchat and @redirchat | ||
125 | void filterLocation(std::string& strUTF8Text) const; // @showloc | ||
126 | void filterNames(std::string& strUTF8Text) const; // @shownames | ||
127 | const std::string& getAnonym(const std::string& strName) const; // @shownames | ||
128 | std::string getVersionString() const; // @version | ||
129 | BOOL isAgentNearby(const LLUUID& uuid) const; // @shownames | ||
130 | bool redirectChatOrEmote(const std::string& strUTF8Test) const; // @redirchat and @rediremote | ||
131 | |||
132 | // Command processing helper functions | ||
133 | BOOL processCommand(const LLUUID& idObj, const std::string& strCommand, bool fFromObj); | ||
134 | void processRetainedCommands(); | ||
135 | void retainCommand(const std::string& strObj, const LLUUID& idObj, const std::string& strCmd); | ||
136 | |||
137 | // Returns a pointer to the currently executing command (do *not* save this pointer) | ||
138 | const RlvCommand* getCurrentCommand() const { return m_pCurCommand; } | ||
139 | // Returns the UUID of the object we're currently executing a command for | ||
140 | const LLUUID& getCurrentObject() const { return m_idCurObject; } | ||
141 | |||
142 | // Initialization | ||
143 | static BOOL canDisable(); | ||
144 | static BOOL isEnabled() { return m_fEnabled; } | ||
145 | static void initLookupTables(); | ||
146 | static BOOL setEnabled(BOOL fEnable); | ||
147 | protected: | ||
148 | void clearState(); | ||
149 | |||
150 | // -------------------------------- | ||
151 | |||
152 | /* | ||
153 | * Inventory related functions | ||
154 | */ | ||
155 | public: | ||
156 | // Starts a fetch of everything under the shared root (if there is one) | ||
157 | static void fetchSharedInventory(); | ||
158 | // Returns the path of the supplied folder (relative to the shared root) | ||
159 | std::string getSharedPath(const LLViewerInventoryCategory* pFolder) const; | ||
160 | std::string getSharedPath(const LLUUID& idFolder) const; | ||
161 | // Returns a pointer to the shared root folder (if there is one) | ||
162 | static LLViewerInventoryCategory* getSharedRoot(); | ||
163 | // A "folded folder" is a folder whose items logically belong to the grandparent rather than the parent | ||
164 | bool isFoldedFolder(const LLInventoryCategory* pFolder, bool fAttach) const; | ||
165 | bool isFoldedFolderLegacy(const LLInventoryCategory* pFolder, bool fAttach) const; | ||
166 | protected: | ||
167 | // Find all folders that match a supplied criteria (clears the supplied array) | ||
168 | bool findSharedFolders(const std::string& strCriteria, LLInventoryModel::cat_array_t& folders) const; | ||
169 | |||
170 | // Returns a subfolder of idParent that starts with name (exact match > partial match) | ||
171 | LLViewerInventoryCategory* getSharedFolder(const LLUUID& idParent, const std::string& strName) const; | ||
172 | // Looks up a folder from a path (relative to the shared root) | ||
173 | LLViewerInventoryCategory* getSharedFolder(const std::string& strPath) const; | ||
174 | |||
175 | bool getWornInfo(const LLInventoryCategory* pFolder, U8& wiFolder, U8& wiChildren) const; | ||
176 | |||
177 | // -------------------------------- | ||
178 | |||
179 | /* | ||
180 | * Event handling (forwards to registered observers if we don't handle the command) | ||
181 | */ | ||
182 | public: | ||
183 | BOOL addObserver(RlvObserver* pObserver) { return m_Emitter.addObserver(pObserver); } | ||
184 | BOOL removeObserver(RlvObserver* pObserver) { return m_Emitter.remObserver(pObserver); } | ||
185 | void addBehaviourObserver(RlvBehaviourObserver* pBhvrObserver); | ||
186 | void removeBehaviourObserver(RlvBehaviourObserver* pBhvrObserver); | ||
187 | void notifyBehaviourObservers(const RlvCommand& rlvCmd, bool fInternal); | ||
188 | |||
189 | // Externally invoked event handlers | ||
190 | void onAttach(LLViewerJointAttachment* pAttachPt, bool fFullyLoaded); // LLVOAvatar::attachObject() | ||
191 | void onDetach(LLViewerJointAttachment* pAttachPt); // LLVOAvatar::detachObject() | ||
192 | bool onGC(); // RlvGCTimer::tick() | ||
193 | void onSavedAssetIntoInventory(const LLUUID& idItem); // LLInventoryModel::processSaveAssetIntoInventory() | ||
194 | protected: | ||
195 | BOOL processAddCommand(const LLUUID& uuid, const RlvCommand& rlvCmd); | ||
196 | BOOL processRemoveCommand(const LLUUID& uuid, const RlvCommand& rlvCmd); | ||
197 | BOOL processReplyCommand(const LLUUID& uuid, const RlvCommand& rlvCmd) const; | ||
198 | BOOL processForceCommand(const LLUUID& uuid, const RlvCommand& rlvCmd) const; | ||
199 | |||
200 | // Command handlers (exist for no other reason than to keep the length of the processXXX functions down) | ||
201 | void onForceDetach(const LLUUID& idObj, const std::string& strOption) const; | ||
202 | void onForceRemOutfit(const LLUUID& idObj, const std::string& strOption) const; | ||
203 | bool onForceSit(const LLUUID& uuid, const std::string& strOption) const; | ||
204 | void onForceWear(const std::string& strPath, bool fAttach, bool fMatchAll) const; | ||
205 | bool onGetPath(const LLUUID& uuid, const std::string& strOption, std::string& strReply) const; | ||
206 | void onGetInvWorn(const std::string& strPath, std::string &strReply) const; | ||
207 | |||
208 | // -------------------------------- | ||
209 | |||
210 | /* | ||
211 | * Member variables | ||
212 | */ | ||
213 | public: | ||
214 | static BOOL fNoSetEnv; | ||
215 | static BOOL fLegacyNaming; | ||
216 | |||
217 | static const std::string cstrSharedRoot; // Name of the shared root folder | ||
218 | static const std::string cstrBlockedRecvIM; // Stand-in text for incoming IM when recvim restricted | ||
219 | static const std::string cstrBlockedSendIM; // Stand-in text for outgoing IM when sendim restricted | ||
220 | static const std::string cstrHidden; // General purpose "this was censored" text | ||
221 | static const std::string cstrHiddenParcel; | ||
222 | static const std::string cstrHiddenRegion; | ||
223 | static const std::string cstrMsgRecvIM; // Message sent to IM sender when sendim restricted | ||
224 | static const std::string cstrMsgTpLure; // Message sent to tplure sender when tplure restricted | ||
225 | static const std::string cstrAnonyms[28]; | ||
226 | protected: | ||
227 | rlv_object_map_t m_Objects; // Map of objects that have active restrictions (by UUID) | ||
228 | rlv_exception_map_t m_Exceptions; // Map of UUIDs that are exempt from the associated ERlvBehaviour | ||
229 | rlv_detach_map_t m_Attachments; // Map of locked attachments (attachment point index -> object that issued @detach=n) | ||
230 | S16 m_LayersAdd[WT_COUNT]; // Array of locked layers (reference counted) | ||
231 | S16 m_LayersRem[WT_COUNT]; // Array of locked layers (reference counted) | ||
232 | S16 m_Behaviours[RLV_BHVR_COUNT]; | ||
233 | |||
234 | rlv_retained_list_t m_Retained; | ||
235 | rlv_reattach_map_t m_AttachPending; | ||
236 | rlv_reattach_map_t m_DetachPending; | ||
237 | rlv_redir_map_t m_Redirections; | ||
238 | RlvGCTimer* m_pGCTimer; | ||
239 | RlvWLSnapshot* m_pWLSnapshot; | ||
240 | |||
241 | RlvCommand* m_pCurCommand; // Convenience (see @tpto) | ||
242 | LLUUID m_idCurObject; // Convenience (see @tpto) | ||
243 | |||
244 | mutable RlvEventEmitter<RlvObserver> m_Emitter; | ||
245 | mutable std::list<RlvBehaviourObserver*> m_BhvrObservers; | ||
246 | RlvBehaviourNotifyObserver* m_pBhvrNotify; | ||
247 | |||
248 | static BOOL m_fEnabled; // Use setEnabled() to toggle this | ||
249 | static BOOL m_fFetchStarted; // TRUE if we fired off an inventory fetch | ||
250 | static BOOL m_fFetchComplete; // TRUE if everything was fetched | ||
251 | static RlvMultiStringSearch m_AttachLookup; // Lookup table for attachment names (lower case) | ||
252 | |||
253 | bool m_fCanCancelTp; | ||
254 | |||
255 | friend class RlvSharedRootFetcher; // Fetcher needs access to m_fFetchComplete | ||
256 | friend class RlvGCTimer; // Timer clear its own point at destruction | ||
257 | |||
258 | // -------------------------------- | ||
259 | |||
260 | /* | ||
261 | * Internal access functions used by unit tests | ||
262 | */ | ||
263 | public: | ||
264 | const rlv_object_map_t* getObjectMap() const { return &m_Objects; } | ||
265 | const rlv_exception_map_t* getExceptionMap() const { return &m_Exceptions; } | ||
266 | const rlv_detach_map_t* getDetachMap() const { return &m_Attachments; } | ||
267 | #ifdef RLV_DEBUG_TESTS | ||
268 | const S16* getAddLayers() const { return m_LayersAdd; } | ||
269 | const S16* getRemLayers() const { return m_LayersRem; } | ||
270 | const S16* getBehaviours() const { return m_Behaviours; } | ||
271 | const rlv_retained_list_t* getRetainedList() const { return &m_Retained; } | ||
272 | #endif // RLV_DEBUG_TESTS | ||
273 | }; | ||
274 | |||
275 | typedef RlvHandler rlv_handler_t; | ||
276 | extern rlv_handler_t gRlvHandler; | ||
277 | |||
278 | // ============================================================================ | ||
279 | // Inlined member functions | ||
280 | // | ||
281 | |||
282 | // Checked: 2009-07-09 (RLVa-1.0.0f) | ||
283 | inline void RlvHandler::addException(ERlvBehaviour eBehaviour, const LLUUID& uuid) | ||
284 | { | ||
285 | if (!uuid.isNull()) | ||
286 | m_Exceptions.insert(std::pair<LLUUID, ERlvBehaviour>(uuid, eBehaviour)); | ||
287 | } | ||
288 | |||
289 | // Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f | ||
290 | inline bool RlvHandler::canShowHoverText(LLViewerObject *pObj) const | ||
291 | { | ||
292 | return ( (!pObj) || (LL_PCODE_VOLUME != pObj->getPCode()) || | ||
293 | !( (hasBehaviour(RLV_BHVR_SHOWHOVERTEXTALL)) || | ||
294 | ( (hasBehaviour(RLV_BHVR_SHOWHOVERTEXTWORLD)) && (!pObj->isHUDAttachment()) ) || | ||
295 | ( (hasBehaviour(RLV_BHVR_SHOWHOVERTEXTHUD)) && (pObj->isHUDAttachment()) ) || | ||
296 | (isException(RLV_BHVR_SHOWHOVERTEXT, pObj->getID())) ) ); | ||
297 | } | ||
298 | |||
299 | // Checked: 2009-05-23 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d | ||
300 | inline S32 RlvHandler::getAttachPointIndex(std::string strText, bool fExact) const | ||
301 | { | ||
302 | U16 nParam; RlvMultiStringSearchMatch match; | ||
303 | LLStringUtil::toLower(strText); | ||
304 | return (fExact) ? ((m_AttachLookup.getExactMatchParam(strText, nParam)) ? nParam : 0) | ||
305 | : ((m_AttachLookup.findLast(strText, match)) ? match.nParam : 0); | ||
306 | } | ||
307 | |||
308 | // Checked: 2009-05-23 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d | ||
309 | inline S32 RlvHandler::getAttachPointIndex(LLViewerObject* pObj) const | ||
310 | { | ||
311 | return (pObj) ? ATTACHMENT_ID_FROM_STATE(pObj->getState()) : 0; | ||
312 | } | ||
313 | |||
314 | // Checked: 2009-06-02 (RLVa-0.2.0g) | ||
315 | inline std::string RlvHandler::getSharedPath(const LLUUID& idFolder) const | ||
316 | { | ||
317 | return getSharedPath(gInventory.getCategory(idFolder)); // getSharedPath() has a NULL pointer check so this is safe | ||
318 | } | ||
319 | |||
320 | // Checked: 2009-06-07 (RLVa-0.2.1c) | ||
321 | inline std::string RlvHandler::getVersionString() const | ||
322 | { | ||
323 | return llformat("RestrainedLife viewer v%d.%d.%d (%s %d.%d.%d.%d - RLVa %d.%d.%d)", | ||
324 | RLV_VERSION_MAJOR, RLV_VERSION_MINOR, RLV_VERSION_PATCH, | ||
325 | LLAppViewer::instance()->getSecondLifeTitle().c_str(), LL_VERSION_MAJOR, LL_VERSION_MINOR, LL_VERSION_PATCH, LL_VERSION_BUILD, | ||
326 | RLVa_VERSION_MAJOR, RLVa_VERSION_MINOR, RLVa_VERSION_PATCH); | ||
327 | } | ||
328 | |||
329 | // Checked: 2009-05-23 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d | ||
330 | inline bool RlvHandler::hasAttachPointName(const LLInventoryItem *pItem, bool fStrict) const | ||
331 | { | ||
332 | return (getAttachPoint(pItem, fStrict) != NULL); // getAttachPoint() has a NULL pointer check so this is safe | ||
333 | } | ||
334 | |||
335 | // Checked: | ||
336 | inline bool RlvHandler::hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption) const | ||
337 | { | ||
338 | return hasBehaviourExcept(eBehaviour, strOption, LLUUID::null); | ||
339 | } | ||
340 | |||
341 | // Checked: | ||
342 | inline bool RlvHandler::hasBehaviour(const std::string& strBehaviour) const | ||
343 | { | ||
344 | return hasBehaviourExcept(strBehaviour, LLUUID::null); | ||
345 | } | ||
346 | |||
347 | // Checked: | ||
348 | inline bool RlvHandler::hasBehaviour(const std::string& strBehaviour, const std::string& strOption) const | ||
349 | { | ||
350 | return hasBehaviourExcept(strBehaviour, strOption, LLUUID::null); | ||
351 | } | ||
352 | |||
353 | // Checked: | ||
354 | inline bool RlvHandler::hasBehaviourExcept(ERlvBehaviour eBehaviour, const LLUUID& idObj) const | ||
355 | { | ||
356 | return hasBehaviourExcept(eBehaviour, std::string(), idObj); | ||
357 | } | ||
358 | |||
359 | #ifdef RLV_EXPERIMENTAL_COMPOSITES | ||
360 | // Checked: | ||
361 | inline bool RlvHandler::isCompositeFolder(const LLInventoryCategory* pFolder) const | ||
362 | { | ||
363 | return getCompositeInfo(pFolder, NULL); | ||
364 | } | ||
365 | |||
366 | // Checked: | ||
367 | inline bool RlvHandler::isCompositeDescendent(const LLUUID& idItem) const | ||
368 | { | ||
369 | return getCompositeInfo(idItem, NULL, NULL); | ||
370 | } | ||
371 | #endif // RLV_EXPERIMENTAL_COMPOSITES | ||
372 | |||
373 | // Checked: 2009-05-23 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d | ||
374 | inline bool RlvHandler::isDetachable(LLViewerObject* pObj) const | ||
375 | { | ||
376 | return (pObj == NULL) || (!pObj->isAttachment()) || (isDetachable(getAttachPointIndex(pObj))); | ||
377 | } | ||
378 | |||
379 | // Checked: | ||
380 | inline bool RlvHandler::isException(ERlvBehaviour eBehaviour, const LLUUID& uuid) const | ||
381 | { | ||
382 | for (rlv_exception_map_t::const_iterator itException = m_Exceptions.lower_bound(uuid), | ||
383 | endException = m_Exceptions.upper_bound(uuid); itException != endException; ++itException) | ||
384 | { | ||
385 | if (itException->second == eBehaviour) | ||
386 | return true; | ||
387 | } | ||
388 | return false; | ||
389 | } | ||
390 | |||
391 | // Checked: | ||
392 | inline bool RlvHandler::isException(const std::string& strBehaviour, const LLUUID& uuid) const | ||
393 | { | ||
394 | return hasBehaviour(strBehaviour, uuid.asString()); | ||
395 | } | ||
396 | |||
397 | // Checked: 2009-07-29 (RLVa-1.0.1b) | Added: RLVa-1.0.1b | ||
398 | inline bool RlvHandler::isFoldedFolder(const LLInventoryCategory* pFolder, bool fAttach) const | ||
399 | { | ||
400 | return | ||
401 | ( | ||
402 | // .(<attachpt>) type folder (on detach we don't care about its children, but on attach there can only be 1 attachment) | ||
403 | ( (gRlvHandler.getAttachPoint(pFolder, true)) && | ||
404 | ( (!fAttach) || (1 == rlvGetDirectDescendentsCount(pFolder, LLAssetType::AT_OBJECT))) ) | ||
405 | #ifdef RLV_EXTENSION_FLAG_NOSTRIP | ||
406 | // .(nostrip) folder | ||
407 | || ( (pFolder) && (".("RLV_FOLDER_FLAG_NOSTRIP")" == pFolder->getName()) ) | ||
408 | #endif // RLV_EXTENSION_FLAG_NOSTRIP | ||
409 | ); | ||
410 | } | ||
411 | |||
412 | // Checked: 2009-05-23 (RLVa-0.2.0d) | Added: RLVa-0.2.0d | ||
413 | inline bool RlvHandler::isRemovableExcept(EWearableType type, const LLUUID& idObj) const | ||
414 | { | ||
415 | // NOTE: mind the bitwise OR rather than the logical OR!! | ||
416 | return (isRemovable(type)) || !( (hasBehaviourExcept(RLV_BHVR_REMOUTFIT, idObj)) | | ||
417 | (hasBehaviourExcept(RLV_BHVR_REMOUTFIT, LLWearable::typeToTypeName(type), idObj)) ); | ||
418 | } | ||
419 | |||
420 | #ifndef RLV_EXTENSION_FLAG_NOSTRIP | ||
421 | // Checked: 2009-05-23 (RLVa-0.2.0d) | Added: RLVa-0.2.0d | ||
422 | bool RlvHandler::isStrippable(const LLUUID& idItem) const | ||
423 | { | ||
424 | return true; | ||
425 | } | ||
426 | #endif // RLV_EXTENSION_FLAG_NOSTRIP | ||
427 | |||
428 | // Checked: 2009-07-09 (RLVa-1.0.0f) | ||
429 | inline void RlvHandler::removeException(ERlvBehaviour eBehaviour, const LLUUID &uuid) | ||
430 | { | ||
431 | if (!uuid.isNull()) | ||
432 | { | ||
433 | for (rlv_exception_map_t::iterator itException = m_Exceptions.lower_bound(uuid), | ||
434 | endException = m_Exceptions.upper_bound(uuid); itException != endException; ++itException) | ||
435 | { | ||
436 | if (itException->second == eBehaviour) | ||
437 | { | ||
438 | m_Exceptions.erase(itException); | ||
439 | break; | ||
440 | } | ||
441 | } | ||
442 | } | ||
443 | } | ||
444 | |||
445 | // Checked: 2009-08-05 (RLVa-1.0.1e) | Modified: RLVa-1.0.1e | ||
446 | inline void RlvHandler::retainCommand(const std::string& strObj, const LLUUID& idObj, const std::string& strCmd) | ||
447 | { | ||
448 | #ifdef RLV_DEBUG | ||
449 | RLV_INFOS << "[" << idObj << "]: " << strCmd << " (retaining)" << LL_ENDL; | ||
450 | #endif // RLV_DEBUG | ||
451 | m_Retained.push_back(RlvRetainedCommand(strObj, idObj, strCmd)); | ||
452 | } | ||
453 | |||
454 | // Checked: 2009-05-23 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d | ||
455 | inline bool RlvHandler::setDetachable(LLViewerObject* pObj, const LLUUID& idRlvObj, bool fDetachable) | ||
456 | { | ||
457 | return setDetachable(getAttachPointIndex(pObj), idRlvObj, fDetachable); // getAttachPointIndex() has a NULL pointer check | ||
458 | } | ||
459 | |||
460 | // ============================================================================ | ||
461 | |||
462 | #endif // RLV_HANDLER_H | ||
diff --git a/linden/indra/newview/rlvhelper.cpp b/linden/indra/newview/rlvhelper.cpp new file mode 100644 index 0000000..6b2a1a0 --- /dev/null +++ b/linden/indra/newview/rlvhelper.cpp | |||
@@ -0,0 +1,674 @@ | |||
1 | #include "llviewerprecompiledheaders.h" | ||
2 | #include "llagent.h" | ||
3 | #include "llviewerobject.h" | ||
4 | #include "llviewerstats.h" | ||
5 | #include "llviewerwindow.h" | ||
6 | #include "llvoavatar.h" | ||
7 | #include "llwlparammanager.h" | ||
8 | |||
9 | #include "rlvhelper.h" | ||
10 | #include "rlvevent.h" | ||
11 | #include "rlvhandler.h" | ||
12 | |||
13 | // ============================================================================ | ||
14 | // Static variable initialization | ||
15 | // | ||
16 | |||
17 | RlvMultiStringSearch RlvCommand::m_BhvrLookup; | ||
18 | |||
19 | // ============================================================================ | ||
20 | |||
21 | // Checked: | ||
22 | RlvCommand::RlvCommand(const std::string& strCommand) | ||
23 | : m_eBehaviour(RLV_BHVR_UNKNOWN), m_eParamType(RLV_TYPE_UNKNOWN) | ||
24 | { | ||
25 | if ((m_fValid = parseCommand(strCommand, m_strBehaviour, m_strOption, m_strParam))) | ||
26 | { | ||
27 | if ( ("n" == m_strParam) || ("add" == m_strParam) ) | ||
28 | m_eParamType = RLV_TYPE_ADD; | ||
29 | else if ( ("y" == m_strParam) || ("rem" == m_strParam) ) | ||
30 | m_eParamType = RLV_TYPE_REMOVE; | ||
31 | else if ("force" == m_strParam) | ||
32 | m_eParamType = RLV_TYPE_FORCE; | ||
33 | else | ||
34 | { | ||
35 | m_eParamType = RLV_TYPE_REPLY; // Assume it's a reply command until we encounter a non-digit | ||
36 | |||
37 | if ( (m_strParam.empty()) || (-1 != m_strParam.find_first_not_of("0123456789")) ) | ||
38 | { | ||
39 | m_eParamType = RLV_TYPE_UNKNOWN; | ||
40 | m_fValid = ("clear" == m_strBehaviour); | ||
41 | } | ||
42 | } | ||
43 | } | ||
44 | |||
45 | if (!m_fValid) | ||
46 | { | ||
47 | m_strBehaviour = m_strOption = m_strParam = ""; | ||
48 | return; | ||
49 | } | ||
50 | |||
51 | U16 nBehaviour; | ||
52 | if (m_BhvrLookup.getExactMatchParam(m_strBehaviour, nBehaviour)) | ||
53 | { | ||
54 | m_eBehaviour = (ERlvBehaviour)nBehaviour; | ||
55 | } | ||
56 | } | ||
57 | |||
58 | RlvCommand::RlvCommand(const RlvCommand& rlvCmd) | ||
59 | : m_fValid(rlvCmd.m_fValid), | ||
60 | m_strBehaviour(rlvCmd.m_strBehaviour), m_eBehaviour(rlvCmd.m_eBehaviour), | ||
61 | m_strOption(rlvCmd.m_strOption), | ||
62 | m_strParam(rlvCmd.m_strParam), m_eParamType(rlvCmd.m_eParamType) | ||
63 | { | ||
64 | } | ||
65 | |||
66 | // ============================================================================ | ||
67 | |||
68 | /* | ||
69 | * ------------------------------ | ||
70 | * Command | RLV | RLVa | ||
71 | * ------------------------------ | ||
72 | * : | F | F (missing behaviour) | ||
73 | * :option | F | F (missing behaviour) | ||
74 | * := | T | F (missing behaviour) | ||
75 | * :option= | T | F (missing behaviour) | ||
76 | * :option=param | T | F (missing behaviour) | ||
77 | * = | T | F (missing behaviour) | ||
78 | * =param | T | F (missing behaviour) | ||
79 | * cmd | F | F (missing param) [T if <behaviour> == "clear"] | ||
80 | * cmd: | F | F (missing param) | ||
81 | * cmd:option | F | F (missing param) | ||
82 | * cmd:= | T | F (missing param) [1] | ||
83 | * cmd:option= | T | F (missing param) [1] | ||
84 | * cmd= | T | F (missing param) [1] | ||
85 | * cmd:option=param | T | T | ||
86 | * cmd=param | T | T | ||
87 | * cmd:=param | T | T | ||
88 | * | ||
89 | * [1] 'clear:=', 'clear:option=' and 'clear=' are "valid" variations of 'clear' | ||
90 | */ | ||
91 | |||
92 | BOOL RlvCommand::parseCommand(/*[in]*/ const std::string& strCommand, | ||
93 | /*[out]*/ std::string& strBehaviour, /*[out]*/ std::string& strOption, /*[out]*/ std::string& strParam) | ||
94 | { | ||
95 | // Format: <behaviour>[:<option>]=<param> | ||
96 | int idxParam = strCommand.find('='); | ||
97 | int idxOption = (idxParam > 0) ? strCommand.find(':') : -1; | ||
98 | if (idxOption > idxParam - 1) | ||
99 | idxOption = -1; | ||
100 | |||
101 | // If <behaviour> is missing it's always an improperly formatted command | ||
102 | if ( (0 == idxOption) || (0 == idxParam) ) | ||
103 | return FALSE; | ||
104 | |||
105 | strBehaviour = strCommand.substr(0, (-1 != idxOption) ? idxOption : idxParam); | ||
106 | strOption = strParam = ""; | ||
107 | |||
108 | // If <param> is missing it's an improperly formatted command | ||
109 | if ( (-1 == idxParam) || ((int)strCommand.length() - 1 == idxParam) ) | ||
110 | { | ||
111 | // Unless "<behaviour> == "clear" AND (idxOption == 0)" | ||
112 | // OR <behaviour> == "clear" AND (idxParam != 0) [see table above] | ||
113 | if ( ("clear" == strBehaviour) && ( (!idxOption) || (idxParam) ) ) | ||
114 | return TRUE; | ||
115 | return FALSE; | ||
116 | } | ||
117 | |||
118 | if ( (-1 != idxOption) && (idxOption + 1 != idxParam) ) | ||
119 | strOption = strCommand.substr(idxOption + 1, idxParam - idxOption - 1); | ||
120 | strParam = strCommand.substr(idxParam + 1); | ||
121 | |||
122 | return TRUE; | ||
123 | } | ||
124 | |||
125 | void RlvCommand::initLookupTable() | ||
126 | { | ||
127 | static bool fInitialized = false; | ||
128 | if (!fInitialized) | ||
129 | { | ||
130 | // NOTE: keep this match with the enumeration at all times | ||
131 | std::string arBehaviours[RLV_BHVR_COUNT] = | ||
132 | { | ||
133 | "version", "detach", "redirchat", "rediremote", "sendim", "recvchat", "recvemote", "recvim", "tploc", "tplure", | ||
134 | "sittp", "edit", "rez", "addoutfit", "remoutfit", "getoutfit", "getattach", "showinv", "unsit", "sit", | ||
135 | "getstatus", "getstatusall", "getinv", "getinvworn", "findfolder", "findfolders", "attach", "attachall", "detachall", | ||
136 | "getpath", "attachthis", "attachallthis", "detachthis", "detachallthis", "fartouch", "showworldmap", "showminimap", | ||
137 | "showloc", "tpto", "accepttp", "shownames", "fly", "getsitid", "setdebug", "setenv", "detachme", | ||
138 | "showhovertextall", "showhovertextworld", "showhovertexthud", "showhovertext", "notify" | ||
139 | }; | ||
140 | |||
141 | for (int idxBvhr = 0; idxBvhr < RLV_BHVR_COUNT; idxBvhr++) | ||
142 | m_BhvrLookup.addKeyword(arBehaviours[idxBvhr], idxBvhr); | ||
143 | |||
144 | fInitialized = true; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | // Checked: 2009-06-07 (RLVa-0.2.1c) | ||
149 | std::string RlvCommand::asString() const | ||
150 | { | ||
151 | return (!m_strOption.empty()) ? (std::string(m_strBehaviour)).append(":").append(m_strOption) : (std::string(m_strBehaviour)); | ||
152 | } | ||
153 | |||
154 | // ========================================================================= | ||
155 | |||
156 | BOOL RlvObject::addCommand(const RlvCommand& rlvCmd) | ||
157 | { | ||
158 | // Sanity checking | ||
159 | if (RLV_TYPE_ADD != rlvCmd.getParamType()) | ||
160 | return FALSE; | ||
161 | |||
162 | // Don't add duplicate commands for this object (ie @detach=n followed by another @detach=n later on) | ||
163 | BOOL fDuplicate = | ||
164 | (RLV_BHVR_UNKNOWN != rlvCmd.getBehaviourType()) | ||
165 | ? hasBehaviour(rlvCmd.getBehaviourType(), rlvCmd.getOption()) | ||
166 | : hasBehaviour(rlvCmd.getBehaviour(), rlvCmd.getOption()); | ||
167 | if (fDuplicate) | ||
168 | return FALSE; | ||
169 | |||
170 | // Now that we know it's not a duplicate, add it to the end of the list | ||
171 | m_Commands.push_back(rlvCmd); | ||
172 | |||
173 | return TRUE; | ||
174 | } | ||
175 | |||
176 | BOOL RlvObject::removeCommand(const RlvCommand& rlvCmd) | ||
177 | { | ||
178 | // Sanity checking | ||
179 | if (RLV_TYPE_REMOVE != rlvCmd.getParamType()) | ||
180 | return FALSE; | ||
181 | |||
182 | for (rlv_command_list_t::iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) | ||
183 | { | ||
184 | //if (*itCmd == rlvCmd) <- commands will never be equal since one is an add and the other is a remove *rolls eyes* | ||
185 | if ( (itCmd->getBehaviour() == rlvCmd.getBehaviour()) && (itCmd->getOption() == rlvCmd.getOption()) ) | ||
186 | { | ||
187 | m_Commands.erase(itCmd); | ||
188 | return TRUE; | ||
189 | } | ||
190 | } | ||
191 | return FALSE; // Command was never added so nothing to remove now | ||
192 | } | ||
193 | |||
194 | BOOL RlvObject::hasBehaviour(ERlvBehaviour eBehaviour) const | ||
195 | { | ||
196 | for (rlv_command_list_t::const_iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) | ||
197 | if ( (itCmd->getBehaviourType() == eBehaviour) && (itCmd->getOption().empty()) ) | ||
198 | return TRUE; | ||
199 | return FALSE; | ||
200 | } | ||
201 | |||
202 | BOOL RlvObject::hasBehaviour(const std::string& strBehaviour) const | ||
203 | { | ||
204 | for (rlv_command_list_t::const_iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) | ||
205 | if ( (itCmd->getBehaviour() == strBehaviour) && (itCmd->getOption().empty()) ) | ||
206 | return TRUE; | ||
207 | return FALSE; | ||
208 | } | ||
209 | |||
210 | BOOL RlvObject::hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption) const | ||
211 | { | ||
212 | for (rlv_command_list_t::const_iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) | ||
213 | if ( (itCmd->getBehaviourType() == eBehaviour) && (itCmd->getOption() == strOption) ) | ||
214 | return TRUE; | ||
215 | return FALSE; | ||
216 | } | ||
217 | |||
218 | BOOL RlvObject::hasBehaviour(const std::string& strBehaviour, const std::string& strOption) const | ||
219 | { | ||
220 | for (rlv_command_list_t::const_iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) | ||
221 | if ( (itCmd->getBehaviour() == strBehaviour) && (itCmd->getOption() == strOption) ) | ||
222 | return TRUE; | ||
223 | return FALSE; | ||
224 | } | ||
225 | |||
226 | // Checked: 2009-06-07 (RLVa-0.2.1c) | ||
227 | std::string RlvObject::getStatusString(const std::string& strMatch) const | ||
228 | { | ||
229 | std::string strStatus, strCmd; | ||
230 | |||
231 | for (rlv_command_list_t::const_iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) | ||
232 | { | ||
233 | strCmd = itCmd->asString(); | ||
234 | if ( (strMatch.empty()) || (std::string::npos != strCmd.find(strMatch)) ) | ||
235 | { | ||
236 | if (!strStatus.empty()) | ||
237 | strStatus.push_back('/'); | ||
238 | strStatus += strCmd; | ||
239 | } | ||
240 | } | ||
241 | |||
242 | return strStatus; | ||
243 | } | ||
244 | |||
245 | // ========================================================================= | ||
246 | /* | ||
247 | * Various helper classes/timers/functors | ||
248 | * | ||
249 | */ | ||
250 | |||
251 | // Checked: 2009-05-26 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d | ||
252 | S32 rlvGetDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType::EType type) | ||
253 | { | ||
254 | S32 cntType = 0; | ||
255 | if (pFolder) | ||
256 | { | ||
257 | LLInventoryModel::cat_array_t* pFolders; | ||
258 | LLInventoryModel::item_array_t* pItems; | ||
259 | gInventory.getDirectDescendentsOf(pFolder->getUUID(), pFolders, pItems); | ||
260 | |||
261 | if (pItems) | ||
262 | { | ||
263 | for (S32 idxItem = 0, cntItem = pItems->count(); idxItem < cntItem; idxItem++) | ||
264 | if (pItems->get(idxItem)->getType() == type) | ||
265 | cntType++; | ||
266 | } | ||
267 | } | ||
268 | return cntType; | ||
269 | } | ||
270 | |||
271 | // Checked: 2009-05-30 (RLVa-0.2.0e) | Added: RLVa-0.2.0e | ||
272 | const LLUUID& RlvWearableItemCollector::getFoldedParent(const LLUUID& idFolder) const | ||
273 | { | ||
274 | std::map<LLUUID, LLUUID>::const_iterator itFolder = m_Folding.end(), itCur = m_Folding.find(idFolder); | ||
275 | while (itCur != m_Folding.end()) | ||
276 | { | ||
277 | itFolder = itCur; | ||
278 | itCur = m_Folding.find(itFolder->second); | ||
279 | } | ||
280 | return (m_Folding.end() == itFolder) ? idFolder : itFolder->second; | ||
281 | } | ||
282 | |||
283 | // Checked: 2009-07-29 (RLVa-1.0.1b) | Modified: RLVa-1.0.1b | ||
284 | bool RlvWearableItemCollector::onCollectFolder(const LLInventoryCategory* pFolder) | ||
285 | { | ||
286 | const LLUUID& idParent = pFolder->getParentUUID(); | ||
287 | if (m_Wearable.end() == std::find(m_Wearable.begin(), m_Wearable.end(), idParent)) | ||
288 | return false; // Not the child of a wearable folder == skip | ||
289 | |||
290 | const std::string& strFolder = pFolder->getName(); | ||
291 | if (strFolder.empty()) // Shouldn't happen but does... naughty Lindens | ||
292 | return false; | ||
293 | |||
294 | #ifdef RLV_EXTENSION_FLAG_NOSTRIP | ||
295 | if ( (!m_fAttach) && (-1 != strFolder.find(RLV_FOLDER_FLAG_NOSTRIP)) ) // Don't process "nostrip" folders on detach | ||
296 | return false; | ||
297 | #endif // RLV_EXTENSION_FLAG_NOSTRIP | ||
298 | |||
299 | if (gRlvHandler.isFoldedFolder(pFolder, m_fAttach)) // Check for folder that should get folded under its parent | ||
300 | { | ||
301 | m_Tentative.push_front(pFolder->getUUID()); | ||
302 | m_Folding.insert(std::pair<LLUUID, LLUUID>(pFolder->getUUID(), idParent)); | ||
303 | } | ||
304 | else if ( (RLV_FOLDER_PREFIX_HIDDEN != strFolder[0]) && (m_fMatchAll) ) // Collect from any non-hidden child folder for *all | ||
305 | { | ||
306 | m_Wearable.push_front(pFolder->getUUID()); | ||
307 | return (idParent == m_idFolder); // (Convenience for @getinvworn) | ||
308 | } | ||
309 | #ifdef RLV_EXPERIMENTAL_COMPOSITES | ||
310 | else if ( (RLV_FOLDER_PREFIX_HIDDEN == strFolder[0]) && // Hidden folder that's a... | ||
311 | (gRlvHandler.isCompositeFolder(pFolder)) && // ... composite folder which we... | ||
312 | ((m_fAttach) || (gRlvHandler.canTakeOffComposite(pFolder))) ) // ... attach or can detach (see composite locking) | ||
313 | { | ||
314 | m_Wearable.push_front(pFolder->getUUID()); | ||
315 | m_Folding.insert(std::pair<LLUUID, LLUUID>(pFolder->getUUID(), idParent)); | ||
316 | } | ||
317 | #endif // RLV_EXPERIMENTAL_COMPOSITES | ||
318 | |||
319 | return false; | ||
320 | } | ||
321 | |||
322 | // Checked: 2009-05-26 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d | ||
323 | bool RlvWearableItemCollector::onCollectItem(const LLInventoryItem* pItem) | ||
324 | { | ||
325 | #ifdef RLV_EXTENSION_FLAG_NOSTRIP | ||
326 | if ( (!m_fAttach) && (-1 != pItem->getName().find(RLV_FOLDER_FLAG_NOSTRIP)) ) // Don't process "nostrip" items on detach | ||
327 | return false; | ||
328 | #endif // RLV_EXTENSION_FLAG_NOSTRIP | ||
329 | |||
330 | const LLUUID& idParent = pItem->getParentUUID(); bool fRet = false; | ||
331 | switch (pItem->getType()) | ||
332 | { | ||
333 | case LLAssetType::AT_BODYPART: | ||
334 | if (!m_fAttach) | ||
335 | break; // Don't process body parts on detach | ||
336 | case LLAssetType::AT_CLOTHING: | ||
337 | #ifdef RLV_EXTENSION_FLAG_NOSTRIP | ||
338 | fRet = ( (m_Wearable.end() != std::find(m_Wearable.begin(), m_Wearable.end(), idParent)) || | ||
339 | ( (m_fAttach) && (m_Tentative.end() != std::find(m_Tentative.begin(), m_Tentative.end(), idParent)) && | ||
340 | (gInventory.getCategory(pItem->getParentUUID())->getName() == ".("RLV_FOLDER_FLAG_NOSTRIP")") ) ); | ||
341 | #else | ||
342 | fRet = (m_Wearable.end() != std::find(m_Wearable.begin(), m_Wearable.end(), idParent)); | ||
343 | #endif // RLV_EXTENSION_FLAG_NOSTRIP | ||
344 | break; | ||
345 | case LLAssetType::AT_OBJECT: | ||
346 | fRet = ( (m_Wearable.end() != std::find(m_Wearable.begin(), m_Wearable.end(), idParent)) || | ||
347 | (m_Tentative.end() != std::find(m_Tentative.begin(), m_Tentative.end(), idParent)) ) && | ||
348 | ( (!m_fAttach) || (gRlvHandler.hasAttachPointName(pItem, true)) ); // Only care about attach point on attach* | ||
349 | break; | ||
350 | #ifdef RLV_EXPERIMENTAL_FORCEWEAR_GESTURES | ||
351 | case LLAssetType::AT_GESTURE: | ||
352 | fRet = (m_Wearable.end() != std::find(m_Wearable.begin(), m_Wearable.end(), idParent)); | ||
353 | break; | ||
354 | #endif // RLV_EXPERIMENTAL_FORCEWEAR_GESTURES | ||
355 | default: | ||
356 | break; | ||
357 | } | ||
358 | return fRet; | ||
359 | } | ||
360 | |||
361 | // Checked: 2009-05-26 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d | ||
362 | bool RlvWearableItemCollector::operator()(LLInventoryCategory* pFolder, LLInventoryItem* pItem) | ||
363 | { | ||
364 | // NOTE: this is used for more than was originally intended so only modify if you're sure it won't break something obscure | ||
365 | return (pFolder) ? onCollectFolder(pFolder) : ( (pItem) ? onCollectItem(pItem) : false ); | ||
366 | } | ||
367 | |||
368 | // Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-0.2.0f | ||
369 | bool RlvSelectHasLockedAttach::apply(LLSelectNode* pNode) | ||
370 | { | ||
371 | return (pNode->getObject()) ? !gRlvHandler.isDetachable(pNode->getObject()) : false; | ||
372 | } | ||
373 | |||
374 | // Checked: 2009-07-05 (RLVa-1.0.0b) | Modified: RLVa-0.2.0f | ||
375 | bool RlvSelectIsOwnedByOrGroupOwned::apply(LLSelectNode* pNode) | ||
376 | { | ||
377 | return (pNode->mPermissions->isGroupOwned()) || (pNode->mPermissions->getOwner() == m_idAgent); | ||
378 | } | ||
379 | |||
380 | // Checked: 2009-05-31 (RLVa-0.2.0f) | Modified: RLVa-0.2.0f | ||
381 | bool RlvSelectIsSittingOn::apply(LLSelectNode* pNode) | ||
382 | { | ||
383 | return (pNode->getObject()) && (pNode->getObject()->getRootEdit() == m_pObject); | ||
384 | } | ||
385 | |||
386 | // Checked: 2009-07-05 (RLVa-1.0.0b) | Modified: RLVa-0.2.0g | ||
387 | bool rlvCanDeleteOrReturn() | ||
388 | { | ||
389 | bool fIsAllowed = true; | ||
390 | |||
391 | if (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) | ||
392 | { | ||
393 | // We'll allow if none of the prims are owned by the avie or group owned | ||
394 | LLObjectSelectionHandle handleSel = LLSelectMgr::getInstance()->getSelection(); | ||
395 | RlvSelectIsOwnedByOrGroupOwned func(gAgent.getID()); | ||
396 | if ( (handleSel.notNull()) && ((0 == handleSel->getRootObjectCount()) || (NULL != handleSel->getFirstRootNode(&func, FALSE))) ) | ||
397 | fIsAllowed = false; | ||
398 | } | ||
399 | |||
400 | if ( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (gAgent.getAvatarObject()) ) | ||
401 | { | ||
402 | // We'll allow if the avie isn't sitting on any of the selected objects | ||
403 | LLObjectSelectionHandle handleSel = LLSelectMgr::getInstance()->getSelection(); | ||
404 | RlvSelectIsSittingOn func(gAgent.getAvatarObject()->getRoot()); | ||
405 | if ( (handleSel.notNull()) && (handleSel->getFirstRootNode(&func, TRUE)) ) | ||
406 | fIsAllowed = false; | ||
407 | } | ||
408 | |||
409 | return fIsAllowed; | ||
410 | } | ||
411 | |||
412 | // Checked: 2009-07-05 (RLVa-1.0.0c) | ||
413 | BOOL rlvAttachToEnabler(void* pParam) | ||
414 | { | ||
415 | // Enables/disables an option on the "Attach to (HUD)" submenu depending on whether it is (un)detachable | ||
416 | LLViewerJointAttachment* pAttachment = (LLViewerJointAttachment*)pParam; | ||
417 | return (!pAttachment) || (gRlvHandler.isDetachable(pAttachment->getObject())); | ||
418 | } | ||
419 | |||
420 | BOOL RlvGCTimer::tick() | ||
421 | { | ||
422 | bool fContinue = gRlvHandler.onGC(); | ||
423 | if (!fContinue) | ||
424 | gRlvHandler.m_pGCTimer = NULL; | ||
425 | return !fContinue; | ||
426 | } | ||
427 | |||
428 | void RlvCurrentlyWorn::fetchWorn() | ||
429 | { | ||
430 | LLInventoryFetchObserver::item_ref_t idItems; | ||
431 | |||
432 | // Fetch all currently worn clothing layers and body parts | ||
433 | for (int type = 0; type < (int)WT_COUNT; type++) | ||
434 | { | ||
435 | const LLUUID& idItem = gAgent.getWearableItem((EWearableType)type); | ||
436 | if (idItem.notNull()) | ||
437 | idItems.push_back(idItem); | ||
438 | } | ||
439 | |||
440 | // Fetch all currently worn attachments | ||
441 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | ||
442 | if (pAvatar) | ||
443 | { | ||
444 | for (LLVOAvatar::attachment_map_t::const_iterator itAttach = pAvatar->mAttachmentPoints.begin(); | ||
445 | itAttach != pAvatar->mAttachmentPoints.end(); ++itAttach) | ||
446 | { | ||
447 | const LLUUID& idItem = itAttach->second->getItemID(); | ||
448 | if (idItem.notNull()) | ||
449 | idItems.push_back(idItem); | ||
450 | } | ||
451 | } | ||
452 | |||
453 | RlvCurrentlyWorn f; | ||
454 | f.fetchItems(idItems); | ||
455 | } | ||
456 | |||
457 | // ========================================================================= | ||
458 | |||
459 | // Checked: 2009-06-03 (RLVa-0.2.0h) | Added: RLVa-0.2.0h | ||
460 | void RlvWLSnapshot::restoreSnapshot(const RlvWLSnapshot* pWLSnapshot) | ||
461 | { | ||
462 | LLWLParamManager* pWLParams = LLWLParamManager::instance(); | ||
463 | if ( (pWLSnapshot) && (pWLParams) ) | ||
464 | { | ||
465 | pWLParams->mAnimator.mIsRunning = pWLSnapshot->fIsRunning; | ||
466 | pWLParams->mAnimator.mUseLindenTime = pWLSnapshot->fUseLindenTime; | ||
467 | pWLParams->mCurParams = pWLSnapshot->WLParams; | ||
468 | pWLParams->propagateParameters(); | ||
469 | } | ||
470 | } | ||
471 | |||
472 | // Checked: 2009-06-03 (RLVa-0.2.0h) | Added: RLVa-0.2.0h | ||
473 | RlvWLSnapshot* RlvWLSnapshot::takeSnapshot() | ||
474 | { | ||
475 | RlvWLSnapshot* pWLSnapshot = NULL; | ||
476 | LLWLParamManager* pWLParams = LLWLParamManager::instance(); | ||
477 | if (pWLParams) | ||
478 | { | ||
479 | pWLSnapshot = new RlvWLSnapshot(); | ||
480 | pWLSnapshot->fIsRunning = pWLParams->mAnimator.mIsRunning; | ||
481 | pWLSnapshot->fUseLindenTime = pWLParams->mAnimator.mUseLindenTime; | ||
482 | pWLSnapshot->WLParams = pWLParams->mCurParams; | ||
483 | } | ||
484 | return pWLSnapshot; | ||
485 | } | ||
486 | |||
487 | // ========================================================================= | ||
488 | |||
489 | BOOL RlvSettings::fShowNameTags = FALSE; | ||
490 | |||
491 | #ifdef RLV_EXTENSION_STARTLOCATION | ||
492 | // Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.1d | ||
493 | void RlvSettings::updateLoginLastLocation() | ||
494 | { | ||
495 | if (gSavedPerAccountSettings.controlExists(RLV_SETTING_LOGINLASTLOCATION)) | ||
496 | { | ||
497 | BOOL fValue = (gRlvHandler.hasBehaviour(RLV_BHVR_TPLOC)) || | ||
498 | ( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && | ||
499 | (gAgent.getAvatarObject()) && (!gAgent.getAvatarObject()->mIsSitting) ); | ||
500 | if (gSavedPerAccountSettings.getBOOL(RLV_SETTING_LOGINLASTLOCATION) != fValue) | ||
501 | { | ||
502 | gSavedPerAccountSettings.setBOOL(RLV_SETTING_LOGINLASTLOCATION, fValue); | ||
503 | gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE); | ||
504 | } | ||
505 | } | ||
506 | } | ||
507 | #endif // RLV_EXTENSION_STARTLOCATION | ||
508 | |||
509 | // ========================================================================= | ||
510 | |||
511 | #ifdef RLV_ADVANCED_TOGGLE_RLVA | ||
512 | // Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-1.0.0h | ||
513 | void rlvDbgToggleEnabled(void*) | ||
514 | { | ||
515 | gSavedSettings.setBOOL(RLV_SETTING_MAIN, !rlv_handler_t::isEnabled()); | ||
516 | |||
517 | #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 | ||
518 | LLStringUtil::format_map_t args; | ||
519 | args["[MESSAGE]"] = llformat("Restrained Life Support will be %s after you restart", | ||
520 | (rlv_handler_t::isEnabled()) ? "disabled" : "enabled" ); | ||
521 | gViewerWindow->alertXml("GenericAlert", args); | ||
522 | #else // Version: 1.23.4 | ||
523 | LLSD args; | ||
524 | args["MESSAGE"] = llformat("Restrained Life Support will be %s after you restart", | ||
525 | (rlv_handler_t::isEnabled()) ? "disabled" : "enabled" ); | ||
526 | LLNotifications::instance().add("GenericAlert", args); | ||
527 | #endif | ||
528 | } | ||
529 | // Checked: 2009-07-08 (RLVa-1.0.0e) | ||
530 | BOOL rlvDbgGetEnabled(void*) | ||
531 | { | ||
532 | return rlv_handler_t::isEnabled(); | ||
533 | } | ||
534 | #endif // RLV_ADVANCED_TOGGLE_RLVA | ||
535 | |||
536 | // ========================================================================= | ||
537 | // Message sending functions | ||
538 | // | ||
539 | |||
540 | // Checked: 2009-08-11 (RLVa-1.0.1h) | Added: RLVa-1.0.1h | ||
541 | void rlvForceDetach(LLViewerJointAttachment* pAttachPt) | ||
542 | { | ||
543 | // Copy/paste from handle_detach_from_avatar() | ||
544 | LLViewerObject* attached_object = pAttachPt->getObject(); | ||
545 | if (attached_object) | ||
546 | { | ||
547 | gMessageSystem->newMessage("ObjectDetach"); | ||
548 | gMessageSystem->nextBlockFast(_PREHASH_AgentData); | ||
549 | gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); | ||
550 | gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | ||
551 | |||
552 | gMessageSystem->nextBlockFast(_PREHASH_ObjectData); | ||
553 | gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, attached_object->getLocalID()); | ||
554 | gMessageSystem->sendReliable( gAgent.getRegionHost() ); | ||
555 | } | ||
556 | } | ||
557 | |||
558 | void rlvSendBusyMessage(const LLUUID& idTo, const std::string& strMsg, const LLUUID& idSession) | ||
559 | { | ||
560 | // (See process_improved_im) | ||
561 | std::string strFullName; | ||
562 | gAgent.buildFullname(strFullName); | ||
563 | |||
564 | pack_instant_message(gMessageSystem, gAgent.getID(), FALSE, gAgent.getSessionID(), idTo, strFullName, | ||
565 | strMsg, IM_ONLINE, IM_BUSY_AUTO_RESPONSE, idSession); | ||
566 | gAgent.sendReliableMessage(); | ||
567 | } | ||
568 | |||
569 | // Checked: 2009-08-05 (RLVa-1.0.1e) | Modified: RLVa-1.0.1e | ||
570 | bool rlvSendChatReply(S32 nChannel, const std::string& strReply) | ||
571 | { | ||
572 | if (!rlvIsValidChannel(nChannel)) | ||
573 | return false; | ||
574 | |||
575 | // Copy/paste from send_chat_from_viewer() | ||
576 | LLMessageSystem* msg = gMessageSystem; | ||
577 | msg->newMessageFast(_PREHASH_ChatFromViewer); | ||
578 | msg->nextBlockFast(_PREHASH_AgentData); | ||
579 | msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); | ||
580 | msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | ||
581 | msg->nextBlockFast(_PREHASH_ChatData); | ||
582 | msg->addStringFast(_PREHASH_Message, strReply); | ||
583 | msg->addU8Fast(_PREHASH_Type, CHAT_TYPE_SHOUT); | ||
584 | msg->addS32("Channel", nChannel); | ||
585 | gAgent.sendReliableMessage(); | ||
586 | LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT); | ||
587 | |||
588 | return true; | ||
589 | } | ||
590 | |||
591 | // ========================================================================= | ||
592 | // String helper functions | ||
593 | // | ||
594 | |||
595 | // Checked: 2009-07-04 (RLVa-1.0.0a) | ||
596 | void rlvStringReplace(std::string& strText, std::string strFrom, const std::string& strTo) | ||
597 | { | ||
598 | if (strFrom.empty()) | ||
599 | return; | ||
600 | |||
601 | size_t lenFrom = strFrom.length(); | ||
602 | size_t lenTo = strTo.length(); | ||
603 | |||
604 | std::string strTemp(strText); | ||
605 | LLStringUtil::toLower(strTemp); | ||
606 | LLStringUtil::toLower(strFrom); | ||
607 | |||
608 | std::string::size_type idxCur, idxStart = 0, idxOffset = 0; | ||
609 | while ( (idxCur = strTemp.find(strFrom, idxStart)) != std::string::npos) | ||
610 | { | ||
611 | strText.replace(idxCur + idxOffset, lenFrom, strTo); | ||
612 | idxStart = idxCur + lenFrom; | ||
613 | idxOffset += lenTo - lenFrom; | ||
614 | } | ||
615 | } | ||
616 | |||
617 | // Checked: 2009-07-29 (RLVa-1.0.1b) | Added: RLVa-1.0.1b | ||
618 | std::string rlvGetFirstParenthesisedText(const std::string& strText, std::string::size_type* pidxMatch /*=NULL*/) | ||
619 | { | ||
620 | if (pidxMatch) | ||
621 | *pidxMatch = std::string::npos; // Assume we won't find anything | ||
622 | |||
623 | std::string::size_type idxIt, idxStart; int cntLevel = 1; | ||
624 | if ((idxStart = strText.find_first_of('(')) == std::string::npos) | ||
625 | return std::string(); | ||
626 | |||
627 | const char* pstrText = strText.c_str(); idxIt = idxStart; | ||
628 | while ( (cntLevel > 0) && (idxIt < strText.length()) ) | ||
629 | { | ||
630 | if ('(' == pstrText[++idxIt]) | ||
631 | cntLevel++; | ||
632 | else if (')' == pstrText[idxIt]) | ||
633 | cntLevel--; | ||
634 | } | ||
635 | |||
636 | if (idxIt < strText.length()) | ||
637 | { | ||
638 | if (pidxMatch) | ||
639 | *pidxMatch = idxStart; // Return the character index of the starting '(' | ||
640 | return strText.substr(idxStart + 1, idxIt - idxStart - 1); | ||
641 | } | ||
642 | return std::string(); | ||
643 | } | ||
644 | |||
645 | // Checked: 2009-07-29 (RLVa-1.0.1b) | Added: RLVa-1.0.1b | ||
646 | std::string rlvGetLastParenthesisedText(const std::string& strText, std::string::size_type* pidxStart /*=NULL*/) | ||
647 | { | ||
648 | if (pidxStart) | ||
649 | *pidxStart = std::string::npos; // Assume we won't find anything | ||
650 | |||
651 | // Extracts the last - matched - parenthesised text from the input string | ||
652 | std::string::size_type idxIt, idxEnd; int cntLevel = 1; | ||
653 | if ((idxEnd = strText.find_last_of(')')) == std::string::npos) | ||
654 | return std::string(); | ||
655 | |||
656 | const char* pstrText = strText.c_str(); idxIt = idxEnd; | ||
657 | while ( (cntLevel > 0) && (idxIt >= 0) ) | ||
658 | { | ||
659 | if (')' == pstrText[--idxIt]) | ||
660 | cntLevel++; | ||
661 | else if ('(' == pstrText[idxIt]) | ||
662 | cntLevel--; | ||
663 | } | ||
664 | |||
665 | if ( (idxIt >= 0) && (idxIt < strText.length()) ) // NOTE: allow for std::string::size_type to be signed or unsigned | ||
666 | { | ||
667 | if (pidxStart) | ||
668 | *pidxStart = idxIt; // Return the character index of the starting '(' | ||
669 | return strText.substr(idxIt + 1, idxEnd - idxIt - 1); | ||
670 | } | ||
671 | return std::string(); | ||
672 | } | ||
673 | |||
674 | // ========================================================================= | ||
diff --git a/linden/indra/newview/rlvhelper.h b/linden/indra/newview/rlvhelper.h new file mode 100644 index 0000000..a0e040e --- /dev/null +++ b/linden/indra/newview/rlvhelper.h | |||
@@ -0,0 +1,579 @@ | |||
1 | #ifndef RLV_HELPER_H | ||
2 | #define RLV_HELPER_H | ||
3 | |||
4 | #include "llboost.h" | ||
5 | #include "llinventorymodel.h" | ||
6 | #include "llselectmgr.h" | ||
7 | #include "llviewercontrol.h" | ||
8 | #include "llviewerobjectlist.h" | ||
9 | #include "llwlparamset.h" | ||
10 | |||
11 | #include "rlvmultistringsearch.h" | ||
12 | |||
13 | // ============================================================================ | ||
14 | // Extensions | ||
15 | // | ||
16 | |||
17 | // Comment out if you don't want the Advanced / RLVa menu (may prevent enabling some extensions or experimental features - see below) | ||
18 | #define RLV_ADVANCED_MENU | ||
19 | // Comment out if you provide your own way to enable/disable RLVa | ||
20 | #define RLV_ADVANCED_TOGGLE_RLVA | ||
21 | |||
22 | // Provides access to "advanced" feature through the RLVa debug menu | ||
23 | #define RLV_EXTENSION_ENABLE_WEAR // "Enable Wear" | ||
24 | #define RLV_EXTENSION_HIDELOCKED // "Hide locked layers", "Hide locked attachments" and "Hide locked inventory" | ||
25 | #define RLV_EXTENSION_FLOATER_RESTRICTIONS // Enables the Advanced / RLVa / Restrictions... floater | ||
26 | |||
27 | // Extensions | ||
28 | #define RLV_EXTENSION_CMD_GETSETDEBUG_EX // Extends the debug variables accessible through @getdebug_xxx/@setdebug_xxx | ||
29 | #define RLV_EXTENSION_CMD_FINDFOLDERS // @findfolders:<option>=<channel> - @findfolder with multiple results | ||
30 | #define RLV_EXTENSION_FLAG_NOSTRIP // Layers and attachments marked as "nostrip" are exempt from @detach/@remoutfit | ||
31 | #define RLV_EXTENSION_STARTLOCATION // Reenables "Start Location" at login if not @tploc=n or @unsit=n restricted at last logoff | ||
32 | #define RLV_EXPERIMENTAL // Enables/disables experimental features en masse | ||
33 | |||
34 | // Experimental features | ||
35 | #ifdef RLV_EXPERIMENTAL | ||
36 | // Stable (will mature to RLV_EXTENSION_XXX in next release if no bugs are found) | ||
37 | #define RLV_EXPERIMENTAL_FARTOUCH_FEEDBACK // Enables "cleaner" UI responses when fartouch blocks something | ||
38 | |||
39 | // Under testing (stable, but requires further testing - safe for public release but may be quirky) | ||
40 | |||
41 | // Under development (don't include in public release) | ||
42 | #if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG | ||
43 | #endif // LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG | ||
44 | #endif // RLV_EXPERIMENTAL | ||
45 | |||
46 | // ============================================================================ | ||
47 | // Defines | ||
48 | // | ||
49 | |||
50 | // Version of the specifcation we support | ||
51 | const S32 RLV_VERSION_MAJOR = 1; | ||
52 | const S32 RLV_VERSION_MINOR = 20; | ||
53 | const S32 RLV_VERSION_PATCH = 0; | ||
54 | |||
55 | // Implementation version | ||
56 | const S32 RLVa_VERSION_MAJOR = 1; | ||
57 | const S32 RLVa_VERSION_MINOR = 0; | ||
58 | const S32 RLVa_VERSION_PATCH = 1; | ||
59 | const S32 RLVa_VERSION_BUILD = 7; | ||
60 | |||
61 | // The official viewer version we're patching against | ||
62 | #define RLV_MAKE_TARGET(x, y, z) ((x << 16) | (y << 8) | z) | ||
63 | #define RLV_TARGET RLV_MAKE_TARGET(1, 22, 11) | ||
64 | |||
65 | // Defining these makes it easier if we ever need to change our tag | ||
66 | #define RLV_WARNS LL_WARNS("RLV") | ||
67 | #define RLV_INFOS LL_INFOS("RLV") | ||
68 | #define RLV_DEBUGS LL_DEBUGS("RLV") | ||
69 | |||
70 | #if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG | ||
71 | // Turn on extended debugging information | ||
72 | #define RLV_DEBUG | ||
73 | // Make sure we halt execution on errors | ||
74 | #define RLV_ERRS LL_ERRS("RLV") | ||
75 | // Uncomment to enable the Advanced / RLVa / Unit Tests menu (non-public) | ||
76 | //#define RLV_DEBUG_TESTS | ||
77 | #else | ||
78 | // Uncomment if you want extended debugging information on release builds | ||
79 | //#define RLV_DEBUG | ||
80 | // Don't halt execution on errors in release | ||
81 | #define RLV_ERRS LL_WARNS("RLV") | ||
82 | #endif // LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG | ||
83 | |||
84 | #define RLV_ROOT_FOLDER "#RLV" | ||
85 | #define RLV_CMD_PREFIX '@' | ||
86 | #define RLV_PUTINV_PREFIX "#RLV/~" | ||
87 | #define RLV_SETROT_OFFSET F_PI_BY_TWO // @setrot is off by 90° with the rest of SL | ||
88 | |||
89 | #define RLV_FOLDER_FLAG_NOSTRIP "nostrip" | ||
90 | #define RLV_FOLDER_PREFIX_HIDDEN '.' | ||
91 | #define RLV_FOLDER_PREFIX_PUTINV '~' | ||
92 | |||
93 | // ============================================================================ | ||
94 | // Enumeration declarations | ||
95 | // | ||
96 | |||
97 | // NOTE: * any changes to this enumeration should be reflected in initLookupTable() | ||
98 | // * only uncomment the ones we actually use in a switch() to keep the size of the lookup table down | ||
99 | enum ERlvBehaviour { | ||
100 | RLV_BHVR_VERSION = 0, // "version" | ||
101 | RLV_BHVR_DETACH, // "detach" | ||
102 | // RLV_BHVR_SENDCHAT, // "sendchat" | ||
103 | // RLV_BHVR_EMOTE, // "emote" | ||
104 | // RLV_BHVR_CHATSHOUT, // "chatshout" | ||
105 | // RLV_BHVR_CHATNORMAL, // "chatnormal" | ||
106 | // RLV_BHVR_CHATWHISPER, // "chatwhisper" | ||
107 | RLV_BHVR_REDIRCHAT, // "redirchat" | ||
108 | RLV_BHVR_REDIREMOTE, // "rediremote" | ||
109 | RLV_BHVR_SENDIM, // "sendim" | ||
110 | RLV_BHVR_RECVCHAT, // "recvchat" | ||
111 | RLV_BHVR_RECVEMOTE, // "recvemote" | ||
112 | RLV_BHVR_RECVIM, // "recvim" | ||
113 | // RLV_BHVR_TPLM, // "tplm" | ||
114 | RLV_BHVR_TPLOC, // "tploc" | ||
115 | RLV_BHVR_TPLURE, // "tplure" | ||
116 | RLV_BHVR_SITTP, // "sittp" | ||
117 | // RLV_BHVR_CLEAR, // "clear" | ||
118 | RLV_BHVR_EDIT, // "edit" | ||
119 | RLV_BHVR_REZ, // "rez" | ||
120 | RLV_BHVR_ADDOUTFIT, // "addoutfit" | ||
121 | RLV_BHVR_REMOUTFIT, // "remoutfit" | ||
122 | RLV_BHVR_GETOUTFIT, // "getoutfit" | ||
123 | RLV_BHVR_GETATTACH, // "getattach" | ||
124 | RLV_BHVR_SHOWINV, // "showinv" | ||
125 | // RLV_BHVR_VIEWNOTE, // "viewnote" | ||
126 | RLV_BHVR_UNSIT, // "unsit" | ||
127 | RLV_BHVR_SIT, // "sit" | ||
128 | // RLV_BHVR_SENDCHANNEL, // "sendchannel" | ||
129 | RLV_BHVR_GETSTATUS, // "getstatus" | ||
130 | RLV_BHVR_GETSTATUSALL, // "getstatusall" | ||
131 | RLV_BHVR_GETINV, // "getinv" | ||
132 | RLV_BHVR_GETINVWORN, // "getinvworn" | ||
133 | RLV_BHVR_FINDFOLDER, // "findfolder" | ||
134 | RLV_BHVR_FINDFOLDERS, // "findfolders" | ||
135 | RLV_BHVR_ATTACH, // "attach" | ||
136 | RLV_BHVR_ATTACHALL, // "attachall" | ||
137 | RLV_BHVR_DETACHALL, // "detachall" | ||
138 | RLV_BHVR_GETPATH, // "getpath" | ||
139 | RLV_BHVR_ATTACHTHIS, // "attachthis" | ||
140 | RLV_BHVR_ATTACHALLTHIS, // "attachallthis" | ||
141 | RLV_BHVR_DETACHTHIS, // "detachthis" | ||
142 | RLV_BHVR_DETACHALLTHIS, // "detachallthis" | ||
143 | RLV_BHVR_FARTOUCH, // "fartouch" | ||
144 | RLV_BHVR_SHOWWORLDMAP, // "showworldmap" | ||
145 | RLV_BHVR_SHOWMINIMAP, // "showminimap" | ||
146 | RLV_BHVR_SHOWLOC, // "showloc" | ||
147 | RLV_BHVR_TPTO, // "tpto" | ||
148 | RLV_BHVR_ACCEPTTP, // "accepttp" | ||
149 | RLV_BHVR_SHOWNAMES, // "shownames" | ||
150 | RLV_BHVR_FLY, // "fly" | ||
151 | RLV_BHVR_GETSITID, // "getsitid" | ||
152 | RLV_BHVR_SETDEBUG, // "setdebug" | ||
153 | RLV_BHVR_SETENV, // "setenv" | ||
154 | RLV_BHVR_DETACHME, // "detachme" | ||
155 | RLV_BHVR_SHOWHOVERTEXTALL, // "showhovertextall" | ||
156 | RLV_BHVR_SHOWHOVERTEXTWORLD, // "showhovertextworld" | ||
157 | RLV_BHVR_SHOWHOVERTEXTHUD, // "showhovertexthud" | ||
158 | RLV_BHVR_SHOWHOVERTEXT, // "showhovertext" | ||
159 | RLV_BHVR_NOTIFY, // "notify" | ||
160 | |||
161 | RLV_BHVR_COUNT, | ||
162 | RLV_BHVR_UNKNOWN | ||
163 | }; | ||
164 | |||
165 | enum ERlvParamType { | ||
166 | RLV_TYPE_UNKNOWN, | ||
167 | RLV_TYPE_ADD, // <param> == "n"|"add" | ||
168 | RLV_TYPE_REMOVE, // <param> == "y"|"rem" | ||
169 | RLV_TYPE_FORCE, // <param> == "force" | ||
170 | RLV_TYPE_REPLY // <param> == <number> | ||
171 | }; | ||
172 | |||
173 | enum ERlvCmdRet { | ||
174 | RLV_RET_NOERROR, // Command executed succesfully | ||
175 | RLV_RET_RETAINED, // Command was retained | ||
176 | RLV_RET_FAILED, // Command failed (general failure) | ||
177 | RLV_RET_FAILED_SYNTAX, // Command failed (syntax error) | ||
178 | RLV_RET_FAILED_UNSET, // Command failed (unset restriction) | ||
179 | RLV_RET_FAILED_DUPLICATE, // Command failed (duplicate) | ||
180 | RLV_RET_FAILED_OPTION, // Command failed (invalid option) | ||
181 | RLV_RET_UNKNOWN // Command unkown | ||
182 | }; | ||
183 | |||
184 | // ============================================================================ | ||
185 | /* | ||
186 | * RlvCommand | ||
187 | * ========== | ||
188 | * Encapsulates an "RLV command" (duh :p) | ||
189 | * | ||
190 | */ | ||
191 | |||
192 | class RlvCommand | ||
193 | { | ||
194 | public: | ||
195 | /* | ||
196 | * Constructors | ||
197 | */ | ||
198 | explicit RlvCommand(const std::string& strCommand); | ||
199 | RlvCommand(const RlvCommand& rlvCmd); | ||
200 | |||
201 | /* | ||
202 | * Accessors | ||
203 | */ | ||
204 | BOOL isValid() const { return m_fValid; } | ||
205 | |||
206 | const std::string& getBehaviour() const { return m_strBehaviour; } | ||
207 | ERlvBehaviour getBehaviourType() const { return m_eBehaviour; } | ||
208 | const std::string& getOption() const { return m_strOption; } | ||
209 | const std::string& getParam() const { return m_strParam; } | ||
210 | ERlvParamType getParamType() const { return m_eParamType; } | ||
211 | |||
212 | std::string asString() const; | ||
213 | |||
214 | /* | ||
215 | * Operators | ||
216 | */ | ||
217 | bool operator ==(const RlvCommand&) const; | ||
218 | |||
219 | // Parses an RLV command into its "tokens" | ||
220 | static BOOL parseCommand(/*[in]*/ const std::string& strCommand, | ||
221 | /*[out]*/ std::string& strBehaviour, /*[out]*/ std::string& strOption, /*[out]*/ std::string& strParam); | ||
222 | static void initLookupTable(); | ||
223 | |||
224 | /* | ||
225 | * Member variables | ||
226 | */ | ||
227 | protected: | ||
228 | BOOL m_fValid; | ||
229 | std::string m_strBehaviour; | ||
230 | ERlvBehaviour m_eBehaviour; | ||
231 | std::string m_strOption; | ||
232 | std::string m_strParam; | ||
233 | ERlvParamType m_eParamType; | ||
234 | |||
235 | static RlvMultiStringSearch m_BhvrLookup; | ||
236 | friend class RlvHandler; | ||
237 | }; | ||
238 | |||
239 | // ============================================================================ | ||
240 | /* | ||
241 | * RlvObject | ||
242 | * ========= | ||
243 | * Encapsulates an "RLV Object" (= an object that has issued an RLV command) | ||
244 | * | ||
245 | */ | ||
246 | |||
247 | typedef std::list<RlvCommand> rlv_command_list_t; | ||
248 | |||
249 | class RlvObject | ||
250 | { | ||
251 | public: | ||
252 | RlvObject(const LLUUID& uuid) : m_UUID(uuid), m_nLookupMisses(0) { m_fLookup = (NULL != gObjectList.findObject(uuid)); } | ||
253 | |||
254 | BOOL addCommand(const RlvCommand& rlvCmd); | ||
255 | BOOL removeCommand(const RlvCommand& rlvCmd); | ||
256 | |||
257 | BOOL hasBehaviour(ERlvBehaviour eBehaviour) const; | ||
258 | BOOL hasBehaviour(const std::string& strBehaviour) const; | ||
259 | BOOL hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption) const; | ||
260 | BOOL hasBehaviour(const std::string& strBehaviour, const std::string& strOption) const; | ||
261 | |||
262 | std::string getStatusString(const std::string& strMatch) const; | ||
263 | |||
264 | const rlv_command_list_t* getCommandList() const { return &m_Commands; } | ||
265 | protected: | ||
266 | LLUUID m_UUID; // The object's UUID | ||
267 | bool m_fLookup; // TRUE if the object existed in gObjectList at one point in time | ||
268 | S16 m_nLookupMisses; // Count of unsuccessful lookups in gObjectList by the GC | ||
269 | rlv_command_list_t m_Commands; // List of behaviours held by this object (in the order they were received) | ||
270 | |||
271 | friend class RlvHandler; | ||
272 | }; | ||
273 | |||
274 | // ============================================================================ | ||
275 | /* | ||
276 | * RlvCriteriaCategoryCollector | ||
277 | * ============================ | ||
278 | * Criteria based folder matching filter used by @findfolder and @findfolders | ||
279 | * | ||
280 | */ | ||
281 | |||
282 | class RlvCriteriaCategoryCollector : public LLInventoryCollectFunctor | ||
283 | { | ||
284 | public: | ||
285 | RlvCriteriaCategoryCollector(const std::string& strCriteria) | ||
286 | { | ||
287 | typedef boost::tokenizer<boost::char_separator<char> > tokenizer; | ||
288 | boost::char_separator<char> sep("&&", "", boost::drop_empty_tokens); | ||
289 | tokenizer tokens(strCriteria, sep); | ||
290 | for (tokenizer::iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken) | ||
291 | m_Criteria.push_back(*itToken); | ||
292 | } | ||
293 | virtual ~RlvCriteriaCategoryCollector() {} | ||
294 | |||
295 | virtual bool operator()(LLInventoryCategory* pFolder, LLInventoryItem* pItem) | ||
296 | { | ||
297 | if ( (!pFolder) || (m_Criteria.empty()) ) // We're only interested in matching folders, we don't care about items | ||
298 | return false; // (if there are no criteria then we don't want to return a match) | ||
299 | |||
300 | std::string strFolderName = pFolder->getName(); | ||
301 | LLStringUtil::toLower(strFolderName); | ||
302 | |||
303 | if ( (strFolderName.empty()) || (RLV_FOLDER_PREFIX_HIDDEN == strFolderName[0]) ) | ||
304 | return false; | ||
305 | |||
306 | for (std::list<std::string>::const_iterator itCrit = m_Criteria.begin(); itCrit != m_Criteria.end(); ++itCrit) | ||
307 | if (-1 == strFolderName.find(*itCrit)) // Return false on the first mismatch | ||
308 | return false; | ||
309 | return true; | ||
310 | } | ||
311 | |||
312 | protected: | ||
313 | std::list<std::string> m_Criteria; | ||
314 | }; | ||
315 | |||
316 | // ============================================================================ | ||
317 | /* | ||
318 | * RlvWearableItemCollector | ||
319 | * ======================== | ||
320 | * Inventory item filter used by attach/detach/attachall/detachall/getinvworn (also used by "Add/Replace Outfit" and "Take Off Items") | ||
321 | * | ||
322 | */ | ||
323 | |||
324 | class RlvWearableItemCollector : public LLInventoryCollectFunctor | ||
325 | { | ||
326 | public: | ||
327 | RlvWearableItemCollector(const LLUUID& idFolder, bool fAttach, bool fMatchAll) | ||
328 | : m_idFolder(idFolder), m_fAttach(fAttach), m_fMatchAll(fMatchAll) | ||
329 | { | ||
330 | m_Wearable.push_back(idFolder); | ||
331 | } | ||
332 | virtual ~RlvWearableItemCollector() {} | ||
333 | |||
334 | virtual bool operator()(LLInventoryCategory* pFolder, LLInventoryItem* pItem); | ||
335 | |||
336 | const LLUUID& getFoldedParent(const LLUUID& idFolder) const; | ||
337 | protected: | ||
338 | bool m_fAttach; | ||
339 | bool m_fMatchAll; | ||
340 | const LLUUID m_idFolder; | ||
341 | |||
342 | bool onCollectFolder(const LLInventoryCategory* pFolder); | ||
343 | bool onCollectItem(const LLInventoryItem* pItem); | ||
344 | |||
345 | std::list<LLUUID> m_Tentative; | ||
346 | std::list<LLUUID> m_Wearable; | ||
347 | |||
348 | std::map<LLUUID, LLUUID> m_Folding; | ||
349 | }; | ||
350 | |||
351 | // ============================================================================ | ||
352 | /* | ||
353 | * RlvRetainedCommand | ||
354 | * ================== | ||
355 | * | ||
356 | */ | ||
357 | |||
358 | struct RlvRetainedCommand | ||
359 | { | ||
360 | public: | ||
361 | std::string strObject; | ||
362 | LLUUID idObject; | ||
363 | std::string strCmd; | ||
364 | |||
365 | RlvRetainedCommand(const std::string obj, const LLUUID& uuid, const std::string& cmd) : strObject(obj), idObject(uuid), strCmd(cmd) {} | ||
366 | private: | ||
367 | RlvRetainedCommand(); | ||
368 | }; | ||
369 | typedef std::list<RlvRetainedCommand> rlv_retained_list_t; | ||
370 | |||
371 | // ============================================================================ | ||
372 | /* | ||
373 | * RlvWLSnapshot | ||
374 | * ============= | ||
375 | * | ||
376 | */ | ||
377 | |||
378 | struct RlvWLSnapshot | ||
379 | { | ||
380 | public: | ||
381 | static void restoreSnapshot(const RlvWLSnapshot* pWLSnapshot); | ||
382 | static RlvWLSnapshot* takeSnapshot(); | ||
383 | private: | ||
384 | RlvWLSnapshot() {} | ||
385 | |||
386 | bool fIsRunning; | ||
387 | bool fUseLindenTime; | ||
388 | LLWLParamSet WLParams; | ||
389 | }; | ||
390 | |||
391 | // ============================================================================ | ||
392 | /* | ||
393 | * RlvSettings | ||
394 | * =========== | ||
395 | * | ||
396 | */ | ||
397 | |||
398 | #define RLV_SETTING_MAIN "RestrainedLife" | ||
399 | #define RLV_SETTING_DEBUG "RestrainedLifeDebug" | ||
400 | #define RLV_SETTING_NOSETENV "RestrainedLifeNoSetEnv" | ||
401 | #define RLV_SETTING_FORBIDGIVETORLV "RestrainedLifeForbidGiveToRLV" | ||
402 | |||
403 | #define RLV_SETTING_ENABLEWEAR "RLVaEnableWear" | ||
404 | #define RLV_SETTING_ENABLELEGACYNAMING "RLVaEnableLegacyNaming" | ||
405 | #define RLV_SETTING_HIDELOCKEDLAYER "RLVaHideLockedLayers" | ||
406 | #define RLV_SETTING_HIDELOCKEDATTACH "RLVaHideLockedAttachments" | ||
407 | #define RLV_SETTING_HIDELOCKEDINVENTORY "RLVaHideLockedInventory" | ||
408 | #define RLV_SETTING_LOGINLASTLOCATION "RLVaLoginLastLocation" | ||
409 | #define RLV_SETTING_SHOWNAMETAGS "RLVaShowNameTags" | ||
410 | |||
411 | inline BOOL rlvGetSettingBOOL(const std::string& strSetting, BOOL fDefault) | ||
412 | { | ||
413 | return (gSavedSettings.controlExists(strSetting)) ? gSavedSettings.getBOOL(strSetting) : fDefault; | ||
414 | } | ||
415 | inline BOOL rlvGetPerUserSettingsBOOL(const std::string& strSetting, BOOL fDefault) | ||
416 | { | ||
417 | return (gSavedPerAccountSettings.controlExists(strSetting)) ? gSavedPerAccountSettings.getBOOL(strSetting) : fDefault; | ||
418 | } | ||
419 | |||
420 | class RlvSettings | ||
421 | { | ||
422 | public: | ||
423 | static BOOL getDebug() { return rlvGetSettingBOOL(RLV_SETTING_DEBUG, FALSE); } | ||
424 | static BOOL getForbidGiveToRLV() { return rlvGetSettingBOOL(RLV_SETTING_FORBIDGIVETORLV, TRUE); } | ||
425 | |||
426 | static BOOL getEnableWear() { return rlvGetSettingBOOL(RLV_SETTING_ENABLEWEAR, FALSE); } | ||
427 | static BOOL getHideLockedLayers() { return rlvGetSettingBOOL(RLV_SETTING_HIDELOCKEDLAYER, FALSE); } | ||
428 | static BOOL getHideLockedAttach() { return rlvGetSettingBOOL(RLV_SETTING_HIDELOCKEDATTACH, FALSE); } | ||
429 | static BOOL getHideLockedInventory() { return rlvGetSettingBOOL(RLV_SETTING_HIDELOCKEDINVENTORY, FALSE); } | ||
430 | |||
431 | #ifdef RLV_EXTENSION_STARTLOCATION | ||
432 | static BOOL getLoginLastLocation() { return rlvGetPerUserSettingsBOOL(RLV_SETTING_LOGINLASTLOCATION, TRUE); } | ||
433 | static void updateLoginLastLocation(); | ||
434 | #endif // RLV_EXTENSION_STARTLOCATION | ||
435 | |||
436 | static BOOL fShowNameTags; | ||
437 | }; | ||
438 | |||
439 | // ============================================================================ | ||
440 | /* | ||
441 | * State keeping classes/structure | ||
442 | * | ||
443 | */ | ||
444 | |||
445 | struct RlvRedirInfo | ||
446 | { | ||
447 | S16 nRedirChat; | ||
448 | S16 nRedirEmote; | ||
449 | |||
450 | RlvRedirInfo() : nRedirChat(0), nRedirEmote(0) {} | ||
451 | bool isActive() { return (nRedirChat + nRedirEmote) != 0; } | ||
452 | }; | ||
453 | |||
454 | struct RlvReattachInfo | ||
455 | { | ||
456 | LLUUID idItem; | ||
457 | bool fInInventory; | ||
458 | bool fAssetSaved; | ||
459 | |||
460 | RlvReattachInfo() : idItem(), fInInventory(false), fAssetSaved(false) {} | ||
461 | }; | ||
462 | |||
463 | // ============================================================================ | ||
464 | /* | ||
465 | * Various helper classes/timers/functors | ||
466 | * | ||
467 | */ | ||
468 | |||
469 | class RlvGCTimer : public LLEventTimer | ||
470 | { | ||
471 | public: | ||
472 | RlvGCTimer() : LLEventTimer(30.0) {} | ||
473 | virtual BOOL tick(); | ||
474 | }; | ||
475 | |||
476 | class RlvCurrentlyWorn : public LLInventoryFetchObserver | ||
477 | { | ||
478 | public: | ||
479 | RlvCurrentlyWorn() {} | ||
480 | ~RlvCurrentlyWorn() {} | ||
481 | virtual void done() {} | ||
482 | |||
483 | static void fetchWorn(); | ||
484 | void fetchItem(const LLUUID& idItem); | ||
485 | }; | ||
486 | |||
487 | struct RlvSelectHasLockedAttach : public LLSelectedNodeFunctor | ||
488 | { | ||
489 | virtual bool apply(LLSelectNode* pNode); | ||
490 | }; | ||
491 | |||
492 | struct RlvSelectIsOwnedByOrGroupOwned : public LLSelectedNodeFunctor | ||
493 | { | ||
494 | RlvSelectIsOwnedByOrGroupOwned(const LLUUID& uuid) : m_idAgent(uuid) {} | ||
495 | virtual bool apply(LLSelectNode* pNode); | ||
496 | LLUUID m_idAgent; | ||
497 | }; | ||
498 | |||
499 | struct RlvSelectIsSittingOn : public LLSelectedNodeFunctor | ||
500 | { | ||
501 | RlvSelectIsSittingOn(LLXform* pObject) : m_pObject(pObject) {} | ||
502 | virtual bool apply(LLSelectNode* pNode); | ||
503 | LLXform* m_pObject; | ||
504 | }; | ||
505 | |||
506 | // ============================================================================ | ||
507 | /* | ||
508 | * Various helper functions | ||
509 | * | ||
510 | */ | ||
511 | |||
512 | BOOL rlvAttachToEnabler(void* pParam); | ||
513 | bool rlvCanDeleteOrReturn(); | ||
514 | S32 rlvGetDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType::EType type); | ||
515 | bool rlvIsEmote(const std::string& strUTF8Text); | ||
516 | bool rlvIsValidChannel(S32 nChannel); | ||
517 | bool rlvIsWearingItem(const LLInventoryItem* pItem); | ||
518 | |||
519 | void rlvForceDetach(LLViewerJointAttachment* pAttachPt); | ||
520 | void rlvSendBusyMessage(const LLUUID& idTo, const std::string& strMsg, const LLUUID& idSession = LLUUID::null); | ||
521 | bool rlvSendChatReply(const std::string& strChannel, const std::string& strReply); | ||
522 | bool rlvSendChatReply(S32 nChannel, const std::string& strReply); | ||
523 | |||
524 | void rlvStringReplace(std::string& strText, std::string strFrom, const std::string& strTo); | ||
525 | std::string rlvGetFirstParenthesisedText(const std::string& strText, std::string::size_type* pidxMatch = NULL); | ||
526 | std::string rlvGetLastParenthesisedText(const std::string& strText, std::string::size_type* pidxStart = NULL); | ||
527 | |||
528 | #ifdef RLV_ADVANCED_TOGGLE_RLVA | ||
529 | // "Advanced / RLVa / Enable RLV" menu option | ||
530 | void rlvDbgToggleEnabled(void*); | ||
531 | BOOL rlvDbgGetEnabled(void*); | ||
532 | #endif // RLV_ADVANCED_TOGGLE_RLVA | ||
533 | |||
534 | // ============================================================================ | ||
535 | // Inlined class member functions | ||
536 | // | ||
537 | |||
538 | inline bool RlvCommand::operator ==(const RlvCommand& rhs) const | ||
539 | { | ||
540 | // The specification notes that "@detach=n" is semantically identical to "@detach=add" (same for "y" and "rem" | ||
541 | return (m_strBehaviour == rhs.m_strBehaviour) && (m_strOption == rhs.m_strOption) && | ||
542 | ( (RLV_TYPE_UNKNOWN != m_eParamType) ? (m_eParamType == rhs.m_eParamType) : (m_strParam == rhs.m_strParam) ); | ||
543 | } | ||
544 | |||
545 | inline void RlvCurrentlyWorn::fetchItem(const LLUUID& idItem) | ||
546 | { | ||
547 | if (idItem.notNull()) | ||
548 | { | ||
549 | LLInventoryFetchObserver::item_ref_t idItems; | ||
550 | idItems.push_back(idItem); | ||
551 | fetchItems(idItems); | ||
552 | } | ||
553 | } | ||
554 | |||
555 | // ============================================================================ | ||
556 | // Inlined helper functions | ||
557 | // | ||
558 | |||
559 | inline bool rlvIsEmote(const std::string& strUTF8Text) | ||
560 | { | ||
561 | return (strUTF8Text.length() > 4) && ( (strUTF8Text.compare(0, 4, "/me ") == 0) || (strUTF8Text.compare(0, 4, "/me'") == 0) ); | ||
562 | } | ||
563 | |||
564 | // Checked: 2009-08-05 (RLVa-1.0.1e) | Added: RLVa-1.0.0e | ||
565 | inline bool rlvIsValidChannel(S32 nChannel) | ||
566 | { | ||
567 | return (nChannel >= 0) && (CHAT_CHANNEL_DEBUG != nChannel); | ||
568 | } | ||
569 | |||
570 | // Checked: 2009-08-05 (RLVa-1.0.1e) | Added: RLVa-1.0.0e | ||
571 | inline bool rlvSendChatReply(const std::string& strChannel, const std::string& strReply) | ||
572 | { | ||
573 | S32 nChannel; | ||
574 | return (LLStringUtil::convertToS32(strChannel, nChannel)) ? rlvSendChatReply(nChannel, strReply) : false; | ||
575 | } | ||
576 | |||
577 | // ============================================================================ | ||
578 | |||
579 | #endif // RLV_HELPER_H | ||
diff --git a/linden/indra/newview/rlvmultistringsearch.cpp b/linden/indra/newview/rlvmultistringsearch.cpp new file mode 100644 index 0000000..0aa9889 --- /dev/null +++ b/linden/indra/newview/rlvmultistringsearch.cpp | |||
@@ -0,0 +1,196 @@ | |||
1 | #include "llviewerprecompiledheaders.h" | ||
2 | |||
3 | #include "rlvmultistringsearch.h" | ||
4 | |||
5 | // ==================================================================================== | ||
6 | |||
7 | #ifndef RLV_LOWORD | ||
8 | #define RLV_LOWORD(x) ( (U16)( ((U32)x) & 0xFFFF) ) | ||
9 | #endif // RLV_LOWORD | ||
10 | |||
11 | #ifndef RLV_HIWORD | ||
12 | #define RLV_HIWORD(x) ( (U16)( (((U32)x) >> 16) & 0xFFFF) ) | ||
13 | #endif // RLV_HIWORD | ||
14 | |||
15 | // ==================================================================================== | ||
16 | |||
17 | // (TODO-RLV: oops, forgot I was experimenting with word matching, get rid of that again?) | ||
18 | #define isLetter(ch) \ | ||
19 | ( ( (ch >= 'a') && (ch <= 'z') ) || ( (ch >= 'A') && (ch <= 'Z') ) ) | ||
20 | |||
21 | RlvMultiStringSearch::RlvMultiStringSearch() | ||
22 | : m_FSM(256), // Start our FSM with room for 256 states (enough for all attachment point names) | ||
23 | m_cntState(0) | ||
24 | { | ||
25 | } | ||
26 | |||
27 | void RlvMultiStringSearch::addKeyword(const std::string& strKeyword, U16 nParam) { | ||
28 | U16 nCurState = 0; // Always start the loop at state 0 | ||
29 | |||
30 | // | ||
31 | // Make sure there are enough unused rows to accomodate the worst case (== strKeyword.length() new states) | ||
32 | // | ||
33 | size_t nMaxState = m_FSM.getSize(); | ||
34 | if (m_cntState + strKeyword.length() > nMaxState) | ||
35 | // Allocate enough new rows (in batches of 256 rows) | ||
36 | m_FSM.resize(nMaxState + ((strKeyword.length() / 256) + 1) * 256); | ||
37 | |||
38 | // | ||
39 | // Walk the string character by character | ||
40 | // | ||
41 | for (int idxCh = 0, cntCh = strKeyword.length(); idxCh < cntCh; idxCh++) { | ||
42 | // Look up the next state for current character | ||
43 | unsigned char ch = strKeyword[idxCh]; | ||
44 | U16 nState = RLV_LOWORD(m_FSM[nCurState][ch]); | ||
45 | |||
46 | // If we're at the last character in the keyword then set the termination bit | ||
47 | if (cntCh - 1 == idxCh) | ||
48 | { | ||
49 | // (Only set the termination bit for the state because this keyword might be a substring of another keyword) | ||
50 | m_FSM[nCurState][ch] = (nParam << 16) | (nState | 0x8000); | ||
51 | } | ||
52 | else if ( (nState & 0x7FFF) == 0 ) // If the new state is 0 then we're creating a new path | ||
53 | { | ||
54 | // (Preserve the termination bit because another keyword might be a substring of this one) | ||
55 | nState = ++m_cntState | (nState & 0x8000); | ||
56 | |||
57 | // Store the new path in the FSM | ||
58 | //m_FSM[nCurState][ch] = (nParam << 16) | nState; | ||
59 | m_FSM[nCurState][ch] |= nState; | ||
60 | } | ||
61 | |||
62 | nCurState = nState & 0x7FFF; // Mask out the termination bit since we never need it for the current state | ||
63 | } | ||
64 | } | ||
65 | |||
66 | // (Iterating over a "const char*" is *significantly* faster than "std::string") | ||
67 | bool RlvMultiStringSearch::findNext(const char* pstrText, int idxCh, int cntCh, RlvMultiStringSearchMatch& match, bool fWordMatch) const | ||
68 | { | ||
69 | U16 nCurState = 0; // Always start the loop at state 0 | ||
70 | U32 nLastMatch = 0; // Holds the state of the last (possibly partial) keyword match | ||
71 | |||
72 | // | ||
73 | // Walk the string character by character | ||
74 | // | ||
75 | for (; idxCh < cntCh; idxCh++) | ||
76 | { | ||
77 | // Keep track of the current state in case we need to backtrack | ||
78 | U16 nPrevState = nCurState; | ||
79 | |||
80 | // If we're currently in state 0, save the current character index (for backtracking or as keyword index match) | ||
81 | if (nCurState == 0) | ||
82 | match.idxMatch = idxCh; | ||
83 | |||
84 | // Look up the current character in the FSM | ||
85 | unsigned char ch = (unsigned char)pstrText[idxCh]; | ||
86 | U32 nCell = m_FSM[nCurState & 0x7FFF][ch]; | ||
87 | |||
88 | // If the termination bit is set then we found a keyword substring match | ||
89 | // If the next state is non-zero then we can't stop yet because the matched keyword might be a substring of another keyword | ||
90 | if (nCell & 0x8000) | ||
91 | { | ||
92 | if ( 0 == (nCell & 0x7FFF) ) | ||
93 | { | ||
94 | // Termination bit with 'next state' equal to 0: matched keyword which isn't also a substring of any other keyword | ||
95 | match.lenMatch = idxCh - match.idxMatch + 1; | ||
96 | match.nParam = RLV_HIWORD(nCell); | ||
97 | |||
98 | // Rudimentary word matching: check if the match is a 'word' | ||
99 | if | ||
100 | ( | ||
101 | (!fWordMatch) || | ||
102 | ( | ||
103 | ( (0 == match.idxMatch) || (!isLetter(pstrText[match.idxMatch - 1])) ) && // Start of string OR non-letter | ||
104 | ( (!isLetter(pstrText[match.idxMatch + match.lenMatch])) ) | ||
105 | ) | ||
106 | ) | ||
107 | { | ||
108 | return true; | ||
109 | } | ||
110 | |||
111 | // Not a word, but there's no need to backtrack: we can move on from the character after the current one | ||
112 | nCell = 0; // Will set nCurState == 0 further down | ||
113 | match.idxMatch = idxCh; // Makes sure we move on to the next character instead of backtracking | ||
114 | } | ||
115 | else | ||
116 | { | ||
117 | nLastMatch = nCell; | ||
118 | |||
119 | // In case it turns out that we need to backtrack and return this match, save the length of this match | ||
120 | match.lenMatch = idxCh - match.idxMatch + 1; | ||
121 | } | ||
122 | } | ||
123 | |||
124 | nCurState = RLV_LOWORD(nCell); | ||
125 | |||
126 | // If our new state is 0, but our previous state wasn't, then we followed a false lead and need to backtrack | ||
127 | if ( (nPrevState != 0) && (nCurState == 0) ) | ||
128 | { | ||
129 | // * if nLastMatch == 0 then we need to backtrack and keep going | ||
130 | // * if nLastMatch != 0 then we previously encountered a keyword match so return that one | ||
131 | if (nLastMatch) { | ||
132 | // Rudimentary word matching: check if the match is a 'word' | ||
133 | if | ||
134 | ( | ||
135 | (!fWordMatch) || | ||
136 | ( | ||
137 | ( (0 == match.idxMatch) || (!isLetter(pstrText[match.idxMatch - 1])) ) && // Start of string OR non-letter | ||
138 | ( (!isLetter(pstrText[match.idxMatch + match.lenMatch])) ) | ||
139 | ) | ||
140 | ) | ||
141 | { | ||
142 | match.nParam = RLV_HIWORD(nLastMatch); | ||
143 | return true; | ||
144 | } else | ||
145 | // Not a word match, so throw away this partial match and backtrack | ||
146 | nLastMatch = 0; | ||
147 | } | ||
148 | |||
149 | idxCh = match.idxMatch; | ||
150 | } | ||
151 | } | ||
152 | |||
153 | // We encountered a match, but while investigating whether it was a substring of another keyword we ran out of characters | ||
154 | if (nLastMatch) | ||
155 | { | ||
156 | // Rudimentary word matching: check if we started at the beginning of a word (we know the one behind us is '\0') | ||
157 | if ( (!fWordMatch) || ( (0 == match.idxMatch) || (!isLetter(pstrText[match.idxMatch - 1])) ) ) | ||
158 | { | ||
159 | match.nParam = RLV_HIWORD(nLastMatch); | ||
160 | return true; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | // None of the keywords is contained in the string: return failure | ||
165 | match.idxMatch = -1; | ||
166 | return false; | ||
167 | } | ||
168 | |||
169 | bool RlvMultiStringSearch::findLast(const std::string& strText, RlvMultiStringSearchMatch& match) const { | ||
170 | RlvMultiStringSearchMatch matchTemp; | ||
171 | match.idxMatch = -1; // (Needed to make the return work in case we don't find anything) | ||
172 | matchTemp.lenMatch = 0; // (Needed to make the first loop iteration start at 0) | ||
173 | |||
174 | // Iterating over a "const char*" is *significantly* faster than "std::string" | ||
175 | const char* pstrText = strText.c_str(); | ||
176 | int lenText = strText.length(); | ||
177 | |||
178 | while (findNext(pstrText, matchTemp.idxMatch + matchTemp.lenMatch + 1, lenText, matchTemp)) | ||
179 | match = matchTemp; | ||
180 | |||
181 | return (match.idxMatch != -1); | ||
182 | } | ||
183 | |||
184 | std::vector<RlvMultiStringSearchMatch> RlvMultiStringSearch::findAll(const std::string& strText) { | ||
185 | std::vector<RlvMultiStringSearchMatch> arMatch; | ||
186 | |||
187 | RlvMultiStringSearchMatch match; | ||
188 | match.lenMatch = 0; // (Needed to make the first loop iteration start at 0) | ||
189 | |||
190 | while (findNext(strText, match.idxMatch + match.lenMatch + 1, match)) | ||
191 | arMatch.push_back(match); | ||
192 | |||
193 | return arMatch; | ||
194 | } | ||
195 | |||
196 | // ==================================================================================== | ||
diff --git a/linden/indra/newview/rlvmultistringsearch.h b/linden/indra/newview/rlvmultistringsearch.h new file mode 100644 index 0000000..43b0172 --- /dev/null +++ b/linden/indra/newview/rlvmultistringsearch.h | |||
@@ -0,0 +1,191 @@ | |||
1 | #ifndef RLV_MULTISTRINGSEARCH_H | ||
2 | #define RLV_MULTISTRINGSEARCH_H | ||
3 | |||
4 | // ============================================================================ | ||
5 | // Template classes for our state machine (2 dimensional array of type T) | ||
6 | |||
7 | // STL vector | ||
8 | template<typename T> class RlvMultiStringSearchFSM_STL | ||
9 | { | ||
10 | public: | ||
11 | /* | ||
12 | * Constructor/destructor | ||
13 | */ | ||
14 | |||
15 | // Initialize the FSM with an initial capacity of 'nCapacity' states | ||
16 | RlvMultiStringSearchFSM_STL(size_t nCapacity) | ||
17 | { | ||
18 | m_arFSM.reserve(nCapacity); | ||
19 | |||
20 | T* pT; | ||
21 | for (size_t idx = 0; idx < nCapacity; idx++) | ||
22 | { | ||
23 | // The width of each row is determined by the alphabet we're using (in this case UTF-8 | ||
24 | // so while every character might consist of multiple bytes there are | ||
25 | // still only 256 'columns' in the state machine) | ||
26 | pT = new T[256](); | ||
27 | |||
28 | // The above *should* initialize to 0 but since we can't account for every compiler doing it :( | ||
29 | memset(pT, 0, sizeof(T) * 256); | ||
30 | |||
31 | m_arFSM.push_back(pT); | ||
32 | } | ||
33 | }; | ||
34 | |||
35 | ~RlvMultiStringSearchFSM_STL() | ||
36 | { | ||
37 | // Free any memory we previously allocated | ||
38 | for (int idx = 0, cnt = m_arFSM.size(); idx < cnt; idx++) | ||
39 | delete[] m_arFSM[idx]; | ||
40 | } | ||
41 | |||
42 | /* | ||
43 | * Operators | ||
44 | */ | ||
45 | // ASSERTION: nState < m_arFSM.size() at all times | ||
46 | // In other words: do *NOT* go out of bounds on the array (no memory will have allocated for that non-existing state) | ||
47 | // (There probably should be a check for that even in release but it seems wasteful, just don't do it :p) | ||
48 | inline T* operator[](size_t nState) | ||
49 | { | ||
50 | //#ifdef _DEBUG | ||
51 | // assert( nState < m_arFSM.size() ); | ||
52 | //#endif // _DEBUG | ||
53 | |||
54 | return m_arFSM[nState]; | ||
55 | } | ||
56 | inline const T* operator[](size_t nState) const | ||
57 | { | ||
58 | //#ifdef _DEBUG | ||
59 | // assert( nState < m_arFSM.size() ); | ||
60 | //#endif // _DEBUG | ||
61 | |||
62 | return m_arFSM[nState]; | ||
63 | } | ||
64 | |||
65 | /* | ||
66 | * Public member functions | ||
67 | */ | ||
68 | |||
69 | size_t getSize() const { return m_arFSM.size(); } | ||
70 | |||
71 | void resize(size_t nNewCapacity) | ||
72 | { | ||
73 | // Get our current capacity (only rows > capacity need memory allocated) | ||
74 | size_t nCurCapacity = m_arFSM.capacity(); | ||
75 | |||
76 | // Only expand, never shrink | ||
77 | if (nNewCapacity <= nCurCapacity) | ||
78 | { | ||
79 | //#ifdef _DEBUG | ||
80 | // assert(false); | ||
81 | //#endif //_DEBUG | ||
82 | |||
83 | return; | ||
84 | } | ||
85 | m_arFSM.resize(nNewCapacity); | ||
86 | |||
87 | // For each new state we added, allocate memory for the columns | ||
88 | for(size_t idx = nCurCapacity; idx < nNewCapacity; idx++) | ||
89 | // The memset is redundant (or rather *should* be) but since we can't account for every compiler doing it :( | ||
90 | m_arFSM[idx] = (T*)memset(new T[256](), 0, sizeof(T) * 256); | ||
91 | } | ||
92 | |||
93 | protected: | ||
94 | /* | ||
95 | * Member variables | ||
96 | */ | ||
97 | std::vector<T*> m_arFSM; | ||
98 | }; | ||
99 | |||
100 | // ============================================================================ | ||
101 | |||
102 | struct RlvMultiStringSearchMatch | ||
103 | { | ||
104 | int idxMatch; // Starting character index into the string of the matched keyword (-1 if no match) | ||
105 | int lenMatch; // Length of the matched keyword (undefined if no match) | ||
106 | U16 nParam; // User supplied parameter for the matched keyword (undefined if no match) | ||
107 | |||
108 | RlvMultiStringSearchMatch() : idxMatch(-1) {} | ||
109 | }; | ||
110 | |||
111 | // ============================================================================ | ||
112 | // The actual search class | ||
113 | |||
114 | class RlvMultiStringSearch | ||
115 | { | ||
116 | public: | ||
117 | /* | ||
118 | * Constructor/destructor | ||
119 | */ | ||
120 | RlvMultiStringSearch(); | ||
121 | //~RlvMultiStringSearch(); | ||
122 | |||
123 | /* | ||
124 | * Public member functions | ||
125 | */ | ||
126 | |||
127 | // Add a keyword to the state machine (if it already exists then it will simply overwrite the existing parameter) | ||
128 | void addKeyword(const std::string& strKeyword, U16 nParam); | ||
129 | |||
130 | BOOL getExactMatchParam(const std::string& strText, U16& nParam) const | ||
131 | { | ||
132 | RlvMultiStringSearchMatch match; | ||
133 | if (findFirst(strText, match)) | ||
134 | { | ||
135 | // We have an exact match if the starting index is 0 | ||
136 | // and the length of the match matches the length of the string | ||
137 | if ( (0 == match.idxMatch) && (match.lenMatch == (int)strText.length()) ) | ||
138 | { | ||
139 | nParam = match.nParam; | ||
140 | return TRUE; | ||
141 | } | ||
142 | } | ||
143 | |||
144 | return FALSE; // Fall-through: no (exact) match | ||
145 | } | ||
146 | |||
147 | // Finds the first occurance of any keyword in the supplied string | ||
148 | bool findFirst(const std::string& strText, RlvMultiStringSearchMatch& match) const; | ||
149 | // Finds the next occurance of any keyword in the supplied string | ||
150 | bool findNext(const std::string& strText, int idxCh, RlvMultiStringSearchMatch& match) const; | ||
151 | // Finds all occurances of any keyword in the supplied string | ||
152 | std::vector<RlvMultiStringSearchMatch> findAll(const std::string& strText); | ||
153 | // Finds the last occurance of any keyword in the supplied string (non-optimized) | ||
154 | bool findLast(const std::string& strText, RlvMultiStringSearchMatch& match) const; | ||
155 | |||
156 | protected: | ||
157 | // Finds the next occurance of any keyword in the supplied string | ||
158 | bool findNext(const char* pstrText, int idxCh, int cntCh, RlvMultiStringSearchMatch& match, bool fWordMatch = true) const; | ||
159 | |||
160 | /* | ||
161 | * Member variables | ||
162 | */ | ||
163 | RlvMultiStringSearchFSM_STL<U32> m_FSM; // Our finite state machine (4 bytes * 256 = 1Kb of memory/state) | ||
164 | // HIWORD(U32) = 16-bits of user data | ||
165 | // LOWORD(U32) = ABBBBBBBBBBBBBBB | ||
166 | // A = termination bit | ||
167 | // If (set) and (B == 0): match | ||
168 | // If (set) and (B != 0): match, but might only be a substring of another keyword | ||
169 | // B = next state (0..32767) | ||
170 | // If (B == 0): false lead -> backtrack | ||
171 | // If (B != 0): partial keyword match, next state | ||
172 | size_t m_cntState; // The number of states in the FSM (= the number of *used* rows in the array) | ||
173 | }; | ||
174 | |||
175 | // ============================================================================ | ||
176 | // Inlined member functions | ||
177 | // | ||
178 | |||
179 | inline bool RlvMultiStringSearch::findFirst(const std::string& strText, RlvMultiStringSearchMatch& match) const | ||
180 | { | ||
181 | return findNext(strText.c_str(), 0, strText.length(), match); | ||
182 | } | ||
183 | |||
184 | inline bool RlvMultiStringSearch::findNext(const std::string& strText, int idxCh, RlvMultiStringSearchMatch& match) const | ||
185 | { | ||
186 | return findNext(strText.c_str(), idxCh, strText.length(), match); | ||
187 | } | ||
188 | |||
189 | // ============================================================================ | ||
190 | |||
191 | #endif // RLV_MULTISTRINGSEARCH_H | ||
diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_prim_import.xml b/linden/indra/newview/skins/default/xui/en-us/floater_prim_import.xml new file mode 100644 index 0000000..191b31e --- /dev/null +++ b/linden/indra/newview/skins/default/xui/en-us/floater_prim_import.xml | |||
@@ -0,0 +1,5 @@ | |||
1 | <?xml version="1.0" encoding="utf-8" standalone="yes" ?> | ||
2 | <floater can_close="true" can_drag_on_left="true" can_minimize="false" | ||
3 | can_resize="false" height="80" name="Import" title="Import progress" width="200" mouse_opaque="true"> | ||
4 | <text height="15" left="10" name="name_label" top="-10"> Progress </text> | ||
5 | </floater> | ||
diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_rlv_behaviour.xml b/linden/indra/newview/skins/default/xui/en-us/floater_rlv_behaviour.xml new file mode 100644 index 0000000..d9e70e6 --- /dev/null +++ b/linden/indra/newview/skins/default/xui/en-us/floater_rlv_behaviour.xml | |||
@@ -0,0 +1,11 @@ | |||
1 | <?xml version="1.0" encoding="utf-8" standalone="yes" ?> | ||
2 | <floater can_close="true" can_drag_on_left="false" can_minimize="true" can_resize="true" | ||
3 | height="425" min_height="200" min_width="375" name="rlvBehaviours" | ||
4 | title="Active RLV Restrictions" width="350"> | ||
5 | <scroll_list bottom="-400" draw_border="true" draw_heading="true" | ||
6 | follows="top|left|bottom|right" height="365" left="15" multi_select="false" | ||
7 | name="behaviour_list" right="-15"> | ||
8 | <column label="Restriction" name="behaviour" width="170" /> | ||
9 | <column label="Object Name" name="name" width="170" /> | ||
10 | </scroll_list> | ||
11 | </floater> \ No newline at end of file | ||
diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_pie_object.xml b/linden/indra/newview/skins/default/xui/en-us/menu_pie_object.xml index 765529d..15cdc9e 100644 --- a/linden/indra/newview/skins/default/xui/en-us/menu_pie_object.xml +++ b/linden/indra/newview/skins/default/xui/en-us/menu_pie_object.xml | |||
@@ -44,7 +44,11 @@ | |||
44 | <on_enable function="Object.EnableReturn" /> | 44 | <on_enable function="Object.EnableReturn" /> |
45 | </menu_item_call> | 45 | </menu_item_call> |
46 | <pie_menu label="More >" name="Rate Menu"> | 46 | <pie_menu label="More >" name="Rate Menu"> |
47 | <menu_item_separator /> | 47 | <menu_item_call label="Backup" enabled="false" hidden="false" |
48 | mouse_opaqu="true" name="Export"> | ||
49 | <on_click function="Object.Export" /> | ||
50 | <on_enable function="Object.EnableExport" /> | ||
51 | </menu_item_call> | ||
48 | <menu_item_call enabled="false" label="Mute" mouse_opaque="true" name="Object Mute"> | 52 | <menu_item_call enabled="false" label="Mute" mouse_opaque="true" name="Object Mute"> |
49 | <on_click function="Object.Mute" /> | 53 | <on_click function="Object.Mute" /> |
50 | <on_enable function="Object.EnableMute" /> | 54 | <on_enable function="Object.EnableMute" /> |
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 a53e339..81c49e7 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 | |||
@@ -8,6 +8,14 @@ | |||
8 | 8 | ||
9 | <menu name="File" create_jump_keys="true" label="File" | 9 | <menu name="File" create_jump_keys="true" label="File" |
10 | opaque="true" tear_off="true"> | 10 | opaque="true" tear_off="true"> |
11 | <menu_item_call enabled="false" hidden="false" label="Import" mouse_opaque="true" name="Import"> | ||
12 | <on_click function="Object.Import" /> | ||
13 | <on_enable function="Object.EnableImport" /> | ||
14 | </menu_item_call> | ||
15 | <menu_item_call enabled="false" hidden="false" label="Upload + Import" mouse_opaque="true" name="Import"> | ||
16 | <on_click function="Object.ImportUpload" /> | ||
17 | <on_enable function="Object.EnableImport" /> | ||
18 | </menu_item_call> | ||
11 | <menu_item_call name="Upload Image" | 19 | <menu_item_call name="Upload Image" |
12 | label="Upload Image (L$[COST])..." | 20 | label="Upload Image (L$[COST])..." |
13 | shortcut="control|U"> | 21 | shortcut="control|U"> |
@@ -1386,6 +1394,42 @@ | |||
1386 | </menu> | 1394 | </menu> |
1387 | 1395 | ||
1388 | 1396 | ||
1397 | <!-- RLVa --> | ||
1398 | |||
1399 | <menu name="RLVa" drop_shadow="true" opaque="true" tear_off="true"> | ||
1400 | |||
1401 | <menu_item_check name="Enable Wear" label="Enable Wear"> | ||
1402 | <on_click function="ToggleControl" userdata="RLVaEnableWear" /> | ||
1403 | <on_check control="RLVaEnableWear" /> | ||
1404 | </menu_item_check> | ||
1405 | |||
1406 | <menu_item_check name="Hide locked layers" label="Hide locked layers"> | ||
1407 | <on_click function="ToggleControl" userdata="RLVaHideLockedLayers" /> | ||
1408 | <on_check control="RLVaHideLockedLayers" /> | ||
1409 | </menu_item_check> | ||
1410 | |||
1411 | <menu_item_check name="Hide locked attachments" | ||
1412 | label="Hide locked attachments"> | ||
1413 | <on_click function="ToggleControl" | ||
1414 | userdata="RLVaHideLockedAttachments" /> | ||
1415 | <on_check control="RLVaHideLockedAttachments" /> | ||
1416 | </menu_item_check> | ||
1417 | |||
1418 | <!-- | ||
1419 | <menu_item_check name="Hide locked inventory" | ||
1420 | label="Hide locked inventory"> | ||
1421 | <on_click function="ToggleControl" | ||
1422 | userdata="RLVaHideLockedInventory" /> | ||
1423 | <on_check control="RLVaHideLockedInventory" /> | ||
1424 | </menu_item_check> | ||
1425 | --> | ||
1426 | |||
1427 | <menu_item_call name="Restrictions..." label="Restrictions..."> | ||
1428 | <on_click function="RLVa.Behaviors.Show" userdata="" /> | ||
1429 | </menu_item_call> | ||
1430 | |||
1431 | </menu> | ||
1432 | |||
1389 | 1433 | ||
1390 | <!-- UI --> | 1434 | <!-- UI --> |
1391 | 1435 | ||
@@ -1905,6 +1949,13 @@ | |||
1905 | userdata="ShowConsoleWindow" /> | 1949 | userdata="ShowConsoleWindow" /> |
1906 | <on_check control="ShowConsoleWindow" /> | 1950 | <on_check control="ShowConsoleWindow" /> |
1907 | </menu_item_check> | 1951 | </menu_item_check> |
1952 | |||
1953 | <menu_item_check name="Restrained Life Active" | ||
1954 | label="Restrained Life Active"> | ||
1955 | <on_click function="RLVa.Main.Toggle" /> | ||
1956 | <on_check function="RLVa.Main.Enabled" /> | ||
1957 | </menu_item_check> | ||
1958 | |||
1908 | <menu_item_check name="Output Debug Minidump" | 1959 | <menu_item_check name="Output Debug Minidump" |
1909 | label="Output Debug Minidump"> | 1960 | label="Output Debug Minidump"> |
1910 | <on_click function="ToggleControl" | 1961 | <on_click function="ToggleControl" |