diff --git a/.gitignore b/.gitignore index f30ca2cc4..4f9405a16 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,5 @@ /edited-files.txt qtcreator-build/ /.pc +/build-* +/viewer-* diff --git a/indra/aistatemachine/aistatemachine.cpp b/indra/aistatemachine/aistatemachine.cpp index 46bda0ad3..4b7470e26 100644 --- a/indra/aistatemachine/aistatemachine.cpp +++ b/indra/aistatemachine/aistatemachine.cpp @@ -614,6 +614,8 @@ void AIStateMachine::multiplex(event_type event) // Continue in bs_multiplex. // If the state is bs_multiplex we only need to run again when need_run was set again in the meantime or when this state machine isn't idle. need_new_run = sub_state_r->need_run || !sub_state_r->idle; + // If this fails then the run state didn't change and neither idle() nor yield() was called. + llassert_always(!(need_new_run && !mYieldEngine && sub_state_r->run_state == run_state)); } break; case bs_abort: @@ -786,10 +788,10 @@ AIStateMachine::state_type AIStateMachine::begin_loop(base_state_type base_state return sub_state_w->run_state; } -void AIStateMachine::run(LLPointer parent, state_type new_parent_state, bool abort_parent, bool on_abort_signal_parent, AIEngine* default_engine) +void AIStateMachine::run(AIStateMachine* parent, state_type new_parent_state, bool abort_parent, bool on_abort_signal_parent, AIEngine* default_engine) { DoutEntering(dc::statemachine, "AIStateMachine::run(" << - (void*)parent.get() << ", " << + (void*)parent << ", " << (parent ? parent->state_str_impl(new_parent_state) : "NA") << ", abort_parent = " << (abort_parent ? "true" : "false") << ", on_abort_signal_parent = " << (on_abort_signal_parent ? "true" : "false") << @@ -1007,6 +1009,15 @@ void AIStateMachine::advance_state(state_type new_state) Dout(dc::statemachine, "Ignored, because " << state_str_impl(sub_state_w->advance_state) << " >= " << state_str_impl(new_state) << "."); return; } + // Ignore call to advance_state when the current state is greater than the requested state: the new state would be + // ignored in begin_loop(), as is already remarked there: an advanced state that is not honored is not a reason to run. + // This call might as well not have happened. Not returning here is a bug because that is effectively a cont(), while + // the state change is and should be being ignored: the statemachine would start running it's current state (again). + if (sub_state_w->run_state > new_state) + { + Dout(dc::statemachine, "Ignored, because " << state_str_impl(sub_state_w->run_state) << " > " << state_str_impl(new_state) << " (current state)."); + return; + } // Increment state. sub_state_w->advance_state = new_state; // Void last call to idle(), if any. @@ -1018,6 +1029,16 @@ void AIStateMachine::advance_state(state_type new_state) #ifdef SHOW_ASSERT // From this moment on. mDebugAdvanceStatePending = true; + // If the new state is equal to the current state, then this should be considered to be a cont() + // because also equal states are ignored in begin_loop(). However, unlike a cont() we ignore a call + // to idle() when the statemachine is already running in this state (because that is a race condition + // and ignoring the idle() is the most logical thing to do then). Hence we treated this as a full + // fletched advance_state but need to tell the debug code that it's really also a cont(). + if (sub_state_w->run_state == new_state) + { + // From this moment. + mDebugContPending = true; + } #endif } if (!mMultiplexMutex.isSelfLocked()) diff --git a/indra/aistatemachine/aistatemachine.h b/indra/aistatemachine/aistatemachine.h index 9b5b0aab6..2b019c91f 100644 --- a/indra/aistatemachine/aistatemachine.h +++ b/indra/aistatemachine/aistatemachine.h @@ -212,7 +212,7 @@ class AIStateMachine : public LLThreadSafeRefCount public: // These functions may be called directly after creation, or from within finish_impl(), or from the call back function. - void run(LLPointer parent, state_type new_parent_state, bool abort_parent = true, bool on_abort_signal_parent = true, AIEngine* default_engine = &gMainThreadEngine); + void run(AIStateMachine* parent, state_type new_parent_state, bool abort_parent = true, bool on_abort_signal_parent = true, AIEngine* default_engine = &gMainThreadEngine); void run(callback_type::signal_type::slot_type const& slot, AIEngine* default_engine = &gMainThreadEngine); void run(void) { run(NULL, 0, false, true, mDefaultEngine); } diff --git a/indra/aistatemachine/aistatemachinethread.cpp b/indra/aistatemachine/aistatemachinethread.cpp index f45d1e845..caeddea5c 100644 --- a/indra/aistatemachine/aistatemachinethread.cpp +++ b/indra/aistatemachine/aistatemachinethread.cpp @@ -101,7 +101,10 @@ void AIStateMachineThreadBase::multiplex_impl(state_type run_state) break; case wait_stopped: if (!mThread->isStopped()) + { + yield(); break; + } // We're done! // // We can only get here when AIThreadImpl::done called cont(), (very diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 449186a08..e8ce73f7d 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -103,12 +103,14 @@ if (LINUX) -pthread ) - # Don't catch SIGCHLD in our base application class for the viewer - # some of our 3rd party libs may need their *own* SIGCHLD handler to work. Sigh! - # The viewer doesn't need to catch SIGCHLD anyway. - add_definitions(-DLL_IGNORE_SIGCHLD) + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -D_FORTIFY_SOURCE=2 ") - if(${CMAKE_C_COMPILER} MATCHES "gcc*") + # Don't catch SIGCHLD in our base application class for the viewer + # some of our 3rd party libs may need their *own* SIGCHLD handler to work. Sigh! + # The viewer doesn't need to catch SIGCHLD anyway. + add_definitions(-DLL_IGNORE_SIGCHLD) + + if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") find_program(GXX g++) mark_as_advanced(GXX) @@ -136,16 +138,6 @@ if (LINUX) OUTPUT_VARIABLE CXX_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) - # Here's a giant hack for Fedora 8, where we can't use - # _FORTIFY_SOURCE if we're using a compiler older than gcc 4.1. - if (${GXX_VERSION} STREQUAL ${CXX_VERSION}) - add_definitions(-D_FORTIFY_SOURCE=2) - else (${GXX_VERSION} STREQUAL ${CXX_VERSION}) - if (NOT ${GXX_VERSION} MATCHES " 4.1.*Red Hat") - add_definitions(-D_FORTIFY_SOURCE=2) - endif (NOT ${GXX_VERSION} MATCHES " 4.1.*Red Hat") - endif (${GXX_VERSION} STREQUAL ${CXX_VERSION}) - #Lets actually get a numerical version of gxx's version STRING(REGEX REPLACE ".* ([0-9])\\.([0-9])\\.([0-9]).*" "\\1\\2\\3" CXX_VERSION ${CXX_VERSION}) @@ -159,6 +151,11 @@ if (LINUX) add_definitions(-Wno-unused-but-set-variable) endif (NOT ${CXX_VERSION} LESS 460) + #gcc 4.8 boost spam wall + if(NOT ${CXX_VERSION} LESS 480) + add_definitions(-Wno-unused-local-typedefs) + endif (NOT ${CXX_VERSION} LESS 480) + # End of hacks. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") @@ -184,39 +181,19 @@ if (LINUX) set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}${MARCH_FLAG} -mfpmath=sse,387 -msse2 ${GCC_EXTRA_OPTIMIZATIONS}") set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}${MARCH_FLAG} -mfpmath=sse,387 -msse2 ${GCC_EXTRA_OPTIMIZATIONS}") endif (${ARCH} STREQUAL "x86_64") - elseif(${CMAKE_C_COMPILER} MATCHES "clang*") - find_program(CLANG clang) - mark_as_advanced(CLANG) - - find_program(CLANGXX clang++) - mark_as_advanced(CLANGXX) - - add_definitions( - -D_FORTIFY_SOURCE=2 - ) - + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") if (NOT STANDALONE) # this stops us requiring a really recent glibc at runtime add_definitions(-fno-stack-protector) endif (NOT STANDALONE) - if (NOT STANDALONE) - set(MARCH_FLAG " -march=pentium4") - endif (NOT STANDALONE) - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}${MARCH_FLAG} -fno-inline -msse2") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}${MARCH_FLAG} -fno-inline -msse2") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}${MARCH_FLAG} -msse2") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}${MARCH_FLAG} -msse2") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}${MARCH_FLAG} -msse2") set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}${MARCH_FLAG} -msse2") - elseif(${CMAKE_C_COMPILER} MATCHES "icc*" AND ${CMAKE_CXX_COMPILER} MATCHES "icpc*") - find_program(ICC icc) - mark_as_advanced(ICC) - - add_definitions( - -D_FORTIFY_SOURCE=2 - ) + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") if (NOT STANDALONE) # this stops us requiring a really recent glibc at runtime @@ -248,7 +225,8 @@ if (DARWIN) add_definitions(-DLL_DARWIN=1 -D_XOPEN_SOURCE) set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS}") - if(${CMAKE_C_COMPILER} MATCHES "gcc*") + + if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mlong-branch") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mlong-branch") # NOTE: it's critical that the optimization flag is put in front. @@ -257,7 +235,7 @@ if (DARWIN) set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}") set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}") - elseif(${CMAKE_C_COMPILER} MATCHES "clang*") + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") # NOTE: it's critical that the optimization flag is put in front. # NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered. set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -msse3") @@ -269,20 +247,21 @@ endif (DARWIN) if (LINUX OR DARWIN) - if(${CMAKE_C_COMPILER} MATCHES "gcc*") - set(UNIX_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs") + if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + add_definitions(-DLL_GNUC=1) + set(UNIX_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs") set(UNIX_CXX_WARNINGS "${UNIX_WARNINGS} -Wno-reorder -Wno-non-virtual-dtor -Woverloaded-virtual") - elseif(${CMAKE_C_COMPILER} MATCHES "clang*") - set(UNIX_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs -Wno-tautological-compare -Wno-char-subscripts -Wno-gnu -Wno-logical-op-parentheses -Wno-non-virtual-dtor") + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + add_definitions(-DLL_CLANG=1) + set(UNIX_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs -Wno-tautological-compare -Wno-char-subscripts -Wno-gnu -Wno-logical-op-parentheses -Wno-non-virtual-dtor") set(UNIX_WARNINGS "${UNIX_WARNINGS} -Woverloaded-virtual -Wno-parentheses-equality -Wno-reorder -Wno-unused-function -Wno-unused-value -Wno-unused-variable") set(UNIX_CXX_WARNINGS "${UNIX_WARNINGS}") - elseif(${CMAKE_C_COMPILER} MATCHES "icc") + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") + add_definitions(-DLL_ICC=1) set(UNIX_WARNINGS "-wd327 -wd597 -wd858") set(UNIX_CXX_WARNINGS "${UNIX_WARNINGS}") - endif() + endif () - # Use -DDISABLE_FATAL_WARNINGS:BOOL=FALSE during configuration to enable fatal warnings. - set(DISABLE_FATAL_WARNINGS TRUE CACHE BOOL "Set this to FALSE to enable fatal warnings.") if (NOT DISABLE_FATAL_WARNINGS) set(UNIX_WARNINGS "${UNIX_WARNINGS} -Werror") set(UNIX_CXX_WARNINGS "${UNIX_CXX_WARNINGS} -Werror") diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index 5bc3e2156..10dd25ac2 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -30,6 +30,7 @@ set(SCRIPTS_DIR ${CMAKE_SOURCE_DIR}/${SCRIPTS_PREFIX}) set(VIEWER_DIR ${CMAKE_SOURCE_DIR}/${VIEWER_PREFIX}) set(DISABLE_TCMALLOC OFF CACHE BOOL "Disable linkage of TCMalloc. (64bit builds automatically disable TCMalloc)") set(LL_TESTS OFF CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation)") +set(DISABLE_FATAL_WARNINGS TRUE CACHE BOOL "Set this to FALSE to enable fatal warnings.") set(LIBS_PREBUILT_DIR ${CMAKE_SOURCE_DIR}/../libraries CACHE PATH "Location of prebuilt libraries.") diff --git a/indra/develop.py b/indra/develop.py index a2215b3b0..853c37e14 100755 --- a/indra/develop.py +++ b/indra/develop.py @@ -45,7 +45,6 @@ import commands class CommandError(Exception): pass - def mkdir(path): try: os.mkdir(path) @@ -54,15 +53,19 @@ def mkdir(path): if err.errno != errno.EEXIST or not os.path.isdir(path): raise -def getcwd(): - cwd = os.getcwd() - if 'a' <= cwd[0] <= 'z' and cwd[1] == ':': +def prettyprint_path_for_cmake(path): + if 'a' <= path[0] <= 'z' and path[1] == ':': # CMake wants DOS drive letters to be in uppercase. The above # condition never asserts on platforms whose full path names # always begin with a slash, so we don't need to test whether # we are running on Windows. - cwd = cwd[0].upper() + cwd[1:] - return cwd + path = path[0].upper() + path[1:] + return path + +def getcwd(): + return prettyprint_path_for_cmake(os.getcwd()) + +source_indra = prettyprint_path_for_cmake(os.path.dirname(os.path.realpath(__file__))) def quote(opts): return '"' + '" "'.join([ opt.replace('"', '') for opt in opts ]) + '"' @@ -150,7 +153,7 @@ class PlatformSetup(object): simple = False try: os.chdir(d) - cmd = self.cmake_commandline(cwd, d, args, simple) + cmd = self.cmake_commandline(source_indra, d, args, simple) print 'Running %r in %r' % (cmd, d) self.run(cmd, 'cmake') finally: @@ -270,18 +273,9 @@ class LinuxSetup(UnixSetup): return 'linux' def build_dirs(self): - # Only build the server code if we have it. platform_build = '%s-%s' % (self.platform(), self.build_type.lower()) - if self.arch() == 'i686' and self.is_internal_tree(): - return ['viewer-' + platform_build, 'server-' + platform_build] - elif self.arch() == 'x86_64' and self.is_internal_tree(): - # the viewer does not build in 64bit -- kdu5 issues - # we can either use openjpeg, or overhaul our viewer to handle kdu5 or higher - # doug knows about kdu issues - return ['server-' + platform_build] - else: - return ['viewer-' + platform_build] + return ['viewer-' + platform_build] def cmake_commandline(self, src_dir, build_dir, opts, simple): args = dict( @@ -293,31 +287,11 @@ class LinuxSetup(UnixSetup): type=self.build_type.upper(), project_name=self.project_name, word_size=self.word_size, + cxx="g++" ) - if not self.is_internal_tree(): - args.update({'cxx':'g++', 'server':'OFF', 'viewer':'ON'}) - else: - if self.distcc: - distcc = self.find_in_path('distcc') - baseonly = True - else: - distcc = [] - baseonly = False - if 'server' in build_dir: - gcc = distcc + self.find_in_path( - self.debian_sarge and 'g++-3.3' or 'g++-4.1', - 'g++', baseonly) - args.update({'cxx': ' '.join(gcc), 'server': 'ON', - 'viewer': 'OFF'}) - else: - gcc41 = distcc + self.find_in_path('g++-4.1', 'g++', baseonly) - args.update({'cxx': ' '.join(gcc41), - 'server': 'OFF', - 'viewer': 'ON'}) + cmd = (('cmake -DCMAKE_BUILD_TYPE:STRING=%(type)s ' - '-G %(generator)r -DSERVER:BOOL=%(server)s ' - '-DVIEWER:BOOL=%(viewer)s -DSTANDALONE:BOOL=%(standalone)s ' - '-DUNATTENDED:BOOL=%(unattended)s ' + '-G %(generator)r -DSTANDALONE:BOOL=%(standalone)s ' '-DWORD_SIZE:STRING=%(word_size)s ' '-DROOT_PROJECT_NAME:STRING=%(project_name)s ' '%(opts)s %(dir)r') diff --git a/indra/libhacd/CMakeLists.txt b/indra/libhacd/CMakeLists.txt index e346bc9b8..59aad8a23 100644 --- a/indra/libhacd/CMakeLists.txt +++ b/indra/libhacd/CMakeLists.txt @@ -1,13 +1,39 @@ -cmake_minimum_required(VERSION 2.6.4) +# -*- cmake -*- -project(libhacd CXX C) +project(libhacd) include(00-Common) -file (GLOB SOURCE_FILES *.cpp ) -file (GLOB INCLUDE_FILES *.h ) +set(libhacd_SOURCE_FILES + hacdGraph.cpp + hacdHACD.cpp + hacdICHull.cpp + hacdManifoldMesh.cpp + hacdMeshDecimator.cpp + hacdMicroAllocator.cpp + hacdRaycastMesh.cpp +) + +set(libhacd_HEADER_FILES + hacdCircularList.h + hacdCircularList.inl + hacdGraph.h + hacdHACD.h + hacdICHull.h + hacdManifoldMesh.h + hacdMeshDecimator.h + hacdMicroAllocator.h + hacdRaycastMesh.h + hacdSArray.h + hacdVector.h + hacdVector.inl + hacdVersion.h +) + +set_source_files_properties(${libhacd_HEADER_FILES} + PROPERTIES HEADER_FILE_ONLY TRUE) IF(WINDOWS) add_definitions(-D_CRT_SECURE_NO_WARNINGS) ENDIF(WINDOWS) -add_library(hacd ${SOURCE_FILES} ${INCLUDE_FILES}) +add_library(hacd ${libhacd_SOURCE_FILES} ${libhacd_INCLUDE_FILES}) diff --git a/indra/libhacd/hacdHACD.h b/indra/libhacd/hacdHACD.h index bdbbc472b..0c9f11653 100644 --- a/indra/libhacd/hacdHACD.h +++ b/indra/libhacd/hacdHACD.h @@ -76,6 +76,7 @@ namespace HACD { public: virtual void operator()( char const *aMsg, double aProgress, double aConcavity, size_t aVertices) = 0; + virtual ~ICallback() {} }; typedef ICallback* CallBackFunction; diff --git a/indra/libndhacd/CMakeLists.txt b/indra/libndhacd/CMakeLists.txt index 93cf90a13..bcc1973c0 100644 --- a/indra/libndhacd/CMakeLists.txt +++ b/indra/libndhacd/CMakeLists.txt @@ -1,9 +1,35 @@ +# -*- cmake -*- + project(libndhacd) +include(00-Common) + include_directories(${LIBS_OPEN_DIR}/libhacd) -set (SOURCE_FILES LLConvexDecomposition.cpp nd_hacdConvexDecomposition.cpp nd_hacdStructs.cpp nd_hacdUtils.cpp nd_EnterExitTracer.cpp nd_StructTracer.cpp ) -file(GLOB HEADER_FILES *.h) +set (libndhacd_SOURCE_FILES + LLConvexDecomposition.cpp + nd_hacdConvexDecomposition.cpp + nd_hacdStructs.cpp + nd_hacdUtils.cpp + nd_EnterExitTracer.cpp + nd_StructTracer.cpp +) -add_library( nd_hacdConvexDecomposition STATIC ${SOURCE_FILES} ${HEADER_FILES}) +set (libndhacd_HEADER_FILES + LLConvexDecomposition.h + ndConvexDecomposition.h + nd_hacdConvexDecomposition.h + nd_hacdStructs.h + nd_StructTracer.h + LLConvexDecompositionStubImpl.h + nd_EnterExitTracer.h + nd_hacdDefines.h + nd_hacdUtils.h + windowsincludes.h +) + +set_source_files_properties(${libndhacd_HEADER_FILES} + PROPERTIES HEADER_FILE_ONLY TRUE) + +add_library( nd_hacdConvexDecomposition STATIC ${libndhacd_SOURCE_FILES} ${libndhacd_HEADER_FILES}) diff --git a/indra/libpathing/CMakeLists.txt b/indra/libpathing/CMakeLists.txt index 087faec05..35086c716 100644 --- a/indra/libpathing/CMakeLists.txt +++ b/indra/libpathing/CMakeLists.txt @@ -1,13 +1,34 @@ -cmake_minimum_required(VERSION 2.6.4) +# -*- cmake -*- + +project(libpathing) + +include(00-Common) +include(LLCommon) +include(LLMath) + +include_directories( + ${LLCOMMON_INCLUDE_DIRS} + ${LLMATH_INCLUDE_DIRS} +) -project(ndPathingLib CXX C) if( MSVC ) add_definitions(-D_SECURE_SCL=0 -D_CRT_SECURE_NO_WARNINGS=1) endif( MSVC ) -file (GLOB SOURCE_FILES *.cpp ) -file (GLOB INCLUDE_FILES *.h ) +set(libpathing_SOURCE_FILES + llpathinglib.cpp + llphysicsextensions.cpp +) -add_library(nd_Pathing STATIC ${SOURCE_FILES} ${INCLUDE_FILES} ) +set(libpathing_HEADER_FILES + llpathinglib.h + llphysicsextensions.h +) + +set_source_files_properties(${libpathing_HEADER_FILES} + PROPERTIES HEADER_FILE_ONLY TRUE) + +add_library(nd_Pathing STATIC ${libpathing_SOURCE_FILES} ${libpathing_HEADER_FILES} ) +add_dependencies(nd_Pathing prepare) diff --git a/indra/libpathing/llpathinglib.cpp b/indra/libpathing/llpathinglib.cpp index 041311de9..19c0bff0f 100644 --- a/indra/libpathing/llpathinglib.cpp +++ b/indra/libpathing/llpathinglib.cpp @@ -1,3 +1,4 @@ +#include "sys.h" #include "llpathinglib.h" void LLPathingLib::initSystem() diff --git a/indra/libpathing/llpathinglib.h b/indra/libpathing/llpathinglib.h index 70fd1d767..30dd0110a 100644 --- a/indra/libpathing/llpathinglib.h +++ b/indra/libpathing/llpathinglib.h @@ -3,37 +3,10 @@ #include -#ifndef LL_V3MATH_H -class LLVector3 -{ -public: - float mV[3]; -}; -#endif - -#ifndef LL_V4COLORU_H -class LLColor4U -{ -public: - unsigned char mV[4]; -}; -#endif - -#ifndef LL_LLUUID_H -class LLUUID -{ -public: - unsigned char mData[16]; -}; -#endif - -#ifndef LLQUATERNION_H -class LLQuaternion -{ -public: - double mQ[4]; -}; -#endif +#include "v3math.h" +#include "v4coloru.h" +#include "llquaternion.h" +#include "lluuid.h" class LLRender; @@ -43,7 +16,7 @@ public: enum LLPLResult { LLPL_NO_PATH, - LLPL_PATH_GENERATED_OK, + LLPL_PATH_GENERATED_OK }; enum LLPLCharacterType @@ -52,7 +25,7 @@ public: LLPL_CHARACTER_TYPE_A, LLPL_CHARACTER_TYPE_B, LLPL_CHARACTER_TYPE_C, - LLPL_CHARACTER_TYPE_D, + LLPL_CHARACTER_TYPE_D }; enum LLShapeType @@ -60,13 +33,13 @@ public: LLST_WalkableObjects = 1, LLST_ObstacleObjects = 2, LLST_MaterialPhantoms = 3, - LLST_ExclusionPhantoms = 4, + LLST_ExclusionPhantoms = 4 }; enum LLPLRenderType { LLPL_START, - LLPL_END, + LLPL_END }; struct Vector @@ -87,9 +60,9 @@ public: operator LLVector3() const { LLVector3 ret; - ret.mV[0] = mX; - ret.mV[1] = mY; - ret.mV[2] = mZ; + ret.mV[0] = (F32) mX; + ret.mV[1] = (F32) mY; + ret.mV[2] = (F32) mZ; return ret; } }; diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index 3c23f5f29..c57bedd8f 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -473,6 +473,8 @@ const std::string LLTexLayerSet::getBodyRegionName() const // virtual void LLTexLayerSet::asLLSD(LLSD& sd) const { + llassert_always(false); // broken function +#if 0 sd["visible"] = LLSD::Boolean(isVisible()); LLSD layer_list_sd; layer_list_t::const_iterator layer_iter = mLayerList.begin(); @@ -492,6 +494,7 @@ void LLTexLayerSet::asLLSD(LLSD& sd) const sd["layers"] = layer_list_sd; sd["masks"] = mask_list_sd; sd["info"] = info_sd; +#endif } diff --git a/indra/llcharacter/llmotioncontroller.h b/indra/llcharacter/llmotioncontroller.h index a0a940a9e..2de13aa36 100644 --- a/indra/llcharacter/llmotioncontroller.h +++ b/indra/llcharacter/llmotioncontroller.h @@ -40,7 +40,6 @@ #include #include -#include "lluuidhashmap.h" #include "llmotion.h" #include "llpose.h" #include "llframetimer.h" diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index a6da6f0c3..ac958ef0e 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -234,7 +234,7 @@ set(llcommon_HEADER_FILES lltypeinfolookup.h lluri.h lluuid.h - lluuidhashmap.h + sguuidhash.h llversionviewer.h.in llworkerthread.h metaclass.h diff --git a/indra/llcommon/aiframetimer.h b/indra/llcommon/aiframetimer.h index cb50caec5..366581c49 100644 --- a/indra/llcommon/aiframetimer.h +++ b/indra/llcommon/aiframetimer.h @@ -67,7 +67,7 @@ class LL_COMMON_API AIFrameTimer mutable Signal* mCallback; // Pointer to callback struct, or NULL when the object wasn't added to sTimerList yet. public: - AIRunningFrameTimer(F64 expiration, AIFrameTimer* timer) : mExpire(LLFrameTimer::getElapsedSeconds() + expiration), mCallback(NULL), mTimer(timer) { } + AIRunningFrameTimer(F64 expiration, AIFrameTimer* timer) : mExpire(LLFrameTimer::getElapsedSeconds() + expiration), mTimer(timer), mCallback(NULL) { } ~AIRunningFrameTimer() { delete mCallback; } // This function is called after the final object was added to sTimerList (where it is initialized in-place). @@ -89,7 +89,7 @@ class LL_COMMON_API AIFrameTimer #if LL_DEBUG // May not copy this object after it was initialized. AIRunningFrameTimer(AIRunningFrameTimer const& running_frame_timer) : - mExpire(running_frame_timer.mExpire), mCallback(running_frame_timer.mCallback), mTimer(running_frame_timer.mTimer) + mExpire(running_frame_timer.mExpire), mTimer(running_frame_timer.mTimer), mCallback(running_frame_timer.mCallback) { llassert(!mCallback); } #endif }; diff --git a/indra/llcommon/llchat.h b/indra/llcommon/llchat.h index 13b99550b..cf3bf9e3e 100644 --- a/indra/llcommon/llchat.h +++ b/indra/llcommon/llchat.h @@ -61,6 +61,13 @@ typedef enum e_chat_audible_level CHAT_AUDIBLE_FULLY = 1 } EChatAudible; +typedef enum e_chat_style +{ + CHAT_STYLE_NORMAL, + CHAT_STYLE_IRC, + CHAT_STYLE_HISTORY +}EChatStyle; + // A piece of chat class LLChat { @@ -80,7 +87,8 @@ public: // [/RLVa:KB] mTime(0.0), mPosAgent(), - mURL() + mURL(), + mChatStyle(CHAT_STYLE_NORMAL) { } LLChat(const LLChat &chat) @@ -93,7 +101,8 @@ public: mMuted(chat.mMuted), mTime(chat.mTime), mPosAgent(chat.mPosAgent), - mURL(chat.mURL) + mURL(chat.mURL), + mChatStyle(chat.mChatStyle) { } std::string mText; // UTF-8 line of text @@ -110,6 +119,7 @@ public: F64 mTime; // viewer only, seconds from viewer start LLVector3 mPosAgent; std::string mURL; + EChatStyle mChatStyle; }; #endif diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h index e903cf607..a6f5f9fa9 100644 --- a/indra/llcommon/llpreprocessor.h +++ b/indra/llcommon/llpreprocessor.h @@ -72,14 +72,14 @@ // Figure out differences between compilers -#if defined(__clang__) && defined(__GNUC__) +#if defined(__clang__) #define CLANG_VERSION (__clang_major__ * 10000 \ + __clang_minor__ * 100 \ + __clang_patchlevel__) #ifndef LL_CLANG #define LL_CLANG 1 #endif -#elif defined (__ICC) && defined(__GNUC__) +#elif defined (__ICC) #ifndef LL_ICC #define LL_ICC 1 #endif diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h index 2e872751f..ec98bb911 100644 --- a/indra/llcommon/llstl.h +++ b/indra/llcommon/llstl.h @@ -178,7 +178,7 @@ struct CopyNewPointer // helper function which returns true if key is in inmap. template //Singu note: This has been generalized to support a broader range of map-esque containers -inline bool is_in_map(const T& inmap, typename const T::key_type& key) +inline bool is_in_map(const T& inmap, typename T::key_type const& key) { if(inmap.find(key) == inmap.end()) { @@ -197,7 +197,7 @@ inline bool is_in_map(const T& inmap, typename const T::key_type& key) // //Singu note: This has been generalized to support a broader range of map-esque containers. template -inline typename T::mapped_type get_if_there(const T& inmap, typename const T::key_type& key, typename T::mapped_type default_value) +inline typename T::mapped_type get_if_there(const T& inmap, typename T::key_type const& key, typename T::mapped_type default_value) { // Typedef here avoids warnings because of new c++ naming rules. typedef typename T::const_iterator map_iter; @@ -222,7 +222,7 @@ inline typename T::mapped_type get_if_there(const T& inmap, typename const T::ke // const char* baz = get_ptr_in_map(foo, 3); // baz == NULL //Singu note: This has been generalized to support a broader range of map-esque containers template -inline typename T::mapped_type get_ptr_in_map(const T& inmap, typename const T::key_type& key) +inline typename T::mapped_type get_ptr_in_map(const T& inmap, typename T::key_type const& key) { return get_if_there(inmap,key,NULL); }; @@ -265,7 +265,7 @@ inline typename T::iterator vector_replace_with_last(T& invec, typename T::itera // //Singu note: This has been generalized to support a broader range of sequence containers template -inline bool vector_replace_with_last(T& invec, typename const T::value_type& val) +inline bool vector_replace_with_last(T& invec, typename T::value_type const& val) { typename T::iterator iter = std::find(invec.begin(), invec.end(), val); if (iter != invec.end()) diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 8a2b6d0b5..1c3fec608 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ -#ifdef __GNUC__ +#if LL_GNUC // Generate code for inlines from llthread.h (needed for is_main_thread()). #pragma implementation "llthread.h" #endif @@ -403,8 +403,8 @@ void LLCondition::broadcast() //============================================================================ LLMutexBase::LLMutexBase() : - mLockingThread(AIThreadID::sNone), - mCount(0) + mCount(0), + mLockingThread(AIThreadID::sNone) { } diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 1f6765935..7d0cc593c 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -27,7 +27,7 @@ #ifndef LL_LLTHREAD_H #define LL_LLTHREAD_H -#ifdef __GNUC__ +#if LL_GNUC // Needed for is_main_thread() when compiling with optimization (relwithdebinfo). // It doesn't hurt to just always specify it though. #pragma interface diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index f6b9db6c1..0182a370d 100644 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -171,14 +171,6 @@ void LLUUID::toString(std::string& out) const (U8)(mData[15])); } -// *TODO: deprecate -void LLUUID::toString(char *out) const -{ - std::string buffer; - toString(buffer); - strcpy(out,buffer.c_str()); /* Flawfinder: ignore */ -} - void LLUUID::toCompressedString(std::string& out) const { char bytes[UUID_BYTES+1]; @@ -187,13 +179,6 @@ void LLUUID::toCompressedString(std::string& out) const out.assign(bytes, UUID_BYTES); } -// *TODO: deprecate -void LLUUID::toCompressedString(char *out) const -{ - memcpy(out, mData, UUID_BYTES); /* Flawfinder: ignore */ - out[UUID_BYTES] = '\0'; -} - std::string LLUUID::getString() const { return asString(); @@ -422,14 +407,9 @@ std::ostream& operator<<(std::ostream& s, const LLUUID &uuid) std::istream& operator>>(std::istream &s, LLUUID &uuid) { - U32 i; - char uuid_str[UUID_STR_LENGTH]; /* Flawfinder: ignore */ - for (i = 0; i < UUID_STR_LENGTH-1; i++) - { - s >> uuid_str[i]; - } - uuid_str[i] = '\0'; - uuid.set(std::string(uuid_str)); + std::string uuid_str; + s >> uuid_str; + uuid.set(uuid_str); return s; } diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h index 4e5bed189..e7b1f525e 100644 --- a/indra/llcommon/lluuid.h +++ b/indra/llcommon/lluuid.h @@ -106,9 +106,7 @@ public: friend LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLUUID &uuid); friend LL_COMMON_API std::istream& operator>>(std::istream& s, LLUUID &uuid); - void toString(char *out) const; // Does not allocate memory, needs 36 characters (including \0) void toString(std::string& out) const; - void toCompressedString(char *out) const; // Does not allocate memory, needs 17 characters (including \0) void toCompressedString(std::string& out) const; std::string asString() const; diff --git a/indra/llcommon/lluuidhashmap.h b/indra/llcommon/lluuidhashmap.h deleted file mode 100644 index c45e41399..000000000 --- a/indra/llcommon/lluuidhashmap.h +++ /dev/null @@ -1,589 +0,0 @@ -/** - * @file lluuidhashmap.h - * @brief A uuid based hash map. - * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLUUIDHASHMAP_H -#define LL_LLUUIDHASHMAP_H - -#include "stdtypes.h" -#include "llerror.h" -#include "lluuid.h" - -// UUID hash map - - /* - LLUUIDHashMap foo(test_equals); - LLUUIDHashMapIter bar(&foo); - - LLDynamicArray source_ids; - const S32 COUNT = 100000; - S32 q; - for (q = 0; q < COUNT; q++) - { - llinfos << "Creating" << llendl; - LLUUID id; - id.generate(); - //llinfos << q << ":" << id << llendl; - uuid_pair pair; - pair.mUUID = id; - pair.mValue = q; - foo.set(id, pair); - source_ids.put(id); - //ms_sleep(1); - } - - uuid_pair cur; - llinfos << "Iterating" << llendl; - for (cur = bar.first(); !bar.done(); cur = bar.next()) - { - if (source_ids[cur.mValue] != cur.mUUID) - { - llerrs << "Incorrect value iterated!" << llendl; - } - //llinfos << cur.mValue << ":" << cur.mUUID << llendl; - //ms_sleep(1); - } - - llinfos << "Finding" << llendl; - for (q = 0; q < COUNT; q++) - { - cur = foo.get(source_ids[q]); - if (source_ids[cur.mValue] != cur.mUUID) - { - llerrs << "Incorrect value found!" << llendl; - } - //llinfos << res.mValue << ":" << res.mUUID << llendl; - //ms_sleep(1); - } - - llinfos << "Removing" << llendl; - for (q = 0; q < COUNT/2; q++) - { - if (!foo.remove(source_ids[q])) - { - llerrs << "Remove failed!" << llendl; - } - //ms_sleep(1); - } - - llinfos << "Iterating" << llendl; - for (cur = bar.first(); !bar.done(); cur = bar.next()) - { - if (source_ids[cur.mValue] != cur.mUUID) - { - llerrs << "Incorrect value found!" << llendl; - } - //llinfos << cur.mValue << ":" << cur.mUUID << llendl; - //ms_sleep(1); - } - llinfos << "Done with UUID map test" << llendl; - - return 0; - */ - - -// -// LLUUIDHashNode -// - -template -class LLUUIDHashNode -{ -public: - LLUUIDHashNode(); - -public: - S32 mCount; - U8 mKey[SIZE]; - DATA mData[SIZE]; - LLUUIDHashNode *mNextNodep; -}; - - -// -// LLUUIDHashNode implementation -// -template -LLUUIDHashNode::LLUUIDHashNode() -{ - mCount = 0; - mNextNodep = NULL; -} - - -template -class LLUUIDHashMap -{ -public: - // basic constructor including sorter - LLUUIDHashMap(BOOL (*equals)(const LLUUID &uuid, const DATA_TYPE &data), - const DATA_TYPE &null_data); - ~LLUUIDHashMap(); - - inline DATA_TYPE &get(const LLUUID &uuid); - inline BOOL check(const LLUUID &uuid) const; - inline DATA_TYPE &set(const LLUUID &uuid, const DATA_TYPE &type); - inline BOOL remove(const LLUUID &uuid); - void removeAll(); - - inline S32 getLength() const; // Warning, NOT O(1!) -public: - BOOL (*mEquals)(const LLUUID &uuid, const DATA_TYPE &data); - LLUUIDHashNode mNodes[256]; - - S32 mIterCount; -protected: - DATA_TYPE mNull; -}; - - -// -// LLUUIDHashMap implementation -// - -template -LLUUIDHashMap::LLUUIDHashMap(BOOL (*equals)(const LLUUID &uuid, const DATA_TYPE &data), - const DATA_TYPE &null_data) -: mEquals(equals), - mIterCount(0), - mNull(null_data) -{ } - -template -LLUUIDHashMap::~LLUUIDHashMap() -{ - removeAll(); -} - -template -void LLUUIDHashMap::removeAll() -{ - S32 bin; - for (bin = 0; bin < 256; bin++) - { - LLUUIDHashNode* nodep = &mNodes[bin]; - - BOOL first = TRUE; - while (nodep) - { - S32 i; - const S32 count = nodep->mCount; - - // Iterate through all members of this node - for (i = 0; i < count; i++) - { - nodep->mData[i] = mNull; - } - - nodep->mCount = 0; - // Done with all objects in this node, go to the next. - - LLUUIDHashNode* curp = nodep; - nodep = nodep->mNextNodep; - - // Delete the node if it's not the first node - if (first) - { - first = FALSE; - curp->mNextNodep = NULL; - } - else - { - delete curp; - } - } - } -} - -template -inline S32 LLUUIDHashMap::getLength() const -{ - S32 count = 0; - S32 bin; - for (bin = 0; bin < 256; bin++) - { - LLUUIDHashNode* nodep = (LLUUIDHashNode*) &mNodes[bin]; - while (nodep) - { - count += nodep->mCount; - nodep = nodep->mNextNodep; - } - } - return count; -} - -template -inline DATA_TYPE &LLUUIDHashMap::get(const LLUUID &uuid) -{ - LLUUIDHashNode* nodep = &mNodes[uuid.mData[0]]; - - // Grab the second byte of the UUID, which is the key for the node data - const S32 second_byte = uuid.mData[1]; - while (nodep) - { - S32 i; - const S32 count = nodep->mCount; - - // Iterate through all members of this node - for (i = 0; i < count; i++) - { - if ((nodep->mKey[i] == second_byte) && mEquals(uuid, nodep->mData[i])) - { - // The second byte matched, and our equality test passed. - // We found it. - return nodep->mData[i]; - } - } - - // Done with all objects in this node, go to the next. - nodep = nodep->mNextNodep; - } - return mNull; -} - - -template -inline BOOL LLUUIDHashMap::check(const LLUUID &uuid) const -{ - const LLUUIDHashNode* nodep = &mNodes[uuid.mData[0]]; - - // Grab the second byte of the UUID, which is the key for the node data - const S32 second_byte = uuid.mData[1]; - while (nodep) - { - S32 i; - const S32 count = nodep->mCount; - - // Iterate through all members of this node - for (i = 0; i < count; i++) - { - if ((nodep->mKey[i] == second_byte) && mEquals(uuid, nodep->mData[i])) - { - // The second byte matched, and our equality test passed. - // We found it. - return TRUE; - } - } - - // Done with all objects in this node, go to the next. - nodep = nodep->mNextNodep; - } - - // Didn't find anything - return FALSE; -} - - -template -inline DATA_TYPE &LLUUIDHashMap::set(const LLUUID &uuid, const DATA_TYPE &data) -{ - // Set is just like a normal find, except that if we find a match - // we replace it with the input value. - // If we don't find a match, we append to the end of the list. - - LLUUIDHashNode* nodep = &mNodes[uuid.mData[0]]; - - const S32 second_byte = uuid.mData[1]; - while (1) - { - const S32 count = nodep->mCount; - - S32 i; - for (i = 0; i < count; i++) - { - if ((nodep->mKey[i] == second_byte) && mEquals(uuid, nodep->mData[i])) - { - // We found a match for this key, replace the data with - // the incoming data. - nodep->mData[i] = data; - return nodep->mData[i]; - } - } - if (!nodep->mNextNodep) - { - // We've iterated through all of the keys without finding a match - if (i < SIZE) - { - // There's still some space on this node, append - // the key and data to it. - nodep->mKey[i] = second_byte; - nodep->mData[i] = data; - nodep->mCount++; - - return nodep->mData[i]; - } - else - { - // This node is full, append a new node to the end. - nodep->mNextNodep = new LLUUIDHashNode; - nodep->mNextNodep->mKey[0] = second_byte; - nodep->mNextNodep->mData[0] = data; - nodep->mNextNodep->mCount = 1; - - return nodep->mNextNodep->mData[0]; - } - } - - // No match on this node, go to the next - nodep = nodep->mNextNodep; - } -} - - -template -inline BOOL LLUUIDHashMap::remove(const LLUUID &uuid) -{ - if (mIterCount) - { - // We don't allow remove when we're iterating, it's bad karma! - llerrs << "Attempted remove while an outstanding iterator in LLUUIDHashMap!" << llendl; - } - // Remove is the trickiest operation. - // What we want to do is swap the last element of the last - // node if we find the one that we want to remove, but we have - // to deal with deleting the node from the tail if it's empty, but - // NOT if it's the only node left. - - LLUUIDHashNode *nodep = &mNodes[uuid.mData[0]]; - - // Not empty, we need to search through the nodes - const S32 second_byte = uuid.mData[1]; - - // A modification of the standard search algorithm. - while (nodep) - { - const S32 count = nodep->mCount; - - S32 i; - for (i = 0; i < count; i++) - { - if ((nodep->mKey[i] == second_byte) && mEquals(uuid, nodep->mData[i])) - { - // We found the node that we want to remove. - // Find the last (and next-to-last) node, and the index of the last - // element. We could conceviably start from the node we're on, - // but that makes it more complicated, this is easier. - - LLUUIDHashNode *prevp = &mNodes[uuid.mData[0]]; - LLUUIDHashNode *lastp = prevp; - - // Find the last and next-to-last - while (lastp->mNextNodep) - { - prevp = lastp; - lastp = lastp->mNextNodep; - } - - // First, swap in the last to the current location. - nodep->mKey[i] = lastp->mKey[lastp->mCount - 1]; - nodep->mData[i] = lastp->mData[lastp->mCount - 1]; - - // Now, we delete the entry - lastp->mCount--; - lastp->mData[lastp->mCount] = mNull; - - if (!lastp->mCount) - { - // We deleted the last element! - if (lastp != &mNodes[uuid.mData[0]]) - { - // Only blitz the node if it's not the head - // Set the previous node to point to NULL, then - // blitz the empty last node - prevp->mNextNodep = NULL; - delete lastp; - } - } - return TRUE; - } - } - - // Iterate to the next node, we've scanned all the entries in this one. - nodep = nodep->mNextNodep; - } - return FALSE; -} - - -// -// LLUUIDHashMapIter -// - -template -class LLUUIDHashMapIter -{ -public: - LLUUIDHashMapIter(LLUUIDHashMap *hash_mapp); - ~LLUUIDHashMapIter(); - - - inline void reset(); - inline void first(); - inline void next(); - inline BOOL done() const; - - DATA_TYPE& operator*() const - { - return mCurHashNodep->mData[mCurHashNodeKey]; - } - DATA_TYPE* operator->() const - { - return &(operator*()); - } - -protected: - LLUUIDHashMap *mHashMapp; - LLUUIDHashNode *mCurHashNodep; - - S32 mCurHashMapNodeNum; - S32 mCurHashNodeKey; - - DATA_TYPE mNull; -}; - - -// -// LLUUIDHashMapIter Implementation -// -template -LLUUIDHashMapIter::LLUUIDHashMapIter(LLUUIDHashMap *hash_mapp) -{ - mHashMapp = hash_mapp; - mCurHashNodep = NULL; - mCurHashMapNodeNum = 0; - mCurHashNodeKey = 0; -} - -template -LLUUIDHashMapIter::~LLUUIDHashMapIter() -{ - reset(); -} - -template -inline void LLUUIDHashMapIter::reset() -{ - if (mCurHashNodep) - { - // We're partway through an iteration, we can clean up now - mHashMapp->mIterCount--; - mCurHashNodep = NULL; - } -} - -template -inline void LLUUIDHashMapIter::first() -{ - // Iterate through until we find the first non-empty node; - S32 i; - for (i = 0; i < 256; i++) - { - if (mHashMapp->mNodes[i].mCount) - { - if (!mCurHashNodep) - { - // Increment, since it's no longer safe for us to do a remove - mHashMapp->mIterCount++; - } - - mCurHashNodep = &mHashMapp->mNodes[i]; - mCurHashMapNodeNum = i; - mCurHashNodeKey = 0; - //return mCurHashNodep->mData[0]; - return; - } - } - - // Completely empty! - mCurHashNodep = NULL; - //return mNull; - return; -} - -template -inline BOOL LLUUIDHashMapIter::done() const -{ - return mCurHashNodep ? FALSE : TRUE; -} - -template -inline void LLUUIDHashMapIter::next() -{ - // No current entry, this iterator is done - if (!mCurHashNodep) - { - //return mNull; - return; - } - - // Go to the next element - mCurHashNodeKey++; - if (mCurHashNodeKey < mCurHashNodep->mCount) - { - // We're not done with this node, return the current element - //return mCurHashNodep->mData[mCurHashNodeKey]; - return; - } - - // Done with this node, move to the next - mCurHashNodep = mCurHashNodep->mNextNodep; - if (mCurHashNodep) - { - // Return the first element - mCurHashNodeKey = 0; - //return mCurHashNodep->mData[0]; - return; - } - - // Find the next non-empty node (keyed on the first byte) - mCurHashMapNodeNum++; - - S32 i; - for (i = mCurHashMapNodeNum; i < 256; i++) - { - if (mHashMapp->mNodes[i].mCount) - { - // We found one that wasn't empty - mCurHashNodep = &mHashMapp->mNodes[i]; - mCurHashMapNodeNum = i; - mCurHashNodeKey = 0; - //return mCurHashNodep->mData[0]; - return; - } - } - - // OK, we're done, nothing else to iterate - mCurHashNodep = NULL; - mHashMapp->mIterCount--; // Decrement since we're safe to do removes now - //return mNull; -} - -#endif // LL_LLUUIDHASHMAP_H diff --git a/indra/llcommon/sguuidhash.h b/indra/llcommon/sguuidhash.h new file mode 100644 index 000000000..b6b65aa0a --- /dev/null +++ b/indra/llcommon/sguuidhash.h @@ -0,0 +1,36 @@ +/* Copyright (C) 2013 Siana Gearz + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA */ + +#ifndef SGUUIDHASH_H +#define SGUUIDHASH_H + +#include "lluuid.h" +#include +#include + +namespace boost { + template<> class hash { + public: + size_t operator()(const LLUUID& id ) const + { + return *reinterpret_cast(id.mData); + } + }; +} + + +#endif diff --git a/indra/llinventory/llpermissionsflags.h b/indra/llinventory/llpermissionsflags.h index 02224d0c8..925976242 100644 --- a/indra/llinventory/llpermissionsflags.h +++ b/indra/llinventory/llpermissionsflags.h @@ -89,6 +89,10 @@ const U8 PERM_GROUP = 0x04; const U8 PERM_EVERYONE = 0x08; const U8 PERM_NEXT_OWNER = 0x10; +// Boolean values for "Set". +const U8 PERM_SET_TRUE = 0x1; +const U8 PERM_SET_FALSE = 0x0; + // This is just a quickie debugging key // no modify: PERM_ALL & ~PERM_MODIFY = 0x7fffbfff // no copy: PERM_ALL & ~PERM_COPY = 0x7fff7fff diff --git a/indra/llmath/llcalcparser.h b/indra/llmath/llcalcparser.h index 0fcd38064..e3eb2bded 100644 --- a/indra/llmath/llcalcparser.h +++ b/indra/llmath/llcalcparser.h @@ -41,7 +41,7 @@ namespace expression { //TODO: If we can find a better way to do this with boost::pheonix::bind lets do it -namespace { // anonymous +//namespace { // anonymous template T min_glue(T a, T b) @@ -91,7 +91,7 @@ struct lazy_bfunc_ } }; -} // end namespace anonymous +//} // end namespace anonymous template struct grammar diff --git a/indra/llmessage/aiaverage.h b/indra/llmessage/aiaverage.h index f8f344df6..ee588bd9f 100644 --- a/indra/llmessage/aiaverage.h +++ b/indra/llmessage/aiaverage.h @@ -52,7 +52,8 @@ class AIAverage { U32 mN; // The number of calls to operator(). int const mNrOfBuckets; // Size of mData. std::vector mData; // The buckets. - LLMutex mLock; // Mutex for all of the above data. + + mutable LLMutex mLock; // Mutex for all of the above data. public: AIAverage(int number_of_buckets) : mCurrentClock(~(U64)0), mTail(0), mCurrentBucket(0), mSum(0), mN(0), mNrOfBuckets(number_of_buckets), mData(number_of_buckets) @@ -88,7 +89,7 @@ class AIAverage { mLock.unlock(); return sum; } - double getAverage(double avg_no_data) + double getAverage(double avg_no_data) const { mLock.lock(); double avg = mSum; diff --git a/indra/llmessage/aicurl.cpp b/indra/llmessage/aicurl.cpp index 06c7f0ab4..e5dcb6ae8 100644 --- a/indra/llmessage/aicurl.cpp +++ b/indra/llmessage/aicurl.cpp @@ -1248,10 +1248,10 @@ AIPerServicePtr CurlEasyRequest::getPerServicePtr(void) return mPerServicePtr; } -bool CurlEasyRequest::removeFromPerServiceQueue(AICurlEasyRequest const& easy_request) const +bool CurlEasyRequest::removeFromPerServiceQueue(AICurlEasyRequest const& easy_request, AICapabilityType capability_type) const { // Note that easy_request (must) represent(s) this object; it's just passed for convenience. - return mPerServicePtr && PerServiceRequestQueue_wat(*mPerServicePtr)->cancel(easy_request); + return mPerServicePtr && PerService_wat(*mPerServicePtr)->cancel(easy_request, capability_type); } std::string CurlEasyRequest::getLowercaseHostname(void) const @@ -1269,7 +1269,8 @@ LLMutex BufferedCurlEasyRequest::sResponderCallbackMutex; bool BufferedCurlEasyRequest::sShuttingDown = false; AIAverage BufferedCurlEasyRequest::sHTTPBandwidth(25); -BufferedCurlEasyRequest::BufferedCurlEasyRequest() : mRequestTransferedBytes(0), mTotalRawBytes(0), mBufferEventsTarget(NULL), mStatus(HTTP_INTERNAL_ERROR_OTHER) +BufferedCurlEasyRequest::BufferedCurlEasyRequest() : + mRequestTransferedBytes(0), mTotalRawBytes(0), mStatus(HTTP_INTERNAL_ERROR_OTHER), mBufferEventsTarget(NULL), mCapabilityType(number_of_capability_types) { AICurlInterface::Stats::BufferedCurlEasyRequest_count++; } @@ -1401,6 +1402,9 @@ void BufferedCurlEasyRequest::prepRequest(AICurlEasyRequest_wat& curl_easy_reque // Keep responder alive. mResponder = responder; + // Cache capability type, because it will be needed even after the responder was removed. + mCapabilityType = responder->capability_type(); + // Send header events to responder if needed. if (mResponder->needsHeaders()) { diff --git a/indra/llmessage/aicurlperservice.cpp b/indra/llmessage/aicurlperservice.cpp index 28721c1e9..ff452c358 100644 --- a/indra/llmessage/aicurlperservice.cpp +++ b/indra/llmessage/aicurlperservice.cpp @@ -42,10 +42,7 @@ #include "llcontrol.h" AIPerService::threadsafe_instance_map_type AIPerService::sInstanceMap; -LLAtomicS32 AIPerService::sTotalQueued; -bool AIPerService::sQueueEmpty; -bool AIPerService::sQueueFull; -bool AIPerService::sRequestStarvation; +AIThreadSafeSimpleDC AIPerService::sTotalQueued; #undef AICurlPrivate @@ -54,14 +51,14 @@ namespace AICurlPrivate { // Cached value of CurlConcurrentConnectionsPerService. U32 CurlConcurrentConnectionsPerService; -// Friend functions of RefCountedThreadSafePerServiceRequestQueue +// Friend functions of RefCountedThreadSafePerService -void intrusive_ptr_add_ref(RefCountedThreadSafePerServiceRequestQueue* per_service) +void intrusive_ptr_add_ref(RefCountedThreadSafePerService* per_service) { per_service->mReferenceCount++; } -void intrusive_ptr_release(RefCountedThreadSafePerServiceRequestQueue* per_service) +void intrusive_ptr_release(RefCountedThreadSafePerService* per_service) { if (--per_service->mReferenceCount == 0) { @@ -74,14 +71,24 @@ void intrusive_ptr_release(RefCountedThreadSafePerServiceRequestQueue* per_servi using namespace AICurlPrivate; AIPerService::AIPerService(void) : - mQueuedCommands(0), mAdded(0), mQueueEmpty(false), - mQueueFull(false), mRequestStarvation(false), mHTTPBandwidth(25), // 25 = 1000 ms / 40 ms. + mHTTPBandwidth(25), // 25 = 1000 ms / 40 ms. mConcurrectConnections(CurlConcurrentConnectionsPerService), + mTotalAdded(0), + mApprovedFirst(0), + mUnapprovedFirst(0) +{ +} + +AIPerService::CapabilityType::CapabilityType(void) : + mApprovedRequests(0), + mQueuedCommands(0), + mAdded(0), + mFlags(0), mMaxPipelinedRequests(CurlConcurrentConnectionsPerService) { } -AIPerService::~AIPerService() +AIPerService::CapabilityType::~CapabilityType() { } @@ -194,7 +201,7 @@ AIPerServicePtr AIPerService::instance(std::string const& servicename) AIPerService::iterator iter = instance_map_w->find(servicename); if (iter == instance_map_w->end()) { - iter = instance_map_w->insert(instance_map_type::value_type(servicename, new RefCountedThreadSafePerServiceRequestQueue)).first; + iter = instance_map_w->insert(instance_map_type::value_type(servicename, new RefCountedThreadSafePerService)).first; } // Note: the creation of AIPerServicePtr MUST be protected by the lock on sInstanceMap (see release()). return iter->second; @@ -215,12 +222,20 @@ void AIPerService::release(AIPerServicePtr& instance) // Therefore, recheck the condition now that we have locked sInstanceMap. if (!instance->exactly_two_left()) { - // Some other thread added this host in the meantime. + // Some other thread added this service in the meantime. return; } - // The reference in the map is the last one; that means there can't be any curl easy requests queued for this host. - llassert(PerServiceRequestQueue_rat(*instance)->mQueuedRequests.empty()); - // Find the host and erase it from the map. +#ifdef SHOW_ASSERT + { + // The reference in the map is the last one; that means there can't be any curl easy requests queued for this service. + PerService_rat per_service_r(*instance); + for (int i = 0; i < number_of_capability_types; ++i) + { + llassert(per_service_r->mCapabilityType[i].mQueuedRequests.empty()); + } + } +#endif + // Find the service and erase it from the map. iterator const end = instance_map_w->end(); for(iterator iter = instance_map_w->begin(); iter != end; ++iter) { @@ -231,7 +246,7 @@ void AIPerService::release(AIPerServicePtr& instance) return; } } - // We should always find the host. + // We should always find the service. llassert(false); } instance.reset(); @@ -239,30 +254,32 @@ void AIPerService::release(AIPerServicePtr& instance) bool AIPerService::throttled() const { - return mAdded >= mConcurrectConnections; + return mTotalAdded >= mConcurrectConnections; } -void AIPerService::added_to_multi_handle(void) +void AIPerService::added_to_multi_handle(AICapabilityType capability_type) { - ++mAdded; + ++mCapabilityType[capability_type].mAdded; + ++mTotalAdded; } -void AIPerService::removed_from_multi_handle(void) +void AIPerService::removed_from_multi_handle(AICapabilityType capability_type) { - --mAdded; - llassert(mAdded >= 0); + --mCapabilityType[capability_type].mAdded; + --mTotalAdded; + llassert(mTotalAdded >= 0 && mCapabilityType[capability_type].mAdded >= 0); } -void AIPerService::queue(AICurlEasyRequest const& easy_request) +void AIPerService::queue(AICurlEasyRequest const& easy_request, AICapabilityType capability_type) { - mQueuedRequests.push_back(easy_request.get_ptr()); - sTotalQueued++; + mCapabilityType[capability_type].mQueuedRequests.push_back(easy_request.get_ptr()); + TotalQueued_wat(sTotalQueued)->count++; } -bool AIPerService::cancel(AICurlEasyRequest const& easy_request) +bool AIPerService::cancel(AICurlEasyRequest const& easy_request, AICapabilityType capability_type) { - queued_request_type::iterator const end = mQueuedRequests.end(); - queued_request_type::iterator cur = std::find(mQueuedRequests.begin(), end, easy_request.get_ptr()); + CapabilityType::queued_request_type::iterator const end = mCapabilityType[capability_type].mQueuedRequests.end(); + CapabilityType::queued_request_type::iterator cur = std::find(mCapabilityType[capability_type].mQueuedRequests.begin(), end, easy_request.get_ptr()); if (cur == end) return false; // Not found. @@ -273,55 +290,122 @@ bool AIPerService::cancel(AICurlEasyRequest const& easy_request) // want to break the order in which requests where added). Swap is also not // thread-safe, but OK here because it only touches the objects in the deque, // and the deque is protected by the lock on the AIPerService object. - queued_request_type::iterator prev = cur; + CapabilityType::queued_request_type::iterator prev = cur; while (++cur != end) { prev->swap(*cur); // This is safe, prev = cur; } - mQueuedRequests.pop_back(); // if this is safe. - --sTotalQueued; - llassert(sTotalQueued >= 0); + mCapabilityType[capability_type].mQueuedRequests.pop_back(); // if this is safe. + TotalQueued_wat total_queued_w(sTotalQueued); + total_queued_w->count--; + llassert(total_queued_w->count >= 0); return true; } -void AIPerService::add_queued_to(curlthread::MultiHandle* multi_handle) +void AIPerService::add_queued_to(curlthread::MultiHandle* multi_handle, bool recursive) { - if (!mQueuedRequests.empty()) + int order[number_of_capability_types]; + // The first two types are approved types, they should be the first to try. + // Try the one that has the largest queue first, if they the queues have equal size, try mApprovedFirst first. + size_t s0 = mCapabilityType[0].mQueuedRequests.size(); + size_t s1 = mCapabilityType[1].mQueuedRequests.size(); + if (s0 == s1) { - multi_handle->add_easy_request(mQueuedRequests.front()); - mQueuedRequests.pop_front(); - llassert(sTotalQueued > 0); - if (!--sTotalQueued) - { - // We obtained a request from the queue, and after that there we no more request in any queue. - sQueueEmpty = true; - } - else - { - // We obtained a request from the queue, and even after that there was at least one more request in some queue. - sQueueFull = true; - } - if (mQueuedRequests.empty()) - { - // We obtained a request from the queue, and after that there we no more request in the queue of this host. - mQueueEmpty = true; - } - else - { - // We obtained a request from the queue, and even after that there was at least one more request in the queue of this host. - mQueueFull = true; - } + order[0] = mApprovedFirst; + mApprovedFirst = 1 - mApprovedFirst; + order[1] = mApprovedFirst; + } + else if (s0 > s1) + { + order[0] = 0; + order[1] = 1; } else { - // We can add a new request, but there is none in the queue! - mRequestStarvation = true; - if (sTotalQueued == 0) + order[0] = 1; + order[1] = 0; + } + // The next two types are unapproved types. Here, try them alternating regardless of queue size. + int n = mUnapprovedFirst; + for (int i = 2; i < number_of_capability_types; ++i, n = (n + 1) % (number_of_capability_types - 2)) + { + order[i] = 2 + n; + } + mUnapprovedFirst = (mUnapprovedFirst + 1) % (number_of_capability_types - 2); + + for (int i = 0; i < number_of_capability_types; ++i) + { + CapabilityType& ct(mCapabilityType[order[i]]); + if (!ct.mQueuedRequests.empty()) { - // The queue of every host is empty! - sRequestStarvation = true; + if (!multi_handle->add_easy_request(ct.mQueuedRequests.front(), true)) + { + // Throttled. If this failed then every capability type will fail: we either are using too much bandwidth, or too many total connections. + // However, it MAY be that this service was thottled for using too much bandwidth by itself. Look if other services can be added. + break; + } + // Request was added, remove it from the queue. + ct.mQueuedRequests.pop_front(); + if (ct.mQueuedRequests.empty()) + { + // We obtained a request from the queue, and after that there we no more request in the queue of this service. + ct.mFlags |= ctf_empty; + } + else + { + // We obtained a request from the queue, and even after that there was at least one more request in the queue of this service. + ct.mFlags |= ctf_full; + } + TotalQueued_wat total_queued_w(sTotalQueued); + llassert(total_queued_w->count > 0); + if (!--(total_queued_w->count)) + { + // We obtained a request from the queue, and after that there we no more request in any queue. + total_queued_w->empty = true; + } + else + { + // We obtained a request from the queue, and even after that there was at least one more request in some queue. + total_queued_w->full = true; + } + // We added something from a queue, so we're done. + return; } + else + { + // We could add a new request, but there is none in the queue! + // Note that if this service does not serve this capability type, + // then obviously this queue was empty; however, in that case + // this variable will never be looked at, so it's ok to set it. + ct.mFlags |= ctf_starvation; + } + if (i == number_of_capability_types - 1) + { + // Last entry also empty. All queues of this service were empty. Check total connections. + TotalQueued_wat total_queued_w(sTotalQueued); + if (total_queued_w->count == 0) + { + // The queue of every service is empty! + total_queued_w->starvation = true; + return; + } + } + } + if (recursive) + { + return; + } + // Nothing from this service could be added, try other services. + instance_map_wat instance_map_w(sInstanceMap); + for (iterator service = instance_map_w->begin(); service != instance_map_w->end(); ++service) + { + PerService_wat per_service_w(*service->second); + if (&*per_service_w == this) + { + continue; + } + per_service_w->add_queued_to(multi_handle, true); } } @@ -329,14 +413,18 @@ void AIPerService::add_queued_to(curlthread::MultiHandle* multi_handle) void AIPerService::purge(void) { instance_map_wat instance_map_w(sInstanceMap); - for (iterator host = instance_map_w->begin(); host != instance_map_w->end(); ++host) + for (iterator service = instance_map_w->begin(); service != instance_map_w->end(); ++service) { - Dout(dc::curl, "Purging queue of host \"" << host->first << "\"."); - PerServiceRequestQueue_wat per_service_w(*host->second); - size_t s = per_service_w->mQueuedRequests.size(); - per_service_w->mQueuedRequests.clear(); - sTotalQueued -= s; - llassert(sTotalQueued >= 0); + Dout(dc::curl, "Purging queues of service \"" << service->first << "\"."); + PerService_wat per_service_w(*service->second); + TotalQueued_wat total_queued_w(sTotalQueued); + for (int i = 0; i < number_of_capability_types; ++i) + { + size_t s = per_service_w->mCapabilityType[i].mQueuedRequests.size(); + per_service_w->mCapabilityType[i].mQueuedRequests.clear(); + total_queued_w->count -= s; + llassert(total_queued_w->count >= 0); + } } } @@ -346,11 +434,31 @@ void AIPerService::adjust_concurrent_connections(int increment) instance_map_wat instance_map_w(sInstanceMap); for (AIPerService::iterator iter = instance_map_w->begin(); iter != instance_map_w->end(); ++iter) { - PerServiceRequestQueue_wat per_service_w(*iter->second); + PerService_wat per_service_w(*iter->second); U32 old_concurrent_connections = per_service_w->mConcurrectConnections; per_service_w->mConcurrectConnections = llclamp(old_concurrent_connections + increment, (U32)1, CurlConcurrentConnectionsPerService); increment = per_service_w->mConcurrectConnections - old_concurrent_connections; - per_service_w->mMaxPipelinedRequests = llmax(per_service_w->mMaxPipelinedRequests + increment, 0); + for (int i = 0; i < number_of_capability_types; ++i) + { + per_service_w->mCapabilityType[i].mMaxPipelinedRequests = llmax(per_service_w->mCapabilityType[i].mMaxPipelinedRequests + increment, (U32)0); + } } } +void AIPerService::Approvement::honored(void) +{ + if (!mHonored) + { + mHonored = true; + AICurlPrivate::PerService_wat per_service_w(*mPerServicePtr); + llassert(per_service_w->mCapabilityType[mCapabilityType].mApprovedRequests > 0); + per_service_w->mCapabilityType[mCapabilityType].mApprovedRequests--; + } +} + +void AIPerService::Approvement::not_honored(void) +{ + honored(); + llwarns << "Approvement for has not been honored." << llendl; +} + diff --git a/indra/llmessage/aicurlperservice.h b/indra/llmessage/aicurlperservice.h index 20271aeb3..f50c1f393 100644 --- a/indra/llmessage/aicurlperservice.h +++ b/indra/llmessage/aicurlperservice.h @@ -53,7 +53,7 @@ class AIPerService; namespace AICurlPrivate { namespace curlthread { class MultiHandle; } -class RefCountedThreadSafePerServiceRequestQueue; +class RefCountedThreadSafePerService; class ThreadSafeBufferedCurlEasyRequest; // Forward declaration of BufferedCurlEasyRequestPtr (see aicurlprivate.h). @@ -61,25 +61,37 @@ typedef boost::intrusive_ptr BufferedCurlEasy // AIPerService objects are created by the curl thread and destructed by the main thread. // We need locking. -typedef AIThreadSafeSimpleDC threadsafe_PerServiceRequestQueue; -typedef AIAccessConst PerServiceRequestQueue_crat; -typedef AIAccess PerServiceRequestQueue_rat; -typedef AIAccess PerServiceRequestQueue_wat; +typedef AIThreadSafeSimpleDC threadsafe_PerService; +typedef AIAccessConst PerService_crat; +typedef AIAccess PerService_rat; +typedef AIAccess PerService_wat; } // namespace AICurlPrivate -// We can't put threadsafe_PerServiceRequestQueue in a std::map because you can't copy a mutex. +// We can't put threadsafe_PerService in a std::map because you can't copy a mutex. // Therefore, use an intrusive pointer for the threadsafe type. -typedef boost::intrusive_ptr AIPerServicePtr; +typedef boost::intrusive_ptr AIPerServicePtr; + +//----------------------------------------------------------------------------- +// + +enum AICapabilityType { // {Capabilities} [Responders] + cap_texture = 0, // GetTexture [HTTPGetResponder] + cap_inventory = 1, // { FetchInventory2, FetchLib2 } [LLInventoryModel::fetchInventoryResponder], { FetchInventoryDescendents2, FetchLibDescendents2 } [LLInventoryModelFetchDescendentsResponder] + cap_mesh = 2, // GetMesh [LLMeshSkinInfoResponder, LLMeshDecompositionResponder, LLMeshPhysicsShapeResponder, LLMeshHeaderResponder, LLMeshLODResponder] + cap_other = 3, // All other capabilities + + number_of_capability_types = 4 +}; //----------------------------------------------------------------------------- // AIPerService -// This class provides a static interface to create and maintain instances -// of AIPerService objects, so that at any moment there is at most -// one instance per hostname:port. Those instances then are used to queue curl -// requests when the maximum number of connections for that host already -// have been reached. +// This class provides a static interface to create and maintain instances of AIPerService objects, +// so that at any moment there is at most one instance per service (hostname:port). +// Those instances then are used to queue curl requests when the maximum number of connections +// for that service already have been reached. And to keep track of the bandwidth usage, and the +// number of queued requests in the pipeline, for this service. class AIPerService { private: typedef std::map instance_map_type; @@ -89,12 +101,9 @@ class AIPerService { static threadsafe_instance_map_type sInstanceMap; // Map of AIPerService instances with the hostname as key. - friend class AIThreadSafeSimpleDC; //threadsafe_PerServiceRequestQueue + friend class AIThreadSafeSimpleDC; // threadsafe_PerService AIPerService(void); - public: - ~AIPerService(); - public: typedef instance_map_type::iterator iterator; typedef instance_map_type::const_iterator const_iterator; @@ -112,53 +121,135 @@ class AIPerService { static void purge(void); private: - typedef std::deque queued_request_type; + static U16 const ctf_empty = 1; + static U16 const ctf_full = 2; + static U16 const ctf_starvation = 4; - int mQueuedCommands; // Number of add commands (minus remove commands) with this host in the command queue. - int mAdded; // Number of active easy handles with this host. - queued_request_type mQueuedRequests; // Waiting (throttled) requests. + struct CapabilityType { + typedef std::deque queued_request_type; - static LLAtomicS32 sTotalQueued; // The sum of mQueuedRequests.size() of all AIPerService objects together. + queued_request_type mQueuedRequests; // Waiting (throttled) requests. + U16 mApprovedRequests; // The number of approved requests by approveHTTPRequestFor that were not added to the command queue yet. + U16 mQueuedCommands; // Number of add commands (minus remove commands), for this service, in the command queue. + U16 mAdded; // Number of active easy handles with this service. + U16 mFlags; // ctf_empty: Set to true when the queue becomes precisely empty. + // ctf_full : Set to true when the queue is popped and then still isn't empty; + // ctf_starvation: Set to true when the queue was about to be popped but was already empty. + U32 mMaxPipelinedRequests; // The maximum number of accepted requests for this service and (approved) capability type, that didn't finish yet. - bool mQueueEmpty; // Set to true when the queue becomes precisely empty. - bool mQueueFull; // Set to true when the queue is popped and then still isn't empty; - bool mRequestStarvation; // Set to true when the queue was about to be popped but was already empty. + // Declare, not define, constructor and destructor - in order to avoid instantiation of queued_request_type from header. + CapabilityType(void); + ~CapabilityType(); - static bool sQueueEmpty; // Set to true when sTotalQueued becomes precisely zero as the result of popping any queue. - static bool sQueueFull; // Set to true when sTotalQueued is still larger than zero after popping any queue. - static bool sRequestStarvation; // Set to true when any queue was about to be popped when sTotalQueued was already zero. + S32 pipelined_requests(void) const { return mApprovedRequests + mQueuedCommands + mQueuedRequests.size() + mAdded; } + }; + + CapabilityType mCapabilityType[number_of_capability_types]; AIAverage mHTTPBandwidth; // Keeps track on number of bytes received for this service in the past second. int mConcurrectConnections; // The maximum number of allowed concurrent connections to this service. - int mMaxPipelinedRequests; // The maximum number of accepted requests that didn't finish yet. + int mTotalAdded; // Number of active easy handles with this host. + int mApprovedFirst; // First capability type to try. + int mUnapprovedFirst; // First capability type to try after all approved types were tried. + + // Global administration of the total number of queued requests of all services combined. + private: + struct TotalQueued { + S32 count; // The sum of mQueuedRequests.size() of all AIPerService objects together. + bool empty; // Set to true when count becomes precisely zero as the result of popping any queue. + bool full; // Set to true when count is still larger than zero after popping any queue. + bool starvation; // Set to true when any queue was about to be popped when count was already zero. + TotalQueued(void) : count(0), empty(false), full(false), starvation(false) { } + }; + static AIThreadSafeSimpleDC sTotalQueued; + typedef AIAccessConst TotalQueued_crat; + typedef AIAccess TotalQueued_rat; + typedef AIAccess TotalQueued_wat; + public: + static S32 total_queued_size(void) { return TotalQueued_rat(sTotalQueued)->count; } + + // Global administration of the maximum number of pipelined requests of all services combined. + private: + struct MaxPipelinedRequests { + S32 count; // The maximum total number of accepted requests that didn't finish yet. + U64 last_increment; // Last time that sMaxPipelinedRequests was incremented. + U64 last_decrement; // Last time that sMaxPipelinedRequests was decremented. + MaxPipelinedRequests(void) : count(32), last_increment(0), last_decrement(0) { } + }; + static AIThreadSafeSimpleDC sMaxPipelinedRequests; + typedef AIAccessConst MaxPipelinedRequests_crat; + typedef AIAccess MaxPipelinedRequests_rat; + typedef AIAccess MaxPipelinedRequests_wat; + public: + static void setMaxPipelinedRequests(S32 count) { MaxPipelinedRequests_wat(sMaxPipelinedRequests)->count = count; } + static void incrementMaxPipelinedRequests(S32 increment) { MaxPipelinedRequests_wat(sMaxPipelinedRequests)->count += increment; } + + // Global administration of throttle fraction (which is the same for all services). + private: + struct ThrottleFraction { + U32 fraction; // A value between 0 and 1024: each service is throttled when it uses more than max_bandwidth * (sThrottleFraction/1024) bandwidth. + AIAverage average; // Average of fraction over 25 * 40ms = 1 second. + U64 last_add; // Last time that faction was added to average. + ThrottleFraction(void) : fraction(1024), average(25), last_add(0) { } + }; + static AIThreadSafeSimpleDC sThrottleFraction; + typedef AIAccessConst ThrottleFraction_crat; + typedef AIAccess ThrottleFraction_rat; + typedef AIAccess ThrottleFraction_wat; + + static LLAtomicU32 sHTTPThrottleBandwidth125; // HTTPThrottleBandwidth times 125 (in bytes/s). + static bool sNoHTTPBandwidthThrottling; // Global override to disable bandwidth throttling. public: - void added_to_command_queue(void) { ++mQueuedCommands; } - void removed_from_command_queue(void) { --mQueuedCommands; llassert(mQueuedCommands >= 0); } - void added_to_multi_handle(void); // Called when an easy handle for this host has been added to the multi handle. - void removed_from_multi_handle(void); // Called when an easy handle for this host is removed again from the multi handle. + void added_to_command_queue(AICapabilityType capability_type) { ++mCapabilityType[capability_type].mQueuedCommands; } + void removed_from_command_queue(AICapabilityType capability_type) { --mCapabilityType[capability_type].mQueuedCommands; llassert(mCapabilityType[capability_type].mQueuedCommands >= 0); } + void added_to_multi_handle(AICapabilityType capability_type); // Called when an easy handle for this host has been added to the multi handle. + void removed_from_multi_handle(AICapabilityType capability_type); // Called when an easy handle for this host is removed again from the multi handle. bool throttled(void) const; // Returns true if the maximum number of allowed requests for this host have been added to the multi handle. - void queue(AICurlEasyRequest const& easy_request); // Add easy_request to the queue. - bool cancel(AICurlEasyRequest const& easy_request); // Remove easy_request from the queue (if it's there). + void queue(AICurlEasyRequest const& easy_request, AICapabilityType capability_type); // Add easy_request to the queue. + bool cancel(AICurlEasyRequest const& easy_request, AICapabilityType capability_type); // Remove easy_request from the queue (if it's there). - void add_queued_to(AICurlPrivate::curlthread::MultiHandle* mh); + void add_queued_to(AICurlPrivate::curlthread::MultiHandle* mh, bool recursive = false); // Add queued easy handle (if any) to the multi handle. The request is removed from the queue, // followed by either a call to added_to_multi_handle() or to queue() to add it back. - S32 pipelined_requests(void) const { return mQueuedCommands + mQueuedRequests.size() + mAdded; } - static S32 total_queued_size(void) { return sTotalQueued; } + S32 pipelined_requests(AICapabilityType capability_type) const { return mCapabilityType[capability_type].pipelined_requests(); } AIAverage& bandwidth(void) { return mHTTPBandwidth; } AIAverage const& bandwidth(void) const { return mHTTPBandwidth; } + static void setNoHTTPBandwidthThrottling(bool nb) { sNoHTTPBandwidthThrottling = nb; } + static void setHTTPThrottleBandwidth(F32 max_kbps) { sHTTPThrottleBandwidth125 = 125.f * max_kbps; } + static size_t getHTTPThrottleBandwidth125(void) { return sHTTPThrottleBandwidth125; } + // Called when CurlConcurrentConnectionsPerService changes. static void adjust_concurrent_connections(int increment); - // Returns true if curl can handle another request for this host. - // Should return false if the maximum allowed HTTP bandwidth is reached, or when + // A helper class to decrement mApprovedRequests after requests approved by approveHTTPRequestFor were handled. + class Approvement : public LLThreadSafeRefCount { + private: + AIPerServicePtr mPerServicePtr; + AICapabilityType mCapabilityType; + bool mHonored; + public: + Approvement(AIPerServicePtr const& per_service, AICapabilityType capability_type) : mPerServicePtr(per_service), mCapabilityType(capability_type), mHonored(false) { } + ~Approvement() { if (!mHonored) not_honored(); } + void honored(void); + void not_honored(void); + }; + + // The two following functions are static and have the AIPerService object passed + // as first argument as an AIPerServicePtr because that avoids the need of having + // the AIPerService object locked for the whole duration of the call. + // The functions only lock it when access is required. + + // Returns approvement if curl can handle another request for this host. + // Should return NULL if the maximum allowed HTTP bandwidth is reached, or when // the latency between request and actual delivery becomes too large. - static bool wantsMoreHTTPRequestsFor(AIPerServicePtr const& per_service, F32 max_kbps, bool no_bandwidth_throttling); + static Approvement* approveHTTPRequestFor(AIPerServicePtr const& per_service, AICapabilityType capability_type); + // Return true if too much bandwidth is being used. + static bool checkBandwidthUsage(AIPerServicePtr const& per_service, U64 sTime_40ms); private: // Disallow copying. @@ -167,17 +258,17 @@ class AIPerService { namespace AICurlPrivate { -class RefCountedThreadSafePerServiceRequestQueue : public threadsafe_PerServiceRequestQueue { +class RefCountedThreadSafePerService : public threadsafe_PerService { public: - RefCountedThreadSafePerServiceRequestQueue(void) : mReferenceCount(0) { } + RefCountedThreadSafePerService(void) : mReferenceCount(0) { } bool exactly_two_left(void) const { return mReferenceCount == 2; } private: // Used by AIPerServicePtr. Object is deleted when reference count reaches zero. LLAtomicU32 mReferenceCount; - friend void intrusive_ptr_add_ref(RefCountedThreadSafePerServiceRequestQueue* p); - friend void intrusive_ptr_release(RefCountedThreadSafePerServiceRequestQueue* p); + friend void intrusive_ptr_add_ref(RefCountedThreadSafePerService* p); + friend void intrusive_ptr_release(RefCountedThreadSafePerService* p); }; extern U32 CurlConcurrentConnectionsPerService; diff --git a/indra/llmessage/aicurlprivate.h b/indra/llmessage/aicurlprivate.h index 57e6d9210..aa5a1ba7b 100644 --- a/indra/llmessage/aicurlprivate.h +++ b/indra/llmessage/aicurlprivate.h @@ -130,11 +130,17 @@ class CurlEasyHandle : public boost::noncopyable, protected AICurlEasyHandleEven // Pause and unpause a connection. CURLcode pause(int bitmask); + // Called if this request should be queued on the curl thread when too much bandwidth is being used. + void setApproved(AIPerService::Approvement* approved) { mApproved = approved; } + + // Returns false when this request should be queued by the curl thread when too much bandwidth is being used. + bool approved(void) const { return mApproved; } + // Called when a request is queued for removal. In that case a race between the actual removal // and revoking of the callbacks is harmless (and happens for the raw non-statemachine version). void remove_queued(void) { mQueuedForRemoval = true; } // In case it's added after being removed. - void add_queued(void) { mQueuedForRemoval = false; } + void add_queued(void) { mQueuedForRemoval = false; if (mApproved) { mApproved->honored(); } } #ifdef DEBUG_CURLIO void debug(bool debug) { if (mDebug) debug_curl_remove_easy(mEasyHandle); if (debug) debug_curl_add_easy(mEasyHandle); mDebug = debug; } @@ -146,6 +152,7 @@ class CurlEasyHandle : public boost::noncopyable, protected AICurlEasyHandleEven mutable char* mErrorBuffer; AIPostFieldPtr mPostField; // This keeps the POSTFIELD data alive for as long as the easy handle exists. bool mQueuedForRemoval; // Set if the easy handle is (probably) added to the multi handle, but is queued for removal. + LLPointer mApproved; // When not set then the curl thread should check bandwidth usage and queue this request if too much is being used. #ifdef DEBUG_CURLIO bool mDebug; #endif @@ -351,8 +358,8 @@ class CurlEasyRequest : public CurlEasyHandle { // PerService API. AIPerServicePtr getPerServicePtr(void); // (Optionally create and) return a pointer to the unique // AIPerService corresponding to mLowercaseServicename. - bool removeFromPerServiceQueue(AICurlEasyRequest const&) const; // Remove this request from the per-host queue, if queued at all. - // Returns true if it was queued. + bool removeFromPerServiceQueue(AICurlEasyRequest const&, AICapabilityType capability_type) const; // Remove this request from the per-host queue, if queued at all. + // Returns true if it was queued. protected: // Pass events to parent. /*virtual*/ void added_to_multi_handle(AICurlEasyRequest_wat& curl_easy_request_w); @@ -410,6 +417,7 @@ class BufferedCurlEasyRequest : public CurlEasyRequest { U8* mLastRead; // Pointer into mInput where we last stopped reading (or NULL to start at the beginning). buffer_ptr_t mOutput; LLHTTPClient::ResponderPtr mResponder; + AICapabilityType mCapabilityType; //U32 mBodyLimit; // From the old LLURLRequestDetail::mBodyLimit, but never used. U32 mStatus; // HTTP status, decoded from the first header line. std::string mReason; // The "reason" from the same header line. @@ -452,6 +460,9 @@ class BufferedCurlEasyRequest : public CurlEasyRequest { // Return true when prepRequest was already called and the object has not been // invalidated as a result of calling timed_out(). bool isValid(void) const { return mResponder; } + + // Return the capability type of this request. + AICapabilityType capability_type(void) const { llassert(mCapabilityType != number_of_capability_types); return mCapabilityType; } }; inline ThreadSafeBufferedCurlEasyRequest* CurlEasyRequest::get_lockobj(void) diff --git a/indra/llmessage/aicurlthread.cpp b/indra/llmessage/aicurlthread.cpp index 8b4f1a022..d27e755c6 100644 --- a/indra/llmessage/aicurlthread.cpp +++ b/indra/llmessage/aicurlthread.cpp @@ -206,8 +206,6 @@ int ioctlsocket(int fd, int, unsigned long* nonblocking_enable) namespace AICurlPrivate { -LLAtomicS32 max_pipelined_requests(32); - enum command_st { cmd_none, cmd_add, @@ -890,7 +888,7 @@ AICurlThread* AICurlThread::sInstance = NULL; AICurlThread::AICurlThread(void) : LLThread("AICurlThread"), mWakeUpFd_in(CURL_SOCKET_BAD), mWakeUpFd(CURL_SOCKET_BAD), - mZeroTimeout(0), mRunning(true), mWakeUpFlag(false) + mZeroTimeout(0), mWakeUpFlag(false), mRunning(true) { create_wakeup_fds(); sInstance = this; @@ -1327,19 +1325,30 @@ void AICurlThread::process_commands(AICurlMultiHandle_wat const& multi_handle_w) // Access command_being_processed only. { command_being_processed_rat command_being_processed_r(command_being_processed); + AICapabilityType capability_type; + AIPerServicePtr per_service; + { + AICurlEasyRequest_wat easy_request_w(*command_being_processed_r->easy_request()); + capability_type = easy_request_w->capability_type(); + per_service = easy_request_w->getPerServicePtr(); + } switch(command_being_processed_r->command()) { case cmd_none: case cmd_boost: // FIXME: future stuff break; case cmd_add: - PerServiceRequestQueue_wat(*AICurlEasyRequest_wat(*command_being_processed_r->easy_request())->getPerServicePtr())->removed_from_command_queue(); - multi_handle_w->add_easy_request(AICurlEasyRequest(command_being_processed_r->easy_request())); + { + multi_handle_w->add_easy_request(AICurlEasyRequest(command_being_processed_r->easy_request()), false); + PerService_wat(*per_service)->removed_from_command_queue(capability_type); break; + } case cmd_remove: - PerServiceRequestQueue_wat(*AICurlEasyRequest_wat(*command_being_processed_r->easy_request())->getPerServicePtr())->added_to_command_queue(); // Not really, but this has the same effect as 'removed a remove command'. + { + PerService_wat(*per_service)->added_to_command_queue(capability_type); // Not really, but this has the same effect as 'removed a remove command'. multi_handle_w->remove_easy_request(AICurlEasyRequest(command_being_processed_r->easy_request()), true); break; + } } // Done processing. command_being_processed_wat command_being_processed_w(command_being_processed_r); @@ -1703,40 +1712,53 @@ CURLMsg const* MultiHandle::info_read(int* msgs_in_queue) const static U32 curl_max_total_concurrent_connections = 32; // Initialized on start up by startCurlThread(). -void MultiHandle::add_easy_request(AICurlEasyRequest const& easy_request) +bool MultiHandle::add_easy_request(AICurlEasyRequest const& easy_request, bool from_queue) { bool throttled = true; // Default. + AICapabilityType capability_type; AIPerServicePtr per_service; { AICurlEasyRequest_wat curl_easy_request_w(*easy_request); + capability_type = curl_easy_request_w->capability_type(); per_service = curl_easy_request_w->getPerServicePtr(); - PerServiceRequestQueue_wat per_service_w(*per_service); - if (mAddedEasyRequests.size() < curl_max_total_concurrent_connections && !per_service_w->throttled()) + // Never throttle on bandwidth if there are no handles running (sTotalAdded == 1, the long poll connection). + bool too_much_bandwidth = sTotalAdded > 1 && !curl_easy_request_w->approved() && AIPerService::checkBandwidthUsage(per_service, get_clock_count() * HTTPTimeout::sClockWidth_40ms); + PerService_wat per_service_w(*per_service); + if (!too_much_bandwidth && sTotalAdded < curl_max_total_concurrent_connections && !per_service_w->throttled()) { curl_easy_request_w->set_timeout_opts(); if (curl_easy_request_w->add_handle_to_multi(curl_easy_request_w, mMultiHandle) == CURLM_OK) { - per_service_w->added_to_multi_handle(); // (About to be) added to mAddedEasyRequests. + per_service_w->added_to_multi_handle(capability_type); // (About to be) added to mAddedEasyRequests. throttled = false; // Fall through... } } } // Release the lock on easy_request. if (!throttled) { // ... to here. - std::pair res = mAddedEasyRequests.insert(easy_request); +#ifdef SHOW_ASSERT + std::pair res = +#endif + mAddedEasyRequests.insert(easy_request); llassert(res.second); // May not have been added before. sTotalAdded++; llassert(sTotalAdded == mAddedEasyRequests.size()); Dout(dc::curl, "MultiHandle::add_easy_request: Added AICurlEasyRequest " << (void*)easy_request.get_ptr().get() << "; now processing " << mAddedEasyRequests.size() << " easy handles [running_handles = " << AICurlInterface::Stats::running_handles << "]."); - return; + return true; + } + if (from_queue) + { + // Throttled. Do not add to queue, because it is already in the queue. + return false; } // The request could not be added, we have to queue it. - PerServiceRequestQueue_wat(*per_service)->queue(easy_request); + PerService_wat(*per_service)->queue(easy_request, capability_type); #ifdef SHOW_ASSERT // Not active yet, but it's no longer an error if next we try to remove the request. AICurlEasyRequest_wat(*easy_request)->mRemovedPerCommand = false; #endif + return true; } CURLMcode MultiHandle::remove_easy_request(AICurlEasyRequest const& easy_request, bool as_per_command) @@ -1749,7 +1771,7 @@ CURLMcode MultiHandle::remove_easy_request(AICurlEasyRequest const& easy_request #ifdef SHOW_ASSERT bool removed = #endif - easy_request_w->removeFromPerServiceQueue(easy_request); + easy_request_w->removeFromPerServiceQueue(easy_request, easy_request_w->capability_type()); #ifdef SHOW_ASSERT if (removed) { @@ -1765,12 +1787,14 @@ CURLMcode MultiHandle::remove_easy_request(AICurlEasyRequest const& easy_request CURLMcode MultiHandle::remove_easy_request(addedEasyRequests_type::iterator const& iter, bool as_per_command) { CURLMcode res; + AICapabilityType capability_type; AIPerServicePtr per_service; { AICurlEasyRequest_wat curl_easy_request_w(**iter); res = curl_easy_request_w->remove_handle_from_multi(curl_easy_request_w, mMultiHandle); + capability_type = curl_easy_request_w->capability_type(); per_service = curl_easy_request_w->getPerServicePtr(); - PerServiceRequestQueue_wat(*per_service)->removed_from_multi_handle(); // (About to be) removed from mAddedEasyRequests. + PerService_wat(*per_service)->removed_from_multi_handle(capability_type); // (About to be) removed from mAddedEasyRequests. #ifdef SHOW_ASSERT curl_easy_request_w->mRemovedPerCommand = as_per_command; #endif @@ -1787,7 +1811,7 @@ CURLMcode MultiHandle::remove_easy_request(addedEasyRequests_type::iterator cons #endif // Attempt to add a queued request, if any. - PerServiceRequestQueue_wat(*per_service)->add_queued_to(this); + PerService_wat(*per_service)->add_queued_to(this); return res; } @@ -2120,7 +2144,7 @@ void BufferedCurlEasyRequest::update_body_bandwidth(void) if (raw_bytes > 0) { U64 const sTime_40ms = curlthread::HTTPTimeout::sTime_10ms >> 2; - AIAverage& http_bandwidth(PerServiceRequestQueue_wat(*getPerServicePtr())->bandwidth()); + AIAverage& http_bandwidth(PerService_wat(*getPerServicePtr())->bandwidth()); http_bandwidth.addData(raw_bytes, sTime_40ms); sHTTPBandwidth.addData(raw_bytes, sTime_40ms); } @@ -2215,7 +2239,7 @@ size_t BufferedCurlEasyRequest::curlHeaderCallback(char* data, size_t size, size } // Update HTTP bandwidth. U64 const sTime_40ms = curlthread::HTTPTimeout::sTime_10ms >> 2; - AIAverage& http_bandwidth(PerServiceRequestQueue_wat(*self_w->getPerServicePtr())->bandwidth()); + AIAverage& http_bandwidth(PerService_wat(*self_w->getPerServicePtr())->bandwidth()); http_bandwidth.addData(header_len, sTime_40ms); sHTTPBandwidth.addData(header_len, sTime_40ms); // Update timeout administration. This must be done after the status is already known. @@ -2421,7 +2445,7 @@ void AICurlEasyRequest::addRequest(void) command_queue_w->commands.push_back(Command(*this, cmd_add)); command_queue_w->size++; AICurlEasyRequest_wat curl_easy_request_w(*get()); - PerServiceRequestQueue_wat(*curl_easy_request_w->getPerServicePtr())->added_to_command_queue(); + PerService_wat(*curl_easy_request_w->getPerServicePtr())->added_to_command_queue(curl_easy_request_w->capability_type()); curl_easy_request_w->add_queued(); } // Something was added to the queue, wake up the thread to get it. @@ -2485,7 +2509,7 @@ void AICurlEasyRequest::removeRequest(void) command_queue_w->commands.push_back(Command(*this, cmd_remove)); command_queue_w->size--; AICurlEasyRequest_wat curl_easy_request_w(*get()); - PerServiceRequestQueue_wat(*curl_easy_request_w->getPerServicePtr())->removed_from_command_queue(); // Note really, but this has the same effect as 'added a remove command'. + PerService_wat(*curl_easy_request_w->getPerServicePtr())->removed_from_command_queue(curl_easy_request_w->capability_type()); // Note really, but this has the same effect as 'added a remove command'. // Suppress warning that would otherwise happen if the callbacks are revoked before the curl thread removed the request. curl_easy_request_w->remove_queued(); } @@ -2511,7 +2535,8 @@ void startCurlThread(LLControlGroup* control_group) curl_max_total_concurrent_connections = sConfigGroup->getU32("CurlMaxTotalConcurrentConnections"); CurlConcurrentConnectionsPerService = sConfigGroup->getU32("CurlConcurrentConnectionsPerService"); gNoVerifySSLCert = sConfigGroup->getBOOL("NoVerifySSLCert"); - max_pipelined_requests = curl_max_total_concurrent_connections; + AIPerService::setMaxPipelinedRequests(curl_max_total_concurrent_connections); + AIPerService::setHTTPThrottleBandwidth(sConfigGroup->getF32("HTTPThrottleBandwidth")); AICurlThread::sInstance = new AICurlThread; AICurlThread::sInstance->start(); @@ -2524,7 +2549,7 @@ bool handleCurlMaxTotalConcurrentConnections(LLSD const& newvalue) U32 old = curl_max_total_concurrent_connections; curl_max_total_concurrent_connections = newvalue.asInteger(); - max_pipelined_requests += curl_max_total_concurrent_connections - old; + AIPerService::incrementMaxPipelinedRequests(curl_max_total_concurrent_connections - old); llinfos << "CurlMaxTotalConcurrentConnections set to " << curl_max_total_concurrent_connections << llendl; return true; } @@ -2574,6 +2599,12 @@ size_t getHTTPBandwidth(void) } // namespace AICurlInterface +// Global AIPerService members. +AIThreadSafeSimpleDC AIPerService::sMaxPipelinedRequests; +AIThreadSafeSimpleDC AIPerService::sThrottleFraction; +LLAtomicU32 AIPerService::sHTTPThrottleBandwidth125(250000); +bool AIPerService::sNoHTTPBandwidthThrottling; + // Return true if we want at least one more HTTP request for this host. // // It's OK if this function is a bit fuzzy, but we don't want it to return @@ -2599,162 +2630,185 @@ size_t getHTTPBandwidth(void) // running requests (in MultiHandle::mAddedEasyRequests)). // //static -bool AIPerService::wantsMoreHTTPRequestsFor(AIPerServicePtr const& per_service, F32 max_kbps, bool no_bandwidth_throttling) +AIPerService::Approvement* AIPerService::approveHTTPRequestFor(AIPerServicePtr const& per_service, AICapabilityType capability_type) { using namespace AICurlPrivate; using namespace AICurlPrivate::curlthread; - bool reject, equal, increment_threshold, decrement_threshold; + // Do certain things at most once every 40ms. + U64 const sTime_40ms = get_clock_count() * HTTPTimeout::sClockWidth_40ms; // Time in 40ms units. + + // Cache all sTotalQueued info. + bool starvation, decrement_threshold; + S32 total_queued_or_added = MultiHandle::total_added_size(); + { + TotalQueued_wat total_queued_w(sTotalQueued); + total_queued_or_added += total_queued_w->count; + starvation = total_queued_w->starvation; + decrement_threshold = total_queued_w->full && !total_queued_w->empty; + total_queued_w->empty = total_queued_w->full = false; // Reset flags. + } // Whether or not we're going to approve a new request, decrement the global threshold first, when appropriate. - // Atomic read max_pipelined_requests for the below calculations. - S32 const max_pipelined_requests_cache = max_pipelined_requests; - decrement_threshold = sQueueFull && !sQueueEmpty; - // Reset flags. - sQueueEmpty = sQueueFull = false; if (decrement_threshold) { - if (max_pipelined_requests_cache > (S32)curl_max_total_concurrent_connections) + MaxPipelinedRequests_wat max_pipelined_requests_w(sMaxPipelinedRequests); + if (max_pipelined_requests_w->count > (S32)curl_max_total_concurrent_connections && + sTime_40ms > max_pipelined_requests_w->last_decrement) { // Decrement the threshold because since the last call to this function at least one curl request finished // and was replaced with another request from the queue, but the queue never ran empty: we have too many // queued requests. - --max_pipelined_requests; + max_pipelined_requests_w->count--; + // Do this at most once every 40 ms. + max_pipelined_requests_w->last_decrement = sTime_40ms; } } - // Check if it's ok to get a new request for this particular service and update the per-service threshold. - - AIAverage* http_bandwidth_ptr; + // Check if it's ok to get a new request for this particular capability type and update the per-capability-type threshold. + bool reject, equal, increment_threshold; { - PerServiceRequestQueue_wat per_service_w(*per_service); - S32 const pipelined_requests_per_service = per_service_w->pipelined_requests(); - reject = pipelined_requests_per_service >= per_service_w->mMaxPipelinedRequests; - equal = pipelined_requests_per_service == per_service_w->mMaxPipelinedRequests; - increment_threshold = per_service_w->mRequestStarvation; - decrement_threshold = per_service_w->mQueueFull && !per_service_w->mQueueEmpty; - // Reset flags. - per_service_w->mQueueFull = per_service_w->mQueueEmpty = per_service_w->mRequestStarvation = false; - // Grab per service bandwidth object. - http_bandwidth_ptr = &per_service_w->bandwidth(); + PerService_wat per_service_w(*per_service); + CapabilityType& ct(per_service_w->mCapabilityType[capability_type]); + S32 const pipelined_requests_per_capability_type = ct.pipelined_requests(); + reject = pipelined_requests_per_capability_type >= (S32)ct.mMaxPipelinedRequests; + equal = pipelined_requests_per_capability_type == ct.mMaxPipelinedRequests; + increment_threshold = ct.mFlags & ctf_starvation; + decrement_threshold = (ct.mFlags & (ctf_empty | ctf_full)) == ctf_full; + ct.mFlags = 0; if (decrement_threshold) { - if (per_service_w->mMaxPipelinedRequests > per_service_w->mConcurrectConnections) + if ((int)ct.mMaxPipelinedRequests > per_service_w->mConcurrectConnections) { - per_service_w->mMaxPipelinedRequests--; + ct.mMaxPipelinedRequests--; } } else if (increment_threshold && reject) { - if (per_service_w->mMaxPipelinedRequests < 2 * per_service_w->mConcurrectConnections) + if ((int)ct.mMaxPipelinedRequests < 2 * per_service_w->mConcurrectConnections) { - per_service_w->mMaxPipelinedRequests++; + ct.mMaxPipelinedRequests++; // Immediately take the new threshold into account. reject = !equal; } } + if (!reject) + { + // Before releasing the lock on per_service, stop other threads from getting a + // too small value from pipelined_requests() and approving too many requests. + ct.mApprovedRequests++; + } } if (reject) { - // Too many request for this host already. - return false; + // Too many request for this service already. + return NULL; } - if (!no_bandwidth_throttling) + // Throttle on bandwidth usage. + if (checkBandwidthUsage(per_service, sTime_40ms)) { - // Throttle on bandwidth usage. - - static size_t throttle_fraction = 1024; // A value between 0 and 1024: each service is throttled when it uses more than max_bandwidth * (throttle_fraction/1024) bandwidth. - static AIAverage fraction(25); // Average over 25 * 40ms = 1 second. - static U64 last_sTime_40ms = 0; - - // Truncate the sums to the last second, and get their value. - U64 const sTime_40ms = get_clock_count() * HTTPTimeout::sClockWidth_40ms; // Time in 40ms units. - size_t const max_bandwidth = 125.f * max_kbps; // Convert kbps to bytes per second. - size_t const total_bandwidth = BufferedCurlEasyRequest::sHTTPBandwidth.truncateData(sTime_40ms); // Bytes received in the past second. - size_t const service_bandwidth = http_bandwidth_ptr->truncateData(sTime_40ms); // Idem for just this service. - if (sTime_40ms > last_sTime_40ms) - { - // Only add throttle_fraction once every 40 ms at most. - // It's ok to ignore other values in the same 40 ms because the value only changes on the scale of 1 second. - fraction.addData(throttle_fraction, sTime_40ms); - last_sTime_40ms = sTime_40ms; - } - double fraction_avg = fraction.getAverage(1024.0); // throttle_fraction averaged over the past second, or 1024 if there is no data. - - // Adjust throttle_fraction based on total bandwidth usage. - if (total_bandwidth == 0) - throttle_fraction = 1024; - else - { - // This is the main formula. It can be made plausible by assuming - // an equilibrium where total_bandwidth == max_bandwidth and - // thus throttle_fraction == fraction_avg for more than a second. - // - // Then, more bandwidth is being used (for example because another - // service starts downloading). Assuming that all services that use - // a significant portion of the bandwidth, the new service included, - // must be throttled (all using the same bandwidth; note that the - // new service is immediately throttled at the same value), then - // the limit should be reduced linear with the fraction: - // max_bandwidth / total_bandwidth. - // - // For example, let max_bandwidth be 1. Let there be two throttled - // services, each using 0.5 (fraction_avg = 1024/2). Lets the new - // service use what it can: also 0.5 - then without reduction the - // total_bandwidth would become 1.5, and throttle_fraction would - // become (1024/2) * 1/1.5 = 1024/3: from 2 to 3 services. - // - // In reality, total_bandwidth would rise linear from 1.0 to 1.5 in - // one second if the throttle fraction wasn't changed. However it is - // changed here. The end result is that any change more or less - // linear fades away in one second. - throttle_fraction = fraction_avg * max_bandwidth / total_bandwidth; - } - if (throttle_fraction > 1024) - throttle_fraction = 1024; - if (total_bandwidth > max_bandwidth) - { - throttle_fraction *= 0.95; - } - - // Throttle this service if it uses too much bandwidth. - if (service_bandwidth > (max_bandwidth * throttle_fraction / 1024)) - { - return false; // wait - } + // Too much bandwidth is being used, either in total or for this service. + PerService_wat(*per_service)->mCapabilityType[capability_type].mApprovedRequests--; // Not approved after all. + return NULL; } // Check if it's ok to get a new request based on the total number of requests and increment the threshold if appropriate. - { - command_queue_rat command_queue_r(command_queue); - S32 const pipelined_requests = command_queue_r->size + sTotalQueued + MultiHandle::total_added_size(); - // We can't take the command being processed (command_being_processed) into account without - // introducing relatively long waiting times for some mutex (namely between when the command - // is moved from command_queue to command_being_processed, till it's actually being added to - // mAddedEasyRequests). The whole purpose of command_being_processed is to reduce the time - // that things are locked to micro seconds, so we'll just accept an off-by-one fuzziness - // here instead. + S32 const pipelined_requests = command_queue_rat(command_queue)->size + total_queued_or_added; + // We can't take the command being processed (command_being_processed) into account without + // introducing relatively long waiting times for some mutex (namely between when the command + // is moved from command_queue to command_being_processed, till it's actually being added to + // mAddedEasyRequests). The whole purpose of command_being_processed is to reduce the time + // that things are locked to micro seconds, so we'll just accept an off-by-one fuzziness + // here instead. - // The maximum number of requests that may be queued in command_queue is equal to the total number of requests - // that may exist in the pipeline minus the number of requests queued in AIPerService objects, minus - // the number of already running requests. - reject = pipelined_requests >= max_pipelined_requests_cache; - equal = pipelined_requests == max_pipelined_requests_cache; - increment_threshold = sRequestStarvation; - } + // The maximum number of requests that may be queued in command_queue is equal to the total number of requests + // that may exist in the pipeline minus the number of requests queued in AIPerService objects, minus + // the number of already running requests. + MaxPipelinedRequests_wat max_pipelined_requests_w(sMaxPipelinedRequests); + reject = pipelined_requests >= max_pipelined_requests_w->count; + equal = pipelined_requests == max_pipelined_requests_w->count; + increment_threshold = starvation; if (increment_threshold && reject) { - if (max_pipelined_requests_cache < 2 * (S32)curl_max_total_concurrent_connections) + if (max_pipelined_requests_w->count < 2 * (S32)curl_max_total_concurrent_connections && + sTime_40ms > max_pipelined_requests_w->last_increment) { - max_pipelined_requests++; + max_pipelined_requests_w->count++; + max_pipelined_requests_w->last_increment = sTime_40ms; // Immediately take the new threshold into account. reject = !equal; } } - return !reject; + if (reject) + { + PerService_wat(*per_service)->mCapabilityType[capability_type].mApprovedRequests--; // Not approved after all. + return NULL; + } + return new Approvement(per_service, capability_type); +} + +bool AIPerService::checkBandwidthUsage(AIPerServicePtr const& per_service, U64 sTime_40ms) +{ + if (sNoHTTPBandwidthThrottling) + return false; + + using namespace AICurlPrivate; + + // Truncate the sums to the last second, and get their value. + size_t const max_bandwidth = AIPerService::getHTTPThrottleBandwidth125(); + size_t const total_bandwidth = BufferedCurlEasyRequest::sHTTPBandwidth.truncateData(sTime_40ms); // Bytes received in the past second. + size_t const service_bandwidth = PerService_wat(*per_service)->bandwidth().truncateData(sTime_40ms); // Idem for just this service. + ThrottleFraction_wat throttle_fraction_w(sThrottleFraction); + if (sTime_40ms > throttle_fraction_w->last_add) + { + throttle_fraction_w->average.addData(throttle_fraction_w->fraction, sTime_40ms); + // Only add throttle_fraction_w->fraction once every 40 ms at most. + // It's ok to ignore other values in the same 40 ms because the value only changes on the scale of 1 second. + throttle_fraction_w->last_add = sTime_40ms; + } + double fraction_avg = throttle_fraction_w->average.getAverage(1024.0); // throttle_fraction_w->fraction averaged over the past second, or 1024 if there is no data. + + // Adjust the fraction based on total bandwidth usage. + if (total_bandwidth == 0) + throttle_fraction_w->fraction = 1024; + else + { + // This is the main formula. It can be made plausible by assuming + // an equilibrium where total_bandwidth == max_bandwidth and + // thus fraction == fraction_avg for more than a second. + // + // Then, more bandwidth is being used (for example because another + // service starts downloading). Assuming that all services that use + // a significant portion of the bandwidth, the new service included, + // must be throttled (all using the same bandwidth; note that the + // new service is immediately throttled at the same value), then + // the limit should be reduced linear with the fraction: + // max_bandwidth / total_bandwidth. + // + // For example, let max_bandwidth be 1. Let there be two throttled + // services, each using 0.5 (fraction_avg = 1024/2). Let the new + // service use what it can: also 0.5 - then without reduction the + // total_bandwidth would become 1.5, and fraction would + // become (1024/2) * 1/1.5 = 1024/3: from 2 to 3 services. + // + // In reality, total_bandwidth would rise linear from 1.0 to 1.5 in + // one second if the throttle fraction wasn't changed. However it is + // changed here. The end result is that any change more or less + // linear fades away in one second. + throttle_fraction_w->fraction = llmin(1024., fraction_avg * max_bandwidth / total_bandwidth + 0.5); + } + if (total_bandwidth > max_bandwidth) + { + throttle_fraction_w->fraction *= 0.95; + } + + // Throttle this service if it uses too much bandwidth. + // Warning: this requires max_bandwidth * 1024 to fit in a size_t. + // On 32 bit that means that HTTPThrottleBandwidth must be less than 33554 kbps. + return (service_bandwidth > (max_bandwidth * throttle_fraction_w->fraction / 1024)); } diff --git a/indra/llmessage/aicurlthread.h b/indra/llmessage/aicurlthread.h index 9f71b015c..9a4c2b487 100644 --- a/indra/llmessage/aicurlthread.h +++ b/indra/llmessage/aicurlthread.h @@ -59,7 +59,7 @@ class MultiHandle : public CurlMultiHandle ~MultiHandle(); // Add/remove an easy handle to/from a multi session. - void add_easy_request(AICurlEasyRequest const& easy_request); + bool add_easy_request(AICurlEasyRequest const& easy_request, bool from_queue); CURLMcode remove_easy_request(AICurlEasyRequest const& easy_request, bool as_per_command = false); // Reads/writes available data from a particular socket (non-blocking). diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index c130938d2..dfbc9e249 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -201,7 +201,8 @@ void LLHTTPClient::request( LLURLRequest::ERequestAction method, Injector* body_injector, LLHTTPClient::ResponderPtr responder, - AIHTTPHeaders& headers/*,*/ + AIHTTPHeaders& headers, + AIPerService::Approvement* approved/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug), EKeepAlive keepalive, EDoesAuthentication does_auth, @@ -221,7 +222,7 @@ void LLHTTPClient::request( LLURLRequest* req; try { - req = new LLURLRequest(method, url, body_injector, responder, headers, keepalive, does_auth, allow_compression); + req = new LLURLRequest(method, url, body_injector, responder, headers, approved, keepalive, does_auth, allow_compression); #ifdef DEBUG_CURLIO req->mCurlEasyRequest.debug(debug); #endif @@ -242,22 +243,22 @@ void LLHTTPClient::getByteRange(std::string const& url, S32 offset, S32 bytes, R { headers.addHeader("Range", llformat("bytes=%d-%d", offset, offset + bytes - 1)); } - request(url, HTTP_GET, NULL, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); + request(url, HTTP_GET, NULL, responder, headers, NULL/*,*/ DEBUG_CURLIO_PARAM(debug)); } void LLHTTPClient::head(std::string const& url, ResponderHeadersOnly* responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug)) { - request(url, HTTP_HEAD, NULL, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); + request(url, HTTP_HEAD, NULL, responder, headers, NULL/*,*/ DEBUG_CURLIO_PARAM(debug)); } void LLHTTPClient::get(std::string const& url, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug)) { - request(url, HTTP_GET, NULL, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); + request(url, HTTP_GET, NULL, responder, headers, NULL/*,*/ DEBUG_CURLIO_PARAM(debug)); } void LLHTTPClient::getHeaderOnly(std::string const& url, ResponderHeadersOnly* responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug)) { - request(url, HTTP_HEAD, NULL, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); + request(url, HTTP_HEAD, NULL, responder, headers, NULL/*,*/ DEBUG_CURLIO_PARAM(debug)); } void LLHTTPClient::get(std::string const& url, LLSD const& query, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug)) @@ -693,17 +694,22 @@ U32 LLHTTPClient::blockingGetRaw(const std::string& url, std::string& body/*,*/ void LLHTTPClient::put(std::string const& url, LLSD const& body, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug)) { - request(url, HTTP_PUT, new LLSDInjector(body), responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), no_keep_alive, no_does_authentication, no_allow_compressed_reply); + request(url, HTTP_PUT, new LLSDInjector(body), responder, headers, NULL/*,*/ DEBUG_CURLIO_PARAM(debug), no_keep_alive, no_does_authentication, no_allow_compressed_reply); } void LLHTTPClient::post(std::string const& url, LLSD const& body, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug), EKeepAlive keepalive, AIStateMachine* parent, AIStateMachine::state_type new_parent_state) { - request(url, HTTP_POST, new LLSDInjector(body), responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive, no_does_authentication, allow_compressed_reply, parent, new_parent_state); + request(url, HTTP_POST, new LLSDInjector(body), responder, headers, NULL/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive, no_does_authentication, allow_compressed_reply, parent, new_parent_state); +} + +void LLHTTPClient::post_approved(std::string const& url, LLSD const& body, ResponderPtr responder, AIHTTPHeaders& headers, AIPerService::Approvement* approved/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug), EKeepAlive keepalive, AIStateMachine* parent, AIStateMachine::state_type new_parent_state) +{ + request(url, HTTP_POST, new LLSDInjector(body), responder, headers, approved/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive, no_does_authentication, allow_compressed_reply, parent, new_parent_state, &gMainThreadEngine); } void LLHTTPClient::postXMLRPC(std::string const& url, XMLRPC_REQUEST xmlrpc_request, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug), EKeepAlive keepalive) { - request(url, HTTP_POST, new XMLRPCInjector(xmlrpc_request), responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive, does_authentication, allow_compressed_reply); + request(url, HTTP_POST, new XMLRPCInjector(xmlrpc_request), responder, headers, NULL/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive, does_authentication, allow_compressed_reply); } void LLHTTPClient::postXMLRPC(std::string const& url, char const* method, XMLRPC_VALUE value, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug), EKeepAlive keepalive) @@ -714,33 +720,33 @@ void LLHTTPClient::postXMLRPC(std::string const& url, char const* method, XMLRPC XMLRPC_RequestSetData(xmlrpc_request, value); // XMLRPCInjector takes ownership of xmlrpc_request and will free it when done. // LLURLRequest takes ownership of the XMLRPCInjector object and will free it when done. - request(url, HTTP_POST, new XMLRPCInjector(xmlrpc_request), responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive, does_authentication, no_allow_compressed_reply); + request(url, HTTP_POST, new XMLRPCInjector(xmlrpc_request), responder, headers, NULL/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive, does_authentication, no_allow_compressed_reply); } void LLHTTPClient::postRaw(std::string const& url, char const* data, S32 size, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug), EKeepAlive keepalive) { - request(url, HTTP_POST, new RawInjector(data, size), responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive); + request(url, HTTP_POST, new RawInjector(data, size), responder, headers, NULL/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive); } void LLHTTPClient::postFile(std::string const& url, std::string const& filename, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug), EKeepAlive keepalive) { - request(url, HTTP_POST, new FileInjector(filename), responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive); + request(url, HTTP_POST, new FileInjector(filename), responder, headers, NULL/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive); } void LLHTTPClient::postFile(std::string const& url, LLUUID const& uuid, LLAssetType::EType asset_type, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug), EKeepAlive keepalive) { - request(url, HTTP_POST, new VFileInjector(uuid, asset_type), responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive); + request(url, HTTP_POST, new VFileInjector(uuid, asset_type), responder, headers, NULL/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive); } // static void LLHTTPClient::del(std::string const& url, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug)) { - request(url, HTTP_DELETE, NULL, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); + request(url, HTTP_DELETE, NULL, responder, headers, NULL/*,*/ DEBUG_CURLIO_PARAM(debug)); } // static void LLHTTPClient::move(std::string const& url, std::string const& destination, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug)) { headers.addHeader("Destination", destination); - request(url, HTTP_MOVE, NULL, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); + request(url, HTTP_MOVE, NULL, responder, headers, NULL/*,*/ DEBUG_CURLIO_PARAM(debug)); } diff --git a/indra/llmessage/llhttpclient.h b/indra/llmessage/llhttpclient.h index 6dc10080c..af11a6687 100644 --- a/indra/llmessage/llhttpclient.h +++ b/indra/llmessage/llhttpclient.h @@ -38,6 +38,7 @@ #include "llassettype.h" #include "llhttpstatuscodes.h" #include "aihttpheaders.h" +#include "aicurlperservice.h" class LLUUID; class LLPumpIO; @@ -223,6 +224,9 @@ public: // If this function returns false then we generate an error when a redirect status (300..399) is received. virtual bool redirect_status_ok(void) const { return followRedir(); } + // Returns the capability type used by this responder. + virtual AICapabilityType capability_type(void) const { return cap_other; } + // Timeout policy to use. virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const = 0; @@ -426,7 +430,8 @@ public: ERequestAction method, Injector* body_injector, ResponderPtr responder, - AIHTTPHeaders& headers/*,*/ + AIHTTPHeaders& headers, + AIPerService::Approvement* approved/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug), EKeepAlive keepalive = keep_alive, EDoesAuthentication does_auth = no_does_authentication, @@ -465,6 +470,10 @@ public: static void post(std::string const& url, LLSD const& body, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive, AIStateMachine* parent = NULL, U32 new_parent_state = 0) { AIHTTPHeaders headers; post(url, body, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive, parent, new_parent_state); } + static void post_approved(std::string const& url, LLSD const& body, ResponderPtr responder, AIHTTPHeaders& headers, AIPerService::Approvement* approved/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive, AIStateMachine* parent = NULL, U32 new_parent_state = 0); + static void post_approved(std::string const& url, LLSD const& body, ResponderPtr responder, AIPerService::Approvement* approved/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive, AIStateMachine* parent = NULL, U32 new_parent_state = 0) + { AIHTTPHeaders headers; post_approved(url, body, responder, headers, approved/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive, parent, new_parent_state); } + /** Takes ownership of request and deletes it when sent */ static void postXMLRPC(std::string const& url, XMLRPC_REQUEST request, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive); static void postXMLRPC(std::string const& url, XMLRPC_REQUEST request, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive) diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index c8be0939b..b10b0c370 100644 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -75,10 +75,15 @@ std::string LLURLRequest::actionAsVerb(LLURLRequest::ERequestAction action) // This might throw AICurlNoEasyHandle. LLURLRequest::LLURLRequest(LLURLRequest::ERequestAction action, std::string const& url, Injector* body, - LLHTTPClient::ResponderPtr responder, AIHTTPHeaders& headers, bool keepalive, bool is_auth, bool compression) : + LLHTTPClient::ResponderPtr responder, AIHTTPHeaders& headers, AIPerService::Approvement* approved, + bool keepalive, bool is_auth, bool compression) : mAction(action), mURL(url), mKeepAlive(keepalive), mIsAuth(is_auth), mNoCompression(!compression), mBody(body), mResponder(responder), mHeaders(headers), mResponderNameCache(responder ? responder->getName() : "") { + if (approved) + { + AICurlEasyRequest_wat(*mCurlEasyRequest)->setApproved(approved); + } } void LLURLRequest::initialize_impl(void) diff --git a/indra/llmessage/llurlrequest.h b/indra/llmessage/llurlrequest.h index 1f9c09914..de92156c6 100644 --- a/indra/llmessage/llurlrequest.h +++ b/indra/llmessage/llurlrequest.h @@ -64,7 +64,10 @@ class LLURLRequest : public AICurlEasyRequestStateMachine { * @param action One of the ERequestAction enumerations. * @param url The url of the request. It should already be encoded. */ - LLURLRequest(ERequestAction action, std::string const& url, Injector* body, LLHTTPClient::ResponderPtr responder, AIHTTPHeaders& headers, bool keepalive, bool is_auth, bool no_compression); + LLURLRequest(ERequestAction action, std::string const& url, Injector* body, + LLHTTPClient::ResponderPtr responder, AIHTTPHeaders& headers, + AIPerService::Approvement* approved, + bool keepalive, bool is_auth, bool no_compression); /** * @brief Cached value of responder->getName() as passed to the constructor. diff --git a/indra/llmessage/llxfermanager.cpp b/indra/llmessage/llxfermanager.cpp index 00b9d8161..9dbb77492 100644 --- a/indra/llmessage/llxfermanager.cpp +++ b/indra/llmessage/llxfermanager.cpp @@ -261,7 +261,7 @@ U32 LLXferManager::numActiveListEntries(LLXfer *list_head) while (list_head) { - if ((list_head->mStatus == e_LL_XFER_IN_PROGRESS)) + if (list_head->mStatus == e_LL_XFER_IN_PROGRESS) { num_entries++; } diff --git a/indra/llplugin/slplugin/slplugin_info.plist b/indra/llplugin/slplugin/slplugin_info.plist old mode 100755 new mode 100644 diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp index 32b5d0994..7ab223f4d 100644 --- a/indra/llrender/llrender2dutils.cpp +++ b/indra/llrender/llrender2dutils.cpp @@ -450,6 +450,7 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex gGL.getTexUnit(0)->bind(image, true); gGL.color4fv(color.mV); + gGL.diffuseColor4fv(color.mV); //workaround: Intel HD 4000 const S32 NUM_VERTICES = 9 * 4; // 9 quads LLVector2 uv[NUM_VERTICES]; diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 629d35642..8b16476ed 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -2397,7 +2397,6 @@ void LLMenuGL::arrange( void ) // Scrolling support item_list_t::iterator first_visible_item_iter; - item_list_t::iterator first_hidden_item_iter = mItems.end(); //S32 height_before_first_visible_item = -1; //S32 visible_items_height = 0; //U32 scrollable_items_cnt = 0; @@ -2895,9 +2894,6 @@ LLMenuItemGL* LLMenuGL::highlightNextItem(LLMenuItemGL* cur_item, BOOL skip_disa next_item_iter = cur_item_iter; next_item_iter++; - // First visible item position in the items list - item_list_t::iterator first_visible_item_iter = std::find(mItems.begin(), mItems.end(), mFirstVisibleItem); - if (next_item_iter == mItems.end()) { next_item_iter = mItems.begin(); @@ -2973,9 +2969,6 @@ LLMenuItemGL* LLMenuGL::highlightPrevItem(LLMenuItemGL* cur_item, BOOL skip_disa prev_item_iter = cur_item_iter; prev_item_iter++; - // First visible item reverse position in the items list - item_list_t::reverse_iterator first_visible_item_iter = std::find(mItems.rbegin(), mItems.rend(), mFirstVisibleItem); - if (prev_item_iter == mItems.rend()) { prev_item_iter = mItems.rbegin(); diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp index 1b0c55fef..1cd91c3a4 100644 --- a/indra/llui/llmultisliderctrl.cpp +++ b/indra/llui/llmultisliderctrl.cpp @@ -280,8 +280,6 @@ void LLMultiSliderCtrl::updateText() void LLMultiSliderCtrl::onEditorCommit(const LLSD& value) { - llassert( caller == mEditor ); - BOOL success = FALSE; F32 val = mCurValue; F32 saved_val = mCurValue; diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 0fb44aa19..ed749aabb 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -944,10 +944,10 @@ const LLTextSegment* LLTextEditor::getPreviousSegment() const { // find segment index at character to left of cursor (or rightmost edge of selection) S32 idx = llmax(0, getSegmentIdxAtOffset(mCursorPos) - 1); - return idx >= 0 ? mSegments[idx] : NULL; + return idx >= 0 ? mSegments[idx] : LLTextSegmentPtr(); } -void LLTextEditor::getSelectedSegments(std::vector& segments) const +void LLTextEditor::getSelectedSegments(std::vector& segments) const { S32 left = hasSelection() ? llmin(mSelectionStart, mSelectionEnd) : mCursorPos; S32 right = hasSelection() ? llmax(mSelectionStart, mSelectionEnd) : mCursorPos; @@ -4512,13 +4512,13 @@ LLTextSegment* LLTextEditor::getSegmentAtLocalPos( S32 x, S32 y ) const // Find the cursor position at the requested local screen position S32 offset = getCursorPosFromLocalCoord( x, y, FALSE ); S32 idx = getSegmentIdxAtOffset(offset); - return idx >= 0 ? mSegments[idx] : NULL; + return idx >= 0 ? mSegments[idx] : LLTextSegmentPtr(); } const LLTextSegment* LLTextEditor::getSegmentAtOffset(S32 offset) const { S32 idx = getSegmentIdxAtOffset(offset); - return idx >= 0 ? mSegments[idx] : NULL; + return idx >= 0 ? mSegments[idx] : LLTextSegmentPtr(); } S32 LLTextEditor::getSegmentIdxAtOffset(S32 offset) const diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 0a0fc2bd5..91be64e65 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -293,7 +293,7 @@ public: const LLTextSegment* getCurrentSegment() const { return getSegmentAtOffset(mCursorPos); } const LLTextSegment* getPreviousSegment() const; - void getSelectedSegments(std::vector& segments) const; + void getSelectedSegments(std::vector& segments) const; static bool isPartOfWord(llwchar c) { return ( (c == '_') || (c == '\'') || LLStringOps::isAlnum((char)c)); } diff --git a/indra/llwindow/glh/glh_linear.h b/indra/llwindow/glh/glh_linear.h old mode 100755 new mode 100644 diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 792a7587f..73723c6f0 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -41,8 +41,8 @@ class LLPreeditor; class LLWindowCallbacks; -static const S32 MIN_WINDOW_WIDTH = 864; -static const S32 MIN_WINDOW_HEIGHT = 472; +const S32 MIN_WINDOW_WIDTH = 256; +const S32 MIN_WINDOW_HEIGHT = 256; // Refer to llwindow_test in test/common/llwindow for usage example diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 28611bdb6..8a0406c18 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -226,7 +226,6 @@ set(viewer_SOURCE_FILES llfloatermodeluploadbase.cpp llfloatermute.cpp llfloaternamedesc.cpp - llfloaternewim.cpp llfloaternotificationsconsole.cpp llfloaterobjectiminfo.cpp llfloateropenobject.cpp @@ -335,7 +334,6 @@ set(viewer_SOURCE_FILES llpanelavatar.cpp llpanelclassified.cpp llpanelcontents.cpp - llpaneldebug.cpp llpaneldirbrowser.cpp llpaneldirclassified.cpp llpaneldirevents.cpp @@ -725,7 +723,6 @@ set(viewer_HEADER_FILES llfloatermodeluploadbase.h llfloatermute.h llfloaternamedesc.h - llfloaternewim.h llfloaternotificationsconsole.h llfloaterobjectiminfo.h llfloateropenobject.h @@ -834,7 +831,6 @@ set(viewer_HEADER_FILES llpanelavatar.h llpanelclassified.h llpanelcontents.h - llpaneldebug.h llpaneldirbrowser.h llpaneldirclassified.h llpaneldirevents.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 61f8f21bc..377ee5cf1 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9,6 +9,17 @@ settings_rlv.xml + PhoenixIMAnnounceStealFocus + + Comment + Open a new IM tab when another person begins typing to you and announce that they are doing so. + Persist + 1 + Type + Boolean + Value + 0 + UseNewTargetOmegaCode Comment @@ -175,7 +186,10 @@ HTTPThrottleBandwidth Comment - The bandwidth (in kbit/s) to strive for + The bandwidth (in kbit/s) to strive for. Smaller values might reduce network + congestion (sim ping time, aka avatar responsiveness). Higher values might download + textures and the inventory faster, although in some cases a too high value might + actually slow that down due to serverside throttling. If unsure, choose 2000. Persist 1 Type @@ -648,6 +662,17 @@ Value 0 + LiruItalicizeActions + + Comment + When enabled, /me chat will be italicized. + Persist + 1 + Type + Boolean + Value + 0 + LiruFlyAfterTeleport Comment @@ -4338,6 +4363,17 @@ This should be as low as possible, but too low may break functionality Value 0.700 + ConsoleBottomOffset + + Comment + User definable offset between the bottom of the chat console and the bottom of the window; increase to move text in the console up + Persist + 1 + Type + S32 + Value + 0 + ConsoleBufferSize Comment @@ -4468,7 +4504,7 @@ This should be as low as possible, but too low may break functionality Type U32 Value - 16 + 8 CurlTimeoutDNSLookup @@ -6839,6 +6875,19 @@ This should be as low as possible, but too low may break functionality Value 0 + RadarUpdateEnabled + + Comment + When false, pauses the radar until further notice, good for banning someone who just left. + Persist + 0 + HideFromEditor + 1 + Type + Boolean + Value + 1 + RadarUpdateRate Comment @@ -15546,6 +15595,17 @@ This should be as low as possible, but too low may break functionality Value 0 + InstantMessagesFriendsOnly + + Comment + Only accept instant messages from residents on your friends list + Persist + 1 + Type + Boolean + Value + 0 + AutoDisengageMic Comment @@ -16393,6 +16453,17 @@ This should be as low as possible, but too low may break functionality Value 0 + ClearBeaconAfterTeleport + + Comment + Clear the red tracker beacon after you teleport + Persist + 1 + Type + Boolean + Value + 0 + LogTextureDownloadsToViewerLog Comment diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index b591a82db..d389c3b8d 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -199,9 +199,9 @@ - - - + + + AscentContactGroups Comment @@ -215,72 +215,7 @@ - AscentInstantMessageResponse - - Comment - Auto response to instant messages - Persist - 1 - Type - String - Value - This is an autoresponse! - - AscentInstantMessageResponseAnyone - - Comment - Whether to auto-respond to anyone - Persist - 1 - Type - Boolean - Value - 0 - - AscentInstantMessageResponseFriends - - Comment - Whether to auto-respond to non-friends - Persist - 1 - Type - Boolean - Value - 0 - - AscentInstantMessageResponseItem - - Comment - Whether to send a item along with the autoresponse - Persist - 1 - Type - Boolean - Value - 0 - - AscentInstantMessageResponseItemData - - Comment - UUID - Persist - 1 - Type - String - Value - - - AscentInstantMessageResponseMuted - - Comment - Whether to auto-respond to muted people - Persist - 1 - Type - Boolean - Value - 0 - + AscentInstantMessageResponseRepeat Comment @@ -292,21 +227,11 @@ Value 0 + AscentInstantMessageShowOnTyping Comment - Whether to perform the autorespond the moment they begin to type instead of waiting for a actual message - Persist - 1 - Type - Boolean - Value - 0 - - AscentInstantMessageShowResponded - - Comment - Whether to hide IMs entirely from those you have chosen to send autoresponses + Whether to perform the autorespond the moment they begin to type instead of waiting for an actual message Persist 1 Type @@ -314,6 +239,219 @@ Value 0 + + + AutoresponseAnyone + + Comment + Whether to send autoresponse to anyone who isn't muted (or just friends, if AutoresponseAnyoneFriendsOnly) + Persist + 1 + Type + Boolean + Value + 0 + + AutoresponseAnyoneFriendsOnly + + Comment + Whether to send AutoresponseAnyone to friends only + Persist + 1 + Type + Boolean + Value + 0 + + AutoresponseAnyoneItem + + Comment + Whether to send a item along with AutoresponseAnyone + Persist + 1 + Type + Boolean + Value + 0 + + AutoresponseAnyoneItemID + + Comment + UUID of item to send along with AutoresponseAnyone + Persist + 1 + Type + String + Value + + + AutoresponseAnyoneMessage + + Comment + Message to send as the autoresponse to AutoresponseAnyone + Persist + 1 + Type + String + Value + This is an autoresponse! + + AutoresponseAnyoneShow + + Comment + Whether to show that AutoresponseAnyone's were sent + Persist + 1 + Type + Boolean + Value + 0 + + AutoresponseNonFriends + + Comment + Whether to send autoresponse to nonfriends, separately using a different response + Persist + 1 + Type + Boolean + Value + 0 + + AutoresponseNonFriendsItem + + Comment + Whether to send a item along with AutoresponseNonFriends + Persist + 1 + Type + Boolean + Value + 0 + + AutoresponseNonFriendsItemID + + Comment + UUID of item to send along with AutoresponseNonFriends + Persist + 1 + Type + String + Value + + + AutoresponseNonFriendsMessage + + Comment + Message to send as the autoresponse to AutoresponseNonFriends + Persist + 1 + Type + String + Value + This is an autoresponse! + + AutoresponseNonFriendsShow + + Comment + Whether to show that AutoresponseNonFriends's were sent + Persist + 1 + Type + Boolean + Value + 0 + + AutoresponseMuted + + Comment + Whether to send autoresponse to muted people + Persist + 1 + Type + Boolean + Value + 0 + + AutoresponseMutedItem + + Comment + Whether to send a item along with AutoresponseMuted + Persist + 1 + Type + Boolean + Value + 0 + + AutoresponseMutedItemID + + Comment + UUID of item to send along with AutoresponseMuted + Persist + 1 + Type + String + Value + + + AutoresponseMutedMessage + + Comment + Message to send as the autoresponse to AutoresponseMuted + Persist + 1 + Type + String + Value + This is an autoresponse! + + BusyModeResponse + + Comment + Auto response to instant messages while in busy mode. + Persist + 1 + Type + String + Value + The Resident you messaged is in 'busy mode' which means they have requested not to be disturbed. Your message will still be shown in their IM panel for later viewing. + + BusyModeResponseItem + + Comment + Whether to send a item along with BusyModeResponse + Persist + 1 + Type + Boolean + Value + 0 + + BusyModeResponseItemID + + Comment + UUID of item to send along with BusyModeResponse + Persist + 1 + Type + String + Value + + + BusyModeResponseShow + + Comment + Whether to show that BusyModeResponses were sent + Persist + 1 + Type + Boolean + Value + 0 + + + EveryoneExport Comment @@ -336,84 +474,7 @@ Value 1 - BusyModeResponse - - Comment - Auto response to instant messages while in busy mode. - - AO.Settings - - Comment - List for animation overrider - Persist - 1 - Type - LLSD - Value - - - - - Responder.Settings - - Comment - New organization to the Auto-Respond settings for keeping clean - Persist - 1 - Type - LLSD - Value - - Message - This is an autoresponse! - - - - rkeastInventoryPreviousCount - - Comment - Used to keep track of the number of items in inventory when fetching for progress reasons. DO NOT EDIT. - Persist - 1 - Type - S32 - Value - -1 - - rkeastInventorySearchType - - Comment - Controls what type of inventory search we perform. - Persist - 0 - Type - U32 - Value - 0 - - rkeastInventoryPartialSearch - - Comment - Toggles whether to search using partial search filters on normal (name, desc, creator) searches. - Persist - 0 - Type - Boolean - Value - 0 - - BusyModeResponse - - Comment - Auto response to instant messages while in busy mode. - Persist - 1 - Type - String - Value - The Resident you messaged is in 'busy mode' which means they have requested not to be disturbed. Your message will still be shown in their IM panel for later viewing. - IMLogTimestamp Comment diff --git a/indra/newview/app_settings/settings_per_account_ascent.xml b/indra/newview/app_settings/settings_per_account_ascent.xml index 810586528..cd73b2f33 100644 --- a/indra/newview/app_settings/settings_per_account_ascent.xml +++ b/indra/newview/app_settings/settings_per_account_ascent.xml @@ -14,72 +14,7 @@ - AscentInstantMessageResponse - - Comment - Auto response to instant messages - Persist - 1 - Type - String - Value - This is an autoresponse! - - AscentInstantMessageResponseAnyone - - Comment - Whether to auto-respond to anyone - Persist - 1 - Type - Boolean - Value - 0 - - AscentInstantMessageResponseFriends - - Comment - Whether to auto-respond to non-friends - Persist - 1 - Type - Boolean - Value - 0 - - AscentInstantMessageResponseItem - - Comment - Whether to send a item along with the autoresponse - Persist - 1 - Type - Boolean - Value - 0 - - AscentInstantMessageResponseItemData - - Comment - UUID - Persist - 1 - Type - String - Value - - - AscentInstantMessageResponseMuted - - Comment - Whether to auto-respond to muted people - Persist - 1 - Type - Boolean - Value - 0 - + AscentInstantMessageResponseRepeat Comment @@ -91,21 +26,11 @@ Value 0 + AscentInstantMessageShowOnTyping Comment - Whether to perform the autorespond the moment they begin to type instead of waiting for a actual message - Persist - 1 - Type - Boolean - Value - 0 - - AscentInstantMessageShowResponded - - Comment - Whether to hide IMs entirely from those you have chosen to send autoresponses + Whether to perform the autorespond the moment they begin to type instead of waiting for an actual message Persist 1 Type @@ -113,5 +38,216 @@ Value 0 + + + AutoresponseAnyone + + Comment + Whether to send autoresponse to anyone who isn't muted (or just friends, if AutoresponseAnyoneFriendsOnly) + Persist + 1 + Type + Boolean + Value + 0 + + AutoresponseAnyoneFriendsOnly + + Comment + Whether to send AutoresponseAnyone to friends only + Persist + 1 + Type + Boolean + Value + 0 + + AutoresponseAnyoneItem + + Comment + Whether to send a item along with AutoresponseAnyone + Persist + 1 + Type + Boolean + Value + 0 + + AutoresponseAnyoneItemID + + Comment + UUID of item to send along with AutoresponseAnyone + Persist + 1 + Type + String + Value + + + AutoresponseAnyoneMessage + + Comment + Message to send as the autoresponse to AutoresponseAnyone + Persist + 1 + Type + String + Value + This is an autoresponse! + + AutoresponseAnyoneShow + + Comment + Whether to show that AutoresponseAnyone's were sent + Persist + 1 + Type + Boolean + Value + 0 + + AutoresponseNonFriends + + Comment + Whether to send autoresponse to nonfriends, separately using a different response + Persist + 1 + Type + Boolean + Value + 0 + + AutoresponseNonFriendsItem + + Comment + Whether to send a item along with AutoresponseNonFriends + Persist + 1 + Type + Boolean + Value + 0 + + AutoresponseNonFriendsItemID + + Comment + UUID of item to send along with AutoresponseNonFriends + Persist + 1 + Type + String + Value + + + AutoresponseNonFriendsMessage + + Comment + Message to send as the autoresponse to AutoresponseNonFriends + Persist + 1 + Type + String + Value + This is an autoresponse! + + AutoresponseNonFriendsShow + + Comment + Whether to show that AutoresponseNonFriends's were sent + Persist + 1 + Type + Boolean + Value + 0 + + AutoresponseMuted + + Comment + Whether to send autoresponse to muted people + Persist + 1 + Type + Boolean + Value + 0 + + AutoresponseMutedItem + + Comment + Whether to send a item along with AutoresponseMuted + Persist + 1 + Type + Boolean + Value + 0 + + AutoresponseMutedItemID + + Comment + UUID of item to send along with AutoresponseMuted + Persist + 1 + Type + String + Value + + + AutoresponseMutedMessage + + Comment + Message to send as the autoresponse to AutoresponseMuted + Persist + 1 + Type + String + Value + This is an autoresponse! + + BusyModeResponse + + Comment + Auto response to instant messages while in busy mode. + Persist + 1 + Type + String + Value + The Resident you messaged is in 'busy mode' which means they have requested not to be disturbed. Your message will still be shown in their IM panel for later viewing. + + BusyModeResponseItem + + Comment + Whether to send a item along with BusyModeResponse + Persist + 1 + Type + Boolean + Value + 0 + + BusyModeResponseItemID + + Comment + UUID of item to send along with BusyModeResponse + Persist + 1 + Type + String + Value + + + BusyModeResponseShow + + Comment + Whether to show that BusyModeResponses were sent + Persist + 1 + Type + Boolean + Value + 0 + - \ No newline at end of file + diff --git a/indra/newview/app_settings/shaders/class1/interface/solidcolorIntelV.glsl b/indra/newview/app_settings/shaders/class1/interface/solidcolorIntelV.glsl new file mode 100644 index 000000000..cdafbd3e3 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/solidcolorIntelV.glsl @@ -0,0 +1,42 @@ +/** + * @file solidcolorV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +uniform mat4 modelview_projection_matrix; + +uniform vec4 color; + +ATTRIBUTE vec3 position; +ATTRIBUTE vec2 texcoord0; + +VARYING vec4 vertex_color; +VARYING vec2 vary_texcoord0; + +void main() +{ + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + vertex_color = color; + vary_texcoord0 = texcoord0; +} + diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl old mode 100755 new mode 100644 diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl old mode 100755 new mode 100644 diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl old mode 100755 new mode 100644 diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl old mode 100755 new mode 100644 diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl old mode 100755 new mode 100644 diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl old mode 100755 new mode 100644 diff --git a/indra/newview/ascentprefschat.cpp b/indra/newview/ascentprefschat.cpp index f24724279..cf60bb715 100644 --- a/indra/newview/ascentprefschat.cpp +++ b/indra/newview/ascentprefschat.cpp @@ -46,8 +46,6 @@ #include "llstartup.h" -LLDropTarget* mObjectDropTarget; -LLPrefsAscentChat* LLPrefsAscentChat::sInst; LLPrefsAscentChat::LLPrefsAscentChat() { @@ -62,44 +60,31 @@ LLPrefsAscentChat::LLPrefsAscentChat() childSetCommitCallback("time_format_combobox", onCommitTimeDate, this); childSetCommitCallback("date_format_combobox", onCommitTimeDate, this); - childSetCommitCallback("AscentInstantMessageResponseAnyone", onCommitAutoResponse, this); - childSetCommitCallback("AscentInstantMessageResponseFriends", onCommitAutoResponse, this); - childSetCommitCallback("AscentInstantMessageResponseMuted", onCommitAutoResponse, this); - childSetCommitCallback("AscentInstantMessageShowOnTyping", onCommitAutoResponse, this); - childSetCommitCallback("AscentInstantMessageShowResponded", onCommitAutoResponse, this); - childSetCommitCallback("AscentInstantMessageResponseRepeat", onCommitAutoResponse, this); - childSetCommitCallback("AscentInstantMessageResponseItem", onCommitAutoResponse, this); - - if(sInst)delete sInst; sInst = this; - LLView* target_view = getChild("im_give_drop_target_rect"); - if (target_view) + bool started = (LLStartUp::getStartupState() == STATE_STARTED); + if (!started) // Disable autoresponse when not logged in { - const std::string drop="drop target"; - if (mObjectDropTarget) delete mObjectDropTarget; - mObjectDropTarget = new LLDropTarget(drop, target_view->getRect(), SinguIMResponseItemDrop);//, mAvatarID); - addChild(mObjectDropTarget); + LLView* autoresponse = getChildView("Autoresponse"); + autoresponse->setAllChildrenEnabled(false); + autoresponse->setToolTip(LLTrans::getString("NotLoggedIn")); } - bool started = LLStartUp::getStartupState() == STATE_STARTED; - if (started) - { - LLUUID itemid = (LLUUID)gSavedPerAccountSettings.getString("AscentInstantMessageResponseItemData"); - LLViewerInventoryItem* item = gInventory.getItem(itemid); - - if (item) - { - LLStringUtil::format_map_t args; - args["[ITEM]"] = item->getName(); - childSetValue("im_give_disp_rect_txt", LLTrans::getString("CurrentlySetTo", args)); - } - else if (itemid.isNull()) - childSetValue("im_give_disp_rect_txt", LLTrans::getString("CurrentlyNotSet")); - else - childSetValue("im_give_disp_rect_txt", LLTrans::getString("CurrentlySetToAnItemNotOnThisAccount")); - } - else childSetValue("im_give_disp_rect_txt", LLTrans::getString("NotLoggedIn")); - - childSetCommitCallback("im_response", onCommitAutoResponse, this); + // Saved per account settings aren't detected by control_name, therefore autoresponse controls get their values here and have them saved during apply. + childSetValue("AscentInstantMessageResponseRepeat", gSavedPerAccountSettings.getBOOL("AscentInstantMessageResponseRepeat")); + childSetValue("AutoresponseAnyone", gSavedPerAccountSettings.getBOOL("AutoresponseAnyone")); + childSetValue("AutoresponseAnyoneFriendsOnly", gSavedPerAccountSettings.getBOOL("AutoresponseAnyoneFriendsOnly")); + childSetValue("AutoresponseAnyoneItem", gSavedPerAccountSettings.getBOOL("AutoresponseAnyoneItem")); + childSetValue("AutoresponseAnyoneMessage", gSavedPerAccountSettings.getString("AutoresponseAnyoneMessage")); + childSetValue("AutoresponseAnyoneShow", gSavedPerAccountSettings.getBOOL("AutoresponseAnyoneShow")); + childSetValue("AutoresponseNonFriends", gSavedPerAccountSettings.getBOOL("AutoresponseNonFriends")); + childSetValue("AutoresponseNonFriendsItem", gSavedPerAccountSettings.getBOOL("AutoresponseNonFriendsItem")); + childSetValue("AutoresponseNonFriendsMessage", gSavedPerAccountSettings.getString("AutoresponseNonFriendsMessage")); + childSetValue("AutoresponseNonFriendsShow", gSavedPerAccountSettings.getBOOL("AutoresponseNonFriendsShow")); + childSetValue("AutoresponseMuted", gSavedPerAccountSettings.getBOOL("AutoresponseMuted")); + childSetValue("AutoresponseMutedItem", gSavedPerAccountSettings.getBOOL("AutoresponseMutedItem")); + childSetValue("AutoresponseMutedMessage", gSavedPerAccountSettings.getString("AutoresponseMutedMessage")); + childSetValue("BusyModeResponse", gSavedPerAccountSettings.getString("BusyModeResponse")); + childSetValue("BusyModeResponseItem", gSavedPerAccountSettings.getBOOL("BusyModeResponseItem")); + childSetValue("BusyModeResponseShow", gSavedPerAccountSettings.getBOOL("BusyModeResponseShow")); childSetEnabled("reset_antispam", started); childSetCommitCallback("reset_antispam", onCommitResetAS, this); @@ -122,8 +107,6 @@ LLPrefsAscentChat::LLPrefsAscentChat() LLPrefsAscentChat::~LLPrefsAscentChat() { - sInst=NULL; - delete mObjectDropTarget; mObjectDropTarget=NULL; } //static @@ -231,30 +214,6 @@ void LLPrefsAscentChat::onCommitTimeDate(LLUICtrl* ctrl, void* userdata) gSavedSettings.setString("TimestampFormat", timestamp); } -//static -void LLPrefsAscentChat::onCommitAutoResponse(LLUICtrl* ctrl, void* user_data) -{ - LLPrefsAscentChat* self = (LLPrefsAscentChat*)user_data; - - gSavedPerAccountSettings.setBOOL("AscentInstantMessageResponseAnyone", self->childGetValue("AscentInstantMessageResponseAnyone")); - gSavedPerAccountSettings.setBOOL("AscentInstantMessageResponseFriends", self->childGetValue("AscentInstantMessageResponseFriends")); - gSavedPerAccountSettings.setBOOL("AscentInstantMessageResponseMuted", self->childGetValue("AscentInstantMessageResponseMuted")); - gSavedPerAccountSettings.setBOOL("AscentInstantMessageShowOnTyping", self->childGetValue("AscentInstantMessageShowOnTyping")); - gSavedPerAccountSettings.setBOOL("AscentInstantMessageShowResponded", self->childGetValue("AscentInstantMessageShowResponded")); - gSavedPerAccountSettings.setBOOL("AscentInstantMessageResponseRepeat", self->childGetValue("AscentInstantMessageResponseRepeat")); - gSavedPerAccountSettings.setBOOL("AscentInstantMessageResponseItem", self->childGetValue("AscentInstantMessageResponseItem")); - gSavedPerAccountSettings.setString("AscentInstantMessageResponse", self->childGetValue("im_response")); -} - -//static -void LLPrefsAscentChat::SinguIMResponseItemDrop(LLViewerInventoryItem* item) -{ - gSavedPerAccountSettings.setString("AscentInstantMessageResponseItemData", item->getUUID().asString()); - LLStringUtil::format_map_t args; - args["[ITEM]"] = item->getName(); - sInst->childSetValue("im_give_disp_rect_txt", LLTrans::getString("CurrentlySetTo", args)); -} - //static void LLPrefsAscentChat::onCommitResetAS(LLUICtrl*, void*) { @@ -327,6 +286,7 @@ void LLPrefsAscentChat::refreshValues() //Chat/IM ----------------------------------------------------------------------------- mIMAnnounceIncoming = gSavedSettings.getBOOL("AscentInstantMessageAnnounceIncoming"); mHideTypingNotification = gSavedSettings.getBOOL("AscentHideTypingNotification"); + mInstantMessagesFriendsOnly = gSavedSettings.getBOOL("InstantMessagesFriendsOnly"); mShowGroupNameInChatIM = gSavedSettings.getBOOL("OptionShowGroupNameInChatIM"); mShowDisplayNameChanges = gSavedSettings.getBOOL("ShowDisplayNameChanges"); mUseTypingBubbles = gSavedSettings.getBOOL("UseTypingBubbles"); @@ -365,24 +325,40 @@ void LLPrefsAscentChat::refreshValues() tempTimeFormat = mTimeFormat; tempDateFormat = mDateFormat; - mIMResponseAnyone = gSavedPerAccountSettings.getBOOL("AscentInstantMessageResponseAnyone"); - mIMResponseFriends = gSavedPerAccountSettings.getBOOL("AscentInstantMessageResponseFriends"); - mIMResponseMuted = gSavedPerAccountSettings.getBOOL("AscentInstantMessageResponseMuted"); - mIMShowOnTyping = gSavedPerAccountSettings.getBOOL("AscentInstantMessageShowOnTyping"); - mIMShowResponded = gSavedPerAccountSettings.getBOOL("AscentInstantMessageShowResponded"); - mIMResponseRepeat = gSavedPerAccountSettings.getBOOL("AscentInstantMessageResponseRepeat"); - mIMResponseItem = gSavedPerAccountSettings.getBOOL("AscentInstantMessageResponseItem"); - mIMResponseText = gSavedPerAccountSettings.getString("AscentInstantMessageResponse"); - //Chat UI ----------------------------------------------------------------------------- mWoLfVerticalIMTabs = gSavedSettings.getBOOL("WoLfVerticalIMTabs"); mOtherChatsTornOff = gSavedSettings.getBOOL("OtherChatsTornOff"); + mIMAnnounceStealFocus = gSavedSettings.getBOOL("PhoenixIMAnnounceStealFocus"); mShowLocalChatFloaterBar = gSavedSettings.getBOOL("ShowLocalChatFloaterBar"); mHorizButt = gSavedSettings.getBOOL("ContactsUseHorizontalButtons"); mOneLineIMButt = gSavedSettings.getBOOL("UseConciseIMButtons"); mOneLineGroupButt = gSavedSettings.getBOOL("UseConciseGroupChatButtons"); mOneLineConfButt = gSavedSettings.getBOOL("UseConciseConferenceButtons"); mOnlyComm = gSavedSettings.getBOOL("CommunicateSpecificShortcut"); + mItalicizeActions = gSavedSettings.getBOOL("LiruItalicizeActions"); + + //Autoresponse ------------------------------------------------------------------------ + mIMResponseAnyoneItemID = gSavedPerAccountSettings.getString("AutoresponseAnyoneItemID"); + mIMResponseNonFriendsItemID = gSavedPerAccountSettings.getString("AutoresponseNonFriendsItemID"); + mIMResponseMutedItemID = gSavedPerAccountSettings.getString("AutoresponseMutedItemID"); + mIMResponseBusyItemID = gSavedPerAccountSettings.getString("BusyModeResponseItemID"); + + gSavedPerAccountSettings.setBOOL("AscentInstantMessageResponseRepeat", childGetValue("AscentInstantMessageResponseRepeat")); + gSavedPerAccountSettings.setBOOL("AutoresponseAnyone", childGetValue("AutoresponseAnyone")); + gSavedPerAccountSettings.setBOOL("AutoresponseAnyoneFriendsOnly", childGetValue("AutoresponseAnyoneFriendsOnly")); + gSavedPerAccountSettings.setBOOL("AutoresponseAnyoneItem", childGetValue("AutoresponseAnyoneItem")); + gSavedPerAccountSettings.setString("AutoresponseAnyoneMessage", childGetValue("AutoresponseAnyoneMessage")); + gSavedPerAccountSettings.setBOOL("AutoresponseAnyoneShow", childGetValue("AutoresponseAnyoneShow")); + gSavedPerAccountSettings.setBOOL("AutoresponseNonFriends", childGetValue("AutoresponseNonFriends")); + gSavedPerAccountSettings.setBOOL("AutoresponseNonFriendsItem", childGetValue("AutoresponseNonFriendsItem")); + gSavedPerAccountSettings.setString("AutoresponseNonFriendsMessage", childGetValue("AutoresponseNonFriendsMessage")); + gSavedPerAccountSettings.setBOOL("AutoresponseNonFriendsShow", childGetValue("AutoresponseNonFriendsShow")); + gSavedPerAccountSettings.setBOOL("AutoresponseMuted", childGetValue("AutoresponseMuted")); + gSavedPerAccountSettings.setBOOL("AutoresponseMutedItem", childGetValue("AutoresponseMutedItem")); + gSavedPerAccountSettings.setString("AutoresponseMutedMessage", childGetValue("AutoresponseMutedMessage")); + gSavedPerAccountSettings.setString("BusyModeResponse", childGetValue("BusyModeResponse")); + gSavedPerAccountSettings.setBOOL("BusyModeResponseItem", childGetValue("BusyModeResponseItem")); + gSavedPerAccountSettings.setBOOL("BusyModeResponseShow", childGetValue("BusyModeResponseShow")); //Spam -------------------------------------------------------------------------------- mEnableAS = gSavedSettings.getBOOL("AntiSpamEnabled"); @@ -434,19 +410,6 @@ void LLPrefsAscentChat::refresh() combo->setCurrentByIndex(mDateFormat); } - childSetValue("AscentInstantMessageResponseAnyone", mIMResponseAnyone); - childSetValue("AscentInstantMessageResponseFriends", mIMResponseFriends); - childSetValue("AscentInstantMessageResponseMuted", mIMResponseMuted); - childSetValue("AscentInstantMessageShowOnTyping", mIMShowOnTyping); - childSetValue("AscentInstantMessageShowResponded", mIMShowResponded); - childSetValue("AscentInstantMessageResponseRepeat", mIMResponseRepeat); - childSetValue("AscentInstantMessageResponseItem", mIMResponseItem); - - LLWString auto_response = utf8str_to_wstring( gSavedPerAccountSettings.getString("AscentInstantMessageResponse") ); - LLWStringUtil::replaceChar(auto_response, '^', '\n'); - LLWStringUtil::replaceChar(auto_response, '%', ' '); - childSetText("im_response", wstring_to_utf8str(auto_response)); - //Antispam ------------------------------------------------------------------------ // sensitivity tuners childSetEnabled("spammsg_checkbox", mEnableAS); @@ -544,6 +507,7 @@ void LLPrefsAscentChat::cancel() //Chat/IM ----------------------------------------------------------------------------- gSavedSettings.setBOOL("AscentInstantMessageAnnounceIncoming", mIMAnnounceIncoming); gSavedSettings.setBOOL("AscentHideTypingNotification", mHideTypingNotification); + gSavedSettings.setBOOL("InstantMessagesFriendsOnly", mInstantMessagesFriendsOnly); gSavedSettings.setBOOL("OptionShowGroupNameInChatIM", mShowGroupNameInChatIM); gSavedSettings.setBOOL("ShowDisplayNameChanges", mShowDisplayNameChanges); gSavedSettings.setBOOL("UseTypingBubbles", mUseTypingBubbles); @@ -595,24 +559,23 @@ void LLPrefsAscentChat::cancel() gSavedSettings.setString("LongTimeFormat", long_time); gSavedSettings.setString("TimestampFormat", timestamp); - gSavedPerAccountSettings.setBOOL("AscentInstantMessageResponseAnyone", mIMResponseAnyone); - gSavedPerAccountSettings.setBOOL("AscentInstantMessageResponseFriends", mIMResponseFriends); - gSavedPerAccountSettings.setBOOL("AscentInstantMessageResponseMuted", mIMResponseMuted); - gSavedPerAccountSettings.setBOOL("AscentInstantMessageShowOnTyping", mIMShowOnTyping); - gSavedPerAccountSettings.setBOOL("AscentInstantMessageShowResponded", mIMShowResponded); - gSavedPerAccountSettings.setBOOL("AscentInstantMessageResponseRepeat", mIMResponseRepeat); - gSavedPerAccountSettings.setBOOL("AscentInstantMessageResponseItem", mIMResponseItem); - gSavedPerAccountSettings.setString("AscentInstantMessageResponse", mIMResponseText); - //Chat UI ----------------------------------------------------------------------------- gSavedSettings.setBOOL("WoLfVerticalIMTabs", mWoLfVerticalIMTabs); gSavedSettings.setBOOL("OtherChatsTornOff", mOtherChatsTornOff); + gSavedSettings.setBOOL("PhoenixIMAnnounceStealFocus", mIMAnnounceStealFocus); gSavedSettings.setBOOL("ShowLocalChatFloaterBar", mShowLocalChatFloaterBar); gSavedSettings.setBOOL("ContactsUseHorizontalButtons", mHorizButt); gSavedSettings.setBOOL("UseConciseIMButtons", mOneLineIMButt); gSavedSettings.setBOOL("UseConciseGroupChatButtons", mOneLineGroupButt); gSavedSettings.setBOOL("UseConciseConferenceButtons", mOneLineConfButt); gSavedSettings.setBOOL("CommunicateSpecificShortcut", mOnlyComm); + gSavedSettings.setBOOL("LiruItalicizeActions", mItalicizeActions); + + //Autoresponse ------------------------------------------------------------------------ + gSavedPerAccountSettings.setString("AutoresponseAnyoneItemID", mIMResponseAnyoneItemID); + gSavedPerAccountSettings.setString("AutoresponseNonFriendsItemID", mIMResponseNonFriendsItemID); + gSavedPerAccountSettings.setString("AutoresponseMutedItemID", mIMResponseMutedItemID); + gSavedPerAccountSettings.setString("BusyModeResponseItemID", mIMResponseBusyItemID); //Spam -------------------------------------------------------------------------------- gSavedSettings.setBOOL("AntiSpamEnabled", mEnableAS); @@ -632,7 +595,7 @@ void LLPrefsAscentChat::cancel() gSavedSettings.setU32("_NACL_AntiSpamSoundMulti", mSoundMulti); gSavedSettings.setU32("_NACL_AntiSpamNewlines", mNewLines); gSavedSettings.setU32("_NACL_AntiSpamSoundPreloadMulti", mPreloadMulti); - gSavedSettings.setBOOL("EnableGestureSounds", mEnableGestureSounds); + gSavedSettings.setBOOL("EnableGestureSounds", mEnableGestureSounds); //Text Options ------------------------------------------------------------------------ gSavedSettings.setBOOL("SpellDisplay", mSpellDisplay); @@ -649,8 +612,6 @@ void LLPrefsAscentChat::cancel() // Update local copy so cancel has no effect void LLPrefsAscentChat::apply() { - gSavedPerAccountSettings.setString("AscentInstantMessageResponse", childGetValue("im_response")); - refreshValues(); refresh(); } diff --git a/indra/newview/ascentprefschat.h b/indra/newview/ascentprefschat.h index 04fa1a69c..aa0b91d9d 100644 --- a/indra/newview/ascentprefschat.h +++ b/indra/newview/ascentprefschat.h @@ -34,8 +34,6 @@ #include "llpanel.h" -#include "lldroptarget.h" - class LLPrefsAscentChat : public LLPanel { @@ -55,7 +53,6 @@ protected: static void onSpellEditCustom(void* data); static void onSpellBaseComboBoxCommit(LLUICtrl* ctrl, void* userdata); static void onCommitTimeDate(LLUICtrl* ctrl, void *userdata); - static void onCommitAutoResponse(LLUICtrl* ctrl, void* user_data); static void onCommitResetAS(LLUICtrl*,void*); static void onCommitEnableAS(LLUICtrl*, void*); static void onCommitDialogBlock(LLUICtrl*, void*); @@ -64,6 +61,7 @@ protected: //Chat/IM ----------------------------------------------------------------------------- BOOL mIMAnnounceIncoming; BOOL mHideTypingNotification; + bool mInstantMessagesFriendsOnly; BOOL mShowGroupNameInChatIM; bool mShowDisplayNameChanges; bool mUseTypingBubbles; @@ -79,24 +77,23 @@ protected: BOOL mSecondsInChatAndIMs; BOOL mSecondsInLog; - BOOL mIMResponseAnyone; - BOOL mIMResponseFriends; - BOOL mIMResponseMuted; - BOOL mIMShowOnTyping; - BOOL mIMShowResponded; - BOOL mIMResponseRepeat; - BOOL mIMResponseItem; - std::string mIMResponseText; - //Chat UI ----------------------------------------------------------------------------- bool mWoLfVerticalIMTabs; bool mOtherChatsTornOff; + bool mIMAnnounceStealFocus; bool mShowLocalChatFloaterBar; bool mHorizButt; bool mOneLineIMButt; bool mOneLineGroupButt; bool mOneLineConfButt; bool mOnlyComm; + bool mItalicizeActions; + + //Autoresponse ------------------------------------------------------------------------ + std::string mIMResponseAnyoneItemID; + std::string mIMResponseNonFriendsItemID; + std::string mIMResponseMutedItemID; + std::string mIMResponseBusyItemID; //Spam -------------------------------------------------------------------------------- BOOL mEnableAS; @@ -128,9 +125,6 @@ protected: LLColor4 mKeywordsColor; BOOL mKeywordsPlaySound; LLUUID mKeywordsSound; -private: - static LLPrefsAscentChat* sInst; - static void SinguIMResponseItemDrop(LLViewerInventoryItem* item); }; #endif diff --git a/indra/newview/ascentprefssys.cpp b/indra/newview/ascentprefssys.cpp index a0477fdda..fc2bc1a62 100644 --- a/indra/newview/ascentprefssys.cpp +++ b/indra/newview/ascentprefssys.cpp @@ -44,12 +44,8 @@ #include "lltexturectrl.h" #include "lluictrlfactory.h" #include "llviewercontrol.h" -#include "llstartup.h" #include "lltrans.h" -LLDropTarget* mBuildDropTarget; -LLPrefsAscentSys* LLPrefsAscentSys::sInst; - LLPrefsAscentSys::LLPrefsAscentSys() { LLUICtrlFactory::getInstance()->buildPanel(this, "panel_preferences_ascent_system.xml"); @@ -91,42 +87,12 @@ LLPrefsAscentSys::LLPrefsAscentSys() getChild("texture control")->setDefaultImageAssetID(LLUUID(gSavedSettings.getString("EmeraldBuildPrefs_Texture"))); childSetCommitCallback("texture control", onCommitTexturePicker, this); - if(sInst)delete sInst; sInst = this; - LLView* target_view = getChild("build_item_drop_target_rect"); - if (target_view) - { - const std::string drop="drop target"; - if (mBuildDropTarget) delete mBuildDropTarget; - mBuildDropTarget = new LLDropTarget(drop, target_view->getRect(), SinguBuildItemDrop);//, mAvatarID); - addChild(mBuildDropTarget); - } - - if (LLStartUp::getStartupState() == STATE_STARTED) - { - LLUUID itemid = (LLUUID)gSavedPerAccountSettings.getString("EmeraldBuildPrefs_Item"); - LLViewerInventoryItem* item = gInventory.getItem(itemid); - - if (item) - { - LLStringUtil::format_map_t args; - args["[ITEM]"] = item->getName(); - childSetValue("build_item_add_disp_rect_txt", LLTrans::getString("CurrentlySetTo", args)); - } - else if (itemid.isNull()) - childSetValue("build_item_add_disp_rect_txt", LLTrans::getString("CurrentlyNotSet")); - else - childSetValue("build_item_add_disp_rect_txt", LLTrans::getString("CurrentlySetToAnItemNotOnThisAccount")); - } - else childSetValue("build_item_add_disp_rect_txt", LLTrans::getString("NotLoggedIn")); - refreshValues(); refresh(); } LLPrefsAscentSys::~LLPrefsAscentSys() { - sInst=NULL; - delete mBuildDropTarget; mBuildDropTarget=NULL; } //static @@ -253,21 +219,13 @@ void LLPrefsAscentSys::onCommitTexturePicker(LLUICtrl* ctrl, void* userdata) if(image_ctrl) gSavedSettings.setString("EmeraldBuildPrefs_Texture", image_ctrl->getImageAssetID().asString()); } -//static -void LLPrefsAscentSys::SinguBuildItemDrop(LLViewerInventoryItem* item) -{ - gSavedPerAccountSettings.setString("EmeraldBuildPrefs_Item", item->getUUID().asString()); - LLStringUtil::format_map_t args; - args["[ITEM]"] = item->getName(); - sInst->childSetValue("build_item_add_disp_rect_txt", LLTrans::getString("CurrentlySetTo", args)); -} - void LLPrefsAscentSys::refreshValues() { //General ----------------------------------------------------------------------------- mDoubleClickTeleport = gSavedSettings.getBOOL("DoubleClickTeleport"); mResetCameraAfterTP = gSavedSettings.getBOOL("OptionRotateCamAfterLocalTP"); mOffsetTPByUserHeight = gSavedSettings.getBOOL("OptionOffsetTPByAgentHeight"); + mClearBeaconAfterTeleport = gSavedSettings.getBOOL("ClearBeaconAfterTeleport"); mLiruFlyAfterTeleport = gSavedSettings.getBOOL("LiruFlyAfterTeleport"); mLiruContinueFlying = gSavedSettings.getBOOL("LiruContinueFlyingOnUnsit"); mPreviewAnimInWorld = gSavedSettings.getBOOL("PreviewAnimInWorld"); @@ -323,6 +281,7 @@ void LLPrefsAscentSys::refreshValues() mColor = gSavedSettings.getColor4("EmeraldBuildPrefs_Color"); mFullBright = gSavedSettings.getBOOL("EmeraldBuildPrefs_FullBright"); mGlow = gSavedSettings.getF32("EmeraldBuildPrefs_Glow"); + mItem = gSavedPerAccountSettings.getString("EmeraldBuildPrefs_Item"); mMaterial = gSavedSettings.getString("BuildPrefs_Material"); mNextCopy = gSavedSettings.getBOOL("NextOwnerCopy"); mNextMod = gSavedSettings.getBOOL("NextOwnerModify"); @@ -420,6 +379,7 @@ void LLPrefsAscentSys::cancel() gSavedSettings.setBOOL("DoubleClickTeleport", mDoubleClickTeleport); gSavedSettings.setBOOL("OptionRotateCamAfterLocalTP", mResetCameraAfterTP); gSavedSettings.setBOOL("OptionOffsetTPByAgentHeight", mOffsetTPByUserHeight); + gSavedSettings.setBOOL("ClearBeaconAfterTeleport", mClearBeaconAfterTeleport); gSavedSettings.setBOOL("LiruFlyAfterTeleport", mLiruFlyAfterTeleport); gSavedSettings.setBOOL("LiruContinueFlyingOnUnsit", mLiruContinueFlying); gSavedSettings.setBOOL("PreviewAnimInWorld", mPreviewAnimInWorld); @@ -474,6 +434,7 @@ void LLPrefsAscentSys::cancel() gSavedSettings.setColor4("EmeraldBuildPrefs_Color", mColor); gSavedSettings.setBOOL("EmeraldBuildPrefs_FullBright", mFullBright); gSavedSettings.setF32("EmeraldBuildPrefs_Glow", mGlow); + gSavedPerAccountSettings.setString("EmeraldBuildPrefs_Item", mItem); gSavedSettings.setString("BuildPrefs_Material", mMaterial); gSavedSettings.setBOOL("NextOwnerCopy", mNextCopy); gSavedSettings.setBOOL("NextOwnerModify", mNextMod); diff --git a/indra/newview/ascentprefssys.h b/indra/newview/ascentprefssys.h index 60cf4f4de..2ecacb43e 100644 --- a/indra/newview/ascentprefssys.h +++ b/indra/newview/ascentprefssys.h @@ -34,8 +34,6 @@ #include "llpanel.h" -#include "lldroptarget.h" - class LLPrefsAscentSys : public LLPanel { @@ -58,6 +56,7 @@ protected: BOOL mDoubleClickTeleport; BOOL mResetCameraAfterTP; BOOL mOffsetTPByUserHeight; + bool mClearBeaconAfterTeleport; bool mLiruFlyAfterTeleport; bool mLiruContinueFlying; BOOL mPreviewAnimInWorld; @@ -107,11 +106,13 @@ protected: bool mDisableClickSitOtherOwner; BOOL mDisplayScriptJumps; F32 mNumScriptDiff; + //Build ------------------------------------------------------------------------------- F32 mAlpha; LLColor4 mColor; BOOL mFullBright; F32 mGlow; + std::string mItem; std::string mMaterial; BOOL mNextCopy; BOOL mNextMod; @@ -124,9 +125,6 @@ protected: F32 mXsize; F32 mYsize; F32 mZsize; -private: - static LLPrefsAscentSys* sInst; - static void SinguBuildItemDrop(LLViewerInventoryItem* item); }; #endif diff --git a/indra/newview/floaterao.cpp b/indra/newview/floaterao.cpp index b7ab4994e..c9386d95a 100644 --- a/indra/newview/floaterao.cpp +++ b/indra/newview/floaterao.cpp @@ -136,73 +136,6 @@ BOOL AOInvTimer::tick() } return FALSE; } -// NC DROP ------------------------------------------------------- - -class AONoteCardDropTarget : public LLView -{ -public: - AONoteCardDropTarget(const std::string& name, const LLRect& rect, void (*callback)(LLViewerInventoryItem*)); - ~AONoteCardDropTarget(); - - void doDrop(EDragAndDropType cargo_type, void* cargo_data); - - // - // LLView functionality - virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg); -protected: - void (*mDownCallback)(LLViewerInventoryItem*); -}; - - -AONoteCardDropTarget::AONoteCardDropTarget(const std::string& name, const LLRect& rect, - void (*callback)(LLViewerInventoryItem*)) : - LLView(name, rect, NOT_MOUSE_OPAQUE, FOLLOWS_ALL), - mDownCallback(callback) -{ -} - -AONoteCardDropTarget::~AONoteCardDropTarget() -{ -} - -void AONoteCardDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data) -{ -// llinfos << "AONoteCardDropTarget::doDrop()" << llendl; -} - -BOOL AONoteCardDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg) -{ - BOOL handled = FALSE; - if(getParent()) - { - handled = TRUE; - LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data; - if(gInventory.getItem(inv_item->getUUID())) - { - *accept = ACCEPT_YES_COPY_SINGLE; - if(drop) - { - mDownCallback(inv_item); - } - } - else - { - *accept = ACCEPT_NO; - } - } - return handled; -} - -AONoteCardDropTarget * LLFloaterAO::mAOItemDropTarget; - // STUFF ------------------------------------------------------- @@ -283,8 +216,6 @@ LLFloaterAO::~LLFloaterAO() mcomboBox_lands = 0; mcomboBox_standups = 0; mcomboBox_prejumps = 0; - delete mAOItemDropTarget; - mAOItemDropTarget = NULL; // llinfos << "floater destroyed" << llendl; } @@ -315,39 +246,6 @@ bool LLFloaterAO::getInstance() BOOL LLFloaterAO::postBuild() { - LLView *target_view = getChild("ao_notecard"); - if(target_view) - { - if (mAOItemDropTarget) - { - delete mAOItemDropTarget; - } - mAOItemDropTarget = new AONoteCardDropTarget("drop target", target_view->getRect(), AOItemDrop);//, mAvatarID); - addChild(mAOItemDropTarget); - } - if(LLStartUp::getStartupState() == STATE_STARTED) - { - LLUUID itemidimport = (LLUUID)gSavedPerAccountSettings.getString("AOConfigNotecardID"); - LLViewerInventoryItem* itemimport = gInventory.getItem(itemidimport); - if(itemimport) - { - LLStringUtil::format_map_t args; - args["[ITEM]"] = itemimport->getName(); - childSetValue("ao_nc_text", LLTrans::getString("CurrentlySetTo", args)); - } - else if(itemidimport.isNull()) - { - childSetValue("ao_nc_text", LLTrans::getString("CurrentlyNotSet")); - } - else - { - childSetValue("ao_nc_text", LLTrans::getString("CurrentlySetToAnItemNotOnThisAccount")); - } - } - else - { - childSetValue("ao_nc_text", LLTrans::getString("NotLoggedIn")); - } childSetAction("more_btn", onClickMore, this); childSetAction("less_btn", onClickLess, this); @@ -793,14 +691,6 @@ void LLFloaterAO::setCurrentStandId(const LLUUID& id) mCurrentStandId = id; } -void LLFloaterAO::AOItemDrop(LLViewerInventoryItem* item) -{ - gSavedPerAccountSettings.setString("AOConfigNotecardID", item->getUUID().asString()); - LLStringUtil::format_map_t args; - args["[ITEM]"] = item->getName(); - sInstance->childSetValue("ao_nc_text", LLTrans::getString("CurrentlySetTo", args)); -} - LLUUID LLFloaterAO::GetAnimID(const LLUUID& id) { for (std::vector::iterator iter = mAOOverrides.begin(); iter != mAOOverrides.end(); ++iter) @@ -1383,7 +1273,7 @@ BOOL LLFloaterAO::SetDefault(void* userdata, LLUUID ao_id, std::string defaultan if (sInstance && (userdata)) { LLComboBox *box = (LLComboBox *) userdata; - if (LLUUID::null == ao_id) + if (ao_id.isNull()) { box->clear(); box->removeall(); diff --git a/indra/newview/floaterao.h b/indra/newview/floaterao.h index 72bdf2903..b8a63f0da 100644 --- a/indra/newview/floaterao.h +++ b/indra/newview/floaterao.h @@ -8,8 +8,6 @@ #include "lleventtimer.h" -class AONoteCardDropTarget; - const int STATE_AGENT_IDLE = 0; const int STATE_AGENT_WALK = 1; const int STATE_AGENT_RUN = 2; @@ -113,8 +111,6 @@ private: static int mAnimationState; static LLUUID mCurrentStandId; - static AONoteCardDropTarget* mAOItemDropTarget; - static void AOItemDrop(LLViewerInventoryItem* item); static void onSpinnerCommit(LLUICtrl* ctrl); static void onComboBoxCommit(LLUICtrl* ctrl); static BOOL SetDefault(void *userdata, LLUUID ao_id, std::string defaultanim); diff --git a/indra/newview/floaterlocalassetbrowse.h b/indra/newview/floaterlocalassetbrowse.h index b95845710..7cd8ab559 100644 --- a/indra/newview/floaterlocalassetbrowse.h +++ b/indra/newview/floaterlocalassetbrowse.h @@ -252,7 +252,6 @@ private: LLButton* mUploadBtn; LLScrollListCtrl* mBitmapList; - LLScrollListCtrl* mUsedList; LLTextureCtrl* mTextureView; LLCheckBoxCtrl* mUpdateChkBox; diff --git a/indra/newview/floatervoicelicense.cpp b/indra/newview/floatervoicelicense.cpp index 93d403744..101398006 100644 --- a/indra/newview/floatervoicelicense.cpp +++ b/indra/newview/floatervoicelicense.cpp @@ -57,7 +57,6 @@ extern AIHTTPTimeoutPolicy iamHereVoice_timeout; FloaterVoiceLicense::FloaterVoiceLicense(const LLSD& key) : LLModalDialog( std::string(" "), 100, 100 ), - mWebBrowserWindowId( 0 ), mLoadCompleteCount( 0 ) { LLUICtrlFactory::getInstance()->buildFloater(this, "floater_voice_license.xml"); diff --git a/indra/newview/floatervoicelicense.h b/indra/newview/floatervoicelicense.h index 30dbb2fa3..10aaa1979 100644 --- a/indra/newview/floatervoicelicense.h +++ b/indra/newview/floatervoicelicense.h @@ -66,7 +66,6 @@ public: /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); private: - int mWebBrowserWindowId; int mLoadCompleteCount; }; diff --git a/indra/newview/hbfloatergrouptitles.cpp b/indra/newview/hbfloatergrouptitles.cpp index 9ebdae508..7ef401146 100644 --- a/indra/newview/hbfloatergrouptitles.cpp +++ b/indra/newview/hbfloatergrouptitles.cpp @@ -157,7 +157,7 @@ void HBFloaterGroupTitles::onActivate(void* userdata) // Set the title LLGroupMgr::getInstance()->sendGroupTitleUpdate(group_id, item->getUUID()); // Force a refresh via the observer - if (group_id == LLUUID::null) + if (group_id.isNull()) { group_id = old_group_id; } diff --git a/indra/newview/importtracker.cpp b/indra/newview/importtracker.cpp index 68a75796a..e88081969 100644 --- a/indra/newview/importtracker.cpp +++ b/indra/newview/importtracker.cpp @@ -236,7 +236,7 @@ void ImportTracker::get_update(S32 newid, BOOL justCreated, BOOL createSelected) msg->nextBlockFast(_PREHASH_ObjectData); msg->addU32Fast(_PREHASH_ObjectLocalID, (U32)newid); msg->addU8Fast(_PREHASH_Field, PERM_NEXT_OWNER); - msg->addBOOLFast(_PREHASH_Set, PERM_ITEM_UNRESTRICTED); + msg->addU8Fast(_PREHASH_Set, PERM_SET_TRUE); U32 flags = 0; if ( gSavedSettings.getBOOL("NextOwnerCopy") ) { @@ -718,7 +718,7 @@ void ImportTracker::send_properties(LLSD& prim, int counter) msg->nextBlockFast(_PREHASH_ObjectData); msg->addU32Fast(_PREHASH_ObjectLocalID, prim["LocalID"].asInteger()); msg->addU8Fast(_PREHASH_Field, PERM_NEXT_OWNER); - msg->addBOOLFast(_PREHASH_Set, PERM_ITEM_UNRESTRICTED); + msg->addU8Fast(_PREHASH_Set, PERM_SET_TRUE); msg->addU32Fast(_PREHASH_Mask, U32(atoi(prim["next_owner_mask"].asString().c_str()))); *//*msg->sendReliable(gAgent.getRegion()->getHost()); @@ -732,7 +732,7 @@ void ImportTracker::send_properties(LLSD& prim, int counter) msg->nextBlockFast(_PREHASH_ObjectData); msg->addU32Fast(_PREHASH_ObjectLocalID, prim["LocalID"].asInteger()); msg->addU8Fast(_PREHASH_Field, PERM_GROUP); - msg->addBOOLFast(_PREHASH_Set, PERM_ITEM_UNRESTRICTED); + msg->addU8Fast(_PREHASH_Set, PERM_SET_TRUE); msg->addU32Fast(_PREHASH_Mask, U32(atoi(prim["group_mask"].asString().c_str()))); *//*msg->sendReliable(gAgent.getRegion()->getHost()); @@ -746,7 +746,7 @@ void ImportTracker::send_properties(LLSD& prim, int counter) msg->nextBlockFast(_PREHASH_ObjectData); msg->addU32Fast(_PREHASH_ObjectLocalID, prim["LocalID"].asInteger()); msg->addU8Fast(_PREHASH_Field, PERM_EVERYONE); - msg->addBOOLFast(_PREHASH_Set, PERM_ITEM_UNRESTRICTED); + msg->addU8Fast(_PREHASH_Set, PERM_SET_TRUE); msg->addU32Fast(_PREHASH_Mask, U32(atoi(prim["everyone_mask"].asString().c_str()))); msg->sendReliable(gAgent.getRegion()->getHost()); diff --git a/indra/newview/installers/windows/install_icon_singularity.BMP b/indra/newview/installers/windows/install_icon_singularity.BMP old mode 100755 new mode 100644 diff --git a/indra/newview/installers/windows/uninstall_icon_singularity.BMP b/indra/newview/installers/windows/uninstall_icon_singularity.BMP old mode 100755 new mode 100644 diff --git a/indra/newview/installers/windows/uninstall_icon_singularity.ico b/indra/newview/installers/windows/uninstall_icon_singularity.ico old mode 100755 new mode 100644 diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index 0806df29d..d6a266240 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -154,7 +154,7 @@ export SL_OPT="`cat gridargs.dat` $@" eval ${SL_ENV} ${SL_CMD} ${SL_OPT} || LL_RUN_ERR=runerr # Handle any resulting errors -if [ -n "$LL_RUN_ERR" ]; then +if [ "$LL_RUN_ERR" = "runerr" ]; then # generic error running the binary echo '*** Bad shutdown. ***' fi diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 1f46baa7e..b3e0eb56d 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -666,11 +666,13 @@ void LLAgent::setFlying(BOOL fly) return; } + /* Singu Note: We don't take off while sitting, don't bother with this check, let us toggle fly whenever. // don't allow taking off while sitting if (fly && gAgentAvatarp->isSitting()) { return; } + */ } if (fly) @@ -883,11 +885,6 @@ void LLAgent::setRegion(LLViewerRegion *regionp) //----------------------------------------------------------------------------- // getRegion() //----------------------------------------------------------------------------- -LLViewerRegion *LLAgent::getRegion() const -{ - return mRegionp; -} - const LLHost& LLAgent::getRegionHost() const { @@ -3862,7 +3859,7 @@ bool LLAgent::teleportCore(bool is_local) // close the map panel so we can see our destination. // we don't close search floater, see EXT-5840. - LLFloaterWorldMap::hide(NULL); + LLFloaterWorldMap::hide(); // hide land floater too - it'll be out of date LLFloaterLand::hideInstance(); diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 6ae193677..bcc469f5e 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -242,7 +242,7 @@ private: //-------------------------------------------------------------------- public: void setRegion(LLViewerRegion *regionp); - LLViewerRegion *getRegion() const; + LLViewerRegion *getRegion() const { return mRegionp; } const LLHost& getRegionHost() const; BOOL inPrelude(); std::string getSLURL() const; //Return uri for current region diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index b49d59044..9d4179621 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -910,7 +910,6 @@ void LLAgentCamera::cameraZoomIn(const F32 fraction) } - LLVector3d camera_offset(mCameraFocusOffsetTarget); LLVector3d camera_offset_unit(mCameraFocusOffsetTarget); F32 min_zoom = 0.f;//LAND_MIN_ZOOM; F32 current_distance = (F32)camera_offset_unit.normalize(); @@ -988,7 +987,6 @@ void LLAgentCamera::cameraOrbitIn(const F32 meters) } else { - LLVector3d camera_offset(mCameraFocusOffsetTarget); LLVector3d camera_offset_unit(mCameraFocusOffsetTarget); F32 current_distance = (F32)camera_offset_unit.normalize(); F32 new_distance = current_distance - meters; diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 31088df5c..66d8b81ba 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -3921,14 +3921,14 @@ void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove) bool fUpdateAppearance = false; for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it) { - const LLInventoryItem* linked_item = gInventory.getLinkedItem(*it); - if ( (rlv_handler_t::isEnabled()) && (!rlvPredCanRemoveItem(linked_item)) ) + const LLUUID& linked_item_id = gInventory.getLinkedItemID(*it); + if ( (rlv_handler_t::isEnabled()) && (!rlvPredCanRemoveItem(gInventory.getItem(linked_item_id))) ) { continue; } fUpdateAppearance = true; - removeCOFItemLinks(linked_item->getUUID()); + removeCOFItemLinks(linked_item_id); } if (fUpdateAppearance) @@ -3948,18 +3948,14 @@ void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove) void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove) { // [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8) - const LLInventoryItem* linked_item = gInventory.getLinkedItem(id_to_remove); - if ( (rlv_handler_t::isEnabled()) && (!rlvPredCanRemoveItem(linked_item)) ) + LLUUID linked_item_id = gInventory.getLinkedItemID(id_to_remove); + if ( (rlv_handler_t::isEnabled()) && (!rlvPredCanRemoveItem(gInventory.getItem(linked_item_id))) ) { return; } - - removeCOFItemLinks(linked_item->getUUID()); - updateAppearanceFromCOF(); // [/RLVA:KB] -// LLUUID linked_item_id = gInventory.getLinkedItemID(id_to_remove); -// removeCOFItemLinks(linked_item_id); -// updateAppearanceFromCOF(); + removeCOFItemLinks(linked_item_id); + updateAppearanceFromCOF(); } bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_body) diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 81cc087cc..8d0f3e971 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -546,16 +546,31 @@ F32 LLDrawable::updateXform(BOOL undamped) } } - if ((mCurrentScale != target_scale) || - (!isRoot() && - (dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED || - !mVObjp->getAngularVelocity().isExactlyZero() || - target_pos != mXform.getPosition() || - target_rot != mXform.getRotation()))) - { //child prim moving or scale change requires immediate rebuild + LLVector3 vec = mCurrentScale-target_scale; + + if (vec*vec > MIN_INTERPOLATE_DISTANCE_SQUARED) + { //scale change requires immediate rebuild mCurrentScale = target_scale; gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); } + else if (!isRoot() && + (!mVObjp->getAngularVelocity().isExactlyZero() || + dist_squared > 0.f)) + { //child prim moving relative to parent, tag as needing to be rendered atomically and rebuild + dist_squared = 1.f; //keep this object on the move list + if (!isState(LLDrawable::ANIMATED_CHILD)) + { + setState(LLDrawable::ANIMATED_CHILD); + gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE); + mVObjp->dirtySpatialGroup(); + } + } + else if (!isRoot() && ( + dist_vec_squared(old_pos, target_pos) > 0.f + || old_rot != target_rot )) + { //fix for BUG-860, MAINT-2275, MAINT-1742, MAINT-2247 + gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); + } else if (!getVOVolume() && !isAvatar()) { movePartition(); diff --git a/indra/newview/lldroptarget.cpp b/indra/newview/lldroptarget.cpp index 2dd2ad5a4..610ce2068 100644 --- a/indra/newview/lldroptarget.cpp +++ b/indra/newview/lldroptarget.cpp @@ -40,24 +40,127 @@ #include "llviewerprecompiledheaders.h" #include "lldroptarget.h" -#include "lltooldraganddrop.h" -#include "llinventorymodel.h" -LLDropTarget::LLDropTarget(const std::string& name, const LLRect& rect, const LLUUID& agent_id) : - LLView(name, rect, NOT_MOUSE_OPAQUE, FOLLOWS_ALL), - mAgentID(agent_id), - mDownCallback(NULL) +#include "llinventorymodel.h" +#include "llstartup.h" +#include "lltextbox.h" +#include "lltooldraganddrop.h" +#include "lltrans.h" + +static LLRegisterWidget r("drop_target"); + +static std::string currently_set_to(const LLViewerInventoryItem* item) { + LLStringUtil::format_map_t args; + args["[ITEM]"] = item->getName(); + return LLTrans::getString("CurrentlySetTo", args); } -LLDropTarget::LLDropTarget(const std::string& name, const LLRect& rect, void (*callback)(LLViewerInventoryItem*)) : - LLView(name, rect, NOT_MOUSE_OPAQUE, FOLLOWS_ALL), - mDownCallback(callback) +LLDropTarget::LLDropTarget(const LLDropTarget::Params& p) +: LLView(p) { + setToolTip(std::string(p.tool_tip)); + + mText = new LLTextBox("drop_text", p.rect, p.label); + addChild(mText); + + setControlName(p.control_name, NULL); + mText->setOrigin(0, 0); + mText->setFollows(FOLLOWS_NONE); + mText->setHAlign(LLFontGL::HCENTER); + mText->setBorderVisible(true); + mText->setBorderColor(LLUI::sColorsGroup->getColor("DefaultHighlightLight")); + + if (p.fill_parent) fillParent(getParent()); } LLDropTarget::~LLDropTarget() { + delete mText; +} + +// static +LLView* LLDropTarget::fromXML(LLXMLNodePtr node, LLView* parent, LLUICtrlFactory* factory) +{ + LLDropTarget* target = new LLDropTarget(); + target->initFromXML(node, parent); + return target; +} + +// virtual +void LLDropTarget::initFromXML(LLXMLNodePtr node, LLView* parent) +{ + LLView::initFromXML(node, parent); + + const LLRect& rect = getRect(); + mText->setRect(LLRect(0, rect.getHeight(), rect.getWidth(), 0)); + + if (node->hasAttribute("name")) // Views can't have names, but drop targets can + { + std::string name; + node->getAttributeString("name", name); + setName(name); + } + + if (node->hasAttribute("label")) + { + std::string label; + node->getAttributeString("label", label); + mText->setText(label); + } + + if (node->hasAttribute("fill_parent")) + { + bool fill; + node->getAttribute_bool("fill_parent", fill); + if (fill) fillParent(parent); + } +} + +// virtual +void LLDropTarget::setControlName(const std::string& control_name, LLView* context) +{ + if (control_name.empty()) // The "empty set" + { + mControl = NULL; + return; // This DropTarget never changes text, it isn't tied to a control + } + + std::string text; + if (LLStartUp::getStartupState() != STATE_STARTED) // Too early for PerAccount + { + text = LLTrans::getString("NotLoggedIn"); + } + else + { + mControl = gSavedPerAccountSettings.getControl(control_name); + const LLUUID id(mControl->getValue().asString()); + if (id.isNull()) + text = LLTrans::getString("CurrentlyNotSet"); + else if (LLViewerInventoryItem* item = gInventory.getItem(id)) + text = currently_set_to(item); + else + text = LLTrans::getString("CurrentlySetToAnItemNotOnThisAccount"); + } + + mText->setText(text); +} + +void LLDropTarget::fillParent(const LLView* parent) +{ + if (!parent) return; // No parent to fill + + const std::string& tool_tip = getToolTip(); + if (!tool_tip.empty()) // Don't tool_tip the entire parent + { + mText->setToolTip(tool_tip); + setToolTip(LLStringExplicit("")); + } + + // The following block enlarges the target, but maintains the desired size for the text and border + mText->setRect(getRect()); // mText takes over the old rectangle, since the position will now be relative to the parent's rectangle for the text. + const LLRect& parent_rect = parent->getRect(); + setRect(LLRect(0, parent_rect.getHeight(), parent_rect.getWidth(), 0)); } void LLDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data) @@ -67,17 +170,23 @@ void LLDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data) BOOL LLDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept, std::string& tooltip_msg) { - if(!getParent()) return false; - if(!mDownCallback) LLToolDragAndDrop::handleGiveDragAndDrop(mAgentID, LLUUID::null, drop, cargo_type, cargo_data, accept); - else + if (mEntityID.isNull()) { - LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data; - if (gInventory.getItem(inv_item->getUUID())) + if (LLViewerInventoryItem* inv_item = static_cast(cargo_data)) { *accept = ACCEPT_YES_COPY_SINGLE; - if (drop) mDownCallback(inv_item); + if (drop) + { + mText->setText(currently_set_to(inv_item)); + if (mControl) mControl->setValue(inv_item->getUUID().asString()); + } } - else *accept = ACCEPT_NO; + else + { + *accept = ACCEPT_NO; + } + return true; } - return true; + return getParent() ? LLToolDragAndDrop::handleGiveDragAndDrop(mEntityID, LLUUID::null, drop, cargo_type, cargo_data, accept) : false; } + diff --git a/indra/newview/lldroptarget.h b/indra/newview/lldroptarget.h index 2dd421239..1a08484ce 100644 --- a/indra/newview/lldroptarget.h +++ b/indra/newview/lldroptarget.h @@ -42,23 +42,44 @@ #include "stdtypes.h" #include "llview.h" -class LLViewerInventoryItem; + class LLDropTarget : public LLView { public: - LLDropTarget(const std::string& name, const LLRect& rect, void (*callback)(LLViewerInventoryItem*)); - LLDropTarget(const std::string& name, const LLRect& rect, const LLUUID& agent_id); + struct Params : public LLInitParam::Block + { + Optional control_name; // Control to change on item drop (Per Account only) + Optional label; // Label for the LLTextBox, used when label doesn't dynamically change on drop + Optional fill_parent; // Whether or not to fill the direct parent, to have a larger drop target. If true, the next sibling must explicitly define its rect without deltas. + Params() + : control_name("control_name", "") + , label("label", "") + , fill_parent("fill_parent", false) + { + changeDefault(mouse_opaque, false); + changeDefault(follows.flags, FOLLOWS_ALL); + } + }; + + LLDropTarget(const Params& p = Params()); ~LLDropTarget(); - void doDrop(EDragAndDropType cargo_type, void* cargo_data); + virtual void doDrop(EDragAndDropType cargo_type, void* cargo_data); // // LLView functionality virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept, std::string& tooltip_msg); - void setAgentID(const LLUUID &agent_id){ mAgentID = agent_id;} + static LLView* fromXML(LLXMLNodePtr node, LLView* parent, class LLUICtrlFactory* factory); + virtual void initFromXML(LLXMLNodePtr node, LLView* parent); + virtual void setControlName(const std::string& control, LLView* context); + + void fillParent(const LLView* parent); + void setEntityID(const LLUUID& id) { mEntityID = id;} protected: - LLUUID mAgentID; - void (*mDownCallback)(LLViewerInventoryItem*); + LLUUID mEntityID; +private: + LLControlVariable* mControl; + class LLTextBox* mText; }; #endif // LLDROPTARGET_H diff --git a/indra/newview/llfloateractivespeakers.cpp b/indra/newview/llfloateractivespeakers.cpp index 8203c310b..839769e27 100644 --- a/indra/newview/llfloateractivespeakers.cpp +++ b/indra/newview/llfloateractivespeakers.cpp @@ -1051,8 +1051,8 @@ void LLSpeakerMgr::update(BOOL resort_ok) { LLUUID speaker_id = speaker_it->first; LLSpeaker* speakerp = speaker_it->second; - - speaker_map_t::iterator cur_speaker_it = speaker_it++; + + speaker_it++; if (voice_channel_active && gVoiceClient->getVoiceEnabled(speaker_id)) { diff --git a/indra/newview/llfloateravatarinfo.cpp b/indra/newview/llfloateravatarinfo.cpp index c9e5ba9cc..cd0cbbc3c 100644 --- a/indra/newview/llfloateravatarinfo.cpp +++ b/indra/newview/llfloateravatarinfo.cpp @@ -40,7 +40,12 @@ // viewer project includes #include "llagentdata.h" #include "llcommandhandler.h" +#include "llimview.h" +#include "llfloaterfriends.h" +#include "llfloatermute.h" +#include "llmenucommands.h" #include "llpanelavatar.h" +#include "llviewermessage.h" #include "lluictrlfactory.h" #include "llweb.h" @@ -60,24 +65,92 @@ const LLRect FAI_RECT(0, 530, 420, 0); class LLAgentHandler : public LLCommandHandler { public: + void verbCallback(const std::string& verb, LLUUID agent_id, const LLAvatarName& avatar_name) + { + if (verb == "im") + { + gIMMgr->setFloaterOpen(TRUE); + gIMMgr->addSession( avatar_name.getCompleteName(), IM_NOTHING_SPECIAL, agent_id); + return; + } + + if (verb == "requestfriend") + { + LLPanelFriends::requestFriendshipDialog( agent_id, avatar_name.getCompleteName() ); + return; + } + + if (verb == "mute") + { + LLFloaterMute::getInstance()->open(); + LLMute mute(agent_id, avatar_name.getCompleteName(), LLMute::AGENT); + LLMuteList::getInstance()->add(mute); + return; + } + + if (verb == "unmute") + { + LLMute mute(agent_id, avatar_name.getCompleteName(), LLMute::AGENT); + LLMuteList::getInstance()->remove(mute); + return; + } + } + // requires trusted browser to trigger LLAgentHandler() : LLCommandHandler("agent", true) { } bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) { - if (params.size() < 2) return false; + if (params.size() < 2) + { + return false; + } LLUUID agent_id; if (!agent_id.set(params[0], FALSE)) { return false; } - if (params[1].asString() == "about") + const std::string verb = params[1].asString(); + if (verb == "about") { LLFloaterAvatarInfo::show(agent_id); return true; } + + if (verb == "pay") + { + handle_pay_by_id(agent_id); + return true; + } + + if (verb == "offerteleport") + { + handle_lure(agent_id); + return true; + } + + if ((verb == "im") || (verb == "requestfriend") || (verb == "unmute")) + { + LLAvatarNameCache::get(agent_id, boost::bind(&LLAgentHandler::verbCallback, this, verb, _1, _2)); + return true; + } + + if (verb == "mute") + { + if (LLMuteList::getInstance()->isMuted(agent_id)) + { + LLFloaterMute::getInstance()->open(); + LLFloaterMute::getInstance()->selectMute(agent_id); + } + else + { + LLAvatarNameCache::get(agent_id, boost::bind(&LLAgentHandler::verbCallback, this, verb, _1, _2)); + } + return true; + } + return false; } }; diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index 39c82ab77..4a5640a27 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -315,7 +315,7 @@ const LLAvatarListEntry::ACTIVITY_TYPE LLAvatarListEntry::getActivity() LLFloaterAvatarList::LLFloaterAvatarList() : LLFloater(std::string("radar")), mTracking(false), - mUpdate(true), + mUpdate("RadarUpdateEnabled"), mDirtyAvatarSorting(false), mUpdateRate(gSavedSettings.getU32("RadarUpdateRate") * 3 + 3), mAvatarList(NULL) @@ -415,12 +415,12 @@ BOOL LLFloaterAvatarList::postBuild() getChild("update_rate")->setSelectedIndex(gSavedSettings.getU32("RadarUpdateRate")); getChild("update_rate")->setCommitCallback(boost::bind(&LLFloaterAvatarList::onCommitUpdateRate, this)); - getChild("hide_mark")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this)); - getChild("hide_pos")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this)); - getChild("hide_alt")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this)); - getChild("hide_act")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this)); - getChild("hide_age")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this)); - getChild("hide_time")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this)); + gSavedSettings.getControl("RadarColumnMarkHidden")->getSignal()->connect(boost::bind(&LLFloaterAvatarList::assessColumns, this)); + gSavedSettings.getControl("RadarColumnPositionHidden")->getSignal()->connect(boost::bind(&LLFloaterAvatarList::assessColumns, this)); + gSavedSettings.getControl("RadarColumnAltitudeHidden")->getSignal()->connect(boost::bind(&LLFloaterAvatarList::assessColumns, this)); + gSavedSettings.getControl("RadarColumnActivityHidden")->getSignal()->connect(boost::bind(&LLFloaterAvatarList::assessColumns, this)); + gSavedSettings.getControl("RadarColumnAgeHidden")->getSignal()->connect(boost::bind(&LLFloaterAvatarList::assessColumns, this)); + gSavedSettings.getControl("RadarColumnTimeHidden")->getSignal()->connect(boost::bind(&LLFloaterAvatarList::assessColumns, this)); // Get a pointer to the scroll list from the interface mAvatarList = getChild("avatar_list"); @@ -438,7 +438,7 @@ BOOL LLFloaterAvatarList::postBuild() if(gHippoGridManager->getConnectedGrid()->isSecondLife()) childSetVisible("hide_client", false); else - getChild("hide_client")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this)); + gSavedSettings.getControl("RadarColumnClientHidden")->getSignal()->connect(boost::bind(&LLFloaterAvatarList::assessColumns, this)); return TRUE; } @@ -529,17 +529,11 @@ void LLFloaterAvatarList::updateAvatarList() //llinfos << "radar refresh: updating map" << llendl; // Check whether updates are enabled - LLCheckboxCtrl* check = getChild("update_enabled_cb"); - if (check && !check->getValue()) + if (!mUpdate) { - mUpdate = FALSE; refreshTracker(); return; } - else - { - mUpdate = TRUE; - } //moved to pipeline to prevent a crash //gPipeline.forAllVisibleDrawables(updateParticleActivity); @@ -1186,7 +1180,7 @@ void LLFloaterAvatarList::onClickTrack() if (mTracking && mTrackedAvatar == agent_id) { - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); mTracking = FALSE; } else @@ -1203,7 +1197,7 @@ void LLFloaterAvatarList::refreshTracker() { if (!mTracking) return; - if (LLTracker::isTracking(NULL)) + if (LLTracker::isTracking()) { if(LLAvatarListEntry* entry = getAvatarEntry(mTrackedAvatar)) { @@ -1215,7 +1209,7 @@ void LLFloaterAvatarList::refreshTracker() } else { // Tracker stopped. - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); mTracking = FALSE; // llinfos << "Tracking stopped." << llendl; } @@ -1248,19 +1242,18 @@ LLAvatarListEntry * LLFloaterAvatarList::getAvatarEntry(LLUUID avatar) BOOL LLFloaterAvatarList::handleKeyHere(KEY key, MASK mask) { - LLFloaterAvatarList* self = getInstance(); - LLScrollListItem* item = self->mAvatarList->getFirstSelected(); + LLScrollListItem* item = mAvatarList->getFirstSelected(); if(item) { LLUUID agent_id = item->getUUID(); if (( KEY_RETURN == key ) && (MASK_NONE == mask)) { - self->setFocusAvatar(agent_id); + setFocusAvatar(agent_id); return TRUE; } else if (( KEY_RETURN == key ) && (MASK_CONTROL == mask)) { - LLAvatarListEntry* entry = self->getAvatarEntry(agent_id); + const LLAvatarListEntry* entry = getAvatarEntry(agent_id); if (entry) { // llinfos << "Trying to teleport to " << entry->getName() << " at " << entry->getPosition() << llendl; @@ -1272,7 +1265,7 @@ BOOL LLFloaterAvatarList::handleKeyHere(KEY key, MASK mask) if (( KEY_RETURN == key ) && (MASK_SHIFT == mask)) { - uuid_vec_t ids = self->mAvatarList->getSelectedIDs(); + uuid_vec_t ids = mAvatarList->getSelectedIDs(); if (ids.size() > 0) { if (ids.size() == 1) @@ -1385,12 +1378,7 @@ void LLFloaterAvatarList::onClickGetKey() if (NULL == item) return; - LLUUID agent_id = item->getUUID(); - - char buffer[UUID_STR_LENGTH]; /*Flawfinder: ignore*/ - agent_id.toString(buffer); - - gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(buffer)); + gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(item->getUUID().asString())); } void LLFloaterAvatarList::sendKeys() @@ -1419,11 +1407,11 @@ void LLFloaterAvatarList::sendKeys() std::ostringstream ids; int num_ids = 0; - for (int i = 0; i < regionp->mMapAvatarIDs.count(); i++) + for (int i = 0; i < regionp->mMapAvatarIDs.count(); ++i) { const LLUUID &id = regionp->mMapAvatarIDs.get(i); - ids << "," << id.asString(); + ids << "," << id; ++num_ids; diff --git a/indra/newview/llfloateravatarlist.h b/indra/newview/llfloateravatarlist.h index 3bcf4ea67..2ad3de090 100644 --- a/indra/newview/llfloateravatarlist.h +++ b/indra/newview/llfloateravatarlist.h @@ -354,7 +354,7 @@ private: /** * @brief TRUE when Updating */ - bool mUpdate; + const LLCachedControl mUpdate; /** * @brief Update rate (if min frames per update) diff --git a/indra/newview/llfloaterbulkpermission.h b/indra/newview/llfloaterbulkpermission.h index 5194b1563..1036b04a2 100644 --- a/indra/newview/llfloaterbulkpermission.h +++ b/indra/newview/llfloaterbulkpermission.h @@ -91,18 +91,12 @@ private: void doCheckUncheckAll(BOOL check); private: - // UI - LLScrollListCtrl* mMessages; - LLButton* mCloseBtn; - // Object Queue LLDynamicArray mObjectIDs; LLUUID mCurrentObjectID; BOOL mDone; LLUUID mID; - - const char* mStartString; }; #endif diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp index 01ed3f0c1..bf92422a1 100644 --- a/indra/newview/llfloaterchat.cpp +++ b/indra/newview/llfloaterchat.cpp @@ -38,54 +38,32 @@ #include "llviewerprecompiledheaders.h" #include "llfloaterchat.h" -#include "llfloateractivespeakers.h" -#include "llfloaterscriptdebug.h" - -#include "llchat.h" -#include "llfontgl.h" -#include "llrect.h" -#include "llerror.h" -#include "llstring.h" -#include "message.h" - -// project include -#include "llagent.h" -#include "llbutton.h" -#include "llcheckboxctrl.h" -#include "llcombobox.h" -#include "llconsole.h" -#include "llfloaterchatterbox.h" -#include "llfloatermute.h" -#include "llkeyboard.h" -//#include "lllineeditor.h" -#include "llmutelist.h" -//#include "llresizehandle.h" -#include "llchatbar.h" -#include "llstatusbar.h" -#include "llviewertexteditor.h" -#include "llviewergesture.h" // for triggering gestures -#include "llviewermessage.h" -#include "llviewerwindow.h" -#include "llviewercontrol.h" -#include "lluictrlfactory.h" -#include "llchatbar.h" -#include "lllogchat.h" -#include "lltexteditor.h" -#include "lltextparser.h" -#include "llfloaterhtml.h" -#include "llweb.h" -#include "llstylemap.h" -#include "ascentkeyword.h" // linden library includes #include "llaudioengine.h" -#include "llchat.h" -#include "llfontgl.h" -#include "llrect.h" -#include "llerror.h" -#include "llstring.h" +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "lltextparser.h" +#include "lltrans.h" #include "llwindow.h" -#include "message.h" + +// project include +#include "ascentkeyword.h" +#include "llagent.h" +#include "llchatbar.h" +#include "llconsole.h" +#include "llfloateractivespeakers.h" +#include "llfloaterchatterbox.h" +#include "llfloatermute.h" +#include "llfloaterscriptdebug.h" +#include "lllogchat.h" +#include "llmutelist.h" +#include "llstylemap.h" +#include "lluictrlfactory.h" +#include "llviewermessage.h" +#include "llviewertexteditor.h" +#include "llviewerwindow.h" +#include "llweb.h" // [RLVa:KB] #include "rlvhandler.h" @@ -94,7 +72,8 @@ // // Global statics // -LLColor4 get_text_color(const LLChat& chat); +LLColor4 agent_chat_color(const LLUUID& id, const std::string&, bool local_chat = true); +LLColor4 get_text_color(const LLChat& chat, bool from_im = false); // // Member Functions @@ -187,13 +166,12 @@ void LLFloaterChat::handleVisibilityChange(BOOL new_visibility) // virtual void LLFloaterChat::onFocusReceived() { - LLView* chat_editor = getChildView("Chat Editor"); - if (getVisible() && childIsVisible("Chat Editor")) + LLUICtrl* chat_editor = getChild("Chat Editor"); + if (getVisible() && chat_editor->getVisible()) { gFocusMgr.setKeyboardFocus(chat_editor); - LLUICtrl * ctrl = static_cast(chat_editor); - ctrl->setFocus(TRUE); + chat_editor->setFocus(TRUE); } LLFloater::onFocusReceived(); @@ -227,9 +205,9 @@ void add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4& // If the msg is from an agent (not yourself though), // extract out the sender name and replace it with the hotlinked name. if (chat.mSourceType == CHAT_SOURCE_AGENT && -// chat.mFromID != LLUUID::null) +// chat.mFromID.notNull()) // [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) - chat.mFromID != LLUUID::null && + chat.mFromID.notNull() && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ) // [/RLVa:KB] { @@ -238,20 +216,27 @@ void add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4& if(chat.mSourceType == CHAT_SOURCE_OBJECT && !chat.mFromName.length()) { - chat.mFromName = "(no name)"; + chat.mFromName = LLTrans::getString("Unnamed"); line = chat.mFromName + line; } + + static const LLCachedControl italicize("LiruItalicizeActions"); + bool is_irc = italicize && chat.mChatStyle == CHAT_STYLE_IRC; // If the chat line has an associated url, link it up to the name. if (!chat.mURL.empty() && (line.length() > chat.mFromName.length() && line.find(chat.mFromName,0) == 0)) { std::string start_line = line.substr(0, chat.mFromName.length() + 1); line = line.substr(chat.mFromName.length() + 1); - const LLStyleSP &sourceStyle = LLStyleMap::instance().lookup(chat.mFromID,chat.mURL); + LLStyleSP sourceStyle = LLStyleMap::instance().lookup(chat.mFromID,chat.mURL); + sourceStyle->mItalic = is_irc; edit->appendStyledText(start_line, false, prepend_newline, sourceStyle); prepend_newline = false; } - edit->appendColoredText(line, false, prepend_newline, color); + LLStyleSP style(new LLStyle); + style->setColor(color); + style->mItalic = is_irc; + edit->appendStyledText(line, false, prepend_newline, style); } void log_chat_text(const LLChat& chat) @@ -439,7 +424,7 @@ void LLFloaterChat::addChat(const LLChat& chat, BOOL from_instant_message, BOOL local_agent) { - LLColor4 text_color = get_text_color(chat); + LLColor4 text_color = get_text_color(chat, from_instant_message); BOOL invisible_script_debug_chat = chat.mChatType == CHAT_TYPE_DEBUG_MSG @@ -474,14 +459,6 @@ void LLFloaterChat::addChat(const LLChat& chat, && gConsole && !local_agent) { - if (chat.mSourceType == CHAT_SOURCE_SYSTEM) - { - text_color = gSavedSettings.getColor("SystemChatColor"); - } - else if(from_instant_message) - { - text_color = gSavedSettings.getColor("IMChatColor"); - } // We display anything if it's not an IM. If it's an IM, check pref... if ( !from_instant_message || gSavedSettings.getBOOL("IMInChatConsole") ) { @@ -547,7 +524,7 @@ void LLFloaterChat::triggerAlerts(const std::string& text) } } -LLColor4 get_text_color(const LLChat& chat) +LLColor4 get_text_color(const LLChat& chat, bool from_im) { LLColor4 text_color; @@ -567,48 +544,7 @@ LLColor4 get_text_color(const LLChat& chat) text_color = gSavedSettings.getColor4("SystemChatColor"); break; case CHAT_SOURCE_AGENT: - if (chat.mFromID.isNull()) - { - text_color = gSavedSettings.getColor4("SystemChatColor"); - } - else - { - if(gAgent.getID() == chat.mFromID) - { - text_color = gSavedSettings.getColor4("UserChatColor"); - } - else - { - static LLCachedControl color_linden_chat("ColorLindenChat"); - if (color_linden_chat && LLMuteList::getInstance()->isLinden(chat.mFromName)) - { - text_color = gSavedSettings.getColor4("AscentLindenColor"); - } - else if (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) - { - static LLCachedControl color_friend_chat("ColorFriendChat"); - static LLCachedControl color_eo_chat("ColorEstateOwnerChat"); - if (color_friend_chat && LLAvatarTracker::instance().isBuddy(chat.mFromID)) - { - text_color = gSavedSettings.getColor4("AscentFriendColor"); - } - else if (color_eo_chat) - { - LLViewerRegion* parent_estate = gAgent.getRegion(); - if (parent_estate && parent_estate->isAlive() && chat.mFromID == parent_estate->getOwner()) - text_color = gSavedSettings.getColor4("AscentEstateOwnerColor"); - else - text_color = gSavedSettings.getColor4("AgentChatColor"); - } - else - text_color = gSavedSettings.getColor4("AgentChatColor"); - } - else - { - text_color = gSavedSettings.getColor4("AgentChatColor"); - } - } - } + text_color = agent_chat_color(chat.mFromID, chat.mFromName, !from_im); break; case CHAT_SOURCE_OBJECT: if (chat.mChatType == CHAT_TYPE_DEBUG_MSG) @@ -751,13 +687,12 @@ void LLFloaterChat::hide(LLFloater* instance, const LLSD& key) BOOL LLFloaterChat::focusFirstItem(BOOL prefer_text_fields, BOOL focus_flash ) { - LLView* chat_editor = getChildView("Chat Editor"); - if (getVisible() && childIsVisible("Chat Editor")) + LLUICtrl* chat_editor = getChild("Chat Editor"); + if (getVisible() && chat_editor->getVisible()) { gFocusMgr.setKeyboardFocus(chat_editor); - LLUICtrl * ctrl = static_cast(chat_editor); - ctrl->setFocus(TRUE); + chat_editor->setFocus(TRUE); return TRUE; } diff --git a/indra/newview/llfloatercustomize.cpp b/indra/newview/llfloatercustomize.cpp index b29558af3..712965961 100644 --- a/indra/newview/llfloatercustomize.cpp +++ b/indra/newview/llfloatercustomize.cpp @@ -189,6 +189,7 @@ LLFloaterCustomize::~LLFloaterCustomize() BOOL LLFloaterCustomize::postBuild() { getChild("Make Outfit")->setCommitCallback(boost::bind(&LLFloaterCustomize::onBtnMakeOutfit, this)); + getChild("Save Outfit")->setCommitCallback(boost::bind(&LLAppearanceMgr::updateBaseOutfit, LLAppearanceMgr::getInstance())); getChild("Ok")->setCommitCallback(boost::bind(&LLFloaterCustomize::onBtnOk, this)); getChild("Cancel")->setCommitCallback(boost::bind(&LLFloater::onClickClose, this)); diff --git a/indra/newview/llfloatergroupinfo.cpp b/indra/newview/llfloatergroupinfo.cpp index d92413c32..3e2e845e3 100644 --- a/indra/newview/llfloatergroupinfo.cpp +++ b/indra/newview/llfloatergroupinfo.cpp @@ -97,7 +97,7 @@ public: return false; } - if (tokens[1].asString() == "about") + if ((tokens[1].asString() == "about") || (tokens[1].asString() == "inspect")) { LLFloaterGroupInfo::showFromUUID(group_id); return true; diff --git a/indra/newview/llfloaterlandholdings.cpp b/indra/newview/llfloaterlandholdings.cpp index 832bf6b86..b60aab459 100644 --- a/indra/newview/llfloaterlandholdings.cpp +++ b/indra/newview/llfloaterlandholdings.cpp @@ -300,7 +300,7 @@ void LLFloaterLandHoldings::buttonCore(S32 which) break; case 1: gFloaterWorldMap->trackLocation(pos_global); - LLFloaterWorldMap::show(NULL, TRUE); + LLFloaterWorldMap::show(true); break; default: break; diff --git a/indra/newview/llfloaternewim.cpp b/indra/newview/llfloaternewim.cpp deleted file mode 100644 index 3acca6e38..000000000 --- a/indra/newview/llfloaternewim.cpp +++ /dev/null @@ -1,250 +0,0 @@ -/** - * @file llfloaternewim.cpp - * @brief Panel allowing the user to create a new IM session. - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" -#include "llfloaternewim.h" -#include "lluictrlfactory.h" -#include "llnamelistctrl.h" -#include "llresmgr.h" -#include "lltabcontainer.h" -#include "llimview.h" - -S32 COL_1_WIDTH = 200; - -static std::string sOnlineDescriptor = "*"; - -LLFloaterNewIM::LLFloaterNewIM() -{ - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_new_im.xml"); -} - -BOOL LLFloaterNewIM::postBuild() -{ - requires("start_btn"); - requires("close_btn"); - requires("user_list"); - - if (checkRequirements()) - { - childSetAction("start_btn", &LLFloaterNewIM::onStart, this); - childSetAction("close_btn", &LLFloaterNewIM::onClickClose, this); - mSelectionList = getChild("user_list"); - if (mSelectionList) - { - mSelectionList->setDoubleClickCallback(boost::bind(&LLFloaterNewIM::onStart,this)); - } - else - { - llwarns << "LLUICtrlFactory::getNameListByName() returned NULL for 'user_list'" << llendl; - } - sOnlineDescriptor = getString("online_descriptor"); - setDefaultBtn("start_btn"); - return TRUE; - } - - return FALSE; -} - - -LLFloaterNewIM::~LLFloaterNewIM() -{ - clearAllTargets(); -} - - -void LLFloaterNewIM::clearAllTargets() -{ - mSelectionList->deleteAllItems(); -} - -void LLFloaterNewIM::addSpecial(const LLUUID& uuid, const std::string& name, - void* data, BOOL bold, BOOL online) -{ - LLSD row; - row["id"] = uuid; - row["name"] = name; - row["target"] = LLNameListCtrl::SPECIAL; - row["columns"][0]["value"] = name; - row["columns"][0]["width"] = COL_1_WIDTH; - row["columns"][0]["font"] = "SANSSERIF"; - row["columns"][0]["font-style"] = bold ? "BOLD" : "NORMAL"; - row["columns"][1]["value"] = online ? sOnlineDescriptor : ""; - row["columns"][1]["font"] = "SANSSERIF"; - row["columns"][1]["font-style"] = "BOLD"; - LLScrollListItem* itemp = mSelectionList->addElement(row); - itemp->setUserdata(data); - - if (mSelectionList->getFirstSelectedIndex() == -1) - { - mSelectionList->selectFirstItem(); - } -} - -void LLFloaterNewIM::addGroup(const LLUUID& uuid, void* data, BOOL bold, BOOL online) -{ - LLSD row; - row["id"] = uuid; - row["target"] = LLNameListCtrl::GROUP; - row["columns"][0]["value"] = ""; // name will be looked up - row["columns"][0]["width"] = COL_1_WIDTH; - row["columns"][0]["font"] = "SANSSERIF"; - row["columns"][0]["font-style"] = bold ? "BOLD" : "NORMAL"; - row["columns"][1]["value"] = online ? sOnlineDescriptor : ""; - row["columns"][1]["font"] = "SANSSERIF"; - row["columns"][1]["font-style"] = "BOLD"; - LLScrollListItem* itemp = mSelectionList->addElement(row); - itemp->setUserdata(data); - - if (mSelectionList->getFirstSelectedIndex() == -1) - { - mSelectionList->selectFirstItem(); - } -} - -void LLFloaterNewIM::addAgent(const LLUUID& uuid, void* data, BOOL online) -{ - LLSD row; - row["id"] = uuid; - row["target"] = LLNameListCtrl::INDIVIDUAL; - row["columns"][0]["value"] = ""; - row["columns"][0]["width"] = COL_1_WIDTH; - row["columns"][0]["font"] = "SANSSERIF"; - row["columns"][0]["font-style"] = online ? "BOLD" : "NORMAL"; - row["columns"][1]["value"] = online ? sOnlineDescriptor : ""; - row["columns"][1]["font"] = "SANSSERIF"; - row["columns"][1]["font-style"] = "BOLD"; - LLScrollListItem* itemp = mSelectionList->addElement(row); - itemp->setUserdata(data); - - if (mSelectionList->getFirstSelectedIndex() == -1) - { - mSelectionList->selectFirstItem(); - } -} - -BOOL LLFloaterNewIM::isUUIDAvailable(const LLUUID& uuid) -{ - std::vector data_list = mSelectionList->getAllData(); - std::vector::iterator data_itor; - for (data_itor = data_list.begin(); data_itor != data_list.end(); ++data_itor) - { - LLScrollListItem* item = *data_itor; - if(item->getUUID() == uuid) - { - return TRUE; - } - } - return FALSE; -} - -void LLFloaterNewIM::onStart(void* userdata) -{ - LLFloaterNewIM* self = (LLFloaterNewIM*) userdata; - - LLScrollListItem* item = self->mSelectionList->getFirstSelected(); - if(item) - { - const LLScrollListCell* cell = item->getColumn(0); - std::string name(cell->getValue()); - - // *NOTE: Do a live detrmination of what type of session it - // should be. If we restrict the new im panel to online users, - // then we can remove some of this code. - EInstantMessage type; - EInstantMessage* t = (EInstantMessage*)item->getUserdata(); - if(t) type = (*t); - else type = LLIMMgr::defaultIMTypeForAgent(item->getUUID()); - gIMMgr->addSession(name, type, item->getUUID()); - - make_ui_sound("UISndStartIM"); - } - else - { - make_ui_sound("UISndInvalidOp"); - } -} - - -// static -void LLFloaterNewIM::onClickClose(void *userdata) -{ - gIMMgr->setFloaterOpen(FALSE); -} - - -BOOL LLFloaterNewIM::handleKeyHere(KEY key, MASK mask) -{ - BOOL handled = LLFloater::handleKeyHere(key, mask); - if (KEY_ESCAPE == key && mask == MASK_NONE) - { - handled = TRUE; - // Close talk panel on escape - gIMMgr->toggle(NULL); - } - - // Might need to call base class here if not handled - return handled; -} - -BOOL LLFloaterNewIM::canClose() -{ - if (getHost()) - { - LLMultiFloater* hostp = (LLMultiFloater*)getHost(); - // if we are the only tab in the im view, go ahead and close - return hostp->getFloaterCount() == 1; - } - return TRUE; -} - -void LLFloaterNewIM::close(bool app_quitting) -{ - if (getHost()) - { - LLMultiFloater* hostp = (LLMultiFloater*)getHost(); - hostp->close(); - } - else - { - LLFloater::close(app_quitting); - } -} - -S32 LLFloaterNewIM::getScrollPos() -{ - return mSelectionList->getScrollPos(); -} - -void LLFloaterNewIM::setScrollPos( S32 pos ) -{ - mSelectionList->setScrollPos( pos ); -} diff --git a/indra/newview/llfloaternewim.h b/indra/newview/llfloaternewim.h deleted file mode 100644 index 9aff36c94..000000000 --- a/indra/newview/llfloaternewim.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @file llfloaternewim.h - * @brief Panel allowing the user to create a new IM session. - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_FLOATER_NEW_IM_H -#define LL_FLOATER_NEW_IM_H - -#include "llfloater.h" - -class LLNameListCtrl; - -class LLFloaterNewIM : public LLFloater -{ -public: - LLFloaterNewIM(); - /*virtual*/ ~LLFloaterNewIM(); - - /*virtual*/ BOOL postBuild(); - - /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); - virtual BOOL canClose(); - virtual void close(bool app_quitting); - - static void onStart(void* userdata); - static void onClickClose(void* userdata); - - void clearAllTargets(); - - // add a scroll list item which has everything specified - useful - // for special IM targets like everyone. - void addSpecial(const LLUUID& uuid, const std::string& name, - void* data, BOOL bold, BOOL online); - - // add a scroll list item for an agent - the name will be autoupdated - // as it appears - void addAgent(const LLUUID& uuid, void* data, BOOL online); - void addGroup(const LLUUID& uuid, void* data, BOOL bold, BOOL online); - - void addDefaultTargets(); - BOOL isUUIDAvailable(const LLUUID& uuid); - - S32 getScrollPos(); - void setScrollPos( S32 pos ); - -protected: - LLNameListCtrl* mSelectionList; -}; - -#endif // LL_NEWIMPANEL_H diff --git a/indra/newview/llfloaterpermissionsmgr.cpp b/indra/newview/llfloaterpermissionsmgr.cpp index 14025ff72..750cd8bfd 100644 --- a/indra/newview/llfloaterpermissionsmgr.cpp +++ b/indra/newview/llfloaterpermissionsmgr.cpp @@ -122,12 +122,12 @@ void LLPermissionsView::addPermissionsData(const std::string& object_name, const y -= LINE + VPAD; LLRect btn_rect(HPAD, y + BTN_HEIGHT, 120, y); - LLButton* button = new LLButton(std::string("Revoke permissions"), btn_rect, LLStringUtil::null, std::bind(&LLPermissionsView::revokePermissions, object_id, permissions_flags)); + LLButton* button = new LLButton(std::string("Revoke permissions"), btn_rect, LLStringUtil::null, boost::bind(&LLPermissionsView::revokePermissions, object_id, permissions_flags)); button->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM); addChild(button); /*btn_rect.set(HPAD + 120 + HPAD, y + BTN_HEIGHT, HPAD + 120 + HPAD + 120, y); - button = new LLButton(std::string("Find in world"), btn_rect, LLStringUtil::null, std::bind(&LLPermissionsView::findObject, object_id, permissions_flags)); + button = new LLButton(std::string("Find in world"), btn_rect, LLStringUtil::null, boost::bind(&LLPermissionsView::findObject, object_id, permissions_flags)); button->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM); addChild(button);*/ } diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 5648e0296..ed0b07be4 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -54,7 +54,6 @@ #include "llpanelnetwork.h" #include "llpanelaudioprefs.h" #include "llpaneldisplay.h" -#include "llpaneldebug.h" #include "llpanelgeneral.h" #include "llpanelinput.h" #include "llpanellogin.h" diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index c55afa92b..387c20ccc 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -46,7 +46,6 @@ class LLPanelGeneral; class LLPanelInput; class LLPanelDisplay; class LLPanelAudioPrefs; -class LLPanelDebug; class LLPanelNetwork; class LLPanelWeb; class LLMessageSystem; @@ -90,7 +89,6 @@ private: LLPanelNetwork *mNetworkPanel; LLPanelDisplay *mDisplayPanel; LLPanelAudioPrefs *mAudioPanel; -// LLPanelDebug *mDebugPanel; LLPrefsChat *mPrefsChat; LLPrefsVoice *mPrefsVoice; LLPrefsIM *mPrefsIM; diff --git a/indra/newview/llfloaterproperties.h b/indra/newview/llfloaterproperties.h index c8e51c02b..69c5eead2 100644 --- a/indra/newview/llfloaterproperties.h +++ b/indra/newview/llfloaterproperties.h @@ -52,7 +52,7 @@ class LLTextBox; class LLPropertiesObserver; -class LLFloaterProperties : public LLFloater, LLInstanceTracker +class LLFloaterProperties : public LLFloater, public LLInstanceTracker { public: static LLFloaterProperties* find(const LLUUID& item_id, diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 102d950f5..83ab8b0e8 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -1,12 +1,11 @@ /** * @file llfloaterreporter.cpp - * @brief Bug and abuse reports. + * @brief Abuse reports. * * $LicenseInfo:firstyear=2002&license=viewergpl$ - * + * Second Life Viewer Source Code * Copyright (c) 2002-2009, Linden Research, Inc. * - * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab * to you under the terms of the GNU General Public License, version 2.0 * ("GPL"), unless you have obtained a separate licensing agreement @@ -39,30 +38,23 @@ // linden library includes #include "llassetstorage.h" +#include "llavatarnamecache.h" #include "llcachename.h" #include "llfontgl.h" -#include "llgl.h" // for renderer #include "llimagej2c.h" #include "llinventory.h" #include "llnotificationsutil.h" #include "llstring.h" #include "llsys.h" -#include "sgversion.h" #include "message.h" #include "v3math.h" // viewer project includes #include "llagent.h" #include "llbutton.h" -#include "llcheckboxctrl.h" -#include "llinventorypanel.h" -#include "lllineeditor.h" #include "lltexturectrl.h" #include "llscrolllistctrl.h" -#include "llimview.h" -#include "lltextbox.h" #include "lldispatcher.h" -#include "llviewertexteditor.h" #include "llviewerobject.h" #include "llviewerregion.h" #include "llcombobox.h" @@ -80,7 +72,7 @@ #include "llfloateravatarpicker.h" #include "lldir.h" #include "llselectmgr.h" -#include "llviewerbuild.h" +#include "sgversion.h" #include "lluictrlfactory.h" #include "llviewernetwork.h" @@ -88,10 +80,6 @@ #include "lltrans.h" -// [RLVa:KB] -#include "rlvhandler.h" -// [/RLVa:KB] - const U32 INCLUDE_SCREENSHOT = 0x01 << 0; class AIHTTPTimeoutPolicy; @@ -101,125 +89,23 @@ extern AIHTTPTimeoutPolicy userReportResponder_timeout; // Globals //----------------------------------------------------------------------------- -// this map keeps track of current reporter instances -// there can only be one instance of each reporter type -LLMap< EReportType, LLFloaterReporter* > gReporterInstances; - -// keeps track of where email is going to - global to avoid a pile -// of static/non-static access outside my control -namespace { - static BOOL gDialogVisible = FALSE; -} - //----------------------------------------------------------------------------- // Member functions //----------------------------------------------------------------------------- -LLFloaterReporter::LLFloaterReporter( - const std::string& name, - const LLRect& rect, - const std::string& title, - EReportType report_type) - : - LLFloater(name, rect, title), - mReportType(report_type), +LLFloaterReporter::LLFloaterReporter() +: LLFloater(), + mReportType(COMPLAINT_REPORT), mObjectID(), mScreenID(), mAbuserID(), + mOwnerName(), mDeselectOnClose( FALSE ), mPicking( FALSE), mPosition(), mCopyrightWarningSeen( FALSE ), mResourceDatap(new LLResourceData()) { - if (report_type == BUG_REPORT) - { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_report_bug.xml"); - } - else - { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_report_abuse.xml"); - } - - childSetText("abuse_location_edit", gAgent.getSLURL() ); - -// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-1.0.0a - if (rlv_handler_t::isEnabled()) - { - // Can't filter these since they get sent as part of the report so just hide them instead - if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) - { - childSetVisible("abuse_location_edit", false); - childSetVisible("pos_field", false); - } - if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) - { - childSetVisible("owner_name", false); - childSetVisible("abuser_name_edit", false); - } - } -// [/RLVa:KB] - - LLButton* pick_btn = getChild("pick_btn"); - if (pick_btn) - { - // XUI: Why aren't these in viewerart.ini? - pick_btn->setImages( std::string("UIImgFaceUUID"), - std::string("UIImgFaceSelectedUUID") ); - childSetAction("pick_btn", onClickObjPicker, this); - } - - if (report_type != BUG_REPORT) - { - // abuser name is selected from a list - LLLineEditor* le = getChild("abuser_name_edit"); - le->setEnabled( FALSE ); - } - - childSetAction("select_abuser", onClickSelectAbuser, this); - - childSetAction("send_btn", onClickSend, this); - childSetAction("cancel_btn", onClickCancel, this); - - enableControls(TRUE); - - // convert the position to a string - LLVector3d pos = gAgent.getPositionGlobal(); - LLViewerRegion *regionp = gAgent.getRegion(); - if (regionp) - { - pos -= regionp->getOriginGlobal(); - } - setPosBox(pos); - - gReporterInstances.addData(report_type, this); - - // Take a screenshot, but don't draw this floater. - setVisible(FALSE); - takeScreenshot(); - setVisible(TRUE); - - // Default text to be blank - childSetText("object_name", LLStringUtil::null); - childSetText("owner_name", LLStringUtil::null); - - childSetFocus("summary_edit"); - - mDefaultSummary = childGetText("details_edit"); - - gDialogVisible = TRUE; - - // only request details for abuse reports (not BUG reports) - if (report_type != BUG_REPORT) - { - // send a message and ask for information about this region - - // result comes back in processRegionInfo(..) - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("RequestRegionInfo"); - msg->nextBlock("AgentData"); - msg->addUUID("AgentID", gAgent.getID()); - msg->addUUID("SessionID", gAgent.getSessionID()); - gAgent.sendReliableMessage(); - }; + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_report_abuse.xml"); } // static @@ -228,16 +114,77 @@ void LLFloaterReporter::processRegionInfo(LLMessageSystem* msg) U32 region_flags; msg->getU32("RegionInfo", "RegionFlags", region_flags); - if ( gDialogVisible ) + if (LLFloaterReporter::instanceExists() && LLFloaterReporter::getInstance()->getVisible()) { LLNotificationsUtil::add("HelpReportAbuseEmailLL"); - }; + } } +// virtual +BOOL LLFloaterReporter::postBuild() +{ + getChild("abuse_location_edit")->setValue(gAgent.getSLURL()); + enableControls(TRUE); + + // convert the position to a string + LLVector3d pos = gAgent.getPositionGlobal(); + LLViewerRegion *regionp = gAgent.getRegion(); + if (regionp) + { + getChild("sim_field")->setValue(regionp->getName()); + pos -= regionp->getOriginGlobal(); + } + setPosBox(pos); + + // Take a screenshot, but don't draw this floater. + setVisible(FALSE); + takeScreenshot(); + setVisible(TRUE); + + // Default text to be blank + getChild("object_name")->setValue(LLStringUtil::null); + getChild("owner_name")->setValue(LLStringUtil::null); + mOwnerName = LLStringUtil::null; + + getChild("summary_edit")->setFocus(TRUE); + + mDefaultSummary = getChild("details_edit")->getValue().asString(); + + // send a message and ask for information about this region - + // result comes back in processRegionInfo(..) + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("RequestRegionInfo"); + msg->nextBlock("AgentData"); + msg->addUUID("AgentID", gAgent.getID()); + msg->addUUID("SessionID", gAgent.getSessionID()); + gAgent.sendReliableMessage(); + + + // abuser name is selected from a list + LLUICtrl* le = getChild("abuser_name_edit"); + le->setEnabled( false ); + + LLButton* pick_btn = getChild("pick_btn"); + // XUI: Why aren't these in viewerart.ini? + pick_btn->setImages(std::string("UIImgFaceUUID"), + std::string("UIImgFaceSelectedUUID") ); + childSetAction("pick_btn", onClickObjPicker, this); + childSetAction("select_abuser", boost::bind(&LLFloaterReporter::onClickSelectAbuser, this)); + + childSetAction("send_btn", onClickSend, this); + childSetAction("cancel_btn", onClickCancel, this); + // grab the user's name + std::string reporter; + gAgent.buildFullname(reporter); + getChild("reporter_field")->setValue(reporter); + + center(); + + return TRUE; +} // virtual LLFloaterReporter::~LLFloaterReporter() { - gReporterInstances.removeData(mReportType); // child views automatically deleted mObjectID = LLUUID::null; @@ -252,27 +199,26 @@ LLFloaterReporter::~LLFloaterReporter() mMCDList.clear(); delete mResourceDatap; - gDialogVisible = FALSE; } // virtual void LLFloaterReporter::draw() { - childSetEnabled("screen_check", TRUE ); + getChildView("screen_check")->setEnabled(TRUE ); LLFloater::draw(); } void LLFloaterReporter::enableControls(BOOL enable) { - childSetEnabled("category_combo", enable); - childSetEnabled("screen_check", enable); - childDisable("screenshot"); - childSetEnabled("pick_btn", enable); - childSetEnabled("summary_edit", enable); - childSetEnabled("details_edit", enable); - childSetEnabled("send_btn", enable); - childSetEnabled("cancel_btn", enable); + getChildView("category_combo")->setEnabled(enable); + getChildView("screen_check")->setEnabled(enable); + getChildView("screenshot")->setEnabled(false); + getChildView("pick_btn")->setEnabled(enable); + getChildView("summary_edit")->setEnabled(enable); + getChildView("details_edit")->setEnabled(enable); + getChildView("send_btn")->setEnabled(enable); + getChildView("cancel_btn")->setEnabled(enable); } void LLFloaterReporter::getObjectInfo(const LLUUID& object_id) @@ -287,28 +233,29 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id) mObjectID = object_id; - if (LLUUID::null != mObjectID) + if (mObjectID.notNull()) { // get object info for the user's benefit - LLViewerObject* objectp = NULL; - objectp = gObjectList.findObject( mObjectID ); - if (objectp) + if (LLViewerObject* objectp = gObjectList.findObject(mObjectID)) { if ( objectp->isAttachment() ) { objectp = (LLViewerObject*)objectp->getRoot(); + mObjectID = objectp->getID(); } // correct the region and position information LLViewerRegion *regionp = objectp->getRegion(); if (regionp) { - childSetText("sim_field", regionp->getName()); + getChild("sim_field")->setValue(regionp->getName()); // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) +/* if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) { childSetText("sim_field", RlvStrings::getString(RLV_STRING_HIDDEN_REGION)); } +*/ // [/RLVa:KB] LLVector3d global_pos; global_pos.setVec(objectp->getPositionRegion()); @@ -317,38 +264,14 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id) if (objectp->isAvatar()) { - // we have the information we need - std::string object_owner; - - LLNameValue* firstname = objectp->getNVPair("FirstName"); - LLNameValue* lastname = objectp->getNVPair("LastName"); - if (firstname && lastname) - { - object_owner.append(firstname->getString()); - object_owner.append(1, ' '); - object_owner.append(lastname->getString()); - } - else - { - object_owner.append("Unknown"); - } - childSetText("object_name", object_owner); -// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RVLa-1.0.0e - if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) - { - childSetVisible("object_name", false); // Hide the object name if the picked object represents an avataz - } -// [/RLVa:KB] - childSetText("owner_name", object_owner); - childSetText("abuser_name_edit", object_owner); - mAbuserID = object_id; + setFromAvatarID(mObjectID); } else { // we have to query the simulator for information // about this object LLMessageSystem* msg = gMessageSystem; - U32 request_flags = (mReportType == BUG_REPORT) ? BUG_REPORT_REQUEST : COMPLAINT_REPORT_REQUEST; + U32 request_flags = COMPLAINT_REPORT_REQUEST; msg->newMessageFast(_PREHASH_RequestObjectPropertiesFamily); msg->nextBlockFast(_PREHASH_AgentData); msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); @@ -363,28 +286,50 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id) } } - -// static -void LLFloaterReporter::onClickSelectAbuser(void *userdata) +void LLFloaterReporter::onClickSelectAbuser() { - LLFloaterReporter *self = (LLFloaterReporter *)userdata; - - gFloaterView->getParentFloater(self)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLFloaterReporter::callbackAvatarID, self, _1, _2), FALSE, TRUE )); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterReporter::callbackAvatarID, this, _1, _2), FALSE, TRUE ); + if (picker) + { + gFloaterView->getParentFloater(this)->addDependentFloater(picker); + } } void LLFloaterReporter::callbackAvatarID(const uuid_vec_t& ids, const std::vector& names) { if (ids.empty() || names.empty()) return; - // this should never be called in a bug report but here for safety. - if ( mReportType != BUG_REPORT ) - { - childSetText("abuser_name_edit", names[0].getCompleteName() ); + getChild("abuser_name_edit")->setValue(names[0].getCompleteName()); - mAbuserID = ids[0]; + mAbuserID = ids[0]; - refresh(); - }; + refresh(); + +} + +void LLFloaterReporter::setFromAvatarID(const LLUUID& avatar_id) +{ + mAbuserID = mObjectID = avatar_id; + std::string avatar_link; + + if (LLAvatarNameCache::getPNSName(avatar_id, avatar_link)) + { + getChild("owner_name")->setValue(avatar_link); + getChild("object_name")->setValue(avatar_link); + getChild("abuser_name_edit")->setValue(avatar_link); + return; + } + + LLAvatarNameCache::get(avatar_id, boost::bind(&LLFloaterReporter::onAvatarNameCache, this, _1, _2)); +} + +void LLFloaterReporter::onAvatarNameCache(const LLUUID& avatar_id, const LLAvatarName& av_name) +{ + std::string avatar_link; + LLAvatarNameCache::getPNSName(av_name, avatar_link); + getChild("owner_name")->setValue(avatar_link); + getChild("object_name")->setValue(avatar_link); + getChild("abuser_name_edit")->setValue(avatar_link); } @@ -400,39 +345,34 @@ void LLFloaterReporter::onClickSend(void *userdata) if(self->validateReport()) { - // only show copyright alert for abuse reports - if ( self->mReportType != BUG_REPORT ) + const int IP_CONTENT_REMOVAL = 66; + const int IP_PERMISSONS_EXPLOIT = 37; + LLComboBox* combo = self->getChild( "category_combo"); + int category_value = combo->getSelectedValue().asInteger(); + + if ( ! self->mCopyrightWarningSeen ) { - const int IP_CONTENT_REMOVAL = 66; - const int IP_PERMISSONS_EXPLOIT = 37; - LLComboBox* combo = self->getChild( "category_combo"); - int category_value = combo->getSelectedValue().asInteger(); - - if ( ! self->mCopyrightWarningSeen ) + std::string details_lc = self->getChild("details_edit")->getValue().asString(); + LLStringUtil::toLower( details_lc ); + std::string summary_lc = self->getChild("summary_edit")->getValue().asString(); + LLStringUtil::toLower( summary_lc ); + if ( details_lc.find( "copyright" ) != std::string::npos || + summary_lc.find( "copyright" ) != std::string::npos || + category_value == IP_CONTENT_REMOVAL || + category_value == IP_PERMISSONS_EXPLOIT) { - - std::string details_lc = self->childGetText("details_edit"); - LLStringUtil::toLower( details_lc ); - std::string summary_lc = self->childGetText("summary_edit"); - LLStringUtil::toLower( summary_lc ); - if ( details_lc.find( "copyright" ) != std::string::npos || - summary_lc.find( "copyright" ) != std::string::npos || - category_value == IP_CONTENT_REMOVAL || - category_value == IP_PERMISSONS_EXPLOIT) - { - LLNotificationsUtil::add("HelpReportAbuseContainsCopyright"); - self->mCopyrightWarningSeen = TRUE; - return; - } - } - else if (category_value == IP_CONTENT_REMOVAL) - { - // IP_CONTENT_REMOVAL *always* shows the dialog - - // ergo you can never send that abuse report type. LLNotificationsUtil::add("HelpReportAbuseContainsCopyright"); + self->mCopyrightWarningSeen = TRUE; return; } } + else if (category_value == IP_CONTENT_REMOVAL) + { + // IP_CONTENT_REMOVAL *always* shows the dialog - + // ergo you can never send that abuse report type. + LLNotificationsUtil::add("HelpReportAbuseContainsCopyright"); + return; + } LLUploadDialog::modalUploadDialog(LLTrans::getString("uploading_abuse_report")); // *TODO don't upload image if checkbox isn't checked @@ -445,10 +385,10 @@ void LLFloaterReporter::onClickSend(void *userdata) } else { - if(self->childGetValue("screen_check")) + if(self->getChild("screen_check")->getValue()) { - self->childDisable("send_btn"); - self->childDisable("cancel_btn"); + self->getChildView("send_btn")->setEnabled(FALSE); + self->getChildView("cancel_btn")->setEnabled(FALSE); // the callback from uploading the image calls sendReportViaLegacy() self->uploadImage(); } @@ -486,8 +426,9 @@ void LLFloaterReporter::onClickObjPicker(void *userdata) LLToolObjPicker::getInstance()->setExitCallback(LLFloaterReporter::closePickTool, self); LLToolMgr::getInstance()->setTransientTool(LLToolObjPicker::getInstance()); self->mPicking = TRUE; - self->childSetText("object_name", LLStringUtil::null); - self->childSetText("owner_name", LLStringUtil::null); + self->getChild("object_name")->setValue(LLStringUtil::null); + self->getChild("owner_name")->setValue(LLStringUtil::null); + self->mOwnerName = LLStringUtil::null; LLButton* pick_btn = self->getChild("pick_btn"); if (pick_btn) pick_btn->setToggleState(TRUE); } @@ -511,62 +452,34 @@ void LLFloaterReporter::closePickTool(void *userdata) // static void LLFloaterReporter::showFromMenu(EReportType report_type) { - if (gReporterInstances.checkData(report_type)) + if (COMPLAINT_REPORT != report_type) { - // ...bring that window to front - LLFloaterReporter *f = gReporterInstances.getData(report_type); - f->open(); /* Flawfinder: ignore */ + llwarns << "Unknown LLViewerReporter type : " << report_type << llendl; + return; } - else + + LLFloaterReporter* f = getInstance(); + if (f) { - LLFloaterReporter *f; - if (BUG_REPORT == report_type) - { - f = LLFloaterReporter::createNewBugReporter(); - } - else if (COMPLAINT_REPORT == report_type) - { - f = LLFloaterReporter::createNewAbuseReporter(); - } - else - { - llwarns << "Unknown LLViewerReporter type : " << report_type << llendl; - return; - } - - f->center(); - - if (report_type == BUG_REPORT) - { - LLNotificationsUtil::add("HelpReportBug"); - } - else - { - // popup for abuse reports is triggered elsewhere - } - - // grab the user's name - std::string fullname; - gAgent.buildFullname(fullname); - f->childSetText("reporter_field", fullname); + f->setReportType(report_type); } } // static -void LLFloaterReporter::showFromObject(const LLUUID& object_id) +void LLFloaterReporter::show(const LLUUID& object_id, const std::string& avatar_name) { - LLFloaterReporter* f = createNewAbuseReporter(); - f->center(); - f->setFocus(TRUE); + LLFloaterReporter* f = getInstance(); - // grab the user's name - std::string fullname; - gAgent.buildFullname(fullname); - f->childSetText("reporter_field", fullname); - - // Request info for this object - f->getObjectInfo(object_id); + if (avatar_name.empty()) + { + // Request info for this object + f->getObjectInfo(object_id); + } + else + { + f->setFromAvatarID(object_id); + } // Need to deselect on close f->mDeselectOnClose = TRUE; @@ -576,55 +489,33 @@ void LLFloaterReporter::showFromObject(const LLUUID& object_id) // static -LLFloaterReporter* LLFloaterReporter::getReporter(EReportType report_type) +void LLFloaterReporter::showFromObject(const LLUUID& object_id) { - LLFloaterReporter *self = NULL; - if (gReporterInstances.checkData(report_type)) - { - // ...bring that window to front - self = gReporterInstances.getData(report_type); - } - return self; + show(object_id); } -LLFloaterReporter* LLFloaterReporter::createNewAbuseReporter() +// static +void LLFloaterReporter::showFromAvatar(const LLUUID& avatar_id, const std::string avatar_name) { - return new LLFloaterReporter("complaint_reporter", - LLRect(), - "Report Abuse", - COMPLAINT_REPORT); + show(avatar_id, avatar_name); } -//static -LLFloaterReporter* LLFloaterReporter::createNewBugReporter() -{ - return new LLFloaterReporter("bug_reporter", - LLRect(), - "Report Bug", - BUG_REPORT); -} - - - void LLFloaterReporter::setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id) { - childSetText("object_name", object_name); -// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RVLa-1.0.0e - if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) - { - childSetVisible("object_name", true); // Show the object name if the picked object is actually an object - } -// [/RLVa:KB] - childSetText("owner_name", owner_name); - childSetText("abuser_name_edit", owner_name); + getChild("object_name")->setValue(object_name); + + + getChild("owner_name")->setValue(owner_name); + getChild("abuser_name_edit")->setValue(owner_name); mAbuserID = owner_id; + mOwnerName = owner_name; } bool LLFloaterReporter::validateReport() { // Ensure user selected a category from the list - LLSD category_sd = childGetValue("category_combo"); + LLSD category_sd = getChild("category_combo")->getValue(); U8 category = (U8)category_sd.asInteger(); if(category >= 100) //This is here for reasons (like shenanigans) { @@ -633,55 +524,39 @@ bool LLFloaterReporter::validateReport() } if (category == 0) { - if ( mReportType != BUG_REPORT ) - { - LLNotificationsUtil::add("HelpReportAbuseSelectCategory"); - } - else - { - LLNotificationsUtil::add("HelpReportAbuseAbuserNameEmpty"); - } + LLNotificationsUtil::add("HelpReportAbuseSelectCategory"); return false; } - if ( mReportType != BUG_REPORT ) - { - if ( childGetText("abuser_name_edit").empty() ) - { - LLNotificationsUtil::add("HelpReportAbuseAbuserLocationEmpty"); - return false; - }; - - if ( childGetText("abuse_location_edit").empty() ) - { - LLNotificationsUtil::add("HelpReportAbuseAbuserLocationEmpty"); - return false; - }; - }; - if ( childGetText("summary_edit").empty() ) + if ( getChild("abuser_name_edit")->getValue().asString().empty() ) { - if ( mReportType != BUG_REPORT ) - { - LLNotificationsUtil::add("HelpReportAbuseSummaryEmpty"); - } - else - { - LLNotificationsUtil::add("HelpReportBugSummaryEmpty"); - } + LLNotificationsUtil::add("HelpReportAbuseAbuserNameEmpty"); + return false; + } + + if ( getChild("abuse_location_edit")->getValue().asString().empty() ) + { + LLNotificationsUtil::add("HelpReportAbuseAbuserLocationEmpty"); + return false; + } + + if ( getChild("abuse_location_edit")->getValue().asString().empty() ) + { + LLNotificationsUtil::add("HelpReportAbuseAbuserLocationEmpty"); + return false; + } + + + if ( getChild("summary_edit")->getValue().asString().empty() ) + { + LLNotificationsUtil::add("HelpReportAbuseSummaryEmpty"); return false; }; - if ( childGetText("details_edit") == mDefaultSummary ) + if ( getChild("details_edit")->getValue().asString() == mDefaultSummary ) { - if ( mReportType != BUG_REPORT ) - { LLNotificationsUtil::add("HelpReportAbuseDetailsEmpty"); - } - else - { - LLNotificationsUtil::add("HelpReportBugDetailsEmpty"); - } return false; }; return true; @@ -710,65 +585,45 @@ LLSD LLFloaterReporter::gatherReport() #if LL_WINDOWS const char* platform = "Win"; - const char* short_platform = "O:W"; #elif LL_DARWIN const char* platform = "Mac"; - const char* short_platform = "O:M"; #elif LL_LINUX const char* platform = "Lnx"; - const char* short_platform = "O:L"; #elif LL_SOLARIS const char* platform = "Sol"; - const char* short_platform = "O:S"; #else const char* platform = "???"; - const char* short_platform = "O:?"; #endif - if ( mReportType == BUG_REPORT) - { - summary << short_platform << " V" << gVersionMajor << "." - << gVersionMinor << "." - << gVersionPatch << "." - << gVersionBuild - << " (" << regionp->getName() << ")" - << "[" << category_name << "] " - << "\"" << childGetValue("summary_edit").asString() << "\""; - } - else - { - summary << "" - << " |" << regionp->getName() << "|" // region reporter is currently in. - << " (" << childGetText("abuse_location_edit") << ")" // region abuse occured in (freeform text - no LLRegionPicker tool) - << " [" << category_name << "] " // updated category - << " {" << childGetText("abuser_name_edit") << "} " // name of abuse entered in report (chosen using LLAvatarPicker) - << " \"" << childGetValue("summary_edit").asString() << "\""; // summary as entered - }; + + summary << "" + << " |" << regionp->getName() << "|" // region reporter is currently in. + << " (" << getChild("abuse_location_edit")->getValue().asString() << ")" // region abuse occured in (freeform text - no LLRegionPicker tool) + << " [" << category_name << "] " // updated category + << " {" << getChild("abuser_name_edit")->getValue().asString() << "} " // name of abuse entered in report (chosen using LLAvatarPicker) + << " \"" << getChild("summary_edit")->getValue().asString() << "\""; // summary as entered + std::ostringstream details; - if (mReportType != BUG_REPORT) - { - details << "V" << gVersionMajor << "." // client version moved to body of email for abuse reports - << gVersionMinor << "." - << gVersionPatch << "." - << gVersionBuild << std::endl << std::endl; - } - std::string object_name = childGetText("object_name"); - std::string owner_name = childGetText("owner_name"); - if (!object_name.empty() && !owner_name.empty()) + + details << "V" << gVersionMajor << "." // client version moved to body of email for abuse reports + << gVersionMinor << "." + << gVersionPatch << "." + << gVersionBuild << std::endl << std::endl; + + std::string object_name = getChild("object_name")->getValue().asString(); + if (!object_name.empty() && !mOwnerName.empty()) { details << "Object: " << object_name << "\n"; - details << "Owner: " << owner_name << "\n"; + details << "Owner: " << mOwnerName << "\n"; } - if ( mReportType != BUG_REPORT ) - { - details << "Abuser name: " << childGetText("abuser_name_edit") << " \n"; - details << "Abuser location: " << childGetText("abuse_location_edit") << " \n"; - }; - details << childGetValue("details_edit").asString(); + details << "Abuser name: " << getChild("abuser_name_edit")->getValue().asString() << " \n"; + details << "Abuser location: " << getChild("abuse_location_edit")->getValue().asString() << " \n"; + + details << getChild("details_edit")->getValue().asString(); std::string version_string; version_string = llformat( @@ -784,14 +639,14 @@ LLSD LLFloaterReporter::gatherReport() // only send a screenshot ID if we're asked to and the email is // going to LL - Estate Owners cannot see the screenshot asset LLUUID screenshot_id = LLUUID::null; - if (childGetValue("screen_check")) + if (getChild("screen_check")->getValue()) { - screenshot_id = childGetValue("screenshot"); - }; + screenshot_id = getChild("screenshot")->getValue(); + } LLSD report = LLSD::emptyMap(); report["report-type"] = (U8) mReportType; - report["category"] = childGetValue("category_combo"); + report["category"] = getChild("category_combo")->getValue(); report["position"] = mPosition.getValue(); report["check-flags"] = (U8)0; // this is not used report["screenshot-id"] = screenshot_id; @@ -877,7 +732,7 @@ public: void LLFloaterReporter::sendReportViaCaps(std::string url, std::string sshot_url, const LLSD& report) { - if(childGetValue("screen_check").asBoolean() && !sshot_url.empty()) + if(getChild("screen_check")->getValue().asBoolean() && !sshot_url.empty()) { // try to upload screenshot LLHTTPClient::post(sshot_url, report, new LLUserReportScreenshotResponder(report, @@ -893,11 +748,11 @@ void LLFloaterReporter::sendReportViaCaps(std::string url, std::string sshot_url void LLFloaterReporter::takeScreenshot() { - const S32 IMAGE_WIDTH = 1024; - const S32 IMAGE_HEIGHT = 768; + // Warning: This crops left and right in case of wide-screen monitor: + const S32 IMAGE_WIDTH = 1024; //gViewerWindow->getWindowWidthRaw(); + const S32 IMAGE_HEIGHT = 768; //gViewerWindow->getWindowHeightRaw(); LLPointer raw = new LLImageRaw; - // Warning: This crops left and right in case of wide-screen monitor: if( !gViewerWindow->rawSnapshot(raw, IMAGE_WIDTH, IMAGE_HEIGHT, (F32)IMAGE_WIDTH / IMAGE_HEIGHT, TRUE, FALSE)) { llwarns << "Unable to take screenshot" << llendl; @@ -911,15 +766,11 @@ void LLFloaterReporter::takeScreenshot() mResourceDatap->mExpectedUploadCost = 0; // we expect that abuse screenshots are free mResourceDatap->mAssetInfo.mTransactionID.generate(); mResourceDatap->mAssetInfo.mUuid = mResourceDatap->mAssetInfo.mTransactionID.makeAssetID(gAgent.getSecureSessionID()); - if (BUG_REPORT == mReportType) + + if (COMPLAINT_REPORT == mReportType) { mResourceDatap->mAssetInfo.mType = LLAssetType::AT_TEXTURE; - mResourceDatap->mPreferredLocation = LLFolderType::EType(-1); - } - else if (COMPLAINT_REPORT == mReportType) - { - mResourceDatap->mAssetInfo.mType = LLAssetType::AT_TEXTURE; - mResourceDatap->mPreferredLocation = LLFolderType::EType(-2); + mResourceDatap->mPreferredLocation = LLFolderType::EType(LLResourceData::INVALID_LOCATION); } else { @@ -987,11 +838,7 @@ void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data, } EReportType report_type = UNKNOWN_REPORT; - if (data->mPreferredLocation == -1) - { - report_type = BUG_REPORT; - } - else if (data->mPreferredLocation == -2) + if (data->mPreferredLocation == LLResourceData::INVALID_LOCATION) { report_type = COMPLAINT_REPORT; } @@ -1000,7 +847,7 @@ void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data, llwarns << "Unknown report type : " << data->mPreferredLocation << llendl; } - LLFloaterReporter *self = getReporter(report_type); + LLFloaterReporter *self = getInstance(); if (self) { self->mScreenID = uuid; @@ -1018,38 +865,38 @@ void LLFloaterReporter::setPosBox(const LLVector3d &pos) mPosition.mV[VX], mPosition.mV[VY], mPosition.mV[VZ]); - childSetText("pos_field", pos_string); + getChild("pos_field")->setValue(pos_string); } -void LLFloaterReporter::setDescription(const std::string& description, LLMeanCollisionData *mcd) -{ - LLFloaterReporter *self = gReporterInstances[COMPLAINT_REPORT]; - if (self) - { - self->childSetText("details_edit", description); +//void LLFloaterReporter::setDescription(const std::string& description, LLMeanCollisionData *mcd) +//{ +// LLFloaterReporter *self = getInstance(); +// if (self) +// { +// self->getChild("details_edit")->setValue(description); - for_each(self->mMCDList.begin(), self->mMCDList.end(), DeletePointer()); - self->mMCDList.clear(); - if (mcd) - { - self->mMCDList.push_back(new LLMeanCollisionData(mcd)); - } - } -} +// for_each(self->mMCDList.begin(), self->mMCDList.end(), DeletePointer()); +// self->mMCDList.clear(); +// if (mcd) +// { +// self->mMCDList.push_back(new LLMeanCollisionData(mcd)); +// } +// } +//} -void LLFloaterReporter::addDescription(const std::string& description, LLMeanCollisionData *mcd) -{ - LLFloaterReporter *self = gReporterInstances[COMPLAINT_REPORT]; - if (self) - { - LLTextEditor* text = self->getChild("details_edit"); - if (text) - { - text->insertText(description); - } - if (mcd) - { - self->mMCDList.push_back(new LLMeanCollisionData(mcd)); - } - } -} +//void LLFloaterReporter::addDescription(const std::string& description, LLMeanCollisionData *mcd) +//{ +// LLFloaterReporter *self = getInstance(); +// if (self) +// { +// LLTextEditor* text = self->getChild("details_edit"); +// if (text) +// { +// text->insertText(description); +// } +// if (mcd) +// { +// self->mMCDList.push_back(new LLMeanCollisionData(mcd)); +// } +// } +//} diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h index e4d13e906..1b10ed671 100644 --- a/indra/newview/llfloaterreporter.h +++ b/indra/newview/llfloaterreporter.h @@ -1,13 +1,12 @@ /** * @file llfloaterreporter.h * @author Andrew Meadows - * @brief Bug and abuse reports. + * @brief Abuse reports. * * $LicenseInfo:firstyear=2006&license=viewergpl$ - * + * Second Life Viewer Source Code * Copyright (c) 2006-2009, Linden Research, Inc. * - * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab * to you under the terms of the GNU General Public License, version 2.0 * ("GPL"), unless you have obtained a separate licensing agreement @@ -49,7 +48,7 @@ class LLMeanCollisionData; struct LLResourceData; // these flags are used to label info requests to the server -const U32 BUG_REPORT_REQUEST = 0x01 << 0; +//const U32 BUG_REPORT_REQUEST = 0x01 << 0; // DEPRECATED const U32 COMPLAINT_REPORT_REQUEST = 0x01 << 1; const U32 OBJECT_PAY_REQUEST = 0x01 << 2; @@ -74,48 +73,45 @@ enum EReportType { NULL_REPORT = 0, // don't use this value anywhere UNKNOWN_REPORT = 1, - BUG_REPORT = 2, + //BUG_REPORT = 2, // DEPRECATED COMPLAINT_REPORT = 3, CS_REQUEST_REPORT = 4 }; class LLFloaterReporter -: public LLFloater +: public LLFloater, public LLSingleton { public: - LLFloaterReporter(const std::string& name, - const LLRect &rect, - const std::string& title, - EReportType = UNKNOWN_REPORT); + LLFloaterReporter(); /*virtual*/ ~LLFloaterReporter(); - + /*virtual*/ BOOL postBuild(); virtual void draw(); + void setReportType(EReportType type) { mReportType = type; } + // Enables all buttons static void showFromMenu(EReportType report_type); static void showFromObject(const LLUUID& object_id); + static void showFromAvatar(const LLUUID& avatar_id, const std::string avatar_name); static void onClickSend (void *userdata); static void onClickCancel (void *userdata); static void onClickObjPicker (void *userdata); - static void onClickSelectAbuser (void *userdata); + void onClickSelectAbuser (); static void closePickTool (void *userdata); static void uploadDoneCallback(const LLUUID &uuid, void* user_data, S32 result, LLExtStat ext_status); static void addDescription(const std::string& description, LLMeanCollisionData *mcd = NULL); static void setDescription(const std::string& description, LLMeanCollisionData *mcd = NULL); - // returns a pointer to reporter of report_type - static LLFloaterReporter* getReporter(EReportType report_type); - static LLFloaterReporter* createNewAbuseReporter(); - static LLFloaterReporter* createNewBugReporter(); - // static static void processRegionInfo(LLMessageSystem* msg); void setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id); private: + static void show(const LLUUID& object_id, const std::string& avatar_name = LLStringUtil::null); + void takeScreenshot(); void sendReportViaCaps(std::string url); void uploadImage(); @@ -128,12 +124,16 @@ private: void enableControls(BOOL own_avatar); void getObjectInfo(const LLUUID& object_id); void callbackAvatarID(const uuid_vec_t& ids, const std::vector& names); + void setFromAvatarID(const LLUUID& avatar_id); + void onAvatarNameCache(const LLUUID& avatar_id, const LLAvatarName& av_name); private: EReportType mReportType; LLUUID mObjectID; LLUUID mScreenID; LLUUID mAbuserID; + // Store the real name, not the link, for upstream reporting + std::string mOwnerName; BOOL mDeselectOnClose; BOOL mPicking; LLVector3 mPosition; diff --git a/indra/newview/llfloaterteleporthistory.cpp b/indra/newview/llfloaterteleporthistory.cpp index 6f3d06407..bdb089e3c 100644 --- a/indra/newview/llfloaterteleporthistory.cpp +++ b/indra/newview/llfloaterteleporthistory.cpp @@ -353,7 +353,7 @@ void LLFloaterTeleportHistory::onShowOnMap(void* data) // point world map at position gFloaterWorldMap->trackURL(region, x, y, z); - LLFloaterWorldMap::show(NULL, TRUE); + LLFloaterWorldMap::show(true); } // static diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp index 700479406..8552b881a 100644 --- a/indra/newview/llfloatertos.cpp +++ b/indra/newview/llfloatertos.cpp @@ -85,7 +85,6 @@ LLFloaterTOS::LLFloaterTOS(ETOSType type, const std::string & message) : LLModalDialog( std::string(" "), 100, 100 ), mType(type), mMessage(message), - mWebBrowserWindowId( 0 ), mLoadCompleteCount( 0 ) { } diff --git a/indra/newview/llfloatertos.h b/indra/newview/llfloatertos.h index c5d587897..331458178 100644 --- a/indra/newview/llfloatertos.h +++ b/indra/newview/llfloatertos.h @@ -80,7 +80,6 @@ private: private: ETOSType mType; std::string mMessage; - int mWebBrowserWindowId; int mLoadCompleteCount; static LLFloaterTOS* sInstance; diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index a622770f0..e3532cfe8 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -42,8 +42,6 @@ #include "llagent.h" #include "llagentcamera.h" -#include "llviewerwindow.h" -#include "llwindow.h" #include "llbutton.h" #include "llcallingcard.h" #include "llcolorscheme.h" @@ -57,9 +55,8 @@ #include "llinventorymodelbackgroundfetch.h" #include "llinventoryobserver.h" #include "lllandmarklist.h" -#include "llnotificationsutil.h" #include "lllineeditor.h" -#include "llpreviewlandmark.h" +#include "llnotificationsutil.h" #include "llregionhandle.h" #include "llscrolllistctrl.h" #include "llsearcheditor.h" @@ -77,10 +74,9 @@ #include "llappviewer.h" #include "llmapimagetype.h" #include "llweb.h" +#include "llwindow.h" // copyTextToClipboard() -#include "llglheaders.h" - // [RLVa:KB] #include "rlvhandler.h" // [/RLVa:KB] @@ -105,6 +101,7 @@ struct SortRegionNames return(LLStringUtil::compareInsensitive(_left.second->getName(), _right.second->getName()) < 0); } }; + enum EPanDirection { PAN_UP, @@ -284,7 +281,7 @@ void LLFloaterWorldMap::onClose(bool app_quitting) } // static -void LLFloaterWorldMap::show(void*, BOOL center_on_target) +void LLFloaterWorldMap::show(bool center_on_target) { // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0c) if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWWORLDMAP)) @@ -351,13 +348,13 @@ void LLFloaterWorldMap::reloadIcons(void*) // static -void LLFloaterWorldMap::toggle(void*) +void LLFloaterWorldMap::toggle() { BOOL visible = gFloaterWorldMap->getVisible(); if (!visible) { - show(NULL, FALSE); + show(false); } else { @@ -368,7 +365,7 @@ void LLFloaterWorldMap::toggle(void*) // static -void LLFloaterWorldMap::hide(void*) +void LLFloaterWorldMap::hide() { gFloaterWorldMap->mIsClosing = TRUE; gFloaterWorldMap->close(); @@ -547,7 +544,7 @@ void LLFloaterWorldMap::trackAvatar( const LLUUID& avatar_id, const std::string& } else { - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); } setDefaultBtn("Teleport"); } @@ -591,7 +588,7 @@ void LLFloaterWorldMap::trackLandmark( const LLUUID& landmark_item_id ) } else { - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); } setDefaultBtn("Teleport"); } @@ -618,7 +615,7 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global) { // We haven't found a region for that point yet, leave the tracking to the world map LLWorldMap::getInstance()->setTracking(pos_global); - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); S32 world_x = S32(pos_global.mdV[0] / 256); S32 world_y = S32(pos_global.mdV[1] / 256); LLWorldMapMessage::getInstance()->sendMapBlockRequest(world_x, world_y, world_x, world_y, true); @@ -635,7 +632,7 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global) // i.e. let the world map that this and tell it it's invalid LLWorldMap::getInstance()->setTracking(pos_global); LLWorldMap::getInstance()->setTrackingInvalid(); - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); setDefaultBtn(""); // clicked on a down region - turn off coord display @@ -774,10 +771,9 @@ void LLFloaterWorldMap::updateLocation() // simNameFromPosGlobal can fail, so don't give the user an invalid SLURL if ( gotSimName ) { - LLVector3d agentPos = gAgent.getPositionGlobal(); - S32 x = llround( (F32)fmod( (F32)agentPos[VX], (F32)REGION_WIDTH_METERS ) ); - S32 y = llround( (F32)fmod( (F32)agentPos[VY], (F32)REGION_WIDTH_METERS ) ); - S32 z = llround( (F32)agentPos[VZ] ); + S32 x = llround( (F32)fmod( (F32)coord_pos[VX], (F32)REGION_WIDTH_METERS ) ); + S32 y = llround( (F32)fmod( (F32)coord_pos[VY], (F32)REGION_WIDTH_METERS ) ); + S32 z = llround( (F32)coord_pos[VZ] ); mSLURL = LLURLDispatcher::buildSLURL(sim_name, x, y, z); } else @@ -880,7 +876,7 @@ void LLFloaterWorldMap::friendsChanged() (buddy_info && !buddy_info->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION)) || gAgent.isGodlike()) { - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); } } } @@ -1098,7 +1094,7 @@ void LLFloaterWorldMap::onLandmarkComboPrearrange( ) if( current_choice.isNull() || !list->setCurrentByID( current_choice ) ) { - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); } } @@ -1108,7 +1104,7 @@ void LLFloaterWorldMap::onComboTextEntry() // Reset the tracking whenever we start typing into any of the search fields, // so that hitting does an auto-complete versus teleporting us to the // previously selected landmark/friend. - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); } void LLFloaterWorldMap::onSearchTextEntry( ) @@ -1131,7 +1127,7 @@ void LLFloaterWorldMap::onLandmarkComboCommit() LLUUID asset_id; LLUUID item_id = list->getCurrentID(); - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); //RN: stopTracking() clears current combobox selection, need to reassert it here list->setCurrentByID(item_id); @@ -1186,7 +1182,7 @@ void LLFloaterWorldMap::onAvatarComboPrearrange( ) if( !list->setCurrentByID( current_choice ) || current_choice.isNull() ) { - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); } } @@ -1293,7 +1289,7 @@ void LLFloaterWorldMap::onCoordinatesCommit() void LLFloaterWorldMap::onClearBtn() { mTrackedStatus = LLTracker::TRACKING_NOTHING; - LLTracker::stopTracking((void *)(intptr_t)TRUE); + LLTracker::stopTracking(true); LLWorldMap::getInstance()->cancelTracking(); mSLURL = ""; // Clear the SLURL since it's invalid mSetToUserPosition = TRUE; // Revert back to the current user position diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h index f249dc52b..40ac1dcb2 100644 --- a/indra/newview/llfloaterworldmap.h +++ b/indra/newview/llfloaterworldmap.h @@ -63,10 +63,10 @@ public: /*virtual*/ void onClose(bool app_quitting); - static void show(void*, BOOL center_on_target ); + static void show(bool center_on_target); static void reloadIcons(void*); - static void toggle(void*); - static void hide(void*); + static void toggle(); + static void hide(); /*virtual*/ void reshape( S32 width, S32 height, BOOL called_from_parent = TRUE ); /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); diff --git a/indra/newview/llgivemoney.cpp b/indra/newview/llgivemoney.cpp index 4f77350bc..b153216ac 100644 --- a/indra/newview/llgivemoney.cpp +++ b/indra/newview/llgivemoney.cpp @@ -101,7 +101,7 @@ LLFloaterPay::LLFloaterPay(const std::string& name, for(U32 i = 0; i < MAX_PAY_BUTTONS; ++i) { mQuickPayButton[i] = getChild("fastpay " + boost::lexical_cast(mQuickPayInfo[i])); - mQuickPayButton[i]->setClickedCallback(boost::bind(&LLFloaterPay::onGive,this,std::ref(mQuickPayInfo[i]))); + mQuickPayButton[i]->setClickedCallback(boost::bind(&LLFloaterPay::onGive,this,boost::ref(mQuickPayInfo[i]))); mQuickPayButton[i]->setVisible(FALSE); mQuickPayButton[i]->setLabelArg("[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol()); } @@ -122,7 +122,7 @@ LLFloaterPay::LLFloaterPay(const std::string& name, LLButton* pay_btn = getChild("pay btn"); - pay_btn->setClickedCallback(boost::bind(&LLFloaterPay::onGive,this,std::ref(mDefaultValue))); + pay_btn->setClickedCallback(boost::bind(&LLFloaterPay::onGive,this,boost::ref(mDefaultValue))); setDefaultBtn(pay_btn); pay_btn->setVisible(false); pay_btn->setEnabled(sLastAmount > 0); diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 707f3d929..9e9cd87c8 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -1123,7 +1123,7 @@ LLFloaterIMPanel::LLFloaterIMPanel( { llwarns << "Other participant is NULL" << llendl; } - + init(session_label); } @@ -1160,7 +1160,7 @@ LLFloaterIMPanel::LLFloaterIMPanel( { llwarns << "Other participant is NULL" << llendl; } - + mSessionInitialTargetIDs = ids; init(session_label); } @@ -1173,9 +1173,9 @@ void LLFloaterIMPanel::init(const std::string& session_label) mSessionLabel = session_label; - // [Ansariel: Display name support] - mProfileButtonEnabled = FALSE; - // [/Ansariel: Display name support] + // [Ansariel: Display name support] + mProfileButtonEnabled = FALSE; + // [/Ansariel: Display name support] static LLCachedControl concise_im("UseConciseIMButtons"); static LLCachedControl concise_group("UseConciseGroupChatButtons"); @@ -1610,25 +1610,25 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, LLColor4 incol static const LLCachedControl mKeywordsChangeColor(gSavedPerAccountSettings, "KeywordsChangeColor", false); static const LLCachedControl mKeywordsColor(gSavedPerAccountSettings, "KeywordsColor", LLColor4(1.f, 1.f, 1.f, 1.f)); - if (gAgent.getID() != source) + if (gAgentID != source) { if (mKeywordsChangeColor) { - if (AscentKeyword::hasKeyword(utf8msg, 2)) - { + if (AscentKeyword::hasKeyword(utf8msg, 2)) + { incolor = mKeywordsColor; - } + } } } const LLColor4& color = incolor; // start tab flashing when receiving im for background session from user - if (source != LLUUID::null) + if (source.notNull()) { LLMultiFloater* hostp = getHost(); if( !isInVisibleChain() && hostp - && source != gAgent.getID()) + && source != gAgentID) { hostp->setFloaterFlashing(this, TRUE); } @@ -1640,14 +1640,15 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, LLColor4 incol removeTypingIndicator(NULL); // Actually add the line - std::string timestring; bool prepend_newline = true; if (gSavedSettings.getBOOL("IMShowTimestamps")) { - timestring = mHistoryEditor->appendTime(prepend_newline); + mHistoryEditor->appendTime(prepend_newline); prepend_newline = false; } + std::string show_name = name; + bool is_irc = false; // 'name' is a sender name that we want to hotlink so that clicking on it opens a profile. if (!name.empty()) // If name exists, then add it to the front of the message. { @@ -1658,40 +1659,36 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, LLColor4 incol } else { - std::string show_name = name; + // IRC style text starts with a colon here; empty names and system messages aren't irc style. + static const LLCachedControl italicize("LiruItalicizeActions"); + is_irc = italicize && utf8msg[0] != ':'; if (source.notNull()) LLAvatarNameCache::getPNSName(source, show_name); // Convert the name to a hotlink and add to message. - const LLStyleSP &source_style = LLStyleMap::instance().lookupAgent(source); + LLStyleSP source_style = LLStyleMap::instance().lookupAgent(source); + source_style->mItalic = is_irc; mHistoryEditor->appendStyledText(show_name,false,prepend_newline,source_style); } prepend_newline = false; } - //Kadah - Bold group mods chat. Doesnt work on the first msg of the session, dont have speakers list yet? - if (gSavedSettings.getBOOL("SingularityBoldGroupModerator") && isModerator(source)) + // Append the chat message in style { - mHistoryEditor->appendColoredText(utf8msg.substr(0,1), false, prepend_newline, color); LLStyleSP style(new LLStyle); - style->setVisible(true); style->setColor(color); - style->setFontName(LLStringUtil::null); - style->mBold = TRUE; - mHistoryEditor->appendStyledText(utf8msg.substr(1), false, prepend_newline, style); + style->mItalic = is_irc; + style->mBold = gSavedSettings.getBOOL("SingularityBoldGroupModerator") && isModerator(source); + mHistoryEditor->appendStyledText(utf8msg, false, prepend_newline, style); } - else - { - mHistoryEditor->appendColoredText(utf8msg, false, prepend_newline, color); - } - + if (log_to_file && gSavedPerAccountSettings.getBOOL("LogInstantMessages") ) { std::string histstr; if (gSavedPerAccountSettings.getBOOL("IMLogTimestamp")) - histstr = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")) + name + utf8msg; + histstr = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")) + show_name + utf8msg; else - histstr = name + utf8msg; + histstr = show_name + utf8msg; // [Ansariel: Display name support] // Floater title contains display name -> bad idea to use that as filename @@ -1706,7 +1703,7 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, LLColor4 incol mNumUnreadMessages++; } - if (source != LLUUID::null) + if (source.notNull()) { mSpeakers->speakerChatted(source); mSpeakers->setSpeakerTyping(source, FALSE); @@ -1722,12 +1719,6 @@ void LLFloaterIMPanel::setVisible(BOOL b) if( b && hostp ) { hostp->setFloaterFlashing(this, FALSE); - - /* Don't change containing floater title - leave it "Instant Message" JC - LLUIString title = sTitleString; - title.setArg("[NAME]", mSessionLabel); - hostp->setTitle( title ); - */ } } @@ -2032,17 +2023,16 @@ void deliver_message(const std::string& utf8_text, bool sent = false; gAgent.buildFullname(name); - const LLRelationship* info = NULL; - info = LLAvatarTracker::instance().getBuddyInfo(other_participant_id); - + const LLRelationship* info = LLAvatarTracker::instance().getBuddyInfo(other_participant_id); + U8 offline = (!info || info->isOnline()) ? IM_ONLINE : IM_OFFLINE; - + if((offline == IM_OFFLINE) && (LLVoiceClient::getInstance()->isOnlineSIP(other_participant_id))) { // User is online through the OOW connector, but not with a regular viewer. Try to send the message via SLVoice. sent = gVoiceClient->sendTextMessage(other_participant_id, utf8_text); } - + if(!sent) { // Send message normally. @@ -2111,56 +2101,56 @@ void LLFloaterIMPanel::onSendMsg() // store sent line in history, duplicates will get filtered if (mInputEditor) mInputEditor->updateHistory(); // Truncate and convert to UTF8 for transport - std::string utf8text = wstring_to_utf8str(text); + std::string utf8_text = wstring_to_utf8str(text); // Convert MU*s style poses into IRC emotes here. - if (gSavedSettings.getBOOL("AscentAllowMUpose") && utf8text.length() > 3 && utf8text[0] == ':') + if (gSavedSettings.getBOOL("AscentAllowMUpose") && utf8_text.length() > 3 && utf8_text[0] == ':') { - if (utf8text[1] == '\'') + if (utf8_text[1] == '\'') { - utf8text.replace(0, 1, "/me"); + utf8_text.replace(0, 1, "/me"); } - else if (isalpha(utf8text[1])) // Do not prevent smileys and such. + else if (isalpha(utf8_text[1])) // Do not prevent smileys and such. { - utf8text.replace(0, 1, "/me "); + utf8_text.replace(0, 1, "/me "); } } - if (utf8text.find("/ME'") == 0 || utf8text.find("/ME ") == 0) //Allow CAPSlock /me - utf8text.replace(1, 2, "me"); - std::string prefix = utf8text.substr(0, 4); - if (gSavedSettings.getBOOL("AscentAutoCloseOOC") && (utf8text.length() > 1) && !mRPMode) + if (utf8_text.find("/ME'") == 0 || utf8_text.find("/ME ") == 0) //Allow CAPSlock /me + utf8_text.replace(1, 2, "me"); + std::string prefix = utf8_text.substr(0, 4); + if (gSavedSettings.getBOOL("AscentAutoCloseOOC") && (utf8_text.length() > 1) && !mRPMode) { //Check if it needs the end-of-chat brackets -HgB - if (utf8text.find("((") == 0 && utf8text.find("))") == std::string::npos) + if (utf8_text.find("((") == 0 && utf8_text.find("))") == std::string::npos) { - if(*utf8text.rbegin() == ')') - utf8text+=" "; - utf8text+="))"; + if(*utf8_text.rbegin() == ')') + utf8_text+=" "; + utf8_text+="))"; } - else if(utf8text.find("[[") == 0 && utf8text.find("]]") == std::string::npos) + else if(utf8_text.find("[[") == 0 && utf8_text.find("]]") == std::string::npos) { - if(*utf8text.rbegin() == ']') - utf8text+=" "; - utf8text+="]]"; + if(*utf8_text.rbegin() == ']') + utf8_text+=" "; + utf8_text+="]]"; } if (prefix != "/me " && prefix != "/me'") //Allow /me to end with )) or ]] { - if (utf8text.find("((") == std::string::npos && utf8text.find("))") == (utf8text.length() - 2)) + if (utf8_text.find("((") == std::string::npos && utf8_text.find("))") == (utf8_text.length() - 2)) { - if(utf8text[0] == '(') - utf8text.insert(0," "); - utf8text.insert(0,"(("); + if(utf8_text[0] == '(') + utf8_text.insert(0," "); + utf8_text.insert(0,"(("); } - else if (utf8text.find("[[") == std::string::npos && utf8text.find("]]") == (utf8text.length() - 2)) + else if (utf8_text.find("[[") == std::string::npos && utf8_text.find("]]") == (utf8_text.length() - 2)) { - if(utf8text[0] == '[') - utf8text.insert(0," "); - utf8text.insert(0,"[["); + if(utf8_text[0] == '[') + utf8_text.insert(0," "); + utf8_text.insert(0,"[["); } } } if (mRPMode && prefix != "/me " && prefix != "/me'") - utf8text = "[[" + utf8text + "]]"; + utf8_text = "[[" + utf8_text + "]]"; // [RLVa:KB] - Checked: 2011-09-17 (RLVa-1.1.4b) | Modified: RLVa-1.1.4b if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIMTO)) ) { @@ -2187,7 +2177,7 @@ void LLFloaterIMPanel::onSendMsg() itSpeaker != speakers.end(); ++itSpeaker) { const LLSpeaker* pSpeaker = *itSpeaker; - if ( (gAgent.getID() != pSpeaker->mID) && (!gRlvHandler.canSendIM(pSpeaker->mID)) ) + if ( (gAgentID != pSpeaker->mID) && (!gRlvHandler.canSendIM(pSpeaker->mID)) ) { fRlvFilter = true; break; @@ -2201,7 +2191,7 @@ void LLFloaterIMPanel::onSendMsg() } if (fRlvFilter) - utf8text = RlvStrings::getString(RLV_STRING_BLOCKED_SENDIM); + utf8_text = RlvStrings::getString(RLV_STRING_BLOCKED_SENDIM); } // [/RLVa:KB] @@ -2210,7 +2200,7 @@ void LLFloaterIMPanel::onSendMsg() // Split messages that are too long, same code like in llimpanel.cpp U32 split = MAX_MSG_BUF_SIZE - 1; U32 pos = 0; - U32 total = utf8text.length(); + U32 total = utf8_text.length(); while (pos < total) { @@ -2223,11 +2213,11 @@ void LLFloaterIMPanel::onSendMsg() else { // don't split utf-8 bytes - while (U8(utf8text[pos + next_split]) != 0x20 // space - && U8(utf8text[pos + next_split]) != 0x21 // ! - && U8(utf8text[pos + next_split]) != 0x2C // , - && U8(utf8text[pos + next_split]) != 0x2E // . - && U8(utf8text[pos + next_split]) != 0x3F // ? + while (U8(utf8_text[pos + next_split]) != 0x20 // space + && U8(utf8_text[pos + next_split]) != 0x21 // ! + && U8(utf8_text[pos + next_split]) != 0x2C // , + && U8(utf8_text[pos + next_split]) != 0x2E // . + && U8(utf8_text[pos + next_split]) != 0x3F // ? && next_split > 0) { --next_split; @@ -2244,7 +2234,7 @@ void LLFloaterIMPanel::onSendMsg() } } - std::string send = utf8text.substr(pos, next_split); + std::string send = utf8_text.substr(pos, next_split); pos += next_split; LL_WARNS("Splitting") << "Pos: " << pos << " next_split: " << next_split << LL_ENDL; @@ -2258,37 +2248,30 @@ LL_WARNS("Splitting") << "Pos: " << pos << " next_split: " << next_split << LL_E if((mDialog == IM_NOTHING_SPECIAL) && (mOtherParticipantUUID.notNull())) { - std::string history_echo; - gAgent.buildFullname(history_echo); + std::string name; + gAgent.buildFullname(name); // Look for IRC-style emotes here. - std::string prefix = utf8text.substr(0, 4); + std::string prefix = utf8_text.substr(0, 4); if (prefix == "/me " || prefix == "/me'") { - utf8text.replace(0,3,""); + utf8_text.replace(0,3,""); } else { - history_echo += ": "; - } - history_echo += utf8text; - - BOOL other_was_typing = mOtherTyping; - - addHistoryLine(history_echo, gSavedSettings.getColor("IMChatColor"), true, gAgent.getID()); - - if (other_was_typing) - { - addTypingIndicator(mOtherTypingName); + utf8_text.insert(0, ": "); } + bool other_was_typing = mOtherTyping; + addHistoryLine(utf8_text, gSavedSettings.getColor("UserChatColor"), true, gAgentID, name); + if (other_was_typing) addTypingIndicator(mOtherTypingName); } } else { //queue up the message to send once the session is //initialized - mQueuedMsgsForInit.append(utf8text); + mQueuedMsgsForInit.append(utf8_text); } } @@ -2425,12 +2408,15 @@ void LLFloaterIMPanel::sendTypingState(BOOL typing) gAgent.sendReliableMessage(); } + void LLFloaterIMPanel::processIMTyping(const LLIMInfo* im_info, BOOL typing) { if (typing) { // other user started typing - addTypingIndicator(im_info->mName); + std::string name; + if (!LLAvatarNameCache::getPNSName(im_info->mFromID, name)) name = im_info->mName; + addTypingIndicator(name); } else { @@ -2568,12 +2554,11 @@ bool LLFloaterIMPanel::onConfirmForceCloseError(const LLSD& notification, const //only 1 option really LLUUID session_id = notification["payload"]["session_id"]; - if ( gIMMgr ) + if (gIMMgr) { - LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession( - session_id); + LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(session_id); - if ( floaterp ) floaterp->close(FALSE); + if (floaterp) floaterp->close(FALSE); } return false; } @@ -2592,29 +2577,20 @@ const bool LLFloaterIMPanel::isModerator(const LLUUID& speaker_id) BOOL LLFloaterIMPanel::focusFirstItem(BOOL prefer_text_fields, BOOL focus_flash ) { - LLView* chat_editor = getChildView("chat_editor"); - if (getVisible() && childIsVisible("chat_editor")) - { - gFocusMgr.setKeyboardFocus(chat_editor); + if (getVisible() && mInputEditor->getVisible()) + { + setInputFocus(true); + return TRUE; + } - LLUICtrl * ctrl = static_cast(chat_editor); - ctrl->setFocus(TRUE); - - return TRUE; - } - - return LLUICtrl::focusFirstItem(prefer_text_fields, focus_flash); + return LLUICtrl::focusFirstItem(prefer_text_fields, focus_flash); } void LLFloaterIMPanel::onFocusReceived() { - LLView* chat_editor = getChildView("chat_editor"); - if (getVisible() && childIsVisible("chat_editor")) + if (getVisible() && mInputEditor->getVisible()) { - gFocusMgr.setKeyboardFocus(chat_editor); - - LLUICtrl * ctrl = static_cast(chat_editor); - ctrl->setFocus(TRUE); + setInputFocus(true); } LLFloater::onFocusReceived(); diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 73d45caf2..b04a2cd18 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -51,7 +51,6 @@ #include "llresmgr.h" #include "llfloaterchat.h" #include "llfloaterchatterbox.h" -#include "llfloaternewim.h" #include "llhttpnode.h" #include "llimpanel.h" #include "llresizebar.h" @@ -88,6 +87,36 @@ LLIMMgr* gIMMgr = NULL; // // Helper Functions // +LLColor4 agent_chat_color(const LLUUID& id, const std::string& name, bool local_chat) +{ + if (id.isNull() || (name == SYSTEM_FROM)) + return gSavedSettings.getColor4("SystemChatColor"); + + if (id == gAgentID) + return gSavedSettings.getColor4("UserChatColor"); + + static const LLCachedControl color_linden_chat("ColorLindenChat"); + if (color_linden_chat && LLMuteList::getInstance()->isLinden(name)) + return gSavedSettings.getColor4("AscentLindenColor"); + + // [RLVa:LF] Chat colors would identify names, don't use them in local chat if restricted + if (local_chat && rlv_handler_t::isEnabled() && gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) + return gSavedSettings.getColor4("AgentChatColor"); + + static const LLCachedControl color_friend_chat("ColorFriendChat"); + if (color_friend_chat && LLAvatarTracker::instance().isBuddy(id)) + return gSavedSettings.getColor4("AscentFriendColor"); + + static const LLCachedControl color_eo_chat("ColorEstateOwnerChat"); + if (color_eo_chat) + { + const LLViewerRegion* parent_estate = gAgent.getRegion(); + if (parent_estate && id == parent_estate->getOwner()) + return gSavedSettings.getColor4("AscentEstateOwnerColor"); + } + + return local_chat ? gSavedSettings.getColor4("AgentChatColor") : gSavedSettings.getColor("IMChatColor"); +} // returns true if a should appear before b //static BOOL group_dictionary_sort( LLGroupData* a, LLGroupData* b ) @@ -482,13 +511,6 @@ void LLIMMgr::addMessage( return; } - //not sure why...but if it is from ourselves we set the target_id - //to be NULL, which seems to be breaking links on group chats, so let's not there. - if (other_participant_id == gAgent.getID() && !gAgent.isInGroup(session_id)) - { - other_participant_id = LLUUID::null; - } - LLFloaterIMPanel* floater; LLUUID new_session_id = session_id; if (new_session_id.isNull()) @@ -572,34 +594,13 @@ void LLIMMgr::addMessage( } // now add message to floater - bool is_from_system = target_id.isNull() || (from == SYSTEM_FROM); - - static LLCachedControl color_linden_chat("ColorLindenChat"); - bool linden = color_linden_chat && LLMuteList::getInstance()->isLinden(from); - - static LLCachedControl color_friend_chat("ColorFriendChat"); - bool contact = color_friend_chat && LLAvatarTracker::instance().isBuddy(other_participant_id); - - static LLCachedControl color_eo_chat("ColorEstateOwnerChat"); - bool estate_owner = false; - if (color_eo_chat) - { - LLViewerRegion* parent_estate = gAgent.getRegion(); - estate_owner = (parent_estate && parent_estate->isAlive() && other_participant_id == parent_estate->getOwner()); - } - - const LLColor4& color = ( is_from_system ? gSavedSettings.getColor4("SystemChatColor") - : linden ? gSavedSettings.getColor4("AscentLindenColor") - : contact ? gSavedSettings.getColor4("AscentFriendColor") - : estate_owner ? gSavedSettings.getColor4("AscentEstateOwnerColor") - : gSavedSettings.getColor("IMChatColor")); + const LLColor4& color = agent_chat_color(other_participant_id, from, false); if ( !link_name ) { floater->addHistoryLine(msg,color); // No name to prepend, so just add the message normally } else { - if( other_participant_id == session_id ) { // The name can be bogus on InWorldz @@ -765,7 +766,10 @@ LLUUID LLIMMgr::addSession( floater->open(); } //mTabContainer->selectTabPanel(panel); - floater->setInputFocus(TRUE); + if(gSavedSettings.getBOOL("PhoenixIMAnnounceStealFocus")) + { + floater->setInputFocus(TRUE); + } return floater->getSessionID(); } @@ -815,7 +819,10 @@ LLUUID LLIMMgr::addSession( floater->open(); } //mTabContainer->selectTabPanel(panel); - floater->setInputFocus(TRUE); + if(gSavedSettings.getBOOL("PhoenixIMAnnounceStealFocus")) + { + floater->setInputFocus(TRUE); + } return floater->getSessionID(); } @@ -1436,7 +1443,7 @@ public: floaterp->processSessionUpdate(body["session_info"]); } - //aply updates we've possibly received previously + //apply updates we've possibly received previously floaterp->updateSpeakersList( gIMMgr->getPendingAgentListUpdates(session_id)); } @@ -1614,8 +1621,9 @@ public: { separator_string = ""; message_offset = 3; + chat.mChatStyle = CHAT_STYLE_IRC; } - + chat.mMuted = is_muted && !is_linden; chat.mFromID = from_id; chat.mFromName = name; @@ -1719,7 +1727,7 @@ public: { return; } - + if(!LLVoiceClient::voiceEnabled()) { // Don't display voice invites unless the user has voice enabled. diff --git a/indra/newview/llinventoryactions.cpp b/indra/newview/llinventoryactions.cpp index ed0c6c54e..fe07063bb 100644 --- a/indra/newview/llinventoryactions.cpp +++ b/indra/newview/llinventoryactions.cpp @@ -31,11 +31,14 @@ */ #include "llviewerprecompiledheaders.h" + #include "llagentwearables.h" +#include "llappearancemgr.h" +#include "llfoldervieweventlistener.h" #include "llimview.h" -#include "llinventoryfunctions.h" #include "llinventorybridge.h" #include "llinventoryclipboard.h" +#include "llinventoryfunctions.h" #include "llinventorymodelbackgroundfetch.h" #include "llinventorypanel.h" #include "llmakeoutfitdialog.h" @@ -43,7 +46,6 @@ #include "llpanelmaininventory.h" #include "llpanelobjectinventory.h" #include "llpreview.h" // For LLMultiPreview -#include "llfoldervieweventlistener.h" #include "lltrans.h" #include "llvoavatarself.h" @@ -317,7 +319,7 @@ void do_create(LLInventoryModel *model, LLInventoryPanel *ptr, std::string type, LLInventoryType::IT_GESTURE, PERM_ALL); } - else if ("outfit" == type) + else if ("outfit" == type || ("update outfit" == type && !LLAppearanceMgr::getInstance()->updateBaseOutfit())) // If updateBaseOutfit fails, prompt to make a new outfit { new LLMakeOutfitDialog(false); return; diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index a68754942..983311680 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2614,7 +2614,6 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id, if(drop && accept) { it = inventory_objects.begin(); - LLInventoryObject::object_list_t::iterator first_it = inventory_objects.begin(); LLMoveInv* move_inv = new LLMoveInv; move_inv->mObjectID = object_id; move_inv->mCategoryID = category_id; diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 3f87c2615..a73a1fee6 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -89,6 +89,7 @@ public: fetchInventoryResponder(const LLSD& request_sd) : mRequestSD(request_sd) {}; /*virtual*/ void result(const LLSD& content); /*virtual*/ void error(U32 status, const std::string& reason); + /*virtual*/ AICapabilityType capability_type(void) const { return cap_inventory; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return fetchInventoryResponder_timeout; } /*virtual*/ char const* getName(void) const { return "fetchInventoryResponder"; } protected: diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 272a0aad8..6a828db9b 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -204,7 +204,8 @@ void LLInventoryModelBackgroundFetch::backgroundFetch() std::string url = region->getCapability("FetchInventory2"); if (!url.empty()) { - if (!mPerServicePtr) + bool mPerServicePtr_initialized = !!mPerServicePtr; + if (!mPerServicePtr_initialized) { // One time initialization needed for bulkFetch(). std::string servicename = AIPerService::extract_canonical_servicename(url); @@ -212,10 +213,14 @@ void LLInventoryModelBackgroundFetch::backgroundFetch() { llinfos << "Initialized service name for bulk inventory fetching with \"" << servicename << "\"." << llendl; mPerServicePtr = AIPerService::instance(servicename); + mPerServicePtr_initialized = true; } } - bulkFetch(); - return; + if (mPerServicePtr_initialized) + { + bulkFetch(); + return; + } } } @@ -415,6 +420,7 @@ class LLInventoryModelFetchDescendentsResponder : public LLHTTPClient::Responder {}; /*virtual*/ void result(const LLSD& content); /*virtual*/ void error(U32 status, const std::string& reason); + /*virtual*/ AICapabilityType capability_type(void) const { return cap_inventory; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return inventoryModelFetchDescendentsResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLInventoryModelFetchDescendentsResponder"; } @@ -600,28 +606,29 @@ void LLInventoryModelBackgroundFetch::bulkFetch() LLViewerRegion* region = gAgent.getRegion(); if (gDisconnected || !region) return; - static LLCachedControl const throttle_bandwidth("HTTPThrottleBandwidth", 2000); - bool const no_bandwidth_throttling = gHippoGridManager->getConnectedGrid()->isAvination(); - if (!AIPerService::wantsMoreHTTPRequestsFor(mPerServicePtr, throttle_bandwidth, no_bandwidth_throttling)) - { - return; // Wait. - } - - U32 item_count=0; - U32 folder_count=0; - U32 max_batch_size=5; + U32 const max_batch_size = 5; U32 sort_order = gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER) & 0x1; uuid_vec_t recursive_cats; + U32 folder_count=0; + U32 folder_lib_count=0; + U32 item_count=0; + U32 item_lib_count=0; + + // This function can do up to four requests at once. + LLPointer approved_folder; + LLPointer approved_folder_lib; + LLPointer approved_item; + LLPointer approved_item_lib; + LLSD folder_request_body; LLSD folder_request_body_lib; LLSD item_request_body; LLSD item_request_body_lib; - while (!mFetchQueue.empty() - && (item_count + folder_count) < max_batch_size) + while (!mFetchQueue.empty()) { const FetchQueueInfo& fetch_info = mFetchQueue.front(); if (fetch_info.mIsCategory) @@ -643,10 +650,27 @@ void LLInventoryModelBackgroundFetch::bulkFetch() folder_sd["fetch_items"] = (LLSD::Boolean)TRUE; if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) + { + if (folder_lib_count == max_batch_size || + (folder_lib_count == 0 && + !(approved_folder_lib = AIPerService::approveHTTPRequestFor(mPerServicePtr, cap_inventory)))) + { + break; + } folder_request_body_lib["folders"].append(folder_sd); + ++folder_lib_count; + } else + { + if (folder_count == max_batch_size || + (folder_count == 0 && + !(approved_folder = AIPerService::approveHTTPRequestFor(mPerServicePtr, cap_inventory)))) + { + break; + } folder_request_body["folders"].append(folder_sd); - folder_count++; + ++folder_count; + } } // May already have this folder, but append child folders to list. if (fetch_info.mRecursive) @@ -676,77 +700,72 @@ void LLInventoryModelBackgroundFetch::bulkFetch() item_sd["item_id"] = itemp->getUUID(); if (itemp->getPermissions().getOwner() == gAgent.getID()) { + if (item_count == max_batch_size || + (item_count == 0 && + !(approved_item = AIPerService::approveHTTPRequestFor(mPerServicePtr, cap_inventory)))) + { + break; + } item_request_body.append(item_sd); + ++item_count; } else { + if (item_lib_count == max_batch_size || + (item_lib_count == 0 && + !(approved_item_lib = AIPerService::approveHTTPRequestFor(mPerServicePtr, cap_inventory)))) + { + break; + } item_request_body_lib.append(item_sd); + ++item_lib_count; } - //itemp->fetchFromServer(); - item_count++; } } mFetchQueue.pop_front(); } - if (item_count + folder_count > 0) + if (item_count + folder_count + item_lib_count + folder_lib_count > 0) { if (folder_count) { std::string url = region->getCapability("FetchInventoryDescendents2"); - mFetchCount++; - if (folder_request_body["folders"].size()) - { - LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body, recursive_cats); - LLHTTPClient::post(url, folder_request_body, fetcher); - } - if (folder_request_body_lib["folders"].size()) - { - std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents2"); - - LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body_lib, recursive_cats); - LLHTTPClient::post(url_lib, folder_request_body_lib, fetcher); - } + llassert(!url.empty()); + ++mFetchCount; + LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body, recursive_cats); + LLHTTPClient::post_approved(url, folder_request_body, fetcher, approved_folder); + } + if (folder_lib_count) + { + std::string url = gAgent.getRegion()->getCapability("FetchLibDescendents2"); + llassert(!url.empty()); + ++mFetchCount; + LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body_lib, recursive_cats); + LLHTTPClient::post_approved(url, folder_request_body_lib, fetcher, approved_folder_lib); } if (item_count) { - std::string url; - - if (item_request_body.size()) - { - mFetchCount++; - url = region->getCapability("FetchInventory2"); - llassert(!url.empty()); - if (!url.empty()) - { - LLSD body; - body["agent_id"] = gAgent.getID(); - body["items"] = item_request_body; - - LLHTTPClient::post(url, body, new LLInventoryModelFetchItemResponder(body)); - } - } - - if (item_request_body_lib.size()) - { - mFetchCount++; - - url = region->getCapability("FetchLib2"); - llassert(!url.empty()); - if (!url.empty()) - { - LLSD body; - body["agent_id"] = gAgent.getID(); - body["items"] = item_request_body_lib; - - LLHTTPClient::post(url, body, new LLInventoryModelFetchItemResponder(body)); - } - } + std::string url = region->getCapability("FetchInventory2"); + llassert(!url.empty()); + ++mFetchCount; + LLSD body; + body["agent_id"] = gAgent.getID(); + body["items"] = item_request_body; + LLHTTPClient::post_approved(url, body, new LLInventoryModelFetchItemResponder(body), approved_item); + } + if (item_lib_count) + { + std::string url = region->getCapability("FetchLib2"); + llassert(!url.empty()); + ++mFetchCount; + LLSD body; + body["agent_id"] = gAgent.getID(); + body["items"] = item_request_body_lib; + LLHTTPClient::post_approved(url, body, new LLInventoryModelFetchItemResponder(body), approved_item_lib); } mFetchTimer.reset(); } - else if (isBulkFetchProcessingComplete()) { llinfos << "Inventory fetch completed" << llendl; diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp index acc23f599..988496eeb 100644 --- a/indra/newview/llmenucommands.cpp +++ b/indra/newview/llmenucommands.cpp @@ -75,7 +75,7 @@ void handle_track_avatar(const LLUUID& agent_id, const std::string& name) LLAvatarTracker::instance().track(agent_id, name); LLFloaterDirectory::hide(NULL); - LLFloaterWorldMap::show(NULL, TRUE); + LLFloaterWorldMap::show(true); } void handle_pay_by_id(const LLUUID& agent_id) @@ -92,7 +92,7 @@ void handle_mouselook(void*) void handle_map(void*) { - LLFloaterWorldMap::toggle(NULL); + LLFloaterWorldMap::toggle(); } void handle_mini_map(void*) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 1c70e6fae..17b3f70e1 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -229,6 +229,7 @@ public: const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer); + /*virtual*/ AICapabilityType capability_type(void) const { return cap_mesh; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return meshHeaderResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLMeshHeaderResponder"; } }; @@ -256,6 +257,7 @@ public: const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer); + /*virtual*/ AICapabilityType capability_type(void) const { return cap_mesh; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return meshLODResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLMeshLODResponder"; } }; @@ -276,6 +278,7 @@ public: const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer); + /*virtual*/ AICapabilityType capability_type(void) const { return cap_mesh; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return meshSkinInfoResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLMeshSkinInfoResponder"; } }; @@ -296,6 +299,7 @@ public: const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer); + /*virtual*/ AICapabilityType capability_type(void) const { return cap_mesh; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return meshDecompositionResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLMeshDecompositionResponder"; } }; @@ -316,6 +320,7 @@ public: const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer); + /*virtual*/ AICapabilityType capability_type(void) const { return cap_mesh; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return meshPhysicsShapeResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLMeshPhysicsShapeResponder"; } }; @@ -2509,7 +2514,7 @@ void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, } S32 LLMeshRepository::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod) -{ +{ return mThread->getActualMeshLOD(mesh_params, lod); } @@ -2660,7 +2665,7 @@ void LLMeshRepository::uploadModel(std::vector& data, LLVector3 return; } AIMeshUpload* uploader = new AIMeshUpload(data, scale, upload_textures, upload_skin, upload_joints, upload_url, do_upload, fee_observer, upload_observer); - uploader->run(); + uploader->run(NULL, 0, false, true, &gMainThreadEngine); } S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod) diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index ce79f9506..5f397c206 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -32,6 +32,7 @@ #include "lluuid.h" #include "llviewertexture.h" #include "llvolume.h" +#include "sguuidhash.h" #define LLCONVEXDECOMPINTER_STATIC 1 @@ -505,8 +506,8 @@ public: typedef std::map > mesh_load_map; mesh_load_map mLoadingMeshes[4]; - - typedef std::map skin_map; + + typedef boost::unordered_map skin_map; skin_map mSkinMap; typedef std::map decomposition_map; diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 9c2a08cc9..43fa927b4 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -971,7 +971,7 @@ BOOL LLNetMap::handleDoubleClick( S32 x, S32 y, MASK mask ) { LLVector3d pos_global = viewPosToGlobal(x, y, gSavedSettings.getBOOL( "MiniMapRotate" )); BOOL new_target = FALSE; - if (!LLTracker::isTracking(NULL)) + if (!LLTracker::isTracking()) { gFloaterWorldMap->trackLocation(pos_global); new_target = TRUE; @@ -983,7 +983,7 @@ BOOL LLNetMap::handleDoubleClick( S32 x, S32 y, MASK mask ) } else { - LLFloaterWorldMap::show(NULL, new_target); + LLFloaterWorldMap::show(new_target); } return TRUE; } @@ -1124,14 +1124,14 @@ bool LLNetMap::LLCheckRotateMap::handleEvent(LLPointer event, const LLS bool LLNetMap::LLStopTracking::handleEvent(LLPointer event, const LLSD& userdata) { - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); return true; } bool LLNetMap::LLEnableTracking::handleEvent(LLPointer event, const LLSD& userdata) { LLNetMap *self = mPtr; - self->findControl(userdata["control"].asString())->setValue(LLTracker::isTracking(NULL)); + self->findControl(userdata["control"].asString())->setValue(LLTracker::isTracking()); return true; } diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index cfc00acb8..7af76fe68 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -70,11 +70,8 @@ #include "llstatusbar.h" #include "lltabcontainer.h" #include "llimview.h" -#include "lltooldraganddrop.h" -#include "lluiconstants.h" #include "llvoavatar.h" #include "llviewercontrol.h" -#include "llviewermenu.h" // *FIX: for is_agent_friend() #include "llviewergenericmessage.h" // send_generic_message #include "llviewerobjectlist.h" #include "llviewerregion.h" @@ -82,7 +79,6 @@ #include "llinventorymodel.h" #include "roles_constants.h" #include "lluictrlfactory.h" -#include "llviewermenu.h" #include "llavatarnamecache.h" #include "lldroptarget.h" @@ -105,6 +101,8 @@ BOOL LLPanelAvatar::sAllowFirstLife = FALSE; extern void callback_invite_to_group(LLUUID group_id, void *user_data); extern void handle_lure(const LLUUID& invitee); extern void handle_pay_by_id(const LLUUID& payee); +BOOL is_agent_friend(const LLUUID& agent_id); +BOOL is_agent_mappable(const LLUUID& agent_id); //----------------------------------------------------------------------------- @@ -362,6 +360,13 @@ void LLPanelAvatarSecondLife::enableControls(BOOL self) { childSetEnabled("img", self); childSetEnabled("about", self); + if (self) // We can't give inventory to self + { + if (LLDropTarget* drop_target = findChild("drop_target_rect")) + removeChild(drop_target); + if (LLTextBox* text_box = findChild("Give item:")) + removeChild(text_box); + } childSetVisible("allow_publish", self); childSetEnabled("allow_publish", self); childSetVisible("?", self); @@ -1419,7 +1424,6 @@ LLPanelAvatar::LLPanelAvatar( mPanelNotes(NULL), mPanelFirstLife(NULL), mPanelWeb(NULL), - mDropTarget(NULL), mAvatarID( LLUUID::null ), // mAvatarID is set with 'setAvatar' or 'setAvatarID' mHaveProperties(FALSE), mHaveStatistics(FALSE), @@ -1580,16 +1584,16 @@ void LLPanelAvatar::setAvatarID(const LLUUID &avatar_id, const std::string &name { if (avatar_id.isNull()) return; - BOOL avatar_changed = FALSE; + //BOOL avatar_changed = FALSE; if (avatar_id != mAvatarID) { - avatar_changed = TRUE; + //avatar_changed = TRUE; if(mAvatarID.notNull()) { LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarID, this); } + mAvatarID = avatar_id; } - mAvatarID = avatar_id; LLAvatarPropertiesProcessor::getInstance()->addObserver(mAvatarID, this); @@ -1613,18 +1617,8 @@ void LLPanelAvatar::setAvatarID(const LLUUID &avatar_id, const std::string &name // Teens don't have this. if (mPanelFirstLife) mPanelFirstLife->enableControls(own_avatar && mAllowEdit); - LLView *target_view = getChild("drop_target_rect"); - if(target_view) - { - if (mDropTarget) - { - delete mDropTarget; - } - mDropTarget = new LLDropTarget("drop target", target_view->getRect(), mAvatarID); - addChild(mDropTarget); - mDropTarget->setAgentID(mAvatarID); - } - + getChild("drop_target_rect")->setEntityID(mAvatarID); + LLNameEditor* name_edit = getChild("name"); if(name_edit) { @@ -1711,8 +1705,6 @@ void LLPanelAvatar::setAvatarID(const LLUUID &avatar_id, const std::string &name childSetEnabled("Mute",FALSE); childSetVisible("Offer Teleport...",FALSE); childSetEnabled("Offer Teleport...",FALSE); - childSetVisible("drop target",FALSE); - childSetEnabled("drop target",FALSE); childSetVisible("Find on Map",FALSE); childSetEnabled("Find on Map",FALSE); childSetVisible("Add Friend...",FALSE); @@ -1735,8 +1727,6 @@ void LLPanelAvatar::setAvatarID(const LLUUID &avatar_id, const std::string &name childSetVisible("Mute",TRUE); childSetEnabled("Mute",FALSE); - childSetVisible("drop target",TRUE); - childSetEnabled("drop target",FALSE); childSetVisible("Find on Map",TRUE); // Note: we don't always know online status, so always allow gods to try to track @@ -1878,11 +1868,9 @@ void LLPanelAvatar::onClickGetKey(void *userdata) LLPanelAvatar* self = (LLPanelAvatar*)userdata; LLUUID agent_id = self->getAvatarID(); - char buffer[UUID_STR_LENGTH]; /*Flawfinder: ignore*/ - agent_id.toString(buffer); - llinfos << "Copy agent id: " << agent_id << " buffer: " << buffer << llendl; + llinfos << "Copy agent id: " << agent_id << llendl; - gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(buffer)); + gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(agent_id.asString())); } // static @@ -1899,7 +1887,7 @@ void LLPanelAvatar::onClickTrack(void* userdata) LLNameEditor* nameedit = self->mPanelSecondLife->getChild("name"); if (nameedit) name = nameedit->getText(); gFloaterWorldMap->trackAvatar(self->mAvatarID, name); - LLFloaterWorldMap::show(NULL, TRUE); + LLFloaterWorldMap::show(true); } } @@ -2062,8 +2050,6 @@ void LLPanelAvatar::processProperties(void* data, EAvatarProcessorType type) childSetEnabled("Pay...",TRUE); childSetEnabled("Mute",TRUE); - childSetEnabled("drop target",TRUE); - mHaveProperties = TRUE; enableOKIfReady(); diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index 38958e834..a524cd915 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -373,8 +373,6 @@ public: std::list mAvatarPanelList; - LLDropTarget* mDropTarget; - // Teen users are not allowed to see or enter data into the first life page, // or their own about/interests text entry fields. static BOOL sAllowFirstLife; diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index 062bc00eb..d0d850db3 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -885,7 +885,7 @@ void LLPanelClassified::onClickMap(void* data) { LLPanelClassified* self = (LLPanelClassified*)data; gFloaterWorldMap->trackLocation(self->mPosGlobal); - LLFloaterWorldMap::show(NULL, TRUE); + LLFloaterWorldMap::show(true); self->sendClassifiedClickMessage("map"); } diff --git a/indra/newview/llpaneldebug.cpp b/indra/newview/llpaneldebug.cpp deleted file mode 100644 index d6528f85f..000000000 --- a/indra/newview/llpaneldebug.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/** - * @file llpaneldebug.cpp - * @brief Debug preferences panel for preferences floater - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -// file include -#include "llpaneldebug.h" - -// linden library includes -#include "llerror.h" -#include "llrect.h" -#include "llstring.h" -#include "llfontgl.h" - -// project includes -#include "llaudioengine.h" -#include "llbutton.h" -#include "llcheckboxctrl.h" -#include "llcolorswatch.h" -#include "llcombobox.h" -#include "llresmgr.h" -#include "llsky.h" -#include "llslider.h" -#include "llsliderctrl.h" -#include "llspinctrl.h" -#include "lltextbox.h" -#include "llui.h" -#include "llvosky.h" -#include "message.h" -#include "llagent.h" -#include "llviewercontrol.h" - -// -// Imported globals -// - - -// -// Globals -// - -// -// Static functions -// - -LLPanelDebug::LLPanelDebug(const std::string& name, const LLRect& rect) -: LLPanel(name, rect) -{ - LLCheckboxCtrl* check = NULL; - LLSliderCtrl *sliderctrl = NULL; - - const LLFontGL* font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ); - - const S32 HPAD = 10; - const S32 VPAD = 4; - - const S32 TOP_PAD = 10; - - // alignment "rulers" for buttons - const S32 SEGMENT_WIDTH = 128; - const S32 LEFT = HPAD; - const S32 RULER1 = LEFT + SEGMENT_WIDTH + 30; - const S32 RULER2 = RULER1 + HPAD; - const S32 RIGHT = RULER2 + SEGMENT_WIDTH; - const S32 LABEL_OFFSET = 60; - - S32 cur_y = rect.getHeight() - TOP_PAD; - - sliderctrl = new LLSliderCtrl(std::string("Drop Shadow Floater"), - LLRect( LEFT, cur_y, RIGHT, cur_y - SLIDERCTRL_HEIGHT ), - std::string("Drop Shadow Floater"), - font, - LABEL_OFFSET, - RULER2 + SPINCTRL_DEFAULT_LABEL_WIDTH + SPINCTRL_BTN_WIDTH, - TRUE, - TRUE, - FALSE, - NULL, - (F32)gSavedSettings.getS32("DropShadowFloater"), - 0.f, 10.f, 1.0f, - std::string("DropShadowFloater")); - sliderctrl->setFollowsTop(); - sliderctrl->setFollowsLeft(); - addChild(sliderctrl); - cur_y -= VPAD + SLIDERCTRL_HEIGHT; - - sliderctrl = new LLSliderCtrl(std::string("Drop Shadow Button"), - LLRect( LEFT, cur_y, RIGHT, cur_y - SLIDERCTRL_HEIGHT ), - std::string("Drop Shadow Button"), - font, - LABEL_OFFSET, - RULER2 + SPINCTRL_DEFAULT_LABEL_WIDTH + SPINCTRL_BTN_WIDTH, - TRUE, - TRUE, - FALSE, - NULL, - (F32)gSavedSettings.getS32("DropShadowButton"), - 0.f, 10.f, 1.0f, - std::string("DropShadowButton")); - sliderctrl->setFollowsTop(); - sliderctrl->setFollowsLeft(); - addChild(sliderctrl); - cur_y -= VPAD + SLIDERCTRL_HEIGHT; - - check = new LLCheckboxCtrl(std::string("left click"), - LLRect(LEFT, cur_y, RIGHT, cur_y - 20), - std::string("Left Click Shows Menu Unless Interactive"), - font, - NULL, - gSavedSettings.getBOOL("LeftClickShowMenu")); - check->setFollows(FOLLOWS_LEFT|FOLLOWS_TOP); - addChild(check); - mLeftClickCheck = check; - cur_y -= VPAD+20; -} - - -LLPanelDebug::~LLPanelDebug() -{ - // Children all cleaned up by default view destructor. -} - - -void LLPanelDebug::apply() -{ - gSavedSettings.setBOOL("LeftClickShowMenu", mLeftClickCheck->get() ); -} - -void LLPanelDebug::cancel() -{ -} diff --git a/indra/newview/llpaneldebug.h b/indra/newview/llpaneldebug.h deleted file mode 100644 index 10e82f5ca..000000000 --- a/indra/newview/llpaneldebug.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @file llpaneldebug.h - * @brief Debug preferences panel for preferences floater - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLPANELDEBUG_H -#define LL_LLPANELDEBUG_H - -#include "llpanel.h" - -class LLCheckBoxCtrl; - -class LLPanelDebug : public LLPanel -{ -public: - LLPanelDebug(const std::string& name, const LLRect& rect); - virtual ~LLPanelDebug(); - - void apply(); // Apply the changed values. - void cancel(); // Cancel the changed values. - -protected: - LLCheckBoxCtrl* mLeftClickCheck; -}; - -#endif // LL_LLPANELDEBUG_H diff --git a/indra/newview/llpanelevent.cpp b/indra/newview/llpanelevent.cpp index 9b453fbeb..ef25b25e9 100644 --- a/indra/newview/llpanelevent.cpp +++ b/indra/newview/llpanelevent.cpp @@ -229,7 +229,7 @@ void LLPanelEvent::onClickMap(void* data) if (!self->mEventInfo.mPosGlobal.isExactlyZero()) { gFloaterWorldMap->trackLocation(self->mEventInfo.mPosGlobal); - LLFloaterWorldMap::show(NULL, TRUE); + LLFloaterWorldMap::show(true); } } diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 2fc014216..7f43b4ce3 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -491,7 +491,7 @@ void LLPanelFace::sendTextureInfo() return (object->mDrawable) ? object->mDrawable->getFace(te): NULL; } } get_last_face_func; - LLFace* last_face; + LLFace* last_face(NULL); LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_last_face_func, last_face); LLPanelFaceSetAlignedTEFunctor setfunc(this, last_face); @@ -654,7 +654,7 @@ void LLPanelFace::getState() return (object->mDrawable) ? object->mDrawable->getFace(te): NULL; } } get_te_face_func; - LLFace* last_face; + LLFace* last_face(NULL); LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, last_face); LLPanelFaceGetIsAlignedTEFunctor get_is_aligend_func(last_face); // this will determine if the texture param controls are tentative: diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp index 71afc3862..26e77c6ba 100644 --- a/indra/newview/llpanelgrouplandmoney.cpp +++ b/indra/newview/llpanelgrouplandmoney.cpp @@ -293,7 +293,7 @@ void LLPanelGroupLandMoney::impl::onMapButton() LLVector3d pos_global(global_x, global_y, global_z); gFloaterWorldMap->trackLocation(pos_global); - LLFloaterWorldMap::show(NULL, TRUE); + LLFloaterWorldMap::show(true); } bool LLPanelGroupLandMoney::impl::applyContribution() diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index ffec84e7d..a69b4c76a 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -66,20 +66,17 @@ const S32 NOTICE_DATE_STRING_SIZE = 30; ///////////////////////// // LLPanelGroupNotices // ///////////////////////// -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLDropTarget -// -// This handy class is a simple way to drop something on another -// view. It handles drop events, always setting itself to the size of -// its parent. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLGroupDropTarget : public LLView + +#include "lldroptarget.h" +class LLGroupDropTarget : public LLDropTarget { public: - LLGroupDropTarget(const std::string& name, const LLRect& rect, LLPanelGroupNotices* panel, const LLUUID& group_id); + LLGroupDropTarget(const LLDropTarget::Params& p = LLDropTarget::Params()); ~LLGroupDropTarget() {}; - void doDrop(EDragAndDropType cargo_type, void* cargo_data); + // + // LLDropTarget functionality + virtual void doDrop(EDragAndDropType cargo_type, void* cargo_data); // // LLView functionality @@ -88,19 +85,26 @@ public: void* cargo_data, EAcceptance* accept, std::string& tooltip_msg); + static LLView* fromXML(LLXMLNodePtr node, LLView* parent, class LLUICtrlFactory* factory); + + void setGroupNoticesPanel(LLPanelGroupNotices* panel) { mGroupNoticesPanel = panel; } protected: LLPanelGroupNotices* mGroupNoticesPanel; - LLUUID mGroupID; }; -LLGroupDropTarget::LLGroupDropTarget(const std::string& name, const LLRect& rect, - LLPanelGroupNotices* panel, const LLUUID& group_id) : - LLView(name, rect, NOT_MOUSE_OPAQUE, FOLLOWS_ALL), - mGroupNoticesPanel(panel), - mGroupID(group_id) +LLGroupDropTarget::LLGroupDropTarget(const LLDropTarget::Params& p) +: LLDropTarget(p) { } +// static +LLView* LLGroupDropTarget::fromXML(LLXMLNodePtr node, LLView* parent, LLUICtrlFactory* factory) +{ + LLGroupDropTarget* target = new LLGroupDropTarget(); + target->initFromXML(node, parent); + return target; +} + void LLGroupDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data) { llinfos << "LLGroupDropTarget::doDrop()" << llendl; @@ -114,7 +118,7 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, { BOOL handled = FALSE; - if (!gAgent.hasPowerInGroup(mGroupID,GP_NOTICES_SEND)) + if (!gAgent.hasPowerInGroup(mEntityID,GP_NOTICES_SEND)) { *accept = ACCEPT_NO; return TRUE; @@ -172,6 +176,8 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, return handled; } +static LLRegisterWidget r("group_drop_target"); + //----------------------------------------------------------------------------- // LLPanelGroupNotices //----------------------------------------------------------------------------- @@ -264,17 +270,9 @@ BOOL LLPanelGroupNotices::postBuild() mPanelCreateNotice = getChild("panel_create_new_notice",recurse); mPanelViewNotice = getChild("panel_view_past_notice",recurse); - // Must be in front of all other UI elements. - LLPanel* dtv = getChild("drop_target",recurse); - LLGroupDropTarget* target = new LLGroupDropTarget("drop_target", - dtv->getRect(), - this, mGroupID); - target->setEnabled(TRUE); - target->setToolTip(dtv->getToolTip()); - - mPanelCreateNotice->addChild(target); - mPanelCreateNotice->removeChild(dtv); - delete dtv; + LLGroupDropTarget* group_drop_target = getChild("drop_target",recurse); + group_drop_target->setEntityID(mGroupID); + group_drop_target->setGroupNoticesPanel(this); arrangeNoticeView(VIEW_PAST_NOTICE); diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 4661be49b..ab9ff5664 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -3,10 +3,9 @@ * @brief Panel for roles information about a particular group. * * $LicenseInfo:firstyear=2006&license=viewergpl$ - * + * Second Life Viewer Source Code * Copyright (c) 2006-2009, Linden Research, Inc. * - * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab * to you under the terms of the GNU General Public License, version 2.0 * ("GPL"), unless you have obtained a separate licensing agreement @@ -1564,9 +1563,11 @@ void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemb { return; } - + // trying to avoid unnecessary hash lookups - if (matchesSearchFilter(av_name.getLegacyName())) + std::string name; + LLAvatarNameCache::getPNSName(av_name, name); // Singu Note: Diverge from LL Viewer and filter by name displayed + if (matchesSearchFilter(name)) { addMemberToList(member); if(!mMembersList->getEnabled()) @@ -1574,13 +1575,13 @@ void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemb mMembersList->setEnabled(TRUE); } } - } + void LLPanelGroupMembersSubTab::updateMembers() { mPendingMemberUpdate = FALSE; - lldebugs << "LLPanelGroupMembersSubTab::updateMembers()" << llendl; + // Rebuild the members list. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); if (!gdatap) @@ -1598,7 +1599,7 @@ void LLPanelGroupMembersSubTab::updateMembers() return; } - //cleanup list only for first iretation + //cleanup list only for first iteration if(mMemberProgress == gdatap->mMembers.begin()) { mMembersList->deleteAllItems(); @@ -1616,10 +1617,11 @@ void LLPanelGroupMembersSubTab::updateMembers() continue; // Do filtering on name if it is already in the cache. - LLAvatarName av_name; - if (LLAvatarNameCache::get(mMemberProgress->first, &av_name)) + // Singu Note: Diverge from LL Viewer and filter by name displayed + std::string fullname; + if (LLAvatarNameCache::getPNSName(mMemberProgress->first, fullname)) { - if (matchesSearchFilter(av_name.getLegacyName())) + if (matchesSearchFilter(fullname)) { addMemberToList(mMemberProgress->second); } diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h index e754b846d..fe1103f2f 100644 --- a/indra/newview/llpanelgrouproles.h +++ b/indra/newview/llpanelgrouproles.h @@ -3,10 +3,9 @@ * @brief Panel for roles information about a particular group. * * $LicenseInfo:firstyear=2006&license=viewergpl$ - * + * Second Life Viewer Source Code * Copyright (c) 2006-2009, Linden Research, Inc. * - * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab * to you under the terms of the GNU General Public License, version 2.0 * ("GPL"), unless you have obtained a separate licensing agreement @@ -34,8 +33,8 @@ #define LL_LLPANELGROUPROLES_H #include "llpanelgroup.h" -#include "llavatarnamecache.h" +class LLAvatarName; class LLFilterEditor; class LLNameListCtrl; class LLPanelGroupSubTab; diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp index da0b9a546..f599fc915 100644 --- a/indra/newview/llpanelpick.cpp +++ b/indra/newview/llpanelpick.cpp @@ -507,7 +507,7 @@ void LLPanelPick::onClickMap(void* data) { LLPanelPick* self = (LLPanelPick*)data; gFloaterWorldMap->trackLocation(self->mPosGlobal); - LLFloaterWorldMap::show(NULL, TRUE); + LLFloaterWorldMap::show(true); } // static diff --git a/indra/newview/llpanelplace.cpp b/indra/newview/llpanelplace.cpp index ba12d60a0..80af2ac56 100644 --- a/indra/newview/llpanelplace.cpp +++ b/indra/newview/llpanelplace.cpp @@ -384,7 +384,7 @@ void LLPanelPlace::onClickMap(void* data) if (!self->mPosGlobal.isExactlyZero()) { gFloaterWorldMap->trackLocation(self->mPosGlobal); - LLFloaterWorldMap::show(NULL, TRUE); + LLFloaterWorldMap::show(true); } } diff --git a/indra/newview/llprefschat.cpp b/indra/newview/llprefschat.cpp index 559ad2ba9..f62a4d4e9 100644 --- a/indra/newview/llprefschat.cpp +++ b/indra/newview/llprefschat.cpp @@ -55,6 +55,7 @@ private: S32 mChatSize; F32 mChatPersist; S32 mChatMaxLines; + S32 mChatBottomOffset; LLColor4 mSystemChatColor; LLColor4 mUserChatColor; LLColor4 mAgentChatColor; @@ -115,6 +116,7 @@ void LLPrefsChatImpl::refreshValues() mChatSize = gSavedSettings.getS32("ChatFontSize"); mChatPersist = gSavedSettings.getF32("ChatPersistTime"); mChatMaxLines = gSavedSettings.getS32("ConsoleMaxLines"); + mChatBottomOffset = gSavedSettings.getS32("ConsoleBottomOffset"); mSystemChatColor = gSavedSettings.getColor4("SystemChatColor"); mUserChatColor = gSavedSettings.getColor4("UserChatColor"); mAgentChatColor = gSavedSettings.getColor4("AgentChatColor"); @@ -140,6 +142,7 @@ void LLPrefsChatImpl::cancel() gSavedSettings.setS32("ChatFontSize", mChatSize); gSavedSettings.setF32("ChatPersistTime", mChatPersist); gSavedSettings.setS32("ConsoleMaxLines", mChatMaxLines); + gSavedSettings.setS32("ConsoleBottomOffset", mChatBottomOffset); gSavedSettings.setColor4("SystemChatColor", mSystemChatColor); gSavedSettings.setColor4("UserChatColor", mUserChatColor); gSavedSettings.setColor4("AgentChatColor", mAgentChatColor); diff --git a/indra/newview/llprefsim.cpp b/indra/newview/llprefsim.cpp index 8aed046ca..2f7faca75 100644 --- a/indra/newview/llprefsim.cpp +++ b/indra/newview/llprefsim.cpp @@ -114,15 +114,12 @@ BOOL LLPrefsIMImpl::postBuild() childDisable("log_chat"); childDisable("log_show_history"); //childDisable("log_path_button"); - childDisable("busy_response"); childDisable("log_instant_messages_timestamp"); childDisable("log_chat_timestamp"); childDisable("log_chat_IM"); childDisable("log_date_timestamp"); childDisable("logfile_name_datestamp"); - childSetText("busy_response", getString("log_in_to_change")); - childSetValue("include_im_in_chat_console", gSavedSettings.getBOOL("IMInChatConsole")); childSetValue("show_timestamps_check", gSavedSettings.getBOOL("IMShowTimestamps")); childSetValue("friends_online_notify_checkbox", gSavedSettings.getBOOL("ChatOnlineNotification")); @@ -147,7 +144,6 @@ BOOL LLPrefsIMImpl::postBuild() void LLPrefsIMImpl::enableHistory() { - if (childGetValue("log_instant_messages").asBoolean() || childGetValue("log_chat").asBoolean()) { childEnable("log_show_history"); @@ -162,18 +158,8 @@ void LLPrefsIMImpl::enableHistory() void LLPrefsIMImpl::apply() { - LLTextEditor* busy = getChild("busy_response"); - LLWString busy_response; - if (busy) busy_response = busy->getWText(); - LLWStringUtil::replaceTabsWithSpaces(busy_response, 4); - LLWStringUtil::replaceChar(busy_response, '\n', '^'); - LLWStringUtil::replaceChar(busy_response, ' ', '%'); - if(mGotPersonalInfo) { - - gSavedPerAccountSettings.setString("BusyModeResponse", std::string(wstring_to_utf8str(busy_response))); - gSavedSettings.setBOOL("IMInChatConsole", childGetValue("include_im_in_chat_console").asBoolean()); gSavedSettings.setBOOL("IMShowTimestamps", childGetValue("show_timestamps_check").asBoolean()); gSavedSettings.setBOOL("ChatOnlineNotification", childGetValue("friends_online_notify_checkbox").asBoolean()); @@ -272,24 +258,11 @@ void LLPrefsIMImpl::setPersonalInfo(const std::string& visibility, bool im_via_e childSetValue("send_im_to_email", im_via_email); childEnable("log_instant_messages"); childEnable("log_chat"); - childEnable("busy_response"); childEnable("log_instant_messages_timestamp"); childEnable("log_chat_timestamp"); childEnable("log_chat_IM"); childEnable("log_date_timestamp"); childEnable("logfile_name_datestamp"); - - //RN: get wide string so replace char can work (requires fixed-width encoding) - LLWString busy_response = utf8str_to_wstring( gSavedPerAccountSettings.getString("BusyModeResponse") ); - LLWStringUtil::replaceChar(busy_response, '^', '\n'); - LLWStringUtil::replaceChar(busy_response, '%', ' '); - childSetText("busy_response", wstring_to_utf8str(busy_response)); -// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) - if (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM)) - { - childDisable("busy_response"); - } -// [/RLVa:KB] enableHistory(); diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 503628f6c..8306a0040 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -597,11 +597,11 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate) } const LLTextSegment* segment = NULL; - std::vector selected_segments; + std::vector selected_segments; mEditor->getSelectedSegments(selected_segments); // try segments in selection range first - std::vector::iterator segment_iter; + std::vector::iterator segment_iter; for (segment_iter = selected_segments.begin(); segment_iter != selected_segments.end(); ++segment_iter) { if((*segment_iter)->getToken() && (*segment_iter)->getToken()->getType() == LLKeywordToken::WORD) diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 5a725767d..300330cb6 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -4740,7 +4740,7 @@ void LLSelectMgr::packPermissions(LLSelectNode* node, void *user_data) gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID()); gMessageSystem->addU8Fast(_PREHASH_Field, data->mField); - gMessageSystem->addBOOLFast(_PREHASH_Set, data->mSet); + gMessageSystem->addU8Fast(_PREHASH_Set, data->mSet ? PERM_SET_TRUE : PERM_SET_FALSE); gMessageSystem->addU32Fast(_PREHASH_Mask, data->mMask); } @@ -5144,10 +5144,9 @@ void LLSelectMgr::processObjectPropertiesFamily(LLMessageSystem* msg, void** use msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Description, desc); // the reporter widget askes the server for info about picked objects - if (request_flags & (COMPLAINT_REPORT_REQUEST | BUG_REPORT_REQUEST)) + if (request_flags & COMPLAINT_REPORT_REQUEST) { - EReportType report_type = (COMPLAINT_REPORT_REQUEST & request_flags) ? COMPLAINT_REPORT : BUG_REPORT; - LLFloaterReporter *reporterp = LLFloaterReporter::getReporter(report_type); + LLFloaterReporter *reporterp = LLFloaterReporter::getInstance(); if (reporterp) { std::string fullname; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 66718b34d..9f44db11b 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -221,7 +221,6 @@ #include "wlfPanel_AdvSettings.h" //Lower right Windlight and Rendering options #include "lldaycyclemanager.h" #include "llfloaterblacklist.h" -#include "scriptcounter.h" #include "shfloatermediaticker.h" #include "llpacketring.h" // @@ -1008,6 +1007,8 @@ bool idle_startup() LLTrans::setDefaultArg("[GRID_OWNER]", gHippoGridManager->getConnectedGrid()->getGridOwner()); LLScriptEdCore::parseFunctions("lsl_functions_os.xml"); //Singu Note: This appends to the base functions parsed from lsl_functions_sl.xml } + // Avination doesn't want the viewer to do bandwidth throttling (it is done serverside, taking UDP into account too). + AIPerService::setNoHTTPBandwidthThrottling(gHippoGridManager->getConnectedGrid()->isAvination()); // create necessary directories // *FIX: these mkdir's should error check @@ -3223,7 +3224,6 @@ void pass_processObjectPropertiesFamily(LLMessageSystem *msg, void**) // Send the result to the corresponding requesters. LLSelectMgr::processObjectPropertiesFamily(msg, NULL); JCFloaterAreaSearch::processObjectPropertiesFamily(msg, NULL); - ScriptCounter::processObjectPropertiesFamily(msg,0); } void register_viewer_callbacks(LLMessageSystem* msg) @@ -4378,9 +4378,17 @@ bool process_login_success_response(std::string& password) tmp = response["search"].asString(); if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setSearchUrl(tmp); tmp = response["currency"].asString(); - if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setCurrencySymbol(tmp); + if (!tmp.empty()) + { + LLTrans::setDefaultArg("[CURRENCY]", tmp); + gHippoGridManager->getConnectedGrid()->setCurrencySymbol(tmp); + } tmp = response["currency_text"].asString(); - if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setCurrencyText(tmp); + if (!tmp.empty()) + { + LLTrans::setDefaultArg("[CURRENCY_TEXT]", tmp); + gHippoGridManager->getConnectedGrid()->setCurrencyText(tmp); + } tmp = response["real_currency"].asString(); if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setRealCurrencySymbol(tmp); tmp = response["directory_fee"].asString(); diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 0563a150c..a9da2c1a9 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -505,9 +505,9 @@ void LLStatusBar::refresh() if (region) { bool pf_disabled = !region->dynamicPathfindingEnabled(); - getChild("pf_dirty")->setVisible(mIsNavMeshDirty); + getChild("pf_dirty")->setVisible(!pf_disabled && mIsNavMeshDirty); getChild("pf_disabled")->setVisible(pf_disabled); - const std::string pf_icon = mIsNavMeshDirty ? "pf_dirty" : pf_disabled ? "pf_disabled" : ""; + const std::string pf_icon = pf_disabled ? "pf_disabled" : mIsNavMeshDirty ? "pf_dirty" : ""; if (!pf_icon.empty()) { x += 6; diff --git a/indra/newview/llstylemap.cpp b/indra/newview/llstylemap.cpp index a34b4b83f..a0c64505e 100644 --- a/indra/newview/llstylemap.cpp +++ b/indra/newview/llstylemap.cpp @@ -33,10 +33,6 @@ #include "llviewerprecompiledheaders.h" #include "llstylemap.h" -#include "llstring.h" -#include "llui.h" -#include "llviewercontrol.h" -#include "llagent.h" LLStyleMap::LLStyleMap() { @@ -60,19 +56,12 @@ const LLStyleSP &LLStyleMap::lookupAgent(const LLUUID &source) if (find(source) == end()) { LLStyleSP style(new LLStyle); - style->setVisible(true); - style->setFontName(LLStringUtil::null); - if (source != LLUUID::null && source != gAgent.getID() ) + if (source.notNull()) { style->setColor(gSavedSettings.getColor4("HTMLLinkColor")); std::string link = llformat("secondlife:///app/agent/%s/about",source.asString().c_str()); style->setLinkHREF(link); } - else - { - // Make the resident's own name white and don't make the name clickable. - style->setColor(LLColor4::white); - } (*this)[source] = style; } return (*this)[source]; @@ -86,9 +75,7 @@ const LLStyleSP &LLStyleMap::lookup(const LLUUID& id, const std::string& link) if (iter == end()) { LLStyleSP style(new LLStyle); - style->setVisible(true); - style->setFontName(LLStringUtil::null); - if (id != LLUUID::null && !link.empty()) + if (id.notNull() && !link.empty()) { style->setColor(gSavedSettings.getColor4("HTMLLinkColor")); style->setLinkHREF(link); diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index f80bd9539..cdc31ae43 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -413,11 +413,8 @@ public: } } - /*virtual*/ bool followRedir() const - { - return mFollowRedir; - } - + /*virtual*/ bool followRedir() const { return mFollowRedir; } + /*virtual*/ AICapabilityType capability_type(void) const { return cap_texture; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return HTTPGetResponder_timeout; } /*virtual*/ char const* getName(void) const { return "HTTPGetResponder"; } @@ -1272,9 +1269,11 @@ bool LLTextureFetchWorker::doWork(S32 param) } // Let AICurl decide if we can process more HTTP requests at the moment or not. - static const LLCachedControl throttle_bandwidth("HTTPThrottleBandwidth", 2000); - bool const no_bandwidth_throttling = gHippoGridManager->getConnectedGrid()->isAvination(); - if (!AIPerService::wantsMoreHTTPRequestsFor(mPerServicePtr, throttle_bandwidth, no_bandwidth_throttling)) + + // AIPerService::approveHTTPRequestFor returns approvement for ONE request. + // This object keeps track of whether or not that is honored. + LLPointer approved = AIPerService::approveHTTPRequestFor(mPerServicePtr, cap_texture); + if (!approved) { return false ; //wait. } @@ -1323,7 +1322,7 @@ bool LLTextureFetchWorker::doWork(S32 param) } LLHTTPClient::request(mUrl, LLHTTPClient::HTTP_GET, NULL, new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, mRequestedOffset, true), - headers/*,*/ DEBUG_CURLIO_PARAM(debug_off), keep_alive, no_does_authentication, allow_compressed_reply, NULL, 0, NULL); + headers, approved/*,*/ DEBUG_CURLIO_PARAM(debug_off), keep_alive, no_does_authentication, allow_compressed_reply, NULL, 0, NULL); res = true; } if (!res) diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 3e7dba834..70c6d0b5e 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -37,6 +37,7 @@ #include "llimageworker.h" #include "llrender.h" +#include "aicurlperservice.h" #include "llappviewer.h" #include "llselectmgr.h" #include "llviewertexlayer.h" @@ -645,18 +646,15 @@ void LLGLTexMemBar::draw() text_color, LLFontGL::LEFT, LLFontGL::TOP); left += LLFontGL::getFontMonospace()->getWidth(text); - // This bandwidth is averaged over 1 seconds (in kbps). - F32 bandwidth = AICurlInterface::getHTTPBandwidth() / 125.f; // Convert from bytes/s to kbps. - // This is the maximum bandwidth allowed for curl transactions (of any type and averaged per second), - // that is actually used to limit the number of HTTP texture requests (and only those). - // Comparing that with 'bandwidth' is a bit like comparing apples and oranges, but again... who really cares. - static const LLCachedControl max_bandwidth("HTTPThrottleBandwidth", 2000); - color = bandwidth > max_bandwidth ? LLColor4::red : bandwidth > max_bandwidth*.75f ? LLColor4::yellow : text_color; + // This bandwidth is averaged over 1 seconds (in bytes/s). + size_t const bandwidth = AICurlInterface::getHTTPBandwidth(); + size_t const max_bandwidth = AIPerService::getHTTPThrottleBandwidth125(); + color = (bandwidth > max_bandwidth) ? LLColor4::red : ((bandwidth > max_bandwidth * .75f) ? LLColor4::yellow : text_color); color[VALPHA] = text_color[VALPHA]; - text = llformat("BW:%.0f/%.0f", bandwidth, max_bandwidth.get()); + text = llformat("BW:%lu/%lu", bandwidth / 125, max_bandwidth / 125); LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, v_offset + line_height*2, color, LLFontGL::LEFT, LLFontGL::TOP); - + S32 dx1 = 0; if (LLAppViewer::getTextureFetch()->mDebugPause) { diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp index a72c8be5b..8d4820dce 100644 --- a/indra/newview/lltoolbar.cpp +++ b/indra/newview/lltoolbar.cpp @@ -307,7 +307,12 @@ void LLToolBar::refresh() setVisible(show && !mouselook); BOOL sitting = FALSE; - if (gAgentAvatarp) + static LLCachedControl continue_flying_on_unsit("LiruContinueFlyingOnUnsit"); + if (continue_flying_on_unsit) + { + sitting = false; + } + else if (gAgentAvatarp) { sitting = gAgentAvatarp->isSitting(); } diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp index 326232fb7..24dc16383 100644 --- a/indra/newview/lltracker.cpp +++ b/indra/newview/lltracker.cpp @@ -111,9 +111,8 @@ LLTracker::~LLTracker() // static -void LLTracker::stopTracking(void* userdata) +void LLTracker::stopTracking(bool clear_ui) { - BOOL clear_ui = ((BOOL)(intptr_t)userdata); instance()->stopTrackingAll(clear_ui); } diff --git a/indra/newview/lltracker.h b/indra/newview/lltracker.h index c727c29d5..f7009ae20 100644 --- a/indra/newview/lltracker.h +++ b/indra/newview/lltracker.h @@ -81,8 +81,8 @@ public: // these are static so that they can be used a callbacks static ETrackingStatus getTrackingStatus() { return instance()->mTrackingStatus; } static ETrackingLocationType getTrackedLocationType() { return instance()->mTrackingLocationType; } - static BOOL isTracking(void*) { return instance()->mTrackingStatus != TRACKING_NOTHING; } - static void stopTracking(void*); + static BOOL isTracking() { return instance()->mTrackingStatus != TRACKING_NOTHING; } + static void stopTracking(bool); static void clearFocus(); static const LLUUID& getTrackedLandmarkAssetID() { return instance()->mTrackedLandmarkAssetID; } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 1fa7a4eca..59958523b 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -84,7 +84,6 @@ #include "aicurl.h" #include "aihttptimeoutpolicy.h" - #ifdef TOGGLE_HACKED_GODLIKE_VIEWER BOOL gHackGodmode = FALSE; #endif @@ -330,6 +329,12 @@ static bool handleBandwidthChanged(const LLSD& newvalue) return true; } +static bool handleHTTPBandwidthChanged(const LLSD& newvalue) +{ + AIPerService::setHTTPThrottleBandwidth((F32) newvalue.asReal()); + return true; +} + static bool handleChatFontSizeChanged(const LLSD& newvalue) { if(gConsole) @@ -666,6 +671,7 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderTreeLODFactor")->getSignal()->connect(boost::bind(&handleTreeLODChanged, _2)); gSavedSettings.getControl("RenderFlexTimeFactor")->getSignal()->connect(boost::bind(&handleFlexLODChanged, _2)); gSavedSettings.getControl("ThrottleBandwidthKBPS")->getSignal()->connect(boost::bind(&handleBandwidthChanged, _2)); + gSavedSettings.getControl("HTTPThrottleBandwidth")->getSignal()->connect(boost::bind(&handleHTTPBandwidthChanged, _2)); gSavedSettings.getControl("RenderGamma")->getSignal()->connect(boost::bind(&handleGammaChanged, _2)); gSavedSettings.getControl("RenderFogRatio")->getSignal()->connect(boost::bind(&handleFogRatioChanged, _2)); gSavedSettings.getControl("RenderMaxPartCount")->getSignal()->connect(boost::bind(&handleMaxPartCountChanged, _2)); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 97ea6d71a..165e22201 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -359,13 +359,13 @@ void LLViewerInventoryItem::fetchFromServer(void) const // we have to check region. It can be null after region was destroyed. See EXT-245 if (region) { - if(gAgent.getID() != mPermissions.getOwner()) + if(gAgent.getID() != mPermissions.getOwner()) { - url = region->getCapability("FetchLib2"); + url = region->getCapability("FetchLib2"); } - else - { - url = region->getCapability("FetchInventory2"); + else + { + url = region->getCapability("FetchInventory2"); } } else diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index ee3c77fcf..52799fdf4 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -63,7 +63,6 @@ #include "llfirstuse.h" #include "llfloaterabout.h" #include "llfloateractivespeakers.h" -#include "llfloaterbvhpreview.h" #include "llfloateravatarinfo.h" #include "llfloateravatarlist.h" #include "llfloateravatartextures.h" @@ -403,7 +402,7 @@ BOOL handle_check_pose(void* userdata) { } -void handle_hide_typing_notification(void*); +void handle_close_all_notifications(void*); void handle_open_message_log(void*); // @@ -761,7 +760,7 @@ void init_menus() ins->setVisible(false); ins = gMenuBarView->getChildView("insert_tools", true, false); ins->setVisible(false); - /* Singu Note: When the advanced and/or admin menu is made xml, this should be uncommented. + /* Singu Note: When the advanced and/or admin menus are made xml, these should be uncommented. ins = gMenuBarView->getChildView("insert_advanced", true, false); ins->setVisible(false); ins = gMenuBarView->getChildView("insert_admin", true, false); @@ -2339,18 +2338,19 @@ bool enable_object_edit() enable = LLViewerParcelMgr::getInstance()->allowAgentBuild() || LLSelectMgr::getInstance()->getSelection()->isAttachment(); } - else if (LLSelectMgr::getInstance()->selectGetAllValidAndObjectsFound()) + // Singu Note: The following check is wasteful, bypass it + // The following RLVa patch has been modified from its original version. It been formatted to run in the time allotted. + //else if (LLSelectMgr::getInstance()->selectGetAllValidAndObjectsFound()) +// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified after RLVa-1.3.0c on 2013-05-18 + else if (!rlv_handler_t::isEnabled() || (!gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) && (!gRlvHandler.hasBehaviour(RLV_BHVR_EDITOBJ))) { -// enable = true; -// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c - bool fRlvCanEdit = (!gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) && (!gRlvHandler.hasBehaviour(RLV_BHVR_EDITOBJ)); - if (!fRlvCanEdit) - { - LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection(); - RlvSelectIsEditable f; - fRlvCanEdit = (hSel.notNull()) && ((hSel->getFirstRootNode(&f, TRUE)) == NULL); - } - enable = fRlvCanEdit; + enable = true; + } + else // Restrictions disallow edit, check for an exception for the selection + { + LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection(); + RlvSelectIsEditable f; + enable = (hSel.notNull()) && ((hSel->getFirstRootNode(&f, TRUE)) == NULL); // [/RLVa:KB] } @@ -3009,7 +3009,12 @@ class LLScriptCount : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - ScriptCounter::serializeSelection(false); + if (LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()) + { + ScriptCounter* sc = new ScriptCounter(false, object); + sc->requestInventories(); + // sc will destroy itself + } return true; } }; @@ -3018,7 +3023,12 @@ class LLScriptDelete : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - ScriptCounter::serializeSelection(true); + if (LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()) + { + ScriptCounter* sc = new ScriptCounter(true, object); + sc->requestInventories(); + // sc will destroy itself + } return true; } }; @@ -3225,10 +3235,7 @@ class LLAvatarCopyUUID : public view_listener_t LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); if(!avatar) return true; - LLUUID uuid = avatar->getID(); - char buffer[UUID_STR_LENGTH]; /*Flawfinder: ignore*/ - uuid.toString(buffer); - gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(buffer)); + gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(avatar->getID().asString())); return true; } }; @@ -3701,6 +3708,17 @@ void handle_open_message_log(void*) LLFloaterMessageLog::show(); } +void handle_close_all_notifications(void*) +{ + LLView::child_list_t child_list(*(gNotifyBoxView->getChildList())); + for(LLView::child_list_iter_t iter = child_list.begin(); + iter != child_list.end(); + iter++) + { + gNotifyBoxView->removeChild(*iter); + } +} + void handle_fake_away_status(void*) { bool fake_away = gSavedSettings.getBOOL("FakeAway"); @@ -3971,7 +3989,12 @@ class LLWorldEnableFly : public view_listener_t bool handleEvent(LLPointer event, const LLSD& userdata) { BOOL sitting = FALSE; - if (gAgentAvatarp) + static LLCachedControl continue_flying_on_unsit("LiruContinueFlyingOnUnsit"); + if (continue_flying_on_unsit) + { + sitting = false; + } + else if (gAgentAvatarp) { sitting = gAgentAvatarp->isSitting(); } @@ -6359,7 +6382,8 @@ struct MenuFloaterDict : public LLSingleton //registerFloater("script info", boost::bind(&LLFloaterScriptLimits::showInstance,LLSD())); // Phoenix: Wolfspirit: Enabled Show Floater out of viewer menu registerFloater("toolbar", boost::bind(&LLToolBar::toggle,(void*)NULL), boost::bind(&LLToolBar::visible,(void*)NULL)); - registerFloater("world map", boost::bind(&LLFloaterWorldMap::toggle,(void*)NULL)); + registerFloater("world map", boost::bind(&LLFloaterWorldMap::toggle)); + registerFloater("sound_explorer", boost::bind(&LLFloaterExploreSounds::toggle), boost::bind(&LLFloaterExploreSounds::visible)); registerFloater("asset_blacklist", boost::bind(&LLFloaterBlacklist::toggle), boost::bind(&LLFloaterBlacklist::visible)); registerFloater ("about land"); @@ -6383,12 +6407,11 @@ struct MenuFloaterDict : public LLSingleton registerFloater ("teleport history"); registerFloater ("pathfinding_characters"); registerFloater ("pathfinding_linksets"); - registerFloater ("object_area_search"); - + } void registerFloater(const std::string& name, boost::function show, boost::function visible = NULL) { - mEntries.insert( std::make_pair( name, std::make_pair( show, visible ) ) ); + mEntries.insert( std::make_pair( name, std::make_pair( show, visible ) ) ); } template void registerFloater(const std::string& name, const LLSD& key = LLSD()) @@ -6459,12 +6482,6 @@ class LLShowFloater : public view_listener_t LLFloaterBump::show(NULL); } } - else if (floater_name == "bug reporter") - { - // Prevent menu from appearing in screen shot. - gMenuHolder->hideMenus(); - LLFloaterReporter::showFromMenu(BUG_REPORT); - } else // Simple codeless floater { LLFloater* floater = LLUICtrlFactory::getInstance()->getBuiltFloater(floater_name); @@ -9064,32 +9081,7 @@ class SinguCloseAllDialogs : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLView::child_list_t child_list(*(gNotifyBoxView->getChildList())); - for(LLView::child_list_iter_t iter = child_list.begin(); - iter != child_list.end(); - iter++) - { - gNotifyBoxView->removeChild(*iter); - } - return true; - } -}; - -class SinguForceGroundSit : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - if (isAgentAvatarValid()) - { - if (!gAgentAvatarp->isSitting()) - { - gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND); - } - else - { - gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); - } - } + handle_close_all_notifications(NULL); return true; } }; @@ -9108,8 +9100,7 @@ class SinguNimble : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - BOOL checked = gSavedSettings.getBOOL("Nimble"); - gSavedSettings.setBOOL("Nimble", !checked); + gSavedSettings.setBOOL("Nimble", !gSavedSettings.getBOOL("Nimble")); return true; } @@ -9119,28 +9110,7 @@ class SinguCheckNimble : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - BOOL checked = gSavedSettings.getBOOL("Nimble"); - gMenuHolder->findControl(userdata["control"].asString())->setValue(checked); - - return true; - } -}; - -class SinguObjectAreaSearch : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - JCFloaterAreaSearch::toggleInstance(); - - return true; - } -}; - -class SinguSoundExplorer : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - LLFloaterExploreSounds::toggle(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(gSavedSettings.getBOOL("Nimble")); return true; } @@ -9170,8 +9140,7 @@ class SinguCheckStreamingAudioDisplay : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - bool checked = handle_singleton_check(NULL); - gMenuHolder->findControl(userdata["control"].asString())->setValue(checked); + gMenuHolder->findControl(userdata["control"].asString())->setValue(handle_singleton_check(NULL)); return true; } @@ -9199,8 +9168,7 @@ class SinguCheckPoseStand : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - bool checked = handle_check_pose(NULL); - gMenuHolder->findControl(userdata["control"].asString())->setValue(checked); + gMenuHolder->findControl(userdata["control"].asString())->setValue(handle_check_pose(NULL)); return true; } }; @@ -9227,8 +9195,7 @@ class SinguCheckDebugConsole : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - bool checked = handle_singleton_check(NULL); - gMenuHolder->findControl(userdata["control"].asString())->setValue(checked); + gMenuHolder->findControl(userdata["control"].asString())->setValue(handle_singleton_check(NULL)); return true; } }; @@ -9237,10 +9204,11 @@ class SinguVisibleDebugConsole : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - bool visible = !(gAgent.getRegion()->getCapability("SimConsoleAsync").empty()); - LLView* item = gMenuBarView->getChildView("Region Debug Console", true, false); - item->setVisible(visible); - + if (LLViewerRegion* region = gAgent.getRegion()) + { + if (LLView* item = gMenuBarView->getChildView("Region Debug Console", true, false)) + item->setVisible(!(region->getCapability("SimConsoleAsync").empty() || region->getCapability("SimConsole").empty())); + } return true; } }; @@ -9445,6 +9413,7 @@ void initialize_menus() addMenu(new LLObjectMeasure(), "Object.Measure"); addMenu(new LLObjectData(), "Object.Data"); addMenu(new LLScriptCount(), "Object.ScriptCount"); + addMenu(new LLObjectVisibleScriptCount(), "Object.VisibleScriptCount"); addMenu(new LLKillEmAll(), "Object.Destroy"); addMenu(new LLPowerfulWizard(), "Object.Explode"); addMenu(new LLCanIHasKillEmAll(), "Object.EnableDestroy"); @@ -9523,13 +9492,9 @@ void initialize_menus() // Singularity menu addMenu(new SinguCloseAllDialogs(), "CloseAllDialogs"); // ---- Fake away handled elsewhere - addMenu(new SinguForceGroundSit(), "ForceGroundSit"); addMenu(new SinguAnimationOverride(), "AnimationOverride"); addMenu(new SinguNimble(), "Nimble"); addMenu(new SinguCheckNimble(), "CheckNimble"); - addMenu(new SinguObjectAreaSearch(), "ObjectAreaSearch"); - addMenu(new SinguSoundExplorer(), "SoundExplorer"); - addMenu(new SinguAssetBlacklist(), "AssetBlacklist"); addMenu(new SinguStreamingAudioDisplay(), "StreamingAudioDisplay"); addMenu(new SinguEnableStreamingAudioDisplay(), "EnableStreamingAudioDisplay"); addMenu(new SinguCheckStreamingAudioDisplay(), "CheckStreamingAudioDisplay"); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index d930cec27..3d22f49a5 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -31,6 +31,7 @@ #include "llviewerprecompiledheaders.h" #include "llviewermessage.h" +#include #include #include "llanimationstates.h" @@ -1950,6 +1951,28 @@ void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string m } +// Replace wild cards in autoresponse messages +std::string replace_wildcards(std::string autoresponse, const LLUUID& id, const std::string& name) +{ + // Add in their legacy name + boost::algorithm::replace_all(autoresponse, "#n", name); + + // Add in our location's slurl + boost::algorithm::replace_all(autoresponse, "#r", gAgent.getSLURL()); + + // Add in their display name + LLAvatarName av_name; + boost::algorithm::replace_all(autoresponse, "#d", LLAvatarNameCache::get(id, &av_name) ? av_name.mDisplayName : name); + + if (!isAgentAvatarValid()) return autoresponse; + // Add in idle time + LLStringUtil::format_map_t args; + args["[MINS]"] = boost::lexical_cast(gAgentAvatarp->mIdleTimer.getElapsedTimeF32()/60); + boost::algorithm::replace_all(autoresponse, "#i", LLTrans::getString("IM_autoresponse_minutes", args)); + + return autoresponse; +} + void process_improved_im(LLMessageSystem *msg, void **user_data) { if (gNoRender) @@ -2019,11 +2042,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) return; // NaCl End - // make sure that we don't have an empty or all-whitespace name + // make sure that we don't have an empty or all-whitespace name LLStringUtil::trim(name); if (name.empty()) { - name = LLTrans::getString("Unnamed"); + name = LLTrans::getString("Unnamed"); } // Preserve the unaltered name for use in group notice mute checking. @@ -2033,7 +2056,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) name = clean_name_from_im(name, dialog); // - llinfos << "RegionID: " << region_id.asString() << llendl; + if (region_id.notNull()) + llinfos << "RegionID: " << region_id.asString() << llendl; // BOOL is_busy = gAgent.getBusy(); @@ -2043,7 +2067,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) BOOL is_linden = LLMuteList::getInstance()->isLinden(name); BOOL is_owned_by_me = FALSE; BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true; - BOOL accept_im_from_only_friend = gSavedSettings.getBOOL("VoiceCallsFriendsOnly"); + BOOL accept_im_from_only_friend = gSavedSettings.getBOOL("InstantMessagesFriendsOnly"); LLUUID computed_session_id = LLIMMgr::computeSessionID(dialog,from_id); @@ -2067,238 +2091,24 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) std::string separator_string(": "); int message_offset = 0; - //Handle IRC styled /me messages. + //Handle IRC styled /me messages. std::string prefix = message.substr(0, 4); if (prefix == "/me " || prefix == "/me'") { + chat.mChatStyle = CHAT_STYLE_IRC; separator_string = ""; message_offset = 3; } - if( dialog == IM_TYPING_START - || dialog == IM_NOTHING_SPECIAL - || dialog == IM_TYPING_STOP - || dialog == IM_BUSY_AUTO_RESPONSE) - { - if(session_id != computed_session_id) - { - session_id = computed_session_id; - } - } - bool typing_init = false; - if( dialog == IM_TYPING_START && !is_muted ) - { - if(!gIMMgr->hasSession(computed_session_id) && gSavedSettings.getBOOL("AscentInstantMessageAnnounceIncoming")) - { - typing_init = true; - gIMMgr->addMessage( - computed_session_id, - from_id, - name, - llformat("%s ",name.c_str()) + LLTrans::getString("IM_announce_incoming"), - name, - IM_NOTHING_SPECIAL, - parent_estate_id, - region_id, - position, - false); - } - } - - bool is_auto_response = false; - if(dialog == IM_NOTHING_SPECIAL) { - // detect auto responses from GreenLife and compatible viewers - is_auto_response = ( message.substr(0, 21) == "/me (auto-response): " ); - } - - bool do_auto_response = false; - if( gSavedPerAccountSettings.getBOOL("AscentInstantMessageResponseAnyone" ) ) - do_auto_response = true; - - // odd name for auto respond to non-friends - if( gSavedPerAccountSettings.getBOOL("AscentInstantMessageResponseFriends") && - LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL ) - do_auto_response = true; - - if( is_muted ) - do_auto_response = gSavedPerAccountSettings.getBOOL("AscentInstantMessageResponseMuted"); - - if( offline != IM_ONLINE ) - do_auto_response = false; - - if( is_auto_response ) - do_auto_response = false; - - // handle cases where IM_NOTHING_SPECIAL is not an IM - if( name == SYSTEM_FROM || - from_id.isNull() || - to_id.isNull() ) - do_auto_response = false; - -// if( do_auto_response ) -// [RLVa:KB] - Alternate: Phoenix-370 - // Phoenix specific: auto-response should be blocked if the avie is RLV @sendim=n restricted and the recipient is not an exception - if ( (do_auto_response) && ( (!gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM)) || (gRlvHandler.isException(RLV_BHVR_SENDIM, from_id)) ) ) -// [/RLVa:KB] - { - if((dialog == IM_NOTHING_SPECIAL && !is_auto_response) || - (dialog == IM_TYPING_START && gSavedSettings.getBOOL("AscentInstantMessageAnnounceIncoming")) - ) - { - BOOL has = gIMMgr->hasSession(computed_session_id); - if(!has || gSavedPerAccountSettings.getBOOL("AscentInstantMessageResponseRepeat") || typing_init) - { - BOOL show = !gSavedPerAccountSettings.getBOOL("AscentInstantMessageShowResponded"); - if(!has && show) - { - gIMMgr->addSession(name, IM_NOTHING_SPECIAL, from_id); - } - if(show) - { - gIMMgr->addMessage( - computed_session_id, - from_id, - SYSTEM_FROM, - LLTrans::getString("IM_autoresponded_to") + llformat(" %s.",name.c_str()), - LLStringUtil::null, - IM_NOTHING_SPECIAL, - parent_estate_id, - region_id, - position, - false); - } - std::string my_name; - gAgent.buildFullname(my_name); - - //<-- Personalized Autoresponse by Madgeek - std::string autoresponse = gSavedPerAccountSettings.getText("AscentInstantMessageResponse"); - //Define Wildcards - std::string fname_wildcard = "#f"; - std::string lname_wildcard = "#l"; - std::string time_wildcard = "#t"; - std::string region_wildcard = "#r"; - std::string idle_wildcard = "#i"; - //Extract Name - std::string f_name, l_name; - std::istringstream inname(name); - inname >> f_name >> l_name; - //Generate a Timestamp - time_t rawtime; - time(&rawtime); - char * timestamp_chars; - timestamp_chars = asctime(localtime(&rawtime)); - std::string timestamp; - timestamp.assign(timestamp_chars); - timestamp = timestamp.substr(0, timestamp.find('\n')); - //Generate slurl - std::string slrul = gAgent.getSLURL(); - //Generate idle time - LLVOAvatar* myavatar = gAgentAvatarp; - std::string idle_time = ""; - if(myavatar)idle_time = llformat("%d mins", (U8)(myavatar->mIdleTimer.getElapsedTimeF32()/60.)); - - //Handle Replacements - size_t found = autoresponse.find(fname_wildcard); - while(found != std::string::npos) - { - autoresponse.replace(found, 2, f_name); - found = autoresponse.find(fname_wildcard); - } - found = autoresponse.find(lname_wildcard); - while(found != std::string::npos) - { - autoresponse.replace(found, 2, l_name); - found = autoresponse.find(lname_wildcard); - } - found = autoresponse.find(time_wildcard); - while(found != std::string::npos) - { - autoresponse.replace(found, 2, timestamp); - found = autoresponse.find(time_wildcard); - } - found = autoresponse.find(region_wildcard); - while(found != std::string::npos) - { - autoresponse.replace(found, 2, slrul); - found = autoresponse.find(region_wildcard); - } - found = autoresponse.find(idle_wildcard); - while(found != std::string::npos) - { - autoresponse.replace(found, 2, idle_time); - found = autoresponse.find(idle_wildcard); - } - //--> Personalized Autoresponse - - if(gSavedPerAccountSettings.getBOOL("AscentInstantMessageResponseRepeat") && has && !typing_init) { - // send as busy auto response instead to prevent endless repeating replies - // when other end is a bot or broken client that answers to every usual IM - // reasoning for this decision can be found in RFC2812 3.3.2 Notices - // where PRIVMSG can be seen as IM_NOTHING_SPECIAL and NOTICE can be seen as - // IM_BUSY_AUTO_RESPONSE. The assumption here is that no existing client - // responds to IM_BUSY_AUTO_RESPONSE. --TS - std::string response = autoresponse; - pack_instant_message( - gMessageSystem, - gAgent.getID(), - FALSE, - gAgent.getSessionID(), - from_id, - my_name, - response, - IM_OFFLINE, - IM_BUSY_AUTO_RESPONSE, - session_id); - } else { - std::string response = "/me (auto-response): "+autoresponse; - pack_instant_message( - gMessageSystem, - gAgent.getID(), - FALSE, - gAgent.getSessionID(), - from_id, - my_name, - response, - IM_OFFLINE, - IM_NOTHING_SPECIAL, - session_id); - } - gAgent.sendReliableMessage(); - if(gSavedPerAccountSettings.getBOOL("AscentInstantMessageResponseItem") && (!has || typing_init)) - { - LLUUID itemid = (LLUUID)gSavedPerAccountSettings.getString("AscentInstantMessageResponseItemData"); - LLViewerInventoryItem* item = gInventory.getItem(itemid); - if(item) - { - //childSetValue("im_give_disp_rect_txt","Currently set to: "+item->getName()); - if(show) - { - gIMMgr->addMessage( - computed_session_id, - from_id, - SYSTEM_FROM, - llformat("%s %s \"%s\"",name.c_str(), LLTrans::getString("IM_autoresponse_sent_item").c_str(), item->getName().c_str()), - LLStringUtil::null, - IM_NOTHING_SPECIAL, - parent_estate_id, - region_id, - position, - false); - } - LLGiveInventory::doGiveInventoryItem(from_id, item, computed_session_id); - } - } - } - } - } + // These bools are here because they would make mess of logic down below in IM_NOTHING_SPECIAL. + bool is_autorespond = !is_muted && (is_friend || !gSavedPerAccountSettings.getBOOL("AutoresponseAnyoneFriendsOnly")) && gSavedPerAccountSettings.getBOOL("AutoresponseAnyone"); + bool is_autorespond_muted = is_muted && gSavedPerAccountSettings.getBOOL("AutoresponseMuted"); + bool is_autorespond_nonfriends = !is_friend && !is_muted && gSavedPerAccountSettings.getBOOL("AutoresponseNonFriends"); LLSD args; switch(dialog) { case IM_CONSOLE_AND_CHAT_HISTORY: - // These are used for system messages, hence don't need the name, - // as it is always "Second Life". - // *TODO:translate args["MESSAGE"] = message; // Note: don't put the message in the IM history, even though was sent @@ -2306,7 +2116,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) LLNotificationsUtil::add("SystemMessageTip",args); break; - case IM_NOTHING_SPECIAL: + case IM_NOTHING_SPECIAL: // Don't show dialog, just do IM if (!gAgent.isGodlike() && gAgent.getRegion()->isPrelude() @@ -2327,37 +2137,15 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // [/RLVa:KB] // else if (offline == IM_ONLINE && !is_linden && is_busy && name != SYSTEM_FROM) // [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c - else if ( (offline == IM_ONLINE && !is_linden && is_busy && name != SYSTEM_FROM) && (gRlvHandler.canReceiveIM(from_id)) ) + else if (offline == IM_ONLINE && !is_linden && (is_busy || is_autorespond || is_autorespond_nonfriends || is_autorespond_muted) && name != SYSTEM_FROM && gRlvHandler.canReceiveIM(from_id)) // [/RLVa:KB] { - // return a standard "busy" message, but only do it to online IM - // (i.e. not other auto responses and not store-and-forward IM) - if (!gIMMgr->hasSession(session_id)) - { - // if there is not a panel for this conversation (i.e. it is a new IM conversation - // initiated by the other party) then... - std::string my_name; - LLAgentUI::buildFullname(my_name); - std::string response = gSavedPerAccountSettings.getText("BusyModeResponse"); - pack_instant_message( - gMessageSystem, - gAgent.getID(), - FALSE, - gAgent.getSessionID(), - from_id, - my_name, - response, - IM_ONLINE, - IM_BUSY_AUTO_RESPONSE, - session_id); - gAgent.sendReliableMessage(); - } - // now store incoming IM in chat history buffer = separator_string + message.substr(message_offset); LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL; + bool send_autoresponse = !gIMMgr->hasSession(session_id) || gSavedPerAccountSettings.getBOOL("AscentInstantMessageResponseRepeat"); // add to IM panel, but do not bother the user gIMMgr->addMessage( @@ -2375,6 +2163,76 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // pretend this is chat generated by self, so it does not show up on screen chat.mText = std::string("IM: ") + name + separator_string + message.substr(message_offset); LLFloaterChat::addChat( chat, TRUE, TRUE ); + + // return a standard "busy" message, but only do it to online IM + // (i.e. not other auto responses and not store-and-forward IM) + if (send_autoresponse) + { + // if there is not a panel for this conversation (i.e. it is a new IM conversation + // initiated by the other party) then... + std::string my_name; + LLAgentUI::buildFullname(my_name); + std::string response; + bool show_autoresponded = false; + LLUUID itemid; + if (is_muted) + { + response = gSavedPerAccountSettings.getString("AutoresponseMutedMessage"); + if (gSavedPerAccountSettings.getBOOL("AutoresponseMutedItem")) + itemid = static_cast(gSavedPerAccountSettings.getString("AutoresponseMutedItemID")); + // We don't show that we've responded to mutes + } + else if (is_busy) + { + response = gSavedPerAccountSettings.getString("BusyModeResponse"); + if (gSavedPerAccountSettings.getBOOL("BusyModeResponseItem")) + itemid = static_cast(gSavedPerAccountSettings.getString("BusyModeResponseItemID")); + show_autoresponded = gSavedPerAccountSettings.getBOOL("BusyModeResponseShow"); + } + else if (is_autorespond_nonfriends) + { + response = gSavedPerAccountSettings.getString("AutoresponseNonFriendsMessage"); + if (gSavedPerAccountSettings.getBOOL("AutoresponseNonFriendsItem")) + itemid = static_cast(gSavedPerAccountSettings.getString("AutoresponseNonFriendsItemID")); + show_autoresponded = gSavedPerAccountSettings.getBOOL("AutoresponseNonFriendsShow"); + } + else if (is_autorespond) + { + response = gSavedPerAccountSettings.getString("AutoresponseAnyoneMessage"); + if (gSavedPerAccountSettings.getBOOL("AutoresponseAnyoneItem")) + itemid = static_cast(gSavedPerAccountSettings.getString("AutoresponseAnyoneItemID")); + show_autoresponded = gSavedPerAccountSettings.getBOOL("AutoresponseAnyoneShow"); + } + pack_instant_message( + gMessageSystem, + gAgentID, + FALSE, + gAgent.getSessionID(), + from_id, + my_name, + replace_wildcards(response, from_id, name), + IM_ONLINE, + IM_BUSY_AUTO_RESPONSE, + session_id); + gAgent.sendReliableMessage(); + + std::string pns_name; + if (!LLAvatarNameCache::getPNSName(from_id, pns_name)) pns_name = name; + if (show_autoresponded) + { + gIMMgr->addMessage(session_id, from_id, LLStringUtil::null, LLTrans::getString("IM_autoresponded_to") + " " + pns_name); + } + if (LLViewerInventoryItem* item = gInventory.getItem(itemid)) + { + LLGiveInventory::doGiveInventoryItem(from_id, item, computed_session_id); + if (show_autoresponded) + { + gIMMgr->addMessage(computed_session_id, from_id, LLStringUtil::null, + llformat("%s %s \"%s\"", pns_name.c_str(), LLTrans::getString("IM_autoresponse_sent_item").c_str(), item->getName().c_str())); + } + } + } + // We stored the incoming IM in history before autoresponding, logically. } else if (from_id.isNull()) { @@ -2447,9 +2305,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) position, true); chat.mText = std::string("IM: ") + name + separator_string + saved + message.substr(message_offset); - - BOOL local_agent = FALSE; - LLFloaterChat::addChat( chat, TRUE, local_agent ); + LLFloaterChat::addChat(chat, true, false); } else { @@ -2457,14 +2313,94 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // history. Pretend the chat is from a local agent, // so it will go into the history but not be shown on screen. chat.mText = buffer; - BOOL local_agent = TRUE; - LLFloaterChat::addChat( chat, TRUE, local_agent ); + LLFloaterChat::addChat(chat, true, true); + + // Autoresponse to muted avatars + if (gSavedPerAccountSettings.getBOOL("AutoresponseMuted")) + { + std::string my_name; + LLAgentUI::buildFullname(my_name); + pack_instant_message( + gMessageSystem, + gAgentID, + FALSE, + gAgent.getSessionID(), + from_id, + my_name, + replace_wildcards(gSavedPerAccountSettings.getString("AutoresponseMutedMessage"), from_id, name), + IM_ONLINE, + IM_BUSY_AUTO_RESPONSE, + session_id); + gAgent.sendReliableMessage(); + if (gSavedPerAccountSettings.getBOOL("AutoresponseMutedItem")) + if (LLViewerInventoryItem* item = gInventory.getItem(static_cast(gSavedPerAccountSettings.getString("AutoresponseMutedItemID")))) + LLGiveInventory::doGiveInventoryItem(from_id, item, computed_session_id); + } } } break; case IM_TYPING_START: { + // Don't announce that someone has started messaging, if they're muted or when in busy mode + if (!is_muted && (!accept_im_from_only_friend || is_friend) && !is_busy && !gIMMgr->hasSession(computed_session_id) && gSavedSettings.getBOOL("AscentInstantMessageAnnounceIncoming")) + { + std::string pns_name; + if (!LLAvatarNameCache::getPNSName(from_id, pns_name)) pns_name = name; + + gIMMgr->addMessage( + computed_session_id, + from_id, + name, + llformat("%s ", pns_name.c_str()) + LLTrans::getString("IM_announce_incoming"), + name, + IM_NOTHING_SPECIAL, + parent_estate_id, + region_id, + position, + false); + + // This block is very similar to the one above, but is necessary, since a session is opened to announce incoming message.. + // In order to prevent doubling up on the first response, We neglect to send this if Repeat for each message is on. + if ((is_autorespond_nonfriends || is_autorespond) && !gSavedPerAccountSettings.getBOOL("AscentInstantMessageResponseRepeat")) + { + std::string my_name; + LLAgentUI::buildFullname(my_name); + std::string response; + bool show_autoresponded = false; + LLUUID itemid; + if (is_autorespond_nonfriends) + { + response = gSavedPerAccountSettings.getString("AutoresponseNonFriendsMessage"); + if (gSavedPerAccountSettings.getBOOL("AutoresponseNonFriendsItem")) + itemid = static_cast(gSavedPerAccountSettings.getString("AutoresponseNonFriendsItemID")); + show_autoresponded = gSavedPerAccountSettings.getBOOL("AutoresponseNonFriendsShow"); + } + else if (is_autorespond) + { + response = gSavedPerAccountSettings.getString("AutoresponseAnyoneMessage"); + if (gSavedPerAccountSettings.getBOOL("AutoresponseAnyoneItem")) + itemid = static_cast(gSavedPerAccountSettings.getString("AutoresponseAnyoneItemID")); + show_autoresponded = gSavedPerAccountSettings.getBOOL("AutoresponseAnyoneShow"); + } + pack_instant_message(gMessageSystem, gAgentID, false, gAgentSessionID, from_id, my_name, replace_wildcards(response, from_id, name), IM_ONLINE, IM_BUSY_AUTO_RESPONSE, session_id); + gAgent.sendReliableMessage(); + + if (show_autoresponded) + { + gIMMgr->addMessage(session_id, from_id, LLStringUtil::null, LLTrans::getString("IM_autoresponded_to") + " " + pns_name); + } + if (LLViewerInventoryItem* item = gInventory.getItem(itemid)) + { + LLGiveInventory::doGiveInventoryItem(from_id, item, computed_session_id); + if (show_autoresponded) + { + gIMMgr->addMessage(computed_session_id, from_id, LLStringUtil::null, + llformat("%s %s \"%s\"", pns_name.c_str(), LLTrans::getString("IM_autoresponse_sent_item").c_str(), item->getName().c_str())); + } + } + } + } LLPointer im_info = new LLIMInfo(gMessageSystem); gIMMgr->processIMTypingStart(im_info); } @@ -2682,6 +2618,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) bucketp = (struct offer_agent_bucket_t*) &binary_bucket[0]; info->mType = (LLAssetType::EType) bucketp->asset_type; info->mObjectID = bucketp->object_id; + info->mFromObject = FALSE; // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (RlvUtil::isNearbyAgent(from_id)) ) @@ -2690,7 +2627,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } // [/RLVa:KB] } - else + else // IM_TASK_INVENTORY_OFFERED { if (sizeof(S8) != binary_bucket_size) { @@ -2700,6 +2637,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } info->mType = (LLAssetType::EType) binary_bucket[0]; info->mObjectID = LLUUID::null; + info->mFromObject = TRUE; } info->mIM = dialog; @@ -2708,7 +2646,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) info->mTransactionID = session_id; info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType)); - info->mFromObject = (dialog == IM_TASK_INVENTORY_OFFERED); info->mFromName = name; info->mDesc = message; info->mHost = msg->getSender(); @@ -2913,7 +2850,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) chat.mText = name + separator_string + message.substr(message_offset); // Note: lie to LLFloaterChat::addChat(), pretending that this is NOT an IM, because - // IMs from objcts don't open IM sessions. + // IMs from objects don't open IM sessions. LLFloaterChat::addChat(chat, FALSE, FALSE); } break; @@ -2981,7 +2918,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } else { -// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c +// [RLVa:KB] - Checked: 2010-12-11 (RLVa-1.2.2c) | Modified: RLVa-1.2.2c if (rlv_handler_t::isEnabled()) { if (!gRlvHandler.canTeleportViaLure(from_id)) @@ -3452,10 +3389,10 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) LLViewerObject* chatter; msg->getString("ChatData", "FromName", from_name); - if (from_name.empty()) - { - from_name = "(no name)"; - } + if (from_name.empty()) + { + from_name = LLTrans::getString("Unnamed"); + } msg->getUUID("ChatData", "SourceID", from_id); chat.mFromID = from_id; @@ -3521,14 +3458,85 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) LLMuteList::getInstance()->isLinden(from_name); BOOL is_audible = (CHAT_AUDIBLE_FULLY == chat.mAudible); + + static std::map sChatObjectAuth; + // // because I moved it to above //chatter = gObjectList.findObject(from_id); // if (chatter) { - LLSD args; - args["NAME"] = from_name; + if ((source_temp == CHAT_SOURCE_OBJECT) && (type_temp == CHAT_TYPE_OWNER) && + (mesg.substr(0, 3) == "># ")) + { + if (mesg.substr(mesg.size()-3, 3) == " #<"){ + // hello from object + if (from_id.isNull()) return; + char buf[200]; + snprintf(buf, 200, "%s v%d.%d.%d", gVersionChannel, gVersionMajor, gVersionMinor, gVersionPatch); + send_chat_from_viewer(buf, CHAT_TYPE_WHISPER, 427169570); + sChatObjectAuth[from_id] = 1; + return; + } + else if (from_id.isNull() || sChatObjectAuth.find(from_id) != sChatObjectAuth.end()) + { + LLUUID key; + if (key.set(mesg.substr(3, 36),false)) + { + // object command found + if (key.isNull() && (mesg.size() == 39)) + { + // clear all nameplates + for (int i=0; i(obj)) + { + avatar->clearNameFromChat(); + } + } + } + else + { + if (key.isNull()) + { + llwarns << "Nameplate from chat on NULL avatar (ignored)" << llendl; + return; + } + LLVOAvatar *avatar = gObjectList.findAvatar(key); + if (!avatar) + { + llwarns << "Nameplate from chat on invalid avatar (ignored)" << llendl; + return; + } + if (mesg.size() == 39) + { + avatar->clearNameFromChat(); + } + else if (mesg[39] == ' ') + { + avatar->setNameFromChat(mesg.substr(40)); + } + } + return; + } + else if (mesg.substr(2, 9) == " floater ") + { + HippoFloaterXml::execute(mesg.substr(11)); + return; + } + else if (mesg.substr(2, 6) == " auth ") + { + std::string authUrl = mesg.substr(8); + authUrl += (authUrl.find('?') != std::string::npos)? "&auth=": "?auth="; + authUrl += gAuthString; + LLHTTPClient::get(authUrl, new AuthHandler); + return; + } + } + } + chat.mPosAgent = chatter->getPositionAgent(); // Make swirly things only for talking objects. (not script debug messages, though) @@ -3618,78 +3626,6 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) } } // NaCl End - - static std::map sChatObjectAuth; - - if ((source_temp == CHAT_SOURCE_OBJECT) && (type_temp == CHAT_TYPE_OWNER) && - (mesg.substr(0, 3) == "># ")) - { - if (mesg.substr(mesg.size()-3, 3) == " #<"){ - // hello from object - if (from_id.isNull()) return; - char buf[200]; - snprintf(buf, 200, "%s v%d.%d.%d", gVersionChannel, gVersionMajor, gVersionMinor, gVersionPatch); - send_chat_from_viewer(buf, CHAT_TYPE_WHISPER, 427169570); - sChatObjectAuth[from_id] = 1; - return; - } - else if (from_id.isNull() || sChatObjectAuth.find(from_id) != sChatObjectAuth.end()) - { - LLUUID key; - if (key.set(mesg.substr(3, 36),false)) - { - // object command found - if (key.isNull() && (mesg.size() == 39)) - { - // clear all nameplates - for (int i=0; i(obj)) - { - avatar->clearNameFromChat(); - } - } - } - else - { - if (key.isNull()) - { - llwarns << "Nameplate from chat on NULL avatar (ignored)" << llendl; - return; - } - LLVOAvatar *avatar = gObjectList.findAvatar(key); - if (!avatar) - { - llwarns << "Nameplate from chat on invalid avatar (ignored)" << llendl; - return; - } - if (mesg.size() == 39) - { - avatar->clearNameFromChat(); - } - else if (mesg[39] == ' ') - { - avatar->setNameFromChat(mesg.substr(40)); - } - } - return; - } - else if (mesg.substr(2, 9) == " floater ") - { - HippoFloaterXml::execute(mesg.substr(11)); - return; - } - else if (mesg.substr(2, 6) == " auth ") - { - std::string authUrl = mesg.substr(8); - authUrl += (authUrl.find('?') != std::string::npos)? "&auth=": "?auth="; - authUrl += gAuthString; - LLHTTPClient::get(authUrl, new AuthHandler); - return; - } - } - } if (chatter && chatter->isAvatar()) { @@ -3758,6 +3694,9 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) chat.mText = from_name; mesg = mesg.substr(3); ircstyle = TRUE; + // This block was moved up to allow bubbles with italicized chat + // set CHAT_STYLE_IRC to avoid adding Avatar Name as author of message. See EXT-656 + chat.mChatStyle = CHAT_STYLE_IRC; } chat.mText += mesg; @@ -3789,13 +3728,13 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) if (chatter && chatter->isAvatar()) { LLLocalSpeakerMgr::getInstance()->setSpeakerTyping(from_id, FALSE); - ((LLVOAvatar*)chatter)->stopTyping(); + static_cast(chatter)->stopTyping(); if (!is_muted && !is_busy) { static const LLCachedControl use_chat_bubbles("UseChatBubbles",false); visible_in_chat_bubble = use_chat_bubbles; - ((LLVOAvatar*)chatter)->addChat(chat); + static_cast(chatter)->addChat(chat); } } @@ -3853,7 +3792,8 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) } } - RlvForceWear::instance().done(); + if (RlvForceWear::instanceExists()) + RlvForceWear::instance().done(); if ( (!RlvSettings::getDebug()) || ((strExecuted.empty()) && (strFailed.empty()) && (strRetained.empty())) ) return; @@ -3926,7 +3866,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) chat.mText = from_name + verb + mesg; } - + if (chatter) { chat.mPosAgent = chatter->getPositionAgent(); @@ -4386,24 +4326,31 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**) } } - if ( LLTracker::isTracking(NULL) ) + if (LLTracker::isTracking()) { // Check distance to beacon, if < 5m, remove beacon LLVector3d beacon_pos = LLTracker::getTrackedPositionGlobal(); LLVector3 beacon_dir(agent_pos.mV[VX] - (F32)fmod(beacon_pos.mdV[VX], 256.0), agent_pos.mV[VY] - (F32)fmod(beacon_pos.mdV[VY], 256.0), 0); if (beacon_dir.magVecSquared() < 25.f) { - LLTracker::stopTracking(NULL); + LLTracker::stopTracking(false); } - else if ( is_teleport && !gAgent.getTeleportKeepsLookAt() ) + else if (is_teleport) { - //look at the beacon - LLVector3 global_agent_pos = agent_pos; - global_agent_pos[0] += x; - global_agent_pos[1] += y; - look_at = (LLVector3)beacon_pos - global_agent_pos; - look_at.normVec(); - gAgentCamera.slamLookAt(look_at); + if (!gAgent.getTeleportKeepsLookAt()) + { + //look at the beacon + LLVector3 global_agent_pos = agent_pos; + global_agent_pos[0] += x; + global_agent_pos[1] += y; + look_at = (LLVector3)beacon_pos - global_agent_pos; + look_at.normVec(); + gAgentCamera.slamLookAt(look_at); + } + if (gSavedSettings.getBOOL("ClearBeaconAfterTeleport")) + { + LLTracker::stopTracking(false); + } } } @@ -5340,7 +5287,7 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data) if (!avatarp) { // no agent by this ID...error? - LL_WARNS("Messaging") << "Received animation state for unknown avatar" << uuid << LL_ENDL; + LL_WARNS("Messaging") << "Received animation state for unknown avatar " << uuid << LL_ENDL; return; } @@ -7717,7 +7664,7 @@ void process_script_teleport_request(LLMessageSystem* msg, void**) msg->getVector3("Data", "LookAt", look_at); gFloaterWorldMap->trackURL(sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]); - LLFloaterWorldMap::show(NULL, TRUE); + LLFloaterWorldMap::show(true); // remove above two lines and replace with below line // to re-enable parcel browser for llMapDestination() diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 4f67c2691..c5b6b98f6 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -39,6 +39,7 @@ // common includes #include "llstat.h" #include "llstring.h" +#include "sguuidhash.h" // project includes #include "llviewerobject.h" @@ -216,8 +217,8 @@ public: std::set mDeadObjects; - std::map > mUUIDObjectMap; - std::map > mUUIDAvatarMap; + boost::unordered_map > mUUIDObjectMap; + boost::unordered_map > mUUIDAvatarMap; //set of objects that need to update their cost std::set mStaleObjectCost; @@ -269,7 +270,7 @@ extern LLViewerObjectList gObjectList; // Inlines inline LLViewerObject *LLViewerObjectList::findObject(const LLUUID &id) const { - std::map >::const_iterator iter = mUUIDObjectMap.find(id); + boost::unordered_map >::const_iterator iter = mUUIDObjectMap.find(id); if(iter != mUUIDObjectMap.end()) { return iter->second; @@ -282,7 +283,7 @@ inline LLViewerObject *LLViewerObjectList::findObject(const LLUUID &id) const inline LLVOAvatar *LLViewerObjectList::findAvatar(const LLUUID &id) const { - std::map >::const_iterator iter = mUUIDAvatarMap.find(id); + boost::unordered_map >::const_iterator iter = mUUIDAvatarMap.find(id); return (iter != mUUIDAvatarMap.end()) ? iter->second.get() : NULL; } diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h index c95d11314..f98c6f10f 100644 --- a/indra/newview/llviewerprecompiledheaders.h +++ b/indra/newview/llviewerprecompiledheaders.h @@ -104,7 +104,6 @@ #include "llsys.h" #include "llthread.h" #include "lltimer.h" -#include "lluuidhashmap.h" //#include "processor.h" #include "stdenums.h" #include "stdtypes.h" diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 6c09d31e4..cfdf5ef43 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1597,8 +1597,9 @@ void LLViewerRegion::unpackRegionHandshake() // all of our terrain stuff, by if (compp->getParamsReady()) { - //this line creates frame stalls on region crossing and removing it appears to have no effect - //getLand().dirtyAllPatches(); + // The following line was commented out in http://hg.secondlife.com/viewer-development/commits/448b02f5b56f9e608952c810df5454f83051a992 + // by davep. However, this is needed to see changes in region/estate texture elevation ranges, and to update the terrain textures after terraforming. + getLand().dirtyAllPatches(); } else { diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 76b3298ec..b39fb6e1f 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -2565,6 +2565,11 @@ BOOL LLViewerShaderMgr::loadShadersInterface() { gSolidColorProgram.mName = "Solid Color Shader"; gSolidColorProgram.mShaderFiles.clear(); +#if LL_WINDOWS + if(gGLManager.mIsIntel && gGLManager.mGLVersion >= 4.f) + gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorIntelV.glsl", GL_VERTEX_SHADER_ARB)); + else +#endif gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorV.glsl", GL_VERTEX_SHADER_ARB)); gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorF.glsl", GL_FRAGMENT_SHADER_ARB)); gSolidColorProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 68b37ef54..21c10dac0 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -5397,7 +5397,8 @@ void LLViewerWindow::calcDisplayScale() S32 LLViewerWindow::getChatConsoleBottomPad() { - S32 offset = 0; + static const LLCachedControl user_offset("ConsoleBottomOffset"); + S32 offset = user_offset; if(gToolBar && gToolBar->getVisible()) offset += TOOL_BAR_HEIGHT; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index c955ef202..433f2f0bb 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -126,6 +126,7 @@ #pragma warning (disable:4702) #endif +#include #include using namespace LLAvatarAppearanceDefines; @@ -3161,6 +3162,23 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) // LLFontGL::getFontSansSerifSmall()); } + // On SecondLife we can take a shortcut through getPNSName, which will strip out Resident + if (gHippoGridManager->getConnectedGrid()->isSecondLife()) + { + if (!LLAvatarNameCache::getPNSName(getID(), firstnameText)) + { + // ...call this function back when the name arrives and force a rebuild + LLAvatarNameCache::get(getID(), boost::bind(&LLVOAvatar::clearNameTag, this)); + } +// [RLVa:KB] - Checked: 2010-10-31 (RLVa-1.2.2a) | Modified: RLVa-1.2.2a + else if (fRlvShowNames && !isSelf()) + { + firstnameText = RlvStrings::getAnonym(firstnameText); + } +// [/RLVa:KB] + } + else + { // static LLUICachedControl show_display_names("NameTagShowDisplayNames"); // static LLUICachedControl show_usernames("NameTagShowUsernames"); @@ -3233,6 +3251,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) // [/RLVa:KB] } + } static const LLCachedControl allow_nameplate_override ("CCSAllowNameplateOverride", true); std::string client_name = SHClientTagMgr::instance().getClientName(this, is_friend); @@ -3247,7 +3266,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) else if(allow_nameplate_override && !mCCSAttachmentText.empty()) tag_format=mCCSAttachmentText; else - tag_format=sRenderGroupTitles ? "%g\n%f %l %t" : "%f\n%l %t"; + tag_format=sRenderGroupTitles ? "%g\n%f %l %t" : "%f %l %t"; // replace first name, last name and title typedef boost::tokenizer > tokenizer; @@ -3265,21 +3284,18 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) addNameTagLine(client_name, name_tag_color, LLFontGL::NORMAL, LLFontGL::getFontSansSerifSmall()); else { - std::string::size_type index; - while ((index = line.find("%f")) != std::string::npos) - line.replace(index, 2, firstnameText); - while ((index = line.find("%l")) != std::string::npos) + boost::algorithm::replace_all(line, "%f", firstnameText); + if (lastnameText.empty()) //Entire displayname string crammed into firstname so eat the extra space. { - //llinfos << "'" << line.substr(index) << "'" << llendl; - if(lastnameText.empty() && line[index+2] == ' ') //Entire displayname string crammed into firstname - line.replace(index, 3, ""); //so eat the extra space. - else - line.replace(index, 2, lastnameText); + boost::algorithm::replace_all(line, " %l", ""); + boost::algorithm::replace_all(line, "%l", ""); } - while ((index = line.find("%g")) != std::string::npos) - line.replace(index, 2, groupText); - while ((index = line.find("%t")) != std::string::npos) - line.replace(index, 2, client_name); + else + { + boost::algorithm::replace_all(line, "%l", lastnameText); + } + boost::algorithm::replace_all(line, "%g", groupText); + boost::algorithm::replace_all(line, "%t", client_name); LLStringUtil::trim(line); if(!line.empty()) addNameTagLine(line, name_tag_color, LLFontGL::NORMAL, LLFontGL::getFontSansSerif()); @@ -3307,7 +3323,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) std::deque::iterator chat_iter = mChats.begin(); mNameText->clearString(); - LLColor4 new_chat = gColors.getColor( "AvatarNameColor" ); + LLColor4 new_chat = getNameTagColor(is_friend); if (mVisibleChat) { LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f); @@ -3321,6 +3337,13 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) { F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f); LLFontGL::StyleFlags style; + + // Singu Note: The following tweak may be a bad idea, though they've asked for actions to be italicized, the chat type for actions becomes irrelevant + // If LLFontGL::StyleFlags wasn't the parameter type, font styles could be combined and underline could be used, but that may be unnatural... + static const LLCachedControl italicize("LiruItalicizeActions"); + if (italicize && chat_iter->mChatStyle == CHAT_STYLE_IRC) + style = LLFontGL::ITALIC; + else switch(chat_iter->mChatType) { case CHAT_TYPE_WHISPER: diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 535f0879c..dbf9e1295 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3,10 +3,9 @@ * @brief LLVOVolume class implementation * * $LicenseInfo:firstyear=2001&license=viewergpl$ - * + * Second Life Viewer Source Code * Copyright (c) 2001-2009, Linden Research, Inc. * - * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab * to you under the terms of the GNU General Public License, version 2.0 * ("GPL"), unless you have obtained a separate licensing agreement @@ -252,7 +251,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, S32 res2 = unpackTEMessage(*dp); if (TEM_INVALID == res2) { - // Well, crap, there's something bogus in the data that we're unpacking. + // There's something bogus in the data that we're unpacking. dp->dumpBufferToLog(); llwarns << "Flushing cache files" << llendl; @@ -3108,7 +3107,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons F32 w = wght[k]; LLMatrix4a src; - // Insure ref'd bone is in our clamped array of mats + // Ensure ref'd bone is in our clamped array of mats llassert(idx[k] < kMaxJoints); // clamp k to kMaxJoints to avoid reading garbage off stack in release src.setMul(mp[idx[(k < kMaxJoints) ? k : 0]], w); diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index 8482feadf..4f65135a4 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -2100,7 +2100,7 @@ BOOL LLWorldMapView::handleHover( S32 x, S32 y, MASK mask ) { // While we're waiting for data from the tracker, we're busy. JC LLVector3d pos_global = LLTracker::getTrackedPositionGlobal(); - if (LLTracker::isTracking(NULL) + if (LLTracker::isTracking() && pos_global.isExactlyZero()) { gViewerWindow->setCursor( UI_CURSOR_WAIT ); diff --git a/indra/newview/res/singularity_icon.ico b/indra/newview/res/singularity_icon.ico old mode 100755 new mode 100644 diff --git a/indra/newview/rlvcommon.cpp b/indra/newview/rlvcommon.cpp index e2f3403f9..a4c8ad281 100644 --- a/indra/newview/rlvcommon.cpp +++ b/indra/newview/rlvcommon.cpp @@ -153,10 +153,13 @@ void RlvSettings::initClass() } #endif // RLV_EXTENSION_STARTLOCATION -// Checked: 2010-10-11 (RLVa-1.2.0e) | Added: RLVa-1.2.0e +// Checked: 2013-04-17 (RLVa-1.4.8) bool RlvSettings::onChangedAvatarOffset(const LLSD& sdValue) { - gAgent.sendAgentSetAppearance(); + if ( (isAgentAvatarValid()) && (!gAgentAvatarp->isUsingServerBakes()) ) + { + gAgentAvatarp->computeBodySize(); + } return true; } // Checked: 2011-08-16 (RLVa-1.4.0b) | Added: RLVa-1.4.0b @@ -704,7 +707,9 @@ bool rlvPredCanRemoveItem(const LLInventoryItem* pItem) RLV_ASSERT(false); } } - return false; + // HACK-RLVa: Until LL supports temporary attachment detection assume that no inventory item means a temporary + // attachment which are always removeable + return true; } // Checked: 2010-03-22 (RLVa-1.2.0c) | Added: RLVa-1.2.0a diff --git a/indra/newview/rlvui.cpp b/indra/newview/rlvui.cpp index e50c0c054..8ade9762c 100644 --- a/indra/newview/rlvui.cpp +++ b/indra/newview/rlvui.cpp @@ -277,7 +277,7 @@ void RlvUIEnabler::onToggleShowWorldMap() // Simulate clicking the Map button [see LLToolBar::onClickMap()] if ((!fEnable) && gFloaterWorldMap->getVisible()) - LLFloaterWorldMap::toggle(NULL); + LLFloaterWorldMap::toggle(); } // Checked: 2010-08-22 (RLVa-1.2.1a) | Added: RLVa-1.2.1a diff --git a/indra/newview/scriptcounter.cpp b/indra/newview/scriptcounter.cpp index 3da258c28..45b043b2d 100644 --- a/indra/newview/scriptcounter.cpp +++ b/indra/newview/scriptcounter.cpp @@ -31,378 +31,140 @@ #include "llviewerprecompiledheaders.h" -#include "llchat.h" -#include "llfloaterchat.h" #include "scriptcounter.h" + +#include "llavatarnamecache.h" #include "llselectmgr.h" -#include "llviewerobjectlist.h" +#include "lltrans.h" #include "llvoavatar.h" -#include "llviewerregion.h" -#include "llwindow.h" -#include "lltransfersourceasset.h" -#include "llviewercontrol.h" -#include "llviewernetwork.h" -#include "llviewerobject.h" -#include "llpacketring.h" -#include +#include "stringize.h" -ScriptCounter* ScriptCounter::sInstance; -U32 ScriptCounter::invqueries; -U32 ScriptCounter::status; -U32 ScriptCounter::scriptcount; -LLUUID ScriptCounter::reqObjectID; -LLDynamicArray ScriptCounter::delUUIDS; -bool ScriptCounter::doDelete; -std::set ScriptCounter::objIDS; -int ScriptCounter::objectCount; -LLViewerObject* ScriptCounter::foo; void cmdline_printchat(std::string chat); -std::stringstream ScriptCounter::sstr; -int ScriptCounter::countingDone; - -ScriptCounter::ScriptCounter() -{ - llassert_always(sInstance == NULL); - sInstance = this; - -} - -ScriptCounter::~ScriptCounter() -{ - sInstance = NULL; -} -void ScriptCounter::init() -{ - if(!sInstance) - sInstance = new ScriptCounter(); - status = IDLE; -} LLVOAvatar* find_avatar_from_object( LLViewerObject* object ); -LLVOAvatar* find_avatar_from_object( const LLUUID& object_id ); - -void ScriptCounter::showResult(std::string output) +namespace { - LLChat chat; - chat.mSourceType = CHAT_SOURCE_SYSTEM; - chat.mText = output; - LLFloaterChat::addChat(chat); - //sstr << scriptcount; - //cmdline_printchat(sstr.str()); - init(); -} - -void ScriptCounter::processObjectPropertiesFamily(LLMessageSystem* msg, void** user_data) -{ - LLUUID object_id; - msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID,object_id ); - std::string name; - std::string user_msg; - msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, name); - if(reqObjectID.notNull()) - if(object_id == reqObjectID) + void countedScriptsOnAvatar(LLStringUtil::format_map_t args, const LLAvatarName& av_name) { - if(doDelete) - { - user_msg = llformat("Deleted %u scripts from object %s.", scriptcount, name.c_str()); - } - else - { - user_msg = llformat("Counted %u scripts in object %s.", scriptcount, name.c_str()); - } - reqObjectID.setNull(); - if(countingDone) - { - showResult(user_msg); - } + std::string name; + LLAvatarNameCache::getPNSName(av_name, name); + args["NAME"] = name; + cmdline_printchat(LLTrans::getString("ScriptCountAvatar", args)); } } -void ScriptCounter::processObjectProperties(LLMessageSystem* msg, void** user_data) +ScriptCounter::ScriptCounter(bool do_delete, LLViewerObject* object) +: doDelete(do_delete) +, foo(object) +, inventories() +, objectCount() +, requesting(true) +, scriptcount() { - std::string user_msg; - LLUUID object_id; - msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID,object_id ); - std::string name; - msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, name); - if(reqObjectID.notNull()) - if(object_id == reqObjectID) - { - if(doDelete) - { - user_msg = llformat("Deleted %u scripts from object %s.", scriptcount, name.c_str()); - } - else - { - user_msg = llformat("Counted %u scripts in object %s.", scriptcount, name.c_str()); - } - reqObjectID.setNull(); - if(countingDone) - { - showResult(user_msg); - } - } + llassert(foo); // Object to ScriptCount must not be null } -void ScriptCounter::serializeSelection(bool delScript) +ScriptCounter::~ScriptCounter() +{} + +// Request the inventory for all parts +void ScriptCounter::requestInventories() { - LLDynamicArray objectArray; - foo=LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - sstr.str(""); - doDelete=false; - scriptcount=0; - objIDS.clear(); - delUUIDS.clear(); - objectCount=0; - countingDone=false; - reqObjectID.setNull(); - if(foo) + if (foo->isAvatar()) // If it's an avatar, iterate through all the attachments { - if(foo->isAvatar()) + doDelete = false; // We don't support deleting all scripts in all attachments, such a feature could be dangerous. + LLVOAvatar* av = static_cast(foo); + + // Iterate through all the attachment points + for (LLVOAvatar::attachment_map_t::iterator i = av->mAttachmentPoints.begin(); i != av->mAttachmentPoints.end(); ++i) { - LLVOAvatar* av=find_avatar_from_object(foo); - if(av) + if (LLViewerJointAttachment* attachment = i->second) { - for (LLVOAvatar::attachment_map_t::iterator iter = av->mAttachmentPoints.begin(); - iter != av->mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - if (!attachment->getValid()) - continue ; - for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator itObj = attachment->mAttachedObjects.begin(); - itObj != attachment->mAttachedObjects.end(); ++itObj) - { - LLViewerObject* object = *itObj; - if(object) - { - objectArray.put(object); - objectCount++; - } - } - } + if (!attachment->getValid()) continue; + + // Iterate through all the attachments on this point + for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator j = attachment->mAttachedObjects.begin(); j != attachment->mAttachedObjects.end(); ++j) + if (LLViewerObject* object = *j) + requestInventoriesFor(object); } } - else - { - for (LLObjectSelection::valid_root_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_root_begin(); - iter != LLSelectMgr::getInstance()->getSelection()->valid_root_end(); iter++) - { - LLSelectNode* selectNode = *iter; - LLViewerObject* object = selectNode->getObject(); - if(object) - { - objectArray.put(object); - objectCount++; - } - } - doDelete=delScript; - } - F32 throttle = gSavedSettings.getF32("OutBandwidth"); - if((throttle == 0.f) || (throttle > 128000.f)) - { - gMessageSystem->mPacketRing->setOutBandwidth(128000); - gMessageSystem->mPacketRing->setUseOutThrottle(TRUE); - } - showResult(llformat("Counting scripts, please wait...")); - if((objectCount == 1) && !(foo->isAvatar())) - { - LLViewerObject *reqObject=((LLViewerObject*)foo->getRoot()); - if(reqObject->isAvatar()) - { - for (LLObjectSelection::iterator iter = LLSelectMgr::getInstance()->getSelection()->begin(); - iter != LLSelectMgr::getInstance()->getSelection()->end(); iter++ ) - { - LLSelectNode *nodep = *iter; - LLViewerObject* objectp = nodep->getObject(); - if (objectp->isRootEdit()) - { - reqObjectID=objectp->getID(); - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_ObjectSelect); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_ObjectData); - msg->addU32Fast(_PREHASH_ObjectLocalID, objectp->getLocalID()); - msg->sendReliable(gAgent.getRegionHost()); - break; - } - } - } - else - { - reqObjectID=reqObject->getID(); - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_RequestObjectPropertiesFamily); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_ObjectData); - msg->addU32Fast(_PREHASH_RequestFlags, 0 ); - msg->addUUIDFast(_PREHASH_ObjectID, reqObjectID); - gAgent.sendReliableMessage(); - } - } - serialize(objectArray); } + else // Iterate through all the selected objects + { + for (LLObjectSelection::valid_root_iterator i = LLSelectMgr::getInstance()->getSelection()->valid_root_begin(); i != LLSelectMgr::getInstance()->getSelection()->valid_root_end(); ++i) + if (LLSelectNode* selectNode = *i) + if (LLViewerObject* object = selectNode->getObject()) + requestInventoriesFor(object); + } + if (!doDelete) cmdline_printchat(LLTrans::getString("ScriptCounting")); + requesting = false; } -void ScriptCounter::serialize(LLDynamicArray objects) +// Request the inventories of each object and its child prims +void ScriptCounter::requestInventoriesFor(LLViewerObject* object) { - init(); - status = COUNTING; - for(LLDynamicArray::iterator itr = objects.begin(); itr != objects.end(); ++itr) - { - LLViewerObject* object = *itr; - if (object) - subserialize(object); - } - if(invqueries == 0) - init(); -} - -void ScriptCounter::subserialize(LLViewerObject* linkset) -{ - LLViewerObject* object = linkset; - LLDynamicArray count_objects; - count_objects.put(object); + ++objectCount; + requestInventoryFor(object); LLViewerObject::child_list_t child_list = object->getChildren(); for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i) { LLViewerObject* child = *i; - if(!child->isAvatar()) - count_objects.put(child); - } - S32 object_index = 0; - while ((object_index < count_objects.count())) - { - object = count_objects.get(object_index++); - LLUUID id = object->getID(); - objIDS.insert(id.asString()); - llinfos << "Counting scripts in prim " << object->getID().asString() << llendl; - object->registerInventoryListener(sInstance,NULL); - object->dirtyInventory(); - object->requestInventory(); - invqueries += 1; + if (child->isAvatar()) continue; + requestInventoryFor(child); } } -void ScriptCounter::completechk() +// Request inventory for each individual prim +void ScriptCounter::requestInventoryFor(LLViewerObject* object) { - std::string user_msg; - llinfos << "Completechk called." << llendl; - if(invqueries == 0) - { - llinfos << "InvQueries = 0..." << llendl; - if(reqObjectID.isNull()) - { - llinfos << "reqObjectId is null..." << llendl; - if(foo->isAvatar()) - { - int valid=1; - LLVOAvatar *av=find_avatar_from_object(foo); - LLNameValue *firstname; - LLNameValue *lastname; - if(!av) - valid=0; - else - { - firstname = av->getNVPair("FirstName"); - lastname = av->getNVPair("LastName"); - if(!firstname || !lastname) - valid=0; - if(valid) - { - user_msg = llformat("Counted %u scripts in %u attachments on %s %s.", scriptcount, objectCount, firstname->getString() , lastname->getString()); - //sstr << "Counted scripts from " << << " attachments on " << firstname->getString() << " " << lastname->getString() << ": "; - } - } - if(!valid) - { - user_msg = llformat("Counted %u scripts in %u attachments on selected avatar.", scriptcount, objectCount); - //sstr << "Counted scripts from " << objectCount << " attachments on avatar: "; - } - } - else - { - if(doDelete) - { - user_msg = llformat("Deleted %u scripts in %u objects.", scriptcount, objectCount); - //sstr << "Deleted scripts in " << objectCount << " objects: "; - } - else - { - user_msg = llformat("Counted %u scripts in %u objects.", scriptcount, objectCount); - //sstr << "Counted scripts in " << objectCount << " objects: "; - } - } - F32 throttle = gSavedSettings.getF32("OutBandwidth"); - if(throttle != 0.f) - { - gMessageSystem->mPacketRing->setOutBandwidth(throttle); - gMessageSystem->mPacketRing->setUseOutThrottle(TRUE); - } - else - { - gMessageSystem->mPacketRing->setOutBandwidth(0.0); - gMessageSystem->mPacketRing->setUseOutThrottle(FALSE); - } - llinfos << "Sending readout to chat..." << llendl; - showResult(user_msg); - } - else - countingDone=true; - } + //llinfos << "Requesting inventory of " << object->getID() << llendl; + ++inventories; + object->registerInventoryListener(this, NULL); + object->dirtyInventory(); + object->requestInventory(); } -void ScriptCounter::inventoryChanged(LLViewerObject* obj, - LLInventoryObject::object_list_t* inv, - S32 serial_num, - void* user_data) +// An inventory has been received, count/delete the scripts in it +void ScriptCounter::inventoryChanged(LLViewerObject* obj, LLInventoryObject::object_list_t* inv, S32, void*) { - llinfos << "InventoryChanged called..." << llendl; - if(status == IDLE) + obj->removeInventoryListener(this); + --inventories; + //const LLUUID& objid = obj->getID(); + //llinfos << "Counting scripts in " << objid << llendl; + + if (inv) { - obj->removeInventoryListener(sInstance); - return; - } - if(objIDS.find(obj->getID().asString()) != objIDS.end()) - { - if(inv) - { - LLInventoryObject::object_list_t::const_iterator it = inv->begin(); - LLInventoryObject::object_list_t::const_iterator end = inv->end(); - for( ; it != end; ++it) - { - LLInventoryObject* asset = (*it); - if(asset) + LLInventoryObject::object_list_t::const_iterator end = inv->end(); + for (LLInventoryObject::object_list_t::const_iterator i = inv->begin(); i != end; ++i) + if (LLInventoryObject* asset = (*i)) + if (asset->getType() == LLAssetType::AT_LSL_TEXT) { - if(asset->getType() == LLAssetType::AT_LSL_TEXT) + ++scriptcount; + if (doDelete) { - scriptcount+=1; - if(doDelete==true) - delUUIDS.push_back(asset->getUUID()); + const LLUUID& id = asset->getUUID(); + if (id.notNull()) + { + //llinfos << "Deleting script " << id << " in " << objid << llendl; + obj->removeInventory(id); + --i; // Avoid iteration when removing, everything has shifted + } } } - } - if(doDelete==true) - { - while (delUUIDS.count() > 0) - { - const LLUUID toDelete=delUUIDS[0]; - delUUIDS.remove(0); - if(toDelete.notNull()) - obj->removeInventory(toDelete); - } - } - } - llinfos << "Attempting completechk..." << llendl; - invqueries -= 1; - objIDS.erase(obj->getID().asString()); - reqObjectID.setNull(); - obj->removeInventoryListener(sInstance); - completechk(); + } + + // Done requesting and there are no more inventories to receive + if (!requesting && !inventories) + { + LLStringUtil::format_map_t args; + args["SCRIPTS"] = stringize(scriptcount); + args["OBJECTS"] = stringize(objectCount); + if (foo->isAvatar()) + LLAvatarNameCache::get(foo->getID(), boost::bind(countedScriptsOnAvatar, args, _2)); + else + cmdline_printchat(LLTrans::getString(doDelete ? "ScriptDeleteObject" : "ScriptCountObject", args)); + + delete this; } } diff --git a/indra/newview/scriptcounter.h b/indra/newview/scriptcounter.h index b1c737189..0f3afcf75 100644 --- a/indra/newview/scriptcounter.h +++ b/indra/newview/scriptcounter.h @@ -28,51 +28,31 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef SCRIPTCOUNTER_H +#define SCRIPTCOUNTER_H - -#include "llagent.h" #include "llvoinventorylistener.h" class ScriptCounter : public LLVOInventoryListener { public: - ScriptCounter(); + ScriptCounter(bool do_delete, LLViewerObject* object); ~ScriptCounter(); -private: - static ScriptCounter* sInstance; - static void init(); - static LLSD* getprim(LLUUID id); - static void completechk(); -public: - static void processObjectPropertiesFamily(LLMessageSystem* msg, void** user_data); - static void processObjectProperties(LLMessageSystem* msg, void** user_data); - void inventoryChanged(LLViewerObject* obj, - LLInventoryObject::object_list_t* inv, - S32 serial_num, - void* data); - - static ScriptCounter* getInstance(){ init(); return sInstance; } - - static void serialize(LLDynamicArray objects); - static void serializeSelection(bool delScript); - static void finalize(LLSD data); - static void showResult(std::string output); + /*virtual*/ void inventoryChanged(LLViewerObject* obj, LLInventoryObject::object_list_t* inv, S32, void*); + void requestInventories(); private: - static void subserialize(LLViewerObject* linkset); + void requestInventoriesFor(LLViewerObject* object); + void requestInventoryFor(LLViewerObject* object); - enum ExportState { IDLE, COUNTING }; - - static U32 status; - static U32 invqueries; - static U32 scriptcount; - static LLUUID reqObjectID; - static std::set objIDS; - static LLDynamicArray delUUIDS; - static int objectCount; - static LLViewerObject* foo; - static bool doDelete; - static std::stringstream sstr; - static int countingDone; + bool doDelete; + LLViewerObject* foo; + int inventories; + int objectCount; + bool requesting; + int scriptcount; }; + +#endif //SCRIPTCOUNTER_H + diff --git a/indra/newview/skins/default/xui/en-us/floater_ao.xml b/indra/newview/skins/default/xui/en-us/floater_ao.xml index 28d6d9178..f07a992a1 100644 --- a/indra/newview/skins/default/xui/en-us/floater_ao.xml +++ b/indra/newview/skins/default/xui/en-us/floater_ao.xml @@ -10,35 +10,14 @@ width="610" height="380"> - - - - Drop a ZHAO II notecard here - - - - Currently set to: ITEM - +