diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000000..6d296d7a24 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,17 @@ +repos: + - repo: https://bitbucket.org/lindenlab/git-hooks.git + rev: v1.0.0-beta2 + hooks: + - id: opensource-license + - id: jira-issue + - id: llsd + - id: no-trigraphs + - id: copyright + - id: end-of-file + files: \.(cpp|c|h|py|glsl|cmake|txt)$ + exclude: language.txt + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.5.0 + hooks: + - id: check-xml + - id: mixed-line-ending diff --git a/autobuild.xml b/autobuild.xml index f04fa20031..ee9eb4f8f4 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -76,9 +76,9 @@ archive hash - 9c93ba8b8af97fc8379f77de77e1540a + 88b6b9ebc2eda992b721529921c82066 url - http://3p.firestormviewer.org/glib-2.48.0.202301938-linux64-202301938.tar.bz2 + http://3p.firestormviewer.org/glib-2.56.0.220911433-linux64_bionic-220911433.tar.bz2 name linux @@ -954,11 +954,11 @@ archive hash - 2db00aa4126d4ee8152fc49b03bb3fe1 + 20c867a0327bb653c8fc377b97d68c55 hash_algorithm md5 url - file:///opt/firestorm/fmodstudio-2.02.05-darwin-220160006.tar.bz2 + file:///opt/firestorm/fmodstudio-2.02.06-darwin64-3.tar.bz2 name darwin @@ -968,11 +968,11 @@ archive hash - 1a6c06c99d67296794b39183387f458d + 9aac95d85fd3f044da3fd9dd44ed5ca2 hash_algorithm md5 url - file:///opt/firestorm/fmodstudio-2.02.05-linux64-220101141.tar.bz2 + file:///opt/firestorm/fmodstudio-2.02.06-linux64_bionic-220911506.tar.bz2 name linux64 @@ -982,11 +982,11 @@ archive hash - 126b2476f65ee4947fec1f754fc9dca9 + b81336e7824c6cf96a6cd6200333b3f7 hash_algorithm md5 url - file:///c:/cygwin/opt/firestorm/fmodstudio-2.02.05-windows-220101109.tar.bz2 + file:///c:/cygwin/opt/firestorm/fmodstudio-2.02.06-windows-220870903.tar.bz2 name windows @@ -996,18 +996,18 @@ archive hash - 891c91e7868bf2e103691bae2ef493eb + cbfb25df1e231a84b0beaf85600efb20 hash_algorithm md5 url - file:///c:/cygwin/opt/firestorm/fmodstudio-2.02.05-windows64-220101110.tar.bz2 + file:///c:/cygwin/opt/firestorm/fmodstudio-2.02.06-windows64-220870905.tar.bz2 name windows64 version - 2.02.05 + 2.02.06 fontconfig @@ -1654,9 +1654,9 @@ archive hash - 94f8c766d77d68e0b8b1ac783b6a02dc + c4dd59fbb0709fc4c7b5ab69b20246f8 url - file:///opt/firestorm/kdu-8.2-linux64-212351600.tar.bz2 + file:///opt/firestorm/kdu-8.2-linux64_bionic-220911445.tar.bz2 name linux64 @@ -2019,18 +2019,18 @@ archive hash - 95cb09a712b7b61e992fe68ab7bf8c72 + d6e7ab8483c348f223fd24028e27a52f hash_algorithm md5 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/92744/837149/llca-202201010217.567162-common-567162.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/93933/844890/llca-202202010217.567974-common-567974.tar.bz2 name common version - 202201010217.567162 + 202202010217.567974 llphysicsextensions_source @@ -2774,9 +2774,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 05c4debd4cccfea620fc7e6f9a190924 + f5f4bc956734e53ef99125ae9aae3a87 url - http://3p.firestormviewer.org/slvoice-3.2.0002.10426.302004-linux64-212691952.tar.bz2 + http://3p.firestormviewer.org/slvoice-3.2-linux64_bionic-220651719.tar.bz2 name linux64 @@ -2988,9 +2988,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 33ed1bb3e24fbd3462da04fb3e917e94 + 1dda5fb3bb649b0ab5a93f22df7cb11e url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/94814/850320/viewer_manager-3.0.568552-darwin64-568552.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/96998/862110/viewer_manager-3.0.569958-darwin64-569958.tar.bz2 name darwin64 @@ -3012,9 +3012,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 2ad8e04965ac8bddb7d351abe09bee07 + 30d1386d0a6883d898fc56757a789b8b url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/94813/850316/viewer_manager-3.0.568552-windows-568552.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/97002/862130/viewer_manager-3.0.569958-windows-569958.tar.bz2 name windows @@ -3025,7 +3025,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors source_type hg version - 3.0.568552 + 3.0.569958 vlc-bin @@ -3077,7 +3077,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors version - 2.2.8.538966 + 3.0.16.565299 xmlrpc-epi diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 76a9e6b981..803cb4f5f0 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -4,7 +4,7 @@ # other commands to guarantee full compatibility # with the version specified ## 3.8 added VS_DEBUGGER_WORKING_DIRECTORY support -cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR) +cmake_minimum_required(VERSION 3.12.0 FATAL_ERROR) set(ROOT_PROJECT_NAME "SecondLife" CACHE STRING "The root project/makefile/solution name. Defaults to SecondLife.") @@ -28,9 +28,9 @@ endif (NOT CMAKE_BUILD_TYPE) # option(OPENSIM "OpenSim support" OFF) if (OPENSIM) - add_definitions(-DOPENSIM=1) + add_compile_definitions(OPENSIM) if (SINGLEGRID) - add_definitions(-DSINGLEGRID=1 -DSINGLEGRID_URI=\"${SINGLEGRID_URI}\") + add_compile_definitions(SINGLEGRID SINGLEGRID_URI=\"${SINGLEGRID_URI}\") message(STATUS "Compiling with OpenSim support - Single Grid version (${SINGLEGRID_URI})") else (SINGLEGRID) message(STATUS "Compiling with OpenSim support") @@ -43,7 +43,7 @@ else (OPENSIM) endif (OPENSIM) if (HAVOK_TPV) - add_definitions(-DHAVOK_TPV=1) + add_compile_definitions(HAVOK_TPV) message(STATUS "Compiling with Havok libraries") endif (HAVOK_TPV) # @@ -51,7 +51,7 @@ endif (HAVOK_TPV) # Support for test builds option(TESTBUILD "Generating test build" OFF) if(TESTBUILD AND TESTBUILDPERIOD) - add_definitions(-DTESTBUILD=1 -DTESTBUILDPERIOD=${TESTBUILDPERIOD}) + add_compile_definitions(TESTBUILD TESTBUILDPERIOD=${TESTBUILDPERIOD}) message(STATUS "Creating test build version; test period: ${TESTBUILDPERIOD} days") endif(TESTBUILD AND TESTBUILDPERIOD) # @@ -63,11 +63,11 @@ if (USE_AVX_OPTIMIZATION) if (USE_AVX2_OPTIMIZATION) message(FATAL_ERROR "You cannot use AVX and AVX2 at the same time!") else (USE_AVX2_OPTIMIZATION) - add_definitions(-DUSE_AVX_OPTIMIZATION=1) + add_compile_definitions(USE_AVX_OPTIMIZATION) message(STATUS "Compiling with AVX optimizations") endif (USE_AVX2_OPTIMIZATION) elseif (USE_AVX2_OPTIMIZATION) - add_definitions(-DUSE_AVX2_OPTIMIZATION=1) + add_compile_definitions(USE_AVX2_OPTIMIZATION) message(STATUS "Compiling with AVX2 optimizations") else (USE_AVX_OPTIMIZATION) message(STATUS "Compiling without AVX optimizations") diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 519f68b53e..34a7c3f18d 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -223,7 +223,7 @@ elseif(LINUX) set(SHARED_LIB_STAGING_DIR_RELWITHDEBINFO "${SHARED_LIB_STAGING_DIR}") set(SHARED_LIB_STAGING_DIR_RELEASE "${SHARED_LIB_STAGING_DIR}") - set(vivox_lib_dir "${ARCH_PREBUILT_DIRS_RELEASE}") + set(vivox_lib_dir "${ARCH_PREBUILT_DIRS_RELEASE}/../../lib32/") set(vivox_libs libsndfile.so.1 libortp.so @@ -255,6 +255,8 @@ elseif(LINUX) libuuid.so.16.0.22 libfontconfig.so.1.8.0 libfontconfig.so.1 + libaprutil-1.so.0 + libapr-1.so.0 ) else (NOT USESYSTEMLIBS) set(release_files diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake index ce61b51b9b..0f5f283f6b 100644 --- a/indra/cmake/bugsplat.cmake +++ b/indra/cmake/bugsplat.cmake @@ -36,9 +36,7 @@ if (USE_BUGSPLAT) if( LINUX ) set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/breakpad) - # Sadly we cannot have the nice things yet and need add_definitions for older cmake - #add_compile_definitions(__STDC_FORMAT_MACROS) - add_definitions(-D__STDC_FORMAT_MACROS) + add_compile_definitions(__STDC_FORMAT_MACROS) else() set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat) endif() diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index d6f2913701..905dd5a7df 100644 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -1533,6 +1533,15 @@ bool LLAudioSource::setupChannel() return true; } +void LLAudioSource::stop() +{ + play(LLUUID::null); + if (mCurrentDatap) + { + // always reset data if something wants us to stop + mCurrentDatap = nullptr; + } +} bool LLAudioSource::play(const LLUUID &audio_uuid) { diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h index 661707b209..ccd408576d 100644 --- a/indra/llaudio/llaudioengine.h +++ b/indra/llaudio/llaudioengine.h @@ -351,7 +351,13 @@ public: LLAudioBuffer *getCurrentBuffer(); bool setupChannel(); - bool play(const LLUUID &audio_id); // Start the audio source playing + + // Stop the audio source, reset audio id even if muted + void stop(); + + // Start the audio source playing, + // takes mute into account to preserve previous id if nessesary + bool play(const LLUUID &audio_id); bool hasPendingPreloads() const; // Has preloads that haven't been done yet diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index c00df59756..5a7174ac9a 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -46,7 +46,6 @@ #include "llstl.h" // for DeletePointer() #include "llstring.h" #include "lleventtimer.h" - #include "stringize.h" #include "llcleanup.h" #include "llevents.h" diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index 2042051dd9..6e1236982a 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -248,14 +248,25 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl // protected_fixedsize_stack sets a guard page past the end of the new // stack so that stack underflow will result in an access violation // instead of weird, subtle, possibly undiagnosed memory stomps. - boost::fibers::fiber newCoro(boost::fibers::launch::dispatch, - std::allocator_arg, - boost::fibers::protected_fixedsize_stack(mStackSize), - [this, &name, &callable](){ toplevel(name, callable); }); - // You have two choices with a fiber instance: you can join() it or you - // can detach() it. If you try to destroy the instance before doing - // either, the program silently terminates. We don't need this handle. - newCoro.detach(); + + try + { + boost::fibers::fiber newCoro(boost::fibers::launch::dispatch, + std::allocator_arg, + boost::fibers::protected_fixedsize_stack(mStackSize), + [this, &name, &callable]() { toplevel(name, callable); }); + + // You have two choices with a fiber instance: you can join() it or you + // can detach() it. If you try to destroy the instance before doing + // either, the program silently terminates. We don't need this handle. + newCoro.detach(); + } + catch (std::bad_alloc&) + { + // Out of memory on stack allocation? + LL_ERRS("LLCoros") << "Bad memory allocation in LLCoros::launch(" << prefix << ")!" << LL_ENDL; + } + return name; } diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp index 995356dc52..067b5e6fbc 100644 --- a/indra/llcommon/lleventcoro.cpp +++ b/indra/llcommon/lleventcoro.cpp @@ -101,7 +101,7 @@ void storeToLLSDPath(LLSD& dest, const LLSD& path, const LLSD& value) } // Drill down to where we should store 'value'. - llsd::drill(dest, path) = value; + llsd::drill_ref(dest, path) = value; } } // anonymous diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp index a1ee1cb7ba..1a43e3675d 100644 --- a/indra/llcommon/llsdutil.cpp +++ b/indra/llcommon/llsdutil.cpp @@ -29,6 +29,7 @@ #include "linden_common.h" #include "llsdutil.h" +#include #if LL_WINDOWS # define WIN32_LEAN_AND_MEAN @@ -868,7 +869,7 @@ bool llsd_equals(const LLSD& lhs, const LLSD& rhs, int bits) namespace llsd { -LLSD& drill(LLSD& blob, const LLSD& rawPath) +LLSD& drill_ref(LLSD& blob, const LLSD& rawPath) { // Treat rawPath uniformly as an array. If it's not already an array, // store it as the only entry in one. (But let's say Undefined means an @@ -923,9 +924,9 @@ LLSD& drill(LLSD& blob, const LLSD& rawPath) LLSD drill(const LLSD& blob, const LLSD& path) { - // non-const drill() does exactly what we want. Temporarily cast away + // drill_ref() does exactly what we want. Temporarily cast away // const-ness and use that. - return drill(const_cast(blob), path); + return drill_ref(const_cast(blob), path); } } // namespace llsd diff --git a/indra/llcommon/llsdutil.h b/indra/llcommon/llsdutil.h index 8678ca97f2..1321615805 100644 --- a/indra/llcommon/llsdutil.h +++ b/indra/llcommon/llsdutil.h @@ -184,10 +184,10 @@ namespace llsd * - Anything else is an error. * * By implication, if path.isUndefined() or otherwise equivalent to an empty - * LLSD::Array, drill() returns 'blob' as is. + * LLSD::Array, drill[_ref]() returns 'blob' as is. */ LLSD drill(const LLSD& blob, const LLSD& path); -LLSD& drill( LLSD& blob, const LLSD& path); +LLSD& drill_ref( LLSD& blob, const LLSD& path); } diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index d694d96d2f..c529ce6052 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -202,18 +202,6 @@ LLOSInfo::LLOSInfo() : GetSystemInfo(&si); //if it fails get regular system info //(Warning: If GetSystemInfo it may result in incorrect information in a WOW64 machine, if the kernel fails to load) - //msdn microsoft finds 32 bit and 64 bit flavors this way.. - //http://msdn.microsoft.com/en-us/library/ms724429(VS.85).aspx (example code that contains quite a few more flavors - //of windows than this code does (in case it is needed for the future) - if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) //check for 64 bit - { - mOSStringSimple += "64-bit "; - } - else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) - { - mOSStringSimple += "32-bit "; - } - // Try calling GetVersionEx using the OSVERSIONINFOEX structure. OSVERSIONINFOEX osvi; ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); @@ -261,12 +249,24 @@ LLOSInfo::LLOSInfo() : // and likely to return 'compatibility' string. // Check presence of dlls/libs or may be their version. // Windows 11 detection - //mOSStringSimple = "Microsoft Windows 10/11"; + //mOSStringSimple = "Microsoft Windows 10/11 "; mMajorVer = 11; LLStringUtil::replaceString(mOSStringSimple, "10", "11"); // } - } + } + + //msdn microsoft finds 32 bit and 64 bit flavors this way.. + //http://msdn.microsoft.com/en-us/library/ms724429(VS.85).aspx (example code that contains quite a few more flavors + //of windows than this code does (in case it is needed for the future) + if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) //check for 64 bit + { + mOSStringSimple += "64-bit "; + } + else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) + { + mOSStringSimple += "32-bit "; + } mOSString = mOSStringSimple; if (mBuild > 0) diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp index 148c18aabe..d4ca7bce65 100644 --- a/indra/llcommon/tests/llerror_test.cpp +++ b/indra/llcommon/tests/llerror_test.cpp @@ -61,6 +61,9 @@ namespace { #ifdef __clang__ # pragma clang diagnostic ignored "-Wunused-function" +#endif +#if __GNUC__ +#pragma GCC diagnostic ignored "-Wunused-function" #endif void test_that_error_h_includes_enough_things_to_compile_a_message() { diff --git a/indra/llcommon/tests/lleventcoro_test.cpp b/indra/llcommon/tests/lleventcoro_test.cpp index ccc4d82b34..4a1d4b8ba9 100644 --- a/indra/llcommon/tests/lleventcoro_test.cpp +++ b/indra/llcommon/tests/lleventcoro_test.cpp @@ -216,6 +216,7 @@ namespace tut } void test_data::postAndWait1() + { BEGIN { mSync.bump(); diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index a613ef0c59..e0aa3f4297 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5838,7 +5838,16 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) resizeIndices(grid_size*grid_size*6); if (!volume->isMeshAssetLoaded()) { - mEdge.resize(grid_size*grid_size * 6); + S32 size = grid_size * grid_size * 6; + try + { + mEdge.resize(size); + } + catch (std::bad_alloc&) + { + LL_WARNS("LLVOLUME") << "Resize of mEdge to " << size << " failed" << LL_ENDL; + return false; + } } U16* out = mIndices; @@ -6647,7 +6656,15 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) if (!volume->isMeshAssetLoaded()) { - mEdge.resize(num_indices); + try + { + mEdge.resize(num_indices); + } + catch (std::bad_alloc&) + { + LL_WARNS("LLVOLUME") << "Resize of mEdge to " << num_indices << " failed" << LL_ENDL; + return false; + } } } @@ -6875,7 +6892,15 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) LLVector4a* norm = mNormals; static LLAlignedArray triangle_normals; - triangle_normals.resize(count); + try + { + triangle_normals.resize(count); + } + catch (std::bad_alloc&) + { + LL_WARNS("LLVOLUME") << "Resize of triangle_normals to " << count << " failed" << LL_ENDL; + return false; + } LLVector4a* output = triangle_normals.mArray; LLVector4a* end_output = output+count; diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 66f8fc96dd..b72d006608 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -178,6 +178,14 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) mTripleClickTimer.reset(); setText(p.default_text()); + if (p.initial_value.isProvided() + && !p.control_name.isProvided()) + { + // Initial value often is descriptive, like "Type some ID here" + // and can be longer than size limitation, ignore size + setText(p.initial_value.getValue().asString(), false); + } + // Initialize current history line iterator mCurrentHistoryLine = mLineHistory.begin(); @@ -406,6 +414,11 @@ void LLLineEditor::updateTextPadding() void LLLineEditor::setText(const LLStringExplicit &new_text) +{ + setText(new_text, true); +} + +void LLLineEditor::setText(const LLStringExplicit &new_text, bool use_size_limit) { // If new text is identical, don't copy and don't move insertion point if (mText.getString() == new_text) @@ -424,13 +437,13 @@ void LLLineEditor::setText(const LLStringExplicit &new_text) all_selected = all_selected || (len == 0 && hasFocus() && mSelectAllonFocusReceived); std::string truncated_utf8 = new_text; - if (truncated_utf8.size() > (U32)mMaxLengthBytes) + if (use_size_limit && truncated_utf8.size() > (U32)mMaxLengthBytes) { truncated_utf8 = utf8str_truncate(new_text, mMaxLengthBytes); } mText.assign(truncated_utf8); - if (mMaxLengthChars) + if (use_size_limit && mMaxLengthChars) { mText.assign(utf8str_symbol_truncate(truncated_utf8, mMaxLengthChars)); } diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index ff536840d2..2387cc1478 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -337,6 +337,8 @@ private: virtual S32 getPreeditFontSize() const; virtual LLWString getPreeditString() const { return getWText(); } + void setText(const LLStringExplicit &new_text, bool use_size_limit); + void setContextMenu(LLContextMenu* new_context_menu); protected: diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 65ea6b3c71..33a5bfd259 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -2404,6 +2404,16 @@ void LLMenuGL::arrange( void ) (*item_iter)->setRect( rect ); } } + + + if (getTornOff()) + { + LLTearOffMenu * torn_off_menu = dynamic_cast(getParent()); + if (torn_off_menu) + { + torn_off_menu->updateSize(); + } + } } if (mKeepFixedSize) { @@ -3930,7 +3940,8 @@ void LLMenuHolderGL::setActivatedItem(LLMenuItemGL* item) /// Class LLTearOffMenu ///============================================================================ LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) : - LLFloater(LLSD()) + LLFloater(LLSD()), + mQuitRequested(false) { S32 floater_header_size = getHeaderHeight(); @@ -3945,7 +3956,7 @@ LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) : LLRect rect; menup->localRectToOtherView(LLRect(-1, menup->getRect().getHeight(), menup->getRect().getWidth() + 3, 0), &rect, gFloaterView); // make sure this floater is big enough for menu - mTargetHeight = (F32)(rect.getHeight() + floater_header_size); + mTargetHeight = rect.getHeight() + floater_header_size; reshape(rect.getWidth(), rect.getHeight()); setRect(rect); @@ -3977,19 +3988,24 @@ LLTearOffMenu::~LLTearOffMenu() void LLTearOffMenu::draw() { mMenu->setBackgroundVisible(isBackgroundOpaque()); - mMenu->needsArrange(); if (getRect().getHeight() != mTargetHeight) { // animate towards target height - reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), mTargetHeight, LLSmoothInterpolation::getInterpolant(0.05f)))); + reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), (F32)mTargetHeight, LLSmoothInterpolation::getInterpolant(0.05f)))); + mMenu->needsArrange(); } LLFloater::draw(); } void LLTearOffMenu::onFocusReceived() { - // if nothing is highlighted, just highlight first item + if (mQuitRequested) + { + return; + } + + // if nothing is highlighted, just highlight first item if (!mMenu->getHighlightedItem()) { mMenu->highlightNextItem(NULL); @@ -4065,6 +4081,31 @@ LLTearOffMenu* LLTearOffMenu::create(LLMenuGL* menup) return tearoffp; } +void LLTearOffMenu::updateSize() +{ + if (mMenu) + { + S32 floater_header_size = getHeaderHeight(); + const LLRect &floater_rect = getRect(); + LLRect new_rect; + mMenu->localRectToOtherView(LLRect(-1, mMenu->getRect().getHeight() + floater_header_size, mMenu->getRect().getWidth() + 3, 0), &new_rect, gFloaterView); + + if (floater_rect.getWidth() != new_rect.getWidth() + || mTargetHeight != new_rect.getHeight()) + { + // make sure this floater is big enough for menu + mTargetHeight = new_rect.getHeight(); + reshape(new_rect.getWidth(), mTargetHeight); + + // Restore menu position + LLRect menu_rect = mMenu->getRect(); + menu_rect.setOriginAndSize(1, 1, + menu_rect.getWidth(), menu_rect.getHeight()); + mMenu->setRect(menu_rect); + } + } +} + void LLTearOffMenu::closeTearOff() { removeChild(mMenu); @@ -4075,6 +4116,7 @@ void LLTearOffMenu::closeTearOff() mMenu->setVisible(FALSE); mMenu->setTornOff(FALSE); mMenu->setDropShadowed(TRUE); + mQuitRequested = true; } LLContextMenuBranch::LLContextMenuBranch(const LLContextMenuBranch::Params& p) diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 9f7ea44aff..73600f01f3 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -885,6 +885,8 @@ public: virtual BOOL handleKeyHere(KEY key, MASK mask); virtual void translate(S32 x, S32 y); + void updateSize(); + private: LLTearOffMenu(LLMenuGL* menup); @@ -892,7 +894,8 @@ private: LLView* mOldParent; LLMenuGL* mMenu; - F32 mTargetHeight; + S32 mTargetHeight; + bool mQuitRequested; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 27fe2cea59..405544ede6 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -1165,6 +1165,24 @@ std::string LLUrlEntryObjectIM::getLocation(const std::string &url) const return LLUrlEntryBase::getLocation(url); } +// +// LLUrlEntryChat Describes a Second Life chat Url, e.g., +// secondlife:///app/chat/42/This%20Is%20a%20test +// + +LLUrlEntryChat::LLUrlEntryChat() +{ + mPattern = boost::regex("secondlife:///app/chat/\\d+/\\S+", + boost::regex::perl|boost::regex::icase); + mMenuName = "menu_url_slapp.xml"; + mTooltip = LLTrans::getString("TooltipSLAPP"); +} + +std::string LLUrlEntryChat::getLabel(const std::string &url, const LLUrlLabelCallback &cb) +{ + return unescapeUrl(url); +} + // LLUrlEntryParcel statics. LLUUID LLUrlEntryParcel::sAgentID(LLUUID::null); LLUUID LLUrlEntryParcel::sSessionID(LLUUID::null); diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 9b41618413..cfdab0c64c 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -418,6 +418,17 @@ public: private: }; +// +// LLUrlEntryChat Describes a Second Life chat Url, e.g., +// secondlife:///app/chat/42/This%20Is%20a%20test +// +class LLUrlEntryChat : public LLUrlEntryBase +{ +public: + LLUrlEntryChat(); + /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); +}; + /// /// LLUrlEntryParcel Describes a Second Life parcel Url, e.g., /// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index d8c1541a6c..8d18780737 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -75,6 +75,7 @@ LLUrlRegistry::LLUrlRegistry() // LLUrlEntryAgent*Name must appear before LLUrlEntryAgent since // LLUrlEntryAgent is a less specific (catchall for agent urls) registerUrl(new LLUrlEntryAgent()); + registerUrl(new LLUrlEntryChat()); registerUrl(new LLUrlEntryGroup()); registerUrl(new LLUrlEntryParcel()); registerUrl(new LLUrlEntryTeleport()); diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index e0cd0bfb46..f3ba4cc6d4 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -325,10 +325,9 @@ void LLWindowSDL::initialiseX11Clipboard() XA_CLIPBOARD = XInternAtom(mSDL_Display, "CLIPBOARD", False); - gSupportedAtoms[0] = XA_STRING; - + gSupportedAtoms[0] = XInternAtom(mSDL_Display, "UTF8_STRING", False); gSupportedAtoms[1] = XInternAtom(mSDL_Display, "COMPOUND_TEXT", False); - gSupportedAtoms[2] = XInternAtom(mSDL_Display, "UTF8_STRING", False); + gSupportedAtoms[2] = XA_STRING; // TARGETS atom XA_TARGETS = XInternAtom(mSDL_Display, "TARGETS", False); @@ -359,7 +358,7 @@ bool LLWindowSDL::getSelectionText( Atom aSelection, Atom aType, LLWString &text &remaining, &data); if (data && len) { - text = LLWString( + text = LLWString( utf8str_to_wstring(reinterpret_cast< char const *>( data ) ) ); XFree(data); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 005d5e25ac..89c9473b58 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -4334,7 +4334,8 @@ BOOL LLWindowWin32::handleImeRequests(WPARAM request, LPARAM param, LRESULT *res S32 context_offset; LLWString context = find_context(wtext, preedit, preedit_length, &context_offset); preedit -= context_offset; - if (preedit_length) + preedit_length = llmin(preedit_length, (S32)context.length() - preedit); + if (preedit_length && preedit >= 0) { // IMR_DOCUMENTFEED may be called when we have an active preedit. // We should pass the context string *excluding* the preedit string. diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index cc8aea0fd1..2a89564715 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -2375,9 +2375,7 @@ if (WINDOWS) add_dependencies(${VIEWER_BINARY_NAME} copy_win_scripts) endif (EXISTS ${CMAKE_SOURCE_DIR}/copy_win_scripts) - add_dependencies(${VIEWER_BINARY_NAME} - SLPlugin - ) + add_dependencies(${VIEWER_BINARY_NAME} SLPlugin) # sets the 'working directory' for debugging from visual studio. # Condition for version can be moved to requirements once build agents will be updated (see TOOL-3865) diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 54358db763..cc81d718c3 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.5.4 +6.5.5 diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml index f9fcc3fc28..0bea094843 100644 --- a/indra/newview/app_settings/cmd_line.xml +++ b/indra/newview/app_settings/cmd_line.xml @@ -238,14 +238,6 @@ map-to NoAudio - - - noinvlib - - desc - Do not request the inventory library. - map-to - NoInventoryLibrary nonotifications diff --git a/indra/newview/app_settings/key_bindings.xml b/indra/newview/app_settings/key_bindings.xml index f3eb303b16..1d6ec5a01a 100644 --- a/indra/newview/app_settings/key_bindings.xml +++ b/indra/newview/app_settings/key_bindings.xml @@ -1,5 +1,5 @@ - + @@ -17,22 +17,13 @@ - - - - - - - - - - - + + @@ -60,19 +51,6 @@ - - - - - - - - - - - - - @@ -88,15 +66,6 @@ - - - - - - - - - @@ -104,9 +73,6 @@ - - - @@ -118,14 +84,10 @@ - - - - - - - + + + @@ -167,16 +129,6 @@ - - - - - - - - - - @@ -192,15 +144,6 @@ - - - - - - - - - @@ -212,17 +155,12 @@ - - - - - - - + + @@ -240,15 +178,9 @@ - - - - - - - - + + \ No newline at end of file diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 7f519c03f5..a946bfaeb9 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6940,11 +6940,11 @@ Type String Value - https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&p=[AUTH_TOKEN]&r=[MATURITY]&lang=[LANGUAGE]&sid=[SESSION_ID] + https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&r=[MATURITY]&lang=[LANGUAGE]&sid=[SESSION_ID] Backup 0 GuidebookURL @@ -8267,19 +8267,6 @@ Value 0 - LoginAsGod - - Comment - Attempt to login with god powers (Linden accounts only) - Persist - 1 - Type - Boolean - Value - 0 - Backup - 0 - LoginLocation Comment @@ -9711,6 +9698,17 @@ Value 1000 + FakeInitialOutfitName + + Comment + Pretend that this is first time login and specified name was chosen + Persist + 1 + Type + String + Value + + NearMeRange Comment @@ -9808,7 +9806,7 @@ NoInventoryLibrary Comment - Do not request inventory library. + (Deprecated) Do not request inventory library. Persist 0 Type diff --git a/indra/newview/fs_resources/EBEDD1D2-A320-43f5-88CF-DD47BBCA5DFB.lsltxt b/indra/newview/fs_resources/EBEDD1D2-A320-43f5-88CF-DD47BBCA5DFB.lsltxt index 11e5ee0ce5..9103d4faf3 100644 --- a/indra/newview/fs_resources/EBEDD1D2-A320-43f5-88CF-DD47BBCA5DFB.lsltxt +++ b/indra/newview/fs_resources/EBEDD1D2-A320-43f5-88CF-DD47BBCA5DFB.lsltxt @@ -7,7 +7,7 @@ // // Bridge platform - string BRIDGE_VERSION = "2.27"; // This should match fslslbridge.cpp + string BRIDGE_VERSION = "2.28"; // This should match fslslbridge.cpp string gLatestURL; integer gViewerIsFirestorm; integer gTryHandshakeOnce = TRUE; @@ -48,8 +48,8 @@ { llReleaseURL(gLatestURL); gLatestURL = ""; - // llRequestSecureURL(); // Uncomment this line and comment next one for HTTPS instead of HTTP (experimental) - llRequestURL(); + llRequestSecureURL(); + // llRequestURL(); -- Uncomment this line and comment the previous one for HTTP instead of HTTPS } detachBridge() diff --git a/indra/newview/fs_viewer_manifest.py b/indra/newview/fs_viewer_manifest.py index 04d75e6c1d..c41620b5be 100644 --- a/indra/newview/fs_viewer_manifest.py +++ b/indra/newview/fs_viewer_manifest.py @@ -194,10 +194,14 @@ class FSViewerManifest: def fs_save_breakpad_symbols(self, osname): from glob import glob import sys - from os.path import isdir + from os.path import isdir, join from shutil import rmtree import tarfile + components = ['Phoenix',self.app_name(),self.args.get('arch'),'.'.join(self.args['version'])] + symbolsName = "_".join(components) + symbolsName = symbolsName + "_" + self.args["viewer_flavor"] + "-" + osname + "-" + str(self.address_size) + ".tar.bz2" + if isdir( "symbols" ): rmtree( "symbols" ) @@ -213,12 +217,7 @@ class FSViewerManifest: if isdir( "symbols" ): for a in self.args: print("%s: %s" % (a, self.args[a])) - symbolsName = "%s/Phoenix_%s_%s_%s_symbols-%s-%d.tar.bz2" % (self.args['configuration'].lower(), - self.fs_channel_legacy_oneword(), - '-'.join( self.args['version'] ), - self.args['viewer_flavor'], - osname, - self.address_size) fTar = tarfile.open( symbolsName, "w:bz2") fTar.add("symbols", arcname=".") + fTar.add( join( self.args["dest"], "build_data.json" ), arcname="build_data.json" ) diff --git a/indra/newview/fsfloaterimport.cpp b/indra/newview/fsfloaterimport.cpp index 3a45f3d342..2248d8796e 100644 --- a/indra/newview/fsfloaterimport.cpp +++ b/indra/newview/fsfloaterimport.cpp @@ -845,8 +845,8 @@ bool FSFloaterImport::processPrimCreated(LLViewerObject* object) LL_DEBUGS("import") << "Setting clickaction on " << prim_uuid.asString() << " to " << prim["clickaction"].asInteger() << LL_ENDL; gMessageSystem->newMessageFast(_PREHASH_ObjectClickAction); gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); gMessageSystem->nextBlockFast(_PREHASH_ObjectData); gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() ); gMessageSystem->addU8("ClickAction", (U8)prim["clickaction"].asInteger()); @@ -860,8 +860,8 @@ bool FSFloaterImport::processPrimCreated(LLViewerObject* object) LL_DEBUGS("import") << "Setting name on " << prim_uuid.asString() << " to " << prim_name << LL_ENDL; gMessageSystem->newMessageFast(_PREHASH_ObjectName); gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); gMessageSystem->nextBlockFast(_PREHASH_ObjectData); gMessageSystem->addU32Fast(_PREHASH_LocalID, object_local_id); gMessageSystem->addStringFast(_PREHASH_Name, prim_name); @@ -873,8 +873,8 @@ bool FSFloaterImport::processPrimCreated(LLViewerObject* object) LL_DEBUGS("import") << "Setting description on " << prim_uuid.asString() << " to " << prim["description"].asString() << LL_ENDL; gMessageSystem->newMessageFast(_PREHASH_ObjectDescription); gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); gMessageSystem->nextBlockFast(_PREHASH_ObjectData); gMessageSystem->addU32Fast(_PREHASH_LocalID, object_local_id); gMessageSystem->addStringFast(_PREHASH_Description, prim["description"].asString()); @@ -887,8 +887,8 @@ bool FSFloaterImport::processPrimCreated(LLViewerObject* object) LL_DEBUGS("import") << "Setting permissions on " << prim_uuid.asString() << LL_ENDL; gMessageSystem->newMessageFast(_PREHASH_ObjectPermissions); gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); gMessageSystem->nextBlockFast(_PREHASH_HeaderData); gMessageSystem->addBOOLFast(_PREHASH_Override, (BOOL)FALSE); @@ -953,8 +953,8 @@ bool FSFloaterImport::processPrimCreated(LLViewerObject* object) LL_DEBUGS("import") << "Setting sale info on " << prim_uuid.asString() << LL_ENDL; gMessageSystem->newMessageFast(_PREHASH_ObjectSaleInfo); gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); gMessageSystem->nextBlockFast(_PREHASH_ObjectData); gMessageSystem->addU32Fast(_PREHASH_LocalID, object->getLocalID()); sale_info.packMessage(gMessageSystem); @@ -1155,8 +1155,8 @@ void FSFloaterImport::setPrimPosition(U8 type, LLViewerObject* object, LLVector3 { gMessageSystem->newMessage(_PREHASH_MultipleObjectUpdate); gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); gMessageSystem->nextBlockFast(_PREHASH_ObjectData); gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID()); gMessageSystem->addU8Fast(_PREHASH_Type, type); @@ -1298,7 +1298,7 @@ void FSFloaterImport::uploadAsset(LLUUID asset_id, LLUUID inventory_item) ci_data->asset_type = asset_type; ci_data->post_asset_upload = false; LLPointer cb = new FSCreateItemCallback(ci_data); - create_inventory_item(gAgent.getID(), gAgent.getSessionID(), + create_inventory_item(gAgentID, gAgentSessionID, folder_id, LLTransactionID::tnull, name, description, asset_type, inventory_type, NO_INV_SUBTYPE, PERM_ALL, cb); return; @@ -1322,7 +1322,7 @@ void FSFloaterImport::uploadAsset(LLUUID asset_id, LLUUID inventory_item) ci_data->asset_type = asset_type; ci_data->post_asset_upload = false; LLPointer cb = new FSCreateItemCallback(ci_data); - create_inventory_item(gAgent.getID(), gAgent.getSessionID(), + create_inventory_item(gAgentID, gAgentSessionID, folder_id, LLTransactionID::tnull, name, description, asset_type, inventory_type, NO_INV_SUBTYPE, PERM_MOVE | PERM_TRANSFER, cb); return; @@ -1372,7 +1372,7 @@ void FSFloaterImport::uploadAsset(LLUUID asset_id, LLUUID inventory_item) ci_data->asset_type = asset_type; ci_data->post_asset_upload = false; LLPointer cb = new FSCreateItemCallback(ci_data); - create_inventory_item(gAgent.getID(), gAgent.getSessionID(), + create_inventory_item(gAgentID, gAgentSessionID, folder_id, LLTransactionID::tnull, name, description, asset_type, inventory_type, NO_INV_SUBTYPE, PERM_ALL, cb); return; @@ -1495,7 +1495,7 @@ void FSFloaterImport::uploadAsset(LLUUID asset_id, LLUUID inventory_item) data->mAssetInfo.setDescription(description); data->mPreferredLocation = folder_type; - if(!url.empty()) + if (!url.empty()) { if (new_file_agent_inventory) { @@ -1508,11 +1508,9 @@ void FSFloaterImport::uploadAsset(LLUUID asset_id, LLUUID inventory_item) body["group_mask"] = LLSD::Integer(LLFloaterPerms::getGroupPerms(perms_prefix)); body["everyone_mask"] = LLSD::Integer(LLFloaterPerms::getEveryonePerms(perms_prefix)); } - - boost::shared_ptr< LLResourceData> pData( data, resourceDeleter ); - - LLCoprocedureManager::instance().enqueueCoprocedure( "FSImporter", "Upload asset", boost::bind( uploadCoroutine, _1, url, body, new_asset_id, asset_type, pData ) ); + boost::shared_ptr< LLResourceData> pData(data, resourceDeleter); + LLCoprocedureManager::instance().enqueueCoprocedure("AssetStorage", "Upload asset", boost::bind( uploadCoroutine, _1, url, body, new_asset_id, asset_type, pData)); LL_DEBUGS("import") << "Asset upload via capability of " << new_asset_id.asString() << " to " << url << " of " << asset_id.asString() << LL_ENDL; } @@ -1583,10 +1581,10 @@ void FSFloaterImport::onAssetUploadComplete(const LLUUID& uuid, void* userdata, LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_MoneyTransferRequest); msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_AgentID, gAgentID); + msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); msg->nextBlockFast(_PREHASH_MoneyData); - msg->addUUIDFast(_PREHASH_SourceID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SourceID, gAgentID); msg->addUUIDFast(_PREHASH_DestID, LLUUID::null); msg->addU8("Flags", 0); // we tell the sim how much we were expecting to pay so it @@ -1613,7 +1611,7 @@ void FSFloaterImport::onAssetUploadComplete(const LLUUID& uuid, void* userdata, fs_data->post_asset_upload = true; fs_data->post_asset_upload_id = asset_id; LLPointer cb = new FSCreateItemCallback(fs_data); - create_inventory_item(gAgent.getID(), gAgent.getSessionID(), + create_inventory_item(gAgentID, gAgentSessionID, folder_id, data->mAssetInfo.mTransactionID, data->mAssetInfo.getName(), data->mAssetInfo.getDescription(), data->mAssetInfo.mType, data->mInventoryType, fs_data->wearable_type, next_owner_perms, @@ -2038,7 +2036,7 @@ void uploadCoroutine( LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &a_httpAdapter } LLPermissions new_perms; - new_perms.init( gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null ); + new_perms.init( gAgentID, gAgentID, LLUUID::null, LLUUID::null ); new_perms.initMasks( PERM_ALL, PERM_ALL, everyone_perms, group_perms, next_owner_perms ); diff --git a/indra/newview/fsfloaterperformance.cpp b/indra/newview/fsfloaterperformance.cpp index 7e11d1dadc..eaaf5b32df 100644 --- a/indra/newview/fsfloaterperformance.cpp +++ b/indra/newview/fsfloaterperformance.cpp @@ -634,6 +634,7 @@ void FSFloaterPerformance::populateNearbyList() auto overall_appearance = avatar->getOverallAppearance(); if (overall_appearance == LLVOAvatar::AOA_INVISIBLE) { + char_iter++; continue; } diff --git a/indra/newview/fsfloatersearch.cpp b/indra/newview/fsfloatersearch.cpp index 2ee7106cb4..d4b308c727 100644 --- a/indra/newview/fsfloatersearch.cpp +++ b/indra/newview/fsfloatersearch.cpp @@ -130,7 +130,7 @@ public: /*virtual*/ void setErrorStatus(S32 status, const std::string& reason) { - LL_ERRS("Search") << "Can't complete remote parcel request. Http Status: " << status << ". Reason : " << reason << LL_ENDL; + LL_WARNS("Search") << "Can't complete remote parcel request. Http Status: " << status << ". Reason : " << reason << LL_ENDL; } private: std::set mParcelIDs; diff --git a/indra/newview/fslslbridge.cpp b/indra/newview/fslslbridge.cpp index e8596296cb..2495242dd1 100644 --- a/indra/newview/fslslbridge.cpp +++ b/indra/newview/fslslbridge.cpp @@ -55,7 +55,7 @@ static const std::string FS_BRIDGE_FOLDER = "#LSL Bridge"; static const std::string FS_BRIDGE_CONTAINER_FOLDER = "Landscaping"; static const U32 FS_BRIDGE_MAJOR_VERSION = 2; -static const U32 FS_BRIDGE_MINOR_VERSION = 27; +static const U32 FS_BRIDGE_MINOR_VERSION = 28; static const U32 FS_MAX_MINOR_VERSION = 99; static const std::string UPLOAD_SCRIPT_CURRENT = "EBEDD1D2-A320-43f5-88CF-DD47BBCA5DFB.lsltxt"; static const std::string FS_STATE_ATTRIBUTE = "state="; diff --git a/indra/newview/fsperfstats.cpp b/indra/newview/fsperfstats.cpp index 1238bd786d..e01631be37 100644 --- a/indra/newview/fsperfstats.cpp +++ b/indra/newview/fsperfstats.cpp @@ -123,7 +123,7 @@ namespace FSPerfStats FSPerfStats::tunables.userImpostorDistanceTuningEnabled = gSavedSettings.getBOOL("FSAutoTuneImpostorByDistEnabled"); FSPerfStats::tunables.userFPSTuningStrategy = gSavedSettings.getU32("FSTuningFPSStrategy"); FSPerfStats::tunables.userTargetFPS = gSavedSettings.getU32("FSTargetFPS"); - FSPerfStats::tunables.userTargetReflections = gSavedSettings.getU32("FSUserTargetReflections"); + FSPerfStats::tunables.userTargetReflections = gSavedSettings.getS32("FSUserTargetReflections"); FSPerfStats::tunables.userAutoTuneEnabled = gSavedSettings.getBOOL("FSAutoTuneFPS"); FSPerfStats::tunables.userAutoTuneLock = gSavedSettings.getBOOL("FSAutoTuneLock"); // Note: The Max ART slider is logarithmic and thus we have an intermediate proxy value diff --git a/indra/newview/installers/linux/appimage.sh b/indra/newview/installers/linux/appimage.sh deleted file mode 100755 index b06a096fa1..0000000000 --- a/indra/newview/installers/linux/appimage.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash - -SCRIPT_PATH=`readlink -f $0` -SCRIPT_PATH=`dirname $SCRIPT_PATH` - -echo "Trying to build AppImage in directory $1 into file $3" - -# All hope is lost if there is no lsb_release command -command -v lsb_release >/dev/null 2>/dev/null || exit 0 - -if [ `lsb_release -is` != "Ubuntu" ] -then - echo "Distribution is not Ubuntu, skipping AppImage creation" - exit 0 -fi - -set -e - -cd $1 -pushd packaged - -wget -q https://github.com/AppImage/AppImages/raw/master/functions.sh -O ./functions.sh -. ./functions.sh -rm functions.sh - -cp firestorm AppRun -cp ${SCRIPT_PATH}/firestorm.desktop firestorm.desktop - -copy_deps -copy_deps -copy_deps -delete_blacklisted - -# Now copy everything to ./lib. The viewer binaries got build with a rpath pointing to ./lib so all so will be magically found there. -#find ./usr/lib/ -type f -print0 | xargs -0 -Ifile cp file ./lib/ -#find ./lib/x86_64-linux-gnu/ -type f -print0 | xargs -0 -Ifile cp file ./lib/ - -#rm -rf ./usr/lib/ -#rm -rf ./lib/x86_64-linux-gnu/ - -find . -empty -type d -delete - -popd - -wget "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage" -chmod a+x appimagetool-x86_64.AppImage -./appimagetool-x86_64.AppImage --appimage-extract -rm appimagetool-x86_64.AppImage -ARCH=x86_64 squashfs-root/AppRun packaged - -if [ -f $2 ] -then - mv $2 $3 -fi diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 22c47b7a58..92086742a4 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -2428,7 +2428,8 @@ void LLAgent::propagate(const F32 dt) //----------------------------------------------------------------------------- void LLAgent::updateAgentPosition(const F32 dt, const F32 yaw_radians, const S32 mouse_x, const S32 mouse_y) { - if (mMoveTimer.getStarted() && mMoveTimer.getElapsedTimeF32() > gSavedSettings.getF32("NotMovingHintTimeout")) + static LLCachedControl hint_timeout(gSavedSettings, "NotMovingHintTimeout"); + if (mMoveTimer.getStarted() && mMoveTimer.getElapsedTimeF32() > hint_timeout) { LLFirstUse::notMoving(); } @@ -2647,7 +2648,8 @@ void LLAgent::endAnimationUpdateUI() gStatusBar->setVisibleForMouselook(true); // We don't use the mini location panel in Firestorm - // if (gSavedSettings.getBOOL("ShowMiniLocationPanel")) + // static LLCachedControl show_mini_location_panel(gSavedSettings, "ShowMiniLocationPanel"); + // if (show_mini_location_panel) // { // LLPanelTopInfoBar::getInstance()->setVisible(TRUE); // } @@ -4694,10 +4696,9 @@ bool LLAgent::teleportCore(bool is_local) // yet if the teleport will succeed. Look in // process_teleport_location_reply - // close the map panel so we can see our destination. - // we don't close search floater, see EXT-5840. - if (!gSavedSettings.getBOOL("FSDoNotHideMapOnTeleport")) // FIRE-17779: Option to not close world map on teleport - LLFloaterReg::hideInstance("world_map"); + // FIRE-17779: Option to not close world map on teleport + if (!gSavedSettings.getBOOL("FSDoNotHideMapOnTeleport")) + LLFloaterReg::hideInstance("world_map"); // hide land floater too - it'll be out of date LLFloaterReg::hideInstance("about_land"); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 2b4bfe4a1b..ca8370f866 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -6310,14 +6310,18 @@ void LLAppViewer::disconnectViewer() } // save inventory if appropriate - gInventory.cache(gInventory.getRootFolderID(), gAgent.getID()); - if (gInventory.getLibraryRootFolderID().notNull() - && gInventory.getLibraryOwnerID().notNull()) - { - gInventory.cache( - gInventory.getLibraryRootFolderID(), - gInventory.getLibraryOwnerID()); - } + if (gInventory.isInventoryUsable() + && gAgent.getID().notNull()) // Shouldn't be null at this stage + { + gInventory.cache(gInventory.getRootFolderID(), gAgent.getID()); + if (gInventory.getLibraryRootFolderID().notNull() + && gInventory.getLibraryOwnerID().notNull()) + { + gInventory.cache( + gInventory.getLibraryRootFolderID(), + gInventory.getLibraryOwnerID()); + } + } LLAvatarNameCache::instance().setCustomNameCheckCallback(LLAvatarNameCache::custom_name_check_callback_t()); // Contact sets saveNameCache(); diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index 99716e9ede..c5d90770d7 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -40,16 +40,42 @@ #include -#include "json/reader.h" // To parse manifest.json from pepperflash - - #include +#include + +#if (__GLIBC__*1000 + __GLIBC_MINOR__) >= 2034 +#pragma message "Compiling with libresolv stubs" +extern "C" +{ + int __res_nquery(res_state statep, + const char *dname, int qclass, int type, + unsigned char *answer, int anslen) + { + return res_nquery( statep, dname, qclass, type, answer, anslen ); + } + + int __dn_expand(const unsigned char *msg, + const unsigned char *eomorig, + const unsigned char *comp_dn, char *exp_dn, + int length) + { + return dn_expand( msg,eomorig,comp_dn,exp_dn,length); + } +} +#endif #if LL_SEND_CRASH_REPORTS #include "breakpad/client/linux/handler/exception_handler.h" #include "breakpad/common/linux/http_upload.h" #include "lldir.h" #include "../llcrashlogger/llcrashlogger.h" +// Fix linux compile +#if LL_USESYSTEMLIBS +#include "jsoncpp/reader.h" // JSON +#else +#include "json/reader.h" // JSON +#endif +// #endif #include "fsversionvalues.h" diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h index f9fe43b215..d9935d42a2 100644 --- a/indra/newview/llappviewerwin32.h +++ b/indra/newview/llappviewerwin32.h @@ -51,8 +51,8 @@ protected: bool initHardwareTest() override; // Win32 uses DX9 to test hardware. bool initParseCommandLine(LLCommandLineParser& clp) override; - virtual bool beingDebugged(); - virtual bool restoreErrorTrap(); + bool beingDebugged() override; + bool restoreErrorTrap() override; bool sendURLToOtherInstance(const std::string& url) override; diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp index ca83afb5ab..04dbf03e31 100644 --- a/indra/newview/llavatarrenderinfoaccountant.cpp +++ b/indra/newview/llavatarrenderinfoaccountant.cpp @@ -345,6 +345,8 @@ void LLAvatarRenderInfoAccountant::idle() && regionp->capabilitiesReceived()) { // each of these is further governed by and resets its own timer + // Note: We can have multiple regions, each launches up to two coroutines, + // it likely is expensive sendRenderInfoToRegion(regionp); getRenderInfoFromRegion(regionp); } diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index e55931cfa9..9d22045a88 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -723,7 +723,8 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg) { if(mBuddyInfo.find(agent_id) != mBuddyInfo.end()) { - if((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS) + if (((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS) + && !gAgent.isDoNotDisturb()) { LLSD args; // Always show complete name in rights dialogs diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index e31f731fde..a3f68ef93a 100644 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -98,10 +98,14 @@ LLConversationViewSession::~LLConversationViewSession() { mActiveVoiceChannelConnection.disconnect(); - if(LLVoiceClient::instanceExists() && mVoiceClientObserver) - { - LLVoiceClient::getInstance()->removeObserver(mVoiceClientObserver); - } + if (mVoiceClientObserver) + { + if (LLVoiceClient::instanceExists()) + { + LLVoiceClient::getInstance()->removeObserver(mVoiceClientObserver); + } + delete mVoiceClientObserver; + } mFlashTimer->unset(); } @@ -257,7 +261,12 @@ BOOL LLConversationViewSession::postBuild() mIsInActiveVoiceChannel = true; if(LLVoiceClient::instanceExists()) { - LLNearbyVoiceClientStatusObserver* mVoiceClientObserver = new LLNearbyVoiceClientStatusObserver(this); + if (mVoiceClientObserver) + { + LLVoiceClient::getInstance()->removeObserver(mVoiceClientObserver); + delete mVoiceClientObserver; + } + mVoiceClientObserver = new LLNearbyVoiceClientStatusObserver(this); LLVoiceClient::getInstance()->addObserver(mVoiceClientObserver); } break; diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index c6ec168cc2..d09dcc4aa9 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -673,16 +673,12 @@ void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector& emissi void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) { - // Tweak performance - //BOOL batch_fullbrights = gSavedSettings.getBOOL("RenderAlphaBatchFullbrights"); - //BOOL batch_emissives = gSavedSettings.getBOOL("RenderAlphaBatchEmissives"); static LLCachedControl batch_fullbrights(gSavedSettings, "RenderAlphaBatchFullbrights"); static LLCachedControl batch_emissives(gSavedSettings, "RenderAlphaBatchEmissives"); - // - BOOL initialized_lighting = FALSE; - BOOL light_enabled = TRUE; + bool initialized_lighting = false; + bool light_enabled = true; - BOOL use_shaders = gPipeline.canUseVertexShaders(); + bool use_shaders = gPipeline.canUseVertexShaders(); for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 527e9c6eeb..70c060379d 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -2315,7 +2315,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) // Niran's optimization const LLTextureEntry* tex_entry = face->getTextureEntry(); - if (tex_entry && tex_entry->getAlpha() == 0.f) + if ( (tex_entry && tex_entry->getAlpha() == 0.f) && ( tex_entry->getGlow() == 0.0 ) ) { continue; } diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 5a9cc27f98..2af32b7d95 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -587,18 +587,8 @@ void LLDrawPoolWater::shade2(bool edge, LLGLSLShader* shader, const LLColor3& li shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, camera.getOrigin().mV); // Factor out instance() calls shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV); shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp); - if (environment.isCloudScrollPaused()) // Factor out instance() calls - { - static const std::array zerowave{ {0.0f, 0.0f} }; - - shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, zerowave.data()); - shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, zerowave.data()); - } - else - { - shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV); - shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV); - } + shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV); + shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV); shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV); shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV); diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index fc95aec90b..0c6c241d9b 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -561,18 +561,18 @@ void LLFloaterCamera::setMode(ECameraControlMode mode) void LLFloaterCamera::switchMode(ECameraControlMode mode) { - setMode(mode); - switch (mode) { case CAMERA_CTRL_MODE_PRESETS: case CAMERA_CTRL_MODE_PAN: sFreeCamera = false; + setMode(mode); // depends onto sFreeCamera clear_camera_tool(); break; case CAMERA_CTRL_MODE_FREE_CAMERA: sFreeCamera = true; + setMode(mode); activate_camera_tool(); break; diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp index bc67c3685a..2f2cc7d1bb 100644 --- a/indra/newview/llfloatergesture.cpp +++ b/indra/newview/llfloatergesture.cpp @@ -623,8 +623,7 @@ void LLFloaterGesture::onCopyPasteAction(const LLSD& command) LLInventoryItem* item = gInventory.getItem(*it); if(item && item->getInventoryType() == LLInventoryType::IT_GESTURE) { - LLWString item_name = utf8str_to_wstring(item->getName()); - LLClipboard::instance().addToClipboard(item_name, 0, item_name.size()); + LLClipboard::instance().addToClipboard(*it); } } } diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index e3404ec9f4..8f186d5ea2 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -386,7 +386,7 @@ void LLFloaterIMSessionTab::draw() void LLFloaterIMSessionTab::enableDisableCallBtn() { - if (LLVoiceClient::instanceExists()) + if (LLVoiceClient::instanceExists() && mVoiceButton) { mVoiceButton->setEnabled( mSessionID.notNull() diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 2987593788..a92cea23c6 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -3626,7 +3626,16 @@ void LLPanelPreference::saveSettings() { view_stack.push_back(*iter); } - } + } + + if (LLStartUp::getStartupState() == STATE_STARTED) + { + LLControlVariable* control = gSavedPerAccountSettings.getControl("VoiceCallsFriendsOnly"); + if (control) + { + mSavedValues[control] = control->getValue(); + } + } } void LLPanelPreference::showMultipleViewersWarning(LLUICtrl* checkbox, const LLSD& value) diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp index d90d761aee..c006e67976 100644 --- a/indra/newview/llfloatersearch.cpp +++ b/indra/newview/llfloatersearch.cpp @@ -185,15 +185,6 @@ void LLFloaterSearch::search(const SearchQuery &p) // add the search query string subs["QUERY"] = LLURI::escape(p.query); - // add the permissions token that login.cgi gave us - // We use "search_token", and fallback to "auth_token" if not present. - LLSD search_token = LLLoginInstance::getInstance()->getResponse("search_token"); - if (search_token.asString().empty()) - { - search_token = LLLoginInstance::getInstance()->getResponse("auth_token"); - } - subs["AUTH_TOKEN"] = search_token.asString(); - // add the user's preferred maturity (can be changed via prefs) std::string maturity; if (gAgent.prefersAdult()) diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 4948039dc8..0513d1c4ba 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -56,10 +56,12 @@ #include "llscrolllistctrl.h" #include "llslurl.h" #include "lltextbox.h" +#include "lltoolbarview.h" #include "lltracker.h" #include "lltrans.h" #include "llviewerinventory.h" // LLViewerInventoryItem #include "llviewermenu.h" +#include "llviewerparcelmgr.h" #include "llviewerregion.h" #include "llviewerstats.h" #include "llviewertexture.h" @@ -95,6 +97,9 @@ static const F32 MAP_ZOOM_TIME = 0.2f; // Currently (01/26/09), this value allows the whole grid to be visible in a 1024x1024 window. static const S32 MAX_VISIBLE_REGIONS = 512; + +const S32 HIDE_BEACON_PAD = 133; + // It would be more logical to have this inside the method where it is used but to compile under gcc this // struct has to be here. struct SortRegionNames @@ -394,6 +399,8 @@ LLFloaterWorldMap::~LLFloaterWorldMap() mFriendObserver = NULL; gFloaterWorldMap = NULL; + + mTeleportFinishConnection.disconnect(); } //static @@ -407,12 +414,16 @@ void LLFloaterWorldMap::onClose(bool app_quitting) { // While we're not visible, discard the overlay images we're using LLWorldMap::getInstance()->clearImageRefs(); + mTeleportFinishConnection.disconnect(); } // virtual void LLFloaterWorldMap::onOpen(const LLSD& key) { - bool center_on_target = (key.asString() == "center"); + mTeleportFinishConnection = LLViewerParcelMgr::getInstance()-> + setTeleportFinishedCallback(boost::bind(&LLFloaterWorldMap::onTeleportFinished, this)); + + bool center_on_target = (key.asString() == "center"); mIsClosing = FALSE; @@ -1936,6 +1947,13 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim) } } +void LLFloaterWorldMap::onTeleportFinished() +{ + if(isInVisibleChain()) + { + LLWorldMapView::setPan(0, 0, TRUE); + } +} void LLFloaterWorldMap::onCommitSearchResult() { @@ -2012,3 +2030,103 @@ void LLFloaterWorldMap::onFocusLost() LLWorldMapView* map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel; map_panel->mPanning = FALSE; } + +LLPanelHideBeacon::LLPanelHideBeacon() : + mHideButton(NULL) +{ +} + +// static +LLPanelHideBeacon* LLPanelHideBeacon::getInstance() +{ + static LLPanelHideBeacon* panel = getPanelHideBeacon(); + return panel; +} + + +BOOL LLPanelHideBeacon::postBuild() +{ + mHideButton = getChild("hide_beacon_btn"); + mHideButton->setCommitCallback(boost::bind(&LLPanelHideBeacon::onHideButtonClick, this)); + + gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLPanelHideBeacon::updatePosition, this)); + + return TRUE; +} + +//virtual +void LLPanelHideBeacon::draw() +{ + if (!LLTracker::isTracking(NULL)) + { + mHideButton->setVisible(false); + return; + } + mHideButton->setVisible(true); + updatePosition(); + LLPanel::draw(); +} + +//virtual +void LLPanelHideBeacon::setVisible(BOOL visible) +{ + if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) visible = false; + + if (visible) + { + updatePosition(); + } + + LLPanel::setVisible(visible); +} + + +//static +LLPanelHideBeacon* LLPanelHideBeacon::getPanelHideBeacon() +{ + LLPanelHideBeacon* panel = new LLPanelHideBeacon(); + panel->buildFromFile("panel_hide_beacon.xml"); + + LL_INFOS() << "Build LLPanelHideBeacon panel" << LL_ENDL; + + panel->updatePosition(); + return panel; +} + +void LLPanelHideBeacon::onHideButtonClick() +{ + LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance(); + if (instance) + { + instance->onClearBtn(); + } +} + +/** +* Updates position of the panel (similar to Stand & Stop Flying panel). +*/ +void LLPanelHideBeacon::updatePosition() +{ + S32 bottom_tb_center = 0; + if (LLToolBar* toolbar_bottom = gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_BOTTOM)) + { + bottom_tb_center = toolbar_bottom->getRect().getCenterX(); + } + + S32 left_tb_width = 0; + if (LLToolBar* toolbar_left = gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_LEFT)) + { + left_tb_width = toolbar_left->getRect().getWidth(); + } + + if (gToolBarView != NULL && gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_LEFT)->hasButtons()) + { + S32 x_pos = bottom_tb_center - getRect().getWidth() / 2 - left_tb_width; + setOrigin( x_pos + HIDE_BEACON_PAD, 0); + } + else + { + S32 x_pos = bottom_tb_center - getRect().getWidth() / 2; + setOrigin( x_pos + HIDE_BEACON_PAD, 0); + } +} diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h index ae77b86d22..c51ea21be6 100644 --- a/indra/newview/llfloaterworldmap.h +++ b/indra/newview/llfloaterworldmap.h @@ -127,7 +127,8 @@ public: // teleport to the tracked item, if there is one void teleport(); void onChangeMaturity(); - + + void onClearBtn(); //Slapp instigated avatar tracking void avatarTrackFromSlapp( const LLUUID& id ); @@ -147,7 +148,6 @@ protected: void onComboTextEntry( ); void onSearchTextEntry( ); - void onClearBtn(); void onClickTeleportBtn(); void onShowTargetBtn(); void onShowAgentBtn(); @@ -176,7 +176,7 @@ protected: void onCoordinatesCommit(); void onCommitSearchResult(); - void cacheLandmarkPosition(); + void onTeleportFinished(); // Parcel details on map void requestParcelInfo(const LLVector3d& pos_global, const LLVector3d& region_origin); @@ -227,9 +227,31 @@ private: LLCtrlListInterface * mListFriendCombo; LLCtrlListInterface * mListLandmarkCombo; LLCtrlListInterface * mListSearchResults; + + boost::signals2::connection mTeleportFinishConnection; }; extern LLFloaterWorldMap* gFloaterWorldMap; + +class LLPanelHideBeacon : public LLPanel +{ +public: + static LLPanelHideBeacon* getInstance(); + + LLPanelHideBeacon(); + /*virtual*/ BOOL postBuild(); + /*virtual*/ void setVisible(BOOL visible); + /*virtual*/ void draw(); + +private: + static LLPanelHideBeacon* getPanelHideBeacon(); + void onHideButtonClick(); + void updatePosition(); + + LLButton* mHideButton; + +}; + #endif diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index 00a5037c08..c03821490d 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -492,8 +492,13 @@ void LLGestureMgr::replaceGesture(const LLUUID& item_id, LLMultiGesture* new_ges mActive[base_item_id] = new_gesture; - delete old_gesture; - old_gesture = NULL; + // replaceGesture(const LLUUID& item_id, const LLUUID& new_asset_id) + // replaces ids without repalcing gesture + if (old_gesture != new_gesture) + { + delete old_gesture; + old_gesture = NULL; + } if (asset_id.notNull()) { @@ -926,7 +931,7 @@ void LLGestureMgr::stepGesture(LLMultiGesture* gesture) else if (gesture->mWaitTimer.getElapsedTimeF32() > MAX_WAIT_ANIM_SECS) { // we've waited too long for an animation - LL_INFOS() << "Waited too long for animations to stop, continuing gesture." + LL_INFOS("GestureMgr") << "Waited too long for animations to stop, continuing gesture." << LL_ENDL; gesture->mWaitingAnimations = FALSE; gesture->mCurrentStep++; @@ -1124,6 +1129,34 @@ void LLGestureMgr::onLoadComplete(const LLUUID& asset_uuid, self.setFetchID(item_id); self.startFetch(); } + + item_map_t::iterator it = self.mActive.find(item_id); + if (it == self.mActive.end()) + { + // Gesture is supposed to be present, active, but NULL + LL_DEBUGS("GestureMgr") << "Gesture " << item_id << " not found in active list" << LL_ENDL; + } + else + { + LLMultiGesture* old_gesture = (*it).second; + if (old_gesture && old_gesture != gesture) + { + LL_DEBUGS("GestureMgr") << "Received dupplicate " << item_id << " callback" << LL_ENDL; + // In case somebody managest to activate, deactivate and + // then activate gesture again, before asset finishes loading. + // LLLoadInfo will have a different pointer, asset storage will + // see it as a different request, resulting in two callbacks. + + // deactivateSimilarGestures() did not turn this one off + // because of matching item_id + self.stopGesture(old_gesture); + + self.mActive.erase(item_id); + delete old_gesture; + old_gesture = NULL; + } + } + self.mActive[item_id] = gesture; // Everything has been successful. Add to the active list. @@ -1158,9 +1191,23 @@ void LLGestureMgr::onLoadComplete(const LLUUID& asset_uuid, } else { - LL_WARNS() << "Unable to load gesture" << LL_ENDL; + LL_WARNS("GestureMgr") << "Unable to load gesture" << LL_ENDL; - self.mActive.erase(item_id); + item_map_t::iterator it = self.mActive.find(item_id); + if (it != self.mActive.end()) + { + LLMultiGesture* old_gesture = (*it).second; + if (old_gesture) + { + // Shouldn't happen, just in case + LL_WARNS("GestureMgr") << "Gesture " << item_id << " existed when it shouldn't" << LL_ENDL; + + self.stopGesture(old_gesture); + delete old_gesture; + old_gesture = NULL; + } + self.mActive.erase(item_id); + } delete gesture; gesture = NULL; @@ -1178,9 +1225,23 @@ void LLGestureMgr::onLoadComplete(const LLUUID& asset_uuid, LLDelayedGestureError::gestureFailedToLoad( item_id ); } - LL_WARNS() << "Problem loading gesture: " << status << LL_ENDL; - - LLGestureMgr::instance().mActive.erase(item_id); + LL_WARNS("GestureMgr") << "Problem loading gesture: " << status << LL_ENDL; + + item_map_t::iterator it = self.mActive.find(item_id); + if (it != self.mActive.end()) + { + LLMultiGesture* old_gesture = (*it).second; + if (old_gesture) + { + // Shouldn't happen, just in case + LL_WARNS("GestureMgr") << "Gesture " << item_id << " existed when it shouldn't" << LL_ENDL; + + self.stopGesture(old_gesture); + delete old_gesture; + old_gesture = NULL; + } + self.mActive.erase(item_id); + } } } diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index 4a6c0c75ce..bfe8c5b5da 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -225,7 +225,7 @@ LLFetchLeaveGroupData* gFetchLeaveGroupData = NULL; void LLGroupActions::search() { // Open groups search panel instead of invoking presumed failed websearch - //LLFloaterReg::showInstance("search", LLSD().with("category", "groups")); + //LLFloaterReg::showInstance("search"); LLFloaterReg::showInstance("search", LLSD().with("tab", "groups")); // } diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 80f47d5cba..a46b8e7783 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -154,6 +154,8 @@ bool LLCanCache::operator()(LLInventoryCategory* cat, LLInventoryItem* item) LLInventoryValidationInfo::LLInventoryValidationInfo(): mFatalErrorCount(0), mWarningCount(0), + mLoopCount(0), + mOrphanedCount(0), mInitialized(false), mFatalNoRootFolder(false), mFatalNoLibraryRootFolder(false), @@ -163,7 +165,10 @@ LLInventoryValidationInfo::LLInventoryValidationInfo(): void LLInventoryValidationInfo::toOstream(std::ostream& os) const { - os << "mFatalErrorCount " << mFatalErrorCount << " mWarningCount " << mWarningCount; + os << "mFatalErrorCount " << mFatalErrorCount + << " mWarningCount " << mWarningCount + << " mLoopCount " << mLoopCount + << " mOrphanedCount " << mOrphanedCount; } @@ -177,6 +182,8 @@ void LLInventoryValidationInfo::asLLSD(LLSD& sd) const { sd["fatal_error_count"] = mFatalErrorCount; sd["warning_count"] = mWarningCount; + sd["loop_count"] = mLoopCount; + sd["orphaned_count"] = mOrphanedCount; sd["initialized"] = mInitialized; sd["missing_system_folders_count"] = LLSD::Integer(mMissingRequiredSystemFolders.size()); sd["fatal_no_root_folder"] = mFatalNoRootFolder; @@ -361,21 +368,35 @@ const LLViewerInventoryCategory* LLInventoryModel::getFirstDescendantOf(const LL return NULL; } -bool LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const +LLInventoryModel::EAnscestorResult LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const { LLInventoryObject *object = getObject(object_id); - while (object && object->getParentUUID().notNull()) - { - LLInventoryObject *parent_object = getObject(object->getParentUUID()); + if (!object) + { + LL_WARNS(LOG_INV) << "Unable to trace topmost ancestor, initial object " << object_id << " does not exist" << LL_ENDL; + return ANSCESTOR_MISSING; + } + + std::set object_ids{ object_id }; // loop protection + while (object->getParentUUID().notNull()) + { + LLUUID parent_id = object->getParentUUID(); + if (object_ids.find(parent_id) != object_ids.end()) + { + LL_WARNS(LOG_INV) << "Detected a loop on an object " << parent_id << " when searching for ancestor of " << object_id << LL_ENDL; + return ANSCESTOR_LOOP; + } + object_ids.insert(parent_id); + LLInventoryObject *parent_object = getObject(parent_id); if (!parent_object) { - LL_WARNS(LOG_INV) << "unable to trace topmost ancestor, missing item for uuid " << object->getParentUUID() << LL_ENDL; - return false; + LL_WARNS(LOG_INV) << "unable to trace topmost ancestor of " << object_id << ", missing item for uuid " << parent_id << LL_ENDL; + return ANSCESTOR_MISSING; } object = parent_object; } result = object->getUUID(); - return true; + return ANSCESTOR_OK; } // Get the object by id. Returns NULL if not found. @@ -3147,42 +3168,69 @@ bool LLInventoryModel::saveToFile(const std::string& filename, LL_INFOS(LOG_INV) << "saving inventory to: (" << filename << ")" << LL_ENDL; - llofstream fileXML(filename.c_str()); - if (!fileXML.is_open()) - { - LL_WARNS(LOG_INV) << "unable to save inventory to: " << filename << LL_ENDL; - return false; - } + try + { + llofstream fileXML(filename.c_str()); + if (!fileXML.is_open()) + { + LL_WARNS(LOG_INV) << "Failed to open file. Unable to save inventory to: " << filename << LL_ENDL; + return false; + } - LLSD cache_ver; - cache_ver["inv_cache_version"] = sCurrentInvCacheVersion; + LLSD cache_ver; + cache_ver["inv_cache_version"] = sCurrentInvCacheVersion; - fileXML << LLSDOStreamer(cache_ver) << std::endl; + if (fileXML.fail()) + { + LL_WARNS(LOG_INV) << "Failed to write cache version to file. Unable to save inventory to: " << filename << LL_ENDL; + return false; + } - S32 count = categories.size(); - S32 cat_count = 0; - S32 i; - for(i = 0; i < count; ++i) - { - LLViewerInventoryCategory* cat = categories[i]; - if(cat->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN) - { - fileXML << LLSDOStreamer(cat->exportLLSD()) << std::endl; - cat_count++; - } - } + fileXML << LLSDOStreamer(cache_ver) << std::endl; - S32 it_count = items.size(); - for(i = 0; i < it_count; ++i) - { - fileXML << LLSDOStreamer(items[i]->asLLSD()) << std::endl; - } + S32 count = categories.size(); + S32 cat_count = 0; + S32 i; + for (i = 0; i < count; ++i) + { + LLViewerInventoryCategory* cat = categories[i]; + if (cat->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN) + { + fileXML << LLSDOStreamer(cat->exportLLSD()) << std::endl; + cat_count++; + } - fileXML.close(); + if (fileXML.fail()) + { + LL_WARNS(LOG_INV) << "Failed to write a folder to file. Unable to save inventory to: " << filename << LL_ENDL; + return false; + } + } - LL_INFOS(LOG_INV) << "Inventory saved: " << cat_count << " categories, " << it_count << " items." << LL_ENDL; + S32 it_count = items.size(); + for (i = 0; i < it_count; ++i) + { + fileXML << LLSDOStreamer(items[i]->asLLSD()) << std::endl; - return true; + if (fileXML.fail()) + { + LL_WARNS(LOG_INV) << "Failed to write an item to file. Unable to save inventory to: " << filename << LL_ENDL; + return false; + } + } + + fileXML.close(); + + LL_INFOS(LOG_INV) << "Inventory saved: " << cat_count << " categories, " << it_count << " items." << LL_ENDL; + } + catch (...) + { + LOG_UNHANDLED_EXCEPTION(""); + LL_INFOS(LOG_INV) << "Failed to save inventory to: (" << filename << ")" << LL_ENDL; + return false; + } + + return true; } // message handling functionality @@ -4303,20 +4351,23 @@ void LLInventoryModel::dumpInventory() const LLPointer LLInventoryModel::validate() const { LLPointer validation_info = new LLInventoryValidationInfo; - S32 fatalities = 0; + S32 fatal_errs = 0; S32 warnings = 0; + S32 loops = 0; + S32 orphaned = 0; if (getRootFolderID().isNull()) { LL_WARNS("Inventory") << "Fatal inventory corruption: no root folder id" << LL_ENDL; validation_info->mFatalNoRootFolder = true; - fatalities++; + fatal_errs++; } if (getLibraryRootFolderID().isNull()) { + // Probably shouldn't be a fatality, inventory can function without a library LL_WARNS("Inventory") << "Fatal inventory corruption: no library root folder id" << LL_ENDL; validation_info->mFatalNoLibraryRootFolder = true; - fatalities++; + fatal_errs++; } if (mCategoryMap.size() + 1 != mParentChildCategoryTree.size()) @@ -4348,7 +4399,23 @@ LLPointer LLInventoryModel::validate() const } LLUUID topmost_ancestor_id; // Will leave as null uuid on failure - getObjectTopmostAncestor(cat_id, topmost_ancestor_id); + EAnscestorResult res = getObjectTopmostAncestor(cat_id, topmost_ancestor_id); + switch (res) + { + case ANSCESTOR_MISSING: + orphaned++; + break; + case ANSCESTOR_LOOP: + loops++; + break; + case ANSCESTOR_OK: + break; + default: + LL_WARNS("Inventory") << "Unknown ancestor error for " << cat_id << LL_ENDL; + warnings++; + break; + } + if (cat_id != cat->getUUID()) { LL_WARNS("Inventory") << "cat id/index mismatch " << cat_id << " " << cat->getUUID() << LL_ENDL; @@ -4448,8 +4515,8 @@ LLPointer LLInventoryModel::validate() const // Topmost ancestor should be root or library. LLUUID topmost_ancestor_id; - bool found = getObjectTopmostAncestor(item_id, topmost_ancestor_id); - if (!found) + EAnscestorResult found = getObjectTopmostAncestor(item_id, topmost_ancestor_id); + if (found != ANSCESTOR_OK) { LL_WARNS("Inventory") << "unable to find topmost ancestor for " << item_id << LL_ENDL; warnings++; @@ -4479,7 +4546,7 @@ LLPointer LLInventoryModel::validate() const { LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName() << "] orphaned - no child cat array for alleged parent " << parent_id << LL_ENDL; - warnings++; + orphaned++; } else { @@ -4497,6 +4564,7 @@ LLPointer LLInventoryModel::validate() const { LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName() << "] orphaned - not found in child cat array of alleged parent " << parent_id << LL_ENDL; + orphaned++; } } } @@ -4505,7 +4573,7 @@ LLPointer LLInventoryModel::validate() const LLFolderType::EType folder_type = cat->getPreferredType(); bool cat_is_in_library = false; LLUUID topmost_id; - if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) && topmost_id == getLibraryRootFolderID()) + if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) == ANSCESTOR_OK && topmost_id == getLibraryRootFolderID()) { cat_is_in_library = true; } @@ -4545,6 +4613,7 @@ LLPointer LLInventoryModel::validate() const if (parent_id.isNull()) { LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName() << "] has null parent id!" << LL_ENDL; + orphaned++; } else { @@ -4555,6 +4624,7 @@ LLPointer LLInventoryModel::validate() const { LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName() << "] orphaned - alleged parent has no child items list " << parent_id << LL_ENDL; + orphaned++; } else { @@ -4571,6 +4641,7 @@ LLPointer LLInventoryModel::validate() const { LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName() << "] orphaned - not found as child of alleged parent " << parent_id << LL_ENDL; + orphaned++; } } @@ -4589,15 +4660,18 @@ LLPointer LLInventoryModel::validate() const LL_WARNS("Inventory") << "link " << item->getUUID() << " type " << item->getActualType() << " missing backlink info at target_id " << target_id << LL_ENDL; + orphaned++; } // Links should have referents. if (item->getActualType() == LLAssetType::AT_LINK && !target_item) { LL_WARNS("Inventory") << "broken item link " << item->getName() << " id " << item->getUUID() << LL_ENDL; + orphaned++; } else if (item->getActualType() == LLAssetType::AT_LINK_FOLDER && !target_cat) { LL_WARNS("Inventory") << "broken folder link " << item->getName() << " id " << item->getUUID() << LL_ENDL; + orphaned++; } if (target_item && target_item->getIsLinkType()) { @@ -4669,8 +4743,8 @@ LLPointer LLInventoryModel::validate() const if (is_automatic) { LL_WARNS("Inventory") << "Fatal inventory corruption: cannot create system folder of type " << ft << LL_ENDL; - fatalities++; - validation_info->mMissingRequiredSystemFolders.insert(LLFolderType::EType(ft)); + fatal_errs++; + validation_info->mMissingRequiredSystemFolders.insert(folder_type); } else { @@ -4681,8 +4755,20 @@ LLPointer LLInventoryModel::validate() const else if (count_under_root > 1) { LL_WARNS("Inventory") << "Fatal inventory corruption: system folder type has excess copies under root, type " << ft << " count " << count_under_root << LL_ENDL; - validation_info->mDuplicateRequiredSystemFolders.insert(LLFolderType::EType(ft)); - fatalities++; + validation_info->mDuplicateRequiredSystemFolders.insert(folder_type); + if (!is_automatic && folder_type != LLFolderType::FT_SETTINGS) + { + // It is a fatal problem or can lead to fatal problems for COF, + // outfits, trash and other non-automatic folders. + fatal_errs++; + } + else + { + // For automatic folders it's not a fatal issue and shouldn't + // break inventory or other functionality further + // Exception: FT_SETTINGS is not automatic, but only deserves a warning. + warnings++; + } } if (count_elsewhere > 0) { @@ -4708,11 +4794,13 @@ LLPointer LLInventoryModel::validate() const } // FIXME need to fail login and tell user to retry, contact support if problem persists. - bool valid = (fatalities == 0); - LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatalities << ", warnings: " << warnings << ", valid: " << valid << LL_ENDL; + bool valid = (fatal_errs == 0); + LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatal_errs << ", warnings: " << warnings << ", valid: " << valid << LL_ENDL; - validation_info->mFatalErrorCount = fatalities; + validation_info->mFatalErrorCount = fatal_errs; validation_info->mWarningCount = warnings; + validation_info->mLoopCount = loops; + validation_info->mOrphanedCount = orphaned; return validation_info; } diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index d64590db87..cb3e886e16 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -72,6 +72,8 @@ public: S32 mFatalErrorCount; S32 mWarningCount; + S32 mLoopCount; // Presence of folders whose ansestors loop onto themselves + S32 mOrphanedCount; // Missing or orphaned items, links and folders bool mInitialized; bool mFatalNoRootFolder; bool mFatalNoLibraryRootFolder; @@ -301,9 +303,14 @@ public: // Check if one object has a parent chain up to the category specified by UUID. BOOL isObjectDescendentOf(const LLUUID& obj_id, const LLUUID& cat_id) const; - + + enum EAnscestorResult{ + ANSCESTOR_OK = 0, + ANSCESTOR_MISSING = 1, + ANSCESTOR_LOOP = 2, + }; // Follow parent chain to the top. - bool getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const; + EAnscestorResult getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const; // Re-added because of start folder id // Collect all items in inventory that are linked to item_id. diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp index b5ac94b1cd..d3ba18525b 100644 --- a/indra/newview/llkeyconflict.cpp +++ b/indra/newview/llkeyconflict.cpp @@ -411,8 +411,16 @@ void LLKeyConflictHandler::loadFromSettings(ESourceMode load_mode) filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_default); if (!gDirUtilp->fileExists(filename) || !loadFromSettings(load_mode, filename, &mControlsMap)) { - // mind placeholders - mControlsMap.insert(mDefaultsMap.begin(), mDefaultsMap.end()); + // Mind placeholders + // Do not use mControlsMap.insert(mDefaultsMap) since mControlsMap has + // placeholders that won't be added over(to) by insert. + // Or instead move generatePlaceholders call to be after copying + control_map_t::iterator iter = mDefaultsMap.begin(); + while (iter != mDefaultsMap.end()) + { + mControlsMap[iter->first].mKeyBind = iter->second.mKeyBind; + iter++; + } } } mLoadMode = load_mode; @@ -575,6 +583,8 @@ void LLKeyConflictHandler::saveToSettings(bool temporary) break; } + keys.xml_version.set(keybindings_xml_version, true); + if (temporary) { // write to temporary xml and use it for gViewerInput @@ -667,13 +677,19 @@ void LLKeyConflictHandler::resetToDefault(const std::string &control_name, U32 i { return; } + LLKeyConflict &type_data = mControlsMap[control_name]; + if (!type_data.mAssignable) + { + return; + } LLKeyData data = getDefaultControl(control_name, index); - if (data != mControlsMap[control_name].getKeyData(index)) + if (data != type_data.getKeyData(index)) { // reset controls that might have been switched to our current control removeConflicts(data, mControlsMap[control_name].mConflictMask); mControlsMap[control_name].setKeyData(data, index); + mHasUnsavedChanges = true; } } @@ -730,9 +746,9 @@ void LLKeyConflictHandler::resetToDefault(const std::string &control_name) resetToDefaultAndResolve(control_name, false); } -void LLKeyConflictHandler::resetToDefaults(ESourceMode mode) +void LLKeyConflictHandler::resetToDefaultsAndResolve() { - if (mode == MODE_SAVED_SETTINGS) + if (mLoadMode == MODE_SAVED_SETTINGS) { control_map_t::iterator iter = mControlsMap.begin(); control_map_t::iterator end = mControlsMap.end(); @@ -745,8 +761,16 @@ void LLKeyConflictHandler::resetToDefaults(ESourceMode mode) else { mControlsMap.clear(); - generatePlaceholders(mode); + + // Set key combinations. + // Copy from mDefaultsMap before doing generatePlaceholders, otherwise + // insert() will fail to add some keys into pre-existing values from + // generatePlaceholders() mControlsMap.insert(mDefaultsMap.begin(), mDefaultsMap.end()); + + // Set conflict masks and mark functions (un)assignable + generatePlaceholders(mLoadMode); + } mHasUnsavedChanges = true; @@ -756,7 +780,7 @@ void LLKeyConflictHandler::resetToDefaults() { if (!empty()) { - resetToDefaults(mLoadMode); + resetToDefaultsAndResolve(); } else { @@ -766,7 +790,7 @@ void LLKeyConflictHandler::resetToDefaults() // 3. We are loading 'current' only to replace it // but it is reliable and works Todo: consider optimizing. loadFromSettings(mLoadMode); - resetToDefaults(mLoadMode); + resetToDefaultsAndResolve(); } } @@ -799,7 +823,7 @@ void LLKeyConflictHandler::resetKeyboardBindings() void LLKeyConflictHandler::generatePlaceholders(ESourceMode load_mode) { - // These controls are meant to cause conflicts when user tries to assign same control somewhere else + // These placeholders are meant to cause conflict resolution when user tries to assign same control somewhere else // also this can be used to pre-record controls that should not conflict or to assign conflict groups/masks if (load_mode == MODE_FIRST_PERSON) @@ -859,24 +883,60 @@ void LLKeyConflictHandler::generatePlaceholders(ESourceMode load_mode) registerTemporaryControl("spin_around_ccw_sitting"); registerTemporaryControl("spin_around_cw_sitting"); } + + + // Special case, mouse clicks passed to scripts have 'lowest' piority + // thus do not conflict, everything else has a chance before them + // also in ML they have highest priority, but only when script-grabbed, + // thus do not conflict + // (see AGENT_CONTROL_ML_LBUTTON_DOWN and CONTROL_LBUTTON_DOWN_INDEX) + LLKeyConflict *type_data = &mControlsMap[script_mouse_handler_name]; + type_data->mAssignable = true; + type_data->mConflictMask = U32_MAX - CONFLICT_LMOUSE; } -bool LLKeyConflictHandler::removeConflicts(const LLKeyData &data, const U32 &conlict_mask) +bool LLKeyConflictHandler::removeConflicts(const LLKeyData &data, U32 conlict_mask) { if (conlict_mask == CONFLICT_NOTHING) { // Can't conflict return true; } + + if (data.mMouse == CLICK_LEFT + && data.mMask == MASK_NONE + && data.mKey == KEY_NONE) + { + if ((conlict_mask & CONFLICT_LMOUSE) == 0) + { + // Can't conflict + return true; + } + else + { + // simplify conflict mask + conlict_mask = CONFLICT_LMOUSE; + } + } + else + { + // simplify conflict mask + conlict_mask &= ~CONFLICT_LMOUSE; + } + std::map conflict_list; control_map_t::iterator cntrl_iter = mControlsMap.begin(); control_map_t::iterator cntrl_end = mControlsMap.end(); for (; cntrl_iter != cntrl_end; ++cntrl_iter) { + const U32 cmp_mask = cntrl_iter->second.mConflictMask; + if ((cmp_mask & conlict_mask) == 0) + { + // can't conflict + continue; + } S32 index = cntrl_iter->second.mKeyBind.findKeyData(data); - if (index >= 0 - && cntrl_iter->second.mConflictMask != CONFLICT_NOTHING - && (cntrl_iter->second.mConflictMask & conlict_mask) != 0) + if (index >= 0) { if (cntrl_iter->second.mAssignable) { diff --git a/indra/newview/llkeyconflict.h b/indra/newview/llkeyconflict.h index 2926ca3aeb..23c1adf1e4 100644 --- a/indra/newview/llkeyconflict.h +++ b/indra/newview/llkeyconflict.h @@ -66,6 +66,7 @@ public: }; const U32 CONFLICT_NOTHING = 0; + const U32 CONFLICT_LMOUSE = 0x1 << 1; // at the moment this just means that key will conflict with everything that is identical const U32 CONFLICT_ANY = U32_MAX; @@ -128,23 +129,24 @@ public: // resets current mode to defaults void resetToDefaults(); - bool empty() { return mControlsMap.empty(); } + bool empty() const { return mControlsMap.empty(); } void clear(); // reloads bindings from last valid user's xml or from default xml // to keyboard's handler static void resetKeyboardBindings(); - bool hasUnsavedChanges() { return mHasUnsavedChanges; } + bool hasUnsavedChanges() const { return mHasUnsavedChanges; } void setLoadMode(ESourceMode mode) { mLoadMode = mode; } - ESourceMode getLoadMode() { return mLoadMode; } + ESourceMode getLoadMode() const { return mLoadMode; } private: void resetToDefaultAndResolve(const std::string &control_name, bool ignore_conflicts); - void resetToDefaults(ESourceMode mode); + void resetToDefaultsAndResolve(); // at the moment these kind of control is not savable, but takes part in conflict resolution void registerTemporaryControl(const std::string &control_name, EMouseClickType mouse_ind, KEY key, MASK mask, U32 conflict_mask); + // conflict mask 0 means that any conflicts will be ignored void registerTemporaryControl(const std::string &control_name, U32 conflict_mask = 0); typedef std::map control_map_t; @@ -152,7 +154,7 @@ private: bool loadFromSettings(const ESourceMode &load_mode, const std::string &filename, control_map_t *destination); void generatePlaceholders(ESourceMode load_mode); //E.x. non-assignable values // returns false in case user is trying to reuse control that can't be reassigned - bool removeConflicts(const LLKeyData &data, const U32 &conlict_mask); + bool removeConflicts(const LLKeyData &data, U32 conlict_mask); // removes flags and removes temporary file, returns 'true' if file was removed bool clearUnsavedChanges(); diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index ba175c27ca..7b41a7320c 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -165,13 +165,12 @@ void LLLoginInstance::constructAuthParams(LLPointer user_credentia //requested_options.append("inventory-meat"); //requested_options.append("inventory-skel-targets"); #if (!defined LL_MINIMIAL_REQUESTED_OPTIONS) - if(FALSE == gSavedSettings.getBOOL("NoInventoryLibrary")) - { - requested_options.append("inventory-lib-root"); - requested_options.append("inventory-lib-owner"); - requested_options.append("inventory-skel-lib"); + + // Not requesting library will trigger mFatalNoLibraryRootFolder + requested_options.append("inventory-lib-root"); + requested_options.append("inventory-lib-owner"); + requested_options.append("inventory-skel-lib"); // requested_options.append("inventory-meat-lib"); - } requested_options.append("initial-outfit"); requested_options.append("gestures"); diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 4a5b6243f3..4626745cb5 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -1182,6 +1182,11 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) } else { + // Media might be blocked, waiting for a file, + // send an empty response to unblock it + const std::vector empty_response; + self->sendPickFileResponse(empty_response); + LLNotificationsUtil::add("MediaFileDownloadUnsupported"); } }; diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index aa2a1325e8..f56ac47e92 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -2949,6 +2949,7 @@ void LLModelPreview::lookupLODModelFiles(S32 lod) std::string lod_filename = mLODFile[LLModel::LOD_HIGH]; // BUG-230890 fix case-sensitive filename handling // std::string ext = ".dae"; + // LLStringUtil::toLower(lod_filename_lower); // std::string::size_type i = lod_filename.rfind(ext); // if (i != std::string::npos) // { @@ -4030,6 +4031,7 @@ void LLModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit) if (!mLODFrozen) { genLODs(lod, 3, enforce_tri_limit); + mFMP->refresh(); // BUG-231970 Fix b0rken upload floater refresh refresh(); } } diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp index cb4c07a417..852b39f442 100644 --- a/indra/newview/llpathfindingmanager.cpp +++ b/indra/newview/llpathfindingmanager.cpp @@ -61,7 +61,7 @@ #define CAP_SERVICE_NAVMESH_STATUS "NavMeshGenerationStatus" -#define CAP_SERVICE_OBJECT_LINKSETS "ObjectNavMeshProperties" +#define CAP_SERVICE_OBJECT_LINKSETS "RegionObjects" #define CAP_SERVICE_TERRAIN_LINKSETS "TerrainNavMeshProperties" #define CAP_SERVICE_CHARACTERS "CharacterProperties" diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index bf5ccdc593..afda93c3a3 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -1033,7 +1033,6 @@ void LLPreviewGesture::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId) // active map with the new pointer. if (LLGestureMgr::instance().isGestureActive(itemId)) { - //*TODO: This is crashing for some reason. Fix it. // Active gesture edited from menu. LLGestureMgr::instance().replaceGesture(itemId, newAssetId); gInventory.notifyObservers(); diff --git a/indra/newview/llsearchableui.cpp b/indra/newview/llsearchableui.cpp index acd325e0af..7548b178b9 100644 --- a/indra/newview/llsearchableui.cpp +++ b/indra/newview/llsearchableui.cpp @@ -134,8 +134,11 @@ void ll::statusbar::SearchableItem::setNotHighlighted( ) { mCtrl->setHighlighted( false ); - if( mWasHiddenBySearch ) - mMenu->setVisible( TRUE ); + if (mWasHiddenBySearch) + { + mMenu->setVisible(TRUE); + mWasHiddenBySearch = false; + } } } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 62d33f8620..70d6d4a116 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -3100,10 +3100,6 @@ bool idle_startup() // Have the agent start watching the friends list so we can update proxies gAgent.observeFriends(); - if (gSavedSettings.getBOOL("LoginAsGod")) - { - gAgent.requestEnterGodMode(); - } // Start automatic replay if the flag is set. if (gSavedSettings.getBOOL("StatsAutoRun") || gAgentPilot.getReplaySession()) @@ -3652,19 +3648,34 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name, gAgentAvatarp->setSex(gender); - // try to find the outfit - if not there, create some default - // wearables. + // try to find the requested outfit or folder + + // -- check for existing outfit in My Outfits + bool do_copy = false; LLUUID cat_id = findDescendentCategoryIDByName( - gInventory.getLibraryRootFolderID(), + gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS), outfit_folder_name); + + // -- check for existing folder in Library if (cat_id.isNull()) { + cat_id = findDescendentCategoryIDByName( + gInventory.getLibraryRootFolderID(), + outfit_folder_name); + if (!cat_id.isNull()) + { + do_copy = true; + } + } + + if (cat_id.isNull()) + { + // -- final fallback: create standard wearables LL_DEBUGS() << "standard wearables" << LL_ENDL; gAgentWearables.createStandardWearables(); } else { - bool do_copy = true; bool do_append = false; LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id); // Need to fetch cof contents before we can wear. @@ -4671,6 +4682,19 @@ bool process_login_success_response(U32 &first_sim_size_x, U32 &first_sim_size_y } } + std::string fake_initial_outfit_name = gSavedSettings.getString("FakeInitialOutfitName"); + if (!fake_initial_outfit_name.empty()) + { + gAgent.setFirstLogin(TRUE); + sInitialOutfit = fake_initial_outfit_name; + if (sInitialOutfitGender.empty()) + { + sInitialOutfitGender = "female"; // just guess, will get overridden when outfit is worn anyway. + } + + LL_WARNS() << "Faking first-time login with initial outfit " << sInitialOutfit << LL_ENDL; + } + // set the location of the Agent Appearance service, from which we can request // avatar baked textures if they are supported by the current region std::string agent_appearance_url = response["agent_appearance_service"]; diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp index 08e26c7214..389c617c0a 100644 --- a/indra/newview/lltoolcomp.cpp +++ b/indra/newview/lltoolcomp.cpp @@ -44,6 +44,7 @@ #include "lltoolmgr.h" #include "lltoolselectrect.h" #include "lltoolplacer.h" +#include "llviewerinput.h" #include "llviewermenu.h" #include "llviewerobject.h" #include "llviewerwindow.h" @@ -763,7 +764,7 @@ BOOL LLToolCompGun::handleHover(S32 x, S32 y, MASK mask) BOOL LLToolCompGun::handleMouseDown(S32 x, S32 y, MASK mask) { // if the left button is grabbed, don't put up the pie menu - if (gAgent.leftButtonGrabbed()) + if (gAgent.leftButtonGrabbed() && gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON)) { gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN); return FALSE; @@ -780,7 +781,7 @@ BOOL LLToolCompGun::handleMouseDown(S32 x, S32 y, MASK mask) BOOL LLToolCompGun::handleDoubleClick(S32 x, S32 y, MASK mask) { // if the left button is grabbed, don't put up the pie menu - if (gAgent.leftButtonGrabbed()) + if (gAgent.leftButtonGrabbed() && gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON)) { gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN); return FALSE; @@ -848,7 +849,10 @@ BOOL LLToolCompGun::handleRightMouseUp(S32 x, S32 y, MASK mask) BOOL LLToolCompGun::handleMouseUp(S32 x, S32 y, MASK mask) { - gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP); + if (gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON)) + { + gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP); + } setCurrentTool( (LLTool*) mGun ); return TRUE; } diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp index 99138bbbd5..b175175801 100644 --- a/indra/newview/lltoolgrab.cpp +++ b/indra/newview/lltoolgrab.cpp @@ -51,6 +51,7 @@ #include "lltoolmgr.h" #include "lltoolpie.h" #include "llviewercamera.h" +#include "llviewerinput.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" @@ -143,7 +144,6 @@ BOOL LLToolGrabBase::handleMouseDown(S32 x, S32 y, MASK mask) LL_INFOS() << "LLToolGrab handleMouseDown" << LL_ENDL; } - // call the base class to propogate info to sim LLTool::handleMouseDown(x, y, mask); // leftButtonGrabbed() checks if controls are reserved by scripts, but does not take masks into account @@ -153,6 +153,19 @@ BOOL LLToolGrabBase::handleMouseDown(S32 x, S32 y, MASK mask) gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE); } mClickedInMouselook = gAgentCamera.cameraMouselook(); + + if (mClickedInMouselook && gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON)) + { + // LLToolCompGun::handleMouseDown handles the event if ML controls are grabed, + // but LLToolGrabBase is often the end point for mouselook clicks if ML controls + // are not grabbed and LLToolGrabBase::handleMouseDown consumes the event, + // so send clicks from here. + // We are sending specifically CONTROL_LBUTTON_DOWN instead of _ML_ version. + gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN); + + // Todo: LLToolGrabBase probably shouldn't consume the event if there is nothing + // to grab in Mouselook, it intercepts handling in scanMouse + } return TRUE; } @@ -980,9 +993,18 @@ void LLToolGrabBase::handleHoverFailed(S32 x, S32 y, MASK mask) BOOL LLToolGrabBase::handleMouseUp(S32 x, S32 y, MASK mask) { - // call the base class to propogate info to sim LLTool::handleMouseUp(x, y, mask); + if (gAgentCamera.cameraMouselook() && gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON)) + { + // LLToolCompGun::handleMouseUp handles the event if ML controls are grabed, + // but LLToolGrabBase is often the end point for mouselook clicks if ML controls + // are not grabbed and LToolGrabBase::handleMouseUp consumes the event, + // so send clicks from here. + // We are sending specifically CONTROL_LBUTTON_UP instead of _ML_ version. + gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP); + } + if( hasMouseCapture() ) { setMouseCapture( FALSE ); diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 1833c78136..14ace2ac63 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -445,8 +445,9 @@ BOOL LLToolPie::handleLeftClickPick() gFocusMgr.setKeyboardFocus(NULL); } - BOOL touchable = (object && object->flagHandleTouch()) - || (parent && parent->flagHandleTouch()); + bool touchable = object + && (object->getClickAction() != CLICK_ACTION_DISABLED) + && (object->flagHandleTouch() || (parent && parent->flagHandleTouch())); // Switch to grab tool if physical or triggerable if (object && @@ -754,6 +755,12 @@ bool LLToolPie::teleportToClickedLocation() LLViewerObject* objp = mHoverPick.getObject(); LLViewerObject* parentp = objp ? objp->getRootEdit() : NULL; + if (objp && (objp->getAvatar() == gAgentAvatarp || objp == gAgentAvatarp)) // ex: nametag + { + // Don't teleport to self, teleporting to other avatars is fine + return false; + } + bool is_in_world = mHoverPick.mObjectID.notNull() && objp && !objp->isHUDAttachment(); bool is_land = mHoverPick.mPickType == LLPickInfo::PICK_LAND; bool pos_non_zero = !mHoverPick.mPosGlobal.isExactlyZero(); @@ -867,7 +874,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask) else if (!mMouseOutsideSlop && mMouseButtonDown // disable camera steering if click on land is not used for moving - && gViewerInput.isMouseBindUsed(CLICK_LEFT)) + && gViewerInput.isMouseBindUsed(CLICK_LEFT, MASK_NONE, MODE_THIRD_PERSON)) { S32 delta_x = x - mMouseDownX; S32 delta_y = y - mMouseDownY; diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp index cb09f52d97..d4a9398259 100644 --- a/indra/newview/llviewerassetstorage.cpp +++ b/indra/newview/llviewerassetstorage.cpp @@ -356,7 +356,7 @@ void LLViewerAssetStorage::checkForTimeouts() // Restore requests LLCoprocedureManager* manager = LLCoprocedureManager::getInstance(); while (mCoroWaitList.size() > 0 - && manager->count(VIEWER_ASSET_STORAGE_CORO_POOL) < LLCoprocedureManager::DEFAULT_QUEUE_SIZE) + && manager->count(VIEWER_ASSET_STORAGE_CORO_POOL) < (LLCoprocedureManager::DEFAULT_QUEUE_SIZE - 1)) { CoroWaitList &request = mCoroWaitList.front(); @@ -430,7 +430,8 @@ void LLViewerAssetStorage::queueRequestHttp( if (!duplicate) { // Coroutine buffer has fixed size (synchronization buffer, so we have no alternatives), so buffer any request above limit - if (LLCoprocedureManager::instance().count(VIEWER_ASSET_STORAGE_CORO_POOL) < LLCoprocedureManager::DEFAULT_QUEUE_SIZE) + LLCoprocedureManager* manager = LLCoprocedureManager::getInstance(); + if (manager->count(VIEWER_ASSET_STORAGE_CORO_POOL) < (LLCoprocedureManager::DEFAULT_QUEUE_SIZE - 1)) { // [UDP Assets] //bool with_http = true; @@ -438,7 +439,7 @@ void LLViewerAssetStorage::queueRequestHttp( //LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp); // [UDP Assets] - LLCoprocedureManager::instance().enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro", + manager->enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro", boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data)); } else diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 3ef82e5e26..0a412f983b 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -1127,7 +1127,7 @@ void handleUserTargetDrawDistanceChanged(const LLSD& newValue) void handleUserTargetReflectionsChanged(const LLSD& newValue) { - const auto newval = gSavedSettings.getF32("FSUserTargetReflections"); + const auto newval = gSavedSettings.getS32("FSUserTargetReflections"); FSPerfStats::tunables.userTargetReflections = newval; } diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp index 782cf21728..881a7df71a 100644 --- a/indra/newview/llviewerinput.cpp +++ b/indra/newview/llviewerinput.cpp @@ -908,13 +908,20 @@ bool toggle_enable_media(EKeystate s) bool walk_to(EKeystate s) { - if (KEYSTATE_DOWN != s) return true; + if (KEYSTATE_DOWN != s) + { + // teleport/walk is usually on mouseclick, mouseclick needs + // to let AGENT_CONTROL_LBUTTON_UP happen if teleport didn't, + // so return false, but if it causes issues, do some kind of + // "return !has_teleported" + return false; + } return LLToolPie::getInstance()->walkToClickedLocation(); } bool teleport_to(EKeystate s) { - if (KEYSTATE_DOWN != s) return true; + if (KEYSTATE_DOWN != s) return false; return LLToolPie::getInstance()->teleportToClickedLocation(); } @@ -942,7 +949,47 @@ bool voice_follow_key(EKeystate s) return false; } -bool agen_control_lbutton_handle(EKeystate s) +bool script_trigger_lbutton(EKeystate s) +{ + // Check for script overriding/expecting left mouse button. + // Note that this does not pass event further and depends onto mouselook. + // Checks CONTROL_ML_LBUTTON_DOWN_INDEX for mouselook, + // CONTROL_LBUTTON_DOWN_INDEX for normal camera + if (gAgent.leftButtonGrabbed()) + { + bool mouselook = gAgentCamera.cameraMouselook(); + switch (s) + { + case KEYSTATE_DOWN: + if (mouselook) + { + gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN); + } + else + { + gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN); + } + return true; + case KEYSTATE_UP: + if (mouselook) + { + gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP); + } + else + { + gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP); + } + return true; + default: + break; + } + } + return false; +} + +// Used by scripts, for overriding/handling left mouse button +// see mControlsTakenCount +bool agent_control_lbutton_handle(EKeystate s) { switch (s) { @@ -1014,6 +1061,7 @@ REGISTER_KEYBOARD_ACTION("teleport_to", teleport_to); REGISTER_KEYBOARD_ACTION("walk_to", walk_to); REGISTER_KEYBOARD_GLOBAL_ACTION("toggle_voice", toggle_voice); REGISTER_KEYBOARD_GLOBAL_ACTION("voice_follow_key", voice_follow_key); +REGISTER_KEYBOARD_ACTION(script_mouse_handler_name, script_trigger_lbutton); #undef REGISTER_KEYBOARD_ACTION LLViewerInput::LLViewerInput() @@ -1286,6 +1334,20 @@ BOOL LLViewerInput::bindMouse(const S32 mode, const EMouseClickType mouse, const typedef boost::function function_t; function_t function = NULL; + if (mouse == CLICK_LEFT + && mask == MASK_NONE + && function_name == script_mouse_handler_name) + { + // Special case + // Left click has script overrides and by default + // is handled via agent_control_lbutton as last option + // In case of mouselook and present overrides it has highest + // priority even over UI and is handled in LLToolCompGun::handleMouseDown + // so just mark it as having default handler + mLMouseDefaultHandling[mode] = true; + return TRUE; + } + LLKeybindFunctionData* result = LLKeyboardActionRegistry::getValue(function_name); if (result) { @@ -1362,7 +1424,8 @@ LLViewerInput::Keys::Keys() : first_person("first_person"), third_person("third_person"), sitting("sitting"), - edit_avatar("edit_avatar") + edit_avatar("edit_avatar"), + xml_version("xml_version", 0) {} void LLViewerInput::resetBindings() @@ -1373,6 +1436,7 @@ void LLViewerInput::resetBindings() mGlobalMouseBindings[i].clear(); mKeyBindings[i].clear(); mMouseBindings[i].clear(); + mLMouseDefaultHandling[i] = false; } } @@ -1391,6 +1455,65 @@ S32 LLViewerInput::loadBindingsXML(const std::string& filename) binding_count += loadBindingMode(keys.third_person, MODE_THIRD_PERSON); binding_count += loadBindingMode(keys.sitting, MODE_SITTING); binding_count += loadBindingMode(keys.edit_avatar, MODE_EDIT_AVATAR); + + // verify version + if (keys.xml_version < 1) + { + // updating from a version that was not aware of LMouse bindings + for (S32 i = 0; i < MODE_COUNT; i++) + { + mLMouseDefaultHandling[i] = true; + } + + // fix missing values + KeyBinding mouse_binding; + mouse_binding.key = ""; + mouse_binding.mask = "NONE"; + mouse_binding.mouse = "LMB"; + mouse_binding.command = script_mouse_handler_name; + + if (keys.third_person.isProvided()) + { + keys.third_person.bindings.add(mouse_binding); + } + + if (keys.first_person.isProvided()) + { + keys.first_person.bindings.add(mouse_binding); + } + + if (keys.sitting.isProvided()) + { + keys.sitting.bindings.add(mouse_binding); + } + + if (keys.edit_avatar.isProvided()) + { + keys.edit_avatar.bindings.add(mouse_binding); + } + + // fix version + keys.xml_version.set(keybindings_xml_version, true); + + // Write the resulting XML to file + LLXMLNodePtr output_node = new LLXMLNode("keys", false); + LLXUIParser write_parser; + write_parser.writeXUI(output_node, keys); + + if (!output_node->isNull()) + { + // file in app_settings is supposed to be up to date + // this is only for the file from user_settings + LL_INFOS("ViewerInput") << "Updating file " << filename << " to a newer version" << LL_ENDL; + LLFILE *fp = LLFile::fopen(filename, "w"); + if (fp != NULL) + { + LLXMLNode::writeHeaderToFile(fp); + output_node->writeToFile(fp); + fclose(fp); + } + } + } } return binding_count; } @@ -1562,17 +1685,6 @@ bool LLViewerInput::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) bool res = scanKey(mKeyBindings[mode], mKeyBindings[mode].size(), key, mask, key_down, key_up, key_level, repeat); - if (!res && agent_control_lbutton.canHandle(CLICK_NONE, key, mask)) - { - if (key_down && !repeat) - { - res = agen_control_lbutton_handle(KEYSTATE_DOWN); - } - if (key_up) - { - res = agen_control_lbutton_handle(KEYSTATE_UP); - } - } return res; } @@ -1696,29 +1808,36 @@ bool LLViewerInput::scanMouse(EMouseClickType click, EMouseState state) const bool res = false; S32 mode = getMode(); MASK mask = gKeyboard->currentMask(TRUE); - - // By default mouse clicks require exact mask - // Todo: support for mIgnoreMasks because some functions like teleports - // expect to be canceled, but for voice it's prefered to ignore mask. res = scanMouse(mMouseBindings[mode], mMouseBindings[mode].size(), click, mask, state, false); - // no user defined actions found or those actions can't handle the key/button, handle control if nessesary - if (!res && agent_control_lbutton.canHandle(click, KEY_NONE, mask)) + + // No user defined actions found or those actions can't handle the key/button, + // so handle CONTROL_LBUTTON if nessesary. + // + // Default handling for MODE_FIRST_PERSON is in LLToolCompGun::handleMouseDown, + // and sends AGENT_CONTROL_ML_LBUTTON_DOWN, but it only applies if ML controls + // are leftButtonGrabbed(), send a normal click otherwise. + + if (!res + && mLMouseDefaultHandling[mode] + && (mode != MODE_FIRST_PERSON || !gAgent.leftButtonGrabbed()) + && (click == CLICK_LEFT || click == CLICK_DOUBLELEFT) + ) { switch (state) { case MOUSE_STATE_DOWN: - agen_control_lbutton_handle(KEYSTATE_DOWN); + agent_control_lbutton_handle(KEYSTATE_DOWN); res = true; break; case MOUSE_STATE_CLICK: // might not work best with some functions, // but some function need specific states too specifically - agen_control_lbutton_handle(KEYSTATE_DOWN); - agen_control_lbutton_handle(KEYSTATE_UP); + agent_control_lbutton_handle(KEYSTATE_DOWN); + agent_control_lbutton_handle(KEYSTATE_UP); res = true; break; case MOUSE_STATE_UP: - agen_control_lbutton_handle(KEYSTATE_UP); + agent_control_lbutton_handle(KEYSTATE_UP); res = true; break; default: @@ -1748,7 +1867,7 @@ void LLViewerInput::scanMouse() } } -bool LLViewerInput::isMouseBindUsed(const EMouseClickType mouse, const MASK mask, const S32 mode) +bool LLViewerInput::isMouseBindUsed(const EMouseClickType mouse, const MASK mask, const S32 mode) const { S32 size = mMouseBindings[mode].size(); for (S32 index = 0; index < size; index++) diff --git a/indra/newview/llviewerinput.h b/indra/newview/llviewerinput.h index 2efb5c95ba..d5c8e6c8e1 100644 --- a/indra/newview/llviewerinput.h +++ b/indra/newview/llviewerinput.h @@ -31,6 +31,8 @@ #include "llinitparam.h" const S32 MAX_KEY_BINDINGS = 128; // was 60 +const S32 keybindings_xml_version = 1; +const std::string script_mouse_handler_name = "script_trigger_lbutton"; class LLNamedFunction { @@ -100,7 +102,7 @@ public: third_person, sitting, edit_avatar; - + Optional xml_version; // 'xml', because 'version' appears to be reserved Keys(); }; @@ -131,7 +133,8 @@ public: BOOL handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down); void scanMouse(); - bool isMouseBindUsed(const EMouseClickType mouse, const MASK mask = MASK_NONE, const S32 mode = MODE_THIRD_PERSON); + bool isMouseBindUsed(const EMouseClickType mouse, const MASK mask, const S32 mode) const; + bool isLMouseHandlingDefault(const S32 mode) const { return mLMouseDefaultHandling[mode]; } private: bool scanKey(const std::vector &binding, @@ -171,6 +174,7 @@ private: // to send what we think function wants based on collection of bools (mKeyRepeated, mKeyLevel, mKeyDown) std::vector mKeyBindings[MODE_COUNT]; std::vector mMouseBindings[MODE_COUNT]; + bool mLMouseDefaultHandling[MODE_COUNT]; // Due to having special priority // keybindings that do not consume event and are handled earlier, before floaters std::vector mGlobalKeyBindings[MODE_COUNT]; diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 2217a10d8e..dd4a806fc8 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -3262,10 +3262,6 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla case LLViewerMediaObserver::MEDIA_EVENT_FILE_DOWNLOAD: { LL_DEBUGS("Media") << "Media event - file download requested - filename is " << plugin->getFileDownloadFilename() << LL_ENDL; - - //unblock media plugin - const std::vector empty_response; - plugin->sendPickFileResponse(empty_response); } break; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index df1afbc78c..126725d6b0 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -159,6 +159,7 @@ #include "llcheckboxctrl.h" #include "llfloatergridstatus.h" #include "llfloaterpreference.h" +#include "llkeyconflict.h" #include "lllogininstance.h" #include "llscenemonitor.h" #include "llsdserialize.h" @@ -9689,26 +9690,88 @@ class LLToggleShaderControl : public view_listener_t }; //[FIX FIRE-1927 - enable DoubleClickTeleport shortcut : SJ] -class LLAdvancedToggleDoubleClickTeleport: public view_listener_t +// This stuff is based on LLPanelPreferenceControls::setKeyBind() and LLPanelPreferenceControls::canKeyBindHandle() +void setDoubleClickAction(const std::string& control) +{ + constexpr LLKeyConflictHandler::ESourceMode mode{ LLKeyConflictHandler::MODE_THIRD_PERSON }; + constexpr EMouseClickType click{ EMouseClickType::CLICK_DOUBLELEFT }; + constexpr KEY key{ KEY_NONE }; + constexpr MASK mask{ MASK_NONE }; + + LLKeyConflictHandler conflictHandler; + conflictHandler.setLoadMode(mode); + conflictHandler.loadFromSettings(mode); + + if (!conflictHandler.canAssignControl(control)) + { + return; + } + + bool is_enabled = conflictHandler.canHandleControl(control, click, key, mask); + if (!is_enabled) + { + // find free spot to add data, if no free spot, assign to first + S32 index = 0; + for (S32 i = 0; i < 3; i++) + { + if (conflictHandler.getControl(control, i).isEmpty()) + { + index = i; + break; + } + } + + bool ignore_mask = true; + conflictHandler.registerControl(control, index, click, key, mask, ignore_mask); + } + else + { + // find specific control and reset it + for (S32 i = 0; i < 3; i++) + { + LLKeyData data = conflictHandler.getControl(control, i); + if (data.mMouse == click && data.mKey == key && data.mMask == mask) + { + conflictHandler.clearControl(control, i); + } + } + } + + conflictHandler.saveToSettings(); +} + +bool isDoubleClickActionEnabled(const std::string control) +{ + constexpr LLKeyConflictHandler::ESourceMode mode{ LLKeyConflictHandler::MODE_THIRD_PERSON }; + constexpr EMouseClickType click{ EMouseClickType::CLICK_DOUBLELEFT }; + constexpr KEY key{ KEY_NONE }; + constexpr MASK mask{ MASK_NONE }; + + LLKeyConflictHandler conflictHandler; + conflictHandler.loadFromSettings(mode); + + return conflictHandler.canHandleControl(control, click, key, mask); +} + +class FSAdvancedToggleDoubleClickAction: public view_listener_t { bool handleEvent(const LLSD& userdata) { - BOOL checked = gSavedSettings.getBOOL("DoubleClickTeleport"); - if (checked) - { - gSavedSettings.setBOOL("DoubleClickTeleport", FALSE); - report_to_nearby_chat(LLTrans::getString("DoubleClickTeleportDisabled")); - } - else - { - gSavedSettings.setBOOL("DoubleClickTeleport", TRUE); - gSavedSettings.setBOOL("DoubleClickAutoPilot", FALSE); - report_to_nearby_chat(LLTrans::getString("DoubleClickTeleportEnabled")); - } + const std::string& control = userdata.asStringRef(); + setDoubleClickAction(control); return true; } }; +class FSAdvancedCheckEnabledDoubleClickAction : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + const std::string& control = userdata.asStringRef(); + return isDoubleClickActionEnabled(control); + } +}; + // Add telemetry controls to the viewer menus class FSTelemetryToggleActive : public view_listener_t { @@ -11963,7 +12026,8 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedClickRenderProfile(), "Advanced.ClickRenderProfile"); view_listener_t::addMenu(new LLAdvancedClickRenderBenchmark(), "Advanced.ClickRenderBenchmark"); //[FIX FIRE-1927 - enable DoubleClickTeleport shortcut : SJ] - view_listener_t::addMenu(new LLAdvancedToggleDoubleClickTeleport, "Advanced.ToggleDoubleClickTeleport"); + view_listener_t::addMenu(new FSAdvancedToggleDoubleClickAction, "Advanced.SetDoubleClickAction"); + view_listener_t::addMenu(new FSAdvancedCheckEnabledDoubleClickAction, "Advanced.CheckEnabledDoubleClickAction"); #ifdef TOGGLE_HACKED_GODLIKE_VIEWER view_listener_t::addMenu(new LLAdvancedHandleToggleHackedGodmode(), "Advanced.HandleToggleHackedGodmode"); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 9da25ecbc2..6c015d4b34 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -1316,6 +1316,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num, MAX_OBJECT_BINARY_DATA_SIZE); mTotalCRC = crc; + // Might need to update mSourceMuted here to properly pick up new radius mSoundCutOffRadius = cutoff; // Owner ID used for sound muting or particle system muting @@ -6042,7 +6043,7 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow else if (flags & LL_SOUND_FLAG_STOP) { // Just shut off the sound - mAudioSourcep->play(LLUUID::null); + mAudioSourcep->stop(); } return; } @@ -6089,7 +6090,7 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow mAudioSourcep->setQueueSounds(queue); if(!queue) // stop any current sound first to avoid "farts of doom" (SL-1541) -MG { - mAudioSourcep->play(LLUUID::null); + mAudioSourcep->stop(); } // Play this sound if region maturity permits diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index a0ae4a9f9b..028bfcd64c 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -3042,6 +3042,21 @@ void LLViewerRegion::unpackRegionHandshake() } mCentralBakeVersion = region_protocols & 1; // was (S32)gSavedSettings.getBOOL("UseServerTextureBaking"); + // Earlier trigger for BOM support on region + #ifdef OPENSIM + constexpr U64 REGION_SUPPORTS_BOM {(U64)1<<63}; + if(region_protocols & REGION_SUPPORTS_BOM) // OS sets bit 63 when BOM supported + { + mMaxBakes = LLAvatarAppearanceDefines::EBakedTextureIndex::BAKED_NUM_INDICES; + mMaxTEs = LLAvatarAppearanceDefines::ETextureIndex::TEX_NUM_INDICES; + } + else + { + mMaxBakes = LLAvatarAppearanceDefines::EBakedTextureIndex::BAKED_LEFT_ARM; + mMaxTEs = LLAvatarAppearanceDefines::ETextureIndex::TEX_HEAD_UNIVERSAL_TATTOO; + } + #endif + // LLVLComposition *compp = getComposition(); if (compp) { @@ -3226,12 +3241,12 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("ObjectAnimation"); capabilityNames.append("ObjectMedia"); capabilityNames.append("ObjectMediaNavigate"); - capabilityNames.append("ObjectNavMeshProperties"); capabilityNames.append("ParcelPropertiesUpdate"); capabilityNames.append("ParcelVoiceInfoRequest"); capabilityNames.append("ProductInfoRequest"); capabilityNames.append("ProvisionVoiceAccountRequest"); capabilityNames.append("ReadOfflineMsgs"); // Requires to respond reliably: AcceptFriendship, AcceptGroupInvite, DeclineFriendship, DeclineGroupInvite + capabilityNames.append("RegionObjects"); capabilityNames.append("RemoteParcelRequest"); capabilityNames.append("RenderMaterials"); capabilityNames.append("RequestTextureDownload"); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index b08f70258c..012fed6ce2 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2506,6 +2506,10 @@ void LLViewerWindow::initWorldUI() LLPanelStandStopFlying* panel_stand_stop_flying = LLPanelStandStopFlying::getInstance(); panel_ssf_container->addChild(panel_stand_stop_flying); + // Leave this out for now until somebody wants to adjust the panel_toolbar_view.xml files... + //LLPanelHideBeacon* panel_hide_beacon = LLPanelHideBeacon::getInstance(); + //panel_ssf_container->addChild(panel_hide_beacon); + panel_ssf_container->setVisible(TRUE); LLMenuOptionPathfindingRebakeNavmesh::getInstance()->initialize(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 6883bdc364..957cf07b77 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1448,11 +1448,8 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { LL_RECORD_BLOCK_TIME(FTM_AVATAR_EXTENT_UPDATE); -// not called as often as it used to be but still no harm in optimising -// S32 box_detail = gSavedSettings.getS32("AvatarBoundingBoxComplexity"); - static const LLCachedControl avatar_bounding_box_complexity(gSavedSettings, "AvatarBoundingBoxComplexity"); - S32 box_detail(avatar_bounding_box_complexity); -// + static LLCachedControl box_detail_cache(gSavedSettings, "AvatarBoundingBoxComplexity"); + S32 box_detail = box_detail_cache; if (getOverallAppearance() != AOA_NORMAL) { if (isControlAvatar()) @@ -2695,17 +2692,14 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time) { LL_INFOS() << "Warning! Idle on dead avatar" << LL_ENDL; return; - } + } // record time and refresh "tooSlow" status FSPerfStats::RecordAvatarTime T(getID(), FSPerfStats::StatType_t::RENDER_IDLE); // per avatar "idle" time. updateTooSlow(); // ; - // Use LLCachedControl static LLCachedControl disable_all_render_types(gSavedSettings, "DisableAllRenderTypes"); if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR)) - //&& !(gSavedSettings.getBOOL("DisableAllRenderTypes")) && !isSelf()) - && !(disable_all_render_types) && !isSelf()) - // + && !disable_all_render_types && !isSelf()) { if (!mIsControlAvatar) { @@ -2867,12 +2861,9 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled) // Don't render the user's own voice visualizer when in mouselook, or when opening the mic is disabled. if(isSelf()) { - // Faster debug settings - //if(gAgentCamera.cameraMouselook() || gSavedSettings.getBOOL("VoiceDisableMic")) - static LLCachedControl voiceDisableMic(gSavedSettings, "VoiceDisableMic"); + static LLCachedControl voiceDisableMic(gSavedSettings, "VoiceDisableMic"); static LLCachedControl fsShowMyOwnVoiceVisualizer(gSavedSettings, "FSShowMyOwnVoiceVisualizer"); // FIRE-21210: Don't show my voice visualizer if (gAgentCamera.cameraMouselook() || voiceDisableMic || !fsShowMyOwnVoiceVisualizer) - // { render_visualizer = false; } @@ -3388,16 +3379,12 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) mChats.clear(); } - static LLCachedControl renderNameShowTime(gSavedSettings, "RenderNameShowTime"); - static LLCachedControl renderNameFadeDuration(gSavedSettings, "RenderNameFadeDuration"); - static LLCachedControl useChatBubbles(gSavedSettings, "UseChatBubbles"); - static LLCachedControl useTypingBubbles(gSavedSettings, "UseTypingBubbles"); - static LLCachedControl renderNameShowSelf(gSavedSettings, "RenderNameShowSelf"); - static LLCachedControl avatarNameTagMode(gSavedSettings, "AvatarNameTagMode"); - const F32 time_visible = mTimeVisible.getElapsedTimeF32(); - const F32 NAME_SHOW_TIME = F32(renderNameShowTime); // seconds - const F32 FADE_DURATION = F32(renderNameFadeDuration); // seconds + static LLCachedControl NAME_SHOW_TIME(gSavedSettings, "RenderNameShowTime"); // seconds + static LLCachedControl FADE_DURATION(gSavedSettings, "RenderNameFadeDuration"); // seconds + static LLCachedControl use_chat_bubbles(gSavedSettings, "UseChatBubbles"); + static LLCachedControl use_typing_bubbles(gSavedSettings, "UseTypingBubbles"); + // [RLVa:KB] - Checked: RLVa-2.0.1 bool fRlvShowAvTag = true, fRlvShowAvName = true; if (RlvActions::isRlvEnabled()) @@ -3406,9 +3393,9 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) fRlvShowAvName = (fRlvShowAvTag) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, getID())); } // [/RLVa:KB] - BOOL visible_chat = useChatBubbles && (mChats.size() || mTyping); - BOOL visible_typing = useTypingBubbles && mTyping; - BOOL render_name = visible_chat || + bool visible_chat = use_chat_bubbles && (mChats.size() || mTyping); + bool visible_typing = use_typing_bubbles && mTyping; + bool render_name = visible_chat || visible_typing || // [RLVa:KB] - Checked: RLVa-2.0.1 ((fRlvShowAvTag) && @@ -3419,10 +3406,11 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) // draw if we're specifically hiding our own name. if (isSelf()) { + static LLCachedControl render_name_show_self(gSavedSettings, "RenderNameShowSelf"); + static LLCachedControl name_tag_mode(gSavedSettings, "AvatarNameTagMode"); render_name = render_name && !gAgentCamera.cameraMouselook() - && (visible_chat || (renderNameShowSelf - && S32(avatarNameTagMode) )); + && (visible_chat || (render_name_show_self && name_tag_mode)); } if ( !render_name ) @@ -3437,7 +3425,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) return; } - BOOL new_name = FALSE; + bool new_name = FALSE; if (visible_chat != mVisibleChat) { mVisibleChat = visible_chat; @@ -3520,7 +3508,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) // idleUpdateNameTagAlpha(new_name, alpha); } -void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) +void LLVOAvatar::idleUpdateNameTagText(bool new_name) { LLNameValue *title = getNVPair("Title"); LLNameValue* firstname = getNVPair("FirstName"); @@ -4137,7 +4125,7 @@ void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last) mNameText->setPositionAgent(name_position); } -void LLVOAvatar::idleUpdateNameTagAlpha(BOOL new_name, F32 alpha) +void LLVOAvatar::idleUpdateNameTagAlpha(bool new_name, F32 alpha) { llassert(mNameText); @@ -4336,11 +4324,8 @@ void LLVOAvatar::updateAppearanceMessageDebugText() { debug_line += llformat(" - cof: %d req: %d rcv:%d", curr_cof_version, last_request_cof_version, last_received_cof_version); - // Use LLCachedControl - //if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure")) - static LLCachedControl debug_force_appearance_request_failure(gSavedSettings, "DebugForceAppearanceRequestFailure"); - if (debug_force_appearance_request_failure) - // + static LLCachedControl debug_force_failure(gSavedSettings, "DebugForceAppearanceRequestFailure"); + if (debug_force_failure) { debug_line += " FORCING ERRS"; } @@ -6681,8 +6666,8 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL if (PlayModeUISndTyping) // FIRE-8190: Preview function for "UI Sounds" Panel { - static LLCachedControl uiSndTyping(gSavedSettings, "UISndTyping"); - LLUUID sound_id = LLUUID(uiSndTyping); + static LLCachedControl ui_snd_string(gSavedSettings, "UISndTyping"); + LLUUID sound_id = LLUUID(ui_snd_string); gAudiop->triggerSound(sound_id, getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_SFX, char_pos_global); } } @@ -6750,7 +6735,7 @@ void LLVOAvatar::resetAnimations() // animations. LLUUID LLVOAvatar::remapMotionID(const LLUUID& id) { - static LLCachedControl use_new_walk_run(gSavedSettings, "UseNewWalkRun"); + static LLCachedControl use_new_walk_run(gSavedSettings, "UseNewWalkRun"); LLUUID result = id; // start special case female walk for female avatars @@ -9225,11 +9210,8 @@ void LLVOAvatar::updateTooSlow() bool LLVOAvatar::isTooComplex() const { bool too_complex; - // Performance improvement - //bool render_friend = (LLAvatarTracker::instance().isBuddy(getID()) && gSavedSettings.getBOOL("AlwaysRenderFriends")); - static LLCachedControl alwaysRenderFriends(gSavedSettings, "AlwaysRenderFriends"); - bool render_friend = ( alwaysRenderFriends && LLAvatarTracker::instance().isBuddy( getID() ) ); // Beq note: isBuddy can be slow only check if we have to - // + static LLCachedControl always_render_friends(gSavedSettings, "AlwaysRenderFriends"); + bool render_friend = (LLAvatarTracker::instance().isBuddy(getID()) && always_render_friends); if (isSelf() || render_friend || mVisuallyMuteSetting == AV_ALWAYS_RENDER) { @@ -10114,7 +10096,8 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe // Parse visual params, if any. S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam); - bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing + static LLCachedControl block_some_avatars(gSavedSettings, "BlockSomeAvatarAppearanceVisualParams"); + bool drop_visual_params_debug = block_some_avatars && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing if( num_blocks > 1 && !drop_visual_params_debug) { //LL_DEBUGS("Avatar") << avString() << " handle visual params, num_blocks " << num_blocks << LL_ENDL; @@ -10232,11 +10215,11 @@ bool resolve_appearance_version(const LLAppearanceMessageContents& contents, S32 //----------------------------------------------------------------------------- void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) { - // Use LLCachedControl - //bool enable_verbose_dumps = gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"); - static LLCachedControl enable_verbose_dumps(gSavedSettings, "DebugAvatarAppearanceMessage"); - // - if (gSavedSettings.getBOOL("BlockAvatarAppearanceMessages")) + static LLCachedControl enable_verbose_dumps(gSavedSettings, "DebugAvatarAppearanceMessage"); + static LLCachedControl block_avatar_appearance_messages(gSavedSettings, "BlockAvatarAppearanceMessages"); + + std::string dump_prefix = getFullname() + "_" + (isSelf()?"s":"o") + "_"; + if (block_avatar_appearance_messages) { LL_WARNS() << "Blocking AvatarAppearance message" << LL_ENDL; return; @@ -10286,7 +10269,10 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) } // [Legacy Bake] - if (mLastUpdateReceivedCOFVersion >= thisAppearanceVersion) +// appearance fail fix from Rye + // if (mLastUpdateReceivedCOFVersion >= thisAppearanceVersion) + if (appearance_version > 0 && mLastUpdateReceivedCOFVersion >= thisAppearanceVersion) +// { LL_WARNS("Avatar") << "Stale appearance received #" << thisAppearanceVersion << " attempt to roll back from #" << mLastUpdateReceivedCOFVersion << diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index ccbd1eb7c6..0488b861a8 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -289,9 +289,9 @@ public: void idleUpdateLoadingEffect(); void idleUpdateWindEffect(); void idleUpdateNameTag(const LLVector3& root_pos_last); - void idleUpdateNameTagText(BOOL new_name); + void idleUpdateNameTagText(bool new_name); void idleUpdateNameTagPosition(const LLVector3& root_pos_last); - void idleUpdateNameTagAlpha(BOOL new_name, F32 alpha); + void idleUpdateNameTagAlpha(bool new_name, F32 alpha); // Colorize tags //LLColor4 getNameTagColor(bool is_friend); LLColor4 getNameTagColor(); @@ -980,8 +980,8 @@ public: // Get typing status bool isTyping() const { return mTyping; } private: - BOOL mVisibleChat; - BOOL mVisibleTyping; + bool mVisibleChat; + bool mVisibleTyping; //-------------------------------------------------------------------- // Lip synch morphs diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 2035f8b46b..208d1cb041 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -1274,8 +1274,9 @@ void LLVOAvatarSelf::checkBOMRebakeRequired() { if(getRegion()) { - auto newBOMStatus = getRegion()->bakesOnMeshEnabled(); - if(!gSavedSettings.getBOOL("CurrentlyUsingBakesOnMesh") != newBOMStatus) + auto bom_can_be_used_here = getRegion()->bakesOnMeshEnabled(); + static const LLCachedControl using_bom(gSavedSettings, "CurrentlyUsingBakesOnMesh", true); + if( using_bom != bom_can_be_used_here) { // force a rebake when the last grid we were on (including previous login) had different BOM support // This replicates forceAppearanceUpdate rather than pulling in the whole of llavatarself. @@ -1284,7 +1285,7 @@ void LLVOAvatarSelf::checkBOMRebakeRequired() doAfterInterval(boost::bind(&LLVOAvatarSelf::forceBakeAllTextures, gAgentAvatarp.get(), true), 5.0); } // update the setting even if we are in SL so that switch SL to OS and back - gSavedSettings.setBOOL("CurrentlyUsingBakesOnMesh", newBOMStatus); + gSavedSettings.setBOOL("CurrentlyUsingBakesOnMesh", bom_can_be_used_here); } } } diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 4b0a3c8259..e2d548cf74 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -2126,7 +2126,7 @@ bool LLVivoxVoiceClient::waitForChannel() { LL_INFOS("Voice") << "Session requesting reprovision and login." << LL_ENDL; requestRelog(); - break; + // break;// Fix broken state model } else if (mNextAudioSession) { @@ -2135,7 +2135,7 @@ bool LLVivoxVoiceClient::waitForChannel() if (!runSession(joinSession)) //suspends { LL_DEBUGS("Voice") << "runSession returned false; leaving inner loop" << LL_ENDL; - break; + // break; Fix broken state model } else { diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 6785e5e8a7..99aa73f691 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -683,7 +683,9 @@ void LLVOSky::idleUpdate(LLAgent &agent, const F64 &time) void LLVOSky::forceSkyUpdate() { mForceUpdate = TRUE; + m_lastAtmosphericsVars = {}; + mCubeMapUpdateStage = -1; } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index a9bad65b56..8bfcd51a3d 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -71,6 +71,8 @@ #include "llmediaentry.h" #include "llmediadataclient.h" #include "llmeshrepository.h" +#include "llnotifications.h" +#include "llnotificationsutil.h" #include "llagent.h" #include "llviewermediafocus.h" #include "lldatapacker.h" @@ -3152,6 +3154,17 @@ void LLVOVolume::mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, } } break; + + case LLViewerMediaObserver::MEDIA_EVENT_FILE_DOWNLOAD: + { + // Media might be blocked, waiting for a file, + // send an empty response to unblock it + const std::vector empty_response; + plugin->sendPickFileResponse(empty_response); + + LLNotificationsUtil::add("MediaFileDownloadUnsupported"); + } + break; default: break; @@ -7073,7 +7086,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace // can we safely treat this as an alpha mask? // Nothing actually sets facecolor use the TE alpha instead. // if (facep->getFaceColor().mV[3] <= 0.f) - if (te->getAlpha() <=0.f || facep->getFaceColor().mV[3] <= 0.f) + if ((te->getAlpha() <=0.f || facep->getFaceColor().mV[3] <= 0.f) && te->getGlow() == 0.0 ) // { //100% transparent, don't render unless we're highlighting transparent FSZoneN("facep->alpha -> invisible"); diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp index 601c4ebe84..de2527e497 100644 --- a/indra/newview/llweb.cpp +++ b/indra/newview/llweb.cpp @@ -203,19 +203,16 @@ std::string LLWeb::expandURLSubstitutions(const std::string &url, // find the grid std::string current_grid = LLGridManager::getInstance()->getGridId(); std::transform(current_grid.begin(), current_grid.end(), current_grid.begin(), ::tolower); - if (current_grid == "agni") + if (current_grid == "damballah") { - substitution["GRID"] = "secondlife.com"; - } - else if (current_grid == "damballah") - { - // Staging grid has its own naming scheme. - substitution["GRID"] = "secondlife-staging.com"; - } - else - { - substitution["GRID"] = llformat("%s.lindenlab.com", current_grid.c_str()); - } + // Staging grid has its own naming scheme. + substitution["GRID"] = "secondlife-staging.com"; + } + else + { + substitution["GRID"] = "secondlife.com"; + } + // expand all of the substitution strings and escape the url std::string expanded_url = url; LLStringUtil::format(expanded_url, substitution); diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 3c2fc1d29e..43947e9b95 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -1688,6 +1688,16 @@ public: virtual void post(ResponsePtr response, const LLSD& context, const LLSD& input) const { if (LLApp::isExiting()) + { + return; + } + + if (gDisconnected) + { + return; + } + + if (!LLWorld::instanceExists()) { return; } @@ -1700,8 +1710,13 @@ public: return; } - LLHost sim(input["body"]["sim-ip-and-port"].asString()); - + LLHost sim(input["body"]["sim-ip-and-port"].asString()); + if (sim.isInvalid()) + { + LL_WARNS() << "Got EstablishAgentCommunication with invalid host" << LL_ENDL; + return; + } + LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(sim); if (!regionp) { @@ -1710,7 +1725,7 @@ public: return; } LL_DEBUGS("CrossingCaps") << "Calling setSeedCapability from LLEstablishAgentCommunication::post. Seed cap == " - << input["body"]["seed-capability"] << LL_ENDL; + << input["body"]["seed-capability"] << " for region " << regionp->getRegionID() << LL_ENDL; regionp->setSeedCapability(input["body"]["seed-capability"]); } }; diff --git a/indra/newview/skins/default/xui/da/notifications.xml b/indra/newview/skins/default/xui/da/notifications.xml index 36968b04fc..704d7b79d2 100644 --- a/indra/newview/skins/default/xui/da/notifications.xml +++ b/indra/newview/skins/default/xui/da/notifications.xml @@ -72,7 +72,7 @@ Fejl detaljer: Beskeden kaldet '[_NAME]' blev ikke fundet i notificati - Kunne ikke tilslutte til [SECOND_LIFE_GRID]. + Kunne ikke tilslutte til [CURRENT_GRID]. '[DIAGNOSTIC]' Check at Internet forbindelsen fungerer korrekt. @@ -477,7 +477,7 @@ Du kan bruge [CURRENT_GRID] normalt og andre personer vil se dig korrekt. Hvis det er første gang du bruger [CURRENT_GRID], skal du først oprette en konto for at logge på. - Der er problemer med at koble på. Der kan være et problem med din Internet forbindelse eller [SECOND_LIFE_GRID]. + Der er problemer med at koble på. Der kan være et problem med din Internet forbindelse eller [CURRENT_GRID]. Du kan enten checke din Internet forbindelse og prøve igen om lidt, klikke på Hjælp for at se [SUPPORT_SITE] siden, eller klikke på Teleport for at forsøge at teleportere hjem. diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml index d128ca3806..3b44691fe4 100644 --- a/indra/newview/skins/default/xui/da/strings.xml +++ b/indra/newview/skins/default/xui/da/strings.xml @@ -2198,7 +2198,7 @@ Hvis du bliver ved med at modtage denne besked, kontakt [SUPPORT_SITE]. Hvis du bliver ved med at modtage denne besked, kontakt venligst [SUPPORT_SITE]. - + Skægstubbe diff --git a/indra/newview/skins/default/xui/de/control_table_contents_media.xml b/indra/newview/skins/default/xui/de/control_table_contents_media.xml index c594aea187..aafb5cbee7 100644 --- a/indra/newview/skins/default/xui/de/control_table_contents_media.xml +++ b/indra/newview/skins/default/xui/de/control_table_contents_media.xml @@ -21,4 +21,7 @@ + + + \ No newline at end of file diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml index a4ea3de8e6..61ee70cb6e 100644 --- a/indra/newview/skins/default/xui/de/notifications.xml +++ b/indra/newview/skins/default/xui/de/notifications.xml @@ -86,7 +86,7 @@ Fehlerdetails: The notification called '[_NAME]' was not found in noti - Verbindung nicht möglich zum [SECOND_LIFE_GRID]. + Verbindung nicht möglich zum [CURRENT_GRID]. '[DIAGNOSTIC]' Stellen Sie sicher, dass Ihre Internetverbindung funktioniert. @@ -710,7 +710,7 @@ Das Objekt ist möglicherweise außer Reichweite oder wurde gelöscht. Dateidownload nicht möglich - Sie haben einen Datei-Download angefordert, der in [SECOND_LIFE] nicht unterstützt wird. + Sie haben einen Datei-Download angefordert, der in [APP_NAME] nicht unterstützt wird. @@ -1513,11 +1513,11 @@ Falls Sie [CURRENT_GRID] zum ersten Mal verwenden, müssen Sie zuerst ein Konto - Es gibt Probleme mit der Verbindung. Möglicherweise besteht ein Problem mit Ihrer Internetverbindung oder dem [SECOND_LIFE_GRID]. + Es gibt Probleme mit der Verbindung. Möglicherweise besteht ein Problem mit Ihrer Internetverbindung oder dem [CURRENT_GRID]. Überprüfen Sie Ihre Internetverbindung und versuchen Sie es dann erneut, oder klicken Sie auf Hilfe, um zu [SUPPORT_SITE] zu gelangen, oder klicken Sie auf Teleportieren, um nach Hause zu teleportieren. - http://de.secondlife.com/support/ + https://www.firestormviewer.org/support/