diff --git a/.hgtags b/.hgtags index 98ba625367..37f7f52848 100755 --- a/.hgtags +++ b/.hgtags @@ -31,6 +31,7 @@ fdf1fd7884cf642ad3d41c3f5bc2521e4a7ab3aa Firestorm_4.6.9_Release 76c9998c37a52d58792e7a22cc5055e831c95023 Firestorm_4.7.3_Release a27ad24ed75000d96d056aa20495637386e4a53e Firestorm_4.7.5_Release 31f9b0f8e9365a87975af3aa73e3f782db17f994 Firestorm_4.7.7_Release +6ef63161a501b12536b1a94b74d0084a4b014572 Firestorm_4.7.9_Release bb38ff1a763738609e1b3cada6d15fa61e5e84b9 2.1.1-release 003dd9461bfa479049afcc34545ab3431b147c7c v2start 52d96ad3d39be29147c5b2181b3bb46af6164f0e alpha-3 diff --git a/README_BUILD_FIRESTORM_LINUX.txt b/README_BUILD_FIRESTORM_LINUX.txt index 18e7aef3ee..382cc5a27f 100755 --- a/README_BUILD_FIRESTORM_LINUX.txt +++ b/README_BUILD_FIRESTORM_LINUX.txt @@ -1,4 +1,4 @@ -First, make sure gcc-4.6 and g++-4.6 are installed. +First, make sure gcc-4.7 and g++-4.7 are installed. 32bit build platforms are better tested at this point and strongly recommended. @@ -44,3 +44,4 @@ Logs: Output: Look for output in build-linux-i686/newview/Release + diff --git a/README_BUILD_FIRESTORM_WIN64.txt b/README_BUILD_FIRESTORM_WIN64.txt index aa0fb9587e..aa44b24907 100755 --- a/README_BUILD_FIRESTORM_WIN64.txt +++ b/README_BUILD_FIRESTORM_WIN64.txt @@ -5,7 +5,7 @@ This is WIP. Please change/expand when seeing fit. 2. autobuild from https://bitbucket.org/NickyD/autobuild-1.0 3. FMOD, if you want sound, please see https://bitbucket.org/NickyD/3p-fmodex -You will find the urls to all 64 bit prebuild packages in /package_override.ini +You will find the urls to all 64 bit prebuild packages in /package_override_vc12.ini Make sure you're not building from a Visual Studio command prompt, or parts of the build chain might accidentally pick up a 32 bit compiler, resulting in x86<>x64 mismatch. diff --git a/autobuild.xml b/autobuild.xml index 6170fb62e6..f5d46ce929 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -27,9 +27,9 @@ archive hash - e54568cfa7bced82cb6eae26471b7fa5 + 68bf8ef0e36e52a995fbe5a4889d5065 url - http://downloads.phoenixviewer.com/slplugin_x86-4.7.8.50261-darwin-201606211711-r3.tar.bz2 + http://downloads.phoenixviewer.com/slplugin_x86-4.7.8.50451-darwin-201607130911-r5.tar.bz2 name windows @@ -1146,6 +1146,46 @@ version 0.10.6.294903 + gstreamer10 + + copyright + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + license + LGPL + license_file + LICENSES/gstreamer.txt + name + gstreamer10 + platforms + + linux + + archive + + hash + 01f39ecf80dae64e30402ac384035b3e + url + http://downloads.phoenixviewer.com/gstreamer10-1.6.3.201605191852-linux-201605191852.tar.bz2 + + name + linux + + windows + + archive + + hash + 437b1dfd7e20cd0b688e2c1393cdbfc3 + url + http://downloads.phoenixviewer.com/gstreamer10-1.6.3.201605192127-r9-windows-201605192127-r9.tar.bz2 + + name + windows + + + version + 0.10.6.294903 + gtk-atk-pango-glib copyright @@ -1163,9 +1203,9 @@ archive hash - 15af375116f5c943ea6f4190bc764224 + 8cd64b4c5d7f02c5ad87051861108749 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/gtk_3p-gtk-atk-pango-glib/rev/294804/arch/Linux/installer/gtk_atk_pango_glib-0.1-linux-294804.tar.bz2 + http://downloads.phoenixviewer.com/gtk_atk_pango_glib-2.0-linux-201608031222.tar.bz2 name linux @@ -1687,11 +1727,11 @@ archive hash - 7d12fe9dff388d237615f7158315d1cb + d382fe4c4d80c4ee778166bf97e82e19 hash_algorithm md5 url - http://downloads.phoenixviewer.com/llceflib-1.0-windows-201602081454-r54.tar.bz2 + http://downloads.phoenixviewer.com/llceflib-1.0-windows-201608011747-r69.tar.bz2 name windows @@ -1701,18 +1741,18 @@ archive hash - 57bbb4defb7986aa241b10558c6abfea + 98c702cb445a3afda0d1ee0eb23069c3 hash_algorithm md5 url - http://downloads.phoenixviewer.com/llceflib-1.0-linux-201603010220-r58.tar.bz2 + http://downloads.phoenixviewer.com/llceflib-1.0-linux-201608022058-r69.tar.bz2 name linux version - 1.5.3.311349 + 1.5.3.317959 llphysicsextensions_source @@ -2231,9 +2271,9 @@ archive hash - 06c3a9b1005249f0c94a8b9f3775f3d3 + 6e7b0961d6489a1b3c3090eccfd6e80e url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/vivox_3p-slvoice/rev/302004/arch/Linux/installer/slvoice-3.2.0002.10426.302004-linux-302004.tar.bz2 + http://downloads.phoenixviewer.com/slvoice-3.2.0002.10426.298329-linux-20160717.tar.bz2 name linux diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 4f0fd0df23..8a386ce866 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -194,7 +194,7 @@ if (LINUX) OUTPUT_STRIP_TRAILING_WHITESPACE) # Gentoo defines _FORTIFY_SOURCE by default - if (NOT ( ${GXX_VERSION} MATCHES "Gentoo 4.[789].*" OR ${GXX_VERSION} MATCHES "Gentoo 5.3.*" ) ) + if (NOT ND_SYSTEM_DEFINES_FORTIFY_SOURCE) # if (${GXX_VERSION} STREQUAL ${CXX_VERSION}) @@ -206,7 +206,7 @@ if (LINUX) endif (${GXX_VERSION} STREQUAL ${CXX_VERSION}) # Gentoo defines _FORTIFY_SOURCE by default - endif (NOT ( ${GXX_VERSION} MATCHES "Gentoo 4.[789].*" OR ${GXX_VERSION} MATCHES "Gentoo 5.3.*" ) ) + endif (NOT ND_SYSTEM_DEFINES_FORTIFY_SOURCE) # # Let's actually get a numerical version of gxx's version diff --git a/indra/cmake/GStreamer10Plugin.cmake b/indra/cmake/GStreamer10Plugin.cmake new file mode 100644 index 0000000000..4f9d255436 --- /dev/null +++ b/indra/cmake/GStreamer10Plugin.cmake @@ -0,0 +1,31 @@ +# -*- cmake -*- +include(Prebuilt) + +if (USESYSTEMLIBS) + include(FindPkgConfig) + + pkg_check_modules(GSTREAMER10 REQUIRED gstreamer-1.0) + pkg_check_modules(GSTREAMER10_PLUGINS_BASE REQUIRED gstreamer-plugins-base-1.0) +elseif (LINUX OR WINDOWS) + use_prebuilt_binary(gstreamer10) + use_prebuilt_binary(libxml2) + set(GSTREAMER10_FOUND ON FORCE BOOL) + set(GSTREAMER10_PLUGINS_BASE_FOUND ON FORCE BOOL) + set(GSTREAMER10_INCLUDE_DIRS + ${LIBS_PREBUILT_DIR}/include/gstreamer-1.0 + ${LIBS_PREBUILT_DIR}/include/glib-2.0 + ${LIBS_PREBUILT_DIR}/include/libxml2 + ) + # We don't need to explicitly link against gstreamer itself, because + # LLMediaImplGStreamer probes for the system's copy at runtime. + set(GSTREAMER10_LIBRARIES) +endif (USESYSTEMLIBS) + +if (GSTREAMER10_FOUND AND GSTREAMER10_PLUGINS_BASE_FOUND) + set(GSTREAMER10 ON CACHE BOOL "Build with GStreamer-1.0 streaming media support.") +endif (GSTREAMER10_FOUND AND GSTREAMER10_PLUGINS_BASE_FOUND) + +if (GSTREAMER10) + add_definitions(-DLL_GSTREAMER10_ENABLED=1) +endif (GSTREAMER10) + diff --git a/indra/cmake/UI.cmake b/indra/cmake/UI.cmake index 1bd0501ed4..efb6d6a25a 100644 --- a/indra/cmake/UI.cmake +++ b/indra/cmake/UI.cmake @@ -50,17 +50,12 @@ else (USESYSTEMLIBS) pango-1.0 pangoft2-1.0 pangox-1.0 - pangoxft-1.0 + #pangoxft-1.0 + gio-2.0 + pangocairo-1.0 + ffi ) - if (ND_BUILD64BIT_ARCH) - set(UI_LIB_NAMES ${UI_LIB_NAMES} - gio-2.0 - pangocairo-1.0 - ffi - ) - endif(ND_BUILD64BIT_ARCH) - foreach(libname ${UI_LIB_NAMES}) find_library(UI_LIB_${libname} NAMES ${libname} diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index fcd584cab4..68f126520c 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -39,11 +39,11 @@ set(INCREMENTAL_LINK OFF CACHE BOOL "Use incremental linking on win32 builds (en # When building for Linux x64 we enable building the media plugins, in all other cases we use the prebuild 32 bit packages # set(ENABLE_MEDIA_PLUGINS ON CACHE BOOL "Turn off building media plugins if they are imported by third-party library mechanism") -if (ND_BUILD64BIT_ARCH AND (${CMAKE_SYSTEM_NAME} MATCHES "Windows" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") ) +if (ND_BUILD64BIT_ARCH AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" ) set( ENABLE_MEDIA_PLUGINS OFF CACHE FORCE "Build with media plugins" ) -else (ND_BUILD64BIT_ARCH AND (${CMAKE_SYSTEM_NAME} MATCHES "Windows" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") ) +else (ND_BUILD64BIT_ARCH AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" ) set(ENABLE_MEDIA_PLUGINS ON CACHE BOOL "Turn off building media plugins if they are imported by third-party library mechanism") -endif (ND_BUILD64BIT_ARCH AND (${CMAKE_SYSTEM_NAME} MATCHES "Windows" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") ) +endif (ND_BUILD64BIT_ARCH AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" ) # if(LIBS_CLOSED_DIR) diff --git a/indra/cmake/ViewerMiscLibs.cmake b/indra/cmake/ViewerMiscLibs.cmake index 14edc262fe..6841109a4d 100644 --- a/indra/cmake/ViewerMiscLibs.cmake +++ b/indra/cmake/ViewerMiscLibs.cmake @@ -12,7 +12,6 @@ if (NOT USESYSTEMLIBS) if( ND_BUILD64BIT_ARCH ) if( WINDOWS ) -# use_prebuilt_binary( slplugin_x86 ) use_prebuilt_binary( wix ) elseif( DARWIN ) use_prebuilt_binary( slplugin_x86 ) diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp index 5daedde837..44f56daf2d 100644 --- a/indra/llcommon/llprocess.cpp +++ b/indra/llcommon/llprocess.cpp @@ -507,40 +507,6 @@ LLProcessPtr LLProcess::create(const LLSDOrParams& params) } } -// Annoying preload hack to make tcmalloc in libcef.so play nicely. -std::string installPreloadHack( std::string const &preload ) -{ - std::string strOldPreload; -#ifdef LL_LINUX - if( preload.size() ) - { - std::string strPreload = preload; - if( getenv( "LD_PRELOAD" ) ) - { - strOldPreload = getenv( "LD_PRELOAD" ); - strPreload = ":" + strOldPreload; - } - - setenv( "LD_PRELOAD", strPreload.c_str(), 1 ); - } -#endif - return strOldPreload; -} - -void uninstallPreloadHack( std::string const &preload, std::string const &strOldPreload ) -{ -#ifdef LL_LINUX - if( preload.empty() ) - return; - - if( strOldPreload.size() ) - setenv( "LD_PRELOAD", strOldPreload.c_str(), 1 ); - else - unsetenv( "LD_PRELOAD" ); -#endif -} -// - /// Call an apr function returning apr_status_t. On failure, log warning and /// throw LLProcessError mentioning the function call that produced that /// result. @@ -706,20 +672,15 @@ LLProcess::LLProcess(const LLSDOrParams& params): // terminate with a null pointer argv.push_back(NULL); - std::string strOldPreload = installPreloadHack( params.preload ); // FS:ND/> Install preload hack (if needed) - // Launch! The NULL would be the environment block, if we were passing // one. Hand-expand chkapr() macro so we can fill in the actual command // string instead of the variable names. if (ll_apr_warn_status(apr_proc_create(&mProcess, argv[0], &argv[0], NULL, procattr, gAPRPoolp))) { - uninstallPreloadHack( params.preload, strOldPreload ); // Remove preload hack throw LLProcessError(STRINGIZE(params << " failed")); } - uninstallPreloadHack( params.preload, strOldPreload ); // Remove preload hack - // arrange to call status_callback() apr_proc_other_child_register(&mProcess, &LLProcess::status_callback, this, mProcess.in, gAPRPoolp); diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index d4d44d2d7f..6f88af82d8 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -32,6 +32,7 @@ include_directories( ) set(llmessage_SOURCE_FILES + fscorehttputil.cpp llassetstorage.cpp llavatarname.cpp llavatarnamecache.cpp @@ -111,6 +112,7 @@ set(llmessage_SOURCE_FILES set(llmessage_HEADER_FILES CMakeLists.txt + fscorehttputil.h llassetstorage.h llavatarname.h llavatarnamecache.h diff --git a/indra/llmessage/fscorehttputil.cpp b/indra/llmessage/fscorehttputil.cpp index 6cdf829632..886905f243 100644 --- a/indra/llmessage/fscorehttputil.cpp +++ b/indra/llmessage/fscorehttputil.cpp @@ -1,3 +1,32 @@ +/** + * @file fscorehttputil.h + * @brief Core HTTP utility classes. + * + * $LicenseInfo:firstyear=2015&license=viewerlgpl$ + * Phoenix Firestorm Viewer Source Code + * Copyright (c) 2015 Nicky Dasmijn + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA + * http://www.firestormviewer.org + * $/LicenseInfo$ + */ + +#include "fscorehttputil.h" + namespace FSCoreHttpUtil { void trivialPostCoroRaw(std::string url, LLCore::HttpRequest::policy_t policyId, LLCore::BufferArray::ptr_t postData, LLCore::HttpHeaders::ptr_t aHeader, completionCallback_t success, completionCallback_t failure) diff --git a/indra/llmessage/fscorehttputil.h b/indra/llmessage/fscorehttputil.h index 3bb2e9e5c4..083f07c2e6 100644 --- a/indra/llmessage/fscorehttputil.h +++ b/indra/llmessage/fscorehttputil.h @@ -1,3 +1,34 @@ +/** + * @file fscorehttputil.h + * @brief Core HTTP utility classes. + * + * $LicenseInfo:firstyear=2015&license=viewerlgpl$ + * Phoenix Firestorm Viewer Source Code + * Copyright (c) 2015 Nicky Dasmijn + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA + * http://www.firestormviewer.org + * $/LicenseInfo$ + */ + +#ifndef FS_COREHTTPUTIL_H +#define FS_COREHTTPUTIL_H + +#include "llcorehttputil.h" namespace FSCoreHttpUtil { @@ -13,3 +44,4 @@ namespace FSCoreHttpUtil completionCallback_t success, completionCallback_t failure); } +#endif // FS_COREHTTPUTIL_H diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp index 6e527cc62a..e6dfa4073b 100644 --- a/indra/llmessage/llcorehttputil.cpp +++ b/indra/llmessage/llcorehttputil.cpp @@ -1345,5 +1345,3 @@ void HttpCoroutineAdapter::trivialPostCoro(std::string url, LLCore::HttpRequest: } // end namespace LLCoreHttpUtil - -#include "fscorehttputil.cpp" diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h index 778d77884a..6f0b865f83 100644 --- a/indra/llmessage/llcorehttputil.h +++ b/indra/llmessage/llcorehttputil.h @@ -684,6 +684,4 @@ private: } // end namespace LLCoreHttpUtil -#include "fscorehttputil.h" - #endif // LL_LLCOREHTTPUTIL_H diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index f55b5c70f0..3a3585dc58 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -4017,7 +4017,10 @@ void LLMessageSystem::sendUntrustedSimulatorMessageCoro(std::string url, std::st { LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("groupMembersRequest", httpPolicy)); + // Fix adapter naming + //httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("groupMembersRequest", httpPolicy)); + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("untrustedSimulatorMessage", httpPolicy)); + // LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions); diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt index ef79252d2b..c24a83eff0 100644 --- a/indra/llplugin/CMakeLists.txt +++ b/indra/llplugin/CMakeLists.txt @@ -70,11 +70,7 @@ list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES}) add_library (llplugin ${llplugin_SOURCE_FILES}) -if( ND_BUILD64BIT_ARCH AND WINDOWS ) - use_prebuilt_binary( slplugin_x86 ) -else() - add_subdirectory(slplugin) -endif( ND_BUILD64BIT_ARCH AND WINDOWS ) +add_subdirectory(slplugin) # Add tests if (LL_TESTS) diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 4bab1b1c54..609c3b4231 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -1488,10 +1488,3 @@ void LLPluginClassMedia::initializeUrlHistory(const LLSD& url_history) LL_DEBUGS("Plugin") << "Sending history" << LL_ENDL; } - -void LLPluginClassMedia::setFlipY( bool enabled ) -{ - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "cef_flipy"); - message.setValueBoolean("enable", enabled); - sendMessage(message); -} diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index a24ea7d4e8..56b5c1a7fd 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -1124,7 +1124,10 @@ bool LLDAELoader::OpenFile(const std::string& filename) std::string LLDAELoader::preprocessDAE(std::string filename) { // Open a DAE file for some preprocessing (like removing space characters in IDs), see MAINT-5678 - std::ifstream inFile; + // FIRE-19806: Mesh upload from a folder with Unicode characters in the name fails + //std::ifstream inFile; + llifstream inFile; + // inFile.open(filename.c_str(), std::ios_base::in); std::stringstream strStream; strStream << inFile.rdbuf(); diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index e6c9880953..a960363e35 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -690,17 +690,26 @@ bool LLGLManager::initGL() glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo); mVRAM = meminfo[0]/1024; + + // VRAM detection logging + LL_INFOS("RenderInit") << "VRAM detected via ATI MemInfo OpenGL extension: " << mVRAM << " MB" << LL_ENDL; } else if (mHasNVXMemInfo) { S32 dedicated_memory; glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &dedicated_memory); mVRAM = dedicated_memory/1024; + + // VRAM detection logging + LL_INFOS("RenderInit") << "VRAM detected via nVidia MemInfo OpenGL extension: " << mVRAM << " MB" << LL_ENDL; } if (mVRAM < 256) { //something likely went wrong using the above extensions, fall back to old method mVRAM = old_vram; + + // VRAM detection logging + LL_WARNS("RenderInit") << "VRAM detected via MemInfo OpenGL extension most likely broken. Reverting to " << mVRAM << " MB" << LL_ENDL; } stop_glerror(); diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h index c7c0fe4582..39286160cf 100644 --- a/indra/llui/llflatlistview.h +++ b/indra/llui/llflatlistview.h @@ -480,6 +480,9 @@ public: // *WORKAROUND: two methods to overload appropriate Params due to localization issue: // no_items_msg & no_filtered_items_msg attributes are not defined as translatable in VLT. See EXT-5931 +// [RLVa:KB] - Checked: RLVa-2.0.3 + const std::string& getNoItemsMsg() const { return mNoItemsMsg; } +// [/RLVa:KB] void setNoItemsMsg(const std::string& msg) { mNoItemsMsg = msg; } void setNoFilteredItemsMsg(const std::string& msg) { mNoFilteredItemsMsg = msg; } diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp index 8141cf9bb8..f05d768ebe 100644 --- a/indra/llwindow/lldxhardware.cpp +++ b/indra/llwindow/lldxhardware.cpp @@ -534,6 +534,7 @@ BOOL LLDXHardware::getInfo(BOOL vram_only, bool disable_wmi) // { mVRAM = vram/(1024*1024); + LL_INFOS("AppInit") << "VRAM Detected via WMI: " << mVRAM << LL_ENDL; } else { // Get the English VRAM string @@ -545,7 +546,7 @@ BOOL LLDXHardware::getInfo(BOOL vram_only, bool disable_wmi) // Dump the string as an int into the structure char *stopstring; mVRAM = strtol(ram_str.c_str(), &stopstring, 10); - LL_INFOS("AppInit") << "VRAM Detected: " << mVRAM << " DX9 string: " << ram_str << LL_ENDL; + LL_INFOS("AppInit") << "VRAM Detected via DirectX: " << mVRAM << " DX9 string: " << ram_str << LL_ENDL; } if (vram_only) diff --git a/indra/media_plugins/CMakeLists.txt b/indra/media_plugins/CMakeLists.txt index ad4ed619c7..e4844b6ac2 100644 --- a/indra/media_plugins/CMakeLists.txt +++ b/indra/media_plugins/CMakeLists.txt @@ -6,13 +6,23 @@ if (LINUX) add_subdirectory(cef) endif (LINUX) -if (WINDOWS OR DARWIN) +if (DARWIN) add_subdirectory(quicktime) add_subdirectory(cef) -endif (WINDOWS OR DARWIN) +endif (DARWIN) if (WINDOWS) + if( WORD_SIZE EQUAL 32 ) + add_subdirectory(quicktime) + endif() + + add_subdirectory(cef) add_subdirectory(winmmshim) endif (WINDOWS) ### add_subdirectory(example) + +if (WINDOWS OR LINUX) + add_subdirectory(gstreamer10) +endif (WINDOWS OR LINUX) + diff --git a/indra/media_plugins/base/CMakeLists.txt b/indra/media_plugins/base/CMakeLists.txt index 7367b9e5e6..06395e91c8 100644 --- a/indra/media_plugins/base/CMakeLists.txt +++ b/indra/media_plugins/base/CMakeLists.txt @@ -29,11 +29,9 @@ include_directories(SYSTEM ### media_plugin_base if(NOT WORD_SIZE EQUAL 32) - if(WINDOWS) - add_definitions(/FIXED:NO) - else(WINDOWS) # not windows therefore gcc LINUX and DARWIN + if( NOT WINDOWS) add_definitions(-fPIC) - endif(WINDOWS) + endif(NOT WINDOWS) endif(NOT WORD_SIZE EQUAL 32) set(media_plugin_base_SOURCE_FILES diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt index adb3e2f732..01713f8f00 100644 --- a/indra/media_plugins/cef/CMakeLists.txt +++ b/indra/media_plugins/cef/CMakeLists.txt @@ -40,11 +40,9 @@ include_directories(SYSTEM ### media_plugin_cef if(NOT WORD_SIZE EQUAL 32) - if(WINDOWS) - add_definitions(/FIXED:NO) - else(WINDOWS) # not windows therefore gcc LINUX and DARWIN + if( NOT WINDOWS) # not windows therefore gcc LINUX and DARWIN add_definitions(-fPIC) - endif(WINDOWS) + endif(NOT WINDOWS) endif(NOT WORD_SIZE EQUAL 32) set(media_plugin_cef_SOURCE_FILES diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 0bdbbad338..6aab622063 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -108,17 +108,11 @@ private: VolumeCatcher mVolumeCatcher; - // FS specific CEF settings - bool mFlipY; - // - - // Buffer for a popup image to be rendered as an overlay U8 *mPopupBuffer; U32 mPopupW; U32 mPopupH; U32 mPopupX; U32 mPopupY; - // }; //////////////////////////////////////////////////////////////////////////////// @@ -147,18 +141,11 @@ MediaPluginBase(host_send_func, host_user_data) mPickedFile = ""; mLLCEFLib = new LLCEFLib(); - // FS specific CEF settings - mFlipY = false; - // - - // Buffer for a popup image to be rendered as an overlay mPopupBuffer = NULL; mPopupW = 0; mPopupH = 0; mPopupX = 0; mPopupY = 0; - // - } //////////////////////////////////////////////////////////////////////////////// @@ -188,10 +175,7 @@ void MediaPluginCEF::postDebugMessage(const std::string& msg) // void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int x, int y, int width, int height, bool is_popup) { - // in case this is a popup, delete our old popup buffer and create a new one if needed. - // Put this here as the media_plugin_cef will send a message with all but is_popup set to 0 in case the popup gets destroyed. -#if FS_CEFLIB_VERSION >= 3 - if (is_popup) + if( is_popup ) { delete mPopupBuffer; mPopupBuffer = NULL; @@ -200,17 +184,11 @@ void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int x, int y, mPopupX = 0; mPopupY = 0; } -#endif - // - - if (mPixels && pixels) + + if( mPixels && pixels ) { if (is_popup) { - // This is a valid popup, copy the texture into our overlay buffer. - // Can a texture ever have an alpha other than 255/1.0 to make an alpha blended popup/dropdown? - // (According to Mobius not w/o hacks, so we assume opague) -#if FS_CEFLIB_VERSION >= 3 if( width > 0 && height> 0 ) { mPopupBuffer = new U8[ width * height * mDepth ]; @@ -218,25 +196,8 @@ void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int x, int y, mPopupH = height; mPopupW = width; mPopupX = x; - mPopupY = y; + mPopupY = mHeight - y - height; } -#endif - // - -#if FS_CEFLIB_VERSION < 3 - // You are outdated and will be buggy - for (int line = 0; line < height; ++line) - { - int inverted_y = mHeight - y - height; - int src = line * width * mDepth; - int dst = (inverted_y + line) * mWidth * mDepth + x * mDepth; - - if (dst + width * mDepth < mWidth * mHeight * mDepth) - { - memcpy(mPixels + dst, pixels + src, width * mDepth); - } - } -#endif } else { @@ -251,14 +212,12 @@ void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int x, int y, U32 bufferSize = mWidth * mHeight * mDepth; U32 popupStride = mPopupW * mDepth; U32 bufferStride = mWidth * mDepth; - int dstY = mHeight - mPopupY - mPopupH; - if( !mFlipY ) - dstY = mPopupY; + int dstY = mPopupY; int src = 0; int dst = dstY * mWidth * mDepth + mPopupX * mDepth; - for (int line = 0; dst + popupStride < bufferSize && line < mPopupH; ++line) + for( int line = 0; dst + popupStride < bufferSize && line < mPopupH; ++line ) { memcpy( mPixels + dst, mPopupBuffer + src, popupStride ); src += popupStride; @@ -532,12 +491,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string) { if (message_name == "init") { - // FS specific CEF settings -#if defined( LL_WINDOWS ) || defined( LL_LINUX ) - mLLCEFLib->setFlipY( mFlipY ); -#endif - // - // event callbacks from LLCefLib mLLCEFLib->setOnPageChangedCallback(boost::bind(&MediaPluginCEF::onPageChangedCallback, this, _1, _2, _3, _4, _5, _6)); mLLCEFLib->setOnCustomSchemeURLCallback(boost::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, _1)); @@ -582,13 +535,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) message.setValueU32("internalformat", GL_RGB); message.setValueU32("format", GL_BGRA); message.setValueU32("type", GL_UNSIGNED_BYTE); - - // if mFlipY is true, teh CEF plugin will flip the texture and it will be in correct opengl format. - // If false, it needs to be flipped by the viewer. - // message.setValueBoolean("coords_opengl", true); - message.setValueBoolean("coords_opengl", mFlipY ); - // - + message.setValueBoolean("coords_opengl", true); sendMessage(message); } else if (message_name == "set_user_data_path") @@ -659,6 +606,8 @@ void MediaPluginCEF::receiveMessage(const char* message_string) S32 x = message_in.getValueS32("x"); S32 y = message_in.getValueS32("y"); + y = mHeight - y; + // only even send left mouse button events to LLCEFLib // (partially prompted by crash in OS X CEF when sending right button events) // we catch the right click in viewer and display our own context menu anyway @@ -832,10 +781,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string) { mJavascriptEnabled = message_in.getValueBoolean("enable"); } - else if( message_name == "cef_flipy" ) - { - mFlipY = message_in.getValueBoolean("enable"); - } } else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) { diff --git a/indra/media_plugins/gstreamer10/CMakeLists.txt b/indra/media_plugins/gstreamer10/CMakeLists.txt new file mode 100644 index 0000000000..4f975d7823 --- /dev/null +++ b/indra/media_plugins/gstreamer10/CMakeLists.txt @@ -0,0 +1,77 @@ +# -*- cmake -*- + +project(media_plugin_gstreamer10) + +include(00-Common) +include(LLCommon) +include(LLImage) +include(LLPlugin) +include(LLMath) +include(LLRender) +include(LLWindow) +include(Linking) +include(PluginAPI) +include(MediaPluginBase) +include(OpenGL) + +include(GStreamer10Plugin) + +include_directories( + ${LLPLUGIN_INCLUDE_DIRS} + ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS} + ${LLCOMMON_INCLUDE_DIRS} + ${LLMATH_INCLUDE_DIRS} + ${LLIMAGE_INCLUDE_DIRS} + ${LLRENDER_INCLUDE_DIRS} + ${LLWINDOW_INCLUDE_DIRS} + ${GSTREAMER10_INCLUDE_DIRS} + ${GSTREAMER10_PLUGINS_BASE_INCLUDE_DIRS} +) +include_directories(SYSTEM + ${LLCOMMON_SYSTEM_INCLUDE_DIRS} + ) + +### media_plugin_gstreamer10 + +if(NOT WORD_SIZE EQUAL 32) + if(NOT WINDOWS) # not windows therefore gcc LINUX and DARWIN + add_definitions(-fPIC) + endif() +endif(NOT WORD_SIZE EQUAL 32) + +set(media_plugin_gstreamer10_SOURCE_FILES + media_plugin_gstreamer10.cpp + llmediaimplgstreamer_syms.cpp + ) + +set(media_plugin_gstreamer10_HEADER_FILES + llmediaimplgstreamer_syms.h + llmediaimplgstreamertriviallogging.h + ) + +add_library(media_plugin_gstreamer10 + SHARED + ${media_plugin_gstreamer10_SOURCE_FILES} +) + +target_link_libraries(media_plugin_gstreamer10 + ${LLPLUGIN_LIBRARIES} + ${MEDIA_PLUGIN_BASE_LIBRARIES} + ${LLCOMMON_LIBRARIES} + ${PLUGIN_API_WINDOWS_LIBRARIES} + ${GSTREAMER10_LIBRARIES} +) + +add_dependencies(media_plugin_gstreamer10 + ${LLPLUGIN_LIBRARIES} + ${MEDIA_PLUGIN_BASE_LIBRARIES} + ${LLCOMMON_LIBRARIES} +) + +if (WINDOWS) + set_target_properties( + media_plugin_gstreamer10 + PROPERTIES + LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMT" + ) +endif (WINDOWS) diff --git a/indra/media_plugins/gstreamer10/llmediaimplgstreamer.h b/indra/media_plugins/gstreamer10/llmediaimplgstreamer.h new file mode 100644 index 0000000000..6bc272c009 --- /dev/null +++ b/indra/media_plugins/gstreamer10/llmediaimplgstreamer.h @@ -0,0 +1,53 @@ +/** + * @file llmediaimplgstreamer.h + * @author Tofu Linden + * @brief implementation that supports media playback via GStreamer. + * + * @cond + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + * @endcond + */ + +// header guard +#ifndef llmediaimplgstreamer_h +#define llmediaimplgstreamer_h + +#if LL_GSTREAMER010_ENABLED + +extern "C" { +#include +#include + +#include "apr_pools.h" +#include "apr_dso.h" +} + + +extern "C" { +gboolean llmediaimplgstreamer_bus_callback (GstBus *bus, + GstMessage *message, + gpointer data); +} + +#endif // LL_GSTREAMER010_ENABLED + +#endif // llmediaimplgstreamer_h diff --git a/indra/media_plugins/gstreamer10/llmediaimplgstreamer_syms.cpp b/indra/media_plugins/gstreamer10/llmediaimplgstreamer_syms.cpp new file mode 100644 index 0000000000..e5e5c1c9a3 --- /dev/null +++ b/indra/media_plugins/gstreamer10/llmediaimplgstreamer_syms.cpp @@ -0,0 +1,197 @@ +/** + * @file llmediaimplgstreamer_syms.cpp + * @brief dynamic GStreamer symbol-grabbing code + * + * @cond + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + * @endcond + */ + +#include +#include +#include + +#ifdef LL_WINDOWS +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0502 +#include +#endif + +#include "linden_common.h" + +extern "C" { +#include +#include +} + +#include "apr_pools.h" +#include "apr_dso.h" + +#ifdef LL_WINDOWS + +#ifndef _M_AMD64 +#define GSTREAMER_REG_KEY "Software\\GStreamer1.0\\x86" +#define GSTREAMER_DIR_SUFFIX "1.0\\x86\\bin\\" +#else +#define GSTREAMER_REG_KEY "Software\\GStreamer1.0\\x86_64" +#define GSTREAMER_DIR_SUFFIX "1.0\\x86_64\\bin\\" +#endif + +bool openRegKey( HKEY &aKey ) +{ + // Try native (32 bit view/64 bit view) of registry first. + if( ERROR_SUCCESS == ::RegOpenKeyExA( HKEY_LOCAL_MACHINE, GSTREAMER_REG_KEY, 0, KEY_QUERY_VALUE, &aKey ) ) + return true; + + // If native view fails, use 32 bit view or registry. + if( ERROR_SUCCESS == ::RegOpenKeyExA( HKEY_LOCAL_MACHINE, GSTREAMER_REG_KEY, 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY, &aKey ) ) + return true; + + return false; +} + +std::string getGStreamerDir() +{ + std::string ret; + HKEY hKey; + + if( openRegKey( hKey ) ) + { + DWORD dwLen(0); + ::RegQueryValueExA( hKey, "InstallDir", nullptr, nullptr, nullptr, &dwLen ); + + if( dwLen > 0 ) + { + std::vector< char > vctBuffer; + vctBuffer.resize( dwLen ); + ::RegQueryValueExA( hKey, "InstallDir", nullptr, nullptr, reinterpret_cast< LPBYTE>(&vctBuffer[ 0 ]), &dwLen ); + ret = &vctBuffer[0]; + + if( ret[ dwLen-1 ] != '\\' ) + ret += "\\"; + ret += GSTREAMER_DIR_SUFFIX; + + SetDllDirectoryA( ret.c_str() ); + } + ::RegCloseKey( hKey ); + } + return ret; +} +#else +std::string getGStreamerDir() { return ""; } +#endif + +#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) RTN (*ll##GSTSYM)(__VA_ARGS__) = NULL; +#include "llmediaimplgstreamer_syms_raw.inc" +#undef LL_GST_SYM + +struct Symloader +{ + bool mRequired; + char const *mName; + apr_dso_handle_sym_t *mPPFunc; +}; + +#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) { REQ, #GSTSYM , (apr_dso_handle_sym_t*)&ll##GSTSYM}, +Symloader sSyms[] = { +#include "llmediaimplgstreamer_syms_raw.inc" +{ false, 0, 0 } }; +#undef LL_GST_SYM + +// a couple of stubs for disgusting reasons +GstDebugCategory* +ll_gst_debug_category_new(gchar *name, guint color, gchar *description) +{ + static GstDebugCategory dummy; + return &dummy; +} +void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname) +{ +} + +static bool sSymsGrabbed = false; +static apr_pool_t *sSymGSTDSOMemoryPool = NULL; + +std::vector< apr_dso_handle_t* > sLoadedLibraries; + +bool grab_gst_syms( std::vector< std::string > const &aDSONames ) +{ + if (sSymsGrabbed) + return true; + + //attempt to load the shared libraries + apr_pool_create(&sSymGSTDSOMemoryPool, NULL); + + for( std::vector< std::string >::const_iterator itr = aDSONames.begin(); itr != aDSONames.end(); ++itr ) + { + apr_dso_handle_t *pDSO(NULL); + std::string strDSO = getGStreamerDir() + *itr; + if( APR_SUCCESS == apr_dso_load( &pDSO, strDSO.c_str(), sSymGSTDSOMemoryPool )) + sLoadedLibraries.push_back( pDSO ); + + for( int i = 0; sSyms[ i ].mName; ++i ) + { + if( !*sSyms[ i ].mPPFunc ) + { + apr_dso_sym( sSyms[ i ].mPPFunc, pDSO, sSyms[ i ].mName ); + } + } + } + + std::stringstream strm; + bool sym_error = false; + for( int i = 0; sSyms[ i ].mName; ++i ) + { + if( sSyms[ i ].mRequired && ! *sSyms[ i ].mPPFunc ) + { + sym_error = true; + strm << sSyms[ i ].mName << std::endl; + } + } + + sSymsGrabbed = !sym_error; + return sSymsGrabbed; +} + + +void ungrab_gst_syms() +{ + // should be safe to call regardless of whether we've + // actually grabbed syms. + + for( std::vector< apr_dso_handle_t* >::iterator itr = sLoadedLibraries.begin(); itr != sLoadedLibraries.end(); ++itr ) + apr_dso_unload( *itr ); + + sLoadedLibraries.clear(); + + if ( sSymGSTDSOMemoryPool ) + { + apr_pool_destroy(sSymGSTDSOMemoryPool); + sSymGSTDSOMemoryPool = NULL; + } + + for( int i = 0; sSyms[ i ].mName; ++i ) + *sSyms[ i ].mPPFunc = NULL; + + sSymsGrabbed = false; +} + diff --git a/indra/media_plugins/gstreamer10/llmediaimplgstreamer_syms.h b/indra/media_plugins/gstreamer10/llmediaimplgstreamer_syms.h new file mode 100644 index 0000000000..0874644ee6 --- /dev/null +++ b/indra/media_plugins/gstreamer10/llmediaimplgstreamer_syms.h @@ -0,0 +1,68 @@ +/** + * @file llmediaimplgstreamer_syms.h + * @brief dynamic GStreamer symbol-grabbing code + * + * @cond + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + * @endcond + */ + +#include "linden_common.h" +#include +extern "C" { +#include +} + +bool grab_gst_syms( std::vector< std::string > const&); +void ungrab_gst_syms(); + +#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) extern RTN (*ll##GSTSYM)(__VA_ARGS__); +#include "llmediaimplgstreamer_syms_raw.inc" +#undef LL_GST_SYM + +// regrettable hacks to give us better runtime compatibility with older systems +#define llg_return_if_fail(COND) do{if (!(COND)) return;}while(0) +#define llg_return_val_if_fail(COND,V) do{if (!(COND)) return V;}while(0) + +// regrettable hacks because GStreamer was not designed for runtime loading +#undef GST_TYPE_MESSAGE +#define GST_TYPE_MESSAGE (llgst_message_get_type()) +#undef GST_TYPE_OBJECT +#define GST_TYPE_OBJECT (llgst_object_get_type()) +#undef GST_TYPE_PIPELINE +#define GST_TYPE_PIPELINE (llgst_pipeline_get_type()) +#undef GST_TYPE_ELEMENT +#define GST_TYPE_ELEMENT (llgst_element_get_type()) +#undef GST_TYPE_VIDEO_SINK +#define GST_TYPE_VIDEO_SINK (llgst_video_sink_get_type()) +// more regrettable hacks to stub-out these .h-exposed GStreamer internals +void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname); +#undef _gst_debug_register_funcptr +#define _gst_debug_register_funcptr ll_gst_debug_register_funcptr +GstDebugCategory* ll_gst_debug_category_new(gchar *name, guint color, gchar *description); +#undef _gst_debug_category_new +#define _gst_debug_category_new ll_gst_debug_category_new +#undef __gst_debug_enabled +#define __gst_debug_enabled (0) + +// more hacks +#define LLGST_MESSAGE_TYPE_NAME(M) (llgst_message_type_get_name(GST_MESSAGE_TYPE(M))) diff --git a/indra/media_plugins/gstreamer10/llmediaimplgstreamer_syms_raw.inc b/indra/media_plugins/gstreamer10/llmediaimplgstreamer_syms_raw.inc new file mode 100644 index 0000000000..da1aa8ec1d --- /dev/null +++ b/indra/media_plugins/gstreamer10/llmediaimplgstreamer_syms_raw.inc @@ -0,0 +1,68 @@ +LL_GST_SYM(true, gst_buffer_new, GstBuffer*, void) +LL_GST_SYM(true, gst_structure_set_value, void, GstStructure *, const gchar *, const GValue*) +LL_GST_SYM(true, gst_init_check, gboolean, int *argc, char **argv[], GError ** err) +LL_GST_SYM(true, gst_message_get_type, GType, void) +LL_GST_SYM(true, gst_message_type_get_name, const gchar*, GstMessageType type) +LL_GST_SYM(true, gst_message_parse_error, void, GstMessage *message, GError **gerror, gchar **debug) +LL_GST_SYM(true, gst_message_parse_warning, void, GstMessage *message, GError **gerror, gchar **debug) +LL_GST_SYM(true, gst_message_parse_state_changed, void, GstMessage *message, GstState *oldstate, GstState *newstate, GstState *pending) +LL_GST_SYM(true, gst_element_set_state, GstStateChangeReturn, GstElement *element, GstState state) +LL_GST_SYM(true, gst_object_unref, void, gpointer object) +LL_GST_SYM(true, gst_object_get_type, GType, void) +LL_GST_SYM(true, gst_pipeline_get_type, GType, void) +LL_GST_SYM(true, gst_pipeline_get_bus, GstBus*, GstPipeline *pipeline) +LL_GST_SYM(true, gst_bus_add_watch, guint, GstBus * bus, GstBusFunc func, gpointer user_data) +LL_GST_SYM(true, gst_element_factory_make, GstElement*, const gchar *factoryname, const gchar *name) +LL_GST_SYM(true, gst_element_get_type, GType, void) +LL_GST_SYM(true, gst_static_pad_template_get, GstPadTemplate*, GstStaticPadTemplate *pad_template) +LL_GST_SYM(true, gst_element_class_add_pad_template, void, GstElementClass *klass, GstPadTemplate *temp) +LL_GST_SYM(true, gst_caps_from_string, GstCaps *, const gchar *string) +LL_GST_SYM(true, gst_caps_get_structure, GstStructure *, const GstCaps *caps, guint index) +LL_GST_SYM(true, gst_element_register, gboolean, GstPlugin *plugin, const gchar *name, guint rank, GType type) +LL_GST_SYM(true, gst_structure_get_int, gboolean, const GstStructure *structure, const gchar *fieldname, gint *value) +LL_GST_SYM(true, gst_structure_get_value, G_CONST_RETURN GValue *, const GstStructure *structure, const gchar *fieldname) +LL_GST_SYM(true, gst_value_get_fraction_numerator, gint, const GValue *value) +LL_GST_SYM(true, gst_value_get_fraction_denominator, gint, const GValue *value) +LL_GST_SYM(true, gst_structure_get_name, G_CONST_RETURN gchar *, const GstStructure *structure) +LL_GST_SYM(true, gst_element_seek, bool, GstElement *, gdouble, GstFormat, GstSeekFlags, GstSeekType, gint64, GstSeekType, gint64) + +LL_GST_SYM(false, gst_registry_fork_set_enabled, void, gboolean enabled) +LL_GST_SYM(false, gst_segtrap_set_enabled, void, gboolean enabled) +LL_GST_SYM(false, gst_message_parse_buffering, void, GstMessage *message, gint *percent) +LL_GST_SYM(false, gst_message_parse_info, void, GstMessage *message, GError **gerror, gchar **debug) +LL_GST_SYM(false, gst_element_query_position, gboolean, GstElement *element, GstFormat *format, gint64 *cur) +LL_GST_SYM(false, gst_version, void, guint *major, guint *minor, guint *micro, guint *nano) + +LL_GST_SYM( true, gst_message_parse_tag, void, GstMessage *, GstTagList **) +LL_GST_SYM( true, gst_tag_list_foreach, void, const GstTagList *, GstTagForeachFunc, gpointer) +LL_GST_SYM( true, gst_tag_list_get_tag_size, guint, const GstTagList *, const gchar *) +LL_GST_SYM( true, gst_tag_list_get_value_index, const GValue *, const GstTagList *, const gchar *, guint) + +LL_GST_SYM( true, gst_caps_new_simple, GstCaps*, const char *, const char*, ... ) + +LL_GST_SYM( true, gst_sample_get_caps, GstCaps*, GstSample* ) +LL_GST_SYM( true, gst_sample_get_buffer, GstBuffer*, GstSample* ) +LL_GST_SYM( true, gst_buffer_map, gboolean, GstBuffer*, GstMapInfo*, GstMapFlags ) +LL_GST_SYM( true, gst_buffer_unmap, void, GstBuffer*, GstMapInfo* ) + +LL_GST_SYM( true, gst_app_sink_set_caps, void, GstAppSink*, GstCaps const* ) +LL_GST_SYM( true, gst_app_sink_pull_sample, GstSample*, GstAppSink* ) + +LL_GST_SYM( true, g_free, void, gpointer ) +LL_GST_SYM( true, g_error_free, void, GError* ) + +LL_GST_SYM( true, g_main_context_pending, gboolean, GMainContext* ) +LL_GST_SYM( true, g_main_loop_get_context, GMainContext*, GMainLoop* ) +LL_GST_SYM( true, g_main_context_iteration, gboolean, GMainContext*, gboolean ) +LL_GST_SYM( true, g_main_loop_new, GMainLoop*, GMainContext*, gboolean ) +LL_GST_SYM( true, g_main_loop_quit, void, GMainLoop* ) +LL_GST_SYM( true, gst_mini_object_unref, void, GstMiniObject* ) +LL_GST_SYM( true, g_object_set, void, gpointer, gchar const*, ... ) +LL_GST_SYM( true, g_source_remove, gboolean, guint ) +LL_GST_SYM( true, g_value_get_string, gchar const*, GValue const* ) + + +LL_GST_SYM( true, gst_debug_set_active, void, gboolean ) +LL_GST_SYM( true, gst_debug_add_log_function, void, GstLogFunction, gpointer, GDestroyNotify ) +LL_GST_SYM( true, gst_debug_set_default_threshold, void, GstDebugLevel ) +LL_GST_SYM( true, gst_debug_message_get , gchar const*, GstDebugMessage * ) \ No newline at end of file diff --git a/indra/media_plugins/gstreamer10/media_plugin_gstreamer10.cpp b/indra/media_plugins/gstreamer10/media_plugin_gstreamer10.cpp new file mode 100644 index 0000000000..5c931ea8f0 --- /dev/null +++ b/indra/media_plugins/gstreamer10/media_plugin_gstreamer10.cpp @@ -0,0 +1,980 @@ +/** + * @file media_plugin_gstreamer10.cpp + * @brief GStreamer-1.0 plugin for LLMedia API plugin system + * + * @cond + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2016, Linden Research, Inc. / Nicky Dasmijn + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + * @endcond + */ + +#define FLIP_Y + +#include "linden_common.h" + +#include "llgl.h" + +#include "llplugininstance.h" +#include "llpluginmessage.h" +#include "llpluginmessageclasses.h" +#include "media_plugin_base.h" + +#define G_DISABLE_CAST_CHECKS +extern "C" { +#include +#include + +} + +#include "llmediaimplgstreamer.h" +#include "llmediaimplgstreamer_syms.h" + +static inline void llgst_caps_unref( GstCaps * caps ) +{ + llgst_mini_object_unref( GST_MINI_OBJECT_CAST( caps ) ); +} + +static inline void llgst_sample_unref( GstSample *aSample ) +{ + llgst_mini_object_unref( GST_MINI_OBJECT_CAST( aSample ) ); +} + +////////////////////////////////////////////////////////////////////////////// +// +class MediaPluginGStreamer10 : public MediaPluginBase +{ +public: + MediaPluginGStreamer10(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + ~MediaPluginGStreamer10(); + + /* virtual */ void receiveMessage(const char *message_string); + + static bool startup(); + static bool closedown(); + + gboolean processGSTEvents(GstBus *bus, GstMessage *message); + +private: + std::string getVersion(); + bool navigateTo( const std::string urlIn ); + bool seek( double time_sec ); + bool setVolume( float volume ); + + // misc + bool pause(); + bool stop(); + bool play(double rate); + bool getTimePos(double &sec_out); + + double MIN_LOOP_SEC = 1.0F; + U32 INTERNAL_TEXTURE_SIZE = 1024; + + bool mIsLooping; + + enum ECommand { + COMMAND_NONE, + COMMAND_STOP, + COMMAND_PLAY, + COMMAND_FAST_FORWARD, + COMMAND_FAST_REWIND, + COMMAND_PAUSE, + COMMAND_SEEK, + }; + ECommand mCommand; + +private: + bool unload(); + bool load(); + + bool update(int milliseconds); + void mouseDown( int x, int y ); + void mouseUp( int x, int y ); + void mouseMove( int x, int y ); + + static bool mDoneInit; + + guint mBusWatchID; + + float mVolume; + + int mDepth; + + // padded texture size we need to write into + int mTextureWidth; + int mTextureHeight; + + bool mSeekWanted; + double mSeekDestination; + + // Very GStreamer-specific + GMainLoop *mPump; // event pump for this media + GstElement *mPlaybin; + GstAppSink *mAppSink; +}; + +//static +bool MediaPluginGStreamer10::mDoneInit = false; + +MediaPluginGStreamer10::MediaPluginGStreamer10( LLPluginInstance::sendMessageFunction host_send_func, + void *host_user_data ) + : MediaPluginBase(host_send_func, host_user_data) + , mBusWatchID ( 0 ) + , mSeekWanted(false) + , mSeekDestination(0.0) + , mPump ( NULL ) + , mPlaybin ( NULL ) + , mAppSink ( NULL ) + , mCommand ( COMMAND_NONE ) +{ +} + +gboolean MediaPluginGStreamer10::processGSTEvents(GstBus *bus, GstMessage *message) +{ + if (!message) + return TRUE; // shield against GStreamer bug + + switch (GST_MESSAGE_TYPE (message)) + { + case GST_MESSAGE_BUFFERING: + { + // NEEDS GST 0.10.11+ + if (llgst_message_parse_buffering) + { + gint percent = 0; + llgst_message_parse_buffering(message, &percent); + } + break; + } + case GST_MESSAGE_STATE_CHANGED: + { + GstState old_state; + GstState new_state; + GstState pending_state; + llgst_message_parse_state_changed(message, + &old_state, + &new_state, + &pending_state); + + switch (new_state) + { + case GST_STATE_VOID_PENDING: + break; + case GST_STATE_NULL: + break; + case GST_STATE_READY: + setStatus(STATUS_LOADED); + break; + case GST_STATE_PAUSED: + setStatus(STATUS_PAUSED); + break; + case GST_STATE_PLAYING: + setStatus(STATUS_PLAYING); + break; + } + break; + } + case GST_MESSAGE_ERROR: + { + GError *err = NULL; + gchar *debug = NULL; + + llgst_message_parse_error (message, &err, &debug); + if (err) + llg_error_free (err); + llg_free (debug); + + mCommand = COMMAND_STOP; + + setStatus(STATUS_ERROR); + + break; + } + case GST_MESSAGE_INFO: + { + if (llgst_message_parse_info) + { + GError *err = NULL; + gchar *debug = NULL; + + llgst_message_parse_info (message, &err, &debug); + if (err) + llg_error_free (err); + llg_free (debug); + } + break; + } + case GST_MESSAGE_WARNING: + { + GError *err = NULL; + gchar *debug = NULL; + + llgst_message_parse_warning (message, &err, &debug); + if (err) + llg_error_free (err); + llg_free (debug); + + break; + } + case GST_MESSAGE_EOS: + /* end-of-stream */ + if (mIsLooping) + { + double eos_pos_sec = 0.0F; + bool got_eos_position = getTimePos(eos_pos_sec); + + if (got_eos_position && eos_pos_sec < MIN_LOOP_SEC) + { + // if we know that the movie is really short, don't + // loop it else it can easily become a time-hog + // because of GStreamer spin-up overhead + // inject a COMMAND_PAUSE + mCommand = COMMAND_PAUSE; + } + else + { + stop(); + play(1.0); + } + } + else // not a looping media + { + // inject a COMMAND_STOP + mCommand = COMMAND_STOP; + } + break; + default: + /* unhandled message */ + break; + } + + /* we want to be notified again the next time there is a message + * on the bus, so return true (false means we want to stop watching + * for messages on the bus and our callback should not be called again) + */ + return TRUE; +} + +extern "C" { + gboolean llmediaimplgstreamer_bus_callback (GstBus *bus, + GstMessage *message, + gpointer data) + { + MediaPluginGStreamer10 *impl = (MediaPluginGStreamer10*)data; + return impl->processGSTEvents(bus, message); + } +} // extern "C" + + + +bool MediaPluginGStreamer10::navigateTo ( const std::string urlIn ) +{ + if (!mDoneInit) + return false; // error + + setStatus(STATUS_LOADING); + + mSeekWanted = false; + + if (NULL == mPump || NULL == mPlaybin) + { + setStatus(STATUS_ERROR); + return false; // error + } + + llg_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), NULL); + + // navigateTo implicitly plays, too. + play(1.0); + + return true; +} + + +class GstSampleUnref +{ + GstSample *mT; +public: + GstSampleUnref( GstSample *aT ) + : mT( aT ) + { llassert_always( mT ); } + + ~GstSampleUnref( ) + { llgst_sample_unref( mT ); } +}; + +bool MediaPluginGStreamer10::update(int milliseconds) +{ + if (!mDoneInit) + return false; // error + + // DEBUGMSG("updating media..."); + + // sanity check + if (NULL == mPump || NULL == mPlaybin) + { + return false; + } + + // see if there's an outstanding seek wanted + if (mSeekWanted && + // bleh, GST has to be happy that the movie is really truly playing + // or it may quietly ignore the seek (with rtsp:// at least). + (GST_STATE(mPlaybin) == GST_STATE_PLAYING)) + { + seek(mSeekDestination); + mSeekWanted = false; + } + + // *TODO: time-limit - but there isn't a lot we can do here, most + // time is spent in gstreamer's own opaque worker-threads. maybe + // we can do something sneaky like only unlock the video object + // for 'milliseconds' and otherwise hold the lock. + while (llg_main_context_pending(llg_main_loop_get_context(mPump))) + { + llg_main_context_iteration(llg_main_loop_get_context(mPump), FALSE); + } + + // check for availability of a new frame + + if( !mAppSink ) + return true; + + if( GST_STATE(mPlaybin) != GST_STATE_PLAYING) // Do not try to pull a sample if not in playing state + return true; + + GstSample *pSample = llgst_app_sink_pull_sample( mAppSink ); + if(!pSample) + return false; // Done playing + + GstSampleUnref oSampleUnref( pSample ); + GstCaps *pCaps = llgst_sample_get_caps ( pSample ); + if (!pCaps) + return false; + + gint width, height; + GstStructure *pStruct = llgst_caps_get_structure ( pCaps, 0); + + int res = llgst_structure_get_int ( pStruct, "width", &width); + res |= llgst_structure_get_int ( pStruct, "height", &height); + + if( !mPixels ) + return true; + + GstBuffer *pBuffer = llgst_sample_get_buffer ( pSample ); + GstMapInfo map; + llgst_buffer_map ( pBuffer, &map, GST_MAP_READ); + + // Our render buffer is always 1kx1k + + U32 rowSkip = INTERNAL_TEXTURE_SIZE / mTextureHeight; + U32 colSkip = INTERNAL_TEXTURE_SIZE / mTextureWidth; + + for (int row = 0; row < mTextureHeight; ++row) + { + U8 const *pTexelIn = map.data + (row*rowSkip * width *3); +#ifndef FLIP_Y + U8 *pTexelOut = mPixels + (row * mTextureWidth * mDepth ); +#else + U8 *pTexelOut = mPixels + ((mTextureHeight-row-1) * mTextureWidth * mDepth ); +#endif + for( int col = 0; col < mTextureWidth; ++col ) + { + pTexelOut[ 0 ] = pTexelIn[0]; + pTexelOut[ 1 ] = pTexelIn[1]; + pTexelOut[ 2 ] = pTexelIn[2]; + pTexelOut += mDepth; + pTexelIn += colSkip*3; + } + } + + llgst_buffer_unmap( pBuffer, &map ); + setDirty(0,0,mTextureWidth,mTextureHeight); + + return true; +} + +void MediaPluginGStreamer10::mouseDown( int x, int y ) +{ + // do nothing +} + +void MediaPluginGStreamer10::mouseUp( int x, int y ) +{ + // do nothing +} + +void MediaPluginGStreamer10::mouseMove( int x, int y ) +{ + // do nothing +} + + +bool MediaPluginGStreamer10::pause() +{ + // todo: error-check this? + if (mDoneInit && mPlaybin) + { + llgst_element_set_state(mPlaybin, GST_STATE_PAUSED); + return true; + } + return false; +} + +bool MediaPluginGStreamer10::stop() +{ + // todo: error-check this? + if (mDoneInit && mPlaybin) + { + llgst_element_set_state(mPlaybin, GST_STATE_READY); + return true; + } + return false; +} + +bool MediaPluginGStreamer10::play(double rate) +{ + // NOTE: we don't actually support non-natural rate. + + // todo: error-check this? + if (mDoneInit && mPlaybin) + { + llgst_element_set_state(mPlaybin, GST_STATE_PLAYING); + return true; + } + return false; +} + +bool MediaPluginGStreamer10::setVolume( float volume ) +{ + // we try to only update volume as conservatively as + // possible, as many gst-plugins-base versions up to at least + // November 2008 have critical race-conditions in setting volume - sigh + if (mVolume == volume) + return true; // nothing to do, everything's fine + + mVolume = volume; + if (mDoneInit && mPlaybin) + { + llg_object_set(mPlaybin, "volume", mVolume, NULL); + return true; + } + + return false; +} + +bool MediaPluginGStreamer10::seek(double time_sec) +{ + bool success = false; + if (mDoneInit && mPlaybin) + { + success = llgst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME, + GstSeekFlags(GST_SEEK_FLAG_FLUSH | + GST_SEEK_FLAG_KEY_UNIT), + GST_SEEK_TYPE_SET, gint64(time_sec*GST_SECOND), + GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); + } + return success; +} + +bool MediaPluginGStreamer10::getTimePos(double &sec_out) +{ + bool got_position = false; + if (mDoneInit && mPlaybin) + { + gint64 pos(0); + GstFormat timefmt = GST_FORMAT_TIME; + got_position = + llgst_element_query_position && + llgst_element_query_position(mPlaybin, + &timefmt, + &pos); + got_position = got_position + && (timefmt == GST_FORMAT_TIME); + // GStreamer may have other ideas, but we consider the current position + // undefined if not PLAYING or PAUSED + got_position = got_position && + (GST_STATE(mPlaybin) == GST_STATE_PLAYING || + GST_STATE(mPlaybin) == GST_STATE_PAUSED); + if (got_position && !GST_CLOCK_TIME_IS_VALID(pos)) + { + if (GST_STATE(mPlaybin) == GST_STATE_PLAYING) + { + // if we're playing then we treat an invalid clock time + // as 0, for complicated reasons (insert reason here) + pos = 0; + } + else + { + got_position = false; + } + + } + // If all the preconditions succeeded... we can trust the result. + if (got_position) + { + sec_out = double(pos) / double(GST_SECOND); // gst to sec + } + } + return got_position; +} + +bool MediaPluginGStreamer10::load() +{ + if (!mDoneInit) + return false; // error + + setStatus(STATUS_LOADING); + + mIsLooping = false; + mVolume = 0.1234567f; // minor hack to force an initial volume update + + // Create a pumpable main-loop for this media + mPump = llg_main_loop_new (NULL, FALSE); + if (!mPump) + { + setStatus(STATUS_ERROR); + return false; // error + } + + // instantiate a playbin element to do the hard work + mPlaybin = llgst_element_factory_make ("playbin", ""); + if (!mPlaybin) + { + setStatus(STATUS_ERROR); + return false; // error + } + + // get playbin's bus + GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin)); + if (!bus) + { + setStatus(STATUS_ERROR); + return false; // error + } + mBusWatchID = llgst_bus_add_watch (bus, + llmediaimplgstreamer_bus_callback, + this); + llgst_object_unref (bus); + + mAppSink = (GstAppSink*)(llgst_element_factory_make ("appsink", "")); + + GstCaps* pCaps = llgst_caps_new_simple( "video/x-raw", + "format", G_TYPE_STRING, "RGB", + "width", G_TYPE_INT, INTERNAL_TEXTURE_SIZE, + "height", G_TYPE_INT, INTERNAL_TEXTURE_SIZE, + NULL ); + + llgst_app_sink_set_caps( mAppSink, pCaps ); + llgst_caps_unref( pCaps ); + + if (!mAppSink) + { + setStatus(STATUS_ERROR); + return false; + } + + llg_object_set(mPlaybin, "video-sink", mAppSink, NULL); + + return true; +} + +bool MediaPluginGStreamer10::unload () +{ + if (!mDoneInit) + return false; // error + + // stop getting callbacks for this bus + llg_source_remove(mBusWatchID); + mBusWatchID = 0; + + if (mPlaybin) + { + llgst_element_set_state (mPlaybin, GST_STATE_NULL); + llgst_object_unref (GST_OBJECT (mPlaybin)); + mPlaybin = NULL; + } + + if (mPump) + { + llg_main_loop_quit(mPump); + mPump = NULL; + } + + mAppSink = NULL; + + setStatus(STATUS_NONE); + + return true; +} + +void LogFunction(GstDebugCategory *category, GstDebugLevel level, const gchar *file, const gchar *function, gint line, GObject *object, GstDebugMessage *message, gpointer user_data ) +#ifndef LL_LINUX // Docu says we need G_GNUC_NO_INSTRUMENT, but GCC says 'error' + G_GNUC_NO_INSTRUMENT +#endif +{ +#ifdef LL_LINUX + std::cerr << file << ":" << line << "(" << function << "): " << llgst_debug_message_get( message ) << std::endl; +#endif +} + +//static +bool MediaPluginGStreamer10::startup() +{ + // first - check if GStreamer is explicitly disabled + if (NULL != getenv("LL_DISABLE_GSTREAMER")) + return false; + + // only do global GStreamer initialization once. + if (!mDoneInit) + { + ll_init_apr(); + + // Get symbols! + std::vector< std::string > vctDSONames; +#if LL_DARWIN +#elif LL_WINDOWS + vctDSONames.push_back( "libgstreamer-1.0-0.dll" ); + vctDSONames.push_back( "libgstapp-1.0-0.dll" ); + vctDSONames.push_back( "libglib-2.0-0.dll" ); + vctDSONames.push_back( "libgobject-2.0-0.dll" ); +#else // linux or other ELFy unixoid + vctDSONames.push_back( "libgstreamer-1.0.so.0" ); + vctDSONames.push_back( "libgstapp-1.0.so.0" ); + vctDSONames.push_back( "libglib-2.0.so.0" ); + vctDSONames.push_back( "libgobject-2.0.so" ); +#endif + if( !grab_gst_syms( vctDSONames ) ) + { + return false; + } + + if (llgst_segtrap_set_enabled) + { + llgst_segtrap_set_enabled(FALSE); + } +#if LL_LINUX + // Gstreamer tries a fork during init, waitpid-ing on it, + // which conflicts with any installed SIGCHLD handler... + struct sigaction tmpact, oldact; + if (llgst_registry_fork_set_enabled ) { + // if we can disable SIGCHLD-using forking behaviour, + // do it. + llgst_registry_fork_set_enabled(false); + } + else { + // else temporarily install default SIGCHLD handler + // while GStreamer initialises + tmpact.sa_handler = SIG_DFL; + sigemptyset( &tmpact.sa_mask ); + tmpact.sa_flags = SA_SIGINFO; + sigaction(SIGCHLD, &tmpact, &oldact); + } +#endif // LL_LINUX + // Protect against GStreamer resetting the locale, yuck. + static std::string saved_locale; + saved_locale = setlocale(LC_ALL, NULL); + +// _putenv_s( "GST_PLUGIN_PATH", "E:\\gstreamer\\1.0\\x86\\lib\\gstreamer-1.0" ); + + llgst_debug_set_default_threshold( GST_LEVEL_WARNING ); + llgst_debug_add_log_function( LogFunction, NULL, NULL ); + llgst_debug_set_active( false ); + + // finally, try to initialize GStreamer! + GError *err = NULL; + gboolean init_gst_success = llgst_init_check(NULL, NULL, &err); + + // restore old locale + setlocale(LC_ALL, saved_locale.c_str() ); + +#if LL_LINUX + // restore old SIGCHLD handler + if (!llgst_registry_fork_set_enabled) + sigaction(SIGCHLD, &oldact, NULL); +#endif // LL_LINUX + + if (!init_gst_success) // fail + { + if (err) + { + llg_error_free(err); + } + return false; + } + + mDoneInit = true; + } + + return true; +} + +//static +bool MediaPluginGStreamer10::closedown() +{ + if (!mDoneInit) + return false; // error + + ungrab_gst_syms(); + + mDoneInit = false; + + return true; +} + +MediaPluginGStreamer10::~MediaPluginGStreamer10() +{ + closedown(); +} + + +std::string MediaPluginGStreamer10::getVersion() +{ + std::string plugin_version = "GStreamer10 media plugin, GStreamer version "; + if (mDoneInit && + llgst_version) + { + guint major, minor, micro, nano; + llgst_version(&major, &minor, µ, &nano); + plugin_version += llformat("%u.%u.%u.%u (runtime), %u.%u.%u.%u (headers)", (unsigned int)major, (unsigned int)minor, + (unsigned int)micro, (unsigned int)nano, (unsigned int)GST_VERSION_MAJOR, (unsigned int)GST_VERSION_MINOR, + (unsigned int)GST_VERSION_MICRO, (unsigned int)GST_VERSION_NANO); + } + else + { + plugin_version += "(unknown)"; + } + return plugin_version; +} + +void MediaPluginGStreamer10::receiveMessage(const char *message_string) +{ + LLPluginMessage message_in; + + if(message_in.parse(message_string) >= 0) + { + std::string message_class = message_in.getClass(); + std::string message_name = message_in.getName(); + + if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE) + { + if(message_name == "init") + { + LLPluginMessage message("base", "init_response"); + LLSD versions = LLSD::emptyMap(); + versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION; + message.setValueLLSD("versions", versions); + + load(); + + message.setValue("plugin_version", getVersion()); + sendMessage(message); + } + else if(message_name == "idle") + { + // no response is necessary here. + double time = message_in.getValueReal("time"); + + // Convert time to milliseconds for update() + update((int)(time * 1000.0f)); + } + else if(message_name == "cleanup") + { + unload(); + closedown(); + } + else if(message_name == "shm_added") + { + SharedSegmentInfo info; + info.mAddress = message_in.getValuePointer("address"); + info.mSize = (size_t)message_in.getValueS32("size"); + std::string name = message_in.getValue("name"); + + mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); + } + else if(message_name == "shm_remove") + { + std::string name = message_in.getValue("name"); + + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if(iter != mSharedSegments.end()) + { + if(mPixels == iter->second.mAddress) + { + // This is the currently active pixel buffer. Make sure we stop drawing to it. + mPixels = NULL; + mTextureSegmentName.clear(); + } + mSharedSegments.erase(iter); + } + + // Send the response so it can be cleaned up. + LLPluginMessage message("base", "shm_remove_response"); + message.setValue("name", name); + sendMessage(message); + } + } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) + { + if(message_name == "init") + { + // Plugin gets to decide the texture parameters to use. + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); + // lame to have to decide this now, it depends on the movie. Oh well. + mDepth = 4; + + mTextureWidth = 1; + mTextureHeight = 1; + + message.setValueU32("format", GL_RGBA); + message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV); + + message.setValueS32("depth", mDepth); + message.setValueS32("default_width", INTERNAL_TEXTURE_SIZE ); + message.setValueS32("default_height", INTERNAL_TEXTURE_SIZE ); + message.setValueU32("internalformat", GL_RGBA8); + message.setValueBoolean("coords_opengl", true); // true == use OpenGL-style coordinates, false == (0,0) is upper left. + message.setValueBoolean("allow_downsample", true); // we respond with grace and performance if asked to downscale + sendMessage(message); + } + else if(message_name == "size_change") + { + std::string name = message_in.getValue("name"); + S32 width = message_in.getValueS32("width"); + S32 height = message_in.getValueS32("height"); + S32 texture_width = message_in.getValueS32("texture_width"); + S32 texture_height = message_in.getValueS32("texture_height"); + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); + message.setValue("name", name); + message.setValueS32("width", width); + message.setValueS32("height", height); + message.setValueS32("texture_width", texture_width); + message.setValueS32("texture_height", texture_height); + sendMessage(message); + + if(!name.empty()) + { + // Find the shared memory region with this name + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if(iter != mSharedSegments.end()) + { + mPixels = (unsigned char*)iter->second.mAddress; + mTextureSegmentName = name; + + mTextureWidth = texture_width; + mTextureHeight = texture_height; + memset( mPixels, 0, mTextureWidth*mTextureHeight*mDepth ); + } + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_request"); + message.setValue("name", mTextureSegmentName); + message.setValueS32("width", INTERNAL_TEXTURE_SIZE ); + message.setValueS32("height", INTERNAL_TEXTURE_SIZE ); + sendMessage(message); + + } + } + else if(message_name == "load_uri") + { + std::string uri = message_in.getValue("uri"); + navigateTo( uri ); + sendStatus(); + } + else if(message_name == "mouse_event") + { + std::string event = message_in.getValue("event"); + S32 x = message_in.getValueS32("x"); + S32 y = message_in.getValueS32("y"); + + if(event == "down") + { + mouseDown(x, y); + } + else if(event == "up") + { + mouseUp(x, y); + } + else if(event == "move") + { + mouseMove(x, y); + }; + }; + } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) + { + if(message_name == "stop") + { + stop(); + } + else if(message_name == "start") + { + double rate = 0.0; + if(message_in.hasValue("rate")) + { + rate = message_in.getValueReal("rate"); + } + // NOTE: we don't actually support rate. + play(rate); + } + else if(message_name == "pause") + { + pause(); + } + else if(message_name == "seek") + { + double time = message_in.getValueReal("time"); + // defer the actual seek in case we haven't + // really truly started yet in which case there + // is nothing to seek upon + mSeekWanted = true; + mSeekDestination = time; + } + else if(message_name == "set_loop") + { + bool loop = message_in.getValueBoolean("loop"); + mIsLooping = loop; + } + else if(message_name == "set_volume") + { + double volume = message_in.getValueReal("volume"); + setVolume(volume); + } + } + } +} + +int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) +{ + if( MediaPluginGStreamer10::startup() ) + { + MediaPluginGStreamer10 *self = new MediaPluginGStreamer10(host_send_func, host_user_data); + *plugin_send_func = MediaPluginGStreamer10::staticReceiveMessage; + *plugin_user_data = (void*)self; + + return 0; // okay + } + else + { + return -1; // failed to init + } +} diff --git a/indra/media_plugins/winmmshim/forwarding_api.cpp b/indra/media_plugins/winmmshim/forwarding_api.cpp index 33f0675028..ec8fe8d6d3 100644 --- a/indra/media_plugins/winmmshim/forwarding_api.cpp +++ b/indra/media_plugins/winmmshim/forwarding_api.cpp @@ -429,7 +429,7 @@ extern "C" { return DefDriverProc_orig( dwDriverIdentifier, hdrvr, uMsg, lParam1, lParam2); } - BOOL WINAPI DriverCallback( DWORD dwCallBack, DWORD dwFlags, HDRVR hdrvr, DWORD msg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2) + BOOL WINAPI DriverCallback( DWORD_PTR dwCallBack, DWORD dwFlags, HDRVR hdrvr, DWORD msg, DWORD_PTR dwUser, DWORD_PTR dwParam1, DWORD_PTR dwParam2 ) { ll_winmm_shim_initialize(); //OutputDebugString(L"DriverCallback\n"); diff --git a/indra/media_plugins/winmmshim/forwarding_api.h b/indra/media_plugins/winmmshim/forwarding_api.h index 1418fc9e1d..ab1978a688 100644 --- a/indra/media_plugins/winmmshim/forwarding_api.h +++ b/indra/media_plugins/winmmshim/forwarding_api.h @@ -46,7 +46,7 @@ typedef HMODULE (WINAPI *GetDriverModuleHandle_type)( HDRVR hDriver); extern GetDriverModuleHandle_type GetDriverModuleHandle_orig; typedef LRESULT (WINAPI *DefDriverProc_type)( DWORD_PTR dwDriverIdentifier, HDRVR hdrvr, UINT uMsg, LPARAM lParam1, LPARAM lParam2); extern DefDriverProc_type DefDriverProc_orig; -typedef BOOL (WINAPI *DriverCallback_type)(DWORD dwCallBack, DWORD dwFlags, HDRVR hdrvr, DWORD msg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2); +typedef BOOL( WINAPI *DriverCallback_type )(DWORD_PTR dwCallBack, DWORD dwFlags, HDRVR hdrvr, DWORD msg, DWORD_PTR dwUser, DWORD_PTR dwParam1, DWORD_PTR dwParam2); extern DriverCallback_type DriverCallback_orig; typedef UINT (WINAPI *mmsystemGetVersion_type)(void); extern mmsystemGetVersion_type mmsystemGetVersion_orig; diff --git a/indra/media_plugins/winmmshim/winmm_shim.cpp b/indra/media_plugins/winmmshim/winmm_shim.cpp index 59dfee74f3..cfba0c49a1 100644 --- a/indra/media_plugins/winmmshim/winmm_shim.cpp +++ b/indra/media_plugins/winmmshim/winmm_shim.cpp @@ -169,6 +169,8 @@ extern "C" { short volume_16 = (short)(sVolumeLevel * 32767.f); +// For x64 we leave out the MMX loop as it needs to be rewritten with SSE2 (_m128) instead of _m64. Needs a check if winshim is even used for x64 before invessting more time. +#ifndef _M_AMD64 // copy volume level 4 times into 64 bit MMX register __m64 volume_64 = _mm_set_pi16(volume_16, volume_16, volume_16, volume_16); __m64* sample_64; @@ -189,6 +191,9 @@ extern "C" // the captain has turned off the MMX sign, you are now free to use floating point registers _mm_empty(); +#else + short *sample_64 = (short*)pwh->lpData; +#endif // finish remaining samples that didn't fit into 64 bit register for (short* sample_16 = (short*)sample_64; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 3e2f26e5ef..aab04249ad 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -139,6 +139,7 @@ set(viewer_SOURCE_FILES fsdroptarget.cpp fsexportperms.cpp fsfloateraddtocontactset.cpp + fsfloateravatarrendersettings.cpp fsfloaterblocklist.cpp fsfloatercontacts.cpp fsfloatercontactsetconfiguration.cpp @@ -879,6 +880,7 @@ set(viewer_HEADER_FILES fsdroptarget.h fsexportperms.h fsfloateraddtocontactset.h + fsfloateravatarrendersettings.h fsfloaterblocklist.h fsfloatercontacts.h fsfloatercontactsetconfiguration.h @@ -1976,6 +1978,20 @@ if (NOT USESYSTEMLIBS) list(APPEND viewer_SOURCE_FILES ${viewer_CHARACTER_FILES}) endif (NOT USESYSTEMLIBS) +# Add Firestorm folders +file(GLOB viewer_FONT_FILES fonts/*.xml) +source_group("Fonts" FILES ${viewer_FONT_FILES}) +set_source_files_properties(${viewer_FONT_FILES} + PROPERTIES HEADER_FILE_ONLY TRUE) +list(APPEND viewer_SOURCE_FILES ${viewer_FONT_FILES}) + +file(GLOB viewer_FS_RESOURCES fs_resources/*) +source_group("Firestorm Resources" FILES ${viewer_FS_RESOURCES}) +set_source_files_properties(${viewer_FS_RESOURCES} + PROPERTIES HEADER_FILE_ONLY TRUE) +list(APPEND viewer_SOURCE_FILES ${viewer_FS_RESOURCES}) +# + if (WINDOWS) file(GLOB viewer_INSTALLER_FILES installers/windows/*.nsi) @@ -2110,6 +2126,7 @@ if (WINDOWS) SLPlugin media_plugin_quicktime media_plugin_cef + media_plugin_gstreamer10 winmm_shim windows-crash-logger ) @@ -2166,14 +2183,10 @@ if (WINDOWS) add_dependencies(${VIEWER_BINARY_NAME} copy_win_scripts) endif (EXISTS ${CMAKE_SOURCE_DIR}/copy_win_scripts) - if( NOT ND_BUILD64BIT_ARCH ) add_dependencies(${VIEWER_BINARY_NAME} SLPlugin - windows-crash-logger + windows-crash-logger ) - else() - add_dependencies(${VIEWER_BINARY_NAME} windows-crash-logger ) - endif( NOT ND_BUILD64BIT_ARCH ) # sets the 'working directory' for debugging from visual studio. if (NOT UNATTENDED) @@ -2364,6 +2377,7 @@ else (NOT ENABLE_MEDIA_PLUGINS) SLPlugin media_plugin_cef media_plugin_gstreamer010 + media_plugin_gstreamer10 llcommon ) endif (NOT ENABLE_MEDIA_PLUGINS) diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index b8de1561f0..e18c67b610 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -4.7.8 +4.7.10 diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index 62ef3bb2f1..7368dc8021 100644 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml @@ -60,7 +60,6 @@ --> import export - fsdata SLURL Outfit diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 4e64f79168..5b5ce05d02 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1254,6 +1254,17 @@ Value + + RLVaCompatibilityModeList + + Comment + Contains a list of creators or partial items names that require compatibility mode handling (see wiki for more information and syntax) + Persist + 1 + Type + String + Value + + RLVaDebugDeprecateExplicitPoint Comment @@ -1287,6 +1298,17 @@ Value 0 + RLVaEnableIMQuery + + Comment + Enables a limited number of configuration queries via IM (e.g. @version) + Persist + 1 + Type + Boolean + Value + 1 + RLVaEnableLegacyNaming Comment @@ -1309,6 +1331,17 @@ Value 1 + RLVaEnableTemporaryAttachments + + Comment + Allows temporary attachments (regardless of origin) to issue RLV commands + Persist + 1 + Type + Boolean + Value + 1 + RLVaExperimentalCommands Comment @@ -1388,17 +1421,6 @@ Value 1 - WarnFirstRLVGiveToRLV - - Comment - Enables FirstRLVGiveToRLV warning dialog - Persist - 1 - Type - Boolean - Value - 1 - DebugSearch @@ -6949,7 +6971,7 @@ InventoryTrashMaxCapacity Comment - Maximum capacity of the Trash folder. User will ve offered to clean it up when exceeded. + Maximum capacity of the Trash folder. User will be offered to clean it up when exceeded. Persist 1 Type @@ -22654,7 +22676,7 @@ Change of this parameter will affect the layout of buttons in notification toast FSFlashOnMessage Comment - Flash/Bounce the app icon when a new message is recieved and Firestorm is not in focus + Flash/Bounce the app icon when a new message is received and Firestorm is not in focus Persist 1 Type @@ -22662,6 +22684,17 @@ Change of this parameter will affect the layout of buttons in notification toast Value 0 + FSFlashOnObjectIM + + Comment + Flash/Bounce the app icon when a new instant message from an object is received and Firestorm is not in focus. + Persist + 1 + Type + Boolean + Value + 1 + FSDisableReturnObjectNotification Comment @@ -23908,17 +23941,6 @@ Change of this parameter will affect the layout of buttons in notification toast SanityComment This value needs to be greater than 0 for a fading effect. - FSFlipCEFY - - Comment - Let CEF internally flip the generated image rather than do it on the GPU. More memory and CPU intensive if enabled. Requires restart. - Persist - 1 - Type - Boolean - Value - 1 - FSStartupClearBrowserCache Comment @@ -24009,18 +24031,7 @@ Change of this parameter will affect the layout of buttons in notification toast Value 0 - FSTagShowTooComplexARW - - Comment - If enabled, the avatar complexity will be shown in the nametag for too complex avatars (Jelly Dolls) - Persist - 1 - Type - Boolean - Value - 1 - - FSTagAlwaysShowARW + FSTagShowARW Comment If enabled, the avatar complexity will be shown in the nametag for every avatar. @@ -24029,8 +24040,52 @@ Change of this parameter will affect the layout of buttons in notification toast Type Boolean Value + 1 + + FSTagShowOwnARW + + Comment + If enabled, the avatar complexity for the own avatar will be shown in the nametag. + Persist + 1 + Type + Boolean + Value 0 + FSTagShowTooComplexOnlyARW + + Comment + If enabled, the avatar complexity will be shown in the nametag only for too complex avatars (Jelly Dolls) + Persist + 1 + Type + Boolean + Value + 1 + + FSLinuxEnableWin32VoiceProxy + + Comment + Use Win32 SLVoice.exe for voice. Needs wine (https://www.winehq.org/) installed, as SLVoice.exe is started inside wine. + Persist + 1 + Type + Boolean + Value + 0 + + FSStatusBarMenuButtonPopupOnRollover + + Comment + Enable rollover popups on top status bar menu icons: Quick Graphics Presets, Volume, and Media. + Persist + 1 + Type + Boolean + Value + 1 + diff --git a/indra/newview/exoflickr.cpp b/indra/newview/exoflickr.cpp index 826c66c951..17ee3244dd 100644 --- a/indra/newview/exoflickr.cpp +++ b/indra/newview/exoflickr.cpp @@ -19,6 +19,7 @@ #include "llviewerprecompiledheaders.h" +#include "fscorehttputil.h" #include "llbufferstream.h" #include "lluri.h" #include "llxmltree.h" diff --git a/indra/newview/exoflickrauth.cpp b/indra/newview/exoflickrauth.cpp index acecfc1f5d..3eff51223a 100644 --- a/indra/newview/exoflickrauth.cpp +++ b/indra/newview/exoflickrauth.cpp @@ -19,6 +19,7 @@ #include "llviewerprecompiledheaders.h" +#include "fscorehttputil.h" #include "llwindow.h" #include "llviewerwindow.h" #include "llbufferstream.h" diff --git a/indra/newview/fsareasearch.cpp b/indra/newview/fsareasearch.cpp index c922de98bc..26e2938e21 100644 --- a/indra/newview/fsareasearch.cpp +++ b/indra/newview/fsareasearch.cpp @@ -1611,7 +1611,11 @@ bool FSPanelAreaSearchList::onContextMenuItemClick(const LLSD& userdata) { LLUUID object_id = (*item_it)->getUUID(); LLViewerObject* objectp = gObjectList.findObject(object_id); - if (objectp) +// if (objectp) +// [RLVa:KB] - Checked: RLVa-2.0.0 | FS-specific + // Don't allow derendering of own attachments when RLVa is enabled + if ( (objectp) && (gAgentID != objectp->getID()) && ((!rlv_handler_t::isEnabled()) || (!objectp->isAttachment()) || (!objectp->permYouOwner())) ) +// [/RLVa:KB] { std::string region_name; LLViewerRegion* region = objectp->getRegion(); diff --git a/indra/newview/fsavatarrenderpersistence.cpp b/indra/newview/fsavatarrenderpersistence.cpp index 1d0b99bf1c..ed80c02e36 100644 --- a/indra/newview/fsavatarrenderpersistence.cpp +++ b/indra/newview/fsavatarrenderpersistence.cpp @@ -29,6 +29,7 @@ #include "fsavatarrenderpersistence.h" #include "llsdserialize.h" + FSAvatarRenderPersistence::FSAvatarRenderPersistence() { } @@ -69,6 +70,8 @@ void FSAvatarRenderPersistence::setAvatarRenderSettings(const LLUUID& avatar_id, { mAvatarRenderMap[avatar_id] = render_settings; } + + mAvatarRenderSettingChangedCallback(avatar_id, render_settings); } void FSAvatarRenderPersistence::loadAvatarRenderSettings() diff --git a/indra/newview/fsavatarrenderpersistence.h b/indra/newview/fsavatarrenderpersistence.h index db893f66fa..469ae85278 100644 --- a/indra/newview/fsavatarrenderpersistence.h +++ b/indra/newview/fsavatarrenderpersistence.h @@ -43,6 +43,15 @@ public: LLVOAvatar::VisualMuteSettings getAvatarRenderSettings(const LLUUID& avatar_id); void setAvatarRenderSettings(const LLUUID& avatar_id, LLVOAvatar::VisualMuteSettings render_settings); + typedef std::map avatar_render_setting_t; + avatar_render_setting_t getAvatarRenderMap() const { return mAvatarRenderMap; } + + typedef boost::signals2::signal render_setting_changed_callback_t; + boost::signals2::connection setAvatarRenderSettingChangedCallback(const render_setting_changed_callback_t::slot_type& cb) + { + return mAvatarRenderSettingChangedCallback.connect(cb); + } + private: FSAvatarRenderPersistence(); virtual ~FSAvatarRenderPersistence(); @@ -50,8 +59,8 @@ private: void loadAvatarRenderSettings(); void saveAvatarRenderSettings(); - typedef std::map avatar_render_setting_t; avatar_render_setting_t mAvatarRenderMap; -}; + render_setting_changed_callback_t mAvatarRenderSettingChangedCallback; +}; #endif // FS_AVATARRENDERPERSISTENCE_H diff --git a/indra/newview/fscommon.cpp b/indra/newview/fscommon.cpp index b29b8590a2..2df3b036a6 100644 --- a/indra/newview/fscommon.cpp +++ b/indra/newview/fscommon.cpp @@ -325,7 +325,7 @@ bool FSCommon::checkIsActionEnabled(const LLUUID& av_id, EFSRegistrarFunctionAct } else if (action == FS_RGSTR_ACT_ZOOM_IN) { - return (!isSelf && LLAvatarActions::canZoomIn(av_id)); + return (!isSelf && !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES) && LLAvatarActions::canZoomIn(av_id)); } else if (action == FS_RGSTR_ACT_OFFER_TELEPORT) { diff --git a/indra/newview/fscommon.h b/indra/newview/fscommon.h index 7dbee113ab..50752931b1 100644 --- a/indra/newview/fscommon.h +++ b/indra/newview/fscommon.h @@ -33,7 +33,7 @@ class LLAvatarName; class LLViewerObject; -const F32 AVATAR_UNKNOWN_Z_OFFSET = -1.f; // Const value for avatars at unknown height +const F64 AVATAR_UNKNOWN_Z_OFFSET = -1.0; // Const value for avatars at unknown height const F32 AVATAR_UNKNOWN_RANGE = -1.f; void report_to_nearby_chat(const std::string& message); diff --git a/indra/newview/fsdata.cpp b/indra/newview/fsdata.cpp index db0a7d033a..27f4031256 100644 --- a/indra/newview/fsdata.cpp +++ b/indra/newview/fsdata.cpp @@ -32,6 +32,7 @@ #include "fsdata.h" #include "fscommon.h" +#include "fscorehttputil.h" #include "fswsassetblacklist.h" /* boost: will not compile unless equivalent is undef'd, beware. */ @@ -56,6 +57,11 @@ #include "llvfs.h" #include "message.h" +// [RLVa:KB] +#include "rlvactions.h" +#include "rlvhelper.h" +// [/RLVa:KB] + const std::string LEGACY_CLIENT_LIST_URL = "http://phoenixviewer.com/app/client_tags/client_list_v2.xml"; const LLUUID MAGIC_ID("3c115e51-04f4-523c-9fa6-98aff1034730"); const F32 HTTP_TIMEOUT = 30.f; @@ -443,6 +449,13 @@ void FSData::processData(const LLSD& fs_data) { updateClientTagsLocal(); } + +// [RLVa:KB] + if ( (RlvActions::isRlvEnabled()) && (fs_data.has("rlva_compat_list")) ) + { + RlvSettings::initCompatibilityMode(fs_data["rlva_compat_list"].asString()); + } +// [/RLVa:KB] } void FSData::processAssets(const LLSD& assets) diff --git a/indra/newview/fsfloateravatarrendersettings.cpp b/indra/newview/fsfloateravatarrendersettings.cpp new file mode 100644 index 0000000000..85aeaef0fb --- /dev/null +++ b/indra/newview/fsfloateravatarrendersettings.cpp @@ -0,0 +1,150 @@ +/** + * @file fsfloateravatarrendersettings.cpp + * @brief Floater for showing persisted avatar render settings + * + * $LicenseInfo:firstyear=2016&license=fsviewerlgpl$ + * Phoenix Firestorm Viewer Source Code + * Copyright (C) 2016, Ansariel Hiller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA + * http://www.firestormviewer.org + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "fsfloateravatarrendersettings.h" + +#include "llnamelistctrl.h" +#include "lltrans.h" +#include "llviewercontrol.h" +#include "llviewerobjectlist.h" +#include "llvoavatar.h" + + +FSFloaterAvatarRenderSettings::FSFloaterAvatarRenderSettings(const LLSD& key) + : LLFloater(key), + mAvatarList(NULL), + mRenderSettingChangedCallbackConnection() +{ +} + +FSFloaterAvatarRenderSettings::~FSFloaterAvatarRenderSettings() +{ + if (mRenderSettingChangedCallbackConnection.connected()) + { + mRenderSettingChangedCallbackConnection.disconnect(); + } +} + + +void FSFloaterAvatarRenderSettings::addElementToList(const LLUUID& avatar_id, LLVOAvatar::VisualMuteSettings render_setting) +{ + static const std::string av_render_never = getString("av_render_never"); + static const std::string av_render_always = getString("av_render_always"); + static const std::string av_name_waiting = LLTrans::getString("AvatarNameWaiting"); + + LLNameListCtrl::NameItem item_params; + item_params.value = avatar_id; + item_params.target = LLNameListCtrl::INDIVIDUAL; + + item_params.columns.add().column("name"); + item_params.name = av_name_waiting; + + std::string render_value = (render_setting == LLVOAvatar::AV_DO_NOT_RENDER ? av_render_never : av_render_always); + item_params.columns.add().value(render_value).column("render_setting"); + + mAvatarList->addNameItemRow(item_params); +} + +BOOL FSFloaterAvatarRenderSettings::postBuild() +{ + mAvatarList = getChild("avatar_list"); + mAvatarList->setContextMenu(&FSFloaterAvatarRenderPersistenceMenu::gFSAvatarRenderPersistenceMenu); + + childSetAction("close_btn", boost::bind(&FSFloaterAvatarRenderSettings::onCloseBtn, this)); + + mRenderSettingChangedCallbackConnection = FSAvatarRenderPersistence::instance().setAvatarRenderSettingChangedCallback(boost::bind(&FSFloaterAvatarRenderSettings::onAvatarRenderSettingChanged, this, _1, _2)); + + loadInitialList(); + + return TRUE; +} + +void FSFloaterAvatarRenderSettings::onCloseBtn() +{ + closeFloater(); +} + +void FSFloaterAvatarRenderSettings::loadInitialList() +{ + FSAvatarRenderPersistence::avatar_render_setting_t avatar_render_map = FSAvatarRenderPersistence::instance().getAvatarRenderMap(); + for (FSAvatarRenderPersistence::avatar_render_setting_t::iterator it = avatar_render_map.begin(); it != avatar_render_map.end(); ++it) + { + addElementToList(it->first, it->second); + } +} + +void FSFloaterAvatarRenderSettings::onAvatarRenderSettingChanged(const LLUUID& avatar_id, LLVOAvatar::VisualMuteSettings render_setting) +{ + mAvatarList->removeNameItem(avatar_id); + if (render_setting != LLVOAvatar::AV_RENDER_NORMALLY) + { + addElementToList(avatar_id, render_setting); + } +} + + +namespace FSFloaterAvatarRenderPersistenceMenu +{ + + FSAvatarRenderPersistenceMenu gFSAvatarRenderPersistenceMenu; + + LLContextMenu* FSAvatarRenderPersistenceMenu::createMenu() + { + // set up the callbacks for all of the avatar menu items + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + + registrar.add("Avatar.ChangeRenderSetting", boost::bind(&FSAvatarRenderPersistenceMenu::changeRenderSetting, this, _2)); + + // create the context menu from the XUI + return createFromFile("menu_fs_avatar_render_setting.xml"); + } + + void FSAvatarRenderPersistenceMenu::changeRenderSetting(const LLSD& param) + { + LLVOAvatar::VisualMuteSettings render_setting = (LLVOAvatar::VisualMuteSettings)param.asInteger(); + + for (uuid_vec_t::iterator it = mUUIDs.begin(); it != mUUIDs.end(); ++it) + { + LLUUID avatar_id = *it; + + LLVOAvatar* avatar = dynamic_cast(gObjectList.findObject(avatar_id)); + if (avatar) + { + // Set setting via the LLVOAvatar instance if it's available; will also call FSAvatarRenderPersistence::setAvatarRenderSettings() + avatar->setVisualMuteSettings(render_setting); + } + else + { + FSAvatarRenderPersistence::instance().setAvatarRenderSettings(avatar_id, render_setting); + } + } + + LLVOAvatar::cullAvatarsByPixelArea(); + } +} diff --git a/indra/newview/fsfloateravatarrendersettings.h b/indra/newview/fsfloateravatarrendersettings.h new file mode 100644 index 0000000000..ec5f302f0c --- /dev/null +++ b/indra/newview/fsfloateravatarrendersettings.h @@ -0,0 +1,76 @@ +/** + * @file fsfloateravatarrendersettings.h + * @brief Floater for showing persisted avatar render settings + * + * $LicenseInfo:firstyear=2016&license=fsviewerlgpl$ + * Phoenix Firestorm Viewer Source Code + * Copyright (C) 2016, Ansariel Hiller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA + * http://www.firestormviewer.org + * $/LicenseInfo$ + */ + +#ifndef FS_FLOATERAVATARRENDERSETTINGS_H +#define FS_FLOATERAVATARRENDERSETTINGS_H + +#include "fsavatarrenderpersistence.h" +#include "llfloater.h" +#include "lllistcontextmenu.h" +#include "llvoavatar.h" + +class LLNameListCtrl; + +class FSFloaterAvatarRenderSettings : public LLFloater +{ + LOG_CLASS(FSFloaterAvatarRenderSettings); +public: + FSFloaterAvatarRenderSettings(const LLSD& key); + virtual ~FSFloaterAvatarRenderSettings(); + + /*virtual*/ BOOL postBuild(); + +private: + void onCloseBtn(); + void onAvatarRenderSettingChanged(const LLUUID& avatar_id, LLVOAvatar::VisualMuteSettings render_setting); + + void loadInitialList(); + void addElementToList(const LLUUID& avatar_id, LLVOAvatar::VisualMuteSettings render_setting); + + LLNameListCtrl* mAvatarList; + + boost::signals2::connection mRenderSettingChangedCallbackConnection; +}; + + + +namespace FSFloaterAvatarRenderPersistenceMenu +{ + +class FSAvatarRenderPersistenceMenu : public LLListContextMenu +{ +public: + /*virtual*/ LLContextMenu* createMenu(); +private: + void changeRenderSetting(const LLSD& param); +}; + +extern FSAvatarRenderPersistenceMenu gFSAvatarRenderPersistenceMenu; + +} // namespace FSFloaterAvatarRenderPersistenceMenu + +#endif // FS_FLOATERAVATARRENDERSETTINGS_H diff --git a/indra/newview/fsfloaterim.cpp b/indra/newview/fsfloaterim.cpp index b51852f42a..7e78c1dea4 100644 --- a/indra/newview/fsfloaterim.cpp +++ b/indra/newview/fsfloaterim.cpp @@ -2068,21 +2068,18 @@ void FSFloaterIM::sRemoveTypingIndicator(const LLSD& data) floater->removeTypingIndicator(); } -void FSFloaterIM::onNewIMReceived( const LLUUID& session_id ) +void FSFloaterIM::onNewIMReceived(const LLUUID& session_id) { - if (isChatMultiTab()) { - FSFloaterIMContainer* im_box = FSFloaterIMContainer::getInstance(); - if (!im_box) return; - - if (FSFloaterIM::findInstance(session_id)) return; + if (FSFloaterIM::findInstance(session_id)) + { + return; + } FSFloaterIM* new_tab = FSFloaterIM::getInstance(session_id); - - im_box->addFloater(new_tab, FALSE, LLTabContainer::END); + FSFloaterIMContainer::getInstance()->addNewSession(new_tab); } - } void FSFloaterIM::onClickCloseBtn(bool app_quitting) @@ -2362,6 +2359,9 @@ void FSFloaterIM::handleMinimized(bool minimized) else { gConsole->addSession(mSessionID); - updateMessages(); + if (mChatHistory) + { + updateMessages(); + } } } diff --git a/indra/newview/fsfloaterimcontainer.cpp b/indra/newview/fsfloaterimcontainer.cpp index 99de89ce32..b9c81f5fcf 100644 --- a/indra/newview/fsfloaterimcontainer.cpp +++ b/indra/newview/fsfloaterimcontainer.cpp @@ -49,7 +49,8 @@ FSFloaterIMContainer::FSFloaterIMContainer(const LLSD& seed) : LLMultiFloater(seed), mActiveVoiceFloater(NULL), mCurrentVoiceState(VOICE_STATE_NONE), - mForceVoiceStateUpdate(false) + mForceVoiceStateUpdate(false), + mIsAddingNewSession(false) { mAutoResize = FALSE; LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this); @@ -233,31 +234,34 @@ void FSFloaterIMContainer::addFloater(LLFloater* floaterp, { // [SL:KB] - Patch: UI-TabRearrange | Checked: 2012-06-22 (Catznip-3.3.0) // If we're redocking a torn off IM floater, return it back to its previous place - if ( (floaterp->isTornOff()) && (LLTabContainer::END == insertion_point) ) + if (!mIsAddingNewSession && (floaterp->isTornOff()) && (LLTabContainer::END == insertion_point) ) { LLChicletPanel* pChicletPanel = LLChicletBar::instance().getChicletPanel(); LLIMChiclet* pChiclet = pChicletPanel->findChiclet(floaterp->getKey()); - S32 idxChiclet = pChicletPanel->getChicletIndex(pChiclet); - if ( (idxChiclet > 0) && (idxChiclet < pChicletPanel->getChicletCount()) ) + if (pChiclet) { - // Look for the first IM session to the left of this one - while (--idxChiclet >= 0) + S32 idxChiclet = pChicletPanel->getChicletIndex(pChiclet); + if ((idxChiclet > 0) && (idxChiclet < pChicletPanel->getChicletCount())) { - if (pChiclet = dynamic_cast(pChicletPanel->getChiclet(idxChiclet))) + // Look for the first IM session to the left of this one + while (--idxChiclet >= 0) { - FSFloaterIM* pFloater = FSFloaterIM::findInstance(pChiclet->getSessionId()); - if (pFloater) + if (pChiclet = dynamic_cast(pChicletPanel->getChiclet(idxChiclet))) { - insertion_point = (LLTabContainer::eInsertionPoint)(mTabContainer->getIndexForPanel(pFloater) + 1); - break; + FSFloaterIM* pFloater = FSFloaterIM::findInstance(pChiclet->getSessionId()); + if (pFloater) + { + insertion_point = (LLTabContainer::eInsertionPoint)(mTabContainer->getIndexForPanel(pFloater) + 1); + break; + } } } } - } - else - { - insertion_point = (0 == idxChiclet) ? LLTabContainer::START : LLTabContainer::END; + else + { + insertion_point = (0 == idxChiclet) ? LLTabContainer::START : LLTabContainer::END; + } } } // [/SL:KB] @@ -270,6 +274,14 @@ void FSFloaterIMContainer::addFloater(LLFloater* floaterp, floaterp->mCloseSignal.connect(boost::bind(&FSFloaterIMContainer::onCloseFloater, this, session_id)); } +void FSFloaterIMContainer::addNewSession(LLFloater* floaterp) +{ + // Make sure we don't do some strange re-arranging if we add a new IM floater due to a new session + mIsAddingNewSession = true; + addFloater(floaterp, FALSE, LLTabContainer::END); + mIsAddingNewSession = false; +} + // [SL:KB] - Patch: Chat-NearbyChatBar | Checked: 2011-12-11 (Catznip-3.2.0d) | Added: Catznip-3.2.0d void FSFloaterIMContainer::removeFloater(LLFloater* floaterp) { diff --git a/indra/newview/fsfloaterimcontainer.h b/indra/newview/fsfloaterimcontainer.h index 608d66c06a..4d11da1993 100644 --- a/indra/newview/fsfloaterimcontainer.h +++ b/indra/newview/fsfloaterimcontainer.h @@ -55,6 +55,8 @@ public: // [/SL:KB] bool hasFloater(LLFloater* floaterp); + void addNewSession(LLFloater* floaterp); + static FSFloaterIMContainer* findInstance(); static FSFloaterIMContainer* getInstance(); @@ -99,6 +101,8 @@ private: void checkFlashing(); uuid_vec_t mFlashingSessions; + bool mIsAddingNewSession; + // [SL:KB] - Patch: UI-TabRearrange | Checked: 2012-05-05 (Catznip-3.3.0) protected: void onIMTabRearrange(S32 tab_index, LLPanel* tab_panel); diff --git a/indra/newview/fsfloatersearch.cpp b/indra/newview/fsfloatersearch.cpp index 9d06a5c81a..8804edbe4a 100644 --- a/indra/newview/fsfloatersearch.cpp +++ b/indra/newview/fsfloatersearch.cpp @@ -1968,13 +1968,13 @@ BOOL FSPanelSearchClassifieds::postBuild() if (mClassifiedsCategory) { LLClassifiedInfo::cat_map::iterator iter; - mClassifiedsCategory->add(LLTrans::getString("all_categories"), LLSD("any")); + mClassifiedsCategory->add(LLTrans::getString("all_categories"), LLSD(0)); mClassifiedsCategory->addSeparator(); for (iter = LLClassifiedInfo::sCategories.begin(); iter != LLClassifiedInfo::sCategories.end(); iter++) { - mClassifiedsCategory->add(LLTrans::getString(iter->second)); + mClassifiedsCategory->add(LLTrans::getString(iter->second), LLSD((S32)iter->first)); } } childSetAction("classifieds_next", boost::bind(&FSPanelSearchClassifieds::onBtnNext, this)); @@ -2008,7 +2008,7 @@ void FSPanelSearchClassifieds::find() LLNotificationsUtil::add("NoContentToSearch"); return; } - U32 category = childGetValue("classifieds_category").asInteger(); + U32 category = mClassifiedsCategory->getValue().asInteger(); BOOL auto_renew = FALSE; U32 flags = pack_classified_flags_request(auto_renew, inc_pg, inc_mature, inc_adult); diff --git a/indra/newview/fsfloatervoicecontrols.cpp b/indra/newview/fsfloatervoicecontrols.cpp index bd6ecf230b..566d44f5b1 100644 --- a/indra/newview/fsfloatervoicecontrols.cpp +++ b/indra/newview/fsfloatervoicecontrols.cpp @@ -54,6 +54,8 @@ #include "llfirstuse.h" #include "llsliderctrl.h" +#include "lltextbox.h" +#include "rlvcommon.h" static void get_voice_participants_uuids(uuid_vec_t& speakers_uuids); void reshape_floater(FSFloaterVoiceControls* floater, S32 delta_height); @@ -112,6 +114,7 @@ FSFloaterVoiceControls::FSFloaterVoiceControls(const LLSD& key) , mInitParticipantsVoiceState(false) , mVolumeSlider(NULL) , mMuteButton(NULL) +, mIsRlvShowNearbyRestricted(false) { static LLUICachedControl voice_left_remove_delay ("VoiceParticipantLeftRemoveDelay", 10); mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&FSFloaterVoiceControls::removeVoiceLeftParticipant, this, _1), voice_left_remove_delay); @@ -158,6 +161,9 @@ BOOL FSFloaterVoiceControls::postBuild() mVolumeSlider = findChild("volume_slider"); mMuteButton = findChild("mute_btn"); + mRlvRestrictedText = getChild("rlv_restricted"); + mRlvRestrictedText->setText(RlvStrings::getString("blocked_nearby")); + if (mVolumeSlider && mMuteButton) { mAvatarList->setCommitCallback(boost::bind(&FSFloaterVoiceControls::onParticipantSelected, this)); @@ -350,8 +356,10 @@ void FSFloaterVoiceControls::refreshParticipantList() mNonAvatarCaller->setName(session->mName); } - mNonAvatarCaller->setVisible(non_avatar_caller); - mAvatarList->setVisible(!non_avatar_caller); + // Ansariel: Changed for RLVa @shownearby + //mNonAvatarCaller->setVisible(non_avatar_caller); + //mAvatarList->setVisible(!non_avatar_caller); + updateListVisibility(); if (!non_avatar_caller) { @@ -885,10 +893,45 @@ void FSFloaterVoiceControls::reset(const LLVoiceChannel::EState& new_state) mAvatarList->setNoItemsCommentText(LLTrans::getString("LoadingData")); } - mAvatarList->setVisible(TRUE); - mNonAvatarCaller->setVisible(FALSE); + // Ansariel: Changed for RLVa @shownearby + //mAvatarList->setVisible(TRUE); + //mNonAvatarCaller->setVisible(FALSE); + updateListVisibility(); mSpeakerManager = NULL; } +void FSFloaterVoiceControls::toggleRlvShowNearbyRestriction(bool restricted) +{ + mIsRlvShowNearbyRestricted = restricted; + updateListVisibility(); +} + +void FSFloaterVoiceControls::updateListVisibility() +{ + if (mIsRlvShowNearbyRestricted && mVoiceType == VC_LOCAL_CHAT) + { + mAvatarList->setVisible(FALSE); + mNonAvatarCaller->setVisible(FALSE); + mRlvRestrictedText->setVisible(TRUE); + } + else + { + mRlvRestrictedText->setVisible(FALSE); + + if (mParticipants) + { + // Case coming from refreshParticipantList + bool non_avatar_caller = VC_PEER_TO_PEER_AVALINE == mVoiceType; + mNonAvatarCaller->setVisible(non_avatar_caller); + mAvatarList->setVisible(!non_avatar_caller); + } + else + { + // Case coming from reset() + mAvatarList->setVisible(TRUE); + mNonAvatarCaller->setVisible(FALSE); + } + } +} //EOF diff --git a/indra/newview/fsfloatervoicecontrols.h b/indra/newview/fsfloatervoicecontrols.h index 5df12f4b2a..c8b9359253 100644 --- a/indra/newview/fsfloatervoicecontrols.h +++ b/indra/newview/fsfloatervoicecontrols.h @@ -43,6 +43,7 @@ class LLOutputMonitorCtrl; class LLSpeakerMgr; class LLSpeakersDelayActionsStorage; class LLSliderCtrl; +class LLTextBox; /** * The Voice Control Panel is an ambient window summoned by clicking the flyout chevron @@ -82,6 +83,8 @@ public: LLAvatarList* getAvatarCallerList() { return mAvatarList; } // [/RLVa:KB] + void toggleRlvShowNearbyRestriction(bool restricted); + private: typedef enum e_voice_controls_type { @@ -248,6 +251,8 @@ private: */ void reset(const LLVoiceChannel::EState& new_state); + void updateListVisibility(); + private: speaker_state_map_t mSpeakerStateMap; LLSpeakerMgr* mSpeakerManager; @@ -258,10 +263,12 @@ private: LLPanel* mAgentPanel; LLOutputMonitorCtrl* mSpeakingIndicator; bool mIsModeratorMutedVoice; + bool mIsRlvShowNearbyRestricted; LLUUID mSelectedParticipant; LLSliderCtrl* mVolumeSlider; LLButton* mMuteButton; + LLTextBox* mRlvRestrictedText; /** * Flag indicated that participants voice states should be initialized. diff --git a/indra/newview/fsgridhandler.cpp b/indra/newview/fsgridhandler.cpp index 482e29ff47..efb0bc3c96 100644 --- a/indra/newview/fsgridhandler.cpp +++ b/indra/newview/fsgridhandler.cpp @@ -47,7 +47,7 @@ #endif #include "llstartup.h" -#include "llcorehttputil.h" +#include "fscorehttputil.h" void downloadError( LLSD const &aData, LLGridManager* mOwner, GridEntry* mData, LLGridManager::AddState mState ) { diff --git a/indra/newview/fspanelradar.cpp b/indra/newview/fspanelradar.cpp index d77d813c51..aede0032b2 100644 --- a/indra/newview/fspanelradar.cpp +++ b/indra/newview/fspanelradar.cpp @@ -42,6 +42,7 @@ #include "llpanelblockedlist.h" #include "llviewercontrol.h" // for gSavedSettings #include "llviewermenu.h" // for gMenuHolder +#include "rlvactions.h" #include "rlvhandler.h" @@ -321,6 +322,11 @@ void FSPanelRadar::updateList(const std::vector& entries, const LLSD& stat S32 lastScroll = mRadarList->getScrollPos(); // Update list + mRadarList->setCommentText(RlvActions::canShowNearbyAgents() ? LLStringUtil::null : RlvStrings::getString("blocked_nearby")); + + bool needs_sort = mRadarList->isSorted(); + mRadarList->setNeedsSort(false); + mRadarList->clearRows(); const std::vector::const_iterator it_end = entries.end(); for (std::vector::const_iterator it = entries.begin(); it != it_end; ++it) @@ -408,6 +414,9 @@ void FSPanelRadar::updateList(const std::vector& entries, const LLSD& stat } } + mRadarList->setNeedsSort(needs_sort); + mRadarList->updateSort(); + LLStringUtil::format_map_t name_count_args; name_count_args["[TOTAL]"] = stats["total"].asString(); name_count_args["[IN_REGION]"] = stats["region"].asString(); diff --git a/indra/newview/fsradar.cpp b/indra/newview/fsradar.cpp index f409b64a63..80dc23d22b 100644 --- a/indra/newview/fsradar.cpp +++ b/indra/newview/fsradar.cpp @@ -55,8 +55,9 @@ #include "llvoiceclient.h" #include "llworld.h" #include "llspeakers.h" -#include "rlvhandler.h" #include "llviewerregion.h" +#include "rlvactions.h" +#include "rlvhandler.h" using namespace boost; @@ -228,14 +229,16 @@ void FSRadar::updateRadarList() //STEP 1: Update our basic data model: detect Avatars & Positions in our defined range std::vector positions; uuid_vec_t avatar_ids; - std::map region_assignments; - if (sLimitRange) + if (RlvActions::canShowNearbyAgents()) { - world->getAvatars(&avatar_ids, &positions, gAgent.getPositionGlobal(), sNearMeRange, ®ion_assignments); - } - else - { - world->getAvatars(&avatar_ids, &positions, LLVector3d(), FLT_MAX, ®ion_assignments); + if (sLimitRange) + { + world->getAvatars(&avatar_ids, &positions, gAgent.getPositionGlobal(), sNearMeRange); + } + else + { + world->getAvatars(&avatar_ids, &positions); + } } // Determine lists of new added and removed avatars @@ -298,13 +301,7 @@ void FSRadar::updateRadarList() // Skip modelling this avatar if its basic data is either inaccessible, or it's a dummy placeholder FSRadarEntry* ent = getEntry(avId); - LLViewerRegion* reg = world->getRegionFromID(region_assignments[avId]); - if (!reg) - { - // Fallback in case we somehow didn't get the region via ID - LL_DEBUGS() << "Couldn't retrieve region by ID - falling back to region from global position" << LL_ENDL; - reg = world->getRegionFromPosGlobal(avPos); - } + LLViewerRegion* reg = world->getRegionFromPosGlobal(avPos); if (!ent) // don't update this radar listing if data is inaccessible { continue; @@ -680,33 +677,35 @@ void FSRadar::updateRadarList() //3b: process alerts for avatars that where here last frame, but gone this frame (ie, they left) // as well as dispatch all earlier detected alerts for crossing range thresholds. // - - radarfields_map_t::iterator rf_it_end = mLastRadarSweep.end(); - for (radarfields_map_t::iterator i = mLastRadarSweep.begin(); i != rf_it_end; ++i) + if (RlvActions::canShowNearbyAgents()) { - LLUUID prevId = i->first; - RadarFields rf = i->second; - if ((sFSRadarShowMutedAndDerendered || !rf.lastIgnore) && mEntryList.find(prevId) == mEntryList.end()) + radarfields_map_t::iterator rf_it_end = mLastRadarSweep.end(); + for (radarfields_map_t::iterator i = mLastRadarSweep.begin(); i != rf_it_end; ++i) { - if (sRadarReportChatRangeLeave && (rf.lastDistance <= chat_range_say) && rf.lastDistance > AVATAR_UNKNOWN_RANGE) + LLUUID prevId = i->first; + RadarFields rf = i->second; + if ((sFSRadarShowMutedAndDerendered || !rf.lastIgnore) && mEntryList.find(prevId) == mEntryList.end()) { - make_ui_sound("UISndRadarChatLeave"); // FIRE-6069: Radar alerts sounds - LLAvatarNameCache::get(prevId, boost::bind(&FSRadar::radarAlertMsg, this, _1, _2, str_chat_leaving)); - } - if (sRadarReportDrawRangeLeave && (rf.lastDistance <= drawRadius) && rf.lastDistance > AVATAR_UNKNOWN_RANGE) - { - make_ui_sound("UISndRadarDrawLeave"); // FIRE-6069: Radar alerts sounds - LLAvatarNameCache::get(prevId, boost::bind(&FSRadar::radarAlertMsg, this, _1, _2, str_draw_distance_leaving)); - } - if (sRadarReportSimRangeLeave && (rf.lastRegion == regionSelf || rf.lastRegion.isNull())) - { - make_ui_sound("UISndRadarSimLeave"); // FIRE-6069: Radar alerts sounds - LLAvatarNameCache::get(prevId, boost::bind(&FSRadar::radarAlertMsg, this, _1, _2, str_region_leaving)); - } - - if (sRadarLeaveChannelAlert) - { - mRadarLeaveAlerts.push_back(prevId); + if (sRadarReportChatRangeLeave && (rf.lastDistance <= chat_range_say) && rf.lastDistance > AVATAR_UNKNOWN_RANGE) + { + make_ui_sound("UISndRadarChatLeave"); // FIRE-6069: Radar alerts sounds + LLAvatarNameCache::get(prevId, boost::bind(&FSRadar::radarAlertMsg, this, _1, _2, str_chat_leaving)); + } + if (sRadarReportDrawRangeLeave && (rf.lastDistance <= drawRadius) && rf.lastDistance > AVATAR_UNKNOWN_RANGE) + { + make_ui_sound("UISndRadarDrawLeave"); // FIRE-6069: Radar alerts sounds + LLAvatarNameCache::get(prevId, boost::bind(&FSRadar::radarAlertMsg, this, _1, _2, str_draw_distance_leaving)); + } + if (sRadarReportSimRangeLeave && (rf.lastRegion == regionSelf || rf.lastRegion.isNull())) + { + make_ui_sound("UISndRadarSimLeave"); // FIRE-6069: Radar alerts sounds + LLAvatarNameCache::get(prevId, boost::bind(&FSRadar::radarAlertMsg, this, _1, _2, str_region_leaving)); + } + + if (sRadarLeaveChannelAlert) + { + mRadarLeaveAlerts.push_back(prevId); + } } } } @@ -789,7 +788,15 @@ void FSRadar::updateRadarList() RadarFields rf; rf.lastDistance = ent->mRange; rf.lastIgnore = ent->mIgnore; - rf.lastRegion = ent->getRegion(); + rf.lastRegion = LLUUID::null; + if (ent->mGlobalPos != LLVector3d(0.0, 0.0, 0.0)) + { + LLViewerRegion* lastRegion = world->getRegionFromPosGlobal(ent->mGlobalPos); + if (lastRegion) + { + rf.lastRegion = lastRegion->getRegionID(); + } + } mLastRadarSweep[ent->mID] = rf; } @@ -797,10 +804,18 @@ void FSRadar::updateRadarList() // //STEP 5: Final data updates and notification of subscribers // - - mAvatarStats["total"] = llformat("%d", mLastRadarSweep.size() - 1); - mAvatarStats["region"] = llformat("%d", inSameRegion); - mAvatarStats["chatrange"] = llformat("%d", inChatRange); + if (RlvActions::canShowNearbyAgents()) + { + mAvatarStats["total"] = llformat("%d", mLastRadarSweep.size() - 1); + mAvatarStats["region"] = llformat("%d", inSameRegion); + mAvatarStats["chatrange"] = llformat("%d", inChatRange); + } + else + { + mAvatarStats["total"] = "-"; + mAvatarStats["region"] = "-"; + mAvatarStats["chatrange"] = "-"; + } checkTracking(); diff --git a/indra/newview/fsradarentry.cpp b/indra/newview/fsradarentry.cpp index 1b1e49c7e3..a681fcb032 100644 --- a/indra/newview/fsradarentry.cpp +++ b/indra/newview/fsradarentry.cpp @@ -42,7 +42,7 @@ FSRadarEntry::FSRadarEntry(const LLUUID& avid) mDisplayName(LLStringUtil::null), mRange(0.f), mFirstSeen(time(NULL)), - mGlobalPos(LLVector3d(0.0f,0.0f,0.0f)), + mGlobalPos(LLVector3d(0.0, 0.0, 0.0)), mRegion(LLUUID::null), mStatus(0), mZOffset(0.f), diff --git a/indra/newview/installers/windows_x64/llplugin.wxs b/indra/newview/installers/windows_x64/llplugin.wxs index bd26c38240..eb90517d1e 100644 --- a/indra/newview/installers/windows_x64/llplugin.wxs +++ b/indra/newview/installers/windows_x64/llplugin.wxs @@ -22,7 +22,8 @@ - + + diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 13bed50f4d..78660f7c91 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -2082,7 +2082,7 @@ bool LLAgentCamera::clampCameraPosition(LLVector3d& posCamGlobal, const LLVector m_fRlvMinDist = true; } - if (!isnan(nDistMult)) + if (!llisnan(nDistMult)) { posCamGlobal = posCamRefGlobal + nDistMult * offsetCamera; m_posRlvRefGlobal = posCamRefGlobal; diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index cd4461f4cd..72482cbe66 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -62,6 +62,7 @@ #include "llavatarpropertiesprocessor.h" // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1) +#include "rlvactions.h" #include "rlvhandler.h" #include "rlvhelper.h" #include "rlvlocks.h" @@ -1911,6 +1912,13 @@ bool LLAppearanceMgr::getCanRemoveFromCOF(const LLUUID& outfit_cat_id) { return false; } +// [RLVa:KB] - Checked: RLVa-2.0.3 + if ( (RlvActions::isRlvEnabled()) && (RlvFolderLocks::instance().isLockedFolder(outfit_cat_id, RLV_LOCK_REMOVE)) ) + { + return false; + } +// [/RLVa:KB] + LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; LLFindWearablesEx is_worn(/*is_worn=*/ true, /*include_body_parts=*/ false); @@ -1930,6 +1938,13 @@ bool LLAppearanceMgr::getCanAddToCOF(const LLUUID& outfit_cat_id) return false; } +// [RLVa:KB] - Checked: RLVa-2.0.3 + if ( (RlvActions::isRlvEnabled()) && (RlvFolderLocks::instance().isLockedFolder(outfit_cat_id, RLV_LOCK_ADD)) ) + { + return false; + } +// [/RLVa:KB] + LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false); @@ -1950,6 +1965,14 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id) return false; } +// [RLVa:KB] - Checked: RLVa-2.0.3 + // Block "Replace Current Outfit" if the user can't wear the new folder + if ( (RlvActions::isRlvEnabled()) && (RlvFolderLocks::instance().isLockedFolder(outfit_cat_id, RLV_LOCK_ADD)) ) + { + return false; + } +// [/RLVa:KB] + // Check whether it's the base outfit. // if (outfit_cat_id.isNull() || outfit_cat_id == getBaseOutfitUUID()) // [SL:KB] - Patch: Appearance-Misc | Checked: 2010-09-21 (Catznip-2.1) @@ -1959,17 +1982,20 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id) return false; } +// FIRE-11920: Always allow replacing outfit // Check whether the outfit contains any wearables we aren't wearing already (STORM-702). - LLInventoryModel::cat_array_t cats; - LLInventoryModel::item_array_t items; - LLFindWearablesEx is_worn(/*is_worn=*/ false, /*include_body_parts=*/ true); - gInventory.collectDescendentsIf(outfit_cat_id, - cats, - items, - LLInventoryModel::EXCLUDE_TRASH, - is_worn); +// LLInventoryModel::cat_array_t cats; +// LLInventoryModel::item_array_t items; +// LLFindWearablesEx is_worn(/*is_worn=*/ false, /*include_body_parts=*/ true); +// gInventory.collectDescendentsIf(outfit_cat_id, +// cats, +// items, +// LLInventoryModel::EXCLUDE_TRASH, +// is_worn); - return items.size() > 0; +// return items.size() > 0; + return TRUE; +// FIRE-11920: Always allow replacing outfit } // Moved from LLWearableList::ContextMenu for wider utility. @@ -2142,9 +2168,9 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, LLInventoryModel::item_array_t body_items; getDescendentsOfAssetType(cof, body_items, LLAssetType::AT_BODYPART); // getDescendentsOfAssetType(category, body_items, LLAssetType::AT_BODYPART); -// [RLVa:KB] - Checked: 2010-03-19 (RLVa-1.2.0) +// [RLVa:KB] - Checked: RLVa-2.0.3 // Filter out any new body parts that can't be worn before adding them - if ( (rlv_handler_t::isEnabled()) && (gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) ) + if ( (RlvActions::isRlvEnabled()) && ((gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) || (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ADD))) ) body_items_new.erase(std::remove_if(body_items_new.begin(), body_items_new.end(), RlvPredCanNotWearItem(RLV_WEAR_REPLACE)), body_items_new.end()); body_items.insert(body_items.end(), body_items_new.begin(), body_items_new.end()); // [/RLVa:KB] @@ -2159,8 +2185,8 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, LLInventoryModel::item_array_t wear_items; if (append) getDescendentsOfAssetType(cof, wear_items, LLAssetType::AT_CLOTHING); -// [RLVa:KB] - Checked: 2010-03-19 (RLVa-1.2.0) - else if ( (rlv_handler_t::isEnabled()) && (gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) ) +// [RLVa:KB] - Checked: RLVa-2.0.3 + else if ( (RlvActions::isRlvEnabled()) && ((gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) || (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_REMOVE))) ) { // Make sure that all currently locked clothing layers remain in COF when replacing getDescendentsOfAssetType(cof, wear_items, LLAssetType::AT_CLOTHING); @@ -2168,9 +2194,9 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, } // [/RLVa:KB] // getDescendentsOfAssetType(category, wear_items, LLAssetType::AT_CLOTHING); -// [RLVa:KB] - Checked: 2010-03-19 (RLVa-1.2.0) +// [RLVa:KB] - Checked: RLVa-2.0.3 // Filter out any new wearables that can't be worn before adding them - if ( (rlv_handler_t::isEnabled()) && (gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) ) + if ( (RlvActions::isRlvEnabled()) && ((gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) || (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ADD))) ) wear_items_new.erase(std::remove_if(wear_items_new.begin(), wear_items_new.end(), RlvPredCanNotWearItem(RLV_WEAR)), wear_items_new.end()); wear_items.insert(wear_items.end(), wear_items_new.begin(), wear_items_new.end()); // [/RLVa:KB] @@ -2185,8 +2211,8 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, LLInventoryModel::item_array_t obj_items; if (append) getDescendentsOfAssetType(cof, obj_items, LLAssetType::AT_OBJECT); -// [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0z) | Modified: RLVa-1.2.0b - else if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) ) +// [RLVa:KB] - Checked: RLVa-2.0.3 + else if ( (RlvActions::isRlvEnabled()) && ((gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) || (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_REMOVE))) ) { // Make sure that all currently locked attachments remain in COF when replacing getDescendentsOfAssetType(cof, obj_items, LLAssetType::AT_OBJECT); @@ -2194,9 +2220,9 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, } // [/RLVa:KB] // getDescendentsOfAssetType(category, obj_items, LLAssetType::AT_OBJECT); -// [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0) +// [RLVa:KB] - Checked: RLVa-2.0.3 // Filter out any new attachments that can't be worn before adding them - if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) ) + if ( (RlvActions::isRlvEnabled()) && ((gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) || (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ADD))) ) obj_items_new.erase(std::remove_if(obj_items_new.begin(), obj_items_new.end(), RlvPredCanNotWearItem(RLV_WEAR)), obj_items_new.end()); obj_items.insert(obj_items.end(), obj_items_new.begin(), obj_items_new.end()); // [/RLVa:KB] diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 2d323961d0..38d83ef90b 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1162,6 +1162,7 @@ bool LLAppViewer::init() // Early out from user choice. return false; } + LL_INFOS("InitInfo") << "Hardware test initialization done." << LL_ENDL ; // Prepare for out-of-memory situations, during which we will crash on @@ -3965,13 +3966,6 @@ LLSD LLAppViewer::getViewerInfo() const // info["LLCEFLIB_VERSION"] = "Undefined"; //#endif -#if defined( FS_CEFLIB_VERSION ) && FS_CEFLIB_VERSION >= 6 - { - std::stringstream strm; - strm << LLCEFLIB_BASE_VERSION << ".FS" << FS_CEFLIB_VERSION << "-" << FS_CEF_VERSION << " (Chrome " << FS_CEF_CHROME_VERSION << ")"; - info[ "LLCEFLIB_VERSION" ] = strm.str(); - } -#endif // Use the total accumulated samples. //S32 packets_in = LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_IN); diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index c68067896f..4ef00f9c73 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -563,7 +563,7 @@ void LLAvatarActions::teleport_request_callback(const LLSD& notification, const std::string strMessage = response["message"]; // Filter the request message if the recipients is IM-blocked - if ( (!RlvActions::isRlvEnabled()) || ((RlvActions::canStartIM(idRecipient)) && (RlvActions::canSendIM(idRecipient))) ) + if ( (RlvActions::isRlvEnabled()) && ((!RlvActions::canStartIM(idRecipient)) || (!RlvActions::canSendIM(idRecipient))) ) { strMessage = RlvStrings::getString(RLV_STRING_HIDDEN); } @@ -1634,7 +1634,7 @@ void LLAvatarActions::getScriptInfo(const LLUUID& idAgent) // Defined in llworld.cpp -LLVector3d unpackLocalToGlobalPosition(U32 compact_local, const LLVector3d& region_origin); +LLVector3d unpackLocalToGlobalPosition(U32 compact_local, const LLVector3d& region_origin, F32 width_scale_factor); // static - Checked: 2010-12-03 (Catznip-2.4.0g) | Added: Catznip-2.4.0g bool getRegionAndPosGlobalFromAgentID(const LLUUID& idAgent, const LLViewerRegion** ppRegion, LLVector3d* pPosGlobal) @@ -1663,7 +1663,7 @@ bool getRegionAndPosGlobalFromAgentID(const LLUUID& idAgent, const LLViewerRegio if (ppRegion) *ppRegion = pRegion; if (pPosGlobal) - *pPosGlobal = unpackLocalToGlobalPosition(pRegion->mMapAvatars.at(idxRegionAgent), pRegion->getOriginGlobal()); + *pPosGlobal = unpackLocalToGlobalPosition(pRegion->mMapAvatars.at(idxRegionAgent), pRegion->getOriginGlobal(), pRegion->getWidthScaleFactor()); return (NULL != pRegion); } } diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index f223d38106..36aec75413 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -294,6 +294,10 @@ void LLAvatarList::draw() void LLAvatarList::clear() { getIDs().clear(); +// [RLVa:KB] - Checked: RLVa-2.0.3 + // We need to be able to call this *somehow* and it actually makes moderate sense to call this in here + updateNoItemsMessage(mNameFilter); +// [/RLVa:KB] setDirty(true); LLFlatListViewEx::clear(); } diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp index 1c0303157f..b706b1b1de 100644 --- a/indra/newview/lleventpoll.cpp +++ b/indra/newview/lleventpoll.cpp @@ -42,21 +42,19 @@ #include "llsdutil.h" // for ll_pretty_print_sd +#include "boost/make_shared.hpp" + namespace LLEventPolling { namespace Details { - class LLEventPollImpl + class LLEventPollImpl: public boost::enable_shared_from_this { public: LLEventPollImpl(const LLHost &sender); - // FIRE-19557; Hold on to LLEventPollImpl while the coroutine runs, otherwise the this pointer can get deleted while the coroutine is still active. - // void start(const std::string &url); - void start( const std::string &url, boost::shared_ptr< LLEventPollImpl > aThis ); - // - + void start(const std::string &url); void stop(); private: @@ -67,16 +65,14 @@ namespace Details static const F32 EVENT_POLL_ERROR_RETRY_SECONDS_INC; static const S32 MAX_EVENT_POLL_HTTP_ERRORS; - // FIRE-19557; Hold on to LLEventPollImpl while the coroutine runs, otherwise the this pointer can get deleted while the coroutine is still active. - // void eventPollCoro(std::string url); - void eventPollCoro( std::string url, boost::shared_ptr< LLEventPollImpl > aThis ); - // + void eventPollCoro(std::string url); void handleMessage(const LLSD &content); bool mDone; LLCore::HttpRequest::ptr_t mHttpRequest; LLCore::HttpRequest::policy_t mHttpPolicy; + LLCore::HttpOptions::ptr_t mHttpOptions; // Restore pre-coro behavior (60s timeout, no retries) std::string mSenderIp; int mCounter; LLCoreHttpUtil::HttpCoroutineAdapter::wptr_t mAdapter; @@ -96,6 +92,7 @@ namespace Details mDone(false), mHttpRequest(), mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID), + mHttpOptions(), // Restore pre-coro behavior (60s timeout, no retries) mSenderIp(), mCounter(sNextCounter++) @@ -104,6 +101,11 @@ namespace Details mHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest); mHttpPolicy = app_core_http.getPolicy(LLAppCoreHttp::AP_LONG_POLL); + // Restore pre-coro behavior (60s timeout, no retries) + mHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions); + mHttpOptions->setRetries(0); + mHttpOptions->setTransferTimeout(60); + // mSenderIp = sender.getIPandPort(); } @@ -124,24 +126,13 @@ namespace Details LLMessageSystem::dispatch(msg_name, message); } - // FIRE-19557; Hold on to LLEventPollImpl while the coroutine runs, otherwise the this pointer can get deleted while the coroutine is still active. - // void LLEventPollImpl::start(const std::string &url) - void LLEventPollImpl::start( const std::string &url, boost::shared_ptr< LLEventPollImpl > aThis ) - // + void LLEventPollImpl::start(const std::string &url) { if (!url.empty()) { - // FIRE-19557; Hold on LLEventPollImpl while the coroutine runs, otherwise the this pointer can get deleted while the coroutine is still active. - - // std::string coroname = - // LLCoros::instance().launch("LLEventPollImpl::eventPollCoro", - // boost::bind(&LLEventPollImpl::eventPollCoro, this, url)); - - std::string coroname = LLCoros::instance().launch("LLEventPollImpl::eventPollCoro", - boost::bind( &LLEventPollImpl::eventPollCoro, this, url, aThis ) ); - - // - + std::string coroname = + LLCoros::instance().launch("LLEventPollImpl::eventPollCoro", + boost::bind(&LLEventPollImpl::eventPollCoro, this->shared_from_this(), url)); LL_INFOS("LLEventPollImpl") << coroname << " with url '" << url << LL_ENDL; } } @@ -163,11 +154,8 @@ namespace Details } } - // FIRE-19557; Hold on to LLEventPollImpl while the coroutine runs, otherwise the this pointer can get deleted while the coroutine is still active. - // void LLEventPollImpl::eventPollCoro(std::string url) - void LLEventPollImpl::eventPollCoro( std::string url, boost::shared_ptr< LLEventPollImpl > aThis ) - // - { + void LLEventPollImpl::eventPollCoro(std::string url) + { LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("EventPoller", mHttpPolicy)); LLSD acknowledge; int errorCount = 0; @@ -189,7 +177,10 @@ namespace Details // << LLSDXMLStreamer(request) << LL_ENDL; LL_DEBUGS("LLEventPollImpl") << " <" << counter << "> posting and yielding." << LL_ENDL; - LLSD result = httpAdapter->postAndSuspend(mHttpRequest, url, request); + // Restore pre-coro behavior (60s timeout, no retries) + //LLSD result = httpAdapter->postAndSuspend(mHttpRequest, url, request); + LLSD result = httpAdapter->postAndSuspend(mHttpRequest, url, request, mHttpOptions); + // // LL_DEBUGS("LLEventPollImpl::eventPollCoro") << "<" << counter << "> result = " // << LLSDXMLStreamer(result) << LL_ENDL; @@ -205,6 +196,15 @@ namespace Details errorCount = 0; continue; } + // Restore pre-coro behavior (60s timeout, no retries) + else if (status == LLCore::HttpStatus(HTTP_BAD_GATEWAY)) + { // Pre-coro says this is the default answer for timeouts and it can happen + // frequently on OpenSim - assume this is normal and issue a new request immediately + LL_INFOS("LLEventPollImpl") << "Received HTTP 502 - start new request." << LL_ENDL; + errorCount = 0; + continue; + } + // else if ((status == LLCore::HttpStatus(LLCore::HttpStatus::LLCORE, LLCore::HE_OP_CANCELED)) || (status == LLCore::HttpStatus(HTTP_NOT_FOUND))) { // Event polling for this server has been canceled. In @@ -304,16 +304,8 @@ namespace Details LLEventPoll::LLEventPoll(const std::string& poll_url, const LLHost& sender): mImpl() { - // FIRE-19557; Hold on to LLEventPollImpl while the coroutine runs, otherwise the this pointer can get deleted while the coroutine is still active. - - // mImpl = boost::unique_ptr - // (new LLEventPolling::Details::LLEventPollImpl(sender)); - // mImpl->start(poll_url); - - mImpl.reset( new LLEventPolling::Details::LLEventPollImpl(sender) ); - mImpl->start( poll_url, mImpl ); - - // + mImpl = boost::make_shared(sender); + mImpl->start(poll_url); } LLEventPoll::~LLEventPoll() diff --git a/indra/newview/lleventpoll.h b/indra/newview/lleventpoll.h index 420b47bd0b..65766dbb2a 100644 --- a/indra/newview/lleventpoll.h +++ b/indra/newview/lleventpoll.h @@ -27,12 +27,6 @@ #ifndef LL_LLEVENTPOLL_H #define LL_LLEVENTPOLL_H -#include "boost/move/unique_ptr.hpp" - -namespace boost -{ - using ::boost::movelib::unique_ptr; // move unique_ptr into the boost namespace. -} class LLHost; @@ -57,10 +51,7 @@ public: private: - // FIRE-19557; Hold on to LLEventPollImpl while the coroutine runs, otherwise the this pointer can get deleted while the coroutine is still active. - // boost::unique_ptr mImpl; - boost::shared_ptr mImpl; - // + boost::shared_ptr mImpl; }; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 4da204b538..f1714bed93 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -293,7 +293,8 @@ void LLFace::setTexture(U32 ch, LLViewerTexture* tex) if ( (LLRender::DIFFUSE_MAP == ch) && (!mShowDiffTexture) ) { mOrigDiffTexture = tex; - return; + if (LLViewerFetchedTexture::sDefaultDiffuseImagep.get() == mTexture[ch].get()) + return; } // [/SL:KB] diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index d8e86e6aa9..06fbaf5a34 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -110,6 +110,9 @@ public: static void startFetchServerReleaseNotes(); static void handleServerReleaseNotes(LLSD results); + + // FIRE-19760: In Help/About Firestorm server release notes not getting fetched + static void fetchServerReleaseNotesCoro(const std::string& cap_url); }; @@ -227,9 +230,11 @@ void LLFloaterAbout::startFetchServerReleaseNotes() // an URL suitable for external browsers in the "Location:" HTTP header. std::string cap_url = region->getCapability("ServerReleaseNotes"); - LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet(cap_url, - &LLFloaterAbout::handleServerReleaseNotes, &LLFloaterAbout::handleServerReleaseNotes); - + // FIRE-19760: In Help/About Firestorm server release notes not getting fetched + //LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet(cap_url, + // &LLFloaterAbout::handleServerReleaseNotes, &LLFloaterAbout::handleServerReleaseNotes); + LLCoros::instance().launch("fetchServerReleaseNotesCoro", boost::bind(&LLFloaterAbout::fetchServerReleaseNotesCoro, cap_url)); + // } /*static*/ @@ -256,8 +261,45 @@ void LLFloaterAbout::handleServerReleaseNotes(LLSD results) } LLAppViewer::instance()->setServerReleaseNotesURL(location); // } + + // FIRE-19760: In Help/About Firestorm server release notes not getting fetched + LLFloaterAbout* floater_about = LLFloaterReg::findTypedInstance("sl_about"); + if (floater_about) + { + floater_about->setSupportText(location); + } + // } +// FIRE-19760: In Help/About Firestorm server release notes not getting fetched +/*static*/ +void LLFloaterAbout::fetchServerReleaseNotesCoro(const std::string& cap_url) +{ + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("fetchServerReleaseNotesCoro", LLCore::HttpRequest::DEFAULT_POLICY_ID)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + + httpOpts->setWantHeaders(true); + httpOpts->setFollowRedirects(false); + + LLSD result = httpAdapter->getAndSuspend(httpRequest, cap_url, httpOpts); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + handleServerReleaseNotes(httpResults); + } + else + { + handleServerReleaseNotes(result); + } + // +} + + class LLFloaterAboutListener: public LLEventAPI { public: diff --git a/indra/newview/llfloaterflickr.cpp b/indra/newview/llfloaterflickr.cpp index 6ea62ccad4..5fcb360937 100644 --- a/indra/newview/llfloaterflickr.cpp +++ b/indra/newview/llfloaterflickr.cpp @@ -54,6 +54,7 @@ #include #include "llspinctrl.h" +#include "llviewernetwork.h" #include "llnotificationsutil.h" #ifdef OPENSIM #include "exoflickr.h" @@ -66,8 +67,12 @@ static LLPanelInjector t_panel_photo("llflickrphotopanel"); static LLPanelInjector t_panel_account("llflickraccountpanel"); const std::string DEFAULT_PHOTO_QUERY_PARAMETERS = "?sourceid=slshare_photo&utm_source=flickr&utm_medium=photo&utm_campaign=slshare"; -const std::string DEFAULT_TAG_TEXT = "secondlife "; -const std::string FLICKR_MACHINE_TAGS_NAMESPACE = "secondlife"; +// Don't assume we're always in Second Life +//const std::string DEFAULT_TAG_TEXT = "secondlife "; +//const std::string FLICKR_MACHINE_TAGS_NAMESPACE = "secondlife"; +const std::string DEFAULT_TAG_TEXT = "Firestorm "; +static std::string FLICKR_MACHINE_TAGS_NAMESPACE = "secondlife"; +// /////////////////////////// //LLFlickrPhotoPanel/////// @@ -122,7 +127,10 @@ BOOL LLFlickrPhotoPanel::postBuild() mDescriptionTextBox = getChild("photo_description"); mLocationCheckbox = getChild("add_location_cb"); mTagsTextBox = getChild("photo_tags"); - mTagsTextBox->setValue(DEFAULT_TAG_TEXT); + // Don't assume we're always in Second Life + //mTagsTextBox->setValue(DEFAULT_TAG_TEXT); + mTagsTextBox->setValue(DEFAULT_TAG_TEXT + (LLGridManager::instance().isInSecondLife() ? "secondlife" : ("\"" + LLGridManager::instance().getGridId()) + "\"") + " "); + // mRatingComboBox = getChild("rating_combobox"); mPostButton = getChild("post_photo_btn"); mCancelButton = getChild("cancel_photo_btn"); @@ -391,7 +399,13 @@ void LLFlickrPhotoPanel::sendPhoto() std::string slurl_string = slurl.getSLURLString(); // Add query parameters so Google Analytics can track incoming clicks! - slurl_string += DEFAULT_PHOTO_QUERY_PARAMETERS; + // Don't assume we're always in Second Life + //slurl_string += DEFAULT_PHOTO_QUERY_PARAMETERS; + if (LLGridManager::instance().isInSecondLife()) + { + slurl_string += DEFAULT_PHOTO_QUERY_PARAMETERS; + } + // std::string photo_link_text = "Visit this location";// at [] in Second Life"; std::string parcel_name = LLViewerParcelMgr::getInstance()->getAgentParcelName(); @@ -404,7 +418,17 @@ void LLFlickrPhotoPanel::sendPhoto() photo_link_text += " at " + parcel_name; } } - photo_link_text += " in Second Life"; + // Don't assume we're always in Second Life + //photo_link_text += " in Second Life"; + if (LLGridManager::instance().isInSecondLife()) + { + photo_link_text += " in Second Life"; + } + else + { + photo_link_text += " in \"" + LLGridManager::instance().getGridLabel() + "\""; + } + // slurl_string = "" + photo_link_text + ""; @@ -427,6 +451,13 @@ void LLFlickrPhotoPanel::sendPhoto() std::string parcel_name = LLViewerParcelMgr::getInstance()->getAgentParcelName(); std::string region_name = region->getName(); + // Don't assume we're always in Second Life + if (!LLGridManager::instance().isInSecondLife()) + { + FLICKR_MACHINE_TAGS_NAMESPACE = LLGridManager::instance().getGridId(); + } + // + if (!region_name.empty()) { tags += llformat(" \"%s:region=%s\"", FLICKR_MACHINE_TAGS_NAMESPACE.c_str(), region_name.c_str()); diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 9934c6e88f..1239d6fedb 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -768,6 +768,8 @@ BOOL LLFloaterPreference::postBuild() // Properly disable avatar tag setting gSavedSettings.getControl("NameTagShowUsernames")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::onAvatarTagSettingsChanged, this)); gSavedSettings.getControl("FSNameTagShowLegacyUsernames")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::onAvatarTagSettingsChanged, this)); + gSavedSettings.getControl("AvatarNameTagMode")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::onAvatarTagSettingsChanged, this)); + gSavedSettings.getControl("FSTagShowARW")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::onAvatarTagSettingsChanged, this)); onAvatarTagSettingsChanged(); // @@ -1192,15 +1194,17 @@ void LLFloaterPreference::onOpen(const LLSD& key) // Fix resetting graphics preset on cancel saveGraphicsPreset(gSavedSettings.getString("PresetGraphicActive")); - bool started = (LLStartUp::getStartupState() == STATE_STARTED); + // FIRE-19810: Make presets global since PresetGraphicActive setting is global as well + //bool started = (LLStartUp::getStartupState() == STATE_STARTED); - LLButton* load_btn = findChild("PrefLoadButton"); - LLButton* save_btn = findChild("PrefSaveButton"); - LLButton* delete_btn = findChild("PrefDeleteButton"); + //LLButton* load_btn = findChild("PrefLoadButton"); + //LLButton* save_btn = findChild("PrefSaveButton"); + //LLButton* delete_btn = findChild("PrefDeleteButton"); - load_btn->setEnabled(started); - save_btn->setEnabled(started); - delete_btn->setEnabled(started); + //load_btn->setEnabled(started); + //save_btn->setEnabled(started); + //delete_btn->setEnabled(started); + // // Hook up and init for filtering collectSearchableItems(); @@ -3219,7 +3223,10 @@ void LLFloaterPreference::onClickBlockList() // Optional standalone blocklist floater //LLFloaterSidePanelContainer::showPanel("people", "panel_people", // LLSD().with("people_panel_tab_name", "blocked_panel")); + BOOL saved_setting = gSavedSettings.getBOOL("FSDisableBlockListAutoOpen"); + gSavedSettings.setBOOL("FSDisableBlockListAutoOpen", FALSE); LLPanelBlockedList::showPanelAndSelect(); + gSavedSettings.setBOOL("FSDisableBlockListAutoOpen", saved_setting); // } @@ -3418,6 +3425,10 @@ void LLFloaterPreference::onAvatarTagSettingsChanged() childSetEnabled("FSshow_legacyun", usernames_enabled); childSetEnabled("legacy_trim_check", usernames_enabled && legacy_enabled); + + bool arw_options_enabled = gSavedSettings.getBOOL("FSTagShowARW") && gSavedSettings.getS32("AvatarNameTagMode") > 0; + childSetEnabled("FSTagShowTooComplexOnlyARW", arw_options_enabled); + childSetEnabled("FSTagShowOwnARW", arw_options_enabled); } // @@ -3630,9 +3641,11 @@ BOOL LLPanelPreference::postBuild() // Only enable Growl checkboxes if Growl is usable if (hasChild("notify_growl_checkbox", TRUE)) { + BOOL growl_enabled = gSavedSettings.getBOOL("FSEnableGrowl") && GrowlManager::isUsable(); getChild("notify_growl_checkbox")->setCommitCallback(boost::bind(&LLPanelPreference::onEnableGrowlChanged, this)); getChild("notify_growl_checkbox")->setEnabled(GrowlManager::isUsable()); - getChild("notify_growl_always_checkbox")->setEnabled(gSavedSettings.getBOOL("FSEnableGrowl") && GrowlManager::isUsable()); + getChild("notify_growl_always_checkbox")->setEnabled(growl_enabled); + getChild("FSFilterGrowlKeywordDuplicateIMs")->setEnabled(growl_enabled); } // @@ -3736,7 +3749,9 @@ void LLPanelPreference::handleFavoritesOnLoginChanged(LLUICtrl* checkbox, const // Only enable Growl checkboxes if Growl is usable void LLPanelPreference::onEnableGrowlChanged() { - getChild("notify_growl_always_checkbox")->setEnabled(gSavedSettings.getBOOL("FSEnableGrowl") && GrowlManager::isUsable()); + BOOL growl_enabled = gSavedSettings.getBOOL("FSEnableGrowl") && GrowlManager::isUsable(); + getChild("notify_growl_always_checkbox")->setEnabled(growl_enabled); + getChild("FSFilterGrowlKeywordDuplicateIMs")->setEnabled(growl_enabled); } // @@ -4039,9 +4054,6 @@ BOOL LLPanelPreferenceGraphics::postBuild() #endif // LL_DARWIN // - // Texture memory management - getChild("GraphicsCardTextureMemory")->setMaxValue((F32)gMaxVideoRam.value()); - return LLPanelPreference::postBuild(); } void LLPanelPreferenceGraphics::draw() @@ -4918,55 +4930,10 @@ void FSPanelPreferenceBackup::onClickBackupSettings() // and only restore selectively std::string file = item->getColumn(2)->getValue().asString(); - if (item->getValue().asString() != "presets") - { - LL_INFOS("SettingsBackup") << "copying per account file " << file << LL_ENDL; - copy_prefs_file( - gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file), - gDirUtilp->getExpandedFilename(LL_PATH_NONE, backup_per_account_folder, file)); - } - else - { - LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_NONE, backup_per_account_folder, PRESETS_DIR)); - - std::string presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR) + gDirUtilp->getDirDelimiter(); - std::string graphics_presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, PRESETS_GRAPHIC) + gDirUtilp->getDirDelimiter(); - std::string camera_presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, PRESETS_CAMERA) + gDirUtilp->getDirDelimiter(); - - if (LLFile::isdir(graphics_presets_folder)) - { - LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_NONE, backup_per_account_folder, PRESETS_DIR, PRESETS_GRAPHIC)); - - std::string file_name; - while (gDirUtilp->getNextFileInDir(graphics_presets_folder, "*", file_name)) - { - std::string source = gDirUtilp->getExpandedFilename(LL_PATH_NONE, graphics_presets_folder, file_name); - - if (LLFile::isfile(source.c_str())) - { - std::string target = gDirUtilp->add(gDirUtilp->add(gDirUtilp->add(backup_per_account_folder, PRESETS_DIR), PRESETS_GRAPHIC), file_name); - copy_prefs_file(source, target); - } - } - } - - if (LLFile::isdir(camera_presets_folder)) - { - LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_NONE, backup_per_account_folder, PRESETS_DIR, PRESETS_CAMERA)); - - std::string file_name; - while (gDirUtilp->getNextFileInDir(camera_presets_folder, "*", file_name)) - { - std::string source = gDirUtilp->getExpandedFilename(LL_PATH_NONE, camera_presets_folder, file_name); - - if (LLFile::isfile(source.c_str())) - { - std::string target = gDirUtilp->add(gDirUtilp->add(gDirUtilp->add(backup_per_account_folder, PRESETS_DIR), PRESETS_CAMERA), file_name); - copy_prefs_file(source, target); - } - } - } - } + LL_INFOS("SettingsBackup") << "copying per account file " << file << LL_ENDL; + copy_prefs_file( + gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file), + gDirUtilp->getExpandedFilename(LL_PATH_NONE, backup_per_account_folder, file)); } } else @@ -4986,28 +4953,73 @@ void FSPanelPreferenceBackup::onClickBackupSettings() LLScrollListItem* item = globalFoldersList[index]; // Don't bother with the checkbox and get the path, since we back up all folders // and only restore selectively - std::string folder = item->getColumn(2)->getValue().asString(); - - std::string folder_name = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, folder) + gDirUtilp->getDirDelimiter(); - std::string backup_folder_name = gDirUtilp->getExpandedFilename(LL_PATH_NONE, dir_name, folder) + gDirUtilp->getDirDelimiter(); - - LL_INFOS("SettingsBackup") << "backing up global folder: " << folder_name << LL_ENDL; - - // create folder if it's not there already - LLFile::mkdir(backup_folder_name.c_str()); - - std::string file_name; - while (gDirUtilp->getNextFileInDir(folder_name, "*", file_name)) + if (item->getValue().asString() != "presets") { - LL_INFOS("SettingsBackup") << "found entry: " << folder_name + file_name << LL_ENDL; - // only copy files, not subfolders - if (LLFile::isfile(folder_name + file_name.c_str())) + std::string folder = item->getColumn(2)->getValue().asString(); + + std::string folder_name = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, folder) + gDirUtilp->getDirDelimiter(); + std::string backup_folder_name = gDirUtilp->getExpandedFilename(LL_PATH_NONE, dir_name, folder) + gDirUtilp->getDirDelimiter(); + + LL_INFOS("SettingsBackup") << "backing up global folder: " << folder_name << LL_ENDL; + + // create folder if it's not there already + LLFile::mkdir(backup_folder_name.c_str()); + + std::string file_name; + while (gDirUtilp->getNextFileInDir(folder_name, "*", file_name)) { - copy_prefs_file(folder_name + file_name, backup_folder_name + file_name); + LL_INFOS("SettingsBackup") << "found entry: " << folder_name + file_name << LL_ENDL; + // only copy files, not subfolders + if (LLFile::isfile(folder_name + file_name.c_str())) + { + copy_prefs_file(folder_name + file_name, backup_folder_name + file_name); + } + else + { + LL_INFOS("SettingsBackup") << "skipping subfolder " << folder_name + file_name << LL_ENDL; + } } - else + } + else + { + LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_NONE, dir_name, PRESETS_DIR)); + + std::string presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR) + gDirUtilp->getDirDelimiter(); + std::string graphics_presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR, PRESETS_GRAPHIC) + gDirUtilp->getDirDelimiter(); + std::string camera_presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR, PRESETS_CAMERA) + gDirUtilp->getDirDelimiter(); + + if (LLFile::isdir(graphics_presets_folder)) { - LL_INFOS("SettingsBackup") << "skipping subfolder " << folder_name + file_name << LL_ENDL; + LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_NONE, dir_name, PRESETS_DIR, PRESETS_GRAPHIC)); + + std::string file_name; + while (gDirUtilp->getNextFileInDir(graphics_presets_folder, "*", file_name)) + { + std::string source = gDirUtilp->getExpandedFilename(LL_PATH_NONE, graphics_presets_folder, file_name); + + if (LLFile::isfile(source.c_str())) + { + std::string target = gDirUtilp->add(gDirUtilp->add(gDirUtilp->add(dir_name, PRESETS_DIR), PRESETS_GRAPHIC), file_name); + copy_prefs_file(source, target); + } + } + } + + if (LLFile::isdir(camera_presets_folder)) + { + LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_NONE, dir_name, PRESETS_DIR, PRESETS_CAMERA)); + + std::string file_name; + while (gDirUtilp->getNextFileInDir(camera_presets_folder, "*", file_name)) + { + std::string source = gDirUtilp->getExpandedFilename(LL_PATH_NONE, camera_presets_folder, file_name); + + if (LLFile::isfile(source.c_str())) + { + std::string target = gDirUtilp->add(gDirUtilp->add(gDirUtilp->add(dir_name, PRESETS_DIR), PRESETS_CAMERA), file_name); + copy_prefs_file(source, target); + } + } } } } @@ -5149,57 +5161,12 @@ void FSPanelPreferenceBackup:: doRestoreSettings(const LLSD& notification, const // Only restore if this item is checked on if (checkbox->getCheckBox()->getValue().asBoolean()) { - if (item->getValue().asString() != "presets") - { - // Get the path to restore for this item - std::string file = item->getColumn(2)->getValue().asString(); - LL_INFOS("SettingsBackup") << "copying per account file " << file << LL_ENDL; - copy_prefs_file( - gDirUtilp->getExpandedFilename(LL_PATH_NONE, backup_per_account_folder, file), - gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file)); - } - else - { - LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR)); - - std::string presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_NONE, backup_per_account_folder, PRESETS_DIR) + gDirUtilp->getDirDelimiter(); - std::string graphics_presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_NONE, backup_per_account_folder, PRESETS_DIR, PRESETS_GRAPHIC) + gDirUtilp->getDirDelimiter(); - std::string camera_presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_NONE, backup_per_account_folder, PRESETS_DIR, PRESETS_CAMERA) + gDirUtilp->getDirDelimiter(); - - if (LLFile::isdir(graphics_presets_folder)) - { - LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, PRESETS_GRAPHIC)); - - std::string file_name; - while (gDirUtilp->getNextFileInDir(graphics_presets_folder, "*", file_name)) - { - std::string source = gDirUtilp->getExpandedFilename(LL_PATH_NONE, graphics_presets_folder, file_name); - - if (LLFile::isfile(source.c_str())) - { - std::string target = gDirUtilp->add(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, PRESETS_GRAPHIC), file_name); - copy_prefs_file(source, target); - } - } - } - - if (LLFile::isdir(camera_presets_folder)) - { - LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, PRESETS_CAMERA)); - - std::string file_name; - while (gDirUtilp->getNextFileInDir(camera_presets_folder, "*", file_name)) - { - std::string source = gDirUtilp->getExpandedFilename(LL_PATH_NONE, camera_presets_folder, file_name); - - if (LLFile::isfile(source.c_str())) - { - std::string target = gDirUtilp->add(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, PRESETS_CAMERA), file_name); - copy_prefs_file(source, target); - } - } - } - } + // Get the path to restore for this item + std::string file = item->getColumn(2)->getValue().asString(); + LL_INFOS("SettingsBackup") << "copying per account file " << file << LL_ENDL; + copy_prefs_file( + gDirUtilp->getExpandedFilename(LL_PATH_NONE, backup_per_account_folder, file), + gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file)); } } @@ -5237,29 +5204,74 @@ void FSPanelPreferenceBackup:: doRestoreSettings(const LLSD& notification, const // Only restore if this item is checked on if (checkbox->getCheckBox()->getValue().asBoolean()) { - // Get the path to restore for this item - std::string folder = item->getColumn(2)->getValue().asString(); - - std::string folder_name = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, folder) + gDirUtilp->getDirDelimiter(); - std::string backup_folder_name = gDirUtilp->getExpandedFilename(LL_PATH_NONE, dir_name, folder) + gDirUtilp->getDirDelimiter(); - - LL_INFOS("SettingsBackup") << "restoring global folder: " << folder_name << LL_ENDL; - - // create folder if it's not there already - LLFile::mkdir(folder_name.c_str()); - - std::string file_name; - while (gDirUtilp->getNextFileInDir(backup_folder_name, "*", file_name)) + if (item->getValue().asString() != "presets") { - LL_INFOS("SettingsBackup") << "found entry: " << backup_folder_name + file_name << LL_ENDL; - // only restore files, not subfolders - if (LLFile::isfile(backup_folder_name + file_name.c_str())) + // Get the path to restore for this item + std::string folder = item->getColumn(2)->getValue().asString(); + + std::string folder_name = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, folder) + gDirUtilp->getDirDelimiter(); + std::string backup_folder_name = gDirUtilp->getExpandedFilename(LL_PATH_NONE, dir_name, folder) + gDirUtilp->getDirDelimiter(); + + LL_INFOS("SettingsBackup") << "restoring global folder: " << folder_name << LL_ENDL; + + // create folder if it's not there already + LLFile::mkdir(folder_name.c_str()); + + std::string file_name; + while (gDirUtilp->getNextFileInDir(backup_folder_name, "*", file_name)) { - copy_prefs_file(backup_folder_name + file_name, folder_name + file_name); + LL_INFOS("SettingsBackup") << "found entry: " << backup_folder_name + file_name << LL_ENDL; + // only restore files, not subfolders + if (LLFile::isfile(backup_folder_name + file_name.c_str())) + { + copy_prefs_file(backup_folder_name + file_name, folder_name + file_name); + } + else + { + LL_INFOS("SettingsBackup") << "skipping subfolder " << backup_folder_name + file_name << LL_ENDL; + } } - else + } + else + { + LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR)); + + std::string presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_NONE, dir_name, PRESETS_DIR) + gDirUtilp->getDirDelimiter(); + std::string graphics_presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_NONE, dir_name, PRESETS_DIR, PRESETS_GRAPHIC) + gDirUtilp->getDirDelimiter(); + std::string camera_presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_NONE, dir_name, PRESETS_DIR, PRESETS_CAMERA) + gDirUtilp->getDirDelimiter(); + + if (LLFile::isdir(graphics_presets_folder)) { - LL_INFOS("SettingsBackup") << "skipping subfolder " << backup_folder_name + file_name << LL_ENDL; + LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR, PRESETS_GRAPHIC)); + + std::string file_name; + while (gDirUtilp->getNextFileInDir(graphics_presets_folder, "*", file_name)) + { + std::string source = gDirUtilp->getExpandedFilename(LL_PATH_NONE, graphics_presets_folder, file_name); + + if (LLFile::isfile(source.c_str())) + { + std::string target = gDirUtilp->add(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR, PRESETS_GRAPHIC), file_name); + copy_prefs_file(source, target); + } + } + } + + if (LLFile::isdir(camera_presets_folder)) + { + LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR, PRESETS_CAMERA)); + + std::string file_name; + while (gDirUtilp->getNextFileInDir(camera_presets_folder, "*", file_name)) + { + std::string source = gDirUtilp->getExpandedFilename(LL_PATH_NONE, camera_presets_folder, file_name); + + if (LLFile::isfile(source.c_str())) + { + std::string target = gDirUtilp->add(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR, PRESETS_CAMERA), file_name); + copy_prefs_file(source, target); + } + } } } } diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp index 201298c2d4..6874c64f92 100644 --- a/indra/newview/llfriendcard.cpp +++ b/indra/newview/llfriendcard.cpp @@ -640,7 +640,7 @@ void LLFriendCardsManager::onFriendListUpdate(U32 changed_mask) void create_agent_calling_card_name_cb(const LLAvatarName& av_name, const LLUUID& calling_cards_folder_id) { create_inventory_item(gAgentID, - gAgent.getSessionID(), + gAgentSessionID, calling_cards_folder_id, LLTransactionID::tnull, av_name.getUserName(), @@ -652,11 +652,8 @@ void create_agent_calling_card_name_cb(const LLAvatarName& av_name, const LLUUID NULL); } -// static -void LLFriendCardsManager::createAgentCallingCard() +void calling_card_folder_loaded_cb(const LLUUID& calling_cards_folder_id) { - const LLUUID calling_cards_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD); - LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; LLFindAgentCallingCard collector; @@ -668,5 +665,26 @@ void LLFriendCardsManager::createAgentCallingCard() LLAvatarNameCache::get(gAgentID, boost::bind(&create_agent_calling_card_name_cb, _2, calling_cards_folder_id)); } } + +// static +void LLFriendCardsManager::createAgentCallingCard() +{ + const LLUUID calling_cards_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD); + + // This instance will be deleted in LLInitialFriendCardsFetch::done(). + LLInitialFriendCardsFetch* fetch = new LLInitialFriendCardsFetch(calling_cards_folder_id, boost::bind(&calling_card_folder_loaded_cb, calling_cards_folder_id)); + fetch->startFetch(); + if (fetch->isFinished()) + { + // everything is already here - call done. + fetch->done(); + } + else + { + // it's all on it's way - add an observer, and the inventory + // will call done for us when everything is here. + gInventory.addObserver(fetch); + } +} // // EOF diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index dbe14c9616..9ce83cf58a 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -326,8 +326,8 @@ bool LLGroupActions::onJoinGroup(const LLSD& notification, const LLSD& response) void LLGroupActions::leave(const LLUUID& group_id) { // if (group_id.isNull()) -// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.4.1a) | Added: RLVa-1.3.0f - if ( (group_id.isNull()) || ((gAgent.getGroupID() == group_id) && (gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP))) ) +// [RLVa:KB] - Checked: RLVa-1.3.0 + if ( (group_id.isNull()) || ((gAgent.getGroupID() == group_id) && (!RlvActions::canChangeActiveGroup())) ) // [/RLVa:KB] { return; @@ -388,8 +388,8 @@ void LLGroupActions::processLeaveGroupDataResponse(const LLUUID group_id) // static void LLGroupActions::activate(const LLUUID& group_id) { -// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.4.1a) | Added: RLVa-1.3.0f - if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP)) && (gRlvHandler.getAgentGroup() != group_id) ) +// [RLVa:KB] - Checked: RLVa-1.3.0 + if ( (!RlvActions::canChangeActiveGroup()) && (gRlvHandler.getAgentGroup() != group_id) ) { return; } diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp index fc46672678..cff7083a4c 100644 --- a/indra/newview/llgrouplist.cpp +++ b/indra/newview/llgrouplist.cpp @@ -43,8 +43,8 @@ #include "llviewercontrol.h" // for gSavedSettings #include "llviewermenu.h" // for gMenuHolder #include "llvoiceclient.h" -// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.3.0f) | Added: RLVa-1.3.0f -#include "rlvhandler.h" +// [RLVa:KB] - Checked: RLVa-2.0.3 +#include "rlvactions.h" // [/RLVa:KB] static LLDefaultChildRegistry::Register r("group_list"); @@ -360,14 +360,14 @@ bool LLGroupList::onContextMenuItemEnable(const LLSD& userdata) bool real_group_selected = selected_group_id.notNull(); // a "real" (not "none") group is selected // each group including "none" can be activated +// [RLVa:KB] - Checked: RLVa-1.3.0 + if (userdata.asString() == "activate") + return (gAgent.getGroupID() != selected_group_id) && (RlvActions::canChangeActiveGroup()); + else if (userdata.asString() == "leave") + return (real_group_selected) && ((gAgent.getGroupID() != selected_group_id) || (RlvActions::canChangeActiveGroup())); +// [/RLVa:KB] // if (userdata.asString() == "activate") // return gAgent.getGroupID() != selected_group_id; -// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.4.1a) | Added: RLVa-1.3.0f - if (userdata.asString() == "activate") - return (gAgent.getGroupID() != selected_group_id) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP)); - else if (userdata.asString() == "leave") - return (real_group_selected) && ((gAgent.getGroupID() != selected_group_id) || (!gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP))); -// [/RLVa:KB] if (userdata.asString() == "call") return real_group_selected && LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking(); diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index ad4dc3a1de..3539b6cd1f 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -259,7 +259,7 @@ void LLHUDText::setString(const std::string &text_utf8) { mTextSegments.clear(); // addLine(text_utf8, mColor); -// [RLVa:KB] - Checked: 2010-03-02 (RLVa-1.4.0a) | Modified: RLVa-1.0.0f +// [RLVa:KB] - Checked: RLVa-2.0.3 // NOTE: setString() is called for debug and map beacons as well if (RlvActions::isRlvEnabled()) { @@ -268,8 +268,10 @@ void LLHUDText::setString(const std::string &text_utf8) { if (!RlvActions::canShowLocation()) RlvUtil::filterLocation(text); - if (!RlvActions::canShowName(RlvActions::SNC_DEFAULT)) - RlvUtil::filterNames(text); + + bool fCanShowNearby = RlvActions::canShowNearbyAgents(); + if ( (!RlvActions::canShowName(RlvActions::SNC_DEFAULT)) || (!fCanShowNearby) ) + RlvUtil::filterNames(text, true, !fCanShowNearby); } else { @@ -671,14 +673,16 @@ F32 LLHUDText::LLHUDTextSegment::getWidth(const LLFontGL* font) } } -// [RLVa:KB] - Checked: 2010-03-27 (RLVa-1.4.0a) | Added: RLVa-1.0.0f -void LLHUDText::refreshAllObjectText() +// [RLVa:KB] - Checked: RLVa-2.0.3 +void LLHUDText::refreshAllObjectText(EObjectTextFilter eObjFilter) { - for (TextObjectIterator itText = sTextObjects.begin(); itText != sTextObjects.end(); ++itText) + for (LLHUDText* pText : sTextObjects) { - LLHUDText* pText = *itText; - if ( (pText) && (!pText->mObjText.empty()) && (pText->mSourceObject) && (LL_PCODE_VOLUME == pText->mSourceObject->getPCode()) ) + if ((pText) && (!pText->mObjText.empty()) && (pText->mSourceObject) && (LL_PCODE_VOLUME == pText->mSourceObject->getPCode()) && + ((OTF_NONE == eObjFilter) || ((OTF_HUD_ATTACHMENTS == eObjFilter) && (pText->mSourceObject->isHUDAttachment())))) + { pText->setString(pText->mObjText); + } } } // [/RLVa:KB] diff --git a/indra/newview/llhudtext.h b/indra/newview/llhudtext.h index 1d33db6d99..b11bdcbbc6 100644 --- a/indra/newview/llhudtext.h +++ b/indra/newview/llhudtext.h @@ -124,10 +124,12 @@ public: static void reshape(); static void setDisplayText(BOOL flag) { sDisplayText = flag ; } -// [RLVa:KB] - Checked: 2010-03-27 (RLVa-1.4.0a) | Added: RLVa-1.0.0f +// [RLVa:KB] - Checked: RLVa-2.0.3 const std::string& getObjectText() const { return mObjText; } void setObjectText(const std::string &utf8string) { mObjText = utf8string; } - static void refreshAllObjectText(); + + enum EObjectTextFilter { OTF_NONE, OTF_HUD_ATTACHMENTS }; + static void refreshAllObjectText(EObjectTextFilter eObjFilter = OTF_NONE); // [/RLVa:KB] // FIRE-17393: Control HUD text fading by options @@ -170,7 +172,7 @@ private: ETextAlignment mTextAlignment; EVertAlignment mVertAlignment; BOOL mHidden; -// [RLVa:KB] - Checked: 2010-03-27 (RLVa-1.4.0a) | Added: RLVa-1.0.0f +// [RLVa:KB] - Checked: RLVa-1.0.0 std::string mObjText; // [/RLVa:KB] diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 05f0a4b01e..1071b4faf3 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -4309,49 +4309,51 @@ public: // [/RLVa:KB] // Mute group chat port from Phoenix - BOOL FSMuteAllGroups = gSavedSettings.getBOOL("FSMuteAllGroups"); - BOOL FSMuteGroupWhenNoticesDisabled = gSavedSettings.getBOOL("FSMuteGroupWhenNoticesDisabled"); - LLGroupData group_data; - if (gAgent.getGroupData(session_id, group_data)) + if (from_id != gAgentID) // FIRE-14222: OpenSim routes agent's chat through here - don't mute it! { - if (FSMuteAllGroups || (FSMuteGroupWhenNoticesDisabled && !group_data.mAcceptNotices)) + BOOL FSMuteAllGroups = gSavedSettings.getBOOL("FSMuteAllGroups"); + BOOL FSMuteGroupWhenNoticesDisabled = gSavedSettings.getBOOL("FSMuteGroupWhenNoticesDisabled"); + LLGroupData group_data; + if (gAgent.getGroupData(session_id, group_data)) { - LL_INFOS() << "Firestorm: muting group chat: " << group_data.mName << LL_ENDL; - - if (gSavedSettings.getBOOL("FSReportMutedGroupChat")) + if (FSMuteAllGroups || (FSMuteGroupWhenNoticesDisabled && !group_data.mAcceptNotices)) { - LLStringUtil::format_map_t args; - args["NAME"] = LLSLURL("group", session_id, "about").getSLURLString(); - report_to_nearby_chat(LLTrans::getString("GroupChatMuteNotice", args)); + LL_INFOS() << "Muting group chat: " << group_data.mName << LL_ENDL; + + if (gSavedSettings.getBOOL("FSReportMutedGroupChat")) + { + LLStringUtil::format_map_t args; + args["NAME"] = LLSLURL("group", session_id, "about").getSLURLString(); + report_to_nearby_chat(LLTrans::getString("GroupChatMuteNotice", args)); + } + + //KC: make sure we leave the group chat at the server end as well + std::string aname; + gAgent.buildFullname(aname); + pack_instant_message( + gMessageSystem, + gAgentID, + FALSE, + gAgentSessionID, + from_id, + aname, + LLStringUtil::null, + IM_ONLINE, + IM_SESSION_LEAVE, + session_id); + gAgent.sendReliableMessage(); + gIMMgr->leaveSession(session_id); + + return; } - - //KC: make sure we leave the group chat at the server end as well - std::string aname; - gAgent.buildFullname(aname); - pack_instant_message( - gMessageSystem, - gAgent.getID(), - FALSE, - gAgent.getSessionID(), - from_id, - aname, - LLStringUtil::null, - IM_ONLINE, - IM_SESSION_LEAVE, - session_id); - gAgent.sendReliableMessage(); - //gIMMgr->removeSession(session_id); - gIMMgr->leaveSession(session_id); - - return; } + // Groupdata debug + else + { + LL_INFOS("Agent_GroupData") << "GROUPDEBUG: Group chat mute: No agent group data for group " << session_id.asString() << LL_ENDL; + } + // } - // Groupdata debug - else - { - LL_INFOS("Agent_GroupData") << "GROUPDEBUG: Group chat mute: No agent group data for group " << session_id.asString() << LL_ENDL; - } - // // Mute group chat port from Phoenix // standard message, not from system diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 6e452fc95d..8263611355 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -4323,6 +4323,13 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& { disabled_items.push_back(std::string("Replace Outfit")); } +// [RLVa:KB] - Checked: RLVa-2.0.3 + // Block "Replace Current Outfit" if the user can't wear the new folder + if ( (RlvActions::isRlvEnabled()) && (RlvFolderLocks::instance().isLockedFolder(mUUID, RLV_LOCK_ADD)) ) + { + disabled_items.push_back(std::string("Replace Outfit")); + } +// [/RLVa:KB] if (!LLAppearanceMgr::instance().getCanAddToCOF(mUUID)) { disabled_items.push_back(std::string("Add To Outfit")); @@ -6546,6 +6553,11 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach { attachment = RlvAttachPtLookup::getAttachPoint(item); } + + if ( (RlvActions::isRlvEnabled()) && (!rlvPredCanWearItem(item, (replace) ? RLV_WEAR_REPLACE : RLV_WEAR_ADD)) ) + { + return; + } // [/RLVa:KB] const LLUUID& item_id = item->getLinkedUUID(); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 1f1a255310..b23a718130 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1026,7 +1026,12 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask) if( item_array ) { // *FIX: bit of a hack to call update server from here... - new_item->updateServer(TRUE); + // FIRE-19635 / BUG-20161: Detached object ends up in root of inventory + //new_item->updateServer(TRUE); + LLInventoryModel::LLCategoryUpdate update(category_id, 1); + gInventory.accountForUpdate(update); + new_item->updateParentOnServer(FALSE); + // item_array->push_back(new_item); } else @@ -1069,7 +1074,12 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask) { // *FIX: bit of a hack to call update server from // here... - new_item->updateServer(TRUE); + // FIRE-19635 / BUG-20161: Detached object ends up in root of inventory + //new_item->updateServer(TRUE); + LLInventoryModel::LLCategoryUpdate update(parent_id, 1); + gInventory.accountForUpdate(update); + new_item->updateParentOnServer(FALSE); + // item_array->push_back(new_item); } else diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 88e93bb796..b583dd58ec 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -3995,10 +3995,11 @@ void LLMeshRepository::uploadModel(std::vector& data, LLVector3 S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod) { - if (mThread) + if (mThread && mesh_id.notNull()) { + LLMutexLock lock(mThread->mHeaderMutex); LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); - if (iter != mThread->mMeshHeader.end()) + if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0) { LLSD& header = iter->second; @@ -4070,9 +4071,30 @@ void LLMeshRepository::uploadError(LLSD& args) mUploadErrorQ.push(args); } +F32 LLMeshRepository::getStreamingCost(LLUUID mesh_id, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value) +{ + if (mThread && mesh_id.notNull()) + { + LLMutexLock lock(mThread->mHeaderMutex); + LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); + if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0) + { + return getStreamingCost(iter->second, radius, bytes, bytes_visible, lod, unscaled_value); + } + } + return 0.f; +} + //static F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value) { + if (header.has("404") + || !header.has("lowest_lod") + || (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION)) + { + return 0.f; + } + F32 max_distance = 512.f; F32 dlowest = llmin(radius/0.03f, max_distance); @@ -4147,7 +4169,7 @@ F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32 } } - F32 max_area = 102932.f; //area of circle that encompasses region + F32 max_area = 102944.f; //area of circle that encompasses region (see MAINT-6559) F32 min_area = 1.f; F32 high_area = llmin(F_PI*dmid*dmid, max_area); @@ -4841,9 +4863,14 @@ void on_new_single_inventory_upload_complete( // and display something saying that it cost L$ LLStatusBar::sendMoneyBalanceRequest(); + // FIRE-10628 - Option to supress upload cost notification + if (gSavedSettings.getBOOL("FSShowUploadPaymentToast")) + { LLSD args; args["AMOUNT"] = llformat("%d", upload_price); LLNotificationsUtil::add("UploadPayment", args); + } + // } if (item_folder_id.notNull()) diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 9f07afb2ea..84d529ad79 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -477,6 +477,7 @@ public: static LLDeadmanTimer sQuiescentTimer; // Time-to-complete-mesh-downloads after significant events + F32 getStreamingCost(LLUUID mesh_id, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL); static F32 getStreamingCost(LLSD& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL); LLMeshRepository(); diff --git a/indra/newview/llmimetypes.cpp b/indra/newview/llmimetypes.cpp index 790a184068..a60a925af8 100644 --- a/indra/newview/llmimetypes.cpp +++ b/indra/newview/llmimetypes.cpp @@ -178,13 +178,33 @@ std::string LLMIMETypes::widgetType(const std::string& mime_type) } } +// Get the selected media impl, hardcoded for now. Can be quicktime/gstreamer/(vlc in the future) depending on OS and bitness +std::string getStreamingPlugin() +{ +#if defined( LL_LINUX ) || defined( LL_WINDOWS ) + return "media_plugin_gstreamer10"; +#else + llassert_always( false ); +#endif +} +// + // static std::string LLMIMETypes::implType(const std::string& mime_type) { mime_info_map_t::const_iterator it = sMap.find(mime_type); if (it != sMap.end()) { - return it->second.mImpl; + // Get the selected media impl, hardcoded for now. Can be quicktime/gstreamer/(vlc in the future) depending on OS and bitness + + // return it->second.mImpl; + std::string impl = it->second.mImpl; + + if( impl == "media_plugin_streaming" ) + return getStreamingPlugin(); + + return impl; + // } else { diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index c337663dd1..00aadae38f 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -946,7 +946,18 @@ void LLPanelPeople::updateNearbyList() std::vector positions; - LLWorld::getInstance()->getAvatars(&mNearbyList->getIDs(), &positions, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange")); +// [RLVa:KB] - Checked: RLVa-2.0.3 + if (RlvActions::canShowNearbyAgents()) + { +// [/RLVa:KB] + LLWorld::getInstance()->getAvatars(&mNearbyList->getIDs(), &positions, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange")); +// [RLVa:KB] - Checked: RLVa-2.0.3 + } + else + { + mNearbyList->getIDs().clear(); + } +// [/RLVa:KB] mNearbyList->setDirty(); DISTANCE_COMPARATOR.updateAvatarsPositions(positions, mNearbyList->getIDs()); @@ -1077,16 +1088,6 @@ void LLPanelPeople::updateButtons() } } } - -// [RLVa:KB] - Checked: RLVa-1.2.0 - if ( (nearby_tab_active) && (RlvActions::isRlvEnabled()) && (!RlvActions::canShowName(RlvActions::SNC_DEFAULT)) ) - { - bool fCanShowNames = true; - std::for_each(selected_uuids.begin(), selected_uuids.end(), [&fCanShowNames](const LLUUID& idAgent) { fCanShowNames &= RlvActions::canShowName(RlvActions::SNC_DEFAULT, idAgent); }); - if (!fCanShowNames) - item_selected = multiple_selected = false; - } -// [/RLBa:KB] } std::string LLPanelPeople::getActiveTabName() const @@ -1334,10 +1335,11 @@ void LLPanelPeople::onAvatarListDoubleClicked(LLUICtrl* ctrl) } // [RLVa:KB] - Checked: RLVa-2.0.1 - if ( (RlvActions::isRlvEnabled()) && (NEARBY_TAB_NAME == getActiveTabName()) && (!RlvActions::canShowName(RlvActions::SNC_DEFAULT, clicked_id)) ) - { - return; - } + // Firestorm radar; commented out + //if ( (RlvActions::isRlvEnabled()) && (NEARBY_TAB_NAME == getActiveTabName()) && (!RlvActions::canShowName(RlvActions::SNC_DEFAULT, clicked_id)) ) + //{ + // return; + //} // [/RLVa:KB] #if 0 // SJB: Useful for testing, but not currently functional or to spec @@ -1457,13 +1459,14 @@ void LLPanelPeople::onImButtonClicked() uuid_vec_t selected_uuids; getCurrentItemIDs(selected_uuids); // [RLVa:KB] - Checked: RLVa-2.0.1 - if ( (RlvActions::isRlvEnabled()) && (NEARBY_TAB_NAME == getActiveTabName()) && (!RlvActions::canShowName(RlvActions::SNC_DEFAULT)) ) - { - bool fCanShowNames = true; - std::for_each(selected_uuids.begin(), selected_uuids.end(), [&fCanShowNames](const LLUUID& idAgent) { fCanShowNames &= RlvActions::canShowName(RlvActions::SNC_DEFAULT, idAgent); }); - if (!fCanShowNames) - return; - } + // Firestorm radar; commented out + //if ( (RlvActions::isRlvEnabled()) && (NEARBY_TAB_NAME == getActiveTabName()) && (!RlvActions::canShowName(RlvActions::SNC_DEFAULT)) ) + //{ + // bool fCanShowNames = true; + // std::for_each(selected_uuids.begin(), selected_uuids.end(), [&fCanShowNames](const LLUUID& idAgent) { fCanShowNames &= RlvActions::canShowName(RlvActions::SNC_DEFAULT, idAgent); }); + // if (!fCanShowNames) + // return; + //} // [/RLVa:KB] if ( selected_uuids.size() == 1 ) { diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index 17747f2d1f..ea3ca077c9 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -71,6 +71,7 @@ public: // [RLVa:KB] - Checked: RLVa-1.2.0 LLAvatarList* getNearbyList() { return mNearbyList; } + void updateNearbyList(); // [/RLVa:KB] // internals @@ -94,7 +95,7 @@ private: void updateFriendListHelpText(); void updateFriendList(); bool updateSuggestedFriendList(); - void updateNearbyList(); +// void updateNearbyList(); void updateRecentList(); void updateFacebookList(bool visible); diff --git a/indra/newview/llpresetsmanager.cpp b/indra/newview/llpresetsmanager.cpp index aed8ae5993..dec8629946 100644 --- a/indra/newview/llpresetsmanager.cpp +++ b/indra/newview/llpresetsmanager.cpp @@ -62,7 +62,10 @@ void LLPresetsManager::triggerChangeSignal() void LLPresetsManager::createMissingDefault() { - std::string default_file = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, PRESETS_GRAPHIC, PRESETS_DEFAULT + ".xml"); + // FIRE-19810: Make presets global since PresetGraphicActive setting is global as well + //std::string default_file = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, PRESETS_GRAPHIC, PRESETS_DEFAULT + ".xml"); + std::string default_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR, PRESETS_GRAPHIC, PRESETS_DEFAULT + ".xml"); + // if (!gDirUtilp->fileExists(default_file)) { LL_INFOS() << "No default preset found -- creating one at " << default_file << LL_ENDL; @@ -78,7 +81,10 @@ void LLPresetsManager::createMissingDefault() std::string LLPresetsManager::getPresetsDir(const std::string& subdirectory) { - std::string presets_path = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR); + // FIRE-19810: Make presets global since PresetGraphicActive setting is global as well + //std::string presets_path = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR); + std::string presets_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR); + // std::string full_path; if (!gDirUtilp->fileExists(presets_path)) @@ -86,7 +92,10 @@ std::string LLPresetsManager::getPresetsDir(const std::string& subdirectory) LLFile::mkdir(presets_path); } - full_path = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, subdirectory); + // FIRE-19810: Make presets global since PresetGraphicActive setting is global as well + //full_path = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, subdirectory); + full_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR, subdirectory); + // if (!gDirUtilp->fileExists(full_path)) { LLFile::mkdir(full_path); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 8e16845d35..2b2cad4d61 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -220,6 +220,7 @@ #include "fsavatarrenderpersistence.h" #include "fscommon.h" +#include "fscorehttputil.h" #include "fsdata.h" #include "fsfloatercontacts.h" #include "fsfloaterimcontainer.h" @@ -320,6 +321,9 @@ void apply_udp_blacklist(const std::string& csv); bool process_login_success_response(U32 &first_sim_size_x, U32 &first_sim_size_y); // Aurora Sim void transition_back_to_login_panel(const std::string& emsg); +// FIRE-18250: Option to disable default eye movement +void update_static_eyes(); +// FIRE-18250 void callback_cache_name(const LLUUID& id, const std::string& full_name, bool is_group) { @@ -1960,6 +1964,11 @@ bool idle_startup() display_startup(); // [FS communication UI] + // FIRE-18250: Option to disable default eye movement + gAgent.addRegionChangedCallback(boost::bind(&update_static_eyes)); + update_static_eyes(); + // + // *Note: this is where gWorldMap used to be initialized. // register null callbacks for audio until the audio system is initialized @@ -2898,15 +2907,6 @@ bool idle_startup() } // - - // FIRE-18250: Option to disable default eye movement - if (gSavedPerAccountSettings.getBOOL("FSStaticEyes")) - { - LLUUID anim_id(gSavedSettings.getString("FSStaticEyesUUID")); - gAgentAvatarp->startMotion(anim_id); - gAgent.sendAnimationRequest(anim_id, ANIM_REQUEST_START); - } - // return TRUE; } @@ -4494,3 +4494,13 @@ void transition_back_to_login_panel(const std::string& emsg) gSavedSettings.setBOOL("AutoLogin", FALSE); } +// FIRE-18250: Option to disable default eye movement +//static +void update_static_eyes() { + if (gSavedPerAccountSettings.getBOOL("FSStaticEyes")) + { + LLUUID anim_id(gSavedSettings.getString("FSStaticEyesUUID")); + gAgent.sendAnimationRequest(anim_id, ANIM_REQUEST_START); + } +} +// diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 7a5668b28d..1053552cba 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -195,7 +195,12 @@ LLStatusBar::LLStatusBar(const LLRect& rect) mNearbyIcons(FALSE), // Script debug mSearchData(NULL), // Hook up and init for filtering mFilterEdit(NULL), // Edit for filtering - mSearchPanel(NULL) // Panel for filtering + mSearchPanel(NULL), // Panel for filtering + mIconPresets(NULL), + mMediaToggle(NULL), + mMouseEnterPresetsConnection(), + mMouseEnterVolumeConnection(), + mMouseEnterNearbyMediaConnection() { setRect(rect); @@ -244,6 +249,22 @@ LLStatusBar::~LLStatusBar() { mShowCoordsCtrlConnection.disconnect(); } + + // FIRE-19697: Add setting to disable graphics preset menu popup on mouse over + if (mMouseEnterPresetsConnection.connected()) + { + mMouseEnterPresetsConnection.disconnect(); + } + if (mMouseEnterVolumeConnection.connected()) + { + mMouseEnterVolumeConnection.disconnect(); + } + if (mMouseEnterNearbyMediaConnection.connected()) + { + mMouseEnterNearbyMediaConnection.disconnect(); + } + // + // LLView destructor cleans up children } @@ -285,26 +306,47 @@ BOOL LLStatusBar::postBuild() //mBtnStats = getChildView("stat_btn"); mIconPresets = getChild( "presets_icon" ); - mIconPresets->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterPresets, this)); + // FIRE-19697: Add setting to disable graphics preset menu popup on mouse over + // mIconPresets->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterPresets, this)); + if (gSavedSettings.getBOOL("FSStatusBarMenuButtonPopupOnRollover")) + { + mMouseEnterPresetsConnection = mIconPresets->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterPresets, this)); + } + // FIRE-19697: Add setting to disable graphics preset menu popup on mouse over mIconPresets->setClickedCallback(boost::bind(&LLStatusBar::onMouseEnterPresets, this)); mBtnVolume = getChild( "volume_btn" ); mBtnVolume->setClickedCallback( onClickVolume, this ); - mBtnVolume->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterVolume, this)); + // FIRE-19697: Add setting to disable status bar icon menu popup on mouseover + // mBtnVolume->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterVolume, this)); + if (gSavedSettings.getBOOL("FSStatusBarMenuButtonPopupOnRollover")) + { + mMouseEnterVolumeConnection = mBtnVolume->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterVolume, this)); + } + // FIRE-19697: Add setting to disable status bar icon menu popup on mouseover - // ## Zi: Media/Stream separation + // Media/Stream separation mStreamToggle = getChild("stream_toggle_btn"); - mStreamToggle->setClickedCallback( &LLStatusBar::onClickStreamToggle, this ); - // ## Zi: Media/Stream separation + mStreamToggle->setClickedCallback(&LLStatusBar::onClickStreamToggle, this); + // Media/Stream separation mMediaToggle = getChild("media_toggle_btn"); mMediaToggle->setClickedCallback( &LLStatusBar::onClickMediaToggle, this ); - mMediaToggle->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterNearbyMedia, this)); + // FIRE-19697: Add setting to disable status bar icon menu popup on mouseover + // mMediaToggle->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterNearbyMedia, this)); + if (gSavedSettings.getBOOL("FSStatusBarMenuButtonPopupOnRollover")) + { + mMouseEnterNearbyMediaConnection = mMediaToggle->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterNearbyMedia, this)); + } + // FIRE-19697: Add setting to disable status bar icon menu popup on mouseover LLHints::registerHintTarget("linden_balance", getChild("balance_bg")->getHandle()); gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&LLStatusBar::onVolumeChanged, this, _2)); + // FIRE-19697: Add setting to disable graphics preset menu popup on mouse over + gSavedSettings.getControl("FSStatusBarMenuButtonPopupOnRollover")->getSignal()->connect(boost::bind(&LLStatusBar::onPopupRolloverChanged, this, _2)); + // Adding Net Stat Graph S32 x = getRect().getWidth() - 2; S32 y = 0; @@ -790,8 +832,11 @@ void LLStatusBar::onClickBuyCurrency() void LLStatusBar::onMouseEnterPresets() { LLView* popup_holder = gViewerWindow->getRootView()->getChildView("popup_holder"); - LLIconCtrl* icon = getChild( "presets_icon" ); - LLRect icon_rect = icon->getRect(); + // Changed presets icon to LLButton + //LLIconCtrl* icon = getChild( "presets_icon" ); + //LLRect icon_rect = icon->getRect(); + LLRect icon_rect = mIconPresets->getRect(); + // LLRect pulldown_rect = mPanelPresetsPulldown->getRect(); pulldown_rect.setLeftTopAndSize(icon_rect.mLeft - (pulldown_rect.getWidth() - icon_rect.getWidth()), @@ -1370,7 +1415,7 @@ void LLStatusBar::onParcelIconClick(EParcelIcon icon) case PATHFINDING_DIRTY_ICON: // Pathfinding rebake functions // LLNotificationsUtil::add("PathfindingDirty"); - LLNotificationsUtil::add("PathfindingDirty",LLSD(),LLSD(),boost::bind(&LLStatusBar::rebakeRegionCallback,this,_1,_2)); + LLNotificationsUtil::add("PathfindingDirty", LLSD(), LLSD(), boost::bind(&LLStatusBar::rebakeRegionCallback, this, _1, _2)); // break; case PATHFINDING_DISABLED_ICON: @@ -1497,10 +1542,9 @@ void LLStatusBar::updateVolumeControlsVisibility(const LLSD& data) // // Pathfinding rebake functions -BOOL LLStatusBar::rebakeRegionCallback(const LLSD& notification,const LLSD& response) +BOOL LLStatusBar::rebakeRegionCallback(const LLSD& notification, const LLSD& response) { - std::string newSetName = response["message"].asString(); - S32 option = LLNotificationsUtil::getSelectedOption(notification,response); + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (option == 0) { @@ -1579,3 +1623,29 @@ void LLStatusBar::updateMenuSearchVisibility(const LLSD& data) } update(); } + +// FIRE-19697: Add setting to disable graphics preset menu popup on mouse over +void LLStatusBar::onPopupRolloverChanged(const LLSD& newvalue) +{ + bool new_value = newvalue.asBoolean(); + + if (mMouseEnterPresetsConnection.connected()) + { + mMouseEnterPresetsConnection.disconnect(); + } + if (mMouseEnterVolumeConnection.connected()) + { + mMouseEnterVolumeConnection.disconnect(); + } + if (mMouseEnterNearbyMediaConnection.connected()) + { + mMouseEnterNearbyMediaConnection.disconnect(); + } + + if (new_value) + { + mMouseEnterPresetsConnection = mIconPresets->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterPresets, this)); + mMouseEnterVolumeConnection = mBtnVolume->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterVolume, this)); + mMouseEnterNearbyMediaConnection = mMediaToggle->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterNearbyMedia, this)); + } +} diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h index 730706bb8b..8a819b914f 100644 --- a/indra/newview/llstatusbar.h +++ b/indra/newview/llstatusbar.h @@ -261,6 +261,10 @@ private: void onNavMeshStatusChange(const LLPathfindingNavMeshStatus &pNavMeshStatus); void createNavMeshStatusListenerForCurrentRegion(); // Pathfinding support + + // FIRE-19697: Add setting to disable graphics preset menu popup on mouse over + void onPopupRolloverChanged(const LLSD& newvalue); + public: /** @@ -362,6 +366,12 @@ private: boost::signals2::connection mShowCoordsCtrlConnection; boost::signals2::connection mParcelMgrConnection; + // FIRE-19697: Add setting to disable graphics preset menu popup on mouse over + boost::signals2::connection mMouseEnterPresetsConnection; + boost::signals2::connection mMouseEnterVolumeConnection; + boost::signals2::connection mMouseEnterNearbyMediaConnection; + // + // Pathfinding rebake functions BOOL rebakeRegionCallback(const LLSD& notification,const LLSD& response); diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index fc2654444a..2135829b87 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -52,6 +52,7 @@ #include "llcoproceduremanager.h" #include "llviewernetwork.h" +#include "llviewercontrol.h" void dialog_refresh_all(); @@ -758,9 +759,14 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti // and display something saying that it cost L$ LLStatusBar::sendMoneyBalanceRequest(); + // FIRE-10628 - Option to supress upload cost notification + if (gSavedSettings.getBOOL("FSShowUploadPaymentToast")) + { LLSD args; args["AMOUNT"] = llformat("%d", uploadPrice); LLNotificationsUtil::add("UploadPayment", args); + } + // } } else diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index fa30a9f294..6c5afb8b3b 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -169,6 +169,7 @@ #include "floatermedialists.h" #include "fsareasearch.h" #include "fsfloateraddtocontactset.h" +#include "fsfloateravatarrendersettings.h" #include "fsfloatercontacts.h" #include "fsfloatercontactsetconfiguration.h" #include "fsfloaterexport.h" @@ -439,6 +440,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("export_collada", "floater_export_collada.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("delete_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("floater_profile", "floater_profile_view.xml",&LLFloaterReg::build); + LLFloaterReg::add("fs_avatar_render_settings", "floater_fs_avatar_render_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("fs_blocklist", "floater_fs_blocklist.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("fs_add_contact", "floater_fs_contact_add.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("fs_contact_set_config", "floater_fs_contact_set_configuration.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp index 453c93ea4c..2c91fbad67 100644 --- a/indra/newview/llviewerjointattachment.cpp +++ b/indra/newview/llviewerjointattachment.cpp @@ -174,10 +174,10 @@ BOOL LLViewerJointAttachment::addObject(LLViewerObject* object) { LL_INFOS() << "(same object re-attached)" << LL_ENDL; // [SL:KB] - Patch: Appearance-TeleportAttachKill | Checked: Catznip-4.0 - if ( (object->permYouOwner()) && (gAgentAvatarp) ) - { - gAgentAvatarp->removePendingDetach(object->getID()); - } +// if ( (object->permYouOwner()) && (gAgentAvatarp) ) +// { +// gAgentAvatarp->removePendingDetach(object->getID()); +// } // [/SL:KB] removeObject(object); // Pass through anyway to let setupDrawable() diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index b591378c78..68759effc6 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -50,6 +50,7 @@ #include "rlvhandler.h" // [/RLVa:KB] #include "llfloaterwebcontent.h" +#include "fsfloatersearch.h" // // Constants @@ -631,7 +632,7 @@ void start_gesture( EKeystate s ) // FIRE-4167: Don't start gesture if a floater with web content has focus LLFloater* focused_floater = gFloaterView->getFocusedFloater(); - if (focused_floater && dynamic_cast(focused_floater)) + if (focused_floater && (dynamic_cast(focused_floater) || dynamic_cast(focused_floater))) { return; } diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 6c75494ddb..ac7c2e411b 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -1888,8 +1888,6 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ bool media_plugin_debugging_enabled = gSavedSettings.getBOOL("MediaPluginDebugging"); media_source->enableMediaPluginDebugging( media_plugin_debugging_enabled || clean_browser); - media_source->setFlipY( gSavedSettings.getBOOL( "FSFlipCEFY" ) ); - // need to set agent string here before instance created media_source->setBrowserUserAgent(LLViewerMedia::getCurrentUserAgent()); @@ -3057,7 +3055,10 @@ void LLViewerMediaImpl::updateImagesMediaStreams() ////////////////////////////////////////////////////////////////////////////////////////// LLViewerMediaTexture* LLViewerMediaImpl::updatePlaceholderImage() { - if(mTextureId.isNull()) +// if(mTextureId.isNull()) +// [SL:KB] - Patch: Render-TextureToggle (Catznip-4.0) + if ( (mTextureId.isNull()) || ((LLViewerFetchedTexture::sDefaultDiffuseImagep.notNull()) && (LLViewerFetchedTexture::sDefaultDiffuseImagep->getID() == mTextureId)) ) +// [/SL:KB] { // The code that created this instance will read from the plugin's bits. return NULL; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index a14c8efe15..7e07683f96 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -7542,6 +7542,13 @@ void handle_viewer_disable_message_log(void*) void handle_customize_avatar() { + // FIRE-19614: Make CTRL-O toggle the appearance floater + if (LLFloaterReg::instanceVisible("appearance")) + { + LLFloaterReg::hideInstance("appearance"); + } + else + // LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "my_outfits")); } diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 6ca748788d..8c2f16f9ae 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -2748,17 +2748,17 @@ static void teleport_region_info_cb(const std::string& slurl, LLSD args, const L if (!can_user_access_dst_region) { - params.name = "TeleportOffered_MaturityBlocked"; + params.name = "TeleportOffered_MaturityBlocked_SLUrl"; send_simple_im(from_id, LLTrans::getString("TeleportMaturityExceeded"), IM_NOTHING_SPECIAL, session_id); send_simple_im(from_id, LLStringUtil::null, IM_LURE_DECLINED, session_id); } else if (does_user_require_maturity_increase) { - params.name = "TeleportOffered_MaturityExceeded"; + params.name = "TeleportOffered_MaturityExceeded_SLUrl"; } else { - params.name = "TeleportOffered"; + params.name = "TeleportOffered_SLUrl"; params.functor.name = "TeleportOffered"; } @@ -2925,11 +2925,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // do nothing -- don't distract newbies in // Prelude with global IMs } -// [RLVa:KB] - Checked: 2011-05-28 (RLVa-1.4.0) - else if ( (rlv_handler_t::isEnabled()) && (offline == IM_ONLINE) && ("@version" == message) && - (!is_muted) && ((!accept_im_from_only_friend) || (is_friend)) ) +// [RLVa:KB] - Checked: RLVa-2.0.3 + else if ( (RlvActions::isRlvEnabled()) && (RlvSettings::getEnableIMQuery()) && (offline == IM_ONLINE) && ("@version" == message) && (!is_muted) && ((!accept_im_from_only_friend) || (is_friend)) ) { - RlvUtil::sendBusyMessage(from_id, RlvStrings::getVersion(), session_id); + RlvUtil::sendBusyMessage(from_id, RlvStrings::getVersion(LLUUID::null), session_id); } // [/RLVa:KB] // else if (offline == IM_ONLINE @@ -3936,7 +3935,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) payload["region_maturity"] = region_access; // FIRE-6786: Always show teleport location in teleport offer - if (dialog == IM_LURE_USER && (!rlv_handler_t::isEnabled() || !fRlvAutoAccept)) + if (dialog == IM_LURE_USER && (!rlv_handler_t::isEnabled() || !fRlvAutoAccept) && LLGridManager::instance().isInSecondLife()) { LLVector3d pos_global = from_region_handle(region_handle); pos_global += LLVector3d(pos); @@ -4210,7 +4209,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // Make osx dashboard icon bounce when window isn't in focus //if (viewer_window && viewer_window->getMinimized()) static LLCachedControl sFlashIcon(gSavedSettings, "FSFlashOnMessage"); - if (viewer_window && dialog != IM_TYPING_START && dialog != IM_TYPING_STOP && sFlashIcon) + static LLCachedControl sFSFlashOnObjectIM(gSavedSettings, "FSFlashOnObjectIM"); + if (viewer_window && dialog != IM_TYPING_START && dialog != IM_TYPING_STOP && sFlashIcon && (sFSFlashOnObjectIM || (chat.mChatType != CHAT_TYPE_IM))) { viewer_window->flashIcon(5.f); } @@ -4733,7 +4733,8 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) // [RLVa:KB] - Checked: 2010-02-XX (RLVa-1.2.0a) | Modified: RLVa-1.1.0f // TODO-RLVa: [RLVa-1.2.0] consider rewriting this before a RLVa-1.2.0 release - if ( (rlv_handler_t::isEnabled()) && (mesg.length() > 3) && (RLV_CMD_PREFIX == mesg[0]) && (CHAT_TYPE_OWNER == chat.mChatType) ) + if ( (rlv_handler_t::isEnabled()) && (mesg.length() > 3) && (RLV_CMD_PREFIX == mesg[0]) && (CHAT_TYPE_OWNER == chat.mChatType) && + ((!chatter) || (!chatter->isAttachment()) || (!chatter->isTempAttachment()) || (RlvSettings::getEnableTemporaryAttachments())) ) { mesg.erase(0, 1); LLStringUtil::toLower(mesg); @@ -5966,11 +5967,11 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data) if (objectp) { // [SL:KB] - Patch: Appearance-TeleportAttachKill | Checked: Catznip-4.0 - if ( (objectp->isAttachment()) && (gAgentAvatarp) && (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) && (objectp->permYouOwner()) ) - { - gAgentAvatarp->addPendingDetach(objectp->getRootEdit()->getID()); - continue; - } +// if ( (objectp->isAttachment()) && (gAgentAvatarp) && (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) && (objectp->permYouOwner()) ) +// { +// gAgentAvatarp->addPendingDetach(objectp->getRootEdit()->getID()); +// continue; +// } // [/SL:KB] // Display green bubble on kill @@ -6370,8 +6371,6 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data) { // Cut down logspam //LL_WARNS() << "Unknown sim stat identifier: " << stat_id << LL_ENDL; - LL_WARNS_ONCE() << "Unknown sim stat identifier: " << stat_id << LL_ENDL; - // } } diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 6435d19a53..c94939ea8d 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -551,7 +551,8 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mInvisibilityCheckHistory(-1), mPaused(FALSE), // Aurora Sim - mWidth(region_width_meters) + mWidth(region_width_meters), + mWidthScaleFactor(region_width_meters / REGION_WIDTH_METERS) // FIRE-19563: Scaling for OpenSim VarRegions { // Moved this up... -> mWidth = region_width_meters; // @@ -2176,8 +2177,12 @@ public: if(i == target_index) { LLVector3d global_pos(region->getOriginGlobal()); - global_pos.mdV[VX] += (F64)x; - global_pos.mdV[VY] += (F64)y; + // FIRE-19563: Scaling for OpenSim VarRegions + //global_pos.mdV[VX] += (F64)x; + //global_pos.mdV[VY] += (F64)y; + global_pos.mdV[VX] += (F64)x * region->getWidthScaleFactor(); + global_pos.mdV[VY] += (F64)y * region->getWidthScaleFactor(); + // global_pos.mdV[VZ] += (F64)z * 4.0; LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos); } @@ -2251,8 +2256,12 @@ void LLViewerRegion::updateCoarseLocations(LLMessageSystem* msg) if(i == target_index) { LLVector3d global_pos(mImpl->mOriginGlobal); - global_pos.mdV[VX] += (F64)(x_pos); - global_pos.mdV[VY] += (F64)(y_pos); + // FIRE-19563: Scaling for OpenSim VarRegions + //global_pos.mdV[VX] += (F64)(x_pos); + //global_pos.mdV[VY] += (F64)(y_pos); + global_pos.mdV[VX] += (F64)(x_pos) * mWidthScaleFactor; + global_pos.mdV[VY] += (F64)(y_pos) * mWidthScaleFactor; + // global_pos.mdV[VZ] += (F64)(z_pos) * 4.0; LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos); } @@ -2315,7 +2324,7 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features) std::stringstream str; LLSDSerialize::toPrettyXML(sim_features, str); - LL_INFOS() << str.str() << LL_ENDL; + LL_INFOS() << "Region ID " << getRegionID().asString() << ": " << str.str() << LL_ENDL; mSimulatorFeatures = sim_features; setSimulatorFeaturesReceived(true); diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 075f6c4496..2fe9be3f02 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -240,6 +240,7 @@ public: void setCacheID(const LLUUID& id); F32 getWidth() const { return mWidth; } + F32 getWidthScaleFactor() const { return mWidthScaleFactor; } // FIRE-19563: Scaling for OpenSim VarRegions void idleUpdate(F32 max_update_time); void lightIdleUpdate(); @@ -495,6 +496,7 @@ private: U64 mHandle; F32 mTimeDilation; // time dilation of physics simulation on simulator S32 mLastUpdate; //last time called idleUpdate() + F32 mWidthScaleFactor; // FIRE-19563: Scaling for OpenSim VarRegions // simulator name std::string mName; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 6b60879548..b12b24e4ad 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -68,11 +68,7 @@ const S32Megabytes gMinVideoRam(32); // Texture memory management //const S32Megabytes gMaxVideoRam(512); -#ifdef ND_BUILD64BIT_ARCH -const S32Megabytes gMaxVideoRam(1024); -#else -const S32Megabytes gMaxVideoRam(512); -#endif +S32Megabytes gMaxVideoRam(512); // @@ -3781,37 +3777,6 @@ void LLViewerMediaTexture::switchTexture(U32 ch, LLFace* facep) if(mIsPlaying) //old textures switch to the media texture { - // If using CEF then set a texture matrix to flip around the Y Axis. - static bool sFlipY = gSavedSettings.getBOOL( "FSFlipCEFY" ); - - LLViewerMediaImpl *pMedia = mMediaImplp; - if( !pMedia ) - pMedia = LLViewerMedia::getMediaImplFromTextureID(mID); - - std::string strMimeType; - if( pMedia ) - strMimeType = pMedia->getMimeType(); - - std::string strImpl = LLMIMETypes::implType( strMimeType ); - bool bCoordsOpenGl = sFlipY; - if( pMedia && pMedia->getMediaPlugin() ) - bCoordsOpenGl = pMedia->getMediaPlugin()->getTextureCoordsOpenGL(); - - if( strImpl == "media_plugin_cef" && !bCoordsOpenGl ) - { - if( !facep->mTextureMatrix ) - { - facep->mTextureMatrix = new LLMatrix4(); - facep->mTextureMatrix->mMatrix[ 1 ][ 1 ] = -1.0f; - facep->mTextureMatrix->mMatrix[ 2 ][ 1 ] = 1.0f; - } - else - { - LL_WARNS() << "Matrix for media face is already set." << LL_ENDL; - } - } - // - facep->switchTexture(ch, this); } else //switch to old textures. diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 04afa120e4..8de0f82233 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -40,7 +40,10 @@ #include extern const S32Megabytes gMinVideoRam; -extern const S32Megabytes gMaxVideoRam; +// Texture memory management +//extern const S32Megabytes gMaxVideoRam; +extern S32Megabytes gMaxVideoRam; +// class LLFace; class LLImageGL ; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 5fa0ddec08..b1abad9be5 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1877,6 +1877,32 @@ LLViewerWindow::LLViewerWindow(const Params& p) LLFeatureManager::getInstance()->setGraphicsLevel(0, false); gSavedSettings.setU32("RenderQualityPerformance", 0); } + + // Texture memory management + // On 64bit builds, allow up to 1GB texture memory on cards with 2GB video + // memory and up to 2GB texture memory on cards with 4GB video memory. Check + // is performed against a lower limit as not exactly 2 or 4GB might not be + // returned. +#ifdef ND_BUILD64BIT_ARCH + LL_INFOS() << "GLManager detected " << gGLManager.mVRAM << " MB VRAM" << LL_ENDL; + + if (gGLManager.mVRAM > 3584) + { + gMaxVideoRam = S32Megabytes(2048); + LL_INFOS() << "At least 4 GB video memory detected - increasing max video ram for textures to 2048 MB" << LL_ENDL; + } + else if (gGLManager.mVRAM > 1536) + { + gMaxVideoRam = S32Megabytes(1024); + LL_INFOS() << "At least 2 GB video memory detected - increasing max video ram for textures to 1024 MB" << LL_ENDL; + } + else if (gGLManager.mVRAM > 768) + { + gMaxVideoRam = S32Megabytes(768); + LL_INFOS() << "At least 1 GB video memory detected - increasing max video ram for textures to 768 MB" << LL_ENDL; + } +#endif + // // Init the image list. Must happen after GL is initialized and before the images that // LLViewerWindow needs are requested. diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index a8b50cb59c..0c437617ae 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -3221,26 +3221,30 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) } // - // Show Arc in nametag (for Jelly Dolls) - // ...or everyone, if selected - static LLCachedControl show_too_complex_arw_tag(gSavedSettings, "FSTagShowTooComplexARW"); - static LLCachedControl show_arw_always_tag(gSavedSettings, "FSTagAlwaysShowARW"); + // Show ARW in nametag options (for Jelly Dolls) + static LLCachedControl show_arw_tag(gSavedSettings, "FSTagShowARW"); + static LLCachedControl show_too_complex_only_arw_tag(gSavedSettings, "FSTagShowTooComplexOnlyARW"); + static LLCachedControl show_own_arw_tag(gSavedSettings, "FSTagShowOwnARW"); U32 complexity(0); LLColor4 complexity_color(LLColor4::grey1); // default if we're not limiting the complexity - if (!isSelf() && (show_arw_always_tag || (show_too_complex_arw_tag && isTooComplex()))) + if (show_arw_tag && + ((isSelf() && show_own_arw_tag) || + (!isSelf() && (!show_too_complex_only_arw_tag || isTooComplex())))) { complexity = mVisualComplexity; - // This calculation is copied from idleUpdateRenderComplexity() + + // Show complexity color if we're limiting and not showing our own ARW... static LLCachedControl max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0); - // Show complexity color if we're limiting... - if (max_render_cost != 0) + if (max_render_cost != 0 && !isSelf()) { + // This calculation is copied from idleUpdateRenderComplexity() F32 green_level = 1.f - llclamp(((F32)complexity - (F32)max_render_cost) / (F32)max_render_cost, 0.f, 1.f); F32 red_level = llmin((F32)complexity / (F32)max_render_cost, 1.f); complexity_color.set(red_level, green_level, 0.f, 1.f); } } + // // Rebuild name tag if state change detected if (!mNameIsSet @@ -3439,10 +3443,11 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) } // Show distance in tag - // Show Arc in nametag (for Jelly Dolls) - // ...or everyone, if selected + // Show ARW in nametag options (for Jelly Dolls) static const std::string complexity_label = LLTrans::getString("Nametag_Complexity_Label"); - if (!isSelf() && (show_arw_always_tag || (show_too_complex_arw_tag && isTooComplex()))) + if (show_arw_tag && + ((isSelf() && show_own_arw_tag) || + (!isSelf() && (!show_too_complex_only_arw_tag || isTooComplex())))) { std::string complexity_string; LLLocale locale(LLLocale::USER_LOCALE); diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index fb08106ead..bfc9ab8964 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -3323,57 +3323,57 @@ void LLVOAvatarSelf::dumpWearableInfo(LLAPRFile& outfile) } // [SL:KB] - Patch: Appearance-TeleportAttachKill | Checked: Catznip-4.0 -void LLVOAvatarSelf::addPendingDetach(const LLUUID& idObject) -{ - if (mPendingObjectDetach.end() == std::find(mPendingObjectDetach.begin(), mPendingObjectDetach.end(), idObject)) - mPendingObjectDetach.push_back(idObject); - - if ((!mPendingObjectDetach.empty()) && (!mTeleportDoneConn.connected())) - mTeleportDoneConn = LLViewerParcelMgr::instance().setTeleportDoneCallback(boost::bind(&LLVOAvatarSelf::onTeleportDone, this)); -} - -bool LLVOAvatarSelf::isPendingDetach(const LLUUID& idObject) const -{ - return mPendingObjectDetach.end() != std::find(mPendingObjectDetach.begin(), mPendingObjectDetach.end(), idObject); -} - -void LLVOAvatarSelf::removePendingDetach(const LLUUID& idObject) -{ - auto itPendingDetach = std::find(mPendingObjectDetach.begin(), mPendingObjectDetach.end(), idObject); - if (mPendingObjectDetach.end() != itPendingDetach) - mPendingObjectDetach.erase(itPendingDetach); - - if (mPendingObjectDetach.empty()) - mTeleportDoneConn.disconnect(); -} - -void LLVOAvatarSelf::onTeleportDone() -{ - mTeleportDoneConn.disconnect(); - doAfterInterval(boost::bind(&LLVOAvatarSelf::checkPendingDetach, this), 30.f); -} - -void LLVOAvatarSelf::checkPendingDetach() -{ - if (gTeleportDisplay) - return; - - for (const LLUUID& idObj : mPendingObjectDetach) - { - LLViewerObject* pObject = gObjectList.findObject(idObj); - if (pObject) - { - gObjectList.killObject(pObject); - if (gShowObjectUpdates) - { - LLColor4 color(0.f, 1.f, 0.f, 1.f); - gPipeline.addDebugBlip(pObject->getPositionAgent(), color); - } - LLSelectMgr::getInstance()->removeObjectFromSelections(idObj); - } - } - mPendingObjectDetach.clear(); -} +//void LLVOAvatarSelf::addPendingDetach(const LLUUID& idObject) +//{ +// if (mPendingObjectDetach.end() == std::find(mPendingObjectDetach.begin(), mPendingObjectDetach.end(), idObject)) +// mPendingObjectDetach.push_back(idObject); +// +// if ((!mPendingObjectDetach.empty()) && (!mTeleportDoneConn.connected())) +// mTeleportDoneConn = LLViewerParcelMgr::instance().setTeleportDoneCallback(boost::bind(&LLVOAvatarSelf::onTeleportDone, this)); +//} +// +//bool LLVOAvatarSelf::isPendingDetach(const LLUUID& idObject) const +//{ +// return mPendingObjectDetach.end() != std::find(mPendingObjectDetach.begin(), mPendingObjectDetach.end(), idObject); +//} +// +//void LLVOAvatarSelf::removePendingDetach(const LLUUID& idObject) +//{ +// auto itPendingDetach = std::find(mPendingObjectDetach.begin(), mPendingObjectDetach.end(), idObject); +// if (mPendingObjectDetach.end() != itPendingDetach) +// mPendingObjectDetach.erase(itPendingDetach); +// +// if (mPendingObjectDetach.empty()) +// mTeleportDoneConn.disconnect(); +//} +// +//void LLVOAvatarSelf::onTeleportDone() +//{ +// mTeleportDoneConn.disconnect(); +// doAfterInterval(boost::bind(&LLVOAvatarSelf::checkPendingDetach, this), 30.f); +//} +// +//void LLVOAvatarSelf::checkPendingDetach() +//{ +// if (gTeleportDisplay) +// return; +// +// for (const LLUUID& idObj : mPendingObjectDetach) +// { +// LLViewerObject* pObject = gObjectList.findObject(idObj); +// if (pObject) +// { +// gObjectList.killObject(pObject); +// if (gShowObjectUpdates) +// { +// LLColor4 color(0.f, 1.f, 0.f, 1.f); +// gPipeline.addDebugBlip(pObject->getPositionAgent(), color); +// } +// LLSelectMgr::getInstance()->removeObjectFromSelections(idObj); +// } +// } +// mPendingObjectDetach.clear(); +//} // [/SL:KB] // [RLVa:KB] - Checked: 2013-03-03 (RLVa-1.4.8) diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 84946ce5a3..5890fa9a86 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -395,6 +395,26 @@ bool LLVivoxVoiceClient::writeString(const std::string &str) return result; } +// On Linux the viewer can run SLVoice.exe through wine (https://www.winehq.org/) +// Vivox does not support Linux anymore and the SDK SLVoice for Linux uses is old and according to LL +// will stop working 'soon' (as of 2016-07-17). See also FIRE-19663 +bool viewerUsesWineForVoice() +{ +#ifndef LL_LINUX + return false; +#else + static LLCachedControl sEnableVoiceChat(gSavedSettings, "FSLinuxEnableWin32VoiceProxy" ); + + return sEnableVoiceChat; +#endif +} + +bool viewerChoosesConnectionHandles() +{ + return viewerUsesWineForVoice(); +} +// + ///////////////////////////// // session control messages @@ -425,13 +445,19 @@ void LLVivoxVoiceClient::connectorCreate() loglevel = savedLogLevel; // } + + // Check if using the old SLVoice for Linux. the SDK in that version is too old to handle the extra args + std::string strConnectorHandle; + if( viewerChoosesConnectionHandles() ) + strConnectorHandle = "" + LLVivoxSecurity::getInstance()->connectorHandle() + ""; + // stream << "" << "V2 SDK" << "" << mVoiceAccountServerURI << "" << "Normal" - << "" << LLVivoxSecurity::getInstance()->connectorHandle() << "" + << strConnectorHandle // Voice in multiple instances; by Latif Khalifa << (gSavedSettings.getBOOL("VoiceMultiInstance") ? "3000050000" : "") // @@ -451,7 +477,10 @@ void LLVivoxVoiceClient::connectorCreate() void LLVivoxVoiceClient::connectorShutdown() { - if(!mConnectorEstablished) + // Voice fix + //if(!mConnectorEstablished) + if(mConnectorEstablished) + // { std::ostringstream stream; stream @@ -649,7 +678,13 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() #elif LL_DARWIN exe_path += "../Resources/SLVoice"; #else - exe_path += "SLVoice"; + // On Linux the viewer can run SLVoice.exe through wine (https://www.winehq.org/) + // exe_path += "SLVoice"; + if( !viewerUsesWineForVoice() ) + exe_path += "SLVoice"; // native version + else + exe_path += "win32/SLVoice.exe"; // use bundled win32 version + // #endif // See if the vivox executable exists llstat s; @@ -657,8 +692,19 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() { // vivox executable exists. Build the command line and launch the daemon. LLProcess::Params params; + + // On Linux the viewer can run SLVoice.exe through wine (https://www.winehq.org/) params.executable = exe_path; + if( !viewerUsesWineForVoice() ) + params.executable = exe_path; + else + { + params.executable = "wine"; + params.args.add( exe_path ); + } + // + std::string loglevel = gSavedSettings.getString("VivoxDebugLevel"); std::string shutdown_timeout = gSavedSettings.getString("VivoxShutdownTimeout"); if (loglevel.empty()) @@ -708,6 +754,8 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() params.cwd = gDirUtilp->getAppRODataDir(); + // Check if using the old SLVoice for Linux. the SDK in that version is too old to handle the extra args + if( viewerChoosesConnectionHandles() ) { // # ifdef VIVOX_HANDLE_ARGS params.args.add("-ah"); params.args.add(LLVivoxSecurity::getInstance()->accountHandle()); @@ -715,6 +763,7 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() params.args.add("-ch"); params.args.add(LLVivoxSecurity::getInstance()->connectorHandle()); # endif // VIVOX_HANDLE_ARGS + } // sGatewayPtr = LLProcess::create(params); @@ -1878,12 +1927,18 @@ void LLVivoxVoiceClient::loginSendMessage() bool autoPostCrashDumps = gSavedSettings.getBOOL("VivoxAutoPostCrashDumps"); + // Check if using the old SLVoice for Linux. the SDK in that version is too old to handle the extra args + std::string strAccountHandle; + if( viewerChoosesConnectionHandles() ) + strAccountHandle = "" + LLVivoxSecurity::getInstance()->accountHandle() + ""; + // + stream << "" << "" << LLVivoxSecurity::getInstance()->connectorHandle() << "" << "" << mAccountName << "" << "" << mAccountPassword << "" - << "" << LLVivoxSecurity::getInstance()->accountHandle() << "" + << strAccountHandle << "VerifyAnswer" << "false" << "0" @@ -2904,6 +2959,8 @@ void LLVivoxVoiceClient::connectorCreateResponse(int statusCode, std::string &st else { // Connector created, move forward. + // Check if using the old SLVoice for Linux. the SDK in that version is too old to handle the extra args + if( viewerChoosesConnectionHandles() ) { // if (connectorHandle == LLVivoxSecurity::getInstance()->connectorHandle()) { LL_INFOS("Voice") << "Connector.Create succeeded, Vivox SDK version is " << versionID << " connector handle " << connectorHandle << LL_ENDL; @@ -2921,6 +2978,15 @@ void LLVivoxVoiceClient::connectorCreateResponse(int statusCode, std::string &st << LL_ENDL; result["connector"] = LLSD::Boolean(false); } + } else { // For old Linux Voice + LL_INFOS("Voice") << "Connector.Create succeeded, Vivox SDK version is " << versionID << LL_ENDL; + mVoiceVersion.serverVersion = versionID; + LLVivoxSecurity::getInstance()->setConnectorHandle(connectorHandle); + mConnectorEstablished = true; + mTerminateDaemon = false; + + result["connector"] = LLSD::Boolean(true); + } // For old Linux voice } LLEventPumps::instance().post("vivoxClientPump", result); @@ -2948,6 +3014,11 @@ void LLVivoxVoiceClient::loginResponse(int statusCode, std::string &statusString else { // Login succeeded, move forward. + + // Check if using the old SLVoice for Linux. + if( !viewerChoosesConnectionHandles() ) + LLVivoxSecurity::getInstance()->setAccountHandle(accountHandle); + // mAccountLoggedIn = true; mNumberOfAliases = numberOfAliases; result["login"] = LLSD::String("response_ok"); @@ -6623,6 +6694,7 @@ LLIOPipe::EStatus LLVivoxProtocolParser::process_impl( XML_SetUserData(parser, this); XML_Parse(parser, mInput.data() + start, delim - start, false); + LL_INFOS("Voice") << "parsing: " << mInput.substr(start, delim - start) << LL_ENDL; // If this message isn't set to be squelched, output the raw XML received. if(!squelchDebugOutput) { @@ -6785,6 +6857,8 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr) void LLVivoxProtocolParser::EndTag(const char *tag) { const std::string& string = textBuffer; + + std::cerr << tag << ": " << textBuffer << std::endl; responseDepth--; diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index b54288e32a..b48da94084 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -1050,6 +1050,11 @@ class LLVivoxSecurity : public LLSingleton std::string connectorHandle() { return mConnectorHandle; }; std::string accountHandle() { return mAccountHandle; }; + // For the old Vivox SDK used on Linux + void setConnectorHandle(const std::string& handle) { mConnectorHandle = handle; } + void setAccountHandle(const std::string& handle) { mAccountHandle = handle; } + // + private: std::string mConnectorHandle; std::string mAccountHandle; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index d7f6d43787..d2083a6eba 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3690,10 +3690,8 @@ F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes, F32* unscaled_v F32 radius = getScale().length()*0.5f; if (isMesh()) - { - LLSD& header = gMeshRepo.getMeshHeader(getVolume()->getParams().getSculptID()); - - return LLMeshRepository::getStreamingCost(header, radius, bytes, visible_bytes, mLOD, unscaled_value); + { + return gMeshRepo.getStreamingCost(getVolume()->getParams().getSculptID(), radius, bytes, visible_bytes, mLOD, unscaled_value); } else { diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 641ca5c2af..a7c63639e8 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -1746,7 +1746,7 @@ void send_agent_resume() //static LLVector3d unpackLocalToGlobalPosition(U32 compact_local, const LLVector3d& region_origin) // [SL:KB] - Patch: UI-SidepanelPeople | Checked: 2010-12-03 (Catznip-2.4.0g) | Added: Catznip-2.4.0g -LLVector3d unpackLocalToGlobalPosition(U32 compact_local, const LLVector3d& region_origin) +LLVector3d unpackLocalToGlobalPosition(U32 compact_local, const LLVector3d& region_origin, F32 width_scale_factor) // [/SL:KB] { LLVector3d pos_local; @@ -1755,13 +1755,15 @@ LLVector3d unpackLocalToGlobalPosition(U32 compact_local, const LLVector3d& regi pos_local.mdV[VY] = (compact_local >> 8) & 0xFFU; pos_local.mdV[VX] = (compact_local >> 16) & 0xFFU; + // FIRE-19563: Scaling for OpenSim VarRegions + pos_local.mdV[VX] *= width_scale_factor; + pos_local.mdV[VY] *= width_scale_factor; + // + return region_origin + pos_local; } -// Make radar more exact and prevent false region crossing notifications -//void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector* positions, const LLVector3d& relative_to, F32 radius) const -void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector* positions, const LLVector3d& relative_to, F32 radius, std::map* region_assignments) const -// +void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector* positions, const LLVector3d& relative_to, F32 radius) const { F32 radius_squared = radius * radius; @@ -1773,12 +1775,6 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector* positi { positions->clear(); } - // Make radar more exact and prevent false region crossing notifications - if (region_assignments != NULL) - { - region_assignments->clear(); - } - // // get the list of avatars from the character list first, so distances are correct // when agent is above 1020m and other avatars are nearby for (std::vector::iterator iter = LLCharacter::sInstances.begin(); @@ -1817,7 +1813,7 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector* positi // //LLVector3d pos_global = unpackLocalToGlobalPosition(regionp->mMapAvatars.at(i), origin_global); U32 compact_local = regionp->mMapAvatars.at(i); - LLVector3d pos_global = unpackLocalToGlobalPosition(compact_local, origin_global); + LLVector3d pos_global = unpackLocalToGlobalPosition(compact_local, origin_global, regionp->getWidthScaleFactor()); // if(dist_vec_squared(pos_global, relative_to) <= radius_squared) { @@ -1844,12 +1840,6 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector* positi } avatar_ids->push_back(uuid); } - // Make radar more exact and prevent false region crossing notifications - if (uuid.notNull() && region_assignments != NULL) - { - region_assignments->insert(std::make_pair(uuid, regionp->getRegionID())); - } - // } } } @@ -1874,7 +1864,7 @@ bool LLWorld::getAvatar(const LLUUID& idAvatar, LLVector3d& posAvatar) const { if (idAvatar == pRegion->mMapAvatarIDs[idxAgent]) { - posAvatar = unpackLocalToGlobalPosition(pRegion->mMapAvatars[idxAgent], pRegion->getOriginGlobal()); + posAvatar = unpackLocalToGlobalPosition(pRegion->mMapAvatars[idxAgent], pRegion->getOriginGlobal(), pRegion->getWidthScaleFactor()); return true; } } diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index bfa668eae8..4bbe548c87 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -232,9 +232,7 @@ public: void getAvatars( uuid_vec_t* avatar_ids = NULL, std::vector* positions = NULL, - // Make radar more exact and prevent false region crossing notifications - //const LLVector3d& relative_to = LLVector3d(), F32 radius = FLT_MAX) const; - const LLVector3d& relative_to = LLVector3d(), F32 radius = FLT_MAX, std::map* region_assignments = NULL) const; + const LLVector3d& relative_to = LLVector3d(), F32 radius = FLT_MAX) const; // [RLVa:KB] - Checked: RLVa-2.0.1 bool getAvatar(const LLUUID& idAvatar, LLVector3d& posAvatar) const; // [/RLVa:KB] diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp index d58781cdb9..c76192ddee 100644 --- a/indra/newview/rlvactions.cpp +++ b/indra/newview/rlvactions.cpp @@ -121,6 +121,13 @@ bool RlvActions::getCameraFOVLimits(F32& nFOVMin, F32& nFOVMax) bool RlvActions::s_BlockNamesContexts[SNC_COUNT] = { 0 }; +bool RlvActions::canChangeActiveGroup(const LLUUID& idRlvObject) +{ + // User can change their active group if: + // - not specifically restricted (by another object that the one specified) from changing their active group + return (idRlvObject.isNull()) ? !gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP) : !gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETGROUP, idRlvObject); +} + // Little helper function to check the IM exclusion range for @recvim, @sendim and @startim (returns: min_dist <= (pos user - pos target) <= max_dist) static bool rlvCheckAvatarIMDistance(const LLUUID& idAvatar, ERlvBehaviourModifier eModDistMin, ERlvBehaviourModifier eModDistMax) { @@ -206,9 +213,14 @@ bool RlvActions::canShowName(EShowNamesContext eContext, const LLUUID& idAgent) return false; } +bool RlvActions::canShowNearbyAgents() +{ + return !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNEARBY); +} + // ============================================================================ // Movement -// +// bool RlvActions::canAcceptTpOffer(const LLUUID& idSender) { diff --git a/indra/newview/rlvactions.h b/indra/newview/rlvactions.h index e11066e25a..c034e829a1 100644 --- a/indra/newview/rlvactions.h +++ b/indra/newview/rlvactions.h @@ -74,6 +74,11 @@ public: // Communication/Avatar interaction // ================================ public: + /* + * Returns true if the user is allowed to change their currently active group + */ + static bool canChangeActiveGroup(const LLUUID& idRlvObject = LLUUID::null); + /* * Returns true if the user is allowed to receive IMs from the specified sender (can be an avatar or a group) */ @@ -108,6 +113,11 @@ public: static bool canShowName(EShowNamesContext eContext, const LLUUID& idAgent = LLUUID::null); static void setShowName(EShowNamesContext eContext, bool fCanShowName) { if ( (eContext < SNC_COUNT) && (isRlvEnabled()) ) { s_BlockNamesContexts[eContext] = !fCanShowName; } } + /* + * Returns true if the user is allowed to see the presence of nearby avatars in UI elements (anonymized or otherwise) + */ + static bool canShowNearbyAgents(); + protected: // Backwards logic so that we can initialize to 0 and it won't block when we forget to/don't check if RLVa is disabled static bool s_BlockNamesContexts[SNC_COUNT]; diff --git a/indra/newview/rlvcommon.cpp b/indra/newview/rlvcommon.cpp index 341a51a805..7abb1eef4f 100644 --- a/indra/newview/rlvcommon.cpp +++ b/indra/newview/rlvcommon.cpp @@ -23,8 +23,10 @@ #include "llregionhandle.h" #include "llsdserialize.h" #include "lltrans.h" +#include "llversioninfo.h" #include "llviewerparcelmgr.h" #include "llviewermenu.h" +#include "llviewerobjectlist.h" #include "llviewerregion.h" #include "llworld.h" @@ -38,6 +40,8 @@ #include // icontains #include // regex_replace_all #include +#include + // ============================================================================ // Forward declarations @@ -76,11 +80,14 @@ void RlvNotifications::onGiveToRLVConfirmation(const LLSD& notification, const L // #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS -bool RlvSettings::fCompositeFolders = false; +bool RlvSettings::s_fCompositeFolders = false; #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS -bool RlvSettings::fCanOOC = true; -bool RlvSettings::fLegacyNaming = true; -bool RlvSettings::fNoSetEnv = false; +bool RlvSettings::s_fCanOOC = true; +bool RlvSettings::s_fLegacyNaming = true; +bool RlvSettings::s_fNoSetEnv = false; +bool RlvSettings::s_fTempAttach = true; +std::list RlvSettings::s_CompatItemCreators; +std::list RlvSettings::s_CompatItemNames; // Checked: 2010-02-27 (RLVa-1.2.0a) | Modified: RLVa-1.1.0i void RlvSettings::initClass() @@ -88,18 +95,24 @@ void RlvSettings::initClass() static bool fInitialized = false; if (!fInitialized) { + initCompatibilityMode(LLStringUtil::null); + + s_fTempAttach = rlvGetSetting(RLV_SETTING_ENABLETEMPATTACH, true); + if (gSavedSettings.controlExists(RLV_SETTING_ENABLETEMPATTACH)) + gSavedSettings.getControl(RLV_SETTING_ENABLETEMPATTACH)->getSignal()->connect(boost::bind(&onChangedSettingBOOL, _2, &s_fTempAttach)); + #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS - fCompositeFolders = rlvGetSetting(RLV_SETTING_ENABLECOMPOSITES, false); + s_fCompositeFolders = rlvGetSetting(RLV_SETTING_ENABLECOMPOSITES, false); if (gSavedSettings.controlExists(RLV_SETTING_ENABLECOMPOSITES)) - gSavedSettings.getControl(RLV_SETTING_ENABLECOMPOSITES)->getSignal()->connect(boost::bind(&onChangedSettingBOOL, _2, &fCompositeFolders)); + gSavedSettings.getControl(RLV_SETTING_ENABLECOMPOSITES)->getSignal()->connect(boost::bind(&onChangedSettingBOOL, _2, &s_fCompositeFolders)); #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS - fLegacyNaming = rlvGetSetting(RLV_SETTING_ENABLELEGACYNAMING, true); + s_fLegacyNaming = rlvGetSetting(RLV_SETTING_ENABLELEGACYNAMING, true); if (gSavedSettings.controlExists(RLV_SETTING_ENABLELEGACYNAMING)) - gSavedSettings.getControl(RLV_SETTING_ENABLELEGACYNAMING)->getSignal()->connect(boost::bind(&onChangedSettingBOOL, _2, &fLegacyNaming)); + gSavedSettings.getControl(RLV_SETTING_ENABLELEGACYNAMING)->getSignal()->connect(boost::bind(&onChangedSettingBOOL, _2, &s_fLegacyNaming)); - fCanOOC = rlvGetSetting(RLV_SETTING_CANOOC, true); - fNoSetEnv = rlvGetSetting(RLV_SETTING_NOSETENV, false); + s_fCanOOC = rlvGetSetting(RLV_SETTING_CANOOC, true); + s_fNoSetEnv = rlvGetSetting(RLV_SETTING_NOSETENV, false); // Don't allow toggling RLVaLoginLastLocation from the debug settings floater if (gSavedPerAccountSettings.controlExists(RLV_SETTING_LOGINLASTLOCATION)) @@ -154,6 +167,65 @@ void RlvSettings::onChangedSettingMain(const LLSD& sdValue) } } +void RlvSettings::initCompatibilityMode(std::string strCompatList) +{ + // NOTE: this function can be called more than once + s_CompatItemCreators.clear(); + s_CompatItemNames.clear(); + + strCompatList.append(";").append(rlvGetSetting("RLVaCompatibilityModeList", "")); + + boost_tokenizer tokCompatList(strCompatList, boost::char_separator(";", "", boost::drop_empty_tokens)); + for (const std::string& strCompatEntry : tokCompatList) + { + if (boost::starts_with(strCompatEntry, "creator:")) + { + LLUUID idCreator; + if ( (44 == strCompatEntry.size()) && (LLUUID::parseUUID(strCompatEntry.substr(8), &idCreator)) && + (s_CompatItemCreators.end() == std::find(s_CompatItemCreators.begin(), s_CompatItemCreators.end(), idCreator)) ) + { + s_CompatItemCreators.push_back(idCreator); + } + } + else if (boost::starts_with(strCompatEntry, "name:")) + { + if (strCompatEntry.size() > 5) + s_CompatItemNames.push_back(strCompatEntry.substr(5)); + } + } +} + +bool RlvSettings::isCompatibilityModeObject(const LLUUID& idRlvObject) +{ + bool fCompatMode = false; + if (idRlvObject.notNull()) + { + const LLViewerObject* pObj = gObjectList.findObject(idRlvObject); + if ( (pObj) && (pObj->isAttachment()) ) + { + const LLViewerInventoryItem* pItem = gInventory.getItem(pObj->getAttachmentItemID()); + if (pItem) + { + fCompatMode = s_CompatItemCreators.end() != std::find(s_CompatItemCreators.begin(), s_CompatItemCreators.end(), pItem->getCreatorUUID()); + if (!fCompatMode) + { + const std::string& strAttachName = pItem->getName(); + for (const std::string& strCompatName : s_CompatItemNames) + { + boost::regex regexp(strCompatName, boost::regex::perl | boost::regex::icase); + if (boost::regex_match(strAttachName, regexp)) + { + fCompatMode = true; + break; + } + } + } + } + } + } + return fCompatMode; +} + // ============================================================================ // RlvStrings // @@ -316,27 +388,26 @@ const char* RlvStrings::getStringFromReturnCode(ERlvCmdRet eRet) return NULL; } -// Checked: 2012-02-25 (RLVa-1.4.5) | Modified: RLVa-1.4.5 -std::string RlvStrings::getVersion(bool fLegacy) +std::string RlvStrings::getVersion(const LLUUID& idRlvObject, bool fLegacy) { + bool fCompatMode = RlvSettings::isCompatibilityModeObject(idRlvObject); return llformat("%s viewer v%d.%d.%d (RLVa %d.%d.%d)", ( (!fLegacy) ? "RestrainedLove" : "RestrainedLife" ), - RLV_VERSION_MAJOR, RLV_VERSION_MINOR, RLV_VERSION_PATCH, + (!fCompatMode) ? RLV_VERSION_MAJOR : RLV_VERSION_MAJOR_COMPAT, (!fCompatMode) ? RLV_VERSION_MINOR : RLV_VERSION_MINOR_COMPAT, (!fCompatMode) ? RLV_VERSION_PATCH : RLV_VERSION_PATCH_COMPAT, RLVa_VERSION_MAJOR, RLVa_VERSION_MINOR, RLVa_VERSION_PATCH); } -// Checked: 2010-04-18 (RLVa-1.4.0a) | Added: RLVa-1.2.0e std::string RlvStrings::getVersionAbout() { - return llformat("RLV v%d.%d.%d / RLVa v%d.%d.%d%c" , - RLV_VERSION_MAJOR, RLV_VERSION_MINOR, RLV_VERSION_PATCH, - RLVa_VERSION_MAJOR, RLVa_VERSION_MINOR, RLVa_VERSION_PATCH, 'a' + RLVa_VERSION_BUILD); + return llformat("RLV v%d.%d.%d / RLVa v%d.%d.%d.%d", RLV_VERSION_MAJOR, RLV_VERSION_MINOR, RLV_VERSION_PATCH, RLVa_VERSION_MAJOR, RLVa_VERSION_MINOR, RLVa_VERSION_PATCH, LLVersionInfo::getBuild()); } -// Checked: 2010-03-27 (RLVa-1.4.0a) | Modified: RLVa-1.1.0a -std::string RlvStrings::getVersionNum() +std::string RlvStrings::getVersionNum(const LLUUID& idRlvObject) { - return llformat("%d%02d%02d%02d", RLV_VERSION_MAJOR, RLV_VERSION_MINOR, RLV_VERSION_PATCH, RLV_VERSION_BUILD); + bool fCompatMode = RlvSettings::isCompatibilityModeObject(idRlvObject); + return llformat("%d%02d%02d%02d", + (!fCompatMode) ? RLV_VERSION_MAJOR : RLV_VERSION_MAJOR_COMPAT, (!fCompatMode) ? RLV_VERSION_MINOR : RLV_VERSION_MINOR_COMPAT, + (!fCompatMode) ? RLV_VERSION_PATCH : RLV_VERSION_PATCH_COMPAT, (!fCompatMode) ? RLV_VERSION_BUILD : RLV_VERSION_BUILD_COMPAT); } // Checked: 2011-11-08 (RLVa-1.5.0) @@ -387,20 +458,21 @@ void RlvUtil::filterLocation(std::string& strUTF8Text) } // Checked: 2010-12-08 (RLVa-1.2.2c) | Modified: RLVa-1.2.2c -void RlvUtil::filterNames(std::string& strUTF8Text, bool fFilterLegacy) +void RlvUtil::filterNames(std::string& strUTF8Text, bool fFilterLegacy, bool fClearMatches) { uuid_vec_t idAgents; LLWorld::getInstance()->getAvatars(&idAgents, NULL); for (int idxAgent = 0, cntAgent = idAgents.size(); idxAgent < cntAgent; idxAgent++) { LLAvatarName avName; - if ( (LLAvatarNameCache::get(idAgents[idxAgent], &avName)) && (!RlvActions::canShowName(RlvActions::SNC_DEFAULT, idAgents[idxAgent])) ) + // NOTE: if we're agressively culling nearby names then ignore exceptions + if ( (LLAvatarNameCache::get(idAgents[idxAgent], &avName)) && ((fClearMatches) || (!RlvActions::canShowName(RlvActions::SNC_DEFAULT, idAgents[idxAgent]))) ) { const std::string& strDisplayName = escape_for_regex(avName.getDisplayName()); bool fFilterDisplay = (strDisplayName.length() > 2); const std::string& strLegacyName = avName.getLegacyName(); fFilterLegacy &= (strLegacyName.length() > 2); - const std::string& strAnonym = RlvStrings::getAnonym(avName); + const std::string& strAnonym = (!fClearMatches) ? RlvStrings::getAnonym(avName) : LLStringUtil::null; // If the display name is a subset of the legacy name we need to filter that first, otherwise it's the other way around if (boost::icontains(strLegacyName, strDisplayName)) diff --git a/indra/newview/rlvcommon.h b/indra/newview/rlvcommon.h index c19f273770..a381fa683f 100644 --- a/indra/newview/rlvcommon.h +++ b/indra/newview/rlvcommon.h @@ -81,20 +81,22 @@ class RlvSettings { public: static bool getDebug() { return rlvGetSetting(RLV_SETTING_DEBUG, false); } - static bool getCanOOC() { return fCanOOC; } + static bool getCanOOC() { return s_fCanOOC; } static bool getForbidGiveToRLV() { return rlvGetSetting(RLV_SETTING_FORBIDGIVETORLV, true); } - static bool getNoSetEnv() { return fNoSetEnv; } + static bool getNoSetEnv() { return s_fNoSetEnv; } static std::string getWearAddPrefix() { return rlvGetSetting(RLV_SETTING_WEARADDPREFIX, LLStringUtil::null); } static std::string getWearReplacePrefix() { return rlvGetSetting(RLV_SETTING_WEARREPLACEPREFIX, LLStringUtil::null); } static bool getDebugHideUnsetDup() { return rlvGetSetting(RLV_SETTING_DEBUGHIDEUNSETDUP, false); } #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS - static BOOL getEnableComposites() { return fCompositeFolders; } + static BOOL getEnableComposites() { return s_fCompositeFolders; } #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS - static bool getEnableLegacyNaming() { return fLegacyNaming; } + static bool getEnableIMQuery() { return rlvGetSetting("RLVaEnableIMQuery", true); } + static bool getEnableLegacyNaming() { return s_fLegacyNaming; } static bool getEnableSharedWear() { return rlvGetSetting(RLV_SETTING_ENABLESHAREDWEAR, false); } - static bool getHideLockedLayers() { return rlvGetSetting(RLV_SETTING_HIDELOCKEDLAYER, false); } + static bool getEnableTemporaryAttachments() { return s_fTempAttach; } + static bool getHideLockedLayers() { return rlvGetSetting(RLV_SETTING_HIDELOCKEDLAYER, false); } static bool getHideLockedAttach() { return rlvGetSetting(RLV_SETTING_HIDELOCKEDATTACH, false); } static bool getHideLockedInventory() { return rlvGetSetting(RLV_SETTING_HIDELOCKEDINVENTORY, false); } static bool getSharedInvAutoRename() { return rlvGetSetting(RLV_SETTING_SHAREDINVAUTORENAME, true); } @@ -102,6 +104,9 @@ public: static bool getLoginLastLocation() { return rlvGetPerUserSetting(RLV_SETTING_LOGINLASTLOCATION, true); } static void updateLoginLastLocation(); + static void initCompatibilityMode(std::string strCompatList); + static bool isCompatibilityModeObject(const LLUUID& idRlvObject); + static void initClass(); static void onChangedSettingMain(const LLSD& sdValue); protected: @@ -109,11 +114,19 @@ protected: static bool onChangedSettingBOOL(const LLSD& sdValue, bool* pfSetting); #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS - static BOOL fCompositeFolders; + static BOOL s_fCompositeFolders; #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS - static bool fCanOOC; - static bool fLegacyNaming; - static bool fNoSetEnv; + + /* + * Member variables + */ +protected: + static bool s_fCanOOC; + static bool s_fLegacyNaming; + static bool s_fNoSetEnv; + static bool s_fTempAttach; + static std::list s_CompatItemCreators; + static std::list s_CompatItemNames; }; // ============================================================================ @@ -132,9 +145,9 @@ public: static const std::string& getString(const std::string& strStringName); static const char* getStringFromReturnCode(ERlvCmdRet eRet); static const std::string& getStringMapPath() { return m_StringMapPath; } - static std::string getVersion(bool fLegacy = false); // @version - static std::string getVersionAbout(); // Shown in Help / About - static std::string getVersionNum(); // @versionnum + static std::string getVersion(const LLUUID& idRlvObject, bool fLegacy = false); + static std::string getVersionAbout(); + static std::string getVersionNum(const LLUUID& idRlvObject); static bool hasString(const std::string& strStringName, bool fCheckCustom = false); static void setCustomString(const std::string& strStringName, const std::string& strStringValue); @@ -157,7 +170,7 @@ public: static bool isNearbyRegion(const std::string& strRegion); // @showloc static void filterLocation(std::string& strUTF8Text); // @showloc - static void filterNames(std::string& strUTF8Text, bool fFilterLegacy = true); // @shownames + static void filterNames(std::string& strUTF8Text, bool fFilterLegacy = true, bool fClearMatches = false); // @shownames static void filterScriptQuestions(S32& nQuestions, LLSD& sdPayload); static bool isForceTp() { return m_fForceTp; } diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index a571aea4eb..7076a19275 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -1,17 +1,17 @@ -/** +/** * * Copyright (c) 2009-2016, Kitty Barnett - * - * The source code in this file is provided to you under the terms of the + * + * 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 + * 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 + * you have read and understood your obligations described above, and agree to * abide by those obligations. - * + * */ #ifndef RLV_DEFINES_H @@ -21,17 +21,22 @@ // Defines // -// Version of the specifcation we support +// 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_BUILD = 0; +// Version of the specifcation we report (in compatibility mode) +const S32 RLV_VERSION_MAJOR_COMPAT = 2; +const S32 RLV_VERSION_MINOR_COMPAT = 8; +const S32 RLV_VERSION_PATCH_COMPAT = 0; +const S32 RLV_VERSION_BUILD_COMPAT = 0; + // Implementation version const S32 RLVa_VERSION_MAJOR = 2; const S32 RLVa_VERSION_MINOR = 0; -const S32 RLVa_VERSION_PATCH = 0; -const S32 RLVa_VERSION_BUILD = 0; +const S32 RLVa_VERSION_PATCH = 3; // Uncomment before a final release #define RLV_RELEASE @@ -123,6 +128,7 @@ enum ERlvBehaviour { RLV_BHVR_SHOWLOC, // "showloc" RLV_BHVR_SHOWNAMES, // "shownames" RLV_BHVR_SHOWNAMETAGS, // "shownametags" + RLV_BHVR_SHOWNEARBY, RLV_BHVR_SHOWHOVERTEXT, // "showhovertext" RLV_BHVR_SHOWHOVERTEXTHUD, // "showhovertexthud" RLV_BHVR_SHOWHOVERTEXTWORLD, // "showhovertextworld" @@ -302,9 +308,10 @@ enum ERlvExceptionCheck enum ERlvLockMask { - RLV_LOCK_ADD = 0x01, - RLV_LOCK_REMOVE = 0x02, - RLV_LOCK_ANY = RLV_LOCK_ADD | RLV_LOCK_REMOVE + RLV_LOCK_NONE = 0x00, + RLV_LOCK_ADD = 0x01, + RLV_LOCK_REMOVE = 0x02, + RLV_LOCK_ANY = RLV_LOCK_ADD | RLV_LOCK_REMOVE }; enum ERlvWearMask @@ -343,6 +350,7 @@ enum ERlvAttachGroupType #define RLV_SETTING_ENABLECOMPOSITES "RLVaEnableCompositeFolders" #define RLV_SETTING_ENABLELEGACYNAMING "RLVaEnableLegacyNaming" #define RLV_SETTING_ENABLESHAREDWEAR "RLVaEnableSharedWear" +#define RLV_SETTING_ENABLETEMPATTACH "RLVaEnableTemporaryAttachments" #define RLV_SETTING_HIDELOCKEDLAYER "RLVaHideLockedLayers" #define RLV_SETTING_HIDELOCKEDATTACH "RLVaHideLockedAttachments" #define RLV_SETTING_HIDELOCKEDINVENTORY "RLVaHideLockedInventory" @@ -365,6 +373,7 @@ enum ERlvAttachGroupType #define RLV_STRING_BLOCKED_AUTOPILOT "blocked_autopilot" #define RLV_STRING_BLOCKED_GENERIC "blocked_generic" +#define RLV_STRING_BLOCKED_GROUPCHANGE "blocked_groupchange" #define RLV_STRING_BLOCKED_PERMATTACH "blocked_permattach" #define RLV_STRING_BLOCKED_PERMTELEPORT "blocked_permteleport" #define RLV_STRING_BLOCKED_RECVIM "blocked_recvim" diff --git a/indra/newview/rlvfloaters.cpp b/indra/newview/rlvfloaters.cpp index 7f7d49cdf8..4b4303cf27 100644 --- a/indra/newview/rlvfloaters.cpp +++ b/indra/newview/rlvfloaters.cpp @@ -234,7 +234,7 @@ void RlvFloaterBehaviours::onBtnCopyToClipboard() { std::ostringstream strRestrictions; - strRestrictions << RlvStrings::getVersion() << "\n"; + strRestrictions << RlvStrings::getVersion(LLUUID::null) << "\n"; const RlvHandler::rlv_object_map_t* pObjects = gRlvHandler.getObjectMap(); for (RlvHandler::rlv_object_map_t::const_iterator itObj = pObjects->begin(), endObj = pObjects->end(); itObj != endObj; ++itObj) diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 8508aa9443..b0837338a5 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -22,6 +22,7 @@ #include "llgroupactions.h" #include "llhudtext.h" #include "llmoveview.h" +#include "llslurl.h" #include "llstartup.h" #include "llviewermessage.h" #include "llviewermenu.h" @@ -478,21 +479,44 @@ ERlvCmdRet RlvHandler::processClearCommand(const RlvCommand& rlvCmd) // Externally invoked event handlers // -// Checked: 2011-05-22 (RLVa-1.4.1a) | Added: RLVa-1.3.1b bool RlvHandler::handleEvent(LLPointer event, const LLSD& sdUserdata) { - // If the user managed to change their active group (= newly joined or created group) we need to reactivate the previous one - if ( (hasBehaviour(RLV_BHVR_SETGROUP)) && ("new group" == event->desc()) && (m_idAgentGroup != gAgent.getGroupID()) ) + // 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()) { - // [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(); - return true; + s_idLastAgentGroup = gAgent.getGroupID(); + s_fGroupChanging = false; + } + + // 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()) ) + { + // 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"))); + + // [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; + } } else { @@ -1076,7 +1100,7 @@ BOOL RlvHandler::setEnabled(BOOL fEnable) if (fEnable) { - RLV_INFOS << "Enabling Restrained Love API support - " << RlvStrings::getVersion() << RLV_ENDL; + RLV_INFOS << "Enabling Restrained Love API support - " << RlvStrings::getVersionAbout() << RLV_ENDL; m_fEnabled = TRUE; // Initialize static classes @@ -1755,6 +1779,38 @@ void RlvBehaviourModifierHandler::onValueChange } } +// Handles: @setcam_fovmin:=n|y and @setcam_fovmax:=n|y +template<> template<> +ERlvCmdRet RlvBehaviourSetCamFovHandler::onCommand(const RlvCommand& rlvCmd, bool& fRefCount) +{ + static float s_nLastCameraAngle = DEFAULT_FIELD_OF_VIEW; + + S32 nRefMinBhvr = gRlvHandler.m_Behaviours[RLV_BHVR_SETCAM_FOVMIN], nRefMaxBhvr = gRlvHandler.m_Behaviours[RLV_BHVR_SETCAM_FOVMAX]; + LLControlVariable* pSetting = gSavedSettings.getControl("CameraAngle"); + + // Save the user's current FOV angle if nothing's been restricted (yet) + if ( (!nRefMinBhvr) && (!nRefMaxBhvr) && (pSetting) ) + s_nLastCameraAngle = (pSetting->isPersisted()) ? LLViewerCamera::instance().getDefaultFOV() : DEFAULT_FIELD_OF_VIEW; + + // Perform default handling of the command + ERlvCmdRet eRet = RlvBehaviourGenericHandler::onCommand(rlvCmd, fRefCount); + if ( (RLV_RET_SUCCESS == eRet) && (fRefCount) && (pSetting) ) + { + if (RLV_TYPE_ADD == rlvCmd.getParamType()) + { + // Don't persist changes from this point + pSetting->setPersist(LLControlVariable::PERSIST_NO); + } + else if ( (RLV_TYPE_REMOVE == rlvCmd.getParamType()) && (1 == nRefMinBhvr + nRefMaxBhvr) ) + { + // Restore the user's last FOV angle (and resume persistance) + LLViewerCamera::instance().setDefaultFOV(s_nLastCameraAngle); + pSetting->setPersist(LLControlVariable::PERSIST_NONDFT); + } + } + return eRet; +} + // Handles: @setcam_fovmin:=n|y changes template<> void RlvBehaviourModifierHandler::onValueChange() const @@ -2033,14 +2089,27 @@ ERlvCmdRet RlvBehaviourHandler::onCommand(const RlvCommand& const LLUUID idAgent = RlvCommandOptionHelper::parseOption(rlvCmd.getOption()); // Refresh the nearby people list (if necessary) - LLPanelPeople* pPeoplePanel = LLFloaterSidePanelContainer::getPanel("people", "panel_people"); - RLV_ASSERT( (pPeoplePanel) && (pPeoplePanel->getNearbyList()) ); - if ( (pPeoplePanel) && (pPeoplePanel->getNearbyList()) && (pPeoplePanel->getNearbyList()->contains(idAgent)) ) - { - if (pPeoplePanel->getNearbyList()->isInVisibleChain()) - pPeoplePanel->onCommit(); - pPeoplePanel->getNearbyList()->updateAvatarNames(); - } + // [Standalone radar] + //LLPanelPeople* pPeoplePanel = LLFloaterSidePanelContainer::getPanel("people", "panel_people"); + //RLV_ASSERT( (pPeoplePanel) && (pPeoplePanel->getNearbyList()) ); + //if ( (pPeoplePanel) && (pPeoplePanel->getNearbyList()) && (pPeoplePanel->getNearbyList()->contains(idAgent)) ) + //{ + // if (pPeoplePanel->getNearbyList()->isInVisibleChain()) + // pPeoplePanel->onCommit(); + // pPeoplePanel->getNearbyList()->updateAvatarNames(); + //} + FSRadar* pRadar = FSRadar::getInstance(); + RLV_ASSERT( (pRadar) ); + if ( (pRadar) ) + pRadar->updateNames(); + // [Standalone radar] + + // Refresh the speaker list + // [FS communication UI] + FSFloaterVoiceControls* pCallFloater = LLFloaterReg::findTypedInstance("fs_voice_controls"); + if (pCallFloater) + pCallFloater->getAvatarCallerList()->updateAvatarNames(); + // [FS communication UI] // Refresh that avatar's name tag and all HUD text LLVOAvatar::invalidateNameTag(idAgent); @@ -2073,6 +2142,47 @@ ERlvCmdRet RlvBehaviourHandler::onCommand(const RlvComman return eRet; } +// Handles: @shownearby=n|y toggles +template<> template<> +void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr) +{ + if (LLApp::isQuitting()) + return; // Nothing to do if the viewer is shutting down + + // Refresh the nearby people list + // [Standalone radar] + // -> This is handled in FSRadar (filtering all items) and + // FSPanelRadar (setting the blocked message). Since the radar + // is updated once every second, we do not hassle to explicitly + // clear it here, since it will happening almost instantly anyway + //LLPanelPeople* pPeoplePanel = LLFloaterSidePanelContainer::getPanel("people", "panel_people"); + //LLAvatarList* pNearbyList = (pPeoplePanel) ? pPeoplePanel->getNearbyList() : NULL; + //RLV_ASSERT( (pPeoplePanel) && (pNearbyList) ); + //if (pNearbyList) + //{ + // static std::string s_strNoItemsMsg = pNearbyList->getNoItemsMsg(); + // pNearbyList->setNoItemsMsg( (fHasBhvr) ? RlvStrings::getString("blocked_nearby") : s_strNoItemsMsg ); + // pNearbyList->clear(); + + // if (pNearbyList->isInVisibleChain()) + // pPeoplePanel->onCommit(); + // if (!fHasBhvr) + // pPeoplePanel->updateNearbyList(); + //} + // [Standalone radar] + + // [FS communication UI] + FSFloaterVoiceControls* pCallFloater = LLFloaterReg::findTypedInstance("fs_voice_controls"); + if (pCallFloater) + { + pCallFloater->toggleRlvShowNearbyRestriction(fHasBhvr); + } + // [FS communication UI] + + // Refresh that avatar's name tag and all HUD text + LLHUDText::refreshAllObjectText(); +} + // Handles: @showself=n|y and @showselfhead=n|y toggles template<> template<> void RlvBehaviourShowSelfToggleHandler::onCommandToggle(ERlvBehaviour eBvhr, bool fHasBhvr) @@ -2358,6 +2468,14 @@ ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlv return RLV_RET_FAILED_OPTION; LLViewerCamera::getInstance()->setDefaultFOV(nFOV); + + // Don't persist non-default changes that are due to RLV; but do resume persistance once reset back to the default + if ( (!gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_FOVMIN)) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_FOVMAX)) ) + { + if (LLControlVariable* pSetting = gSavedSettings.getControl("CameraAngle")) + pSetting->setPersist( (pSetting->isDefault()) ? LLControlVariable::PERSIST_NONDFT : LLControlVariable::PERSIST_NO ); + } + return RLV_RET_SUCCESS; } @@ -2410,7 +2528,7 @@ void RlvHandler::onForceWearCallback(const uuid_vec_t& idItems, U32 nFlags) cons template<> template<> ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd) { - if (gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETGROUP, rlvCmd.getObjectID())) + if (!RlvActions::canChangeActiveGroup(rlvCmd.getObjectID())) { return RLV_RET_FAILED_LOCK; } @@ -2566,11 +2684,11 @@ ERlvCmdRet RlvHandler::processReplyCommand(const RlvCommand& rlvCmd) const case RLV_BHVR_VERSION: // @version= - Checked: 2010-03-27 (RLVa-1.4.0a) case RLV_BHVR_VERSIONNEW: // @versionnew= - Checked: 2010-03-27 (RLVa-1.4.0a) | Added: RLVa-1.2.0b // NOTE: RLV will respond even if there's an option - strReply = RlvStrings::getVersion(RLV_BHVR_VERSION == rlvCmd.getBehaviourType()); + strReply = RlvStrings::getVersion(rlvCmd.getObjectID(), RLV_BHVR_VERSION == rlvCmd.getBehaviourType()); break; case RLV_BHVR_VERSIONNUM: // @versionnum= - Checked: 2010-03-27 (RLVa-1.4.0a) | Added: RLVa-1.0.4b // NOTE: RLV will respond even if there's an option - strReply = RlvStrings::getVersionNum(); + strReply = RlvStrings::getVersionNum(rlvCmd.getObjectID()); break; case RLV_BHVR_GETATTACH: // @getattach[:]= eRet = onGetAttach(rlvCmd, strReply); diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index 72cb58ff61..a661dc5f6e 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -123,7 +123,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourInfo("remoutfit", RLV_BHVR_REMOUTFIT, RLV_TYPE_ADDREM)); addEntry(new RlvBehaviourGenericProcessor("rez", RLV_BHVR_REZ)); addEntry(new RlvBehaviourProcessor("sendchannel", RlvBehaviourInfo::BHVR_STRICT)); - addEntry(new RlvBehaviourProcessor("sendchannel_except", RlvBehaviourInfo::BHVR_STRICT)); + 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)); @@ -144,8 +144,9 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericProcessor("showminimap", RLV_BHVR_SHOWMINIMAP)); addEntry(new RlvBehaviourToggleProcessor("shownames", RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourToggleProcessor("shownametags", RlvBehaviourInfo::BHVR_STRICT )); - addEntry(new RlvBehaviourGenericToggleProcessor("showself", RlvBehaviourInfo::BHVR_EXTENDED)); - addEntry(new RlvBehaviourGenericToggleProcessor("showselfhead", RlvBehaviourInfo::BHVR_EXTENDED)); + addEntry(new RlvBehaviourGenericToggleProcessor("shownearby", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); + addEntry(new RlvBehaviourGenericToggleProcessor("showself", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); + addEntry(new RlvBehaviourGenericToggleProcessor("showselfhead", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addEntry(new RlvBehaviourGenericProcessor("showworldmap", RLV_BHVR_SHOWWORLDMAP)); addEntry(new RlvBehaviourGenericProcessor("sit", RLV_BHVR_SIT)); addEntry(new RlvBehaviourGenericProcessor("sittp", RLV_BHVR_SITTP)); @@ -167,7 +168,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericProcessor("touchworld", RLV_BHVR_TOUCHWORLD)); addEntry(new RlvBehaviourGenericProcessor("tplm", RLV_BHVR_TPLM)); addEntry(new RlvBehaviourGenericProcessor("tploc", RLV_BHVR_TPLOC)); - addEntry(new RlvBehaviourGenericProcessor("tplocal", RLV_BHVR_TPLOCAL)); + 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)); addEntry(new RlvBehaviourGenericProcessor("tplure", RLV_BHVR_TPLURE, RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourGenericProcessor("tprequest", RLV_BHVR_TPREQUEST, RlvBehaviourInfo::BHVR_STRICT | RlvBehaviourInfo::BHVR_EXTENDED)); @@ -179,23 +180,23 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericProcessor("viewtexture", RLV_BHVR_VIEWTEXTURE)); // Camera addEntry(new RlvBehaviourGenericToggleProcessor("setcam")); - addEntry(new RlvBehaviourGenericProcessor("setcam_avdistmin", RLV_BHVR_SETCAM_AVDISTMIN)); + 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())); - addEntry(new RlvBehaviourGenericProcessor("setcam_avdistmax", RLV_BHVR_SETCAM_AVDISTMAX)); + 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)); - addEntry(new RlvBehaviourGenericProcessor("setcam_origindistmin", RLV_BHVR_SETCAM_ORIGINDISTMIN)); + 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)); - addEntry(new RlvBehaviourGenericProcessor("setcam_origindistmax", RLV_BHVR_SETCAM_ORIGINDISTMAX)); + 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)); 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 RlvBehaviourGenericProcessor("setcam_fovmin", RLV_BHVR_SETCAM_FOVMIN)); + 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)); - addEntry(new RlvBehaviourGenericProcessor("setcam_fovmax", RLV_BHVR_SETCAM_FOVMAX)); - addEntry(new RlvBehaviourGenericToggleProcessor("setcam_mouselook")); + 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)); + 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)); addEntry(new RlvBehaviourGenericToggleProcessor("setcam_unlock")); @@ -361,7 +362,7 @@ const RlvBehaviourInfo* RlvBehaviourDictionary::getBehaviourInfo(const std::stri if (pfStrict) *pfStrict = fStrict; - rlv_string2info_map_t::const_iterator itBhvr = m_String2InfoMap.find(std::make_pair(strBhvr, (eParamType & RLV_TYPE_ADDREM) ? RLV_TYPE_ADDREM : eParamType)); + rlv_string2info_map_t::const_iterator itBhvr = m_String2InfoMap.find(std::make_pair( (!fStrict) ? strBhvr : strBhvr.substr(0, strBhvr.size() - 4), (eParamType & RLV_TYPE_ADDREM) ? RLV_TYPE_ADDREM : eParamType)); return ( (itBhvr != m_String2InfoMap.end()) && ((!fStrict) || (itBhvr->second->hasStrict())) ) ? itBhvr->second : NULL; } diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h index 72b157ec94..6f9dc3c722 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -174,6 +174,7 @@ typedef RlvBehaviourToggleHandler RlvBehaviourCamEyeF typedef RlvBehaviourHandler RlvBehaviourAddRemAttachHandler; // Shared between @addattach and @remattach typedef RlvBehaviourHandler RlvBehaviourSendChannelHandler; // Shared between @sendchannel and @sendchannel_except typedef RlvBehaviourHandler RlvBehaviourRecvSendStartIMHandler; // Shared between @recvim, @sendim and @startim +typedef RlvBehaviourHandler RlvBehaviourSetCamFovHandler; // Shared between @setcam_fovmin and @setcam_fovmax typedef RlvBehaviourToggleHandler RlvBehaviourShowSelfToggleHandler; // Shared between @showself and @showselfhead typedef RlvBehaviourHandler RlvBehaviourCamZoomMinMaxHandler; // Shared between @camzoommin and @camzoommax (deprecated) typedef RlvReplyHandler RlvReplyCamMinMaxModifierHandler; // Shared between @getcam_avdistmin and @getcam_avdistmax @@ -385,7 +386,7 @@ public: */ public: std::string asString() const; - const std::string& getBehaviour() const { return (m_pBhvrInfo) ? m_pBhvrInfo->getBehaviour() : m_strBehaviour; } + const std::string& getBehaviour() const { return m_strBehaviour; } ERlvBehaviour getBehaviourType() const { return (m_pBhvrInfo) ? m_pBhvrInfo->getBehaviourType() : RLV_BHVR_UNKNOWN; } U32 getBehaviourFlags() const{ return (m_pBhvrInfo) ? m_pBhvrInfo->getBehaviourFlags() : 0; } const LLUUID& getObjectID() const { return m_idObj; } diff --git a/indra/newview/rlvlocks.cpp b/indra/newview/rlvlocks.cpp index d9dd35f793..3763e3b745 100644 --- a/indra/newview/rlvlocks.cpp +++ b/indra/newview/rlvlocks.cpp @@ -949,7 +949,7 @@ protected: // Checked: 2011-03-28 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g RlvFolderLocks::RlvFolderLocks() - : m_fLookupDirty(false), m_fLockedRoot(false), m_cntLockAdd(0), m_cntLockRem(0) + : m_fLookupDirty(false), m_RootLockType(RLV_LOCK_NONE), m_cntLockAdd(0), m_cntLockRem(0) { LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&RlvFolderLocks::onNeedsLookupRefresh, this)); RlvInventory::instance().addSharedRootIDChangedCallback(boost::bind(&RlvFolderLocks::onNeedsLookupRefresh, this)); @@ -972,6 +972,9 @@ void RlvFolderLocks::addFolderLock(const folderlock_source_t& lockSource, ELockP else if (RLV_LOCK_ADD == eLockType) m_cntLockAdd++; } + + if (!m_AttachmentChangeConnection.connected()) + m_AttachmentChangeConnection = gAgentAvatarp->setAttachmentCallback(boost::bind(&RlvFolderLocks::onNeedsLookupRefresh, this)); m_fLookupDirty = true; } @@ -1198,7 +1201,7 @@ bool RlvFolderLocks::isLockedFolder(LLUUID idFolder, ERlvLockMask eLockTypeMask, idFolderCur = (pParent) ? pParent->getParentUUID() : idFolderRoot; } // If we didn't encounter an explicit deny lock with no exception then the folder is locked if the entire inventory is locked down - return (m_fLockedRoot) && (eSourceTypeMask & ST_ROOTFOLDER) && (idsRlvObjRem.empty()) && (idsRlvObjAdd.empty()); + return (m_RootLockType & eLockTypeMask) && (eSourceTypeMask & ST_ROOTFOLDER) && (idsRlvObjRem.empty()) && (idsRlvObjAdd.empty()); } // Checked: 2010-11-30 (RLVa-1.3.0b) | Added: RLVa-1.3.0b @@ -1214,7 +1217,7 @@ void RlvFolderLocks::refreshLockedLookups() const // // Refresh locked folders // - m_fLockedRoot = false; + m_RootLockType = RLV_LOCK_NONE; m_LockedFolderMap.clear(); for (folderlock_list_t::const_iterator itFolderLock = m_FolderLocks.begin(); itFolderLock != m_FolderLocks.end(); ++itFolderLock) { @@ -1228,8 +1231,8 @@ void RlvFolderLocks::refreshLockedLookups() const const LLViewerInventoryCategory* pFolder = lockedFolders.at(idxFolder); if (idFolderRoot != pFolder->getUUID()) m_LockedFolderMap.insert(std::pair(pFolder->getUUID(), pLockDescr)); - else - m_fLockedRoot |= (SCOPE_SUBTREE == pLockDescr->eLockScope); + else if (SCOPE_SUBTREE == pLockDescr->eLockScope) + m_RootLockType |= (U32)pLockDescr->eLockType; } } } diff --git a/indra/newview/rlvlocks.h b/indra/newview/rlvlocks.h index 69df3c9283..61ab0acbb0 100644 --- a/indra/newview/rlvlocks.h +++ b/indra/newview/rlvlocks.h @@ -367,6 +367,8 @@ public: const uuid_vec_t& getAttachmentLookups() { return m_LockedAttachmentRem; } const uuid_vec_t& getWearableLookups() { return m_LockedWearableRem; } protected: + boost::signals2::connection m_AttachmentChangeConnection; + // Map of folder locks (idRlvObj -> lockDescr) folderlock_list_t m_FolderLocks; // List of add and remove locked folder descriptions S32 m_cntLockAdd; // Number of RLV_LOCK_ADD locked folders in m_FolderLocks @@ -374,11 +376,11 @@ protected: // Cached item look-up variables typedef std::multimap folderlock_map_t; - mutable bool m_fLookupDirty; - mutable bool m_fLockedRoot; - mutable uuid_vec_t m_LockedAttachmentRem; - mutable folderlock_map_t m_LockedFolderMap; - mutable uuid_vec_t m_LockedWearableRem; + mutable bool m_fLookupDirty; + mutable U32 m_RootLockType; + mutable uuid_vec_t m_LockedAttachmentRem; + mutable folderlock_map_t m_LockedFolderMap; + mutable uuid_vec_t m_LockedWearableRem; private: friend class LLSingleton; }; @@ -475,15 +477,14 @@ inline bool RlvAttachmentLocks::isLockedAttachment(const LLViewerObject* pAttach RLV_ASSERT( (!pAttachObj) || (pAttachObj == pAttachObj->getRootEdit()) ); // Object is locked if: - // - it's not a temporary attachment // - it's specifically marked as non-detachable (ie @detach=n) // - it's attached to an attachment point that is RLV_LOCK_REMOVE locked (ie @remattach:=n) // - it's part of a locked folder return - (pAttachObj) && (pAttachObj->isAttachment()) && (!pAttachObj->isTempAttachment()) && - ( (m_AttachObjRem.find(pAttachObj->getID()) != m_AttachObjRem.end()) || + (pAttachObj) && (pAttachObj->isAttachment()) && + ( (m_AttachObjRem.find(pAttachObj->getID()) != m_AttachObjRem.end()) || (isLockedAttachmentPoint(RlvAttachPtLookup::getAttachPointIndex(pAttachObj), RLV_LOCK_REMOVE)) || - (RlvFolderLocks::instance().isLockedAttachment(pAttachObj->getAttachmentItemID())) ); + ((!pAttachObj->isTempAttachment()) && (RlvFolderLocks::instance().isLockedAttachment(pAttachObj->getAttachmentItemID()))) ); } // Checked: 2010-02-28 (RLVa-1.2.0a) | Added: RLVa-1.0.5a diff --git a/indra/newview/skins/ansastorm/themes/blood/colors.xml b/indra/newview/skins/ansastorm/themes/blood/colors.xml index a301896073..dbb6facb7f 100644 --- a/indra/newview/skins/ansastorm/themes/blood/colors.xml +++ b/indra/newview/skins/ansastorm/themes/blood/colors.xml @@ -327,7 +327,7 @@ value="0.04 0.04 0.04 1.0" /> + value="0.2 0 0 0.5" /> diff --git a/indra/newview/skins/default/xui/da/menu_viewer.xml b/indra/newview/skins/default/xui/da/menu_viewer.xml index b309ea0be3..9cd1b6d912 100644 --- a/indra/newview/skins/default/xui/da/menu_viewer.xml +++ b/indra/newview/skins/default/xui/da/menu_viewer.xml @@ -5,7 +5,7 @@ - + diff --git a/indra/newview/skins/default/xui/da/notifications.xml b/indra/newview/skins/default/xui/da/notifications.xml index 70af513329..e2534e7c86 100644 --- a/indra/newview/skins/default/xui/da/notifications.xml +++ b/indra/newview/skins/default/xui/da/notifications.xml @@ -1369,6 +1369,15 @@ Prøv igen om lidt. + [NAME_SLURL] har tilbudt en teleport til deres lokation: + +[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> +
+