diff --git a/.hgpatchinfo/.RLVa.dep b/.hgpatchinfo/.RLVa.dep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/.hgpatchinfo/Appearance-Misc.dep b/.hgpatchinfo/Appearance-Misc.dep deleted file mode 100644 index e4c3d9f5ad..0000000000 --- a/.hgpatchinfo/Appearance-Misc.dep +++ /dev/null @@ -1 +0,0 @@ -4ef383e7a5cdbf1dedd7458a56a9d13ebb7fddf2 \ No newline at end of file diff --git a/.hgpatchinfo/Appearance-Misc.desc b/.hgpatchinfo/Appearance-Misc.desc deleted file mode 100644 index dbc5fa8cae..0000000000 --- a/.hgpatchinfo/Appearance-Misc.desc +++ /dev/null @@ -1,21 +0,0 @@ -[Appearance/Misc] -- fixed : LLAppearanceMgr::filterWearableItems() doesn't properly filter body parts -- fixed : LLWearableList::processGetAssetReply() creates multiple LLWearable instances for the same asset UUID - -> fix for http://jira.secondlife.com/browse/VWR-20608 -- fixed : attachments sometimes detach only to instantly get reattached after logon -- fixed : Add to/Replace Outfit removes newly worn attachments on completion - -> fix for http://jira.secondlife.com/browse/VWR-18512 -- fixed : attachments that attach and then instantly detach don't have their COF link removed -- fixed : multiple LLWearableHoldingPattern instances lead to "COF corruption" -- fixed : get_is_item_worn() shouldn't make the assumption that items in COFs are always worn -- fixed : drag-and-drop wear behaviour of an attachment onto self isn't consistant with the drag-and-drop behaviour of wearables - -> normal-drop : replace wear - -> Ctrl-drop : add wear -- fixed : LLAppearanceMgr::registerAttachment() fails to (re)add a link for worn attachments that aren't linked to in COF at log-on -- fixed : LLViewerObject::getAttachmentItemID() sometimes returns the NULL UUID for the avatar's own attachments -- fixed : LLAppearanceMgr::updateAppearanceFromCOF() doesn't properly filter items collected from folder links - -> create an outfit with a folder link + "Replace Outfit" == wearables that exist in both COF and the linked folder will end up worn multiple times -- changed : enable "Replace Current Outfit" on the base outfit if it's marked dirty -- changed : "RenderUnloadedAvatar" no longer affects the user's own avatar - -> side-effect of the fix above due to the change to LLVOAvatar::isFullyLoaded() -- added : InitialWearablesLoadedSignal signal which is emitted *once* when the initial wearables are loaded diff --git a/.hgpatchinfo/Appearance-MixedViewers.dep b/.hgpatchinfo/Appearance-MixedViewers.dep deleted file mode 100644 index 0056f0bc00..0000000000 --- a/.hgpatchinfo/Appearance-MixedViewers.dep +++ /dev/null @@ -1 +0,0 @@ -23a6fee23f1d6a2432201906d41e80f3471e8700 \ No newline at end of file diff --git a/.hgpatchinfo/Appearance-MixedViewers.desc b/.hgpatchinfo/Appearance-MixedViewers.desc deleted file mode 100644 index 622d025f34..0000000000 --- a/.hgpatchinfo/Appearance-MixedViewers.desc +++ /dev/null @@ -1,5 +0,0 @@ -[Appearance/MixedViewers] -- fixed : "Worn items in Viewer 2 and Viewer 1.x aren't synchronized" [see http://jira.secondlife.com/browse/VWR-17594] - -> current fix compares *only* the wearables in COF with the wearables specified by AgentWearablesUpdate - -> controlled by "VerifyInitialWearables" (defaults to FALSE with SL-3.0) -- fixed : minor memory leak in LLInitialWearablesFetch::processWearablesMessage() diff --git a/.hgpatchinfo/Chat-NearbyChat.dep b/.hgpatchinfo/Chat-NearbyChat.dep deleted file mode 100644 index 822b8009e0..0000000000 --- a/.hgpatchinfo/Chat-NearbyChat.dep +++ /dev/null @@ -1 +0,0 @@ -d370e6c8ece17733128371a4d0eeaff9ebb52c7f \ No newline at end of file diff --git a/.hgpatchinfo/Chat-NearbyChat.desc b/.hgpatchinfo/Chat-NearbyChat.desc deleted file mode 100644 index b0f09310ff..0000000000 --- a/.hgpatchinfo/Chat-NearbyChat.desc +++ /dev/null @@ -1,7 +0,0 @@ -[Chat/NearbyChat] -- added : (user-resizable) multi-line chat bar to the nearby chat floater -- added : "NearbyChatFloaterBarType" setting to control the appearance of the chat bar in the nearby chat floater - -> 0 - legacy, now single line; 1 - single line (default); 2 - multi line (can be toggled at run-time) -- added : Shift+Enter to whisper from the chatbar(s) -- added : "NearbyChatFloaterWindow" setting to optionally embed the nearby chat floater in the tabbed conversations floater -- added : "save_tearoff_state" for floaters to track the torn off state of LLMultiFloater hosted floaters across viewer sessions diff --git a/.hgpatchinfo/Misc-Spellcheck.dep b/.hgpatchinfo/Misc-Spellcheck.dep deleted file mode 100644 index 880131d517..0000000000 --- a/.hgpatchinfo/Misc-Spellcheck.dep +++ /dev/null @@ -1 +0,0 @@ -5697118601ade0f70f851639661ba637174b3024 \ No newline at end of file diff --git a/.hgpatchinfo/RLVa.dep b/.hgpatchinfo/RLVa.dep deleted file mode 100644 index c9364fce94..0000000000 --- a/.hgpatchinfo/RLVa.dep +++ /dev/null @@ -1 +0,0 @@ -a2a692a4b575df65deec805e8eae2a9c84985855 \ No newline at end of file diff --git a/.hgpatchinfo/UI-Base.dep b/.hgpatchinfo/UI-Base.dep deleted file mode 100644 index 03c82ae969..0000000000 --- a/.hgpatchinfo/UI-Base.dep +++ /dev/null @@ -1 +0,0 @@ -ea427b73d98383faebb9d0209b753dc71b846676 \ No newline at end of file diff --git a/.hgpatchinfo/UI-Base.desc b/.hgpatchinfo/UI-Base.desc deleted file mode 100644 index 1678043a31..0000000000 --- a/.hgpatchinfo/UI-Base.desc +++ /dev/null @@ -1,6 +0,0 @@ -[UI/Base] -- added : static registration of an LLPanel derived class with a custom class creator - -> used in the UI-SidepanelOutfits patch branch -- added : registration of an LLFloater derived class with a callback for the XML filename - -> used in the Chat-Misc patch branch - -> used in the Chat-NearbyChat patch branch diff --git a/.hgpatchinfo/Viewer-Build.dep b/.hgpatchinfo/Viewer-Build.dep deleted file mode 100644 index 6ef8d775bf..0000000000 --- a/.hgpatchinfo/Viewer-Build.dep +++ /dev/null @@ -1 +0,0 @@ -43f5dc9c781eb7528a08abd58b2e4fea6ff1838e \ No newline at end of file diff --git a/.hgpatchinfo/Viewer-Build.desc b/.hgpatchinfo/Viewer-Build.desc deleted file mode 100644 index 6a503b7e35..0000000000 --- a/.hgpatchinfo/Viewer-Build.desc +++ /dev/null @@ -1,10 +0,0 @@ -[Viewer/Build] -* Changed compiler options for "Release with Debug" builds -* Changed compiler and linker options for "Release" builds -* Removed LL's changeset tags and added new (consistent) SL-X.Y.Z tags for releases -* Break into the debugger rather than forcing the process into an unrecoverable state for "llerrs" on non-release builds - -> Windows only -* CATZ-234: Updated FMOD Ex library to v4.44.61 (Windows) -* CATZ-232: Updated OpenJPEG library to v1.5.2 (Windows) -* [FIXED] Viewer fails to compile with only the Windows 8 SDK installed -* [FIXED] JpegLib is built with "Whole Program Optimization" and causing slow linker performance diff --git a/.hgpatchinfo/World-Minimap.desc b/.hgpatchinfo/World-Minimap.desc deleted file mode 100644 index 7202dac6c0..0000000000 --- a/.hgpatchinfo/World-Minimap.desc +++ /dev/null @@ -1,21 +0,0 @@ -[World/Minimap] -- added : "MiniMapObjects" setting to control the rendering of objects on the minimap - -> enabled by default -- added : property line overlay on the minimap -- added : "Property Lines" context menu option on the mini-map to toggle showing property lines - -> controls 'MiniMapPropertyLines' setting, defaults to on -- added : (optionally) use world map tile texture for the mini-map region texture -- added : "Terrain Textures" as an option to the mini-map "Show" context menu - -> with "Terrain Textures" and "World Map Textures" as separated options it will hopefully become clearer what the texture option entails -- added : (optionally) show for-sale parcels with a yellow highlight on the mini-map - -> controlled by 'MiniMapForSaleParcels', defaults to off -- added : colour collision parcels a transparent red - -> controlled by 'MiniMapCollisionParcels', defaults to on -- added : user-configurable "MiniMapParcelOverylay" color for the property lines on the mini-map -- added : "Place Profile" menu item to the mini-map context menu -- added : "View Profile" context menu item for singular and context sub-menu for multiple dots on the mini-map -- changed : removed title bar from the mini-map + fixed vertical centering of directions -- changed : moved mini-map zoom options into a "Zoom" sub-menu -- changed : mini-map zoom levels for "Close", "Medium" and "Far" options - -> removed dead code in LLFloaterMap::handleZoom() -- changed : only show the "Stop Tracking" mini-map context menu item if we're actually tracking something diff --git a/autobuild.xml b/autobuild.xml index bf90bfa095..d03420df4b 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3,6 +3,36 @@ installables + dullahan-gcc5 + + copyright + Copyright (c) 2017, Linden Research, Inc. + description + A headless browser SDK that uses the Chromium Embedded Framework (CEF). It is designed to make it easier to write applications that render modern web content directly to a memory buffer, inject synthesized mouse and keyboard events as well as interact with web based features like JavaScript or cookies. + license + MPL + license_file + LICENSES/LICENSE.txt + name + dullahan-gcc5 + platforms + + linux64 + + archive + + hash + cffd8a7f9d8e55ecd50c72cc39b41f3d + url + http://downloads.phoenixviewer.com/dullahan_gcc5-1.1.1080_3.3325.1750.gaabe4c4-linux64-181420123.tar.bz2 + + name + linux64 + + + version + 1.1.1080_3.3325.1750.gaabe4c4 + ndPhysicsStub license @@ -156,9 +186,9 @@ archive hash - 2dd97d8bd012be4cdc58f550395feb7d + ff2e4df5bffe0203dc654b111347e617 url - http://downloads.phoenixviewer.com/SDL-1.2.15-linux-180871815.tar.bz2 + http://downloads.phoenixviewer.com/SDL-1.2.15-linux-181412059.tar.bz2 name linux @@ -168,9 +198,9 @@ archive hash - 608dfd27f7aed9d57cf1f581c995b680 + 64c1dff0e19792acec7fd32556bf4d7b url - http://downloads.phoenixviewer.com/SDL-1.2.15-linux64-180841947.tar.bz2 + http://downloads.phoenixviewer.com/SDL-1.2.15-linux64-181411635.tar.bz2 name linux64 @@ -882,11 +912,11 @@ archive hash - 9f69c9fa0932d54d17c159fc33faea87 + 5946db540ecd6da093d15c7f793359f9 hash_algorithm md5 url - file:///opt/firestorm/fmodstudio-1.10.04-darwin-180681405.tar.bz2 + file:///opt/firestorm/fmodstudio-1.10.05-darwin-181440931.tar.bz2 name darwin @@ -896,11 +926,11 @@ archive hash - a379240b46b13b2b9e858baa79d1a6ab + 32c7ddbc7a5134c849c8c58323dac1cd hash_algorithm md5 url - file:///opt/firestorm/fmodstudio-1.10.04-linux-180891813.tar.bz2 + file:///opt/firestorm/fmodstudio-1.10.05-linux-181440917.tar.bz2 name linux @@ -910,11 +940,11 @@ archive hash - e0b59ec3b5549b9a0f9caf8c7116af4e + eb04055057a549ac778c7f1391963dfe hash_algorithm md5 url - file:///opt/firestorm/fmodstudio-1.10.04-linux64-180891838.tar.bz2 + file:///opt/firestorm/fmodstudio-1.10.05-linux64-181440918.tar.bz2 name linux64 @@ -924,11 +954,11 @@ archive hash - 7cf0785fa38889c9028fe776eda060f6 + 79dca4b585181c18f983cb3adc4f9633 hash_algorithm md5 url - file:///c:/cygwin/opt/firestorm/fmodstudio-1.10.04-windows-180672209.tar.bz2 + file:///c:/cygwin/opt/firestorm/fmodstudio-1.10.05-windows-181432216.tar.bz2 name windows @@ -938,11 +968,11 @@ archive hash - fe0951c7fffbf1cd0154bcdb5bcaa5c9 + 9e2a8fa5e4bdb0a1eba8be3717029c31 hash_algorithm md5 url - file:///c:/cygwin/opt/firestorm/fmodstudio-1.10.04-windows64-180672211.tar.bz2 + file:///c:/cygwin/opt/firestorm/fmodstudio-1.10.05-windows64-181432218.tar.bz2 name windows64 @@ -2828,9 +2858,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 86cb59b79ce0aafe28d4055a17d1f748 + c5404596040e5f6e66a09a6de5edeefa url - http://downloads.phoenixviewer.com/open_libndofdev-0.3.180871824-linux-180871824.tar.bz2 + http://downloads.phoenixviewer.com/open_libndofdev-0.3.181412109-linux-181412109.tar.bz2 name linux @@ -2840,9 +2870,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 4df349abfc942fb8e674244d1bd0a515 + 774e6a85deb149309f1ccf59d2f5c5a4 url - http://downloads.phoenixviewer.com/open_libndofdev-0.3.180841957-linux64-180841957.tar.bz2 + http://downloads.phoenixviewer.com/open_libndofdev-0.3.181411657-linux64-181411657.tar.bz2 name linux64 diff --git a/indra/cmake/CEFPlugin.cmake b/indra/cmake/CEFPlugin.cmake index 8aefbaf2fc..40f9c317a6 100644 --- a/indra/cmake/CEFPlugin.cmake +++ b/indra/cmake/CEFPlugin.cmake @@ -6,7 +6,12 @@ if (USESYSTEMLIBS) set(CEFPLUGIN OFF CACHE BOOL "CEFPLUGIN support for the llplugin/llmedia test apps.") else (USESYSTEMLIBS) + if (LINUX AND ( CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.9.4 ) ) + message( "Using dullahan for GCC >= 5 " ) + use_prebuilt_binary(dullahan-gcc5) + else() use_prebuilt_binary(dullahan) + endif() set(CEFPLUGIN ON CACHE BOOL "CEFPLUGIN support for the llplugin/llmedia test apps.") set(CEF_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/cef) diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp index 2acfe62580..18035fdd2f 100644 --- a/indra/llappearance/llwearable.cpp +++ b/indra/llappearance/llwearable.cpp @@ -440,7 +440,13 @@ LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream, LL_WARNS() << "Bad Wearable asset: bad texture, #" << i << LL_ENDL; return LLWearable::FAILURE; } - + + if (te >= ETextureIndex::TEX_NUM_INDICES) //createLayers() converts to ETextureIndex + { + LL_WARNS() << "Bad Wearable asset: bad texture index: " << te << LL_ENDL; + return LLWearable::FAILURE; + } + if( !LLUUID::validate( uuid_buffer ) ) { LL_WARNS() << "Bad Wearable asset: bad texture uuid: " diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 50f7eb749c..e246d8b1a0 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -611,6 +611,41 @@ std::string utf8str_substr(const std::string& utf8str, const S32 index, const S3 return utf8str.substr(index, cur_char); } } + +void utf8str_split(std::list& split_list, const std::string& utf8str, size_t maxlen, char split_token) +{ + split_list.clear(); + + std::string::size_type lenMsg = utf8str.length(), lenIt = 0; + + const char* pstrIt = utf8str.c_str(); std::string strTemp; + while (lenIt < lenMsg) + { + if (lenIt + maxlen < lenMsg) + { + // Find the last split character + const char* pstrTemp = pstrIt + maxlen; + while ( (pstrTemp > pstrIt) && (*pstrTemp != split_token) ) + pstrTemp--; + + if (pstrTemp > pstrIt) + strTemp = utf8str.substr(lenIt, pstrTemp - pstrIt); + else + strTemp = utf8str_substr(utf8str, lenIt, maxlen); + } + else + { + strTemp = utf8str.substr(lenIt, std::string::npos); + } + + split_list.push_back(strTemp); + + lenIt += strTemp.length(); + pstrIt = utf8str.c_str() + lenIt; + if (*pstrIt == split_token) + lenIt++; + } +} // [/RLVa:KB] std::string utf8str_symbol_truncate(const std::string& utf8str, const S32 symbol_len) diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 3fcda31c16..9c030473fb 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -36,6 +36,9 @@ #include #include "llformat.h" #include "llsd.h" +// [RLVa:KB] - Checked: RLVa-2.1.0 +#include +// [/RLVa:KB] #if LL_LINUX || LL_SOLARIS #include @@ -564,6 +567,7 @@ LL_COMMON_API std::string utf8str_truncate(const std::string& utf8str, const S32 // [RLVa:KB] - Checked: RLVa-2.1.0 LL_COMMON_API std::string utf8str_substr(const std::string& utf8str, const S32 index, const S32 max_len); +LL_COMMON_API void utf8str_split(std::list& split_list, const std::string& utf8str, size_t maxlen, char split_token); // [/RLVa:KB] LL_COMMON_API std::string utf8str_trim(const std::string& utf8str); diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp index 3a6eebebba..7bb67594af 100644 --- a/indra/llrender/llgltexture.cpp +++ b/indra/llrender/llgltexture.cpp @@ -316,7 +316,10 @@ BOOL LLGLTexture::getIsAlphaMask() const return mGLTexturep->getIsAlphaMask() ; } -BOOL LLGLTexture::getMask(const LLVector2 &tc) +//BOOL LLGLTexture::getMask(const LLVector2 &tc) +// [RLVa:KB] - Checked: RLVa-2.3 (@setoverlay) +bool LLGLTexture::getMask(const LLVector2 &tc) const +// [/RLVa:KB] { llassert(mGLTexturep.notNull()) ; diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h index 14fd85a0fb..a283f35ade 100644 --- a/indra/llrender/llgltexture.h +++ b/indra/llrender/llgltexture.h @@ -143,7 +143,10 @@ public: LLGLenum getPrimaryFormat() const; BOOL getIsAlphaMask() const ; LLTexUnit::eTextureType getTarget(void) const ; - BOOL getMask(const LLVector2 &tc); +// [RLVa:KB] - Checked: RLVa-2.3 (@setoverlay) + bool getMask(const LLVector2 &tc) const; +// [/RLVa:KB] +// BOOL getMask(const LLVector2 &tc); F32 getTimePassedSinceLastBound(); BOOL getMissed() const ; BOOL isJustBound()const ; diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 0ffaa480a6..2f4a505235 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -2001,7 +2001,10 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) } } -BOOL LLImageGL::getMask(const LLVector2 &tc) +//BOOL LLImageGL::getMask(const LLVector2 &tc) +// [RLVa:KB] - Checked: RLVa-2.3 (@setoverlay) +BOOL LLImageGL::getMask(const LLVector2 &tc) const +// [/RLVa:KB] { BOOL res = TRUE; diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 4035ce3bc0..255a64c3a2 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -153,7 +153,10 @@ public: void setUseMipMaps(BOOL usemips) { mUseMipMaps = usemips; } void updatePickMask(S32 width, S32 height, const U8* data_in); - BOOL getMask(const LLVector2 &tc); +// [RLVa:KB] - Checked: RLVa-2.3 (@setoverlay) + BOOL getMask(const LLVector2 &tc) const; +// [/RLVa:KB] +// BOOL getMask(const LLVector2 &tc); void checkTexSize(bool forced = false) const ; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 60d7fd2cef..b5d8556e31 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -843,6 +843,7 @@ set(viewer_SOURCE_FILES rlvinventory.cpp rlvextensions.cpp rlvfloaters.cpp + rlvmodifiers.cpp rlvui.cpp sanitycheck.cpp streamtitledisplay.cpp @@ -1594,6 +1595,7 @@ set(viewer_HEADER_FILES rlvinventory.h rlvextensions.h rlvfloaters.h + rlvmodifiers.h rlvui.h roles_constants.h qtoolalign.h diff --git a/indra/newview/app_settings/grids.xml b/indra/newview/app_settings/grids.xml index a9efb14391..bb6490cc14 100644 --- a/indra/newview/app_settings/grids.xml +++ b/indra/newview/app_settings/grids.xml @@ -189,7 +189,7 @@ grid.avatarconnection.com:8002/ DEPRECATED - TRUE + TRUE name grid.avatarconnection.com:8002/ @@ -468,7 +468,7 @@ login.osgrid.org LastModified - 2012-08-03T15:36:22.93Z + 2019-04-19T21:15:00.00Z about http://www.osgrid.org/ gatekeeper @@ -591,7 +591,7 @@ util.aditi.lindenlab.com LastModified - 2018-04-15T11:25:00Z + 2019-04-19T21:15:00Z app_slurl_base secondlife:///app gridname @@ -622,7 +622,7 @@ util.agni.lindenlab.com LastModified - 2018-04-15T11:25:00Z + 2019-04-19T21:15:00Z app_slurl_base secondlife:///app favorite diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index d9ca23a1b6..d27c58ee41 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -12601,6 +12601,17 @@ Change of this parameter will affect the layout of buttons in notification toast Backup 0 + RenderResolutionMultiplier + + Comment + Multiplier for rendering 3D scene at reduced resolution. + Persist + 1 + Type + F32 + Value + 1.0 + RenderShaderLightingMaxLevel Comment diff --git a/indra/newview/fsfloatersearch.cpp b/indra/newview/fsfloatersearch.cpp index c3baa1ecdd..f994899459 100644 --- a/indra/newview/fsfloatersearch.cpp +++ b/indra/newview/fsfloatersearch.cpp @@ -28,48 +28,46 @@ #include "llviewerprecompiledheaders.h" #include "fsfloatersearch.h" + #include "fsavatarsearchmenu.h" +#include "fsdispatchclassifiedclickthrough.h" +#include "fspanelclassified.h" +#include "fspanelprofile.h" #include "fsscrolllistctrl.h" #include "lfsimfeaturehandler.h" #include "llagent.h" +#include "llavataractions.h" #include "llavatarname.h" #include "llavatarnamecache.h" +#include "llavatarpropertiesprocessor.h" #include "llclassifiedflags.h" +#include "llclassifiedinfo.h" +#include "llcombobox.h" #include "lldateutil.h" -#include "llqueryflags.h" #include "lleventflags.h" #include "lleventnotifier.h" +#include "llfloaterreg.h" +#include "llfloaterworldmap.h" +#include "llgroupactions.h" #include "llgroupmgr.h" -#include "llparcel.h" -#include "llclassifiedinfo.h" -#include "llremoteparcelrequest.h" -#include "llavatarpropertiesprocessor.h" -#include "llproductinforequest.h" +#include "llloadingindicator.h" #include "lllogininstance.h" +#include "llnotificationsutil.h" +#include "llpanelclassified.h" +#include "llparcel.h" +#include "llproductinforequest.h" +#include "llqueryflags.h" +#include "llremoteparcelrequest.h" +#include "lltimer.h" +#include "lltrans.h" #include "llviewercontrol.h" #include "llviewergenericmessage.h" #include "llviewernetwork.h" #include "llviewerregion.h" -#include "llnotificationsutil.h" -#include "lltrans.h" #include "message.h" - -#include "llcombobox.h" -#include "llfloaterreg.h" -#include "llloadingindicator.h" -#include "lltimer.h" - -#include "llavataractions.h" -#include "llgroupactions.h" -#include "llfloaterworldmap.h" -#include "fspanelclassified.h" -#include "fspanelprofile.h" -#include "llpanelclassified.h" -#include "fsdispatchclassifiedclickthrough.h" - -#include #include #include +#include static const S32 MIN_SEARCH_STRING_SIZE = 2; static const S32 RESULT_PAGE_SIZE = 100; @@ -87,19 +85,19 @@ public: FSSearchRemoteParcelInfoObserver(FSFloaterSearch* floater) : LLRemoteParcelInfoObserver(), mParent(floater) {} - + ~FSSearchRemoteParcelInfoObserver() { // remove any in-flight observers std::set::iterator it; for (it = mParcelIDs.begin(); it != mParcelIDs.end(); ++it) - { - const LLUUID &id = *it; - LLRemoteParcelInfoProcessor::getInstance()->removeObserver(id, this); - } + { + const LLUUID &id = *it; + LLRemoteParcelInfoProcessor::getInstance()->removeObserver(id, this); + } mParcelIDs.clear(); } - + /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data) { if (mParent) @@ -109,7 +107,7 @@ public: mParcelIDs.erase(parcel_data.parcel_id); LLRemoteParcelInfoProcessor::getInstance()->removeObserver(parcel_data.parcel_id, this); } - + /*virtual*/ void setParcelID(const LLUUID& parcel_id) { if (!parcel_id.isNull()) @@ -119,14 +117,14 @@ public: LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(parcel_id); } } - + /*virtual*/ void setErrorStatus(S32 status, const std::string& reason) { LL_ERRS("Search") << "Can't complete remote parcel request. Http Status: " << status << ". Reason : " << reason << LL_ENDL; } private: std::set mParcelIDs; - FSFloaterSearch* mParent; + FSFloaterSearch* mParent; }; ///// Avatar Properties Observer ///// @@ -137,7 +135,7 @@ public: FSSearchAvatarPropertiesObserver(FSFloaterSearch* floater) : LLAvatarPropertiesObserver(), mParent(floater) {} - + ~FSSearchAvatarPropertiesObserver() { // remove any in-flight observers @@ -149,7 +147,7 @@ public: } mAvatarIDs.clear(); } - + void processProperties(void* data, EAvatarProcessorType type) { if (APT_PROPERTIES == type) @@ -164,7 +162,7 @@ public: if (APT_CLASSIFIED_INFO == type) { LLAvatarClassifiedInfo* c_info = static_cast(data); - if(c_info) + if (c_info) { mParent->displayClassifiedDetails(c_info); LLAvatarPropertiesProcessor::getInstance()->removeObserver(c_info->classified_id, this); @@ -181,7 +179,7 @@ public: } private: std::set mAvatarIDs; - FSFloaterSearch* mParent; + FSFloaterSearch* mParent; }; ///// Group Info Observer ///// @@ -201,12 +199,12 @@ public: groupmgr->sendGroupPropertiesRequest(group_id); } } - + ~FSSearchGroupInfoObserver() { LLGroupMgr::getInstance()->removeObserver(this); } - + void changed(LLGroupChange gc) { if (gc == GC_PROPERTIES) @@ -217,8 +215,8 @@ public: } } private: - FSFloaterSearch* mParent; - LLUUID mID; + FSFloaterSearch* mParent; + LLUUID mID; }; ///// Silly Classified Clickthrough Class ///// @@ -272,7 +270,9 @@ void FSFloaterSearch::onOpen(const LLSD& key) void FSFloaterSearch::onClose(bool app_quitting) { if (mTabContainer) + { gSavedSettings.setS32("FSLastSearchTab", mTabContainer->getCurrentPanelIndex()); + } } BOOL FSFloaterSearch::postBuild() @@ -287,15 +287,15 @@ BOOL FSFloaterSearch::postBuild() childSetAction("teleport_btn", boost::bind(&FSFloaterSearch::onBtnTeleport, this)); childSetAction("map_btn", boost::bind(&FSFloaterSearch::onBtnMap, this)); resetVerbs(); - - mPanelPeople = findChild("panel_ls_people"); - mPanelGroups = findChild("panel_ls_groups"); - mPanelPlaces = findChild("panel_ls_places"); - mPanelEvents = findChild("panel_ls_events"); - mPanelLand = findChild("panel_ls_land"); + + mPanelPeople = findChild("panel_ls_people"); + mPanelGroups = findChild("panel_ls_groups"); + mPanelPlaces = findChild("panel_ls_places"); + mPanelEvents = findChild("panel_ls_events"); + mPanelLand = findChild("panel_ls_land"); mPanelClassifieds = findChild("panel_ls_classifieds"); - mPanelWeb = findChild("panel_ls_web"); - + mPanelWeb = findChild("panel_ls_web"); + // If skin has legacy full profile view, use it mPanelProfile = mPanelPeople->findChild("panel_profile_view"); if (mPanelProfile) @@ -304,7 +304,7 @@ BOOL FSFloaterSearch::postBuild() mPanelProfile->setEmbedded(true); mPanelPeople->childSetAction("people_profile_btn", boost::bind(&FSFloaterSearch::onBtnPeopleProfile, this)); } - + mDetailsPanel = getChild("panel_ls_details"); mDetailTitle = getChild("title"); mDetailDesc = getChild("desc"); @@ -326,19 +326,19 @@ BOOL FSFloaterSearch::postBuild() mDetailsPanel->setVisible(false); } mHasSelection = false; - + if (!mTabContainer->selectTab(gSavedSettings.getS32("FSLastSearchTab"))) { mTabContainer->selectFirstTab(); } - + return TRUE; } void FSFloaterSearch::onTabChange() { LLPanel* active_panel = mTabContainer->getCurrentPanel(); - + if (active_panel == mPanelWeb) { mDetailsPanel->setVisible(false); @@ -354,7 +354,7 @@ void FSFloaterSearch::onTabChange() LLPanel* FSFloaterSearch::getSearchPanel(std::string panel_name) { FSFloaterSearch* search_instance = LLFloaterReg::getTypedInstance("search"); - if(search_instance && search_instance->mTabContainer) + if (search_instance && search_instance->mTabContainer) { return search_instance->mTabContainer->getPanelByName(panel_name); } @@ -374,19 +374,19 @@ void FSFloaterSearch::onSelectedItem(const LLUUID& selected_item, ESearchCategor switch (type) { case SC_AVATAR: - { - // If skin has legacy full profile view, use it - if (mPanelProfile) { - mPanelProfile->setVisible(true); - mPanelProfile->onOpen(selected_item); + // If skin has legacy full profile view, use it + if (mPanelProfile) + { + mPanelProfile->setVisible(true); + mPanelProfile->onOpen(selected_item); + } + else + { + LLAvatarPropertiesProcessor::getInstance()->addObserver(selected_item, mAvatarPropertiesObserver); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(selected_item); + } } - else - { - LLAvatarPropertiesProcessor::getInstance()->addObserver(selected_item, mAvatarPropertiesObserver); - LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(selected_item); - } - } break; case SC_GROUP: mGroupPropertiesRequest = new FSSearchGroupInfoObserver(selected_item, this); @@ -408,11 +408,11 @@ void FSFloaterSearch::onSelectedEvent(const S32 selected_event) { resetVerbs(); flushDetails(); - + gMessageSystem->newMessageFast(_PREHASH_EventInfoRequest); gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); gMessageSystem->nextBlockFast(_PREHASH_EventData); gMessageSystem->addU32Fast(_PREHASH_EventID, selected_event); gAgent.sendReliableMessage(); @@ -429,18 +429,23 @@ void FSFloaterSearch::displayParcelDetails(const LLParcelData& parcel_data) // HACK: Flag 0x2 == adult region, // Flag 0x1 == mature region, otherwise assume PG if (parcel_data.flags & 0x2) + { mDetailMaturity->setValue("Parcel_R_Dark"); + } else if (parcel_data.flags & 0x1) + { mDetailMaturity->setValue("Parcel_M_Dark"); + } else + { mDetailMaturity->setValue("Parcel_PG_Dark"); - + } + LLStringUtil::format_map_t map; map["DWELL"] = llformat("%.0f", (F64)parcel_data.dwell); map["AREA"] = llformat("%d m²", parcel_data.actual_area); - map["LOCATION"] = llformat("%s (%d, %d, %d)", - parcel_data.sim_name.c_str(), region_x, region_y, region_z); - + map["LOCATION"] = llformat("%s (%d, %d, %d)", parcel_data.sim_name.c_str(), region_x, region_y, region_z); + mParcelGlobal = LLVector3d(parcel_data.global_x, parcel_data.global_y, parcel_data.global_z); mDetailsPanel->setVisible(true); mHasSelection = true; @@ -467,15 +472,14 @@ void FSFloaterSearch::displayAvatarDetails(LLAvatarData*& avatar_data) map["PARTNER"] = LLSLURL("agent", avatar_data->partner_id, "inspect").getSLURLString(); mDetailAux2->setValue(getString("string.partner", map)); } - + mDetailsPanel->setVisible(true); mHasSelection = true; mDetailTitle->setValue(LLTrans::getString("LoadingData")); mDetailDesc->setValue(avatar_data->about_text); mDetailSnapshot->setValue(avatar_data->image_id); mDetailAux1->setValue(getString("string.age", map)); - LLAvatarNameCache::get(avatar_data->avatar_id, - boost::bind(&FSFloaterSearch::avatarNameUpdatedCallback,this, _1, _2)); + LLAvatarNameCache::get(avatar_data->avatar_id, boost::bind(&FSFloaterSearch::avatarNameUpdatedCallback,this, _1, _2)); childSetVisible("people_profile_btn", true); childSetVisible("people_message_btn", true); childSetVisible("people_friend_btn", true); @@ -486,11 +490,11 @@ void FSFloaterSearch::displayAvatarDetails(LLAvatarData*& avatar_data) void FSFloaterSearch::displayGroupDetails(LLGroupMgrGroupData*& group_data) { if (group_data) - { + { LLStringUtil::format_map_t map; map["MEMBER_COUNT"] = llformat("%d",group_data->mMemberCount); map["FOUNDER"] = LLSLURL("agent", group_data->mFounderID, "inspect").getSLURLString(); - + mDetailsPanel->setVisible(true); mHasSelection = true; mDetailTitle->setValue(LLTrans::getString("LoadingData")); @@ -506,8 +510,7 @@ void FSFloaterSearch::displayGroupDetails(LLGroupMgrGroupData*& group_data) childSetVisible("group_join_btn", true); getChildView("group_join_btn")->setEnabled(join_btn_enabled); getChildView("group_message_btn")->setEnabled(is_member); - gCacheName->getGroup(getSelectedID(), - boost::bind(&FSFloaterSearch::groupNameUpdatedCallback, this, _1, _2, _3)); + gCacheName->getGroup(getSelectedID(), boost::bind(&FSFloaterSearch::groupNameUpdatedCallback, this, _1, _2, _3)); } } @@ -516,13 +519,18 @@ void FSFloaterSearch::displayClassifiedDetails(LLAvatarClassifiedInfo*& c_info) if (c_info) { if (c_info->flags & CLASSIFIED_FLAG_MATURE) + { mDetailMaturity->setValue("Parcel_M_Dark"); + } else + { mDetailMaturity->setValue("Parcel_PG_Dark"); + } + LLStringUtil::format_map_t map; map["LISTING_PRICE"] = llformat("L$%d", c_info->price_for_listing); map["SLURL"] = LLSLURL("parcel", c_info->parcel_id, "about").getSLURLString(); - + mDetailsPanel->setVisible(true); mHasSelection = true; mDetailMaturity->setVisible(true); @@ -541,11 +549,18 @@ void FSFloaterSearch::displayClassifiedDetails(LLAvatarClassifiedInfo*& c_info) void FSFloaterSearch::displayEventDetails(U32 eventId, F64 eventEpoch, const std::string& eventDateStr, const std::string &eventName, const std::string &eventDesc, const std::string &simName, U32 eventDuration, U32 eventFlags, U32 eventCover, LLVector3d eventGlobalPos) { if (eventFlags == EVENT_FLAG_ADULT) + { mDetailMaturity->setValue("Parcel_R_Dark"); + } else if (eventFlags == EVENT_FLAG_MATURE) + { mDetailMaturity->setValue("Parcel_M_Dark"); + } else + { mDetailMaturity->setValue("Parcel_PG_Dark"); + } + S32 region_x; S32 region_y; S32 region_z; @@ -560,7 +575,7 @@ void FSFloaterSearch::displayEventDetails(U32 eventId, F64 eventEpoch, const std map["COVERCHARGE"] = llformat("L$%d", eventCover); mDetailAux2->setValue(getString("string.covercharge", map)); } - + mParcelGlobal = eventGlobalPos; mEventID = eventId; mDetailsPanel->setVisible(true); @@ -599,13 +614,17 @@ void FSFloaterSearch::groupNameUpdatedCallback(const LLUUID& id, const std::stri void FSFloaterSearch::setLoadingProgress(bool started) { LLLoadingIndicator* indicator = getChild("loading"); - - indicator->setVisible(started); - - if (started) - indicator->start(); - else - indicator->stop(); + + indicator->setVisible(started); + + if (started) + { + indicator->start(); + } + else + { + indicator->stop(); + } } void FSFloaterSearch::resetVerbs() @@ -673,10 +692,13 @@ void FSFloaterSearch::onBtnTeleport() /// the user may elect to minimize the floater (2), or to do nothing (any other setting) static LLCachedControl teleport_action(gSavedSettings, "FSLegacySearchActionOnTeleport"); if (teleport_action == 1) + { closeFloater(); + } else if (teleport_action == 2) + { setMinimized(TRUE); - + } } } @@ -728,12 +750,12 @@ BOOL FSPanelSearchPeople::postBuild() mSearchResults->setCommentText(LLTrans::getString("no_results")); mSearchResults->setContextMenu(&gFSAvatarSearchMenu); } - + childSetAction("people_next", boost::bind(&FSPanelSearchPeople::onBtnNext, this)); childSetAction("people_back", boost::bind(&FSPanelSearchPeople::onBtnBack, this)); getChildView("people_next")->setEnabled(FALSE); getChildView("people_back")->setEnabled(FALSE); - + return TRUE; } @@ -751,19 +773,25 @@ void FSPanelSearchPeople::find() mSearchResults->setCommentText(LLTrans::getString("search_short")); return; } - + + LLStringUtil::replaceChar(text, '.', ' '); + mResultsReceived = 0; if (mQueryID.notNull()) + { mQueryID.setNull(); + } mQueryID.generate(); if (mStartSearch < 0) + { mStartSearch = 0; - + } + gMessageSystem->newMessage("DirFindQuery"); gMessageSystem->nextBlock("AgentData"); - gMessageSystem->addUUID("AgentID", gAgent.getID()); - gMessageSystem->addUUID("SessionID", gAgent.getSessionID()); + gMessageSystem->addUUID("AgentID", gAgentID); + gMessageSystem->addUUID("SessionID", gAgentSessionID); gMessageSystem->nextBlock("QueryData"); gMessageSystem->addUUID("QueryID", getQueryID()); gMessageSystem->addString("QueryText", text); @@ -771,7 +799,7 @@ void FSPanelSearchPeople::find() gMessageSystem->addS32("QueryStart", mStartSearch); gAgent.sendReliableMessage(); LL_DEBUGS("Search") << "Firing off search request: " << getQueryID() << LL_ENDL; - + mSearchResults->deleteAllItems(); mSearchResults->setCommentText(LLTrans::getString("searching")); mNumResultsReturned = 0; @@ -780,11 +808,11 @@ void FSPanelSearchPeople::find() void FSPanelSearchPeople::onBtnFind() { std::string text = mSearchComboBox->getSimple(); - if(!text.empty()) + if (!text.empty()) { LLSearchHistory::getInstance()->addEntry(text); } - + resetSearch(); find(); @@ -794,7 +822,7 @@ void FSPanelSearchPeople::onBtnNext() { mStartSearch += RESULT_PAGE_SIZE; getChildView("people_back")->setEnabled(TRUE); - + find(); } @@ -802,7 +830,7 @@ void FSPanelSearchPeople::onBtnBack() { mStartSearch -= RESULT_PAGE_SIZE; getChildView("people_back")->setEnabled(mStartSearch > 0); - + find(); } @@ -839,32 +867,35 @@ void FSPanelSearchPeople::onSelectItem() void FSPanelSearchPeople::processSearchReply(LLMessageSystem* msg, void**) { LLUUID query_id; - std::string first_name; - std::string last_name; + std::string first_name; + std::string last_name; LLUUID agent_id; - + msg->getUUIDFast(_PREHASH_QueryData, _PREHASH_QueryID, query_id); msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id); - + // This result is not for us. - if (agent_id != gAgent.getID()) return; + if (agent_id != gAgentID) + { + return; + } LL_DEBUGS("Search") << "received search results - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; - + FSPanelSearchPeople* self = (FSPanelSearchPeople*)FSFloaterSearch::getSearchPanel("panel_ls_people"); - + // floater is closed or these are not results from our last request if (NULL == self || query_id != self->getQueryID()) { return; } - + LLScrollListCtrl* search_results = self->getChild("search_results_people"); - + if (self->mNumResultsReturned++ == 0) { search_results->deleteAllItems(); } - + // Check for status messages if (msg->getNumberOfBlocks("StatusData")) { @@ -897,8 +928,8 @@ void FSPanelSearchPeople::processSearchReply(LLMessageSystem* msg, void**) return; } } - - BOOL found_one = FALSE; + + bool found_one = false; S32 num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies); if (num_new_rows == 0 && self->mResultsReceived == 0) { @@ -907,10 +938,10 @@ void FSPanelSearchPeople::processSearchReply(LLMessageSystem* msg, void**) search_results->setEnabled(FALSE); search_results->setCommentText(LLTrans::getString("not_found", map)); } - + self->mResultsReceived += num_new_rows; num_new_rows = self->showNextButton(num_new_rows); - + for (S32 i = 0; i < num_new_rows; i++) { msg->getStringFast( _PREHASH_QueryReplies, _PREHASH_FirstName, first_name, i); @@ -930,25 +961,25 @@ void FSPanelSearchPeople::processSearchReply(LLMessageSystem* msg, void**) { LL_DEBUGS("Search") << "Got: " << first_name << " " << last_name << " AgentID: " << agent_id << LL_ENDL; search_results->setEnabled(TRUE); - found_one = TRUE; + found_one = true; std::string avatar_name; avatar_name = LLCacheName::buildFullName(first_name, last_name); - + LLSD content; LLSD element; - + element["id"] = agent_id; - + element["columns"][0]["column"] = "icon"; element["columns"][0]["type"] = "icon"; element["columns"][0]["value"] = "icon_avatar_offline.tga"; - + element["columns"][1]["column"] = "username"; element["columns"][1]["value"] = avatar_name; - + content["name"] = avatar_name; - + search_results->addElement(element, ADD_BOTTOM); self->mResultsContent[agent_id.asString()] = content; } @@ -994,12 +1025,12 @@ BOOL FSPanelSearchGroups::postBuild() mSearchResults->setEnabled(FALSE); mSearchResults->setCommentText(LLTrans::getString("no_results")); } - + childSetAction("groups_next", boost::bind(&FSPanelSearchGroups::onBtnNext, this)); childSetAction("groups_back", boost::bind(&FSPanelSearchGroups::onBtnBack, this)); getChildView("groups_next")->setEnabled(FALSE); getChildView("groups_back")->setEnabled(FALSE); - + return TRUE; } @@ -1009,14 +1040,14 @@ void FSPanelSearchGroups::focusDefaultElement() } void FSPanelSearchGroups::find() -{ +{ std::string text = filterShortWords(mSearchComboBox->getSimple()); if (text.size() == 0) { mSearchResults->setCommentText(LLTrans::getString("search_short")); return; } - + static LLUICachedControl inc_pg("ShowPGSims", 1); static LLUICachedControl inc_mature("ShowMatureSims", 0); static LLUICachedControl inc_adult("ShowAdultSims", 0); @@ -1027,29 +1058,41 @@ void FSPanelSearchGroups::find() } U32 scope = 0; if (gAgent.wantsPGOnly()) + { scope |= DFQ_PG_SIMS_ONLY; + } bool adult_enabled = gAgent.canAccessAdult(); bool mature_enabled = gAgent.canAccessMature(); if (inc_pg) + { scope |= DFQ_INC_PG; + } if (inc_mature && mature_enabled) + { scope |= DFQ_INC_MATURE; + } if (inc_adult && adult_enabled) + { scope |= DFQ_INC_ADULT; + } scope |= DFQ_GROUPS; - + mResultsReceived = 0; if (mQueryID.notNull()) + { mQueryID.setNull(); + } mQueryID.generate(); - + if (mStartSearch < 0) + { mStartSearch = 0; - + } + gMessageSystem->newMessage("DirFindQuery"); gMessageSystem->nextBlock("AgentData"); - gMessageSystem->addUUID("AgentID", gAgent.getID()); - gMessageSystem->addUUID("SessionID", gAgent.getSessionID()); + gMessageSystem->addUUID("AgentID", gAgentID); + gMessageSystem->addUUID("SessionID", gAgentSessionID); gMessageSystem->nextBlock("QueryData"); gMessageSystem->addUUID("QueryID", getQueryID()); gMessageSystem->addString("QueryText", text); @@ -1057,7 +1100,7 @@ void FSPanelSearchGroups::find() gMessageSystem->addS32("QueryStart", mStartSearch); gAgent.sendReliableMessage(); LL_DEBUGS("Search") << "Firing off search request: " << getQueryID() << LL_ENDL; - + mSearchResults->deleteAllItems(); mSearchResults->setCommentText(LLTrans::getString("searching")); mNumResultsReturned = 0; @@ -1070,7 +1113,7 @@ void FSPanelSearchGroups::onBtnFind() { LLSearchHistory::getInstance()->addEntry(text); } - + resetSearch(); find(); @@ -1080,7 +1123,7 @@ void FSPanelSearchGroups::onBtnNext() { mStartSearch += RESULT_PAGE_SIZE; getChildView("groups_back")->setEnabled(TRUE); - + find(); } @@ -1088,7 +1131,7 @@ void FSPanelSearchGroups::onBtnBack() { mStartSearch -= RESULT_PAGE_SIZE; getChildView("groups_back")->setEnabled(mStartSearch > 0); - + find(); } @@ -1118,7 +1161,9 @@ void FSPanelSearchGroups::onSelectItem() } FSFloaterSearch* search_instance = LLFloaterReg::getTypedInstance("search"); if (search_instance) + { search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_GROUP); + } } // static @@ -1130,30 +1175,33 @@ void FSPanelSearchGroups::processSearchReply(LLMessageSystem* msg, void**) std::string group_name; S32 members; F32 search_order; - + msg->getUUIDFast( _PREHASH_QueryData, _PREHASH_QueryID, query_id); msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AgentID, agent_id); - + // Not for us - if (agent_id != gAgent.getID()) return; + if (agent_id != gAgentID) + { + return; + } LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; - + FSPanelSearchGroups* self = (FSPanelSearchGroups*)FSFloaterSearch::getSearchPanel("panel_ls_groups"); - + // floater is closed or these are not results from our last request if (NULL == self || query_id != self->mQueryID) { return; } - + LLScrollListCtrl* search_results = self->getChild("search_results_groups"); - + // Clear "Searching" label on first results if (self->mNumResultsReturned++ == 0) { search_results->deleteAllItems(); } - + // Check for status messages if (msg->getNumberOfBlocks("StatusData")) { @@ -1186,8 +1234,8 @@ void FSPanelSearchGroups::processSearchReply(LLMessageSystem* msg, void**) return; } } - - BOOL found_one = FALSE; + + bool found_one = false; S32 num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies); if (num_new_rows == 0 && self->mResultsReceived == 0) { @@ -1196,10 +1244,10 @@ void FSPanelSearchGroups::processSearchReply(LLMessageSystem* msg, void**) search_results->setEnabled(FALSE); search_results->setCommentText(LLTrans::getString("not_found", map)); } - + self->mResultsReceived += num_new_rows; num_new_rows = self->showNextButton(num_new_rows); - + for (S32 i = 0; i < num_new_rows; i++) { msg->getUUIDFast( _PREHASH_QueryReplies, _PREHASH_GroupID, group_id, i); @@ -1218,28 +1266,28 @@ void FSPanelSearchGroups::processSearchReply(LLMessageSystem* msg, void**) { LL_DEBUGS("Search") << "Got: " << group_name << " GroupID: " << group_id << LL_ENDL; search_results->setEnabled(TRUE); - found_one = TRUE; - + found_one = true; + LLSD content; LLSD element; - + element["id"] = group_id; - + element["columns"][0]["column"] = "icon"; element["columns"][0]["type"] = "icon"; element["columns"][0]["value"] = "Icon_Group"; - + element["columns"][1]["column"] = "group_name"; element["columns"][1]["value"] = group_name; - + element["columns"][2]["column"] = "members"; element["columns"][2]["value"] = members; - + element["columns"][3]["column"] = "score"; element["columns"][3]["value"] = search_order; - + content["name"] = group_name; - + search_results->addElement(element, ADD_BOTTOM); self->mResultsContent[group_id.asString()] = content; } @@ -1301,7 +1349,7 @@ BOOL FSPanelSearchPlaces::postBuild() childSetAction("places_back", boost::bind(&FSPanelSearchPlaces::onBtnBack, this)); getChildView("places_next")->setEnabled(FALSE); getChildView("places_back")->setEnabled(FALSE); - + return TRUE; } @@ -1311,14 +1359,14 @@ void FSPanelSearchPlaces::focusDefaultElement() } void FSPanelSearchPlaces::find() -{ +{ std::string text = filterShortWords(mSearchComboBox->getSimple()); if (text.size() == 0) { mSearchResults->setCommentText(LLTrans::getString("search_short")); return; } - + static LLUICachedControl inc_pg("ShowPGSims", 1); static LLUICachedControl inc_mature("ShowMatureSims", 0); static LLUICachedControl inc_adult("ShowAdultSims", 0); @@ -1339,29 +1387,41 @@ void FSPanelSearchPlaces::find() } U32 scope = 0; if (gAgent.wantsPGOnly()) + { scope |= DFQ_PG_SIMS_ONLY; + } bool adult_enabled = gAgent.canAccessAdult(); bool mature_enabled = gAgent.canAccessMature(); if (inc_pg) + { scope |= DFQ_INC_PG; + } if (inc_mature && mature_enabled) + { scope |= DFQ_INC_MATURE; + } if (inc_adult && adult_enabled) + { scope |= DFQ_INC_ADULT; + } scope |= DFQ_DWELL_SORT; - + mResultsReceived = 0; if (mQueryID.notNull()) + { mQueryID.setNull(); + } mQueryID.generate(); - + if (mStartSearch < 0) + { mStartSearch = 0; - + } + gMessageSystem->newMessage("DirPlacesQuery"); gMessageSystem->nextBlock("AgentData"); - gMessageSystem->addUUID("AgentID", gAgent.getID()); - gMessageSystem->addUUID("SessionID", gAgent.getSessionID()); + gMessageSystem->addUUID("AgentID", gAgentID); + gMessageSystem->addUUID("SessionID", gAgentSessionID); gMessageSystem->nextBlock("QueryData"); gMessageSystem->addUUID("QueryID", getQueryID()); gMessageSystem->addString("QueryText", text); @@ -1372,7 +1432,7 @@ void FSPanelSearchPlaces::find() gMessageSystem->addS32("QueryStart", mStartSearch); gAgent.sendReliableMessage(); LL_DEBUGS("Search") << "Firing off places search request: " << getQueryID() << LL_ENDL; - + mSearchResults->deleteAllItems(); mSearchResults->setCommentText(LLTrans::getString("searching")); mNumResultsReturned = 0; @@ -1381,13 +1441,13 @@ void FSPanelSearchPlaces::find() void FSPanelSearchPlaces::onBtnFind() { std::string text = mSearchComboBox->getSimple(); - if(!text.empty()) + if (!text.empty()) { LLSearchHistory::getInstance()->addEntry(text); } - + resetSearch(); - + find(); } @@ -1395,7 +1455,7 @@ void FSPanelSearchPlaces::onBtnNext() { mStartSearch += RESULT_PAGE_SIZE; getChildView("places_back")->setEnabled(TRUE); - + find(); } @@ -1403,7 +1463,7 @@ void FSPanelSearchPlaces::onBtnBack() { mStartSearch -= RESULT_PAGE_SIZE; getChildView("places_back")->setEnabled(mStartSearch > 0); - + find(); } @@ -1433,43 +1493,48 @@ void FSPanelSearchPlaces::onSelectItem() } FSFloaterSearch* search_instance = LLFloaterReg::getTypedInstance("search"); if (search_instance) + { search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_PLACE); + } } // static void FSPanelSearchPlaces::processSearchReply(LLMessageSystem* msg, void**) { - LLUUID agent_id; - LLUUID query_id; - LLUUID parcel_id; + LLUUID agent_id; + LLUUID query_id; + LLUUID parcel_id; std::string name; - BOOL for_sale; - BOOL auction; - F32 dwell; - + BOOL for_sale; + BOOL auction; + F32 dwell; + msg->getUUID("AgentData", "AgentID", agent_id); msg->getUUID("QueryData", "QueryID", query_id); - + // Not for us - if (agent_id != gAgent.getID()) return; + if (agent_id != gAgentID) + { + return; + } LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; - + FSPanelSearchPlaces* self = (FSPanelSearchPlaces*)FSFloaterSearch::getSearchPanel("panel_ls_places"); - + // floater is closed or these are not results from our last request if (NULL == self || query_id != self->getQueryID()) { return; } - + LLScrollListCtrl* search_results = self->getChild("search_results_places"); - + // Clear "Searching" label on first results if (self->mNumResultsReturned++ == 0) { search_results->deleteAllItems(); } - + // Check for status messages if (msg->getNumberOfBlocks("StatusData")) { @@ -1508,8 +1573,8 @@ void FSPanelSearchPlaces::processSearchReply(LLMessageSystem* msg, void**) return; } } - - BOOL found_one = FALSE; + + bool found_one = false; S32 num_new_rows = msg->getNumberOfBlocks("QueryReplies"); if (num_new_rows == 0 && self->mResultsReceived == 0) { @@ -1518,10 +1583,10 @@ void FSPanelSearchPlaces::processSearchReply(LLMessageSystem* msg, void**) search_results->setEnabled(FALSE); search_results->setCommentText(LLTrans::getString("not_found", map)); } - + self->mResultsReceived += num_new_rows; num_new_rows = self->showNextButton(num_new_rows); - + for (S32 i = 0; i < num_new_rows; i++) { msg->getUUID( "QueryReplies", "ParcelID", parcel_id, i); @@ -1541,13 +1606,13 @@ void FSPanelSearchPlaces::processSearchReply(LLMessageSystem* msg, void**) { LL_DEBUGS("Search") << "Got: " << name << " ParcelID: " << parcel_id << LL_ENDL; search_results->setEnabled(TRUE); - found_one = TRUE; - + found_one = true; + LLSD content; LLSD element; - + element["id"] = parcel_id; - + if (auction) { element["columns"][0]["column"] = "icon"; @@ -1566,16 +1631,16 @@ void FSPanelSearchPlaces::processSearchReply(LLMessageSystem* msg, void**) element["columns"][0]["type"] = "icon"; element["columns"][0]["value"] = "Icon_Place"; } - + element["columns"][1]["column"] = "place_name"; element["columns"][1]["value"] = name; - + content["name"] = name; - + std::string buffer = llformat("%.0f", (F64)dwell); element["columns"][2]["column"] = "dwell"; element["columns"][2]["value"] = buffer; - + search_results->addElement(element, ADD_BOTTOM); self->mResultsContent[parcel_id.asString()] = content; } @@ -1650,67 +1715,99 @@ void FSPanelSearchLand::find() LLNotificationsUtil::add("NoContentToSearch"); return; } - + U32 category = ST_ALL; const std::string& selection = findChild("land_category")->getSelectedValue().asString(); if (!selection.empty()) { if (selection == "Auction") + { category = ST_AUCTION; + } else if (selection == "Mainland") + { category = ST_MAINLAND; + } else if (selection == "Estate") + { category = ST_ESTATE; + } } - + U32 scope = 0; if (gAgent.wantsPGOnly()) + { scope |= DFQ_PG_SIMS_ONLY; + } bool mature_enabled = gAgent.canAccessMature(); bool adult_enabled = gAgent.canAccessAdult(); if (inc_pg) + { scope |= DFQ_INC_PG; + } if (inc_mature && mature_enabled) + { scope |= DFQ_INC_MATURE; + } if (inc_adult && adult_enabled) + { scope |= DFQ_INC_ADULT; + } const std::string& sort = findChild("land_sort_combo")->getSelectedValue().asString(); if (!sort.empty()) { if (sort == "Name") + { scope |= DFQ_NAME_SORT; + } else if (sort == "Price") + { scope |= DFQ_PRICE_SORT; + } else if (sort == "PPM") + { scope |= DFQ_PER_METER_SORT; + } else if (sort == "Area") + { scope |= DFQ_AREA_SORT; + } } else { scope |= DFQ_PRICE_SORT; } if (childGetValue("ascending_check").asBoolean()) + { scope |= DFQ_SORT_ASC; + } if (limit_price) + { scope |= DFQ_LIMIT_BY_PRICE; + } if (limit_area) + { scope |= DFQ_LIMIT_BY_AREA; + } S32 price = childGetValue("edit_price").asInteger(); S32 area = childGetValue("edit_area").asInteger(); - + mResultsReceived = 0; if (mQueryID.notNull()) + { mQueryID.setNull(); + } mQueryID.generate(); - + if (mStartSearch < 0) + { mStartSearch = 0; - + } + gMessageSystem->newMessage("DirLandQuery"); gMessageSystem->nextBlock("AgentData"); - gMessageSystem->addUUID("AgentID", gAgent.getID()); - gMessageSystem->addUUID("SessionID", gAgent.getSessionID()); + gMessageSystem->addUUID("AgentID", gAgentID); + gMessageSystem->addUUID("SessionID", gAgentSessionID); gMessageSystem->nextBlock("QueryData"); gMessageSystem->addUUID("QueryID", getQueryID()); gMessageSystem->addU32("QueryFlags", scope); @@ -1720,7 +1817,7 @@ void FSPanelSearchLand::find() gMessageSystem->addS32("QueryStart", mStartSearch); gAgent.sendReliableMessage(); LL_DEBUGS("Search") << "Firing off places search request: " << getQueryID() << category << LL_ENDL; - + mSearchResults->deleteAllItems(); mSearchResults->setCommentText(LLTrans::getString("searching")); mNumResultsReturned = 0; @@ -1729,7 +1826,7 @@ void FSPanelSearchLand::find() void FSPanelSearchLand::onBtnFind() { resetSearch(); - + find(); } @@ -1737,7 +1834,7 @@ void FSPanelSearchLand::onBtnNext() { mStartSearch += RESULT_PAGE_SIZE; getChildView("land_back")->setEnabled(TRUE); - + find(); } @@ -1745,7 +1842,7 @@ void FSPanelSearchLand::onBtnBack() { mStartSearch -= RESULT_PAGE_SIZE; getChildView("land_back")->setEnabled(mStartSearch > 0); - + find(); } @@ -1775,51 +1872,56 @@ void FSPanelSearchLand::onSelectItem() } FSFloaterSearch* search_instance = LLFloaterReg::getTypedInstance("search"); if (search_instance) + { search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_PLACE); + } } // static void FSPanelSearchLand::processSearchReply(LLMessageSystem* msg, void**) { - LLUUID agent_id; - LLUUID query_id; - LLUUID parcel_id; + LLUUID agent_id; + LLUUID query_id; + LLUUID parcel_id; std::string name; - std::string land_sku; - std::string land_type; - BOOL auction; - BOOL for_sale; - S32 price; - S32 area; - + std::string land_sku; + std::string land_type; + BOOL auction; + BOOL for_sale; + S32 price; + S32 area; + msg->getUUID("AgentData", "AgentID", agent_id); msg->getUUID("QueryData", "QueryID", query_id); - + // Not for us - if (agent_id != gAgent.getID()) return; + if (agent_id != gAgentID) + { + return; + } LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; - + FSPanelSearchLand* self = (FSPanelSearchLand*)FSFloaterSearch::getSearchPanel("panel_ls_land"); - + // floater is closed or these are not results from our last request if (NULL == self || query_id != self->mQueryID) { return; } - + LLScrollListCtrl* search_results = self->getChild("search_results_land"); // clear "Searching" label on first results if (self->mNumResultsReturned++ == 0) { search_results->deleteAllItems(); } - + static LLUICachedControl use_price("FindLandPrice", 1); static LLUICachedControl use_area("FindLandArea", 1); S32 limit_price = self->childGetValue("edit_price").asInteger(); S32 limit_area = self->childGetValue("edit_area").asInteger(); - - BOOL found_one = FALSE; + + bool found_one = false; S32 num_new_rows = msg->getNumberOfBlocks("QueryReplies"); if (num_new_rows == 0 && self->mResultsReceived == 0) { @@ -1829,7 +1931,7 @@ void FSPanelSearchLand::processSearchReply(LLMessageSystem* msg, void**) search_results->setCommentText(LLTrans::getString("not_found", map)); } self->mResultsReceived += num_new_rows; - + S32 not_auction = 0; for (S32 i = 0; i < num_new_rows; i++) { @@ -1849,7 +1951,7 @@ void FSPanelSearchLand::processSearchReply(LLMessageSystem* msg, void**) { LL_DEBUGS("Search") << "Got: " << name << " ClassifiedID: " << parcel_id << LL_ENDL; search_results->setEnabled(TRUE); - found_one = TRUE; + found_one = true; if ( msg->getSizeFast(_PREHASH_QueryReplies, i, _PREHASH_ProductSKU) > 0 ) { msg->getStringFast( _PREHASH_QueryReplies, _PREHASH_ProductSKU, land_sku, i); @@ -1861,15 +1963,21 @@ void FSPanelSearchLand::processSearchReply(LLMessageSystem* msg, void**) land_type = LLTrans::getString("land_type_unknown"); } if (parcel_id.isNull()) + { continue; + } if (use_price && (price > limit_price)) + { continue; + } if (use_area && (area < limit_area)) + { continue; - + } + LLSD content; LLSD element; - + element["id"] = parcel_id; if (auction) { @@ -1889,12 +1997,12 @@ void FSPanelSearchLand::processSearchReply(LLMessageSystem* msg, void**) element["columns"][0]["type"] = "icon"; element["columns"][0]["value"] = "Icon_Place"; } - + element["columns"][1]["column"] = "land_name"; element["columns"][1]["value"] = name; - + content["place_name"] = name; - + std::string buffer = "Auction"; if (!auction) { @@ -1903,16 +2011,20 @@ void FSPanelSearchLand::processSearchReply(LLMessageSystem* msg, void**) } element["columns"][2]["column"] = "price"; element["columns"][2]["value"] = price; - + element["columns"][3]["column"] = "area"; element["columns"][3]["value"] = area; if (!auction) { F32 ppm; if (area > 0) + { ppm = (F32)price / (F32)area; + } else + { ppm = 0.f; + } std::string ppm_buffer = llformat("%.1f", ppm); element["columns"][4]["column"] = "ppm"; element["columns"][4]["value"] = ppm_buffer; @@ -1922,10 +2034,10 @@ void FSPanelSearchLand::processSearchReply(LLMessageSystem* msg, void**) element["columns"][4]["column"] = "ppm"; element["columns"][4]["value"] = "1.0"; } - + element["columns"][5]["column"] = "land_type"; element["columns"][5]["value"] = land_type; - + search_results->addElement(element, ADD_BOTTOM); self->mResultsContent[parcel_id.asString()] = content; } @@ -1974,7 +2086,7 @@ BOOL FSPanelSearchClassifieds::postBuild() mSearchResults->setEnabled(FALSE); mSearchResults->setCommentText(LLTrans::getString("no_results")); } - + mClassifiedsCategory = getChild("classifieds_category"); if (mClassifiedsCategory) { @@ -2010,7 +2122,7 @@ void FSPanelSearchClassifieds::find() mSearchResults->setCommentText(LLTrans::getString("search_short")); return; } - + static LLUICachedControl inc_pg("ShowPGClassifieds", 1); static LLUICachedControl inc_mature("ShowMatureClassifieds", 0); static LLUICachedControl inc_adult("ShowAdultClassifieds", 0); @@ -2022,19 +2134,23 @@ void FSPanelSearchClassifieds::find() U32 category = mClassifiedsCategory->getValue().asInteger(); BOOL auto_renew = FALSE; U32 flags = pack_classified_flags_request(auto_renew, inc_pg, inc_mature, inc_adult); - + mResultsReceived = 0; if (mQueryID.notNull()) + { mQueryID.setNull(); + } mQueryID.generate(); - + if (mStartSearch < 0) + { mStartSearch = 0; - + } + gMessageSystem->newMessageFast(_PREHASH_DirClassifiedQuery); gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); gMessageSystem->nextBlockFast(_PREHASH_QueryData); gMessageSystem->addUUIDFast(_PREHASH_QueryID, getQueryID()); gMessageSystem->addStringFast(_PREHASH_QueryText, text); @@ -2043,7 +2159,7 @@ void FSPanelSearchClassifieds::find() gMessageSystem->addS32Fast(_PREHASH_QueryStart, mStartSearch); gAgent.sendReliableMessage(); LL_DEBUGS("Search") << "Firing off classified ad search request: " << getQueryID() << LL_ENDL; - + mSearchResults->deleteAllItems(); mSearchResults->setCommentText(LLTrans::getString("searching")); mNumResultsReturned = 0; @@ -2056,9 +2172,9 @@ void FSPanelSearchClassifieds::onBtnFind() { LLSearchHistory::getInstance()->addEntry(text); } - + resetSearch(); - + find(); } @@ -2066,7 +2182,7 @@ void FSPanelSearchClassifieds::onBtnNext() { mStartSearch += RESULT_PAGE_SIZE; getChildView("classifieds_back")->setEnabled(TRUE); - + find(); } @@ -2074,7 +2190,7 @@ void FSPanelSearchClassifieds::onBtnBack() { mStartSearch -= RESULT_PAGE_SIZE; getChildView("classifieds_back")->setEnabled(mStartSearch > 0); - + find(); } @@ -2104,29 +2220,34 @@ void FSPanelSearchClassifieds::onSelectItem() } FSFloaterSearch* search_instance = LLFloaterReg::getTypedInstance("search"); if (search_instance) + { search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_CLASSIFIED); + } } // static void FSPanelSearchClassifieds::processSearchReply(LLMessageSystem* msg, void**) { - LLUUID agent_id; - LLUUID query_id; - LLUUID classified_id; - std::string name; - U32 creation_date; - U32 expiration_date; - S32 price_for_listing; - + LLUUID agent_id; + LLUUID query_id; + LLUUID classified_id; + std::string name; + U32 creation_date; + U32 expiration_date; + S32 price_for_listing; + msg->getUUID("AgentData", "AgentID", agent_id); msg->getUUID("QueryData", "QueryID", query_id); - + // Not for us - if (agent_id != gAgent.getID()) return; + if (agent_id != gAgentID) + { + return; + } LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; - + FSPanelSearchClassifieds* self = (FSPanelSearchClassifieds*)FSFloaterSearch::getSearchPanel("panel_ls_classifieds"); - + if (msg->getNumberOfBlocks("StatusData")) { U32 status; @@ -2136,21 +2257,21 @@ void FSPanelSearchClassifieds::processSearchReply(LLMessageSystem* msg, void**) LLNotificationsUtil::add("SearchWordBanned"); } } - + // floater is closed or these are not results from our last request if (NULL == self || query_id != self->mQueryID) { return; } - + LLScrollListCtrl* search_results = self->getChild("search_results_classifieds"); - + // Clear "Searching" label on first results if (self->mNumResultsReturned++ == 0) { search_results->deleteAllItems(); } - + // Check for status messages if (msg->getNumberOfBlocks("StatusData")) { @@ -2183,8 +2304,8 @@ void FSPanelSearchClassifieds::processSearchReply(LLMessageSystem* msg, void**) return; } } - - BOOL found_one = FALSE; + + bool found_one = false; S32 num_new_rows = msg->getNumberOfBlocks("QueryReplies"); if (num_new_rows == 0 && self->mResultsReceived == 0) { @@ -2195,7 +2316,7 @@ void FSPanelSearchClassifieds::processSearchReply(LLMessageSystem* msg, void**) } self->mResultsReceived += num_new_rows; num_new_rows = self->showNextButton(num_new_rows); - + for (S32 i = 0; i < num_new_rows; i++) { msg->getUUID( "QueryReplies", "ClassifiedID", classified_id, i); @@ -2215,25 +2336,25 @@ void FSPanelSearchClassifieds::processSearchReply(LLMessageSystem* msg, void**) { LL_DEBUGS("Search") << "Got: " << name << " ClassifiedID: " << classified_id << LL_ENDL; search_results->setEnabled(TRUE); - found_one = TRUE; - + found_one = true; + LLSD content; LLSD element; - + element["id"] = classified_id; - + element["columns"][0]["column"] = "icon"; element["columns"][0]["type"] = "icon"; element["columns"][0]["value"] = "icon_top_pick.tga"; - + element["columns"][1]["column"] = "classified_name"; element["columns"][1]["value"] = name; - + element["columns"][2]["column"] = "price"; element["columns"][2]["value"] = price_for_listing; - + content["name"] = name; - + search_results->addElement(element, ADD_BOTTOM); self->mResultsContent[classified_id.asString()] = content; } @@ -2287,20 +2408,20 @@ BOOL FSPanelSearchEvents::postBuild() mEventsMode->setCommitCallback(boost::bind(&FSPanelSearchEvents::onSearchModeChanged, this)); mEventsMode->selectFirstItem(); } - + childSetAction("events_next", boost::bind(&FSPanelSearchEvents::onBtnNext, this)); childSetAction("events_back", boost::bind(&FSPanelSearchEvents::onBtnBack, this)); childSetAction("events_tomorrow", boost::bind(&FSPanelSearchEvents::onBtnTomorrow, this)); childSetAction("events_yesterday", boost::bind(&FSPanelSearchEvents::onBtnYesterday, this)); childSetAction("events_today", boost::bind(&FSPanelSearchEvents::onBtnToday, this)); - + getChildView("events_next")->setEnabled(FALSE); getChildView("events_back")->setEnabled(FALSE); getChildView("events_tomorrow")->setEnabled(FALSE); getChildView("events_yesterday")->setEnabled(FALSE); getChildView("events_today")->setEnabled(FALSE); setDay(0); - + return TRUE; } @@ -2310,9 +2431,9 @@ void FSPanelSearchEvents::focusDefaultElement() } void FSPanelSearchEvents::find() -{ +{ std::string text = filterShortWords(mSearchComboBox->getSimple()); - + static LLUICachedControl inc_pg("ShowPGEvents", 1); static LLUICachedControl inc_mature("ShowMatureEvents", 0); static LLUICachedControl inc_adult("ShowAdultEvents", 0); @@ -2321,41 +2442,57 @@ void FSPanelSearchEvents::find() LLNotificationsUtil::add("NoContentToSearch"); return; } - + U32 category = findChild("events_category")->getSelectedValue().asInteger(); U32 scope = DFQ_DATE_EVENTS; if (gAgent.wantsPGOnly()) + { scope |= DFQ_PG_SIMS_ONLY; + } bool mature_enabled = gAgent.canAccessMature(); bool adult_enabled = gAgent.canAccessAdult(); if (inc_pg) + { scope |= DFQ_INC_PG; + } if (inc_mature && mature_enabled) + { scope |= DFQ_INC_MATURE; + } if (inc_adult && adult_enabled) + { scope |= DFQ_INC_ADULT; - + } + std::ostringstream string; - + if ("current" == childGetValue("events_search_mode").asString()) + { string << "u|"; + } else + { string << mDay << "|"; + } string << category << "|"; string << text; - + mResultsReceived = 0; if (mQueryID.notNull()) + { mQueryID.setNull(); + } mQueryID.generate(); - + if (mStartSearch < 0) + { mStartSearch = 0; - + } + gMessageSystem->newMessage("DirFindQuery"); gMessageSystem->nextBlock("AgentData"); - gMessageSystem->addUUID("AgentID", gAgent.getID()); - gMessageSystem->addUUID("SessionID", gAgent.getSessionID()); + gMessageSystem->addUUID("AgentID", gAgentID); + gMessageSystem->addUUID("SessionID", gAgentSessionID); gMessageSystem->nextBlock("QueryData"); gMessageSystem->addUUID("QueryID", getQueryID()); gMessageSystem->addString("QueryText", string.str()); @@ -2363,7 +2500,7 @@ void FSPanelSearchEvents::find() gMessageSystem->addS32("QueryStart", mStartSearch); gAgent.sendReliableMessage(); LL_DEBUGS("Search") << "Firing off search request: " << getQueryID() << " Search Text: " << string.str() << LL_ENDL; - + mSearchResults->deleteAllItems(); mSearchResults->setCommentText(LLTrans::getString("searching")); mNumResultsReturned = 0; @@ -2372,13 +2509,13 @@ void FSPanelSearchEvents::find() void FSPanelSearchEvents::onBtnFind() { std::string text = mSearchComboBox->getSimple(); - if(!text.empty()) + if (!text.empty()) { LLSearchHistory::getInstance()->addEntry(text); } - + resetSearch(); - + find(); } @@ -2386,7 +2523,7 @@ void FSPanelSearchEvents::onBtnNext() { mStartSearch += RESULT_PAGE_SIZE; getChildView("events_back")->setEnabled(TRUE); - + find(); } @@ -2394,7 +2531,7 @@ void FSPanelSearchEvents::onBtnBack() { mStartSearch -= RESULT_PAGE_SIZE; getChildView("events_back")->setEnabled(mStartSearch > 0); - + find(); } @@ -2402,7 +2539,7 @@ void FSPanelSearchEvents::onBtnTomorrow() { resetSearch(); setDay(mDay + 1); - + find(); } @@ -2410,7 +2547,7 @@ void FSPanelSearchEvents::onBtnYesterday() { resetSearch(); setDay(mDay - 1); - + find(); } @@ -2418,7 +2555,7 @@ void FSPanelSearchEvents::onBtnToday() { resetSearch(); setDay(0); - + find(); } @@ -2449,7 +2586,7 @@ void FSPanelSearchEvents::setDay(S32 day) { mDay = day; struct tm* internal_time; - + time_t utc = time_corrected(); utc += day * 24 * 60 * 60; internal_time = utc_to_pacific_time(utc, is_daylight_savings()); @@ -2477,35 +2614,40 @@ void FSPanelSearchEvents::onSelectItem() S32 event_id = mSearchResults->getSelectedValue(); FSFloaterSearch* search_instance = LLFloaterReg::getTypedInstance("search"); if (search_instance) + { search_instance->FSFloaterSearch::onSelectedEvent(event_id); + } } // static void FSPanelSearchEvents::processSearchReply(LLMessageSystem* msg, void**) { - LLUUID agent_id; - LLUUID query_id; - LLUUID owner_id; + LLUUID agent_id; + LLUUID query_id; + LLUUID owner_id; std::string name; std::string date; - + msg->getUUID("AgentData", "AgentID", agent_id); msg->getUUID("QueryData", "QueryID", query_id); - + // Not for us - if (agent_id != gAgent.getID()) return; + if (agent_id != gAgentID) + { + return; + } LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; - + FSPanelSearchEvents* self = (FSPanelSearchEvents*)FSFloaterSearch::getSearchPanel("panel_ls_events"); - + // floater is closed or these are not results from our last request if (NULL == self || query_id != self->mQueryID) { return; } - + LLScrollListCtrl* search_results = self->getChild("search_results_events"); - + // Clear "Searching" label on first results if (self->mNumResultsReturned++ == 0) { @@ -2561,7 +2703,7 @@ void FSPanelSearchEvents::processSearchReply(LLMessageSystem* msg, void**) return; } } - + S32 num_new_rows = msg->getNumberOfBlocks("QueryReplies"); if (num_new_rows == 0 && self->mResultsReceived == 0) { @@ -2570,20 +2712,20 @@ void FSPanelSearchEvents::processSearchReply(LLMessageSystem* msg, void**) search_results->setEnabled(FALSE); search_results->setCommentText(LLTrans::getString("not_found", map)); } - + self->mResultsReceived += num_new_rows; num_new_rows = self->showNextButton(num_new_rows); static LLUICachedControl inc_pg("ShowPGEvents", 1); static LLUICachedControl inc_mature("ShowMatureEvents", 0); static LLUICachedControl inc_adult("ShowAdultEvents", 0); - BOOL found_one = FALSE; + bool found_one = false; for (S32 i = 0; i < num_new_rows; i++) { U32 event_id; U32 unix_time; U32 event_flags; - + msg->getUUID( "QueryReplies", "OwnerID", owner_id, i); msg->getString( "QueryReplies", "Name", name, i); msg->getU32( "QueryReplies", "EventID", event_id, i); @@ -2614,13 +2756,13 @@ void FSPanelSearchEvents::processSearchReply(LLMessageSystem* msg, void**) continue; } search_results->setEnabled(TRUE); - found_one = TRUE; + found_one = true; LLSD content; LLSD element; - + element["id"] = llformat("%u", event_id); - + if (event_flags == EVENT_FLAG_ADULT) { element["columns"][0]["column"] = "icon"; @@ -2641,16 +2783,16 @@ void FSPanelSearchEvents::processSearchReply(LLMessageSystem* msg, void**) } element["columns"][1]["column"] = "name"; element["columns"][1]["value"] = name; - + element["columns"][2]["column"] = "date"; element["columns"][2]["value"] = date; - + element["columns"][3]["column"] = "time"; element["columns"][3]["value"] = llformat("%u", unix_time); - + content["name"] = name; content["event_id"] = (S32)event_id; - + search_results->addElement(element, ADD_BOTTOM); std::string event = llformat("%u", event_id); self->mResultsContent[event] = content; @@ -2694,14 +2836,17 @@ BOOL FSPanelSearchWeb::postBuild() void FSPanelSearchWeb::loadURL(const SearchQuery &p) { - if (!mWebBrowser || !p.validateBlock()) return; - + if (!mWebBrowser || !p.validateBlock()) + { + return; + } + // work out the subdir to use based on the requested category LLSD subs = LLSD().with("CATEGORY", (mCategoryPaths.has(p.category) ? mCategoryPaths[p.category].asString() : mCategoryPaths["all"].asString())); - + // add the search query string subs["QUERY"] = LLURI::escape(p.query); - + // add the permissions token that login.cgi gave us // We use "search_token", and fallback to "auth_token" if not present. LLSD search_token = LLLoginInstance::getInstance()->getResponse("search_token"); @@ -2710,7 +2855,7 @@ void FSPanelSearchWeb::loadURL(const SearchQuery &p) search_token = LLLoginInstance::getInstance()->getResponse("auth_token"); } subs["AUTH_TOKEN"] = search_token.asString(); - + // add the user's preferred maturity (can be changed via prefs) std::string maturity; if (gAgent.prefersAdult()) @@ -2726,10 +2871,10 @@ void FSPanelSearchWeb::loadURL(const SearchQuery &p) maturity = "13"; // PG } subs["MATURITY"] = maturity; - + // add the user's god status subs["GODLIKE"] = gAgent.isGodlike() ? "1" : "0"; - + // Get the search URL and expand all of the substitutions // (also adds things like [LANGUAGE], [VERSION], [OS], etc.) std::string url; @@ -2745,9 +2890,9 @@ void FSPanelSearchWeb::loadURL(const SearchQuery &p) { url = LFSimFeatureHandler::instance().searchURL(); } - + url = LLWeb::expandURLSubstitutions(url, subs); - + // Finally, load the URL in the webpanel mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML); } @@ -2774,8 +2919,11 @@ void FSPanelSearchWeb::draw() std::string filterShortWords(std::string query_string) { - if (query_string.length() < 1) return ""; - + if (query_string.length() < 1) + { + return ""; + } + std::string final_query; bool filtered = false; boost::char_separator sep(" "); @@ -2799,7 +2947,7 @@ std::string filterShortWords(std::string query_string) filtered = true; } } - + if (filtered) { LLSD args = LLSD().with("FINALQUERY", final_query); @@ -2811,14 +2959,17 @@ std::string filterShortWords(std::string query_string) void fillSearchComboBox(LLSearchComboBox* search_combo) { - if(search_combo == NULL) return; - + if (search_combo == NULL) + { + return; + } + LLSearchHistory::getInstance()->load(); - + LLSearchHistory::search_history_list_t search_list = LLSearchHistory::getInstance()->getSearchHistoryList(); LLSearchHistory::search_history_list_t::const_iterator it = search_list.begin(); - for( ; search_list.end() != it; ++it) + for ( ; search_list.end() != it; ++it) { LLSearchHistory::LLSearchHistoryItem item = *it; search_combo->add(item.search_query); diff --git a/indra/newview/fsnearbychathub.cpp b/indra/newview/fsnearbychathub.cpp index 1b27b4c8cb..fa08908cf5 100644 --- a/indra/newview/fsnearbychathub.cpp +++ b/indra/newview/fsnearbychathub.cpp @@ -422,14 +422,8 @@ void FSNearbyChat::sendChatFromViewer(const LLWString& wtext, const LLWString& o if ( (0 == channel) && (rlv_handler_t::isEnabled()) ) { // Adjust the (public) chat "volume" on chat and gestures (also takes care of playing the proper animation) - if ( ((CHAT_TYPE_SHOUT == type) || (CHAT_TYPE_NORMAL == type)) && (gRlvHandler.hasBehaviour(RLV_BHVR_CHATNORMAL)) ) - type = CHAT_TYPE_WHISPER; - else if ( (CHAT_TYPE_SHOUT == type) && (gRlvHandler.hasBehaviour(RLV_BHVR_CHATSHOUT)) ) - type = CHAT_TYPE_NORMAL; - else if ( (CHAT_TYPE_WHISPER == type) && (gRlvHandler.hasBehaviour(RLV_BHVR_CHATWHISPER)) ) - type = CHAT_TYPE_NORMAL; - - animate &= !gRlvHandler.hasBehaviour( (!RlvUtil::isEmote(utf8_text)) ? RLV_BHVR_REDIRCHAT : RLV_BHVR_REDIREMOTE ); + type = RlvActions::checkChatVolume(type); + animate &= !RlvActions::hasBehaviour( (!RlvUtil::isEmote(utf8_text)) ? RLV_BHVR_REDIRCHAT : RLV_BHVR_REDIREMOTE ); } // [/RLVa:KB] diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 7bb6ea67a6..b8a2d52f2a 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -5647,7 +5647,7 @@ void LLTeleportRequestViaLocationLookAt::startTeleport() // [RLVa:KB] - Checked: RLVa-2.0.0 gAgent.doTeleportViaLocationLookAt(getPosGlobal(), getLookAt()); // [/RLVa:KB] -// gAgent.doTeleportViaLocationLookAt(getPosGlobal()); +// gAgent.doTeleportViaLocationLookAt(getPosGlobal()); } void LLTeleportRequestViaLocationLookAt::restartTeleport() @@ -5656,7 +5656,7 @@ void LLTeleportRequestViaLocationLookAt::restartTeleport() // [RLVa:KB] - Checked: RLVa-2.0.0 gAgent.doTeleportViaLocationLookAt(getPosGlobal(), getLookAt()); // [/RLVa:KB] -// gAgent.doTeleportViaLocationLookAt(getPosGlobal()); +// gAgent.doTeleportViaLocationLookAt(getPosGlobal()); } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index aef1486727..f5898300c4 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3779,7 +3779,7 @@ LLSD LLAppViewer::getViewerInfo() const #endif // [RLVa:KB] - Checked: 2010-04-18 (RLVa-1.2.0) - info["RLV_VERSION"] = (rlv_handler_t::isEnabled()) ? RlvStrings::getVersionAbout() : "(disabled)"; + info["RLV_VERSION"] = (rlv_handler_t::isEnabled()) ? RlvStrings::getVersionAbout() : LLTrans::getString("RLVaStatusDisabled"); // [/RLVa:KB] info["OPENGL_VERSION"] = (const char*)(glGetString(GL_VERSION)); info["LIBCURL_VERSION"] = LLCore::LLHttp::getCURLVersion(); diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index 2ab1b33b65..3ea0ba93a6 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -478,7 +478,10 @@ void LLFloaterIMNearbyChat::onChatBoxKeystroke() S32 length = raw_text.length(); - if( (length > 0) && (raw_text[0] != '/') ) // forward slash is used for escape (eg. emote) sequences +// if( (length > 0) && (raw_text[0] != '/') ) // forward slash is used for escape (eg. emote) sequences +// [RLVa:KB] - Checked: 2010-03-26 (RLVa-1.2.0b) | Modified: RLVa-1.0.0d + if ( (length > 0) && (raw_text[0] != '/') && (!RlvActions::hasBehaviour(RLV_BHVR_REDIRCHAT)) ) +// [/RLVa:KB] { gAgent.startTyping(); } @@ -719,6 +722,15 @@ void LLFloaterIMNearbyChat::sendChatFromViewer(const LLWString &wtext, EChatType utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1); } +// [RLVa:KB] - Checked: 2010-03-27 (RLVa-1.2.0b) | Modified: RLVa-1.2.0b + if ( (0 == channel) && (RlvActions::isRlvEnabled()) ) + { + // Adjust the (public) chat "volume" on chat and gestures (also takes care of playing the proper animation) + type = RlvActions::checkChatVolume(type); + animate &= !RlvActions::hasBehaviour( (!RlvUtil::isEmote(utf8_text)) ? RLV_BHVR_REDIRCHAT : RLV_BHVR_REDIREMOTE ); + } +// [/RLVa:KB] + // Don't animate for chats people can't hear (chat to scripts) if (animate && (channel == 0)) { diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index c7453a09da..ff411782fe 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -66,7 +66,7 @@ // [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e) #include "rlvactions.h" #include "rlvhandler.h" -#include "rlvhelper.h" +#include "rlvmodifiers.h" // [/RLVa:KB] #include diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index 3706396d8d..3171941407 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -1533,7 +1533,11 @@ void LLGroupMgr::notifyObservers(LLGroupChange gc) if(obs_it == mParticularObservers.end()) return; - observer_set_t& obs = obs_it->second; +// observer_set_t& obs = obs_it->second; +// [RLVa:KB] - Checked: RLVa-2.3 (General bugfix) + // Iterate over a *copy* of the observer list + observer_set_t obs = obs_it->second; +// [/RLVa:KB] for (observer_set_t::iterator ob_it = obs.begin(); ob_it != obs.end(); ++ob_it) { (*ob_it)->changed(group_id, gc); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index a2e1b62d68..b409379365 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1521,8 +1521,8 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) mColorSwatch->setValid(FALSE); } getChildView("color trans")->setEnabled(FALSE); + mCtrlRpt->setEnabled(FALSE); // Doesn't exist as of 2016-11-16 - //getChildView("rpt")->setEnabled(FALSE); //getChildView("tex offset")->setEnabled(FALSE); // getChildView("tex gen")->setEnabled(FALSE); @@ -1634,6 +1634,12 @@ void LLPanelFace::updateVisibility() getChildView("radio_material_type")->setVisible(!show_media); // FIRE-11407 - Be consistant and hide this with the other controls getChildView("rptctrl")->setVisible(combo_matmedia->getEnabled()); + getChildView("tex gen")->setVisible(combo_matmedia->getEnabled()); + getChildView("combobox texgen")->setVisible(combo_matmedia->getEnabled()); + getChildView("checkbox planar align")->setVisible(combo_matmedia->getEnabled()); + getChildView("checkbox_sync_settings")->setVisible(combo_matmedia->getEnabled()); + getChildView("copytextures")->setVisible(combo_matmedia->getEnabled()); + getChildView("pastetextures")->setVisible(combo_matmedia->getEnabled()); // and other additions... getChildView("flipTextureScaleU")->setVisible(combo_matmedia->getEnabled()); getChildView("flipTextureScaleV")->setVisible(combo_matmedia->getEnabled()); diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp index 313462812f..0e585dc63f 100644 --- a/indra/newview/llpanelwearing.cpp +++ b/indra/newview/llpanelwearing.cpp @@ -176,7 +176,7 @@ protected: attachments_selected = true; } // [RLVa:KB] - Checked: 2012-07-28 (RLVa-1.4.7) - if ( (rlv_handler_t::isEnabled()) && (!rlvPredCanRemoveItem(item)) ) + if ( (rlv_handler_t::isEnabled()) && (!rlvPredCanRemoveItem(*it)) ) { rlv_locked_count++; } diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index ab5123e964..bac3d10d0a 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -101,7 +101,7 @@ // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a) #include "rlvactions.h" #include "rlvhandler.h" -#include "rlvhelper.h" +#include "rlvmodifiers.h" // [/RLVa:KB] // Aurora Sim #include "llviewernetwork.h" @@ -2594,7 +2594,8 @@ void LLSelectMgr::logNoOp(LLSelectNode* node, void *) // static void LLSelectMgr::logAttachmentRequest(LLSelectNode* node, void *) { - LLAttachmentsMgr::instance().onAttachmentRequested(node->mItemID); +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-3.7 +// LLAttachmentsMgr::instance().onAttachmentRequested(node->mItemID); } // static diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp index 65ff61f02a..c16e630f42 100644 --- a/indra/newview/lltoolplacer.cpp +++ b/indra/newview/lltoolplacer.cpp @@ -45,7 +45,7 @@ #include "llui.h" // [RLVa:KB] - Checked: 2010-03-23 (RLVa-1.2.0a) #include "rlvhandler.h" -#include "rlvhelper.h" +#include "rlvmodifiers.h" // [/RLVa:KB] //Headers added for functions moved from viewer.cpp diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp index da0fe6251d..6dbbdd7f89 100644 --- a/indra/newview/lltoolselect.cpp +++ b/indra/newview/lltoolselect.cpp @@ -49,7 +49,7 @@ #include "llworld.h" // [RLVa:KB] - Checked: RLVa-2.0.0 #include "rlvactions.h" -#include "rlvhelper.h" +#include "rlvmodifiers.h" #include "llfloaterreg.h" // [/RLVa:KB] diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 40073b7ecd..001a670ec3 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -199,18 +199,7 @@ static bool handleAvatarHoverOffsetChanged(const LLSD& newvalue) { if (isAgentAvatarValid()) { - // [Legacy bake] - //gAgentAvatarp->setHoverIfRegionEnabled(); - if (gAgent.getRegion()->avatarHoverHeightEnabled()) - { - LLVector3 avOffset(0.0f, 0.0f, llclamp(newvalue.asReal(), MIN_HOVER_Z, MAX_HOVER_Z)); - gAgentAvatarp->setHoverOffset(avOffset, true); - } - else if (!gAgentAvatarp->isUsingServerBakes()) - { - gAgentAvatarp->computeBodySize(); - } - // [Legacy bake] + gAgentAvatarp->setHoverIfRegionEnabled(); } return true; } @@ -1013,6 +1002,9 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderDebugGL")->getSignal()->connect(boost::bind(&handleRenderDebugGLChanged, _2)); gSavedSettings.getControl("RenderDebugPipeline")->getSignal()->connect(boost::bind(&handleRenderDebugPipelineChanged, _2)); gSavedSettings.getControl("RenderResolutionDivisor")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _2)); +// [SL:KB] - Patch: Settings-RenderResolutionMultiplier | Checked: Catznip-5.4 + gSavedSettings.getControl("RenderResolutionMultiplier")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _2)); +// [/SL:KB] gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleRenderDeferredChanged, _2)); gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index a21495a961..9ea275d5b6 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -79,6 +79,7 @@ #include "llpostprocess.h" #include "llscenemonitor.h" // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a) +#include "rlvhandler.h" #include "rlvlocks.h" // [/RLVa:KB] #include "llpresetsmanager.h" @@ -1427,6 +1428,12 @@ void render_ui(F32 zoom_factor, int subfield) } render_hud_elements(); +// [RLVa:KB] - Checked: RLVa-2.3 (@setoverlay) + if (gRlvHandler.isEnabled()) + { + gRlvHandler.renderOverlay(); + } +// [/RLVa:KB] render_hud_attachments(); } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 6f89755f75..0da3da9773 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -10237,7 +10237,14 @@ void handle_rebake_textures(void*) if (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion()) { // [SL:KB] - Patch: Appearance-Misc | Checked: 2015-06-27 (Catznip-3.7) - LLAppearanceMgr::instance().syncCofVersionAndRefresh(); + if (!gAgent.getRegionCapability("IncrementCOFVersion").empty()) + { + LLAppearanceMgr::instance().syncCofVersionAndRefresh(); + } + else + { + LLAppearanceMgr::instance().requestServerAppearanceUpdate(); + } // [/SL:KB] // LLAppearanceMgr::instance().requestServerAppearanceUpdate(); avatar_tex_refresh(gAgentAvatarp); // FIRE-11800 - Refresh the textures too diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 47a76a51fd..50d81fa162 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -5293,7 +5293,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de } // [RLVa:KB] - Checked: RLVa-1.2.0 - if ( (found) && ((gTeleportDisplay) || ((rlv_handler_t::isEnabled()) && (found) && (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT)))) ) + if ( (found) && ((gTeleportDisplay) || ((rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT)))) ) { // Allow picking if: // - the drag-and-drop tool is active (allows inventory offers) @@ -6950,6 +6950,16 @@ void LLPickInfo::fetchResults() mPickPt = mMousePt; +// [RLVa:KB] - Checked: RLVa-2.3 (@setoverlay) + if ( (gRlvHandler.isEnabled()) && (hit_object) && (!hit_object->isHUDAttachment()) ) + { + if (gRlvHandler.hitTestOverlay(mMousePt)) + { + hit_object = nullptr; + } + } +// [/RLVa:KB] + U32 te_offset = face_hit > -1 ? face_hit : 0; if (mPickParticle) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 901afa10a8..5e4358eee7 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -8459,11 +8459,11 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading) BOOL LLVOAvatar::isFullyLoaded() const { -// return (mRenderUnloadedAvatar || mFullyLoaded); -// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.2) +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-2.2 // Changes to LLAppearanceMgr::updateAppearanceFromCOF() expect this function to actually return mFullyLoaded for gAgentAvatarp return (mRenderUnloadedAvatar && !isSelf()) ||(mFullyLoaded); // [/SL:KB] +// return (mRenderUnloadedAvatar || mFullyLoaded); } bool LLVOAvatar::isTooComplex() const diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 255a197fb1..eb388edca9 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -296,6 +296,12 @@ void LLVOAvatarSelf::setHoverIfRegionEnabled() setHoverOffset(LLVector3(0.0, 0.0, llclamp(hover_z,MIN_HOVER_Z,MAX_HOVER_Z))); LL_INFOS("Avatar") << avString() << " set hover height from debug setting " << hover_z << LL_ENDL; } + // [Legacy bake] + else if (!isUsingServerBakes()) + { + computeBodySize(); + } + // [Legacy bake] else { setHoverOffset(LLVector3(0.0, 0.0, 0.0)); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 8cf8868e2b..0d57c5399d 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -142,6 +142,9 @@ bool LLPipeline::RenderDeferred; F32 LLPipeline::RenderDeferredSunWash; U32 LLPipeline::RenderFSAASamples; U32 LLPipeline::RenderResolutionDivisor; +// [SL:KB] - Patch: Settings-RenderResolutionMultiplier | Checked: Catznip-5.4 +F32 LLPipeline::RenderResolutionMultiplier; +// [/SL:KB] bool LLPipeline::RenderUIBuffer; S32 LLPipeline::RenderShadowDetail; bool LLPipeline::RenderDeferredSSAO; @@ -615,6 +618,9 @@ void LLPipeline::init() connectRefreshCachedSettingsSafe("RenderDeferredSunWash"); connectRefreshCachedSettingsSafe("RenderFSAASamples"); connectRefreshCachedSettingsSafe("RenderResolutionDivisor"); +// [SL:KB] - Patch: Settings-RenderResolutionMultiplier | Checked: Catznip-5.4 + connectRefreshCachedSettingsSafe("RenderResolutionMultiplier"); +// [/SL:KB] connectRefreshCachedSettingsSafe("RenderUIBuffer"); connectRefreshCachedSettingsSafe("RenderShadowDetail"); connectRefreshCachedSettingsSafe("RenderDeferredSSAO"); @@ -834,17 +840,20 @@ void LLPipeline::resizeScreenTexture() GLuint resX = gViewerWindow->getWorldViewWidthRaw(); GLuint resY = gViewerWindow->getWorldViewHeightRaw(); -// [RLVa:KB] - Checked: 2014-02-23 (RLVa-1.4.10) - U32 resMod = RenderResolutionDivisor, resAdjustedX = resX, resAdjustedY = resY; - if ( (resMod > 1) && (resMod < resX) && (resMod < resY) ) +// [SL:KB] - Patch: Settings-RenderResolutionMultiplier | Checked: Catznip-5.4 + if ( (RenderResolutionDivisor > 1) && (RenderResolutionDivisor < resX) && (RenderResolutionDivisor < resY) ) { - resAdjustedX /= resMod; - resAdjustedY /= resMod; + resX /= RenderResolutionDivisor; + resY /= RenderResolutionDivisor; } + else if (RenderResolutionMultiplier != 1.f) + { + resX *= RenderResolutionMultiplier; + resY *= RenderResolutionMultiplier; + } +// [/SL:KB] - if ( (resAdjustedX != mScreen.getWidth()) || (resAdjustedY != mScreen.getHeight()) ) -// [/RLVa:KB] -// if ((resX != mScreen.getWidth()) || (resY != mScreen.getHeight())) + if ((resX != mScreen.getWidth()) || (resY != mScreen.getHeight())) { releaseScreenBuffers(); if (!allocateScreenBuffer(resX,resY)) @@ -1001,6 +1010,13 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) resX /= res_mod; resY /= res_mod; } +// [SL:KB] - Patch: Settings-RenderResolutionMultiplier | Checked: Catznip-5.4 + else if (RenderResolutionMultiplier != 1.f) + { + resX *= RenderResolutionMultiplier; + resY *= RenderResolutionMultiplier; + } +// [/SL:KB] if (RenderUIBuffer) { @@ -1184,6 +1200,9 @@ void LLPipeline::refreshCachedSettings() RenderDeferredSunWash = gSavedSettings.getF32("RenderDeferredSunWash"); RenderFSAASamples = gSavedSettings.getU32("RenderFSAASamples"); RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor"); +// [SL:KB] - Patch: Settings-RenderResolutionMultiplier | Checked: Catznip-5.4 + RenderResolutionMultiplier = gSavedSettings.getF32("RenderResolutionMultiplier"); +// [/SL:KB] RenderUIBuffer = gSavedSettings.getBOOL("RenderUIBuffer"); RenderShadowDetail = gSavedSettings.getS32("RenderShadowDetail"); RenderDeferredSSAO = gSavedSettings.getBOOL("RenderDeferredSSAO"); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 81277ee214..7fd0170e17 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -908,6 +908,9 @@ public: static F32 RenderDeferredSunWash; static U32 RenderFSAASamples; static U32 RenderResolutionDivisor; +// [SL:KB] - Patch: Settings-RenderResolutionMultiplier | Checked: Catznip-5.4 + static F32 RenderResolutionMultiplier; +// [/SL:KB] static bool RenderUIBuffer; static S32 RenderShadowDetail; static bool RenderDeferredSSAO; diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp index 95c17a5f6a..16a9c4c380 100644 --- a/indra/newview/rlvactions.cpp +++ b/indra/newview/rlvactions.cpp @@ -20,10 +20,12 @@ #include "llviewercamera.h" #include "llvoavatarself.h" #include "llworld.h" + #include "rlvactions.h" #include "rlvhelper.h" #include "rlvhandler.h" #include "rlvinventory.h" +#include "rlvmodifiers.h" // ============================================================================ // Camera @@ -308,12 +310,12 @@ bool RlvActions::canTeleportToLocal(const LLVector3d& posGlobal) // NOTE: if we're teleporting due to an active command we should disregard any restrictions from the same object const LLUUID& idRlvObjExcept = gRlvHandler.getCurrentObject(); bool fCanStand = RlvActions::canStand(idRlvObjExcept); - if ( (fCanStand) && ((gRlvHandler.hasBehaviourExcept(RLV_BHVR_SITTP, gRlvHandler.getCurrentObject())) || (gRlvHandler.hasBehaviourExcept(RLV_BHVR_TPLOCAL, gRlvHandler.getCurrentObject()))) ) + if ( (fCanStand) && ((gRlvHandler.hasBehaviourExcept(RLV_BHVR_SITTP, idRlvObjExcept)) || (gRlvHandler.hasBehaviourExcept(RLV_BHVR_TPLOCAL, idRlvObjExcept))) ) { // User can stand up but is either @sittp or @tplocal restricted so we need to distance check const F32 nDistSq = (LLVector2(posGlobal.mdV[0], posGlobal.mdV[1]) - LLVector2(gAgent.getPositionGlobal().mdV[0], gAgent.getPositionGlobal().mdV[1])).lengthSquared(); F32 nMaxDist = llmin(RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_TPLOCALDIST)->getValue(), RLV_MODIFIER_TPLOCAL_DEFAULT); - if (gRlvHandler.hasBehaviour(RLV_BHVR_SITTP)) + if (gRlvHandler.hasBehaviourExcept(RLV_BHVR_SITTP, idRlvObjExcept)) nMaxDist = llmin(nMaxDist, RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SITTPDIST)->getValue()); return (nDistSq < nMaxDist * nMaxDist); } diff --git a/indra/newview/rlvcommon.cpp b/indra/newview/rlvcommon.cpp index a50761cf19..13787a01fd 100644 --- a/indra/newview/rlvcommon.cpp +++ b/indra/newview/rlvcommon.cpp @@ -374,6 +374,8 @@ const char* RlvStrings::getStringFromReturnCode(ERlvCmdRet eRet) return "missing #RLV"; case RLV_RET_FAILED_DEPRECATED: return "deprecated and disabled"; + case RLV_RET_FAILED_NOBEHAVIOUR: + return "no active behaviours"; // The following are identified by the chat verb case RLV_RET_RETAINED: case RLV_RET_SUCCESS: @@ -624,28 +626,10 @@ void RlvUtil::sendIMMessage(const LLUUID& idRecipient, const std::string& strMsg std::string strAgentName; LLAgentUI::buildFullname(strAgentName); - std::string::size_type lenMsg = strMsg.length(), lenIt = 0; - - const char* pstrIt = strMsg.c_str(); std::string strTemp; - while (lenIt < lenMsg) + std::list msgList; + utf8str_split(msgList, strMsg, MAX_MSG_STR_LEN, chSplit); + for (const std::string& strMsg : msgList) { - if (lenIt + MAX_MSG_STR_LEN < lenMsg) - { - // Find the last split character - const char* pstrTemp = pstrIt + MAX_MSG_STR_LEN; - while ( (pstrTemp > pstrIt) && (*pstrTemp != chSplit) ) - pstrTemp--; - - if (pstrTemp > pstrIt) - strTemp = strMsg.substr(lenIt, pstrTemp - pstrIt); - else - strTemp = utf8str_substr(strMsg, lenIt, MAX_MSG_STR_LEN); - } - else - { - strTemp = strMsg.substr(lenIt, std::string::npos); - } - pack_instant_message( gMessageSystem, gAgent.getID(), @@ -653,28 +637,11 @@ void RlvUtil::sendIMMessage(const LLUUID& idRecipient, const std::string& strMsg gAgent.getSessionID(), idRecipient, strAgentName.c_str(), - strTemp.c_str(), - ( (!pBuddyInfo) || (pBuddyInfo->isOnline()) ) ? IM_ONLINE : IM_OFFLINE, + strMsg.c_str(), + ((!pBuddyInfo) || (pBuddyInfo->isOnline())) ? IM_ONLINE : IM_OFFLINE, IM_NOTHING_SPECIAL, idSession); gAgent.sendReliableMessage(); - - lenIt += strTemp.length(); - pstrIt = strMsg.c_str() + lenIt; - if (*pstrIt == chSplit) - lenIt++; - } -} - -void RlvUtil::teleportCallback(U64 hRegion, const LLVector3& posRegion, const LLVector3& vecLookAt) -{ - if (hRegion) - { - const LLVector3d posGlobal = from_region_handle(hRegion) + (LLVector3d)posRegion; - if (vecLookAt.isExactlyZero()) - gAgent.teleportViaLocation(posGlobal); - else - gAgent.teleportViaLocationLookAt(posGlobal, vecLookAt); } } diff --git a/indra/newview/rlvcommon.h b/indra/newview/rlvcommon.h index 0374825346..ce87046da3 100644 --- a/indra/newview/rlvcommon.h +++ b/indra/newview/rlvcommon.h @@ -57,7 +57,7 @@ class RlvObject; struct RlvException; typedef boost::variant RlvExceptionOption; -typedef boost::variant RlvBehaviourModifierValue; +typedef boost::variant RlvBehaviourModifierValue; class RlvGCTimer; @@ -186,7 +186,6 @@ public: static bool sendChatReply(S32 nChannel, const std::string& strUTF8Text); static bool sendChatReply(const std::string& strChannel, const std::string& strUTF8Text); static void sendIMMessage(const LLUUID& idTo, const std::string& strMsg, char chSplit); - static void teleportCallback(U64 hRegion, const LLVector3& posRegion, const LLVector3& vecLookAt); protected: static bool m_fForceTp; // @standtp }; diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index b3689104b2..a84fb8b8bb 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -23,8 +23,8 @@ // Version of the specifcation we report const S32 RLV_VERSION_MAJOR = 3; -const S32 RLV_VERSION_MINOR = 1; -const S32 RLV_VERSION_PATCH = 4; +const S32 RLV_VERSION_MINOR = 2; +const S32 RLV_VERSION_PATCH = 1; const S32 RLV_VERSION_BUILD = 0; // Version of the specifcation we report (in compatibility mode) @@ -35,7 +35,7 @@ const S32 RLV_VERSION_BUILD_COMPAT = 0; // Implementation version const S32 RLVa_VERSION_MAJOR = 2; -const S32 RLVa_VERSION_MINOR = 1; +const S32 RLVa_VERSION_MINOR = 2; const S32 RLVa_VERSION_PATCH = 0; // Uncomment before a final release @@ -71,6 +71,7 @@ const S32 RLVa_VERSION_PATCH = 0; #define RLV_ROOT_FOLDER "#RLV" #define RLV_CMD_PREFIX '@' +#define RLV_MODIFIER_ANIMATION_FREQUENCY 10 #define RLV_MODIFIER_TPLOCAL_DEFAULT 256.f // Any teleport that's more than a region away is non-local #define RLV_MODIFIER_FARTOUCH_DEFAULT 1.5f // Specifies the default @fartouch distance #define RLV_MODIFIER_SITTP_DEFAULT 1.5f // Specifies the default @sittp distance @@ -231,6 +232,14 @@ enum ERlvBehaviour { // Camera (force) RLV_BHVR_SETCAM_MODE, // Switch the user's camera into the specified mode (e.g. mouselook or thirdview) + // Overlay + RLV_BHVR_SETOVERLAY, // Gives an object exclusive control of the overlay + RLV_BHVR_SETOVERLAY_ALPHA, // Changes the overlay texture's transparency level + RLV_BHVR_SETOVERLAY_TEXTURE, // Changes the overlay texture + RLV_BHVR_SETOVERLAY_TINT, // Changes the tint that's applied to the overlay texture + RLV_BHVR_SETOVERLAY_TOUCH, // Block world interaction (=touching) based on the alpha channel of the overlay texture + RLV_BHVR_SETOVERLAY_TWEEN, // Animate between the current overlay settings and the supplied values + RLV_BHVR_COUNT, RLV_BHVR_UNKNOWN }; @@ -238,6 +247,10 @@ enum ERlvBehaviour { enum ERlvBehaviourModifier { RLV_MODIFIER_FARTOUCHDIST, // Radius of a sphere around the user in which they can interact with the world + RLV_MODIFIER_OVERLAY_ALPHA, // Transparency level of the overlay texture (in addition to the texture's own alpha channel) + RLV_MODIFIER_OVERLAY_TEXTURE, // Specifies the UUID of the overlay texture + RLV_MODIFIER_OVERLAY_TINT, // The tint that's applied to the overlay texture + RLV_MODIFIER_OVERLAY_TOUCH, // Determines whether the overlay texture's alpha channel will be used to allow/block world interaction RLV_MODIFIER_RECVIMDISTMIN, // Minimum distance to receive an IM from an otherwise restricted sender (squared value) RLV_MODIFIER_RECVIMDISTMAX, // Maximum distance to receive an IM from an otherwise restricted sender (squared value) RLV_MODIFIER_SENDIMDISTMIN, // Minimum distance to send an IM to an otherwise restricted recipient (squared value) @@ -296,6 +309,7 @@ enum ERlvCmdRet { RLV_RET_FAILED_UNKNOWN, // Command failed (unknown command) RLV_RET_FAILED_NOSHAREDROOT, // Command failed (missing #RLV) RLV_RET_FAILED_DEPRECATED, // Command failed (deprecated and no longer supported) + RLV_RET_FAILED_NOBEHAVIOUR, // Command failed (force modifier on an object with no active restrictions) RLV_RET_NO_PROCESSOR // Command doesn't have a template processor define (legacy code) }; #define RLV_RET_SUCCEEDED(eCmdRet) (((eCmdRet) & RLV_RET_SUCCESS) == RLV_RET_SUCCESS) diff --git a/indra/newview/rlvextensions.cpp b/indra/newview/rlvextensions.cpp index 9a3def7735..baa2be38fc 100644 --- a/indra/newview/rlvextensions.cpp +++ b/indra/newview/rlvextensions.cpp @@ -158,7 +158,6 @@ bool RlvWindLightControl::setFloat(F32 nValue) class RlvWindLight : public LLSingleton { LLSINGLETON(RlvWindLight); - public: std::string getValue(const std::string& strSetting, bool& fError); bool setValue(const std::string& strRlvName, const std::string& strValue); diff --git a/indra/newview/rlvfloaters.cpp b/indra/newview/rlvfloaters.cpp index a4086fa21f..ed531eb93b 100644 --- a/indra/newview/rlvfloaters.cpp +++ b/indra/newview/rlvfloaters.cpp @@ -384,6 +384,10 @@ void RlvFloaterBehaviours::refreshAll() sdModifierColumns[1]["value"] = llformat("%f", boost::get(modValue)); else if (typeid(int) == modValue.type()) sdModifierColumns[1]["value"] = llformat("%d", boost::get(modValue)); + else if (typeid(bool) == modValue.type()) + sdModifierColumns[1]["value"] = (boost::get(modValue)) ? "true" : "false"; + else if (typeid(LLUUID) == modValue.type()) + sdModifierColumns[1]["value"] = boost::get(modValue).asString(); } else { @@ -746,6 +750,7 @@ BOOL RlvFloaterConsole::postBuild() void RlvFloaterConsole::onClose(bool fQuitting) { + RlvBehaviourDictionary::instance().clearModifiers(gAgent.getID()); gRlvHandler.processCommand(gAgent.getID(), "clear", true); } diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 4c3a95adf9..b0dfc153fb 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -1,6 +1,6 @@ /** * - * Copyright (c) 2009-2016, Kitty Barnett + * Copyright (c) 2009-2018, Kitty Barnett * * The source code in this file is provided to you under the terms of the * GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY; @@ -43,12 +43,14 @@ #include "llpaneloutfitsinventory.h" // @showinv - "Appearance" floater #include "llpanelpeople.h" // @shownames #include "llpanelwearing.h" // @showinv - "Appearance / Current Outfit" panel +#include "llregionhandle.h" // @tpto #include "llsidepanelappearance.h" // @showinv - "Appearance / Edit appearance" panel #include "lltabcontainer.h" // @showinv - Tab container control for inventory tabs #include "lltoolmgr.h" // @edit #include "llviewercamera.h" // @setcam and related #include "llworldmapmessage.h" // @tpto #include "llviewertexturelist.h" // @setcam_texture +#include "llviewerwindow.h" // @setoverlay // RLVa includes #include "rlvactions.h" @@ -58,6 +60,7 @@ #include "rlvhelper.h" #include "rlvinventory.h" #include "rlvlocks.h" +#include "rlvmodifiers.h" #include "rlvui.h" #include "rlvextensions.h" @@ -144,10 +147,14 @@ RlvHandler::RlvHandler() : m_fCanCancelTp(true), m_posSitSource(), m_pGCTimer(NU memset(m_Behaviours, 0, sizeof(S16) * RLV_BHVR_COUNT); } -// Checked: 2010-04-07 (RLVa-1.2.0d) | Modified: RLVa-1.0.1d RlvHandler::~RlvHandler() { gAgent.removeListener(this); + if (m_PendingGroupChange.first.notNull()) + { + LLGroupMgr::instance().removeObserver(m_PendingGroupChange.first, this); + m_PendingGroupChange = std::make_pair(LLUUID::null, LLStringUtil::null); + } //delete m_pGCTimer; // <- deletes itself } @@ -387,6 +394,7 @@ ERlvCmdRet RlvHandler::processCommand(const RlvCommand& rlvCmd, bool fFromObj) if (0 == itObj->second.m_Commands.size()) { RLV_DEBUGS << "\t- command list empty => removing " << idCurObj << RLV_ENDL; + RlvBehaviourDictionary::instance().clearModifiers(idCurObj); m_Objects.erase(itObj); } } @@ -546,9 +554,21 @@ void RlvHandler::onIMQueryListResponse(const LLSD& sdNotification, const LLSD sd } // ============================================================================ -// Externally invoked event handlers +// Command specific helper functions - @setgroup // +void RlvHandler::changed(const LLUUID& idGroup, LLGroupChange change) +{ + // If we're receiving information about a group we're not interested in, we forgot a removeObserver somewhere + RLV_ASSERT(idGroup == m_PendingGroupChange.first); + + if ( ((GC_ALL == change) || (GC_ROLE_DATA == change)) && (m_PendingGroupChange.first == idGroup) ) + { + LLGroupMgr::instance().removeObserver(m_PendingGroupChange.first, this); + setActiveGroupRole(m_PendingGroupChange.first, m_PendingGroupChange.second); + } +} + bool RlvHandler::handleEvent(LLPointer event, const LLSD& sdUserdata) { // Ansariel: We really only want to handle "new group" events here. Registering for this event @@ -561,48 +581,123 @@ bool RlvHandler::handleEvent(LLPointer event, const LLSD& // NOTE: we'll fire once for every group the user belongs to so we need to manually keep track of pending changes static LLUUID s_idLastAgentGroup = LLUUID::null; - static bool s_fGroupChanging = false; - if (s_idLastAgentGroup != gAgent.getGroupID()) { s_idLastAgentGroup = gAgent.getGroupID(); - s_fGroupChanging = false; + onActiveGroupChanged(); } + return false; +} +void RlvHandler::onActiveGroupChanged() +{ // If the user managed to change their active group (= newly joined or created group) we need to reactivate the previous one - if ( (!RlvActions::canChangeActiveGroup()) /*&& ("new group" == event->desc())*/ && (m_idAgentGroup != gAgent.getGroupID()) ) + if ( (!RlvActions::canChangeActiveGroup()) && (m_idAgentGroup != gAgent.getGroupID()) ) { // Make sure they still belong to the group if ( (m_idAgentGroup.notNull()) && (!gAgent.isInGroup(m_idAgentGroup)) ) { m_idAgentGroup.setNull(); - s_fGroupChanging = false; } - if (!s_fGroupChanging) - { - RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_GROUPCHANGE, - LLSD().with("GROUP_SLURL", (m_idAgentGroup.notNull()) ? LLSLURL("group", m_idAgentGroup, "about").getSLURLString() : LLTrans::getString("GroupNameNone"))); + // Notify them about the change + const LLSD sdArgs = LLSD().with("GROUP_SLURL", (m_idAgentGroup.notNull()) ? llformat("secondlife:///app/group/%s/about", m_idAgentGroup.asString().c_str()) : "(none)"); + RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_GROUPCHANGE, sdArgs); - // [Copy/paste from LLGroupActions::activate()] - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_ActivateGroup); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_GroupID, m_idAgentGroup); - gAgent.sendReliableMessage(); - s_fGroupChanging = true; - return true; - } + setActiveGroup(m_idAgentGroup); } else { m_idAgentGroup = gAgent.getGroupID(); + + // Allowed change - check if we still need to activate a role + if ( (m_PendingGroupChange.first.notNull()) && (m_PendingGroupChange.first == m_idAgentGroup) ) + { + setActiveGroupRole(m_PendingGroupChange.first, m_PendingGroupChange.second); + } } - return false; } +void RlvHandler::setActiveGroup(const LLUUID& idGroup) +{ + // If we have an existing observer fpr a different group, remove it + if ( (m_PendingGroupChange.first.notNull()) && (m_PendingGroupChange.first != idGroup) ) + { + LLGroupMgr::instance().removeObserver(m_PendingGroupChange.first, this); + m_PendingGroupChange = std::make_pair(LLUUID::null, LLStringUtil::null); + } + + if (gAgent.getGroupID() != idGroup) + { + // [Copy/paste from LLGroupActions::activate()] + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_ActivateGroup); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_GroupID, idGroup); + gAgent.sendReliableMessage(); + } + m_idAgentGroup = idGroup; +} + +void RlvHandler::setActiveGroupRole(const LLUUID& idGroup, const std::string& strRole) +{ + // Check if we need a group change first + if (gAgent.getGroupID() != idGroup) + { + setActiveGroup(idGroup); + m_PendingGroupChange = std::make_pair(idGroup, strRole); + return; + } + + // Now that we have the correct group, check if we need to request the role information + /*const*/ auto* pGroupData = LLGroupMgr::instance().getGroupData(idGroup); + if ( ((!pGroupData) && (gAgent.isInGroup(idGroup))) || (!pGroupData->isRoleDataComplete()) ) + { + if (m_PendingGroupChange.first.notNull()) + LLGroupMgr::instance().removeObserver(m_PendingGroupChange.first, this); + m_PendingGroupChange = std::make_pair(idGroup, strRole); + LLGroupMgr::instance().addObserver(idGroup, this); + LLGroupMgr::instance().sendGroupRoleDataRequest(idGroup); + return; + } + + // We have everything - activate the requested role (if we can find it) + if (pGroupData) + { + enum class EMatch { NoMatch, Partial, Exact } eMatch = EMatch::NoMatch; LLUUID idRole; + for (const auto& roleData : pGroupData->mRoles) + { + // NOTE: exact matches take precedence over partial matches; in case of partial matches the last match wins + const std::string& strRoleName = roleData.second->getRoleData().mRoleName; + if (boost::istarts_with(strRoleName, strRole)) + { + idRole = roleData.first; + eMatch = (strRoleName.length() == strRole.length()) ? EMatch::Exact : EMatch::Partial; + if (eMatch == EMatch::Exact) + break; + } + } + + if (eMatch != EMatch::NoMatch) + { + RLV_INFOS << "Activating role '" << strRole << "' for group '" << pGroupData->mName << "'" << RLV_ENDL; + LLGroupMgr::getInstance()->sendGroupTitleUpdate(idGroup, idRole); + } + else + { + RLV_INFOS << "Couldn't find role '" << strRole << "' in group '" << pGroupData->mName << "'" << RLV_ENDL; + } + } + + m_PendingGroupChange = std::make_pair(LLUUID::null, LLStringUtil::null); +} + +// ============================================================================ +// Externally invoked event handlers +// + // Checked: 2010-08-29 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c void RlvHandler::onSitOrStand(bool fSitting) { @@ -806,6 +901,22 @@ void RlvHandler::onLoginComplete() processRetainedCommands(); } +void RlvHandler::onTeleportCallback(U64 hRegion, const LLVector3& posRegion, const LLVector3& vecLookAt, const LLUUID& idRlvObj) +{ + if (hRegion) + { + m_CurObjectStack.push(idRlvObj); + + const LLVector3d posGlobal = from_region_handle(hRegion) + (LLVector3d)posRegion; + if (vecLookAt.isExactlyZero()) + gAgent.teleportViaLocation(posGlobal); + else + gAgent.teleportViaLocationLookAt(posGlobal, vecLookAt); + + m_CurObjectStack.pop(); + } +} + // Checked: 2010-04-05 (RLVa-1.2.0d) | Added: RLVa-1.2.0d void RlvHandler::onTeleportFailed() { @@ -1429,13 +1540,13 @@ ERlvCmdRet RlvBehaviourGenericHandler::onCommand(const RlvC if (RLV_TYPE_ADD == rlvCmd.getParamType()) { gRlvHandler.m_Behaviours[rlvCmd.getBehaviourType()]++; - pBhvrModifier->addValue(modValue, rlvCmd.getObjectID()); + pBhvrModifier->addValue(modValue, rlvCmd.getObjectID(), rlvCmd.getBehaviourType()); gRlvHandler.m_Behaviours[rlvCmd.getBehaviourType()]--; } else { gRlvHandler.m_Behaviours[rlvCmd.getBehaviourType()]--; - pBhvrModifier->removeValue(modValue, rlvCmd.getObjectID()); + pBhvrModifier->removeValue(modValue, rlvCmd.getObjectID(), rlvCmd.getBehaviourType()); gRlvHandler.m_Behaviours[rlvCmd.getBehaviourType()]++; } @@ -1459,13 +1570,13 @@ ERlvCmdRet RlvBehaviourGenericHandler::onCommand(co if (RLV_TYPE_ADD == rlvCmd.getParamType()) { gRlvHandler.m_Behaviours[rlvCmd.getBehaviourType()]++; - pBhvrModifier->addValue(pBhvrModifier->getDefaultValue(), rlvCmd.getObjectID()); + pBhvrModifier->addValue(pBhvrModifier->getDefaultValue(), rlvCmd.getObjectID(), rlvCmd.getBehaviourType()); gRlvHandler.m_Behaviours[rlvCmd.getBehaviourType()]--; } else { gRlvHandler.m_Behaviours[rlvCmd.getBehaviourType()]--; - pBhvrModifier->removeValue(pBhvrModifier->getDefaultValue(), rlvCmd.getObjectID()); + pBhvrModifier->removeValue(pBhvrModifier->getDefaultValue(), rlvCmd.getObjectID(), rlvCmd.getBehaviourType()); gRlvHandler.m_Behaviours[rlvCmd.getBehaviourType()]++; } } @@ -1645,6 +1756,42 @@ void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour eBh RlvUIEnabler::instance().removeGenericFloaterFilter("beacons"); } +// Handles: @setoverlay=n|y toggles +template<> template<> +void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr) +{ + // Once an object has exclusive control over the overlay only its behaviours should be active. This affects: + // - behaviour modifiers => handled for us once we set the primary object + + LLUUID idRlvObject; + if (fHasBhvr) + { + // Get the UUID of the primary object (there should only be one) + std::list lObjects; + gRlvHandler.findBehaviour(RLV_BHVR_SETOVERLAY, lObjects); + RLV_ASSERT(lObjects.size() == 1); + idRlvObject = lObjects.front()->getObjectID(); + } + + RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_ALPHA)->setPrimaryObject(idRlvObject); + RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_TINT)->setPrimaryObject(idRlvObject); + RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_TEXTURE)->setPrimaryObject(idRlvObject); + RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_TOUCH)->setPrimaryObject(idRlvObject); +} + +// Handles: @setoverlay_texture:=n|y changes +template<> +void RlvBehaviourModifierHandler::onValueChange() const +{ + if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_TEXTURE)) + { + if (pBhvrModifier->hasValue()) + gRlvHandler.setOverlayImage(pBhvrModifier->getValue()); + else + gRlvHandler.clearOverlayImage(); + } +} + // Handles: @sendchannel[:]=n|y and @sendchannel_except[:]=n|y template<> template<> ERlvCmdRet RlvBehaviourSendChannelHandler::onCommand(const RlvCommand& rlvCmd, bool& fRefCount) @@ -1704,15 +1851,15 @@ ERlvCmdRet RlvBehaviourRecvSendStartIMHandler::onCommand(const RlvCommand& rlvCm RlvBehaviourModifier *pBhvrModDistMin = RlvBehaviourDictionary::instance().getModifier(eModDistMin), *pBhvrModDistMax = RlvBehaviourDictionary::instance().getModifier(eModDistMax); if (RLV_TYPE_ADD == rlvCmd.getParamType()) { - pBhvrModDistMin->addValue(nDistMin * nDistMin, rlvCmd.getObjectID()); + pBhvrModDistMin->addValue(nDistMin * nDistMin, rlvCmd.getObjectID(), rlvCmd.getBehaviourType()); if (optionList.size() >= 2) - pBhvrModDistMax->addValue(nDistMax * nDistMax, rlvCmd.getObjectID()); + pBhvrModDistMax->addValue(nDistMax * nDistMax, rlvCmd.getObjectID(), rlvCmd.getBehaviourType()); } else { - pBhvrModDistMin->removeValue(nDistMin * nDistMin, rlvCmd.getObjectID()); + pBhvrModDistMin->removeValue(nDistMin * nDistMin, rlvCmd.getObjectID(), rlvCmd.getBehaviourType()); if (optionList.size() >= 2) - pBhvrModDistMax->removeValue(nDistMax * nDistMax, rlvCmd.getObjectID()); + pBhvrModDistMax->removeValue(nDistMax * nDistMax, rlvCmd.getObjectID(), rlvCmd.getBehaviourType()); } fRefCount = true; @@ -2202,6 +2349,24 @@ ERlvCmdRet RlvCommandHandlerBaseImpl::processCommand(const RlvCo return (*pHandler)(rlvCmd); } +// Handles: @bhvr:=force +template<> +ERlvCmdRet RlvForceGenericHandler::onCommand(const RlvCommand& rlvCmd) +{ + // The object should be holding at least one active behaviour + if (!gRlvHandler.hasBehaviour(rlvCmd.getObjectID())) + return RLV_RET_FAILED_NOBEHAVIOUR; + + // There should be an option and it should specify a valid modifier (RlvBehaviourModifier performs the appropriate type checks) + RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifierFromBehaviour(rlvCmd.getBehaviourType()); + RlvBehaviourModifierValue modValue; + if ( (!rlvCmd.hasOption()) || (!pBhvrModifier) || (!pBhvrModifier->convertOptionValue(rlvCmd.getOption(), modValue)) ) + return RLV_RET_FAILED_OPTION; + + pBhvrModifier->setValue(modValue, rlvCmd.getObjectID()); + return RLV_RET_SUCCESS; +} + // Checked: 2010-04-07 (RLVa-1.2.0d) | Modified: RLVa-1.1.0j ERlvCmdRet RlvHandler::processForceCommand(const RlvCommand& rlvCmd) const { @@ -2497,6 +2662,32 @@ ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rl return RLV_RET_SUCCESS; } +// Handles: @setoverlay_tween:[];[];=force +template<> template<> +ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd) +{ + std::vector optionList; + if ( (!RlvCommandOptionHelper::parseStringList(rlvCmd.getOption(), optionList)) || (3 != optionList.size()) ) + return RLV_RET_FAILED_OPTION; + + // Parse the duration first (required param) + float tweenDuration = .0f; + if (!RlvCommandOptionHelper::parseOption(optionList[2], tweenDuration)) + return RLV_RET_FAILED_OPTION; + + // Process the overlay alpha tween (if there is one and it is a valid value) + float overlayAlpha = .0f; + if (RlvCommandOptionHelper::parseOption(optionList[0], overlayAlpha)) + RlvBehaviourModifierAnimator::instance().addTween(rlvCmd.getObjectID(), RLV_MODIFIER_OVERLAY_ALPHA, RlvBehaviourModifierAnimationType::Lerp, overlayAlpha, tweenDuration); + + // Process the overlay tint tween (if there is one and it is a valid value) + LLVector3 overlayColor; + if (RlvCommandOptionHelper::parseOption(optionList[1], overlayColor)) + RlvBehaviourModifierAnimator::instance().addTween(rlvCmd.getObjectID(), RLV_MODIFIER_OVERLAY_TINT, RlvBehaviourModifierAnimationType::Lerp, overlayColor, tweenDuration); + + return RLV_RET_SUCCESS; +} + // Checked: 2010-08-30 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c ERlvCmdRet RlvHandler::onForceWear(const LLViewerInventoryCategory* pFolder, U32 nFlags) const { @@ -2526,20 +2717,24 @@ void RlvHandler::onForceWearCallback(const uuid_vec_t& idItems, U32 nFlags) cons } } -// Handles: @setgroup:=force +// Handles: @setgroup:[;]=force template<> template<> ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd) { if (!RlvActions::canChangeActiveGroup(rlvCmd.getObjectID())) return RLV_RET_FAILED_LOCK; + std::vector optionList; + if ( (!RlvCommandOptionHelper::parseStringList(rlvCmd.getOption(), optionList)) || (optionList.size() < 1) || (optionList.size() > 2) ) + return RLV_RET_FAILED_OPTION; + LLUUID idGroup; bool fValid = false; - if ("none" == rlvCmd.getOption()) + if ("none" == optionList[0]) { idGroup.setNull(); fValid = true; } - else if (idGroup.set(rlvCmd.getOption())) + else if (idGroup.set(optionList[0])) { fValid = (idGroup.isNull()) || (gAgent.isInGroup(idGroup, true)); } @@ -2549,10 +2744,10 @@ ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCm for (const auto& groupData : gAgent.mGroups) { // NOTE: exact matches take precedence over partial matches; in case of partial matches the last match wins - if (boost::istarts_with(groupData.mName, rlvCmd.getOption())) + if (boost::istarts_with(groupData.mName, optionList[0])) { idGroup = groupData.mID; - fExactMatch = groupData.mName.length() == rlvCmd.getOption().length(); + fExactMatch = groupData.mName.length() == optionList[0].length(); if (fExactMatch) break; } @@ -2562,8 +2757,10 @@ ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCm if (fValid) { - gRlvHandler.m_idAgentGroup = idGroup; - LLGroupActions::activate(idGroup); + if (optionList.size() == 1) + gRlvHandler.setActiveGroup(idGroup); + else if (optionList.size() == 2) + gRlvHandler.setActiveGroupRole(idGroup, optionList[1]); } return (fValid) ? RLV_RET_SUCCESS : RLV_RET_FAILED_OPTION; @@ -2653,7 +2850,7 @@ ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd) return RLV_RET_FAILED_OPTION; } - LLWorldMapMessage::url_callback_t cb = boost::bind(&RlvUtil::teleportCallback, _1, posRegion, vecLookAt); + LLWorldMapMessage::url_callback_t cb = boost::bind(&RlvHandler::onTeleportCallback, &gRlvHandler, _1, posRegion, vecLookAt, rlvCmd.getObjectID()); LLWorldMapMessage::getInstance()->sendNamedRegionRequest(posList[0], cb, std::string(""), true); } @@ -2971,12 +3168,12 @@ ERlvCmdRet RlvBehaviourCamZoomMinMaxHandler::onCommand(const RlvCommand& rlvCmd, if (RLV_TYPE_ADD == rlvCmd.getParamType()) { gRlvHandler.m_Behaviours[(RLV_BHVR_CAMZOOMMIN == rlvCmd.getBehaviourType()) ? RLV_BHVR_SETCAM_FOVMIN : RLV_BHVR_SETCAM_FOVMAX]++; - pBhvrModifier->addValue(DEFAULT_FIELD_OF_VIEW / nMult, rlvCmd.getObjectID()); + pBhvrModifier->addValue(DEFAULT_FIELD_OF_VIEW / nMult, rlvCmd.getObjectID(), rlvCmd.getBehaviourType()); } else { gRlvHandler.m_Behaviours[(RLV_BHVR_CAMZOOMMIN == rlvCmd.getBehaviourType()) ? RLV_BHVR_SETCAM_FOVMIN : RLV_BHVR_SETCAM_FOVMAX]--; - pBhvrModifier->removeValue(DEFAULT_FIELD_OF_VIEW / nMult, rlvCmd.getObjectID()); + pBhvrModifier->removeValue(DEFAULT_FIELD_OF_VIEW / nMult, rlvCmd.getObjectID(), rlvCmd.getBehaviourType()); } } @@ -3251,3 +3448,92 @@ ERlvCmdRet RlvHandler::onGetPath(const RlvCommand& rlvCmd, std::string& strReply } // ============================================================================ +// Command specific helper functions - @setoverlay +// + +void RlvHandler::clearOverlayImage() +{ + if (m_pOverlayImage) + { + m_pOverlayImage->setBoostLevel(m_nOverlayOrigBoost); + m_pOverlayImage = nullptr; + } +} + +bool RlvHandler::hitTestOverlay(const LLCoordGL& ptMouse) const +{ + if (!m_pOverlayImage) + return false; + + RlvBehaviourModifier* pTouchModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_TOUCH); + return (pTouchModifier) && (pTouchModifier->hasValue()) && (pTouchModifier->getValue()) && + (m_pOverlayImage->getMask(LLVector2((float)ptMouse.mX / gViewerWindow->getWorldViewWidthScaled(), (float)ptMouse.mY / gViewerWindow->getWorldViewHeightScaled()))); +} + +void RlvHandler::renderOverlay() +{ + if ( (hasBehaviour(RLV_BHVR_SETOVERLAY)) && (m_pOverlayImage) ) + { + if (LLGLSLShader::sNoFixedFunction) + { + gUIProgram.bind(); + } + + int nWidth = gViewerWindow->getWorldViewWidthScaled(); + int nHeight = gViewerWindow->getWorldViewHeightScaled(); + + m_pOverlayImage->addTextureStats(nWidth * nHeight); + m_pOverlayImage->setKnownDrawSize(nWidth, nHeight); + + LLGLSUIDefault glsUI; + gViewerWindow->setup2DRender(); + gGL.pushMatrix(); + + const LLVector2& displayScale = gViewerWindow->getDisplayScale(); + gGL.scalef(displayScale.mV[VX], displayScale.mV[VY], 1.f); + + gGL.getTexUnit(0)->bind(m_pOverlayImage); + const LLVector3 overlayTint = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_TINT)->getValue(); + gGL.color4f(overlayTint.mV[0], overlayTint.mV[1], overlayTint.mV[2], llclamp(RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_OVERLAY_ALPHA)->getValue(), 0.0f, 1.0f)); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2i(nWidth, nHeight); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2i(0, nHeight); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2i(0, 0); + + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2i(nWidth, nHeight); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2i(0, 0); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2i(nWidth, 0); + gGL.end(); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + gGL.popMatrix(); + gGL.flush(); + + if (LLGLSLShader::sNoFixedFunction) + { + gUIProgram.unbind(); + } + } +} + +void RlvHandler::setOverlayImage(const LLUUID& idTexture) +{ + if ( (m_pOverlayImage) && (m_pOverlayImage->getID() == idTexture) ) + return; + + clearOverlayImage(); + m_pOverlayImage = LLViewerTextureManager::getFetchedTexture(idTexture, FTT_DEFAULT, MIPMAP_YES, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + m_nOverlayOrigBoost = m_pOverlayImage->getBoostLevel(); + m_pOverlayImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW); + m_pOverlayImage->forceToSaveRawImage(0); +} + +// ============================================================================ diff --git a/indra/newview/rlvhandler.h b/indra/newview/rlvhandler.h index ef2ca55786..7c48d0c276 100644 --- a/indra/newview/rlvhandler.h +++ b/indra/newview/rlvhandler.h @@ -1,6 +1,6 @@ /** * - * Copyright (c) 2009-2016, Kitty Barnett + * Copyright (c) 2009-2018, Kitty Barnett * * The source code in this file is provided to you under the terms of the * GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY; @@ -17,14 +17,21 @@ #ifndef RLV_HANDLER_H #define RLV_HANDLER_H +#include "llgroupmgr.h" #include #include "rlvcommon.h" #include "rlvhelper.h" + // ============================================================================ + // Forward declarations + // + +class LLViewerFetchedTexture; + // ============================================================================ -class RlvHandler : public LLOldEvents::LLSimpleListener +class RlvHandler : public LLOldEvents::LLSimpleListener, public LLParticularGroupObserver { // Temporary LLSingleton look-alike public: @@ -52,6 +59,8 @@ public: // Returns TRUE is at least one object contains the specified behaviour (and optional option) bool hasBehaviour(ERlvBehaviour eBhvr) const { return (eBhvr < RLV_BHVR_COUNT) ? (0 != m_Behaviours[eBhvr]) : false; } bool hasBehaviour(ERlvBehaviour eBhvr, const std::string& strOption) const; + // Returns TRUE if the specified object has at least one active behaviour + bool hasBehaviour(const LLUUID& idObj) { return m_Objects.end() != m_Objects.find(idObj); } // Returns TRUE if the specified object contains the specified behaviour (and optional option) bool hasBehaviour(const LLUUID& idObj, ERlvBehaviour eBhvr, const std::string& strOption = LLStringUtil::null) const; // Returns TRUE if at least one object (except the specified one) contains the specified behaviour (and optional option) @@ -93,7 +102,7 @@ public: * Helper functions */ public: - // Accessors + // Accessors/Mutators const LLUUID& getAgentGroup() const { return m_idAgentGroup; } // @setgroup bool getCanCancelTp() const { return m_fCanCancelTp; } // @accepttp and @tpto void setCanCancelTp(bool fAllow) { m_fCanCancelTp = fAllow; } // @accepttp and @tpto @@ -102,7 +111,9 @@ public: // Command specific helper functions bool filterChat(std::string& strUTF8Text, bool fFilterEmote) const; // @sendchat, @recvchat and @redirchat + bool hitTestOverlay(const LLCoordGL& ptMouse) const; // @setoverlay bool redirectChatOrEmote(const std::string& strUTF8Test) const; // @redirchat and @rediremote + void renderOverlay(); // @setoverlay // Command processing helper functions ERlvCmdRet processCommand(const LLUUID& idObj, const std::string& strCommand, bool fFromObj); @@ -119,6 +130,12 @@ public: static bool isEnabled() { return m_fEnabled; } static bool setEnabled(bool fEnable); protected: + // Command specific helper functions (NOTE: these generally do not perform safety checks) + void clearOverlayImage(); // @setoverlay=n + void setActiveGroup(const LLUUID& idGroup); // @setgroup=force + void setActiveGroupRole(const LLUUID& idGroup, const std::string& strRole); // @setgroup=force + void setOverlayImage(const LLUUID& idTexture); // @setoverlay=n + void onIMQueryListResponse(const LLSD& sdNotification, const LLSD sdResponse); // -------------------------------- @@ -143,7 +160,7 @@ protected: // Externally invoked event handlers public: - bool handleEvent(LLPointer event, const LLSD& sdUserdata); // Implementation of public LLSimpleListener + void onActiveGroupChanged(); void onAttach(const LLViewerObject* pAttachObj, const LLViewerJointAttachment* pAttachPt); void onDetach(const LLViewerObject* pAttachObj, const LLViewerJointAttachment* pAttachPt); bool onGC(); @@ -152,6 +169,17 @@ public: void onTeleportFailed(); void onTeleportFinished(const LLVector3d& posArrival); static void onIdleStartup(void* pParam); +protected: + void onTeleportCallback(U64 hRegion, const LLVector3& posRegion, const LLVector3& vecLookAt, const LLUUID& idRlvObj); + + /* + * Base class overrides + */ +public: + // LLParticularGroupObserver implementation + void changed(const LLUUID& group_id, LLGroupChange gc) override; + // LLOldEvents::LLSimpleListener implementation + bool handleEvent(LLPointer event, const LLSD& sdUserdata) override; /* * Command processing @@ -205,15 +233,19 @@ protected: static bool m_fEnabled; // Use setEnabled() to toggle this - bool m_fCanCancelTp; // @accepttp=n and @tpto=force - mutable LLVector3d m_posSitSource; // @standtp=n (mutable because onForceXXX handles are all declared as const) - mutable LLUUID m_idAgentGroup; // @setgroup=n + bool m_fCanCancelTp; // @accepttp=n and @tpto=force + mutable LLVector3d m_posSitSource; // @standtp=n (mutable because onForceXXX handles are all declared as const) + mutable LLUUID m_idAgentGroup; // @setgroup=n + std::pair m_PendingGroupChange; // @setgroup=force + LLPointer m_pOverlayImage = nullptr; // @setoverlay=n + int m_nOverlayOrigBoost = 0; // @setoverlay=n friend class RlvSharedRootFetcher; // Fetcher needs access to m_fFetchComplete friend class RlvGCTimer; // Timer clear its own point at destruction - template friend struct RlvBehaviourGenericHandler; + template friend struct RlvBehaviourGenericHandler; template friend struct RlvCommandHandlerBaseImpl; template friend struct RlvCommandHandler; + template friend class RlvBehaviourModifierHandler; // -------------------------------- diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index 60030df9ea..5e430b580a 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -29,6 +29,7 @@ #include "rlvhelper.h" #include "rlvhandler.h" #include "rlvinventory.h" +#include "rlvmodifiers.h" #include @@ -104,7 +105,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericProcessor("editobj", RLV_BHVR_EDITOBJ)); addEntry(new RlvBehaviourGenericProcessor("emote", RLV_BHVR_EMOTE)); addEntry(new RlvBehaviourGenericProcessor("fartouch", RLV_BHVR_FARTOUCH)); - addModifier(RLV_BHVR_FARTOUCH, RLV_MODIFIER_FARTOUCHDIST, new RlvBehaviourModifier("Fartouch Distance", RLV_MODIFIER_FARTOUCH_DEFAULT, true, new RlvBehaviourModifier_CompMin)); + addModifier(RLV_BHVR_FARTOUCH, RLV_MODIFIER_FARTOUCHDIST, new RlvBehaviourModifier("Fartouch Distance", RLV_MODIFIER_FARTOUCH_DEFAULT, true, new RlvBehaviourModifierCompMin)); addEntry(new RlvBehaviourGenericProcessor("fly", RLV_BHVR_FLY)); addEntry(new RlvBehaviourGenericProcessor("interact", RLV_BHVR_INTERACT, RlvBehaviourInfo::BHVR_EXTENDED)); addEntry(new RlvBehaviourInfo("notify", RLV_BHVR_NOTIFY, RLV_TYPE_ADDREM)); @@ -114,8 +115,8 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericProcessor("recvemote", RLV_BHVR_RECVEMOTE, RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourGenericProcessor("recvemotefrom", RLV_BHVR_RECVEMOTEFROM, RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourProcessor("recvim", RlvBehaviourInfo::BHVR_STRICT)); - addModifier(RLV_BHVR_RECVIM, RLV_MODIFIER_RECVIMDISTMIN, new RlvBehaviourModifier("RecvIM Distance (Min)", F32_MAX, true, new RlvBehaviourModifier_CompMax)); - addModifier(RLV_BHVR_RECVIM, RLV_MODIFIER_RECVIMDISTMAX, new RlvBehaviourModifier("RecvIM Distance (Max)", F32_MAX, true, new RlvBehaviourModifier_CompMin)); + addModifier(RLV_BHVR_RECVIM, RLV_MODIFIER_RECVIMDISTMIN, new RlvBehaviourModifier("RecvIM Distance (Min)", F32_MAX, true, new RlvBehaviourModifierCompMax)); + addModifier(RLV_BHVR_RECVIM, RLV_MODIFIER_RECVIMDISTMAX, new RlvBehaviourModifier("RecvIM Distance (Max)", F32_MAX, true, new RlvBehaviourModifierCompMin)); addEntry(new RlvBehaviourGenericProcessor("recvimfrom", RLV_BHVR_RECVIMFROM, RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourInfo("redirchat", RLV_BHVR_REDIRCHAT, RLV_TYPE_ADDREM)); addEntry(new RlvBehaviourInfo("rediremote", RLV_BHVR_REDIREMOTE, RLV_TYPE_ADDREM)); @@ -126,8 +127,8 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourProcessor("sendchannel_except", RlvBehaviourInfo::BHVR_STRICT | RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addEntry(new RlvBehaviourGenericProcessor("sendchat", RLV_BHVR_SENDCHAT)); addEntry(new RlvBehaviourToggleProcessor("sendim", RlvBehaviourInfo::BHVR_STRICT)); - addModifier(RLV_BHVR_SENDIM, RLV_MODIFIER_SENDIMDISTMIN, new RlvBehaviourModifier("SendIM Distance (Min)", F32_MAX, true, new RlvBehaviourModifier_CompMax)); - addModifier(RLV_BHVR_SENDIM, RLV_MODIFIER_SENDIMDISTMAX, new RlvBehaviourModifier("SendIM Distance (Max)", F32_MAX, true, new RlvBehaviourModifier_CompMin)); + addModifier(RLV_BHVR_SENDIM, RLV_MODIFIER_SENDIMDISTMIN, new RlvBehaviourModifier("SendIM Distance (Min)", F32_MAX, true, new RlvBehaviourModifierCompMax)); + addModifier(RLV_BHVR_SENDIM, RLV_MODIFIER_SENDIMDISTMAX, new RlvBehaviourModifier("SendIM Distance (Max)", F32_MAX, true, new RlvBehaviourModifierCompMin)); addEntry(new RlvBehaviourGenericProcessor("sendimto", RLV_BHVR_SENDIMTO, RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourGenericProcessor("sendgesture", RLV_BHVR_SENDGESTURE, RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addEntry(new RlvBehaviourGenericToggleProcessor("setdebug")); @@ -150,11 +151,11 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericProcessor("showworldmap", RLV_BHVR_SHOWWORLDMAP)); addEntry(new RlvBehaviourGenericProcessor("sit", RLV_BHVR_SIT)); addEntry(new RlvBehaviourGenericProcessor("sittp", RLV_BHVR_SITTP)); - addModifier(RLV_BHVR_SITTP, RLV_MODIFIER_SITTPDIST, new RlvBehaviourModifier("SitTp Distance", RLV_MODIFIER_SITTP_DEFAULT, true, new RlvBehaviourModifier_CompMin)); + addModifier(RLV_BHVR_SITTP, RLV_MODIFIER_SITTPDIST, new RlvBehaviourModifier("SitTp Distance", RLV_MODIFIER_SITTP_DEFAULT, true, new RlvBehaviourModifierCompMin)); addEntry(new RlvBehaviourGenericProcessor("standtp", RLV_BHVR_STANDTP)); addEntry(new RlvBehaviourProcessor("startim", RlvBehaviourInfo::BHVR_STRICT)); - addModifier(RLV_BHVR_STARTIM, RLV_MODIFIER_STARTIMDISTMIN, new RlvBehaviourModifier("StartIM Distance (Min)", F32_MAX, true, new RlvBehaviourModifier_CompMax)); - addModifier(RLV_BHVR_STARTIM, RLV_MODIFIER_STARTIMDISTMAX, new RlvBehaviourModifier("StartIM Distance (Max)", F32_MAX, true, new RlvBehaviourModifier_CompMin)); + addModifier(RLV_BHVR_STARTIM, RLV_MODIFIER_STARTIMDISTMIN, new RlvBehaviourModifier("StartIM Distance (Min)", F32_MAX, true, new RlvBehaviourModifierCompMax)); + addModifier(RLV_BHVR_STARTIM, RLV_MODIFIER_STARTIMDISTMAX, new RlvBehaviourModifier("StartIM Distance (Max)", F32_MAX, true, new RlvBehaviourModifierCompMin)); addEntry(new RlvBehaviourGenericProcessor("startimto", RLV_BHVR_STARTIMTO, RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourGenericProcessor("temprun", RLV_BHVR_TEMPRUN)); addEntry(new RlvBehaviourGenericProcessor("touchall", RLV_BHVR_TOUCHALL)); @@ -169,7 +170,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericProcessor("tplm", RLV_BHVR_TPLM)); addEntry(new RlvBehaviourGenericProcessor("tploc", RLV_BHVR_TPLOC)); addEntry(new RlvBehaviourGenericProcessor("tplocal", RLV_BHVR_TPLOCAL, RlvBehaviourInfo::BHVR_EXPERIMENTAL)); - addModifier(RLV_BHVR_TPLOCAL, RLV_MODIFIER_TPLOCALDIST, new RlvBehaviourModifier("Local Teleport Distance", RLV_MODIFIER_TPLOCAL_DEFAULT, true, new RlvBehaviourModifier_CompMin)); + addModifier(RLV_BHVR_TPLOCAL, RLV_MODIFIER_TPLOCALDIST, new RlvBehaviourModifier("Local Teleport Distance", RLV_MODIFIER_TPLOCAL_DEFAULT, true, new RlvBehaviourModifierCompMin)); addEntry(new RlvBehaviourGenericProcessor("tplure", RLV_BHVR_TPLURE, RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourGenericProcessor("tprequest", RLV_BHVR_TPREQUEST, RlvBehaviourInfo::BHVR_STRICT | RlvBehaviourInfo::BHVR_EXTENDED)); addEntry(new RlvBehaviourInfo("unsharedunwear", RLV_BHVR_UNSHAREDUNWEAR, RLV_TYPE_ADDREM)); @@ -178,24 +179,25 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericProcessor("viewnote", RLV_BHVR_VIEWNOTE)); addEntry(new RlvBehaviourGenericProcessor("viewscript", RLV_BHVR_VIEWSCRIPT)); addEntry(new RlvBehaviourGenericProcessor("viewtexture", RLV_BHVR_VIEWTEXTURE)); + // Camera addEntry(new RlvBehaviourGenericToggleProcessor("setcam")); addEntry(new RlvBehaviourGenericProcessor("setcam_avdistmin", RLV_BHVR_SETCAM_AVDISTMIN, RlvBehaviourInfo::BHVR_EXPERIMENTAL)); - addModifier(RLV_BHVR_SETCAM_AVDISTMIN, RLV_MODIFIER_SETCAM_AVDISTMIN, new RlvBehaviourModifierHandler("Camera - Avatar Distance (Min)", 0.0f, false, new RlvBehaviourModifier_CompMax())); + addModifier(RLV_BHVR_SETCAM_AVDISTMIN, RLV_MODIFIER_SETCAM_AVDISTMIN, new RlvBehaviourModifierHandler("Camera - Avatar Distance (Min)", 0.0f, false, new RlvBehaviourModifierCompMax())); addEntry(new RlvBehaviourGenericProcessor("setcam_avdistmax", RLV_BHVR_SETCAM_AVDISTMAX, RlvBehaviourInfo::BHVR_EXPERIMENTAL)); - addModifier(RLV_BHVR_SETCAM_AVDISTMAX, RLV_MODIFIER_SETCAM_AVDISTMAX, new RlvBehaviourModifier("Camera - Avatar Distance (Max)", F32_MAX, false, new RlvBehaviourModifier_CompMin)); + addModifier(RLV_BHVR_SETCAM_AVDISTMAX, RLV_MODIFIER_SETCAM_AVDISTMAX, new RlvBehaviourModifier("Camera - Avatar Distance (Max)", F32_MAX, false, new RlvBehaviourModifierCompMin)); addEntry(new RlvBehaviourGenericProcessor("setcam_origindistmin", RLV_BHVR_SETCAM_ORIGINDISTMIN, RlvBehaviourInfo::BHVR_EXPERIMENTAL)); - addModifier(RLV_BHVR_SETCAM_ORIGINDISTMIN, RLV_MODIFIER_SETCAM_ORIGINDISTMIN, new RlvBehaviourModifier("Camera - Focus Distance (Min)", 0.0f, true, new RlvBehaviourModifier_CompMax)); + addModifier(RLV_BHVR_SETCAM_ORIGINDISTMIN, RLV_MODIFIER_SETCAM_ORIGINDISTMIN, new RlvBehaviourModifier("Camera - Focus Distance (Min)", 0.0f, true, new RlvBehaviourModifierCompMax)); addEntry(new RlvBehaviourGenericProcessor("setcam_origindistmax", RLV_BHVR_SETCAM_ORIGINDISTMAX, RlvBehaviourInfo::BHVR_EXPERIMENTAL)); - addModifier(RLV_BHVR_SETCAM_ORIGINDISTMAX, RLV_MODIFIER_SETCAM_ORIGINDISTMAX, new RlvBehaviourModifier("Camera - Focus Distance (Max)", F32_MAX, true, new RlvBehaviourModifier_CompMin)); + addModifier(RLV_BHVR_SETCAM_ORIGINDISTMAX, RLV_MODIFIER_SETCAM_ORIGINDISTMAX, new RlvBehaviourModifier("Camera - Focus Distance (Max)", F32_MAX, true, new RlvBehaviourModifierCompMin)); addEntry(new RlvBehaviourGenericToggleProcessor("setcam_eyeoffset", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addModifier(RLV_BHVR_SETCAM_EYEOFFSET, RLV_MODIFIER_SETCAM_EYEOFFSET, new RlvBehaviourModifierHandler("Camera - Eye Offset", LLVector3::zero, true, nullptr)); addEntry(new RlvBehaviourGenericToggleProcessor("setcam_focusoffset", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addModifier(RLV_BHVR_SETCAM_FOCUSOFFSET, RLV_MODIFIER_SETCAM_FOCUSOFFSET, new RlvBehaviourModifierHandler("Camera - Focus Offset", LLVector3::zero, true, nullptr)); addEntry(new RlvBehaviourProcessor("setcam_fovmin")); - addModifier(RLV_BHVR_SETCAM_FOVMIN, RLV_MODIFIER_SETCAM_FOVMIN, new RlvBehaviourModifierHandler("Camera - FOV (Min)", DEFAULT_FIELD_OF_VIEW, true, new RlvBehaviourModifier_CompMax)); + addModifier(RLV_BHVR_SETCAM_FOVMIN, RLV_MODIFIER_SETCAM_FOVMIN, new RlvBehaviourModifierHandler("Camera - FOV (Min)", DEFAULT_FIELD_OF_VIEW, true, new RlvBehaviourModifierCompMax)); addEntry(new RlvBehaviourProcessor("setcam_fovmax")); - addModifier(RLV_BHVR_SETCAM_FOVMAX, RLV_MODIFIER_SETCAM_FOVMAX, new RlvBehaviourModifierHandler("Camera - FOV (Max)", DEFAULT_FIELD_OF_VIEW, true, new RlvBehaviourModifier_CompMin)); + addModifier(RLV_BHVR_SETCAM_FOVMAX, RLV_MODIFIER_SETCAM_FOVMAX, new RlvBehaviourModifierHandler("Camera - FOV (Max)", DEFAULT_FIELD_OF_VIEW, true, new RlvBehaviourModifierCompMin)); addEntry(new RlvBehaviourGenericToggleProcessor("setcam_mouselook")); addEntry(new RlvBehaviourGenericProcessor("setcam_textures", RLV_BHVR_SETCAM_TEXTURES)); addModifier(RLV_BHVR_SETCAM_TEXTURES, RLV_MODIFIER_SETCAM_TEXTURE, new RlvBehaviourModifierHandler("Camera - Forced Texture", IMG_DEFAULT, true, nullptr)); @@ -208,6 +210,18 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourProcessor("camzoommax", RlvBehaviourInfo::BHVR_DEPRECATED)); addEntry(new RlvBehaviourGenericToggleProcessor("camunlock", RlvBehaviourInfo::BHVR_SYNONYM | RlvBehaviourInfo::BHVR_DEPRECATED)); + // Overlay + addEntry(new RlvBehaviourGenericToggleProcessor("setoverlay", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); + addModifier(new RlvForceGenericProcessor("setoverlay_alpha", RLV_BHVR_SETOVERLAY_ALPHA, RlvBehaviourInfo::BHVR_EXPERIMENTAL), + RLV_MODIFIER_OVERLAY_ALPHA, new RlvBehaviourModifier("Overlay - Alpha", 1.0f, false, new RlvBehaviourModifierComp())); + addModifier(new RlvForceGenericProcessor("setoverlay_texture", RLV_BHVR_SETOVERLAY_TEXTURE, RlvBehaviourInfo::BHVR_EXPERIMENTAL), + RLV_MODIFIER_OVERLAY_TEXTURE, new RlvBehaviourModifierHandler("Overlay - Texture", LLUUID::null, false, new RlvBehaviourModifierComp())); + addModifier(new RlvForceGenericProcessor("setoverlay_tint", RLV_BHVR_SETOVERLAY_TINT, RlvBehaviourInfo::BHVR_EXPERIMENTAL), + RLV_MODIFIER_OVERLAY_TINT, new RlvBehaviourModifier("Overlay - Tint", LLVector3(1.0f, 1.0f, 1.0f), false, new RlvBehaviourModifierComp())); + addModifier(new RlvBehaviourGenericProcessor("setoverlay_touch", RLV_BHVR_SETOVERLAY_TOUCH, RlvBehaviourInfo::BHVR_EXPERIMENTAL), + RLV_MODIFIER_OVERLAY_TOUCH, new RlvBehaviourModifier("Overlay - Touch", true, true, new RlvBehaviourModifierComp())); + addEntry(new RlvForceProcessor("setoverlay_tween", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); + // // Force-wear // @@ -356,6 +370,23 @@ void RlvBehaviourDictionary::addModifier(ERlvBehaviour eBhvr, ERlvBehaviourModif } } +// Convenience function to add both the behaviour entry as well as the corresponding modifier entry +void RlvBehaviourDictionary::addModifier(const RlvBehaviourInfo* pBhvrEntry, ERlvBehaviourModifier eModifier, RlvBehaviourModifier* pModifierEntry) +{ + addEntry(pBhvrEntry); + addModifier(pBhvrEntry->getBehaviourType(), eModifier, pModifierEntry); +} + +// TODO: this shouldn't be in this class - find a better spot for it +void RlvBehaviourDictionary::clearModifiers(const LLUUID& idRlvObj) +{ + for (int idxModifier = 0; idxModifier < RLV_MODIFIER_COUNT; idxModifier++) + { + if (m_BehaviourModifiers[idxModifier]) + m_BehaviourModifiers[idxModifier]->clearValues(idRlvObj); + } +} + const RlvBehaviourInfo* RlvBehaviourDictionary::getBehaviourInfo(const std::string& strBhvr, ERlvParamType eParamType, bool* pfStrict) const { bool fStrict = boost::algorithm::ends_with(strBhvr, "_sec"); @@ -422,10 +453,10 @@ void RlvBehaviourDictionary::toggleBehaviourFlag(const std::string& strBhvr, ERl // RlvBehaviourModifier // -RlvBehaviourModifier::RlvBehaviourModifier(std::string strName, const RlvBehaviourModifierValue& defaultValue, bool fAddDefaultOnEmpty, RlvBehaviourModifier_Comp* pValueComparator) +RlvBehaviourModifier::RlvBehaviourModifier(std::string strName, const RlvBehaviourModifierValue& defaultValue, bool fAddDefaultOnEmpty, RlvBehaviourModifierComp* pValueComparator) : m_strName(strName), m_DefaultValue(defaultValue), m_fAddDefaultOnEmpty(fAddDefaultOnEmpty), m_pValueComparator(pValueComparator) { - m_pValueComparator = (pValueComparator) ? pValueComparator : new RlvBehaviourModifier_Comp(); + m_pValueComparator = (pValueComparator) ? pValueComparator : new RlvBehaviourModifierComp(); } RlvBehaviourModifier::~RlvBehaviourModifier() @@ -437,11 +468,11 @@ RlvBehaviourModifier::~RlvBehaviourModifier() } } -bool RlvBehaviourModifier::addValue(const RlvBehaviourModifierValue& modValue, const LLUUID& idObject) +bool RlvBehaviourModifier::addValue(const RlvBehaviourModifierValue& modValue, const LLUUID& idRlvObj, ERlvBehaviour eBhvr) { if (modValue.which() == m_DefaultValue.which()) { - m_Values.insert((m_pValueComparator) ? std::lower_bound(m_Values.begin(), m_Values.end(), std::make_pair(modValue, idObject), boost::bind(&RlvBehaviourModifier_Comp::operator(), m_pValueComparator, _1, _2)) : m_Values.end(), std::make_pair(modValue, idObject)); + m_Values.insert((m_pValueComparator) ? std::lower_bound(m_Values.begin(), m_Values.end(), std::make_tuple(modValue, idRlvObj, eBhvr), boost::bind(&RlvBehaviourModifierComp::operator(), m_pValueComparator, _1, _2)) : m_Values.end(), std::make_tuple(modValue, idRlvObj, eBhvr)); // NOTE: change signal needs to trigger before modifier handlers so cached values have a chance to update properly m_ChangeSignal(getValue()); onValueChange(); @@ -450,6 +481,21 @@ bool RlvBehaviourModifier::addValue(const RlvBehaviourModifierValue& modValue, c return false; } +void RlvBehaviourModifier::clearValues(const LLUUID& idRlvObj) +{ + size_t origCount = m_Values.size(); + m_Values.erase(std::remove_if(m_Values.begin(), m_Values.end(), + [&idRlvObj](const RlvBehaviourModifierValueTuple& modValue) { + return (std::get<1>(modValue) == idRlvObj) && (std::get<2>(modValue) == RLV_BHVR_UNKNOWN); + }), m_Values.end()); + RlvBehaviourModifierAnimator::instance().clearTweens(idRlvObj); + if (origCount != m_Values.size()) + { + onValueChange(); + m_ChangeSignal(getValue()); + } +} + const LLUUID& RlvBehaviourModifier::getPrimaryObject() const { return (m_pValueComparator) ? m_pValueComparator->m_idPrimaryObject : LLUUID::null; @@ -459,14 +505,19 @@ bool RlvBehaviourModifier::hasValue() const { // If no primary object is set this returns "any value set"; otherwise it returns "any value set by the primary object" if ( (!m_pValueComparator) || (m_pValueComparator->m_idPrimaryObject.isNull()) ) return !m_Values.empty(); - return (!m_Values.empty()) ? m_Values.front().second == m_pValueComparator->m_idPrimaryObject : false; + return (!m_Values.empty()) ? std::get<1>(m_Values.front()) == m_pValueComparator->m_idPrimaryObject : false; } -void RlvBehaviourModifier::removeValue(const RlvBehaviourModifierValue& modValue, const LLUUID& idObject) +bool RlvBehaviourModifier::hasValue(const LLUUID& idRlvObj) const +{ + return m_Values.end() != std::find_if(m_Values.begin(), m_Values.end(), [&idRlvObj](const RlvBehaviourModifierValueTuple& cmpValue) { return std::get<1>(cmpValue) == idRlvObj; }); +} + +void RlvBehaviourModifier::removeValue(const RlvBehaviourModifierValue& modValue, const LLUUID& idRlvObj, ERlvBehaviour eBhvr) { if ( (modValue.which() == m_DefaultValue.which()) ) { - auto itValue = std::find(m_Values.begin(), m_Values.end(), std::make_pair(modValue, idObject)); + auto itValue = std::find(m_Values.begin(), m_Values.end(), std::make_tuple(modValue, idRlvObj, eBhvr)); if (m_Values.end() != itValue) { m_Values.erase(itValue); @@ -481,12 +532,37 @@ void RlvBehaviourModifier::setPrimaryObject(const LLUUID& idPrimaryObject) if (m_pValueComparator) { m_pValueComparator->m_idPrimaryObject = idPrimaryObject; - m_Values.sort(boost::bind(&RlvBehaviourModifier_Comp::operator(), m_pValueComparator, _1, _2)); + m_Values.sort(boost::bind(&RlvBehaviourModifierComp::operator(), m_pValueComparator, _1, _2)); onValueChange(); m_ChangeSignal(getValue()); } } +void RlvBehaviourModifier::setValue(const RlvBehaviourModifierValue& modValue, const LLUUID& idRlvObj) +{ + if ( (modValue.which() == m_DefaultValue.which()) ) + { + auto itValue = std::find_if(m_Values.begin(), m_Values.end(), + [&idRlvObj](const RlvBehaviourModifierValueTuple& cmpValue) { + return (std::get<1>(cmpValue) == idRlvObj) && (std::get<2>(cmpValue) == RLV_BHVR_UNKNOWN); + }); + if (m_Values.end() != itValue) + { + // The object already has a modifier value set => change it + std::get<0>(*itValue) = modValue; + if (m_pValueComparator) + m_Values.sort(boost::bind(&RlvBehaviourModifierComp::operator(), m_pValueComparator, _1, _2)); + onValueChange(); + m_ChangeSignal(getValue()); + } + else + { + // The command doesn't have a modifier value yet => add it + addValue(modValue, idRlvObj, RLV_BHVR_UNKNOWN); + } + } +} + bool RlvBehaviourModifier::convertOptionValue(const std::string& optionValue, RlvBehaviourModifierValue& modValue) const { try diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h index e03fc7d586..31ac0e4bc3 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -30,6 +30,7 @@ // class RlvBehaviourModifier; +struct RlvBehaviourModifierComp; // ============================================================================ // RlvBehaviourInfo class - Generic behaviour descriptor (used by restrictions, reply and force commands) @@ -95,13 +96,15 @@ class RlvBehaviourDictionary : public LLSingleton LLSINGLETON(RlvBehaviourDictionary); ~RlvBehaviourDictionary(); public: - void addEntry(const RlvBehaviourInfo* pEntry); + void addEntry(const RlvBehaviourInfo* pBhvrEntry); void addModifier(ERlvBehaviour eBhvr, ERlvBehaviourModifier eModifier, RlvBehaviourModifier* pModifierEntry); + void addModifier(const RlvBehaviourInfo* pBhvrEntry, ERlvBehaviourModifier eModifier, RlvBehaviourModifier* pModifierEntry); /* * General helper functions */ public: + void clearModifiers(const LLUUID& idRlvObj); ERlvBehaviour getBehaviourFromString(const std::string& strBhvr, ERlvParamType eParamType, bool* pfStrict = NULL) const; const RlvBehaviourInfo* getBehaviourInfo(const std::string& strBhvr, ERlvParamType eParamType, bool* pfStrict = NULL) const; bool getCommands(const std::string& strMatch, ERlvParamType eParamType, std::list& cmdList) const; @@ -206,6 +209,8 @@ template struct RlvBehaviourGenericHandler { static ERlvCmdRet onCommand(const RlvCommand& rlvCmd, bool& fRefCount); }; template using RlvBehaviourGenericProcessor = RlvBehaviourProcessor>; +template struct RlvForceGenericHandler { static ERlvCmdRet onCommand(const RlvCommand& rlvCmd); }; +template using RlvForceGenericProcessor = RlvForceProcessor>; // ============================================================================ // RlvBehaviourProcessor and related classes - Handles add/rem comamnds aka "restrictions) @@ -224,44 +229,12 @@ template RlvBehaviourModifierValueTuple; - -struct RlvBehaviourModifier_Comp -{ - virtual ~RlvBehaviourModifier_Comp() {} - virtual bool operator()(const RlvBehaviourModifierValueTuple& lhs, const RlvBehaviourModifierValueTuple& rhs) - { - // Values that match the primary object take precedence (otherwise maintain relative ordering) - if ( (rhs.second == m_idPrimaryObject) && (lhs.second != m_idPrimaryObject) ) - return false; - return true; - } - - LLUUID m_idPrimaryObject; -}; -struct RlvBehaviourModifier_CompMin : public RlvBehaviourModifier_Comp -{ - bool operator()(const RlvBehaviourModifierValueTuple& lhs, const RlvBehaviourModifierValueTuple& rhs) override - { - if ( (m_idPrimaryObject.isNull()) || ((lhs.second == m_idPrimaryObject) && (rhs.second == m_idPrimaryObject)) ) - return lhs.first < rhs.first; - return RlvBehaviourModifier_Comp::operator()(lhs, rhs); - } -}; -struct RlvBehaviourModifier_CompMax : public RlvBehaviourModifier_Comp -{ - bool operator()(const RlvBehaviourModifierValueTuple& lhs, const RlvBehaviourModifierValueTuple& rhs) override - { - if ( (m_idPrimaryObject.isNull()) || ((lhs.second == m_idPrimaryObject) && (rhs.second == m_idPrimaryObject)) ) - return rhs.first < lhs.first; - return RlvBehaviourModifier_Comp::operator()(lhs, rhs); - } -}; +typedef std::tuple RlvBehaviourModifierValueTuple; class RlvBehaviourModifier { public: - RlvBehaviourModifier(const std::string strName, const RlvBehaviourModifierValue& defaultValue, bool fAddDefaultOnEmpty, RlvBehaviourModifier_Comp* pValueComparator = nullptr); + RlvBehaviourModifier(const std::string strName, const RlvBehaviourModifierValue& defaultValue, bool fAddDefaultOnEmpty, RlvBehaviourModifierComp* pValueComparator = nullptr); virtual ~RlvBehaviourModifier(); /* @@ -270,16 +243,19 @@ public: protected: virtual void onValueChange() const {} public: - bool addValue(const RlvBehaviourModifierValue& modValue, const LLUUID& idObject); + bool addValue(const RlvBehaviourModifierValue& modValue, const LLUUID& idRlvObj, ERlvBehaviour eBhvr = RLV_BHVR_UNKNOWN); bool convertOptionValue(const std::string& optionValue, RlvBehaviourModifierValue& modValue) const; + void clearValues(const LLUUID& idRlvObj); bool getAddDefault() const { return m_fAddDefaultOnEmpty; } const RlvBehaviourModifierValue& getDefaultValue() const { return m_DefaultValue; } const LLUUID& getPrimaryObject() const; const std::string& getName() const { return m_strName; } - const RlvBehaviourModifierValue& getValue() const { return (hasValue()) ? m_Values.front().first : m_DefaultValue; } + const RlvBehaviourModifierValue& getValue() const { return (hasValue()) ? std::get<0>(m_Values.front()) : m_DefaultValue; } template const T& getValue() const { return boost::get(getValue()); } bool hasValue() const; - void removeValue(const RlvBehaviourModifierValue& modValue, const LLUUID& idObject); + bool hasValue(const LLUUID& idRlvObj) const; + void removeValue(const RlvBehaviourModifierValue& modValue, const LLUUID& idRlvObj, ERlvBehaviour eBhvr = RLV_BHVR_UNKNOWN); + void setValue(const RlvBehaviourModifierValue& modValue, const LLUUID& idRlvObj); void setPrimaryObject(const LLUUID& idPrimaryObject); typedef boost::signals2::signal change_signal_t; @@ -294,80 +270,7 @@ protected: bool m_fAddDefaultOnEmpty; std::list m_Values; change_signal_t m_ChangeSignal; - RlvBehaviourModifier_Comp* m_pValueComparator; -}; - -template -class RlvBehaviourModifierHandler : public RlvBehaviourModifier -{ -public: - //using RlvBehaviourModifier::RlvBehaviourModifier; // Needs VS2015 and up - RlvBehaviourModifierHandler(const std::string& strName, const RlvBehaviourModifierValue& defaultValue, bool fAddDefaultOnEmpty, RlvBehaviourModifier_Comp* pValueComparator) - : RlvBehaviourModifier(strName, defaultValue, fAddDefaultOnEmpty, pValueComparator) {} -protected: - void onValueChange() const override; -}; - -// Inspired by LLControlCache -template -class RlvBehaviourModifierCache : public LLRefCount, public LLInstanceTracker, ERlvBehaviourModifier> -{ -public: - RlvBehaviourModifierCache(ERlvBehaviourModifier eModifier) - : LLInstanceTracker, ERlvBehaviourModifier>(eModifier) - { - RlvBehaviourModifier* pBhvrModifier = (eModifier < RLV_MODIFIER_COUNT) ? RlvBehaviourDictionary::instance().getModifier(eModifier) : nullptr; - if (pBhvrModifier) - { - mConnection = pBhvrModifier->getSignal().connect(boost::bind(&RlvBehaviourModifierCache::handleValueChange, this, _1)); - mCachedValue = pBhvrModifier->getValue(); - } - else - { - mCachedValue = {}; - } - } - ~RlvBehaviourModifierCache() {} - - /* - * Member functions - */ -public: - const T& getValue() const { return mCachedValue; } -protected: - void handleValueChange(const RlvBehaviourModifierValue& newValue) { mCachedValue = boost::get(newValue); } - - /* - * Member variables - */ -protected: - T mCachedValue; - boost::signals2::scoped_connection mConnection; -}; - -// Inspired by LLCachedControl -template -class RlvCachedBehaviourModifier -{ -public: - RlvCachedBehaviourModifier(ERlvBehaviourModifier eModifier) - { - if ((mCachedModifierPtr = RlvBehaviourModifierCache::getInstance(eModifier)) == nullptr) - mCachedModifierPtr = new RlvBehaviourModifierCache(eModifier); - } - - /* - * Operators - */ -public: - operator const T&() const { return mCachedModifierPtr->getValue(); } - const T& operator()() { return mCachedModifierPtr->getValue(); } - - /* - * Member variables - */ -protected: - LLPointer> mCachedModifierPtr; + RlvBehaviourModifierComp* m_pValueComparator; }; // ============================================================================ diff --git a/indra/newview/rlvlocks.h b/indra/newview/rlvlocks.h index a88f11c063..a8cca393f2 100644 --- a/indra/newview/rlvlocks.h +++ b/indra/newview/rlvlocks.h @@ -140,7 +140,8 @@ extern RlvAttachmentLocks gRlvAttachmentLocks; // TODO-RLVa: [RLVa-1.2.1] This class really looks rather cluttered so look into cleaning it up/simplifying it a bit class RlvAttachmentLockWatchdog : public LLSingleton { - LLSINGLETON(RlvAttachmentLockWatchdog); + LLSINGLETON_EMPTY_CTOR(RlvAttachmentLockWatchdog); +protected: ~RlvAttachmentLockWatchdog() { delete m_pTimer; } /* @@ -212,11 +213,9 @@ protected: virtual ~RlvAttachmentLockWatchdogTimer() { m_pWatchdog->m_pTimer = NULL; } virtual BOOL tick() { return m_pWatchdog->onTimer(); } RlvAttachmentLockWatchdog* m_pWatchdog; - } *m_pTimer; + } *m_pTimer = nullptr; }; -inline RlvAttachmentLockWatchdog::RlvAttachmentLockWatchdog() : m_pTimer(NULL) {} - // ============================================================================ // RlvWearableLocks class declaration - modelled on RlvAttachmentLocks (attach pt = wearable type - attachment = wearable) // @@ -283,13 +282,11 @@ extern RlvWearableLocks gRlvWearableLocks; class RlvFolderLocks : public LLSingleton { friend class RlvLockedDescendentsCollector; - LLSINGLETON(RlvFolderLocks); - public: // Specifies the source of a folder lock enum ELockSourceType - { + { ST_ATTACHMENT = 0x01, ST_ATTACHMENTPOINT = 0x02, ST_FOLDER = 0x04, ST_ROOTFOLDER = 0x08, ST_SHAREDPATH = 0x10, ST_WEARABLETYPE = 0x20, ST_NONE= 0x00, ST_MASK_ANY = 0xFF }; diff --git a/indra/newview/rlvmodifiers.cpp b/indra/newview/rlvmodifiers.cpp new file mode 100644 index 0000000000..ce082254f2 --- /dev/null +++ b/indra/newview/rlvmodifiers.cpp @@ -0,0 +1,115 @@ +/** + * + * Copyright (c) 2009-2018, Kitty Barnett + * + * The source code in this file is provided to you under the terms of the + * GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt + * in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt + * + * By copying, modifying or distributing this software, you acknowledge that + * you have read and understood your obligations described above, and agree to + * abide by those obligations. + * + */ + +#include "llviewerprecompiledheaders.h" + +#include "rlvmodifiers.h" + +// ==================================================================================== +// RlvBehaviourModifierAnimator +// + +RlvBehaviourModifierAnimator::~RlvBehaviourModifierAnimator() +{ + if (!m_TimerHandle.isDead()) + m_TimerHandle.markDead(); +} + +void RlvBehaviourModifierAnimator::addTween(const LLUUID& idObject, ERlvBehaviourModifier eBhvrMod, RlvBehaviourModifierAnimationType eAnimType, const RlvBehaviourModifierValue& endValue, float nDuration) +{ + // Make sure we don't run two animations on the same modifier for the same object + const auto itTween = std::find_if(m_Tweens.begin(), m_Tweens.end(), [&idObject, eBhvrMod](const RlvBehaviourModifierTween& t) { return t.idObject == idObject && t.eBhvrMod == eBhvrMod; }); + if (m_Tweens.end() != itTween) + m_Tweens.erase(itTween); + + if (const RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier(eBhvrMod)) + { + RlvBehaviourModifierTween newTween; + newTween.idObject = idObject; + newTween.eBhvrMod = eBhvrMod; + newTween.eAnimType = RlvBehaviourModifierAnimationType::Lerp; + newTween.nStartTime = LLTimer::getElapsedSeconds(); + newTween.nDuration = nDuration; + newTween.startValue = pBhvrModifier->getValue(); + newTween.endValue = endValue; + if (newTween.startValue.which() == newTween.endValue.which()) + { + if (m_TimerHandle.isDead()) + m_TimerHandle = (new AnimationTimer())->getHandle(); + m_Tweens.emplace_back(std::move(newTween)); + } + } +} + +void RlvBehaviourModifierAnimator::clearTweens(const LLUUID& idObject, ERlvBehaviourModifier eBhvrMod) +{ + m_Tweens.erase(std::remove_if(m_Tweens.begin(), m_Tweens.end(), + [&idObject, eBhvrMod](const RlvBehaviourModifierTween& cmpTween) + { + return cmpTween.idObject == idObject && ((cmpTween.eBhvrMod == eBhvrMod) || (RLV_MODIFIER_UNKNOWN == eBhvrMod)); + }), m_Tweens.end()); +} + +// ==================================================================================== +// RlvBehaviourModifierAnimator timer +// + +RlvBehaviourModifierAnimator::AnimationTimer::AnimationTimer() + : LLEventTimer(1.f / RLV_MODIFIER_ANIMATION_FREQUENCY) +{ +} + + +BOOL RlvBehaviourModifierAnimator::AnimationTimer::tick() +{ + RlvBehaviourModifierAnimator& modAnimatior = RlvBehaviourModifierAnimator::instance(); + const double curTime = LLTimer::getElapsedSeconds(); + + const auto activeTweens = modAnimatior.m_Tweens; + for (const auto& curTween : activeTweens) + { + if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier(curTween.eBhvrMod)) + { + // Update the modifier's value + float curFactor = (curTime - curTween.nStartTime) / curTween.nDuration; + if (curFactor < 1.0) + { + const auto& valueType = curTween.startValue.type(); + if (typeid(float) == valueType) + pBhvrModifier->setValue(lerp(boost::get(curTween.startValue), boost::get(curTween.endValue), curFactor), curTween.idObject); + else if (typeid(int) == valueType) + pBhvrModifier->setValue(lerp(boost::get(curTween.startValue), boost::get(curTween.endValue), curFactor), curTween.idObject); + else if (typeid(LLVector3) == valueType) + pBhvrModifier->setValue(lerp(boost::get(curTween.startValue), boost::get(curTween.endValue), curFactor), curTween.idObject); + } + else + { + pBhvrModifier->setValue(curTween.endValue, curTween.idObject); + auto itTween = std::find_if(modAnimatior.m_Tweens.begin(), modAnimatior.m_Tweens.end(), + [&curTween](const RlvBehaviourModifierTween& t) + { + // NOTE: implementation leak - taking advantage of the fact that we know there can only be one active tween per object/modifier/type combination + return t.idObject == curTween.idObject && t.eBhvrMod == curTween.eBhvrMod && t.eAnimType == curTween.eAnimType; + }); + modAnimatior.m_Tweens.erase(itTween); + } + } + } + + return modAnimatior.m_Tweens.empty(); +} + + // ==================================================================================== diff --git a/indra/newview/rlvmodifiers.h b/indra/newview/rlvmodifiers.h new file mode 100644 index 0000000000..832e01de1e --- /dev/null +++ b/indra/newview/rlvmodifiers.h @@ -0,0 +1,192 @@ +/** + * + * Copyright (c) 2009-2018, Kitty Barnett + * + * The source code in this file is provided to you under the terms of the + * GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt + * in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt + * + * By copying, modifying or distributing this software, you acknowledge that + * you have read and understood your obligations described above, and agree to + * abide by those obligations. + * + */ + +#pragma once + +#include "llhandle.h" +#include "llsingleton.h" +#include "rlvhelper.h" + +// ==================================================================================== +// RlvBehaviourModifierHandler - Behaviour modifiers change handler class (use this if changes require code to be processed) +// + +template +class RlvBehaviourModifierHandler : public RlvBehaviourModifier +{ +public: + //using RlvBehaviourModifier::RlvBehaviourModifier; // Needs VS2015 and up + RlvBehaviourModifierHandler(const std::string& strName, const RlvBehaviourModifierValue& defaultValue, bool fAddDefaultOnEmpty, RlvBehaviourModifierComp* pValueComparator) + : RlvBehaviourModifier(strName, defaultValue, fAddDefaultOnEmpty, pValueComparator) {} +protected: + void onValueChange() const override; +}; + +// ==================================================================================== +// RlvBehaviourModifierComp - Behaviour modifiers comparers (used for sorting) +// + +struct RlvBehaviourModifierComp +{ + virtual ~RlvBehaviourModifierComp() {} + virtual bool operator()(const RlvBehaviourModifierValueTuple& lhs, const RlvBehaviourModifierValueTuple& rhs) + { + // Values that match the primary object take precedence (otherwise maintain relative ordering) + if ( (std::get<1>(rhs) == m_idPrimaryObject) && (std::get<1>(lhs) != m_idPrimaryObject) ) + return false; + return true; + } + + LLUUID m_idPrimaryObject; +}; + +struct RlvBehaviourModifierCompMin : public RlvBehaviourModifierComp +{ + bool operator()(const RlvBehaviourModifierValueTuple& lhs, const RlvBehaviourModifierValueTuple& rhs) override + { + if ( (m_idPrimaryObject.isNull()) || ((std::get<1>(lhs) == m_idPrimaryObject) && (std::get<1>(rhs) == m_idPrimaryObject)) ) + return std::get<0>(lhs) < std::get<0>(rhs); + return RlvBehaviourModifierComp::operator()(lhs, rhs); + } +}; + +struct RlvBehaviourModifierCompMax : public RlvBehaviourModifierComp +{ + bool operator()(const RlvBehaviourModifierValueTuple& lhs, const RlvBehaviourModifierValueTuple& rhs) override + { + if ( (m_idPrimaryObject.isNull()) || ((std::get<1>(lhs) == m_idPrimaryObject) && (std::get<1>(rhs) == m_idPrimaryObject)) ) + return std::get<0>(rhs) < std::get<0>(lhs); + return RlvBehaviourModifierComp::operator()(lhs, rhs); + } +}; + +// ==================================================================================== +// RlvBehaviourModifierAnimator - A class to animate behaviour modifiers +// + +enum class RlvBehaviourModifierAnimationType { Lerp }; + +struct RlvBehaviourModifierTween +{ + LLUUID idObject; + ERlvBehaviourModifier eBhvrMod; + RlvBehaviourModifierAnimationType eAnimType; + double nStartTime; + float nDuration; + RlvBehaviourModifierValue startValue; + RlvBehaviourModifierValue endValue; +}; + +class RlvBehaviourModifierAnimator : public LLSingleton +{ + LLSINGLETON_EMPTY_CTOR(RlvBehaviourModifierAnimator); +public: + ~RlvBehaviourModifierAnimator(); + + /* + * Member functions + */ +public: + void addTween(const LLUUID& idObject, ERlvBehaviourModifier eBhvrMod, RlvBehaviourModifierAnimationType eAnimType, const RlvBehaviourModifierValue& endValue, float nDuration); + void clearTweens(const LLUUID& idObject) { clearTweens(idObject, RLV_MODIFIER_UNKNOWN); } + void clearTweens(const LLUUID& idObject, ERlvBehaviourModifier eBhvrMod); + + /* + * Animation timer + */ +protected: + class AnimationTimer : public LLEventTimer, public LLHandleProvider + { + public: + AnimationTimer(); + BOOL tick() override; + }; + + /* + * Member variables + */ +protected: + LLHandle m_TimerHandle; + std::list< RlvBehaviourModifierTween> m_Tweens; +}; + +// ==================================================================================== +// RlvCachedBehaviourModifier - Provides an optimized way to access a modifier that's frequently accessed and rarely updated +// + +// Inspired by LLControlCache +template +class RlvBehaviourModifierCache : public LLRefCount, public LLInstanceTracker, ERlvBehaviourModifier> +{ +public: + RlvBehaviourModifierCache(ERlvBehaviourModifier eModifier) + : LLInstanceTracker, ERlvBehaviourModifier>(eModifier) + { + if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier(eModifier)) + { + mConnection = pBhvrModifier->getSignal().connect(boost::bind(&RlvBehaviourModifierCache::handleValueChange, this, _1)); + mCachedValue = pBhvrModifier->getValue(); + } + else + { + mCachedValue = {}; + RLV_ASSERT(false); + } + } + ~RlvBehaviourModifierCache() {} + + /* + * Member functions + */ +public: + const T& getValue() const { return mCachedValue; } +protected: + void handleValueChange(const RlvBehaviourModifierValue& newValue) { mCachedValue = boost::get(newValue); } + + /* + * Member variables + */ +protected: + T mCachedValue; + boost::signals2::scoped_connection mConnection; +}; + +// Inspired by LLCachedControl +template +class RlvCachedBehaviourModifier +{ +public: + RlvCachedBehaviourModifier(ERlvBehaviourModifier eModifier) + { + if ((mCachedModifierPtr = RlvBehaviourModifierCache::getInstance(eModifier)) == nullptr) + mCachedModifierPtr = new RlvBehaviourModifierCache(eModifier); + } + + /* + * Operators + */ +public: + operator const T&() const { return mCachedModifierPtr->getValue(); } + const T& operator()() { return mCachedModifierPtr->getValue(); } + + /* + * Member variables + */ +protected: + LLPointer> mCachedModifierPtr; +}; + +// ==================================================================================== diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index 0767ad943c..3424261886 100644 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -6102,6 +6102,9 @@ Setzen Sie den Editorpfad in Anführungszeichen deaktiviert + + (deaktiviert) + Erlebnis diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 47ccef11da..762eedc82c 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2791,6 +2791,7 @@ Try enclosing path to the editor with double quotes. RLVa will be [STATE] after you restart enabled disabled + (disabled) Experience diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index 56961a5a0f..9e8c1c21aa 100644 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -5869,6 +5869,9 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas Cargando... + + (deshabilitado) + Experiencia diff --git a/indra/newview/skins/default/xui/pl/floater_buy_land.xml b/indra/newview/skins/default/xui/pl/floater_buy_land.xml index 0d57d1f851..15b3c1d236 100644 --- a/indra/newview/skins/default/xui/pl/floater_buy_land.xml +++ b/indra/newview/skins/default/xui/pl/floater_buy_land.xml @@ -210,7 +210,7 @@ Działka ta zawiera 512 m² ziemi. Masz 2,100 L$. -