Merge branch 'master' into UICleanup
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -24,3 +24,5 @@
|
||||
/edited-files.txt
|
||||
qtcreator-build/
|
||||
/.pc
|
||||
/build-*
|
||||
/viewer-*
|
||||
|
||||
@@ -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<AIStateMachine> 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())
|
||||
|
||||
@@ -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<AIStateMachine> 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); }
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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.")
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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})
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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})
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "sys.h"
|
||||
#include "llpathinglib.h"
|
||||
|
||||
void LLPathingLib::initSystem()
|
||||
|
||||
@@ -3,37 +3,10 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include <map>
|
||||
#include <deque>
|
||||
|
||||
#include "lluuidhashmap.h"
|
||||
#include "llmotion.h"
|
||||
#include "llpose.h"
|
||||
#include "llframetimer.h"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -178,7 +178,7 @@ struct CopyNewPointer
|
||||
// helper function which returns true if key is in inmap.
|
||||
template <typename T>
|
||||
//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 <typename T>
|
||||
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 <typename T>
|
||||
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 <typename T>
|
||||
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())
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<uuid_pair, 32> foo(test_equals);
|
||||
LLUUIDHashMapIter<uuid_pair, 32> bar(&foo);
|
||||
|
||||
LLDynamicArray<LLUUID> 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 DATA, int SIZE>
|
||||
class LLUUIDHashNode
|
||||
{
|
||||
public:
|
||||
LLUUIDHashNode();
|
||||
|
||||
public:
|
||||
S32 mCount;
|
||||
U8 mKey[SIZE];
|
||||
DATA mData[SIZE];
|
||||
LLUUIDHashNode<DATA, SIZE> *mNextNodep;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// LLUUIDHashNode implementation
|
||||
//
|
||||
template <class DATA, int SIZE>
|
||||
LLUUIDHashNode<DATA, SIZE>::LLUUIDHashNode()
|
||||
{
|
||||
mCount = 0;
|
||||
mNextNodep = NULL;
|
||||
}
|
||||
|
||||
|
||||
template <class DATA_TYPE, int SIZE>
|
||||
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<DATA_TYPE, SIZE> mNodes[256];
|
||||
|
||||
S32 mIterCount;
|
||||
protected:
|
||||
DATA_TYPE mNull;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// LLUUIDHashMap implementation
|
||||
//
|
||||
|
||||
template <class DATA_TYPE, int SIZE>
|
||||
LLUUIDHashMap<DATA_TYPE, SIZE>::LLUUIDHashMap(BOOL (*equals)(const LLUUID &uuid, const DATA_TYPE &data),
|
||||
const DATA_TYPE &null_data)
|
||||
: mEquals(equals),
|
||||
mIterCount(0),
|
||||
mNull(null_data)
|
||||
{ }
|
||||
|
||||
template <class DATA_TYPE, int SIZE>
|
||||
LLUUIDHashMap<DATA_TYPE, SIZE>::~LLUUIDHashMap()
|
||||
{
|
||||
removeAll();
|
||||
}
|
||||
|
||||
template <class DATA_TYPE, int SIZE>
|
||||
void LLUUIDHashMap<DATA_TYPE, SIZE>::removeAll()
|
||||
{
|
||||
S32 bin;
|
||||
for (bin = 0; bin < 256; bin++)
|
||||
{
|
||||
LLUUIDHashNode<DATA_TYPE, SIZE>* 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<DATA_TYPE, SIZE>* 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 <class DATA_TYPE, int SIZE>
|
||||
inline S32 LLUUIDHashMap<DATA_TYPE, SIZE>::getLength() const
|
||||
{
|
||||
S32 count = 0;
|
||||
S32 bin;
|
||||
for (bin = 0; bin < 256; bin++)
|
||||
{
|
||||
LLUUIDHashNode<DATA_TYPE, SIZE>* nodep = (LLUUIDHashNode<DATA_TYPE, SIZE>*) &mNodes[bin];
|
||||
while (nodep)
|
||||
{
|
||||
count += nodep->mCount;
|
||||
nodep = nodep->mNextNodep;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
template <class DATA_TYPE, int SIZE>
|
||||
inline DATA_TYPE &LLUUIDHashMap<DATA_TYPE, SIZE>::get(const LLUUID &uuid)
|
||||
{
|
||||
LLUUIDHashNode<DATA_TYPE, SIZE>* 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 <class DATA_TYPE, int SIZE>
|
||||
inline BOOL LLUUIDHashMap<DATA_TYPE, SIZE>::check(const LLUUID &uuid) const
|
||||
{
|
||||
const LLUUIDHashNode<DATA_TYPE, SIZE>* 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 <class DATA_TYPE, int SIZE>
|
||||
inline DATA_TYPE &LLUUIDHashMap<DATA_TYPE, SIZE>::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<DATA_TYPE, SIZE>* 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<DATA_TYPE, SIZE>;
|
||||
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 <class DATA_TYPE, int SIZE>
|
||||
inline BOOL LLUUIDHashMap<DATA_TYPE, SIZE>::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<DATA_TYPE, SIZE> *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<DATA_TYPE, SIZE> *prevp = &mNodes[uuid.mData[0]];
|
||||
LLUUIDHashNode<DATA_TYPE, SIZE> *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 DATA_TYPE, int SIZE>
|
||||
class LLUUIDHashMapIter
|
||||
{
|
||||
public:
|
||||
LLUUIDHashMapIter(LLUUIDHashMap<DATA_TYPE, SIZE> *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<DATA_TYPE, SIZE> *mHashMapp;
|
||||
LLUUIDHashNode<DATA_TYPE, SIZE> *mCurHashNodep;
|
||||
|
||||
S32 mCurHashMapNodeNum;
|
||||
S32 mCurHashNodeKey;
|
||||
|
||||
DATA_TYPE mNull;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// LLUUIDHashMapIter Implementation
|
||||
//
|
||||
template <class DATA_TYPE, int SIZE>
|
||||
LLUUIDHashMapIter<DATA_TYPE, SIZE>::LLUUIDHashMapIter(LLUUIDHashMap<DATA_TYPE, SIZE> *hash_mapp)
|
||||
{
|
||||
mHashMapp = hash_mapp;
|
||||
mCurHashNodep = NULL;
|
||||
mCurHashMapNodeNum = 0;
|
||||
mCurHashNodeKey = 0;
|
||||
}
|
||||
|
||||
template <class DATA_TYPE, int SIZE>
|
||||
LLUUIDHashMapIter<DATA_TYPE, SIZE>::~LLUUIDHashMapIter()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
template <class DATA_TYPE, int SIZE>
|
||||
inline void LLUUIDHashMapIter<DATA_TYPE, SIZE>::reset()
|
||||
{
|
||||
if (mCurHashNodep)
|
||||
{
|
||||
// We're partway through an iteration, we can clean up now
|
||||
mHashMapp->mIterCount--;
|
||||
mCurHashNodep = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
template <class DATA_TYPE, int SIZE>
|
||||
inline void LLUUIDHashMapIter<DATA_TYPE, SIZE>::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 <class DATA_TYPE, int SIZE>
|
||||
inline BOOL LLUUIDHashMapIter<DATA_TYPE, SIZE>::done() const
|
||||
{
|
||||
return mCurHashNodep ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
template <class DATA_TYPE, int SIZE>
|
||||
inline void LLUUIDHashMapIter<DATA_TYPE, SIZE>::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
|
||||
36
indra/llcommon/sguuidhash.h
Normal file
36
indra/llcommon/sguuidhash.h
Normal file
@@ -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 <boost/functional/hash.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
namespace boost {
|
||||
template<> class hash<LLUUID> {
|
||||
public:
|
||||
size_t operator()(const LLUUID& id ) const
|
||||
{
|
||||
return *reinterpret_cast<const size_t*>(id.mData);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
|
||||
@@ -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 <typename T>
|
||||
T min_glue(T a, T b)
|
||||
@@ -91,7 +91,7 @@ struct lazy_bfunc_
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace anonymous
|
||||
//} // end namespace anonymous
|
||||
|
||||
template <typename FPT, typename Iterator>
|
||||
struct grammar
|
||||
|
||||
@@ -52,7 +52,8 @@ class AIAverage {
|
||||
U32 mN; // The number of calls to operator().
|
||||
int const mNrOfBuckets; // Size of mData.
|
||||
std::vector<Data> 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;
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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::TotalQueued> 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<ThreadSafeBufferedCurlEasyRequest> BufferedCurlEasy
|
||||
|
||||
// AIPerService objects are created by the curl thread and destructed by the main thread.
|
||||
// We need locking.
|
||||
typedef AIThreadSafeSimpleDC<AIPerService> threadsafe_PerServiceRequestQueue;
|
||||
typedef AIAccessConst<AIPerService> PerServiceRequestQueue_crat;
|
||||
typedef AIAccess<AIPerService> PerServiceRequestQueue_rat;
|
||||
typedef AIAccess<AIPerService> PerServiceRequestQueue_wat;
|
||||
typedef AIThreadSafeSimpleDC<AIPerService> threadsafe_PerService;
|
||||
typedef AIAccessConst<AIPerService> PerService_crat;
|
||||
typedef AIAccess<AIPerService> PerService_rat;
|
||||
typedef AIAccess<AIPerService> 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<AICurlPrivate::RefCountedThreadSafePerServiceRequestQueue> AIPerServicePtr;
|
||||
typedef boost::intrusive_ptr<AICurlPrivate::RefCountedThreadSafePerService> 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<std::string, AIPerServicePtr> 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<AIPerService>; //threadsafe_PerServiceRequestQueue
|
||||
friend class AIThreadSafeSimpleDC<AIPerService>; // 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<AICurlPrivate::BufferedCurlEasyRequestPtr> 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<AICurlPrivate::BufferedCurlEasyRequestPtr> 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<TotalQueued> sTotalQueued;
|
||||
typedef AIAccessConst<TotalQueued> TotalQueued_crat;
|
||||
typedef AIAccess<TotalQueued> TotalQueued_rat;
|
||||
typedef AIAccess<TotalQueued> 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<MaxPipelinedRequests> sMaxPipelinedRequests;
|
||||
typedef AIAccessConst<MaxPipelinedRequests> MaxPipelinedRequests_crat;
|
||||
typedef AIAccess<MaxPipelinedRequests> MaxPipelinedRequests_rat;
|
||||
typedef AIAccess<MaxPipelinedRequests> 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<ThrottleFraction> sThrottleFraction;
|
||||
typedef AIAccessConst<ThrottleFraction> ThrottleFraction_crat;
|
||||
typedef AIAccess<ThrottleFraction> ThrottleFraction_rat;
|
||||
typedef AIAccess<ThrottleFraction> 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;
|
||||
|
||||
@@ -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<AIPerService::Approvement> 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)
|
||||
|
||||
@@ -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<addedEasyRequests_type::iterator, bool> res = mAddedEasyRequests.insert(easy_request);
|
||||
#ifdef SHOW_ASSERT
|
||||
std::pair<addedEasyRequests_type::iterator, bool> 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::MaxPipelinedRequests> AIPerService::sMaxPipelinedRequests;
|
||||
AIThreadSafeSimpleDC<AIPerService::ThrottleFraction> 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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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() : "<uninitialized>")
|
||||
{
|
||||
if (approved)
|
||||
{
|
||||
AICurlEasyRequest_wat(*mCurlEasyRequest)->setApproved(approved);
|
||||
}
|
||||
}
|
||||
|
||||
void LLURLRequest::initialize_impl(void)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
0
indra/llplugin/slplugin/slplugin_info.plist
Executable file → Normal file
0
indra/llplugin/slplugin/slplugin_info.plist
Executable file → Normal file
@@ -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];
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<const LLTextSegmentPtr>& segments) const
|
||||
void LLTextEditor::getSelectedSegments(std::vector<LLTextSegmentPtr>& 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
|
||||
|
||||
@@ -293,7 +293,7 @@ public:
|
||||
|
||||
const LLTextSegment* getCurrentSegment() const { return getSegmentAtOffset(mCursorPos); }
|
||||
const LLTextSegment* getPreviousSegment() const;
|
||||
void getSelectedSegments(std::vector<const LLTextSegmentPtr>& segments) const;
|
||||
void getSelectedSegments(std::vector<LLTextSegmentPtr>& segments) const;
|
||||
|
||||
static bool isPartOfWord(llwchar c) { return ( (c == '_') || (c == '\'') || LLStringOps::isAlnum((char)c)); }
|
||||
|
||||
|
||||
0
indra/llwindow/glh/glh_linear.h
Executable file → Normal file
0
indra/llwindow/glh/glh_linear.h
Executable file → Normal file
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -9,6 +9,17 @@
|
||||
<string>settings_rlv.xml</string>
|
||||
</array>
|
||||
|
||||
<key>PhoenixIMAnnounceStealFocus</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Open a new IM tab when another person begins typing to you and announce that they are doing so.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>UseNewTargetOmegaCode</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -175,7 +186,10 @@
|
||||
<key>HTTPThrottleBandwidth</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>The bandwidth (in kbit/s) to strive for</string>
|
||||
<string>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.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
@@ -648,6 +662,17 @@
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>LiruItalicizeActions</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>When enabled, /me chat will be italicized.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>LiruFlyAfterTeleport</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -4338,6 +4363,17 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<key>Value</key>
|
||||
<real>0.700</real>
|
||||
</map>
|
||||
<key>ConsoleBottomOffset</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>User definable offset between the bottom of the chat console and the bottom of the window; increase to move text in the console up</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<real>0</real>
|
||||
</map>
|
||||
<key>ConsoleBufferSize</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -4468,7 +4504,7 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>16</integer>
|
||||
<integer>8</integer>
|
||||
</map>
|
||||
<key>CurlTimeoutDNSLookup</key>
|
||||
<map>
|
||||
@@ -6839,6 +6875,19 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RadarUpdateEnabled</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>When false, pauses the radar until further notice, good for banning someone who just left.</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>HideFromEditor</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>RadarUpdateRate</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -15546,6 +15595,17 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>InstantMessagesFriendsOnly</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Only accept instant messages from residents on your friends list</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoDisengageMic</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -16393,6 +16453,17 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>ClearBeaconAfterTeleport</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Clear the red tracker beacon after you teleport</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>LogTextureDownloadsToViewerLog</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
||||
@@ -199,9 +199,9 @@
|
||||
</map>
|
||||
|
||||
<!-- End AO -->
|
||||
|
||||
|
||||
<!-- Ascent Account-Specific (Always) -->
|
||||
|
||||
|
||||
<!-- Ascent Account-Specific (Always) -->
|
||||
<key>AscentContactGroups</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -215,72 +215,7 @@
|
||||
<string />
|
||||
</array>
|
||||
</map>
|
||||
<key>AscentInstantMessageResponse</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Auto response to instant messages</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>This is an autoresponse!</string>
|
||||
</map>
|
||||
<key>AscentInstantMessageResponseAnyone</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to auto-respond to anyone</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AscentInstantMessageResponseFriends</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to auto-respond to non-friends</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AscentInstantMessageResponseItem</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to send a item along with the autoresponse</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AscentInstantMessageResponseItemData</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>UUID</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string></string>
|
||||
</map>
|
||||
<key>AscentInstantMessageResponseMuted</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to auto-respond to muted people</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
|
||||
<key>AscentInstantMessageResponseRepeat</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -292,21 +227,11 @@
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
|
||||
<key>AscentInstantMessageShowOnTyping</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to perform the autorespond the moment they begin to type instead of waiting for a actual message</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AscentInstantMessageShowResponded</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to hide IMs entirely from those you have chosen to send autoresponses</string>
|
||||
<string>Whether to perform the autorespond the moment they begin to type instead of waiting for an actual message</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
@@ -314,6 +239,219 @@
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
|
||||
<!-- Autoresponse Section -->
|
||||
<key>AutoresponseAnyone</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to send autoresponse to anyone who isn't muted (or just friends, if AutoresponseAnyoneFriendsOnly)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoresponseAnyoneFriendsOnly</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to send AutoresponseAnyone to friends only</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoresponseAnyoneItem</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to send a item along with AutoresponseAnyone</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoresponseAnyoneItemID</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>UUID of item to send along with AutoresponseAnyone</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string/>
|
||||
</map>
|
||||
<key>AutoresponseAnyoneMessage</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Message to send as the autoresponse to AutoresponseAnyone</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>This is an autoresponse!</string>
|
||||
</map>
|
||||
<key>AutoresponseAnyoneShow</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to show that AutoresponseAnyone's were sent</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoresponseNonFriends</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to send autoresponse to nonfriends, separately using a different response</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoresponseNonFriendsItem</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to send a item along with AutoresponseNonFriends</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoresponseNonFriendsItemID</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>UUID of item to send along with AutoresponseNonFriends</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string/>
|
||||
</map>
|
||||
<key>AutoresponseNonFriendsMessage</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Message to send as the autoresponse to AutoresponseNonFriends</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>This is an autoresponse!</string>
|
||||
</map>
|
||||
<key>AutoresponseNonFriendsShow</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to show that AutoresponseNonFriends's were sent</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoresponseMuted</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to send autoresponse to muted people</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoresponseMutedItem</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to send a item along with AutoresponseMuted</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoresponseMutedItemID</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>UUID of item to send along with AutoresponseMuted</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string/>
|
||||
</map>
|
||||
<key>AutoresponseMutedMessage</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Message to send as the autoresponse to AutoresponseMuted</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>This is an autoresponse!</string>
|
||||
</map>
|
||||
<key>BusyModeResponse</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Auto response to instant messages while in busy mode.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>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.</string>
|
||||
</map>
|
||||
<key>BusyModeResponseItem</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to send a item along with BusyModeResponse</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>BusyModeResponseItemID</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>UUID of item to send along with BusyModeResponse</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string/>
|
||||
</map>
|
||||
<key>BusyModeResponseShow</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to show that BusyModeResponses were sent</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
|
||||
|
||||
<key>EveryoneExport</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -336,84 +474,7 @@
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>BusyModeResponse</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Auto response to instant messages while in busy mode.</string>
|
||||
</map>
|
||||
<key>AO.Settings</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>List for animation overrider</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>LLSD</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<string/>
|
||||
</array>
|
||||
</map>
|
||||
<key>Responder.Settings</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>New organization to the Auto-Respond settings for keeping clean</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>LLSD</string>
|
||||
<key>Value</key>
|
||||
<map>
|
||||
<key>Message</key>
|
||||
<string>This is an autoresponse!</string>
|
||||
</map>
|
||||
</map>
|
||||
<!-- Ascent Account-Specific (Always) -->
|
||||
<!-- General additions -->
|
||||
<key>rkeastInventoryPreviousCount</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Used to keep track of the number of items in inventory when fetching for progress reasons. DO NOT EDIT.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>rkeastInventorySearchType</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Controls what type of inventory search we perform.</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>rkeastInventoryPartialSearch</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Toggles whether to search using partial search filters on normal (name, desc, creator) searches.</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>BusyModeResponse</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Auto response to instant messages while in busy mode.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>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.</string>
|
||||
</map>
|
||||
<key>IMLogTimestamp</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
||||
@@ -14,72 +14,7 @@
|
||||
<string />
|
||||
</array>
|
||||
</map>
|
||||
<key>AscentInstantMessageResponse</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Auto response to instant messages</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>This is an autoresponse!</string>
|
||||
</map>
|
||||
<key>AscentInstantMessageResponseAnyone</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to auto-respond to anyone</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AscentInstantMessageResponseFriends</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to auto-respond to non-friends</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AscentInstantMessageResponseItem</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to send a item along with the autoresponse</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AscentInstantMessageResponseItemData</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>UUID</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string></string>
|
||||
</map>
|
||||
<key>AscentInstantMessageResponseMuted</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to auto-respond to muted people</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
|
||||
<key>AscentInstantMessageResponseRepeat</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -91,21 +26,11 @@
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
|
||||
<key>AscentInstantMessageShowOnTyping</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to perform the autorespond the moment they begin to type instead of waiting for a actual message</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AscentInstantMessageShowResponded</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to hide IMs entirely from those you have chosen to send autoresponses</string>
|
||||
<string>Whether to perform the autorespond the moment they begin to type instead of waiting for an actual message</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
@@ -113,5 +38,216 @@
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
|
||||
<!-- Autoresponse Section -->
|
||||
<key>AutoresponseAnyone</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to send autoresponse to anyone who isn't muted (or just friends, if AutoresponseAnyoneFriendsOnly)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoresponseAnyoneFriendsOnly</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to send AutoresponseAnyone to friends only</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoresponseAnyoneItem</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to send a item along with AutoresponseAnyone</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoresponseAnyoneItemID</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>UUID of item to send along with AutoresponseAnyone</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string/>
|
||||
</map>
|
||||
<key>AutoresponseAnyoneMessage</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Message to send as the autoresponse to AutoresponseAnyone</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>This is an autoresponse!</string>
|
||||
</map>
|
||||
<key>AutoresponseAnyoneShow</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to show that AutoresponseAnyone's were sent</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoresponseNonFriends</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to send autoresponse to nonfriends, separately using a different response</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoresponseNonFriendsItem</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to send a item along with AutoresponseNonFriends</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoresponseNonFriendsItemID</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>UUID of item to send along with AutoresponseNonFriends</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string/>
|
||||
</map>
|
||||
<key>AutoresponseNonFriendsMessage</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Message to send as the autoresponse to AutoresponseNonFriends</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>This is an autoresponse!</string>
|
||||
</map>
|
||||
<key>AutoresponseNonFriendsShow</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to show that AutoresponseNonFriends's were sent</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoresponseMuted</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to send autoresponse to muted people</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoresponseMutedItem</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to send a item along with AutoresponseMuted</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoresponseMutedItemID</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>UUID of item to send along with AutoresponseMuted</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string/>
|
||||
</map>
|
||||
<key>AutoresponseMutedMessage</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Message to send as the autoresponse to AutoresponseMuted</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>This is an autoresponse!</string>
|
||||
</map>
|
||||
<key>BusyModeResponse</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Auto response to instant messages while in busy mode.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>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.</string>
|
||||
</map>
|
||||
<key>BusyModeResponseItem</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to send a item along with BusyModeResponse</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>BusyModeResponseItemID</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>UUID of item to send along with BusyModeResponse</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string/>
|
||||
</map>
|
||||
<key>BusyModeResponseShow</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to show that BusyModeResponses were sent</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
</map>
|
||||
</llsd>
|
||||
</llsd>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
0
indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl
Executable file → Normal file
0
indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl
Executable file → Normal file
0
indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl
Executable file → Normal file
0
indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl
Executable file → Normal file
0
indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl
Executable file → Normal file
0
indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl
Executable file → Normal file
0
indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl
Executable file → Normal file
0
indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl
Executable file → Normal file
0
indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl
Executable file → Normal file
0
indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl
Executable file → Normal file
0
indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl
Executable file → Normal file
0
indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl
Executable file → Normal file
@@ -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<LLView>("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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<LLTextureCtrl>("texture control")->setDefaultImageAssetID(LLUUID(gSavedSettings.getString("EmeraldBuildPrefs_Texture")));
|
||||
childSetCommitCallback("texture control", onCommitTexturePicker, this);
|
||||
|
||||
if(sInst)delete sInst; sInst = this;
|
||||
LLView* target_view = getChild<LLView>("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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<LLView>("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<struct_overrides>::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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -252,7 +252,6 @@ private:
|
||||
LLButton* mUploadBtn;
|
||||
|
||||
LLScrollListCtrl* mBitmapList;
|
||||
LLScrollListCtrl* mUsedList;
|
||||
LLTextureCtrl* mTextureView;
|
||||
LLCheckBoxCtrl* mUpdateChkBox;
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -66,7 +66,6 @@ public:
|
||||
/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
|
||||
|
||||
private:
|
||||
int mWebBrowserWindowId;
|
||||
int mLoadCompleteCount;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
0
indra/newview/installers/windows/install_icon_singularity.BMP
Executable file → Normal file
0
indra/newview/installers/windows/install_icon_singularity.BMP
Executable file → Normal file
|
Before Width: | Height: | Size: 256 KiB After Width: | Height: | Size: 256 KiB |
0
indra/newview/installers/windows/uninstall_icon_singularity.BMP
Executable file → Normal file
0
indra/newview/installers/windows/uninstall_icon_singularity.BMP
Executable file → Normal file
|
Before Width: | Height: | Size: 254 KiB After Width: | Height: | Size: 254 KiB |
0
indra/newview/installers/windows/uninstall_icon_singularity.ico
Executable file → Normal file
0
indra/newview/installers/windows/uninstall_icon_singularity.ico
Executable file → Normal file
|
Before Width: | Height: | Size: 359 KiB After Width: | Height: | Size: 359 KiB |
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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<LLDropTarget> 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<LLViewerInventoryItem*>(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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Params, LLView::Params>
|
||||
{
|
||||
Optional<std::string> control_name; // Control to change on item drop (Per Account only)
|
||||
Optional<std::string> label; // Label for the LLTextBox, used when label doesn't dynamically change on drop
|
||||
Optional<bool> 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
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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<LLRadioGroup>("update_rate")->setSelectedIndex(gSavedSettings.getU32("RadarUpdateRate"));
|
||||
getChild<LLRadioGroup>("update_rate")->setCommitCallback(boost::bind(&LLFloaterAvatarList::onCommitUpdateRate, this));
|
||||
|
||||
getChild<LLCheckboxCtrl>("hide_mark")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this));
|
||||
getChild<LLCheckboxCtrl>("hide_pos")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this));
|
||||
getChild<LLCheckboxCtrl>("hide_alt")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this));
|
||||
getChild<LLCheckboxCtrl>("hide_act")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this));
|
||||
getChild<LLCheckboxCtrl>("hide_age")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this));
|
||||
getChild<LLCheckboxCtrl>("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<LLScrollListCtrl>("avatar_list");
|
||||
@@ -438,7 +438,7 @@ BOOL LLFloaterAvatarList::postBuild()
|
||||
if(gHippoGridManager->getConnectedGrid()->isSecondLife())
|
||||
childSetVisible("hide_client", false);
|
||||
else
|
||||
getChild<LLCheckboxCtrl>("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<LLCheckboxCtrl>("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;
|
||||
|
||||
|
||||
|
||||
@@ -354,7 +354,7 @@ private:
|
||||
/**
|
||||
* @brief TRUE when Updating
|
||||
*/
|
||||
bool mUpdate;
|
||||
const LLCachedControl<bool> mUpdate;
|
||||
|
||||
/**
|
||||
* @brief Update rate (if min frames per update)
|
||||
|
||||
@@ -91,18 +91,12 @@ private:
|
||||
void doCheckUncheckAll(BOOL check);
|
||||
|
||||
private:
|
||||
// UI
|
||||
LLScrollListCtrl* mMessages;
|
||||
LLButton* mCloseBtn;
|
||||
|
||||
// Object Queue
|
||||
LLDynamicArray<LLUUID> mObjectIDs;
|
||||
LLUUID mCurrentObjectID;
|
||||
BOOL mDone;
|
||||
|
||||
LLUUID mID;
|
||||
|
||||
const char* mStartString;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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<LLUICtrl>("Chat Editor");
|
||||
if (getVisible() && chat_editor->getVisible())
|
||||
{
|
||||
gFocusMgr.setKeyboardFocus(chat_editor);
|
||||
|
||||
LLUICtrl * ctrl = static_cast<LLUICtrl*>(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<bool> 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<bool> 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<bool> color_friend_chat("ColorFriendChat");
|
||||
static LLCachedControl<bool> 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<LLUICtrl>("Chat Editor");
|
||||
if (getVisible() && chat_editor->getVisible())
|
||||
{
|
||||
gFocusMgr.setKeyboardFocus(chat_editor);
|
||||
|
||||
LLUICtrl * ctrl = static_cast<LLUICtrl*>(chat_editor);
|
||||
ctrl->setFocus(TRUE);
|
||||
chat_editor->setFocus(TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -189,6 +189,7 @@ LLFloaterCustomize::~LLFloaterCustomize()
|
||||
BOOL LLFloaterCustomize::postBuild()
|
||||
{
|
||||
getChild<LLUICtrl>("Make Outfit")->setCommitCallback(boost::bind(&LLFloaterCustomize::onBtnMakeOutfit, this));
|
||||
getChild<LLUICtrl>("Save Outfit")->setCommitCallback(boost::bind(&LLAppearanceMgr::updateBaseOutfit, LLAppearanceMgr::getInstance()));
|
||||
getChild<LLUICtrl>("Ok")->setCommitCallback(boost::bind(&LLFloaterCustomize::onBtnOk, this));
|
||||
getChild<LLUICtrl>("Cancel")->setCommitCallback(boost::bind(&LLFloater::onClickClose, this));
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<LLButton>("start_btn");
|
||||
requires<LLButton>("close_btn");
|
||||
requires<LLNameListCtrl>("user_list");
|
||||
|
||||
if (checkRequirements())
|
||||
{
|
||||
childSetAction("start_btn", &LLFloaterNewIM::onStart, this);
|
||||
childSetAction("close_btn", &LLFloaterNewIM::onClickClose, this);
|
||||
mSelectionList = getChild<LLNameListCtrl>("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<LLScrollListItem*> data_list = mSelectionList->getAllData();
|
||||
std::vector<LLScrollListItem*>::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 );
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);*/
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -52,7 +52,7 @@ class LLTextBox;
|
||||
|
||||
class LLPropertiesObserver;
|
||||
|
||||
class LLFloaterProperties : public LLFloater, LLInstanceTracker<LLFloaterProperties, LLUUID>
|
||||
class LLFloaterProperties : public LLFloater, public LLInstanceTracker<LLFloaterProperties, LLUUID>
|
||||
{
|
||||
public:
|
||||
static LLFloaterProperties* find(const LLUUID& item_id,
|
||||
|
||||
@@ -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<LLButton>("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<LLLineEditor>("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<LLUICtrl>("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<LLUICtrl>("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<LLUICtrl>("object_name")->setValue(LLStringUtil::null);
|
||||
getChild<LLUICtrl>("owner_name")->setValue(LLStringUtil::null);
|
||||
mOwnerName = LLStringUtil::null;
|
||||
|
||||
getChild<LLUICtrl>("summary_edit")->setFocus(TRUE);
|
||||
|
||||
mDefaultSummary = getChild<LLUICtrl>("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<LLUICtrl>("abuser_name_edit");
|
||||
le->setEnabled( false );
|
||||
|
||||
LLButton* pick_btn = getChild<LLButton>("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<LLUICtrl>("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<LLUICtrl>("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<LLAvatarName>& 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<LLUICtrl>("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<LLUICtrl>("owner_name")->setValue(avatar_link);
|
||||
getChild<LLUICtrl>("object_name")->setValue(avatar_link);
|
||||
getChild<LLUICtrl>("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<LLUICtrl>("owner_name")->setValue(avatar_link);
|
||||
getChild<LLUICtrl>("object_name")->setValue(avatar_link);
|
||||
getChild<LLUICtrl>("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<LLComboBox>( "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<LLComboBox>( "category_combo");
|
||||
int category_value = combo->getSelectedValue().asInteger();
|
||||
|
||||
if ( ! self->mCopyrightWarningSeen )
|
||||
std::string details_lc = self->getChild<LLUICtrl>("details_edit")->getValue().asString();
|
||||
LLStringUtil::toLower( details_lc );
|
||||
std::string summary_lc = self->getChild<LLUICtrl>("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<LLUICtrl>("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<LLUICtrl>("object_name")->setValue(LLStringUtil::null);
|
||||
self->getChild<LLUICtrl>("owner_name")->setValue(LLStringUtil::null);
|
||||
self->mOwnerName = LLStringUtil::null;
|
||||
LLButton* pick_btn = self->getChild<LLButton>("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<LLUICtrl>("object_name")->setValue(object_name);
|
||||
|
||||
|
||||
getChild<LLUICtrl>("owner_name")->setValue(owner_name);
|
||||
getChild<LLUICtrl>("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<LLUICtrl>("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<LLUICtrl>("abuser_name_edit")->getValue().asString().empty() )
|
||||
{
|
||||
if ( mReportType != BUG_REPORT )
|
||||
{
|
||||
LLNotificationsUtil::add("HelpReportAbuseSummaryEmpty");
|
||||
}
|
||||
else
|
||||
{
|
||||
LLNotificationsUtil::add("HelpReportBugSummaryEmpty");
|
||||
}
|
||||
LLNotificationsUtil::add("HelpReportAbuseAbuserNameEmpty");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( getChild<LLUICtrl>("abuse_location_edit")->getValue().asString().empty() )
|
||||
{
|
||||
LLNotificationsUtil::add("HelpReportAbuseAbuserLocationEmpty");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( getChild<LLUICtrl>("abuse_location_edit")->getValue().asString().empty() )
|
||||
{
|
||||
LLNotificationsUtil::add("HelpReportAbuseAbuserLocationEmpty");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if ( getChild<LLUICtrl>("summary_edit")->getValue().asString().empty() )
|
||||
{
|
||||
LLNotificationsUtil::add("HelpReportAbuseSummaryEmpty");
|
||||
return false;
|
||||
};
|
||||
|
||||
if ( childGetText("details_edit") == mDefaultSummary )
|
||||
if ( getChild<LLUICtrl>("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<LLUICtrl>("abuse_location_edit")->getValue().asString() << ")" // region abuse occured in (freeform text - no LLRegionPicker tool)
|
||||
<< " [" << category_name << "] " // updated category
|
||||
<< " {" << getChild<LLUICtrl>("abuser_name_edit")->getValue().asString() << "} " // name of abuse entered in report (chosen using LLAvatarPicker)
|
||||
<< " \"" << getChild<LLUICtrl>("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<LLUICtrl>("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<LLUICtrl>("abuser_name_edit")->getValue().asString() << " \n";
|
||||
details << "Abuser location: " << getChild<LLUICtrl>("abuse_location_edit")->getValue().asString() << " \n";
|
||||
|
||||
details << getChild<LLUICtrl>("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<LLUICtrl>("screen_check")->getValue())
|
||||
{
|
||||
screenshot_id = childGetValue("screenshot");
|
||||
};
|
||||
screenshot_id = getChild<LLUICtrl>("screenshot")->getValue();
|
||||
}
|
||||
|
||||
LLSD report = LLSD::emptyMap();
|
||||
report["report-type"] = (U8) mReportType;
|
||||
report["category"] = childGetValue("category_combo");
|
||||
report["category"] = getChild<LLUICtrl>("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<LLUICtrl>("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<LLImageRaw> 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<LLUICtrl>("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<LLUICtrl>("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<LLTextEditor>("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<LLTextEditor>("details_edit");
|
||||
// if (text)
|
||||
// {
|
||||
// text->insertText(description);
|
||||
// }
|
||||
// if (mcd)
|
||||
// {
|
||||
// self->mMCDList.push_back(new LLMeanCollisionData(mcd));
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
@@ -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<LLFloaterReporter>
|
||||
{
|
||||
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<LLAvatarName>& 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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user