# Conflicts:
#	indra/llcommon/llsdserialize.cpp
#	indra/llcommon/llsdserialize.h
#	indra/newview/llmeshrepository.cpp
#	indra/newview/llvoicevivox.h
master
Ansariel 2023-02-10 00:50:19 +01:00
commit 3079cda486
207 changed files with 3318 additions and 3097 deletions

8
.gitignore vendored
View File

@ -19,12 +19,8 @@ debian/files
debian/secondlife-appearance-utility* debian/secondlife-appearance-utility*
debian/secondlife-viewer* debian/secondlife-viewer*
indra/.distcc indra/.distcc
build-vc80/ build-vc[0-9]*-32**
build-vc100/ build-vc[0-9]*-64**
build-vc120/
build-vc[0-9]*-32*/
build-vc[0-9]*-64*/
build-vc160-64/
indra/CMakeFiles indra/CMakeFiles
indra/build-vc[0-9]* indra/build-vc[0-9]*
indra/lib/mono/1.0/*.dll indra/lib/mono/1.0/*.dll

View File

@ -2832,9 +2832,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key> <key>archive</key>
<map> <map>
<key>hash</key> <key>hash</key>
<string>53966a7ba6342395acb7ce15bc3fbe0a</string> <string>8114c6a7e499ea20d325db0de08ce30a</string>
<key>url</key> <key>url</key>
<string>http://3p.firestormviewer.org/openjpeg-2.3.1.203000304-darwin-203000304.tar.bz2</string> <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/105469/923024/openjpeg-2.5.0.575496-darwin64-575496.tar.bz2</string>
</map> </map>
<key>name</key> <key>name</key>
<string>darwin64</string> <string>darwin64</string>
@ -2856,9 +2856,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key> <key>archive</key>
<map> <map>
<key>hash</key> <key>hash</key>
<string>ba2034b4a372fd46c3e09f56bede38a7</string> <string>edc9388870d951632a6d595792293e05</string>
<key>url</key> <key>url</key>
<string>http://3p.firestormviewer.org/openjpeg-2.4.0.211361403-windows-211361403.tar.bz2</string> <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/105472/923036/openjpeg-2.5.0.575496-windows-575496.tar.bz2</string>
</map> </map>
<key>name</key> <key>name</key>
<string>windows</string> <string>windows</string>
@ -2868,16 +2868,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key> <key>archive</key>
<map> <map>
<key>hash</key> <key>hash</key>
<string>d7ac606703a9330a2d8a3f7276cb6894</string> <string>b95f0732f2388ebb0ddf33d4a30e0ff1</string>
<key>url</key> <key>url</key>
<string>http://3p.firestormviewer.org/openjpeg-2.4.0.211361407-windows64-211361407.tar.bz2</string> <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/105471/923037/openjpeg-2.5.0.575496-windows64-575496.tar.bz2</string>
</map> </map>
<key>name</key> <key>name</key>
<string>windows64</string> <string>windows64</string>
</map> </map>
</map> </map>
<key>version</key> <key>version</key>
<string>2.4.0</string> <string>2.5.0.575496</string>
</map> </map>
<key>openssl</key> <key>openssl</key>
<map> <map>

View File

@ -285,6 +285,7 @@ Beq Janus
SL-15709 SL-15709
SL-16021 SL-16021
SL-16027 SL-16027
SL-18592
SL-18637 SL-18637
Beth Walcher Beth Walcher
Bezilon Kasei Bezilon Kasei
@ -376,6 +377,7 @@ Charlie Sazaland
Chaser Zaks Chaser Zaks
BUG-225599 BUG-225599
BUG-227485 BUG-227485
SL-16874
Cherry Cheevers Cherry Cheevers
ChickyBabes Zuzu ChickyBabes Zuzu
Chorazin Allen Chorazin Allen
@ -1388,6 +1390,7 @@ Sovereign Engineer
OPEN-343 OPEN-343
SL-11625 SL-11625
BUG-229030 BUG-229030
SL-14696
SL-14705 SL-14705
SL-14706 SL-14706
SL-14707 SL-14707
@ -1395,6 +1398,12 @@ Sovereign Engineer
SL-14732 SL-14732
SL-15096 SL-15096
SL-16127 SL-16127
SL-18249
SL-18394
SL-18412
SL-18497
SL-18525
SL-18534
SpacedOut Frye SpacedOut Frye
VWR-34 VWR-34
VWR-45 VWR-45
@ -1657,6 +1666,8 @@ Zi Ree
VWR-25588 VWR-25588
STORM-1790 STORM-1790
STORM-1842 STORM-1842
SL-18348
SL-18593
Zipherius Turas Zipherius Turas
VWR-76 VWR-76
VWR-77 VWR-77

View File

@ -262,7 +262,7 @@ elseif(LINUX)
${EXPAT_COPY} ${EXPAT_COPY}
libhunspell-1.3.so.0.0.0 libhunspell-1.3.so.0.0.0
libopenal.so libopenal.so
#libopenjpeg.so #libopenjp2.so
libuuid.so.16 libuuid.so.16
libuuid.so.16.0.22 libuuid.so.16.0.22
#libfontconfig.so.1.10.1 # <FS:PC> fontconfig and freetype should be taken from the #libfontconfig.so.1.10.1 # <FS:PC> fontconfig and freetype should be taken from the

View File

@ -16,9 +16,10 @@ FIND_PATH(OPENJPEG_INCLUDE_DIR openjpeg.h
/usr/include/openjpeg-2.1 /usr/include/openjpeg-2.1
/usr/include/openjpeg /usr/include/openjpeg
/usr/include /usr/include
include/openjpeg
) )
SET(OPENJPEG_NAMES ${OPENJPEG_NAMES} openjpeg openjp2) SET(OPENJPEG_NAMES ${OPENJPEG_NAMES} openjp2)
FIND_LIBRARY(OPENJPEG_LIBRARY FIND_LIBRARY(OPENJPEG_LIBRARY
NAMES ${OPENJPEG_NAMES} NAMES ${OPENJPEG_NAMES}
PATHS /usr/lib /usr/local/lib PATHS /usr/lib /usr/local/lib

View File

@ -10,6 +10,5 @@ else (USESYSTEMLIBS)
use_prebuilt_binary(openjpeg) use_prebuilt_binary(openjpeg)
set(OPENJPEG_LIBRARIES openjp2) set(OPENJPEG_LIBRARIES openjp2)
set(OPENJPEG_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/openjpeg) set(OPENJPEG_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/openjpeg)
endif (USESYSTEMLIBS) endif (USESYSTEMLIBS)

View File

@ -313,7 +313,12 @@ LLAvatarAppearance::~LLAvatarAppearance()
} }
} }
if (mRoot) mRoot->removeAllChildren(); if (mRoot)
{
mRoot->removeAllChildren();
delete mRoot;
mRoot = nullptr;
}
mJointMap.clear(); mJointMap.clear();
clearSkeleton(); clearSkeleton();

View File

@ -76,7 +76,7 @@ LLLocalTextureObject::LLLocalTextureObject(const LLLocalTextureObject& lto) :
LLLocalTextureObject::~LLLocalTextureObject() LLLocalTextureObject::~LLLocalTextureObject()
{ {
delete_and_clear(mTexLayers); // <FS:Ansariel> Mem-leak fix by Drake Arconis delete_and_clear(mTexLayers);
} }
LLGLTexture* LLLocalTextureObject::getImage() const LLGLTexture* LLLocalTextureObject::getImage() const

View File

@ -1232,7 +1232,7 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8
BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints) BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints)
{ {
BOOL old_version = FALSE; BOOL old_version = FALSE;
mJointMotionList = new LLKeyframeMotion::JointMotionList; std::unique_ptr<LLKeyframeMotion::JointMotionList> joint_motion_list(new LLKeyframeMotion::JointMotionList);
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// get base priority // get base priority
@ -1244,14 +1244,12 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
if (!dp.unpackU16(version, "version")) if (!dp.unpackU16(version, "version"))
{ {
LL_WARNS() << "can't read version number for animation " << asset_id << LL_ENDL; LL_WARNS() << "can't read version number for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
if (!dp.unpackU16(sub_version, "sub_version")) if (!dp.unpackU16(sub_version, "sub_version"))
{ {
LL_WARNS() << "can't read sub version number for animation " << asset_id << LL_ENDL; LL_WARNS() << "can't read sub version number for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1264,7 +1262,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
#if LL_RELEASE #if LL_RELEASE
LL_WARNS() << "Bad animation version " << version << "." << sub_version LL_WARNS() << "Bad animation version " << version << "." << sub_version
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
#else #else
LL_ERRS() << "Bad animation version " << version << "." << sub_version LL_ERRS() << "Bad animation version " << version << "." << sub_version
@ -1276,89 +1273,80 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "can't read animation base_priority" LL_WARNS() << "can't read animation base_priority"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
mJointMotionList->mBasePriority = (LLJoint::JointPriority) temp_priority; joint_motion_list->mBasePriority = (LLJoint::JointPriority) temp_priority;
if (mJointMotionList->mBasePriority >= LLJoint::ADDITIVE_PRIORITY) if (joint_motion_list->mBasePriority >= LLJoint::ADDITIVE_PRIORITY)
{ {
mJointMotionList->mBasePriority = (LLJoint::JointPriority)((S32)LLJoint::ADDITIVE_PRIORITY-1); joint_motion_list->mBasePriority = (LLJoint::JointPriority)((S32)LLJoint::ADDITIVE_PRIORITY-1);
mJointMotionList->mMaxPriority = mJointMotionList->mBasePriority; joint_motion_list->mMaxPriority = joint_motion_list->mBasePriority;
} }
else if (mJointMotionList->mBasePriority < LLJoint::USE_MOTION_PRIORITY) else if (joint_motion_list->mBasePriority < LLJoint::USE_MOTION_PRIORITY)
{ {
LL_WARNS() << "bad animation base_priority " << mJointMotionList->mBasePriority LL_WARNS() << "bad animation base_priority " << joint_motion_list->mBasePriority
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// get duration // get duration
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (!dp.unpackF32(mJointMotionList->mDuration, "duration")) if (!dp.unpackF32(joint_motion_list->mDuration, "duration"))
{ {
LL_WARNS() << "can't read duration" LL_WARNS() << "can't read duration"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
if (mJointMotionList->mDuration > MAX_ANIM_DURATION || if (joint_motion_list->mDuration > MAX_ANIM_DURATION ||
!llfinite(mJointMotionList->mDuration)) !llfinite(joint_motion_list->mDuration))
{ {
LL_WARNS() << "invalid animation duration" LL_WARNS() << "invalid animation duration"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// get emote (optional) // get emote (optional)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (!dp.unpackString(mJointMotionList->mEmoteName, "emote_name")) if (!dp.unpackString(joint_motion_list->mEmoteName, "emote_name"))
{ {
LL_WARNS() << "can't read optional_emote_animation" LL_WARNS() << "can't read optional_emote_animation"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
if(mJointMotionList->mEmoteName==mID.asString()) if(joint_motion_list->mEmoteName==mID.asString())
{ {
LL_WARNS() << "Malformed animation mEmoteName==mID" LL_WARNS() << "Malformed animation mEmoteName==mID"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// get loop // get loop
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (!dp.unpackF32(mJointMotionList->mLoopInPoint, "loop_in_point") || if (!dp.unpackF32(joint_motion_list->mLoopInPoint, "loop_in_point") ||
!llfinite(mJointMotionList->mLoopInPoint)) !llfinite(joint_motion_list->mLoopInPoint))
{ {
LL_WARNS() << "can't read loop point" LL_WARNS() << "can't read loop point"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
if (!dp.unpackF32(mJointMotionList->mLoopOutPoint, "loop_out_point") || if (!dp.unpackF32(joint_motion_list->mLoopOutPoint, "loop_out_point") ||
!llfinite(mJointMotionList->mLoopOutPoint)) !llfinite(joint_motion_list->mLoopOutPoint))
{ {
LL_WARNS() << "can't read loop point" LL_WARNS() << "can't read loop point"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
if (!dp.unpackS32(mJointMotionList->mLoop, "loop")) if (!dp.unpackS32(joint_motion_list->mLoop, "loop"))
{ {
LL_WARNS() << "can't read loop" LL_WARNS() << "can't read loop"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1368,27 +1356,25 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
if (female_land_anim == asset_id || formal_female_land_anim == asset_id) if (female_land_anim == asset_id || formal_female_land_anim == asset_id)
{ {
LL_WARNS() << "Animation(" << asset_id << ") won't be looped." << LL_ENDL; LL_WARNS() << "Animation(" << asset_id << ") won't be looped." << LL_ENDL;
mJointMotionList->mLoop = FALSE; joint_motion_list->mLoop = FALSE;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// get easeIn and easeOut // get easeIn and easeOut
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (!dp.unpackF32(mJointMotionList->mEaseInDuration, "ease_in_duration") || if (!dp.unpackF32(joint_motion_list->mEaseInDuration, "ease_in_duration") ||
!llfinite(mJointMotionList->mEaseInDuration)) !llfinite(joint_motion_list->mEaseInDuration))
{ {
LL_WARNS() << "can't read easeIn" LL_WARNS() << "can't read easeIn"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
if (!dp.unpackF32(mJointMotionList->mEaseOutDuration, "ease_out_duration") || if (!dp.unpackF32(joint_motion_list->mEaseOutDuration, "ease_out_duration") ||
!llfinite(mJointMotionList->mEaseOutDuration)) !llfinite(joint_motion_list->mEaseOutDuration))
{ {
LL_WARNS() << "can't read easeOut" LL_WARNS() << "can't read easeOut"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1400,7 +1386,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "can't read hand pose" LL_WARNS() << "can't read hand pose"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1408,11 +1393,10 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "invalid LLHandMotion::eHandPose index: " << word LL_WARNS() << "invalid LLHandMotion::eHandPose index: " << word
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
mJointMotionList->mHandPose = (LLHandMotion::eHandPose)word; joint_motion_list->mHandPose = (LLHandMotion::eHandPose)word;
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// get number of joint motions // get number of joint motions
@ -1422,7 +1406,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "can't read number of joints" LL_WARNS() << "can't read number of joints"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1430,19 +1413,17 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "no joints" LL_WARNS() << "no joints"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
else if (num_motions > LL_CHARACTER_MAX_ANIMATED_JOINTS) else if (num_motions > LL_CHARACTER_MAX_ANIMATED_JOINTS)
{ {
LL_WARNS() << "too many joints" LL_WARNS() << "too many joints"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
mJointMotionList->mJointMotionArray.clear(); joint_motion_list->mJointMotionArray.clear();
mJointMotionList->mJointMotionArray.reserve(num_motions); joint_motion_list->mJointMotionArray.reserve(num_motions);
mJointStates.clear(); mJointStates.clear();
mJointStates.reserve(num_motions); mJointStates.reserve(num_motions);
@ -1453,14 +1434,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
for(U32 i=0; i<num_motions; ++i) for(U32 i=0; i<num_motions; ++i)
{ {
JointMotion* joint_motion = new JointMotion; JointMotion* joint_motion = new JointMotion;
mJointMotionList->mJointMotionArray.push_back(joint_motion); joint_motion_list->mJointMotionArray.push_back(joint_motion);
std::string joint_name; std::string joint_name;
if (!dp.unpackString(joint_name, "joint_name")) if (!dp.unpackString(joint_name, "joint_name"))
{ {
LL_WARNS() << "can't read joint name" LL_WARNS() << "can't read joint name"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1468,7 +1448,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "attempted to animate special " << joint_name << " joint" LL_WARNS() << "attempted to animate special " << joint_name << " joint"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1515,7 +1494,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "can't read joint priority." LL_WARNS() << "can't read joint priority."
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1523,15 +1501,14 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "joint priority unknown - too low." LL_WARNS() << "joint priority unknown - too low."
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
joint_motion->mPriority = (LLJoint::JointPriority)joint_priority; joint_motion->mPriority = (LLJoint::JointPriority)joint_priority;
if (joint_priority != LLJoint::USE_MOTION_PRIORITY && if (joint_priority != LLJoint::USE_MOTION_PRIORITY &&
joint_priority > mJointMotionList->mMaxPriority) joint_priority > joint_motion_list->mMaxPriority)
{ {
mJointMotionList->mMaxPriority = (LLJoint::JointPriority)joint_priority; joint_motion_list->mMaxPriority = (LLJoint::JointPriority)joint_priority;
} }
joint_state->setPriority((LLJoint::JointPriority)joint_priority); joint_state->setPriority((LLJoint::JointPriority)joint_priority);
@ -1543,7 +1520,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "can't read number of rotation keys" LL_WARNS() << "can't read number of rotation keys"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1570,7 +1546,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "can't read rotation key (" << k << ")" LL_WARNS() << "can't read rotation key (" << k << ")"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1581,17 +1556,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "can't read rotation key (" << k << ")" LL_WARNS() << "can't read rotation key (" << k << ")"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
time = U16_to_F32(time_short, 0.f, mJointMotionList->mDuration); time = U16_to_F32(time_short, 0.f, joint_motion_list->mDuration);
if (time < 0 || time > mJointMotionList->mDuration) if (time < 0 || time > joint_motion_list->mDuration)
{ {
LL_WARNS() << "invalid frame time" LL_WARNS() << "invalid frame time"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
} }
@ -1601,40 +1574,58 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
LLVector3 rot_angles; LLVector3 rot_angles;
U16 x, y, z; U16 x, y, z;
BOOL success = TRUE;
if (old_version) if (old_version)
{ {
success = dp.unpackVector3(rot_angles, "rot_angles") && rot_angles.isFinite(); if (!dp.unpackVector3(rot_angles, "rot_angles"))
{
LL_WARNS() << "can't read rot_angles in rotation key (" << k << ")" << LL_ENDL;
return FALSE;
}
if (!rot_angles.isFinite())
{
LL_WARNS() << "non-finite angle in rotation key (" << k << ")" << LL_ENDL;
return FALSE;
}
LLQuaternion::Order ro = StringToOrder("ZYX"); LLQuaternion::Order ro = StringToOrder("ZYX");
rot_key.mRotation = mayaQ(rot_angles.mV[VX], rot_angles.mV[VY], rot_angles.mV[VZ], ro); rot_key.mRotation = mayaQ(rot_angles.mV[VX], rot_angles.mV[VY], rot_angles.mV[VZ], ro);
} }
else else
{ {
success &= dp.unpackU16(x, "rot_angle_x"); if (!dp.unpackU16(x, "rot_angle_x"))
success &= dp.unpackU16(y, "rot_angle_y"); {
success &= dp.unpackU16(z, "rot_angle_z"); LL_WARNS() << "can't read rot_angle_x in rotation key (" << k << ")" << LL_ENDL;
return FALSE;
}
if (!dp.unpackU16(y, "rot_angle_y"))
{
LL_WARNS() << "can't read rot_angle_y in rotation key (" << k << ")" << LL_ENDL;
return FALSE;
}
if (!dp.unpackU16(z, "rot_angle_z"))
{
LL_WARNS() << "can't read rot_angle_z in rotation key (" << k << ")" << LL_ENDL;
return FALSE;
}
LLVector3 rot_vec; LLVector3 rot_vec;
rot_vec.mV[VX] = U16_to_F32(x, -1.f, 1.f); rot_vec.mV[VX] = U16_to_F32(x, -1.f, 1.f);
rot_vec.mV[VY] = U16_to_F32(y, -1.f, 1.f); rot_vec.mV[VY] = U16_to_F32(y, -1.f, 1.f);
rot_vec.mV[VZ] = U16_to_F32(z, -1.f, 1.f); rot_vec.mV[VZ] = U16_to_F32(z, -1.f, 1.f);
if(!rot_vec.isFinite())
{
LL_WARNS() << "non-finite angle in rotation key (" << k << ")"
<< " for animation " << asset_id << LL_ENDL;
return FALSE;
}
rot_key.mRotation.unpackFromVector3(rot_vec); rot_key.mRotation.unpackFromVector3(rot_vec);
} }
if( !(rot_key.mRotation.isFinite()) ) if(!rot_key.mRotation.isFinite())
{ {
LL_WARNS() << "non-finite angle in rotation key" LL_WARNS() << "non-finite angle in rotation key (" << k << ")"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
success = FALSE;
}
if (!success)
{
LL_WARNS() << "can't read rotation key (" << k << ")"
<< " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1648,7 +1639,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "can't read number of position keys" LL_WARNS() << "can't read number of position keys"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1675,7 +1665,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "can't read position key (" << k << ")" LL_WARNS() << "can't read position key (" << k << ")"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
} }
@ -1685,18 +1674,19 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "can't read position key (" << k << ")" LL_WARNS() << "can't read position key (" << k << ")"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
pos_key.mTime = U16_to_F32(time_short, 0.f, mJointMotionList->mDuration); pos_key.mTime = U16_to_F32(time_short, 0.f, joint_motion_list->mDuration);
} }
BOOL success = TRUE;
if (old_version) if (old_version)
{ {
success = dp.unpackVector3(pos_key.mPosition, "pos"); if (!dp.unpackVector3(pos_key.mPosition, "pos"))
{
LL_WARNS() << "can't read pos in position key (" << k << ")" << LL_ENDL;
return FALSE;
}
//MAINT-6162 //MAINT-6162
pos_key.mPosition.mV[VX] = llclamp( pos_key.mPosition.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); pos_key.mPosition.mV[VX] = llclamp( pos_key.mPosition.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
@ -1708,27 +1698,31 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
U16 x, y, z; U16 x, y, z;
success &= dp.unpackU16(x, "pos_x"); if (!dp.unpackU16(x, "pos_x"))
success &= dp.unpackU16(y, "pos_y"); {
success &= dp.unpackU16(z, "pos_z"); LL_WARNS() << "can't read pos_x in position key (" << k << ")" << LL_ENDL;
return FALSE;
}
if (!dp.unpackU16(y, "pos_y"))
{
LL_WARNS() << "can't read pos_y in position key (" << k << ")" << LL_ENDL;
return FALSE;
}
if (!dp.unpackU16(z, "pos_z"))
{
LL_WARNS() << "can't read pos_z in position key (" << k << ")" << LL_ENDL;
return FALSE;
}
pos_key.mPosition.mV[VX] = U16_to_F32(x, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); pos_key.mPosition.mV[VX] = U16_to_F32(x, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
pos_key.mPosition.mV[VY] = U16_to_F32(y, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); pos_key.mPosition.mV[VY] = U16_to_F32(y, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
pos_key.mPosition.mV[VZ] = U16_to_F32(z, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); pos_key.mPosition.mV[VZ] = U16_to_F32(z, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
} }
if( !(pos_key.mPosition.isFinite()) ) if(!pos_key.mPosition.isFinite())
{ {
LL_WARNS() << "non-finite position in key" LL_WARNS() << "non-finite position in key"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
success = FALSE;
}
if (!success)
{
LL_WARNS() << "can't read position key (" << k << ")"
<< " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1736,7 +1730,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
if (is_pelvis) if (is_pelvis)
{ {
mJointMotionList->mPelvisBBox.addPoint(pos_key.mPosition); joint_motion_list->mPelvisBBox.addPoint(pos_key.mPosition);
} }
} }
@ -1751,7 +1745,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "can't read number of constraints" LL_WARNS() << "can't read number of constraints"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1769,25 +1762,21 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
for(S32 i = 0; i < num_constraints; ++i) for(S32 i = 0; i < num_constraints; ++i)
{ {
// read in constraint data // read in constraint data
JointConstraintSharedData* constraintp = new JointConstraintSharedData; std::unique_ptr<JointConstraintSharedData> constraintp(new JointConstraintSharedData);
U8 byte = 0; U8 byte = 0;
if (!dp.unpackU8(byte, "chain_length")) if (!dp.unpackU8(byte, "chain_length"))
{ {
LL_WARNS() << "can't read constraint chain length" LL_WARNS() << "can't read constraint chain length"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete constraintp;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
constraintp->mChainLength = (S32) byte; constraintp->mChainLength = (S32) byte;
if((U32)constraintp->mChainLength > mJointMotionList->getNumJointMotions()) if((U32)constraintp->mChainLength > joint_motion_list->getNumJointMotions())
{ {
LL_WARNS() << "invalid constraint chain length" LL_WARNS() << "invalid constraint chain length"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete constraintp;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1795,8 +1784,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "can't read constraint type" LL_WARNS() << "can't read constraint type"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete constraintp;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1804,8 +1791,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "invalid constraint type" LL_WARNS() << "invalid constraint type"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete constraintp;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
constraintp->mConstraintType = (EConstraintType)byte; constraintp->mConstraintType = (EConstraintType)byte;
@ -1816,8 +1801,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "can't read source volume name" LL_WARNS() << "can't read source volume name"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete constraintp;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1828,8 +1811,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "not a valid source constraint volume " << str LL_WARNS() << "not a valid source constraint volume " << str
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete constraintp;
delete mJointMotionList; // <FS:Beq> avoid mem-leak as per others
return FALSE; return FALSE;
} }
@ -1837,8 +1818,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "can't read constraint source offset" LL_WARNS() << "can't read constraint source offset"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete constraintp;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1846,8 +1825,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "non-finite constraint source offset" LL_WARNS() << "non-finite constraint source offset"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete constraintp;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1855,8 +1832,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "can't read target volume name" LL_WARNS() << "can't read target volume name"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete constraintp;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1875,8 +1850,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "not a valid target constraint volume " << str LL_WARNS() << "not a valid target constraint volume " << str
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete constraintp;
delete mJointMotionList; // <FS:Beq> avoid mem-leak as per others
return FALSE; return FALSE;
} }
} }
@ -1885,8 +1858,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "can't read constraint target offset" LL_WARNS() << "can't read constraint target offset"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete constraintp;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1894,8 +1865,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "non-finite constraint target offset" LL_WARNS() << "non-finite constraint target offset"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete constraintp;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1903,8 +1872,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "can't read constraint target direction" LL_WARNS() << "can't read constraint target direction"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete constraintp;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1912,8 +1879,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "non-finite constraint target direction" LL_WARNS() << "non-finite constraint target direction"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete constraintp;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1927,8 +1892,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "can't read constraint ease in start time" LL_WARNS() << "can't read constraint ease in start time"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete constraintp;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1936,8 +1899,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "can't read constraint ease in stop time" LL_WARNS() << "can't read constraint ease in stop time"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete constraintp;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1945,8 +1906,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "can't read constraint ease out start time" LL_WARNS() << "can't read constraint ease out start time"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete constraintp;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -1954,36 +1913,31 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "can't read constraint ease out stop time" LL_WARNS() << "can't read constraint ease out stop time"
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete constraintp;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
mJointMotionList->mConstraints.push_front(constraintp);
constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; // note: mChainLength is size-limited - comes from a byte
LLJoint* joint = mCharacter->findCollisionVolume(constraintp->mSourceConstraintVolume); LLJoint* joint = mCharacter->findCollisionVolume(constraintp->mSourceConstraintVolume);
// get joint to which this collision volume is attached // get joint to which this collision volume is attached
if (!joint) if (!joint)
{ {
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; // note: mChainLength is size-limited - comes from a byte
for (S32 i = 0; i < constraintp->mChainLength + 1; i++) for (S32 i = 0; i < constraintp->mChainLength + 1; i++)
{ {
LLJoint* parent = joint->getParent(); LLJoint* parent = joint->getParent();
if (!parent) if (!parent)
{ {
LL_WARNS() << "Joint with no parent: " << joint->getName() LL_WARNS() << "Joint with no parent: " << joint->getName()
<< " Emote: " << mJointMotionList->mEmoteName << " Emote: " << joint_motion_list->mEmoteName
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
joint = parent; joint = parent;
constraintp->mJointStateIndices[i] = -1; constraintp->mJointStateIndices[i] = -1;
for (U32 j = 0; j < mJointMotionList->getNumJointMotions(); j++) for (U32 j = 0; j < joint_motion_list->getNumJointMotions(); j++)
{ {
LLJoint* constraint_joint = getJoint(j); LLJoint* constraint_joint = getJoint(j);
@ -1991,7 +1945,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "Invalid joint " << j LL_WARNS() << "Invalid joint " << j
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
delete mJointMotionList; // <FS:Ansariel> Mem-leak fix by Drake Arconis
return FALSE; return FALSE;
} }
@ -2005,17 +1958,16 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{ {
LL_WARNS() << "No joint index for constraint " << i LL_WARNS() << "No joint index for constraint " << i
<< " for animation " << asset_id << LL_ENDL; << " for animation " << asset_id << LL_ENDL;
// <FS:Ansariel> Mem-leak fix by Drake Arconis
//delete constraintp;
delete mJointMotionList;
// </FS:Ansariel>
return FALSE; return FALSE;
} }
} }
joint_motion_list->mConstraints.push_front(constraintp.release());
} }
} }
// *FIX: support cleanup of old keyframe data // *FIX: support cleanup of old keyframe data
mJointMotionList = joint_motion_list.release(); // release from unique_ptr to member;
LLKeyframeDataCache::addKeyframeData(getID(), mJointMotionList); LLKeyframeDataCache::addKeyframeData(getID(), mJointMotionList);
mAssetStatus = ASSET_LOADED; mAssetStatus = ASSET_LOADED;

View File

@ -287,25 +287,15 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl
return name; return name;
} }
namespace
{
#if LL_WINDOWS #if LL_WINDOWS
static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop, const std::string& name) U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
{ {
// C++ exceptions were logged in toplevelTryWrapper, but not SEH
// log SEH exceptions here, to make sure it gets into bugsplat's
// report and because __try won't allow std::string operations
if (code != STATUS_MSC_EXCEPTION)
{
LL_WARNS() << "SEH crash in " << name << ", code: " << code << LL_ENDL;
}
// Handle bugsplat here, since GetExceptionInformation() can only be
// called from within filter for __except(filter), not from __except's {}
// Bugsplat should get all exceptions, C++ and SEH
LLApp::instance()->reportCrashToBugsplat(exception_infop);
// Only convert non C++ exceptions.
if (code == STATUS_MSC_EXCEPTION) if (code == STATUS_MSC_EXCEPTION)
{ {
// C++ exception, go on // C++ exception, go on
@ -318,28 +308,38 @@ U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop,
} }
} }
void LLCoros::sehHandle(const std::string& name, const LLCoros::callable_t& callable) void sehandle(const LLCoros::callable_t& callable)
{ {
__try __try
{ {
LLCoros::toplevelTryWrapper(name, callable); callable();
} }
__except (cpp_exception_filter(GetExceptionCode(), GetExceptionInformation(), name)) __except (exception_filter(GetExceptionCode(), GetExceptionInformation()))
{ {
// convert to C++ styled exception for handlers other than bugsplat // convert to C++ styled exception
// Note: it might be better to use _se_set_translator // Note: it might be better to use _se_set_translator
// if you want exception to inherit full callstack // if you want exception to inherit full callstack
//
// in case of bugsplat this will get to exceptionTerminateHandler and
// looks like fiber will terminate application after that
char integer_string[512]; char integer_string[512];
sprintf(integer_string, "SEH crash in %s, code: %lu\n", name.c_str(), GetExceptionCode()); sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode());
throw std::exception(integer_string); throw std::exception(integer_string);
} }
} }
#endif
void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& callable) #else // ! LL_WINDOWS
inline void sehandle(const LLCoros::callable_t& callable)
{
callable();
}
#endif // ! LL_WINDOWS
} // anonymous namespace
// Top-level wrapper around caller's coroutine callable.
// Normally we like to pass strings and such by const reference -- but in this
// case, we WANT to copy both the name and the callable to our local stack!
void LLCoros::toplevel(std::string name, callable_t callable)
{ {
// keep the CoroData on this top-level function's stack frame // keep the CoroData on this top-level function's stack frame
CoroData corodata(name); CoroData corodata(name);
@ -349,12 +349,12 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call
// run the code the caller actually wants in the coroutine // run the code the caller actually wants in the coroutine
try try
{ {
callable(); sehandle(callable);
} }
catch (const Stop& exc) catch (const Stop& exc)
{ {
LL_INFOS("LLCoros") << "coroutine " << name << " terminating because " LL_INFOS("LLCoros") << "coroutine " << name << " terminating because "
<< exc.what() << LL_ENDL; << exc.what() << LL_ENDL;
} }
catch (const LLContinueError&) catch (const LLContinueError&)
{ {
@ -365,36 +365,14 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call
} }
catch (...) catch (...)
{ {
#if LL_WINDOWS
// Any OTHER kind of uncaught exception will cause the viewer to
// crash, SEH handling should catch it and report to bugsplat.
LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
// to not modify callstack
throw;
#else
// Stash any OTHER kind of uncaught exception in the rethrow() queue // Stash any OTHER kind of uncaught exception in the rethrow() queue
// to be rethrown by the main fiber. // to be rethrown by the main fiber.
LL_WARNS("LLCoros") << "Capturing uncaught exception in coroutine " LL_WARNS("LLCoros") << "Capturing uncaught exception in coroutine "
<< name << LL_ENDL; << name << LL_ENDL;
LLCoros::instance().saveException(name, std::current_exception()); LLCoros::instance().saveException(name, std::current_exception());
#endif
} }
} }
// Top-level wrapper around caller's coroutine callable.
// Normally we like to pass strings and such by const reference -- but in this
// case, we WANT to copy both the name and the callable to our local stack!
void LLCoros::toplevel(std::string name, callable_t callable)
{
#if LL_WINDOWS
// Because SEH can's have unwinding, need to call a wrapper
// 'try' is inside SEH handling to not catch LLContinue
sehHandle(name, callable);
#else
toplevelTryWrapper(name, callable);
#endif
}
//static //static
void LLCoros::checkStop() void LLCoros::checkStop()
{ {

View File

@ -307,11 +307,7 @@ public:
private: private:
std::string generateDistinctName(const std::string& prefix) const; std::string generateDistinctName(const std::string& prefix) const;
void toplevelTryWrapper(const std::string& name, const callable_t& callable); void toplevel(std::string name, callable_t callable);
#if LL_WINDOWS
void sehHandle(const std::string& name, const callable_t& callable); // calls toplevelTryWrapper
#endif
void toplevel(std::string name, callable_t callable); // calls sehHandle or toplevelTryWrapper
struct CoroData; struct CoroData;
static CoroData& get_CoroData(const std::string& caller); static CoroData& get_CoroData(const std::string& caller);
void saveException(const std::string& name, std::exception_ptr exc); void saveException(const std::string& name, std::exception_ptr exc);

View File

@ -954,7 +954,7 @@ namespace LLError
for (a = sets.beginArray(), end = sets.endArray(); a != end; ++a) for (a = sets.beginArray(), end = sets.endArray(); a != end; ++a)
{ {
const LLSD& entry = *a; const LLSD& entry = *a;
if (entry.isMap() && !entry.emptyMap()) if (entry.isMap() && entry.size() != 0)
{ {
ELevel level = decodeLevel(entry["level"]); ELevel level = decodeLevel(entry["level"]);

View File

@ -34,10 +34,9 @@
#include <iostream> #include <iostream>
#include "apr_base64.h" #include "apr_base64.h"
// <FS:Beq pp Rye> Add non-allocating variants of unzip_llsd
#include <boost/iostreams/device/array.hpp> #include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp> #include <boost/iostreams/stream.hpp>
// </FS:Beq pp Rye>
#ifdef LL_USESYSTEMLIBS #ifdef LL_USESYSTEMLIBS
# include <zlib.h> # include <zlib.h>
#else #else
@ -2132,8 +2131,8 @@ std::string zip_llsd(LLSD& data)
{ //copy result into output { //copy result into output
if (strm.avail_out >= CHUNK) if (strm.avail_out >= CHUNK)
{ {
// free(output); deflateEnd(&strm);
if( output ) if(output)
free(output); free(output);
LL_WARNS() << "Failed to compress LLSD block." << LL_ENDL; LL_WARNS() << "Failed to compress LLSD block." << LL_ENDL;
return std::string(); return std::string();
@ -2157,8 +2156,8 @@ std::string zip_llsd(LLSD& data)
} }
else else
{ {
// free(output); deflateEnd(&strm);
if( output ) if(output)
free(output); free(output);
LL_WARNS() << "Failed to compress LLSD block." << LL_ENDL; LL_WARNS() << "Failed to compress LLSD block." << LL_ENDL;
return std::string(); return std::string();
@ -2170,8 +2169,7 @@ std::string zip_llsd(LLSD& data)
std::string result((char*) output, size); std::string result((char*) output, size);
deflateEnd(&strm); deflateEnd(&strm);
// free(output); if(output)
if( output )
free(output); free(output);
return result; return result;
@ -2182,148 +2180,8 @@ std::string zip_llsd(LLSD& data)
// and deserializes from that copy using LLSDSerialize // and deserializes from that copy using LLSDSerialize
LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is, S32 size) LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is, S32 size)
{ {
// <FS:Beq pp Rye> Add non-allocating variants of unzip_llsd std::unique_ptr<U8[]> in = std::unique_ptr<U8[]>(new(std::nothrow) U8[size]);
// U8* result = NULL; if (!in)
// llssize cur_size = 0;
// z_stream strm;
// const U32 CHUNK = 65536;
// U8 *in = new(std::nothrow) U8[size];
// if (!in)
// {
// return ZR_MEM_ERROR;
// }
// is.read((char*) in, size);
// U8 out[CHUNK];
// strm.zalloc = Z_NULL;
// strm.zfree = Z_NULL;
// strm.opaque = Z_NULL;
// strm.avail_in = size;
// strm.next_in = in;
// S32 ret = inflateInit(&strm);
// do
// {
// strm.avail_out = CHUNK;
// strm.next_out = out;
// ret = inflate(&strm, Z_NO_FLUSH);
// if (ret == Z_STREAM_ERROR)
// {
// LL_DEBUGS() << "Unzip error: Z_STREAM_ERROR" << LL_ENDL; // <FS>
// inflateEnd(&strm);
// // free(result);
// if( result )
// free(result);
// delete [] in;
// return ZR_DATA_ERROR;
// }
// switch (ret)
// {
// case Z_NEED_DICT:
// ret = Z_DATA_ERROR;
// case Z_DATA_ERROR:
// case Z_MEM_ERROR:
// LL_DEBUGS() << "Unzip error: " << ret << LL_ENDL; // <FS>
// inflateEnd(&strm);
// // free(result);
// if( result )
// free(result);
// delete [] in;
// return ZR_MEM_ERROR;
// break;
// }
// U32 have = CHUNK-strm.avail_out;
// U8* new_result = (U8*)realloc(result, cur_size + have);
// if (new_result == NULL)
// {
// inflateEnd(&strm);
// if (result)
// {
// free(result);
// }
// delete[] in;
// return ZR_MEM_ERROR;
// }
// result = new_result;
// memcpy(result+cur_size, out, have);
// cur_size += have;
// } while (ret == Z_OK);
// inflateEnd(&strm);
// delete [] in;
// if (ret != Z_STREAM_END)
// {
// LL_DEBUGS() << "Unzip error: !Z_STREAM_END" << LL_ENDL; // <FS>
// // free(result);
// if( result )
// free(result);
// return ZR_DATA_ERROR;
// }
// //result now points to the decompressed LLSD block
// {
// std::istringstream istr;
// // Since we are using this for meshes, data we are dealing with tend to be large.
// // So string can potentially fail to allocate, make sure this won't cause problems
// try
// {
// std::string res_str((char*)result, cur_size);
// std::string deprecated_header("<? LLSD/Binary ?>");
// if (res_str.substr(0, deprecated_header.size()) == deprecated_header)
// {
// res_str = res_str.substr(deprecated_header.size() + 1, cur_size);
// }
// cur_size = res_str.size();
// istr.str(res_str);
// }
// #ifdef LL_WINDOWS
// catch (std::length_error)
// {
// // free(result);
// if( result )
// free(result);
// return ZR_SIZE_ERROR;
// }
// #endif
// catch (std::bad_alloc&)
// {
// // free(result);
// if( result )
// free(result);
// return ZR_MEM_ERROR;
// }
// if (!LLSDSerialize::fromBinary(data, istr, cur_size, UNZIP_LLSD_MAX_DEPTH))
// {
// // free(result);
// if( result )
// free(result);
// return ZR_PARSE_ERROR;
// }
// }
// // free(result);
// if( result )
// free(result);
// return ZR_OK;
std::unique_ptr<U8[]> in;
try
{
in = std::unique_ptr<U8[]>(new U8[size]);
}
catch(const std::bad_alloc&)
{ {
return ZR_MEM_ERROR; return ZR_MEM_ERROR;
} }
@ -2338,19 +2196,12 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, const U8* in, S32
llssize cur_size = 0; llssize cur_size = 0;
z_stream strm; z_stream strm;
constexpr U32 CHUNK = 1024 * 256; constexpr U32 CHUNK = 1024 * 512;
static thread_local std::unique_ptr<U8[]> out; static thread_local std::unique_ptr<U8[]> out;
if (!out) if (!out)
{ {
try out = std::unique_ptr<U8[]>(new(std::nothrow) U8[CHUNK]);
{
out = std::unique_ptr<U8[]>(new U8[CHUNK]);
}
catch (const std::bad_alloc&)
{
return ZR_MEM_ERROR;
}
} }
strm.zalloc = Z_NULL; strm.zalloc = Z_NULL;
@ -2360,15 +2211,6 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, const U8* in, S32
strm.next_in = const_cast<U8*>(in); strm.next_in = const_cast<U8*>(in);
S32 ret = inflateInit(&strm); S32 ret = inflateInit(&strm);
switch (ret)
{
case Z_STREAM_ERROR:
return ZR_DATA_ERROR;
case Z_VERSION_ERROR:
return ZR_VERSION_ERROR;
case Z_MEM_ERROR:
return ZR_MEM_ERROR;
}
do do
{ {
@ -2381,7 +2223,9 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, const U8* in, S32
case Z_DATA_ERROR: case Z_DATA_ERROR:
{ {
inflateEnd(&strm); inflateEnd(&strm);
free(result); // free(result);
if( result )
free(result);
return ZR_DATA_ERROR; return ZR_DATA_ERROR;
} }
case Z_STREAM_ERROR: case Z_STREAM_ERROR:
@ -2395,7 +2239,9 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, const U8* in, S32
case Z_MEM_ERROR: case Z_MEM_ERROR:
{ {
inflateEnd(&strm); inflateEnd(&strm);
free(result); // free(result);
if( result )
free(result);
return ZR_MEM_ERROR; return ZR_MEM_ERROR;
} }
} }
@ -2422,7 +2268,9 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, const U8* in, S32
if (ret != Z_STREAM_END) if (ret != Z_STREAM_END)
{ {
free(result); // free(result);
if( result )
free(result);
return ZR_DATA_ERROR; return ZR_DATA_ERROR;
} }
@ -2434,134 +2282,138 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, const U8* in, S32
if (!LLSDSerialize::fromBinary(data, istrm, cur_size, UNZIP_LLSD_MAX_DEPTH)) if (!LLSDSerialize::fromBinary(data, istrm, cur_size, UNZIP_LLSD_MAX_DEPTH))
{ {
free(result); // free(result);
if( result )
free(result);
return ZR_PARSE_ERROR; return ZR_PARSE_ERROR;
} }
} }
free(result); // free(result);
if( result )
free(result);
return ZR_OK; return ZR_OK;
} }
// </FS:Beq pp Rye> // </FS:Beq pp Rye>
//This unzip function will only work with a gzip header and trailer - while the contents //This unzip function will only work with a gzip header and trailer - while the contents
//of the actual compressed data is the same for either format (gzip vs zlib ), the headers //of the actual compressed data is the same for either format (gzip vs zlib ), the headers
//and trailers are different for the formats. //and trailers are different for the formats.
U8* unzip_llsdNavMesh( bool& valid, size_t& outsize, std::istream& is, S32 size ) U8* unzip_llsdNavMesh(bool& valid, unsigned int& outsize, std::istream& is, S32 size)
{ {
// <FS:Beq pp Rye> Add non-allocating variants of unzip_llsd // <FS:Beq pp Rye> Add non-allocating variants of unzip_llsd
// if (size == 0) // if (size == 0)
// { // {
// LL_WARNS() << "No data to unzip." << LL_ENDL; // LL_WARNS() << "No data to unzip." << LL_ENDL;
// return NULL; // return NULL;
// } // }
// U8* result = NULL; // U8* result = NULL;
// U32 cur_size = 0; // U32 cur_size = 0;
// z_stream strm; // z_stream strm;
// const U32 CHUNK = 0x4000; // const U32 CHUNK = 0x4000;
// U8 *in = new(std::nothrow) U8[size]; // U8 *in = new(std::nothrow) U8[size];
// if (in == NULL) // if (in == NULL)
// { // {
// LL_WARNS() << "Memory allocation failure." << LL_ENDL; // LL_WARNS() << "Memory allocation failure." << LL_ENDL;
// return NULL; // return NULL;
// } // }
// is.read((char*) in, size); // is.read((char*) in, size);
// U8 out[CHUNK]; // U8 out[CHUNK];
// strm.zalloc = Z_NULL; // strm.zalloc = Z_NULL;
// strm.zfree = Z_NULL; // strm.zfree = Z_NULL;
// strm.opaque = Z_NULL; // strm.opaque = Z_NULL;
// strm.avail_in = size; // strm.avail_in = size;
// strm.next_in = in; // strm.next_in = in;
// valid = true; // <FS:ND/> Default is all okay. // valid = true; // <FS:ND/> Default is all okay.
// S32 ret = inflateInit2(&strm, windowBits | ENABLE_ZLIB_GZIP ); // S32 ret = inflateInit2(&strm, windowBits | ENABLE_ZLIB_GZIP );
// do // do
// { // {
// strm.avail_out = CHUNK; // strm.avail_out = CHUNK;
// strm.next_out = out; // strm.next_out = out;
// ret = inflate(&strm, Z_NO_FLUSH); // ret = inflate(&strm, Z_NO_FLUSH);
// if (ret == Z_STREAM_ERROR) // if (ret == Z_STREAM_ERROR)
// { // {
// inflateEnd(&strm); // inflateEnd(&strm);
// // free(result); // // free(result);
// if( result ) // if( result )
// free(result); // free(result);
// delete [] in; // delete [] in;
// in = NULL; result = NULL;// <FS:ND> Or we get a double free aftr the while loop ... // in = NULL; result = NULL;// <FS:ND> Or we get a double free aftr the while loop ...
// valid = false; // valid = false;
// } // }
// switch (ret) // switch (ret)
// { // {
// case Z_NEED_DICT: // case Z_NEED_DICT:
// ret = Z_DATA_ERROR; // ret = Z_DATA_ERROR;
// case Z_DATA_ERROR: // case Z_DATA_ERROR:
// case Z_MEM_ERROR: // case Z_MEM_ERROR:
// inflateEnd(&strm); // inflateEnd(&strm);
// // free(result); // // free(result);
// if( result ) // if( result )
// free(result); // free(result);
// delete [] in; // delete [] in;
// valid = false; // valid = false;
// in = NULL; result = NULL;// <FS:ND> Or we get a double free aftr the while loop ... // in = NULL; result = NULL;// <FS:ND> Or we get a double free aftr the while loop ...
// break; // break;
// } // }
// if( valid ) {// <FS:ND> in case this stream is invalid, do not pass the already freed buffer to realloc. // if( valid ) {// <FS:ND> in case this stream is invalid, do not pass the already freed buffer to realloc.
// U32 have = CHUNK-strm.avail_out; // U32 have = CHUNK-strm.avail_out;
// U8* new_result = (U8*) realloc(result, cur_size + have); // U8* new_result = (U8*) realloc(result, cur_size + have);
// if (new_result == NULL) // if (new_result == NULL)
// { // {
// LL_WARNS() << "Failed to unzip LLSD NavMesh block: can't reallocate memory, current size: " << cur_size // LL_WARNS() << "Failed to unzip LLSD NavMesh block: can't reallocate memory, current size: " << cur_size
// << " bytes; requested " << cur_size + have // << " bytes; requested " << cur_size + have
// << " bytes; total syze: ." << size << " bytes." // << " bytes; total syze: ." << size << " bytes."
// << LL_ENDL; // << LL_ENDL;
// inflateEnd(&strm); // inflateEnd(&strm);
// if (result) // if (result)
// { // {
// free(result); // free(result);
// } // }
// delete[] in; // delete[] in;
// valid = false; // valid = false;
// return NULL; // return NULL;
// } // }
// result = new_result; // result = new_result;
// memcpy(result+cur_size, out, have); // memcpy(result+cur_size, out, have);
// cur_size += have; // cur_size += have;
// } // </FS:ND> // } // </FS:ND>
// } while (ret == Z_OK); // } while (ret == Z_OK);
// inflateEnd(&strm); // inflateEnd(&strm);
// delete [] in; // delete [] in;
// if (ret != Z_STREAM_END) // if (ret != Z_STREAM_END)
// { // {
// // <FS:ND> result might have been freed above. And calling free with a null pointer is not defined. // // <FS:ND> result might have been freed above. And calling free with a null pointer is not defined.
// // free(result); // // free(result);
// if( result ) // if( result )
// free(result); // free(result);
// // </FS:ND> // // </FS:ND>
// valid = false; // valid = false;
// return NULL; // return NULL;
// } // }
// //result now points to the decompressed LLSD block // //result now points to the decompressed LLSD block
// { // {
// outsize= cur_size; // outsize= cur_size;
// valid = true; // valid = true;
// } // }
// return result; // return result;
// } // }
if (size == 0) if (size == 0)
{ {
LL_WARNS() << "No data to unzip." << LL_ENDL; LL_WARNS() << "No data to unzip." << LL_ENDL;
@ -2578,18 +2430,18 @@ U8* unzip_llsdNavMesh( bool& valid, size_t& outsize, std::istream& is, S32 size
return nullptr; return nullptr;
} }
is.read((char*) in.get(), size); is.read((char*)in.get(), size);
return unzip_llsdNavMesh(valid, outsize, in.get(), size); return unzip_llsdNavMesh(valid, outsize, in.get(), size);
} }
U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, const U8* in, S32 size ) U8* unzip_llsdNavMesh(bool& valid, unsigned int& outsize, const U8* in, S32 size)
{ {
if (size == 0) if (size == 0)
{ {
LL_WARNS() << "No data to unzip." << LL_ENDL; LL_WARNS() << "No data to unzip." << LL_ENDL;
return nullptr; return nullptr;
} }
U8* result = NULL; U8* result = nullptr;
U32 cur_size = 0; U32 cur_size = 0;
z_stream strm; z_stream strm;
@ -2604,7 +2456,7 @@ U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, const U8* in, S32 siz
strm.next_in = const_cast<U8*>(in); strm.next_in = const_cast<U8*>(in);
S32 ret = inflateInit2(&strm, windowBits | ENABLE_ZLIB_GZIP ); S32 ret = inflateInit2(&strm, windowBits | ENABLE_ZLIB_GZIP);
do do
{ {
strm.avail_out = CHUNK; strm.avail_out = CHUNK;
@ -2614,26 +2466,26 @@ U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, const U8* in, S32 siz
{ {
inflateEnd(&strm); inflateEnd(&strm);
free(result); free(result);
return NULL; return nullptr;
} }
switch (ret) switch (ret)
{ {
case Z_NEED_DICT: case Z_NEED_DICT:
ret = Z_DATA_ERROR; ret = Z_DATA_ERROR;
// [[fallthrough]]; // <FS:Beq> TODO when we have C++17 compilation. [[fallthrough]];
case Z_DATA_ERROR: case Z_DATA_ERROR:
case Z_MEM_ERROR: case Z_MEM_ERROR:
inflateEnd(&strm); inflateEnd(&strm);
free(result); free(result);
valid = false; valid = false;
return NULL; return nullptr;
} }
U32 have = CHUNK-strm.avail_out; U32 have = CHUNK - strm.avail_out;
U8* new_result = (U8*) realloc(result, cur_size + have); U8* new_result = (U8*)realloc(result, cur_size + have);
if (new_result == NULL) if (!new_result)
{ {
LL_WARNS() << "Failed to unzip LLSD NavMesh block: can't reallocate memory, current size: " << cur_size LL_WARNS() << "Failed to unzip LLSD NavMesh block: can't reallocate memory, current size: " << cur_size
<< " bytes; requested " << cur_size + have << " bytes; requested " << cur_size + have
@ -2645,10 +2497,10 @@ U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, const U8* in, S32 siz
free(result); free(result);
} }
valid = false; valid = false;
return NULL; return nullptr;
} }
result = new_result; result = new_result;
memcpy(result+cur_size, out, have); memcpy(result + cur_size, out, have);
cur_size += have; cur_size += have;
} while (ret == Z_OK); } while (ret == Z_OK);
@ -2659,17 +2511,18 @@ U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, const U8* in, S32 siz
{ {
free(result); free(result);
valid = false; valid = false;
return NULL; return nullptr;
} }
//result now points to the decompressed LLSD block //result now points to the decompressed LLSD block
{ {
outsize= cur_size; outsize = cur_size;
valid = true; valid = true;
} }
return result; return result;
} }
// </FS:Beq pp Rye>
char* strip_deprecated_header(char* in, llssize& cur_size, llssize* header_size) char* strip_deprecated_header(char* in, llssize& cur_size, llssize* header_size)
{ {
@ -2689,4 +2542,4 @@ char* strip_deprecated_header(char* in, llssize& cur_size, llssize* header_size)
return in; return in;
} }
// </FS:Beq pp Rye>

View File

@ -858,14 +858,12 @@ public:
ZR_SIZE_ERROR, ZR_SIZE_ERROR,
ZR_DATA_ERROR, ZR_DATA_ERROR,
ZR_PARSE_ERROR, ZR_PARSE_ERROR,
// <FS:Beq pp Rye> Add non-allocating variants of unzip_llsd ZR_BUFFER_ERROR,
ZR_BUFFER_ERROR, ZR_VERSION_ERROR
ZR_VERSION_ERROR
// </FS:Beq>
} EZipRresult; } EZipRresult;
// return OK or reason for failure // return OK or reason for failure
static EZipRresult unzip_llsd(LLSD& data, std::istream& is, S32 size); static EZipRresult unzip_llsd(LLSD& data, std::istream& is, S32 size);
static EZipRresult unzip_llsd(LLSD& data, const U8* in, S32 size); // <FS:Beq pp Rye/> Add non-allocating variants of unzip_llsd static EZipRresult unzip_llsd(LLSD& data, const U8* in, S32 size);
}; };
//dirty little zip functions -- yell at davep //dirty little zip functions -- yell at davep
@ -878,5 +876,4 @@ LL_COMMON_API U8* unzip_llsdNavMesh(bool& valid, unsigned int& outsize, const U8
// returns a pointer to the array or past the array if the deprecated header exists // returns a pointer to the array or past the array if the deprecated header exists
LL_COMMON_API char* strip_deprecated_header(char* in, llssize& cur_size, llssize* header_size = nullptr); LL_COMMON_API char* strip_deprecated_header(char* in, llssize& cur_size, llssize* header_size = nullptr);
// </FS:Beq>
#endif // LL_LLSDSERIALIZE_H #endif // LL_LLSDSERIALIZE_H

View File

@ -1027,44 +1027,6 @@ LLUUID::LLUUID()
// </FS> // </FS>
} }
// Copy constructor
LLUUID::LLUUID(const LLUUID& rhs)
{
LL_PROFILE_ZONE_SCOPED;
// <FS> Fix for misaligned unsigned ints in LLUUID; by Sovereign Engineer / Shyotl Kuhr
//U32 *tmp = (U32 *)mData;
//U32 *rhstmp = (U32 *)rhs.mData;
//tmp[0] = rhstmp[0];
//tmp[1] = rhstmp[1];
//tmp[2] = rhstmp[2];
//tmp[3] = rhstmp[3];
memcpy(mData, rhs.mData, sizeof(mData));
// </FS>
}
LLUUID::~LLUUID()
{
}
// Assignment
LLUUID& LLUUID::operator=(const LLUUID& rhs)
{
LL_PROFILE_ZONE_SCOPED;
// <FS> Fix for misaligned unsigned ints in LLUUID; by Sovereign Engineer / Shyotl Kuhr
//// No need to check the case where this==&rhs. The branch is slower than the write.
//U32 *tmp = (U32 *)mData;
//U32 *rhstmp = (U32 *)rhs.mData;
//tmp[0] = rhstmp[0];
//tmp[1] = rhstmp[1];
//tmp[2] = rhstmp[2];
//tmp[3] = rhstmp[3];
memcpy(mData, rhs.mData, sizeof(mData));
// </FS>
return *this;
}
LLUUID::LLUUID(const char *in_string) LLUUID::LLUUID(const char *in_string)
{ {
if (!in_string || in_string[0] == 0) if (!in_string || in_string[0] == 0)

View File

@ -29,11 +29,10 @@
#include <iostream> #include <iostream>
#include <set> #include <set>
#include <vector> #include <vector>
#include <cstring> // <FS:Beq> for std::memmove
#include "stdtypes.h" #include "stdtypes.h"
#include "llpreprocessor.h" #include "llpreprocessor.h"
#include <boost/functional/hash.hpp> #include <boost/functional/hash.hpp>
#include "llprofiler.h"
class LLMutex; class LLMutex;
const S32 UUID_BYTES = 16; const S32 UUID_BYTES = 16;
@ -56,12 +55,7 @@ public:
LLUUID(); LLUUID();
explicit LLUUID(const char *in_string); // Convert from string. explicit LLUUID(const char *in_string); // Convert from string.
explicit LLUUID(const std::string& in_string); // Convert from string. explicit LLUUID(const std::string& in_string); // Convert from string.
LLUUID(const LLUUID &in); ~LLUUID() = default;
LLUUID(LLUUID&& rhs) noexcept { LL_PROFILE_ZONE_SCOPED; std::memmove(mData, rhs.mData, sizeof(mData));};
LLUUID &operator=(const LLUUID &rhs);
LLUUID &operator=(LLUUID &&rhs) noexcept { LL_PROFILE_ZONE_SCOPED; std::memmove(mData, rhs.mData, sizeof(mData));return *this;};
~LLUUID();
// //
// MANIPULATORS // MANIPULATORS
@ -189,6 +183,9 @@ public:
U8 mData[UUID_BYTES]; U8 mData[UUID_BYTES];
}; };
static_assert(std::is_trivially_copyable<LLUUID>::value, "LLUUID must be trivial copy");
static_assert(std::is_trivially_move_assignable<LLUUID>::value, "LLUUID must be trivial move");
static_assert(std::is_standard_layout<LLUUID>::value, "LLUUID must be a standard layout type");
typedef std::vector<LLUUID> uuid_vec_t; typedef std::vector<LLUUID> uuid_vec_t;
typedef std::set<LLUUID> uuid_set_t; typedef std::set<LLUUID> uuid_set_t;

View File

@ -248,8 +248,6 @@ namespace LL
TimePoint until = TimePoint::clock::now() + std::chrono::hours(24); TimePoint until = TimePoint::clock::now() + std::chrono::hours(24);
pop_result popped = tryPopUntil_(lock, until, tt); pop_result popped = tryPopUntil_(lock, until, tt);
if (popped == POPPED) if (popped == POPPED)
// <FS:Ansariel> Prevent RVO elision
//return std::move(tt);
return tt; return tt;
// DONE: throw, just as super::pop() does // DONE: throw, just as super::pop() does

View File

@ -66,16 +66,16 @@ LLDir_Mac::LLDir_Mac()
const std::string secondLifeString = "Firestorm"; const std::string secondLifeString = "Firestorm";
std::string *executablepathstr = getSystemExecutableFolder(); std::string executablepathstr = getSystemExecutableFolder();
//NOTE: LLINFOS/LLERRS will not output to log here. The streams are not initialized. //NOTE: LLINFOS/LLERRS will not output to log here. The streams are not initialized.
if (executablepathstr) if (!executablepathstr.empty())
{ {
// mExecutablePathAndName // mExecutablePathAndName
mExecutablePathAndName = *executablepathstr; mExecutablePathAndName = executablepathstr;
boost::filesystem::path executablepath(*executablepathstr); boost::filesystem::path executablepath(executablepathstr);
# ifndef BOOST_SYSTEM_NO_DEPRECATED # ifndef BOOST_SYSTEM_NO_DEPRECATED
#endif #endif
@ -83,8 +83,8 @@ LLDir_Mac::LLDir_Mac()
mExecutableDir = executablepath.parent_path().string(); mExecutableDir = executablepath.parent_path().string();
// mAppRODataDir // mAppRODataDir
std::string *resourcepath = getSystemResourceFolder(); std::string resourcepath = getSystemResourceFolder();
mAppRODataDir = *resourcepath; mAppRODataDir = resourcepath;
// *NOTE: When running in a dev tree, use the copy of // *NOTE: When running in a dev tree, use the copy of
// skins in indra/newview/ rather than in the application bundle. This // skins in indra/newview/ rather than in the application bundle. This
@ -110,11 +110,11 @@ LLDir_Mac::LLDir_Mac()
} }
// mOSUserDir // mOSUserDir
std::string *appdir = getSystemApplicationSupportFolder(); std::string appdir = getSystemApplicationSupportFolder();
std::string rootdir; std::string rootdir;
//Create root directory //Create root directory
if (CreateDirectory(*appdir, secondLifeString, &rootdir)) if (CreateDirectory(appdir, secondLifeString, &rootdir))
{ {
// Save the full path to the folder // Save the full path to the folder
@ -128,12 +128,10 @@ LLDir_Mac::LLDir_Mac()
} }
//mOSCacheDir //mOSCacheDir
std::string *cachedir = getSystemCacheFolder(); std::string cachedir = getSystemCacheFolder();
if (!cachedir.empty())
if (cachedir)
{ {
mOSCacheDir = *cachedir; mOSCacheDir = cachedir;
//TODO: This changes from ~/Library/Cache/Secondlife to ~/Library/Cache/com.app.secondlife/Secondlife. Last dir level could go away. //TODO: This changes from ~/Library/Cache/Secondlife to ~/Library/Cache/com.app.secondlife/Secondlife. Last dir level could go away.
//<FS:TS> Adjust the cache directory to match what's expected in lldir. //<FS:TS> Adjust the cache directory to match what's expected in lldir.
//CreateDirectory(mOSCacheDir, secondLifeString, NULL); //CreateDirectory(mOSCacheDir, secondLifeString, NULL);
@ -159,12 +157,10 @@ LLDir_Mac::LLDir_Mac()
// mTempDir // mTempDir
//Aura 120920 boost::filesystem::temp_directory_path() not yet implemented on mac. :( //Aura 120920 boost::filesystem::temp_directory_path() not yet implemented on mac. :(
std::string *tmpdir = getSystemTempFolder(); std::string tmpdir = getSystemTempFolder();
if (tmpdir) if (!tmpdir.empty())
{ {
CreateDirectory(tmpdir, secondLifeString, &mTempDir);
CreateDirectory(*tmpdir, secondLifeString, &mTempDir);
if (tmpdir) delete tmpdir;
} }
mWorkingDir = getCurPath(); mWorkingDir = getCurPath();

View File

@ -33,11 +33,11 @@
#include <iostream> #include <iostream>
std::string* getSystemTempFolder(); std::string getSystemTempFolder();
std::string* getSystemCacheFolder(); std::string getSystemCacheFolder();
std::string* getSystemApplicationSupportFolder(); std::string getSystemApplicationSupportFolder();
std::string* getSystemResourceFolder(); std::string getSystemResourceFolder();
std::string* getSystemExecutableFolder(); std::string getSystemExecutableFolder();
#endif // LL_LLDIR_UTILS_OBJC_H #endif // LL_LLDIR_UTILS_OBJC_H

View File

@ -30,75 +30,75 @@
#include "lldir_utils_objc.h" #include "lldir_utils_objc.h"
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
std::string* getSystemTempFolder() std::string getSystemTempFolder()
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; std::string result;
NSString * tempDir = NSTemporaryDirectory(); @autoreleasepool {
if (tempDir == nil) NSString * tempDir = NSTemporaryDirectory();
tempDir = @"/tmp"; if (tempDir == nil)
std::string *result = ( new std::string([tempDir UTF8String]) ); tempDir = @"/tmp";
[pool release]; result = std::string([tempDir UTF8String]);
}
return result; return result;
} }
//findSystemDirectory scoped exclusively to this file. //findSystemDirectory scoped exclusively to this file.
std::string* findSystemDirectory(NSSearchPathDirectory searchPathDirectory, std::string findSystemDirectory(NSSearchPathDirectory searchPathDirectory,
NSSearchPathDomainMask domainMask) NSSearchPathDomainMask domainMask)
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; std::string result;
@autoreleasepool {
NSString *path = nil;
std::string *result = nil; // Search for the path
NSString *path = nil; NSArray* paths = NSSearchPathForDirectoriesInDomains(searchPathDirectory,
domainMask,
YES);
if ([paths count])
{
path = [paths objectAtIndex:0];
//HACK: Always attempt to create directory, ignore errors.
NSError *error = nil;
// Search for the path [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error];
NSArray* paths = NSSearchPathForDirectoriesInDomains(searchPathDirectory,
domainMask,
YES);
if ([paths count])
{
path = [paths objectAtIndex:0];
//HACK: Always attempt to create directory, ignore errors.
NSError *error = nil;
[[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error];
result = new std::string([path UTF8String]); result = std::string([path UTF8String]);
}
} }
[pool release];
return result; return result;
} }
std::string* getSystemExecutableFolder() std::string getSystemExecutableFolder()
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; std::string result;
@autoreleasepool {
NSString *bundlePath = [[NSBundle mainBundle] executablePath]; NSString *bundlePath = [[NSBundle mainBundle] executablePath];
std::string *result = (new std::string([bundlePath UTF8String])); result = std::string([bundlePath UTF8String]);
[pool release]; }
return result; return result;
} }
std::string* getSystemResourceFolder() std::string getSystemResourceFolder()
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; std::string result;
@autoreleasepool {
NSString *bundlePath = [[NSBundle mainBundle] resourcePath]; NSString *bundlePath = [[NSBundle mainBundle] resourcePath];
std::string *result = (new std::string([bundlePath UTF8String])); result = std::string([bundlePath UTF8String]);
[pool release]; }
return result; return result;
} }
std::string* getSystemCacheFolder() std::string getSystemCacheFolder()
{ {
return findSystemDirectory (NSCachesDirectory, return findSystemDirectory (NSCachesDirectory,
NSUserDomainMask); NSUserDomainMask);
} }
std::string* getSystemApplicationSupportFolder() std::string getSystemApplicationSupportFolder()
{ {
return findSystemDirectory (NSApplicationSupportDirectory, return findSystemDirectory (NSApplicationSupportDirectory,
NSUserDomainMask); NSUserDomainMask);

View File

@ -257,12 +257,7 @@ void LLPngWrapper::normalizeImage()
png_set_strip_16(mReadPngPtr); png_set_strip_16(mReadPngPtr);
} }
#if LL_DARWIN
const F64 SCREEN_GAMMA = 1.8;
#else
const F64 SCREEN_GAMMA = 2.2; const F64 SCREEN_GAMMA = 2.2;
#endif
if (png_get_gAMA(mReadPngPtr, mReadInfoPtr, &mGamma)) if (png_get_gAMA(mReadPngPtr, mReadInfoPtr, &mGamma))
{ {
png_set_gamma(mReadPngPtr, SCREEN_GAMMA, mGamma); png_set_gamma(mReadPngPtr, SCREEN_GAMMA, mGamma);

File diff suppressed because it is too large Load Diff

View File

@ -2406,13 +2406,12 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL; LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL;
return false; return false;
} }
// <FS:Beq pp Rye> Add non-allocating variants of of unpackVolumeFaces
return unpackVolumeFacesInternal(mdl); return unpackVolumeFacesInternal(mdl);
} }
bool LLVolume::unpackVolumeFaces(U8* in_data, S32 size) bool LLVolume::unpackVolumeFaces(U8* in_data, S32 size)
{ {
//input stream is now pointing at a zlib compressed block of LLSD //input data is now pointing at a zlib compressed block of LLSD
//decompress block //decompress block
LLSD mdl; LLSD mdl;
U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, in_data, size); U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, in_data, size);
@ -2426,7 +2425,6 @@ bool LLVolume::unpackVolumeFaces(U8* in_data, S32 size)
bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl) bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
{ {
// </FS:Beq pp Rye>
{ {
U32 face_count = mdl.size(); U32 face_count = mdl.size();

View File

@ -1113,14 +1113,12 @@ protected:
BOOL generate(); BOOL generate();
void createVolumeFaces(); void createVolumeFaces();
public: public:
virtual bool unpackVolumeFaces(std::istream& is, S32 size); bool unpackVolumeFaces(std::istream& is, S32 size);
// <FS:Beq pp Rye> Add non-allocating variants of of unpackVolumeFaces
bool unpackVolumeFaces(U8* in_data, S32 size); bool unpackVolumeFaces(U8* in_data, S32 size);
private: private:
bool unpackVolumeFacesInternal(const LLSD& mdl); bool unpackVolumeFacesInternal(const LLSD& mdl);
public: public:
// </FS:Beq pp Rye>
virtual void setMeshAssetLoaded(BOOL loaded); virtual void setMeshAssetLoaded(BOOL loaded);
virtual BOOL isMeshAssetLoaded(); virtual BOOL isMeshAssetLoaded();

View File

@ -754,14 +754,13 @@ BOOL LLDataPackerAsciiBuffer::packString(const std::string& value, const char *n
BOOL LLDataPackerAsciiBuffer::unpackString(std::string& value, const char *name) BOOL LLDataPackerAsciiBuffer::unpackString(std::string& value, const char *name)
{ {
BOOL success = TRUE;
char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/ char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/
if (!getValueStr(name, valuestr, DP_BUFSIZE)) // NULL terminated if (!getValueStr(name, valuestr, DP_BUFSIZE)) // NULL terminated
{ {
return FALSE; return FALSE;
} }
value = valuestr; value = valuestr;
return success; return TRUE;
} }

View File

@ -482,7 +482,7 @@ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataou
apr_size_t expected_len = outlen; apr_size_t expected_len = outlen;
handle->setBlocking(1000); handle->setBlocking(100000); // <FS:Beq/> extend the arbitrary timeout value to 100ms. this should be more than enough for most LAN proxies and plenty for a localhost
rv = apr_socket_send(apr_socket, dataout, &outlen); rv = apr_socket_send(apr_socket, dataout, &outlen);
if (APR_SUCCESS != rv) if (APR_SUCCESS != rv)
@ -498,7 +498,7 @@ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataou
rv = -1; rv = -1;
} }
ms_sleep(1); // ms_sleep(1); // <FS:Beq/> remove the unnecessary sleep.
if (APR_SUCCESS == rv) if (APR_SUCCESS == rv)
{ {

View File

@ -92,7 +92,7 @@ namespace tut
Sync sync; Sync sync;
int foo = 0; int foo = 0;
LLCoprocedureManager::instance().initializePool("PoolName"); LLCoprocedureManager::instance().initializePool("PoolName");
LLUUID queueId = LLCoprocedureManager::instance().enqueueCoprocedure("PoolName", "ProcName", LLCoprocedureManager::instance().enqueueCoprocedure("PoolName", "ProcName",
[&foo, &sync] (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t & ptr, const LLUUID & id) { [&foo, &sync] (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t & ptr, const LLUUID & id) {
sync.bump(); sync.bump();
foo = 1; foo = 1;

View File

@ -1413,6 +1413,16 @@ LLMeshSkinInfo::LLMeshSkinInfo(LLSD& skin):
fromLLSD(skin); fromLLSD(skin);
} }
LLMeshSkinInfo::LLMeshSkinInfo(const LLUUID& mesh_id, LLSD& skin) :
mMeshID(mesh_id),
mPelvisOffset(0.0),
mLockScaleIfJointPosition(false),
mInvalidJointsScrubbed(false),
mJointNumsInitialized(false)
{
fromLLSD(skin);
}
void LLMeshSkinInfo::fromLLSD(LLSD& skin) void LLMeshSkinInfo::fromLLSD(LLSD& skin)
{ {
if (skin.has("joint_names")) if (skin.has("joint_names"))

View File

@ -43,12 +43,13 @@ class domMesh;
#define MAX_MODEL_FACES 8 #define MAX_MODEL_FACES 8
LL_ALIGN_PREFIX(16) LL_ALIGN_PREFIX(16)
class LLMeshSkinInfo class LLMeshSkinInfo : public LLRefCount
{ {
LL_ALIGN_NEW LL_ALIGN_NEW
public: public:
LLMeshSkinInfo(); LLMeshSkinInfo();
LLMeshSkinInfo(LLSD& data); LLMeshSkinInfo(LLSD& data);
LLMeshSkinInfo(const LLUUID& mesh_id, LLSD& data);
void fromLLSD(LLSD& data); void fromLLSD(LLSD& data);
LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const; LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const;
void updateHash(); void updateHash();

View File

@ -515,6 +515,17 @@ LLFlatListView::LLFlatListView(const LLFlatListView::Params& p)
} }
}; };
LLFlatListView::~LLFlatListView()
{
for (pairs_iterator_t it = mItemPairs.begin(); it != mItemPairs.end(); ++it)
{
mItemsPanel->removeChild((*it)->first);
(*it)->first->die();
delete *it;
}
mItemPairs.clear();
}
// virtual // virtual
void LLFlatListView::draw() void LLFlatListView::draw()
{ {

View File

@ -307,6 +307,7 @@ public:
virtual S32 notify(const LLSD& info) ; virtual S32 notify(const LLSD& info) ;
virtual ~LLFlatListView();
protected: protected:
/** Pairs LLpanel representing a single item LLPanel and LLSD associated with it */ /** Pairs LLpanel representing a single item LLPanel and LLSD associated with it */

View File

@ -163,6 +163,7 @@ LLFolderView::LLFolderView(const Params& p)
: LLFolderViewFolder(p), : LLFolderViewFolder(p),
mScrollContainer( NULL ), mScrollContainer( NULL ),
mPopupMenuHandle(), mPopupMenuHandle(),
mMenuFileName(p.options_menu),
mAllowMultiSelect(p.allow_multiselect), mAllowMultiSelect(p.allow_multiselect),
mAllowDrag(p.allow_drag), mAllowDrag(p.allow_drag),
mShowEmptyMessage(p.show_empty_message), mShowEmptyMessage(p.show_empty_message),
@ -186,6 +187,7 @@ LLFolderView::LLFolderView(const Params& p)
mDragStartY(0), mDragStartY(0),
// [/SL:KB] // [/SL:KB]
mCallbackRegistrar(NULL), mCallbackRegistrar(NULL),
mEnableRegistrar(NULL),
mUseEllipses(p.use_ellipses), mUseEllipses(p.use_ellipses),
mDraggingOverItem(NULL), mDraggingOverItem(NULL),
mStatusTextBox(NULL), mStatusTextBox(NULL),
@ -248,17 +250,6 @@ LLFolderView::LLFolderView(const Params& p)
mStatusTextBox->setFollowsTop(); mStatusTextBox->setFollowsTop();
addChild(mStatusTextBox); addChild(mStatusTextBox);
// make the popup menu available
llassert(LLMenuGL::sMenuContainer != NULL);
LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(p.options_menu, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
if (!menu)
{
menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu");
}
menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor"));
mPopupMenuHandle = menu->getHandle();
mViewModelItem->openItem(); mViewModelItem->openItem();
mAreChildrenInited = true; // root folder is a special case due to not being loaded normally, assume that it's inited. mAreChildrenInited = true; // root folder is a special case due to not being loaded normally, assume that it's inited.
@ -280,6 +271,7 @@ LLFolderView::~LLFolderView( void )
mStatusTextBox = NULL; mStatusTextBox = NULL;
if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die(); if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
mPopupMenuHandle.markDead();
mAutoOpenItems.removeAllNodes(); mAutoOpenItems.removeAllNodes();
clearSelection(); clearSelection();
@ -1534,22 +1526,56 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL; BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL;
S32 count = mSelectedItems.size(); S32 count = mSelectedItems.size();
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); LLMenuGL* menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get());
if (!menu)
{
if (mCallbackRegistrar)
{
mCallbackRegistrar->pushScope();
}
if (mEnableRegistrar)
{
mEnableRegistrar->pushScope();
}
llassert(LLMenuGL::sMenuContainer != NULL);
menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(mMenuFileName, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
if (!menu)
{
menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu");
}
menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor"));
mPopupMenuHandle = menu->getHandle();
if (mEnableRegistrar)
{
mEnableRegistrar->popScope();
}
if (mCallbackRegistrar)
{
mCallbackRegistrar->popScope();
}
}
bool hide_folder_menu = mSuppressFolderMenu && isFolderSelected(); bool hide_folder_menu = mSuppressFolderMenu && isFolderSelected();
if ((handled if (menu && (handled
&& ( count > 0 && (hasVisibleChildren()) ) // show menu only if selected items are visible && ( count > 0 && (hasVisibleChildren()) )) && // show menu only if selected items are visible
&& menu ) &&
!hide_folder_menu) !hide_folder_menu)
{ {
if (mCallbackRegistrar) if (mCallbackRegistrar)
{ {
mCallbackRegistrar->pushScope(); mCallbackRegistrar->pushScope();
} }
if (mEnableRegistrar)
{
mEnableRegistrar->pushScope();
}
updateMenuOptions(menu); updateMenuOptions(menu);
menu->updateParent(LLMenuGL::sMenuContainer); menu->updateParent(LLMenuGL::sMenuContainer);
LLMenuGL::showPopup(this, menu, x, y); LLMenuGL::showPopup(this, menu, x, y);
if (mEnableRegistrar)
{
mEnableRegistrar->popScope();
}
if (mCallbackRegistrar) if (mCallbackRegistrar)
{ {
mCallbackRegistrar->popScope(); mCallbackRegistrar->popScope();
@ -1627,7 +1653,7 @@ void LLFolderView::deleteAllChildren()
{ {
closeRenamer(); closeRenamer();
if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die(); if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
mPopupMenuHandle = LLHandle<LLView>(); mPopupMenuHandle.markDead();
mScrollContainer = NULL; mScrollContainer = NULL;
mRenameItem = NULL; mRenameItem = NULL;
mRenamer = NULL; mRenamer = NULL;

View File

@ -240,6 +240,7 @@ public:
bool showItemLinkOverlays() { return mShowItemLinkOverlays; } bool showItemLinkOverlays() { return mShowItemLinkOverlays; }
void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; } void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; }
void setEnableRegistrar(LLUICtrl::EnableCallbackRegistry::ScopedRegistrar* registrar) { mEnableRegistrar = registrar; }
LLPanel* getParentPanel() { return mParentPanel.get(); } LLPanel* getParentPanel() { return mParentPanel.get(); }
// DEBUG only // DEBUG only
@ -277,6 +278,7 @@ protected:
protected: protected:
LLHandle<LLView> mPopupMenuHandle; LLHandle<LLView> mPopupMenuHandle;
std::string mMenuFileName;
selected_items_t mSelectedItems; selected_items_t mSelectedItems;
bool mKeyboardSelection, bool mKeyboardSelection,
@ -336,6 +338,7 @@ protected:
LLFolderViewItem* mDraggingOverItem; // See EXT-719 LLFolderViewItem* mDraggingOverItem; // See EXT-719
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* mCallbackRegistrar; LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* mCallbackRegistrar;
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar* mEnableRegistrar;
public: public:
static F32 sAutoOpenTime; static F32 sAutoOpenTime;

View File

@ -432,21 +432,15 @@ public:
mFilter(filter) mFilter(filter)
{} {}
virtual ~LLFolderViewModel() virtual ~LLFolderViewModel() {}
{
delete mSorter;
mSorter = NULL;
delete mFilter;
mFilter = NULL;
}
virtual SortType& getSorter() { return *mSorter; } virtual SortType& getSorter() { return *mSorter; }
virtual const SortType& getSorter() const { return *mSorter; } virtual const SortType& getSorter() const { return *mSorter; }
virtual void setSorter(const SortType& sorter) { mSorter = new SortType(sorter); requestSortAll(); } virtual void setSorter(const SortType& sorter) { mSorter.reset(new SortType(sorter)); requestSortAll(); }
virtual FilterType& getFilter() { return *mFilter; } virtual FilterType& getFilter() { return *mFilter; }
virtual const FilterType& getFilter() const { return *mFilter; } virtual const FilterType& getFilter() const { return *mFilter; }
virtual void setFilter(const FilterType& filter) { mFilter = new FilterType(filter); } virtual void setFilter(const FilterType& filter) { mFilter.reset(new FilterType(filter)); }
// By default, we assume the content is available. If a network fetch mechanism is implemented for the model, // By default, we assume the content is available. If a network fetch mechanism is implemented for the model,
// this method needs to be overloaded and return the relevant fetch status. // this method needs to be overloaded and return the relevant fetch status.
@ -484,8 +478,8 @@ public:
} }
protected: protected:
SortType* mSorter; std::unique_ptr<SortType> mSorter;
FilterType* mFilter; std::unique_ptr<FilterType> mFilter;
}; };
#endif // LLFOLDERVIEWMODEL_H #endif // LLFOLDERVIEWMODEL_H

View File

@ -164,8 +164,6 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
mHighlightColor(p.highlight_color()), mHighlightColor(p.highlight_color()),
mPreeditBgColor(p.preedit_bg_color()), mPreeditBgColor(p.preedit_bg_color()),
mGLFont(p.font), mGLFont(p.font),
// <FS:Ansariel> Delay context menu initialization if LLMenuGL::sMenuContainer is still NULL
mDelayedInit(false),
mContextMenuHandle(), mContextMenuHandle(),
mAutoreplaceCallback() mAutoreplaceCallback()
{ {
@ -212,24 +210,6 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
setPrevalidateInput(p.prevalidate_input_callback()); setPrevalidateInput(p.prevalidate_input_callback());
setPrevalidate(p.prevalidate_callback()); setPrevalidate(p.prevalidate_callback());
// <FS:Ansariel> Delay context menu initialization if LLMenuGL::sMenuContainer is still NULL
if (LLMenuGL::sMenuContainer)
{
// </FS:Ansariel>
llassert(LLMenuGL::sMenuContainer != NULL);
LLContextMenu* menu = LLUICtrlFactory::instance().createFromFile<LLContextMenu>
("menu_text_editor.xml",
LLMenuGL::sMenuContainer,
LLMenuHolderGL::child_registry_t::instance());
setContextMenu(menu);
// <FS:Ansariel> Delay context menu initialization if LLMenuGL::sMenuContainer is still NULL
}
else
{
mDelayedInit = true;
}
// </FS:Ansariel>
} }
LLLineEditor::~LLLineEditor() LLLineEditor::~LLLineEditor()
@ -244,9 +224,6 @@ LLLineEditor::~LLLineEditor()
} }
setContextMenu(NULL); setContextMenu(NULL);
// <FS:Ansariel> Delay context menu initialization if LLMenuGL::sMenuContainer is still NULL
mDelayedInit = false;
// calls onCommit() while LLLineEditor still valid // calls onCommit() while LLLineEditor still valid
gFocusMgr.releaseFocusIfNeeded( this ); gFocusMgr.releaseFocusIfNeeded( this );
} }
@ -1660,10 +1637,7 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask )
KEY_SHIFT != key && KEY_SHIFT != key &&
KEY_CONTROL != key && KEY_CONTROL != key &&
KEY_ALT != key && KEY_ALT != key &&
// <FS> Capslock deselecting text
//KEY_CAPSLOCK )
KEY_CAPSLOCK != key) KEY_CAPSLOCK != key)
// </FS>
{ {
deselect(); deselect();
} }
@ -2759,24 +2733,16 @@ LLWString LLLineEditor::getConvertedText() const
void LLLineEditor::showContextMenu(S32 x, S32 y, bool set_cursor_pos) void LLLineEditor::showContextMenu(S32 x, S32 y, bool set_cursor_pos)
// </FS:Ansariel> // </FS:Ansariel>
{ {
//LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get()); LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
// <FS:Ansariel> Delay context menu initialization if LLMenuGL::sMenuContainer is still NULL if (!menu)
LLContextMenu* menu = NULL;
if (mDelayedInit && !mContextMenuHandle.get())
{ {
llassert(LLMenuGL::sMenuContainer != NULL); llassert(LLMenuGL::sMenuContainer != NULL);
menu = LLUICtrlFactory::instance().createFromFile<LLContextMenu> menu = LLUICtrlFactory::createFromFile<LLContextMenu>
("menu_text_editor.xml", ("menu_text_editor.xml",
LLMenuGL::sMenuContainer, LLMenuGL::sMenuContainer,
LLMenuHolderGL::child_registry_t::instance()); LLMenuHolderGL::child_registry_t::instance());
setContextMenu(menu); setContextMenu(menu);
} }
else
{
menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
}
mDelayedInit = false;
// </FS:Ansariel>
if (menu) if (menu)
{ {
@ -2827,8 +2793,6 @@ void LLLineEditor::setContextMenu(LLContextMenu* new_context_menu)
{ {
menu->die(); menu->die();
mContextMenuHandle.markDead(); mContextMenuHandle.markDead();
// <FS:Ansariel> Delay context menu initialization if LLMenuGL::sMenuContainer is still NULL
mDelayedInit = false;
} }
if (new_context_menu) if (new_context_menu)

View File

@ -422,9 +422,6 @@ protected:
LLHandle<LLContextMenu> mContextMenuHandle; LLHandle<LLContextMenu> mContextMenuHandle;
// <FS:Ansariel> Delay context menu initialization if LLMenuGL::sMenuContainer is still NULL
bool mDelayedInit;
private: private:
// Instances that by default point to the statics but can be overidden in XML. // Instances that by default point to the statics but can be overidden in XML.
LLPointer<LLUIImage> mBgImage; LLPointer<LLUIImage> mBgImage;

View File

@ -4125,12 +4125,7 @@ void LLTearOffMenu::closeTearOff()
LLContextMenuBranch::LLContextMenuBranch(const LLContextMenuBranch::Params& p) LLContextMenuBranch::LLContextMenuBranch(const LLContextMenuBranch::Params& p)
: LLMenuItemGL(p) : LLMenuItemGL(p)
//mBranch( p.branch()->getHandle() ) // <FS> Context menu memory leak fix by Rye Mutt
{ {
// <FS> Context menu memory leak fix by Rye Mutt
//mBranch.get()->hide();
//mBranch.get()->setParentMenuItem(this);
// </FS>
LLContextMenu* branch = static_cast<LLContextMenu*>(p.branch); LLContextMenu* branch = static_cast<LLContextMenu*>(p.branch);
if (branch) if (branch)
{ {
@ -4140,7 +4135,6 @@ LLContextMenuBranch::LLContextMenuBranch(const LLContextMenuBranch::Params& p)
} }
} }
// <FS> Context menu memory leak fix by Rye Mutt
LLContextMenuBranch::~LLContextMenuBranch() LLContextMenuBranch::~LLContextMenuBranch()
{ {
if (mBranch.get()) if (mBranch.get())
@ -4148,30 +4142,21 @@ LLContextMenuBranch::~LLContextMenuBranch()
mBranch.get()->die(); mBranch.get()->die();
} }
} }
// </FS>
// called to rebuild the draw label // called to rebuild the draw label
void LLContextMenuBranch::buildDrawLabel( void ) void LLContextMenuBranch::buildDrawLabel( void )
{ {
// <FS> Context menu memory leak fix by Rye Mutt
auto menu = getBranch(); auto menu = getBranch();
if (menu) if (menu)
// </FS>
{ {
// default enablement is this -- if any of the subitems are // default enablement is this -- if any of the subitems are
// enabled, this item is enabled. JC // enabled, this item is enabled. JC
// <FS> Context menu memory leak fix by Rye Mutt
//U32 sub_count = mBranch.get()->getItemCount();
U32 sub_count = menu->getItemCount(); U32 sub_count = menu->getItemCount();
// </FS>
U32 i; U32 i;
BOOL any_enabled = FALSE; BOOL any_enabled = FALSE;
for (i = 0; i < sub_count; i++) for (i = 0; i < sub_count; i++)
{ {
// <FS> Context menu memory leak fix by Rye Mutt
//LLMenuItemGL* item = mBranch.get()->getItem(i);
LLMenuItemGL* item = menu->getItem(i); LLMenuItemGL* item = menu->getItem(i);
// </FS>
item->buildDrawLabel(); item->buildDrawLabel();
if (item->getEnabled() && !item->getDrawTextDisabled() ) if (item->getEnabled() && !item->getDrawTextDisabled() )
{ {
@ -4193,28 +4178,18 @@ void LLContextMenuBranch::buildDrawLabel( void )
void LLContextMenuBranch::showSubMenu() void LLContextMenuBranch::showSubMenu()
{ {
// <FS> Context menu memory leak fix by Rye Mutt
//LLMenuItemGL* menu_item = mBranch.get()->getParentMenuItem();
//if (menu_item != NULL && menu_item->getVisible())
//{
// S32 center_x;
// S32 center_y;
// localPointToScreen(getRect().getWidth(), getRect().getHeight() , &center_x, &center_y);
// mBranch.get()->show(center_x, center_y);
//}
auto menu = getBranch(); auto menu = getBranch();
if (menu) if(menu)
{ {
LLMenuItemGL* menu_item = menu->getParentMenuItem(); LLMenuItemGL* menu_item = menu->getParentMenuItem();
if (menu_item != NULL && menu_item->getVisible()) if (menu_item != NULL && menu_item->getVisible())
{ {
S32 center_x; S32 center_x;
S32 center_y; S32 center_y;
localPointToScreen(getRect().getWidth(), getRect().getHeight() , &center_x, &center_y); localPointToScreen(getRect().getWidth(), getRect().getHeight(), &center_x, &center_y);
menu->show(center_x, center_y); menu->show(center_x, center_y);
} }
} }
// </FS>
} }
// onCommit() - do the primary funcationality of the menu item. // onCommit() - do the primary funcationality of the menu item.
@ -4227,15 +4202,6 @@ void LLContextMenuBranch::setHighlight( BOOL highlight )
{ {
if (highlight == getHighlight()) return; if (highlight == getHighlight()) return;
LLMenuItemGL::setHighlight(highlight); LLMenuItemGL::setHighlight(highlight);
// <FS> Context menu memory leak fix by Rye Mutt
//if( highlight )
//{
// showSubMenu();
//}
//else
//{
// mBranch.get()->hide();
//}
auto menu = getBranch(); auto menu = getBranch();
if (menu) if (menu)
{ {
@ -4248,7 +4214,6 @@ void LLContextMenuBranch::setHighlight( BOOL highlight )
menu->hide(); menu->hide();
} }
} }
// </FS>
} }

View File

@ -754,11 +754,7 @@ public:
LLContextMenuBranch(const Params&); LLContextMenuBranch(const Params&);
// <FS> Context menu memory leak fix by Rye Mutt
//virtual ~LLContextMenuBranch()
//{}
virtual ~LLContextMenuBranch(); virtual ~LLContextMenuBranch();
// </FS>
// called to rebuild the draw label // called to rebuild the draw label
virtual void buildDrawLabel( void ); virtual void buildDrawLabel( void );

View File

@ -92,7 +92,7 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p)
mMouseDownSignal(NULL), mMouseDownSignal(NULL),
mMouseUpSignal(NULL) mMouseUpSignal(NULL)
{ {
mValue.emptyMap(); mValue = LLSD::emptyMap();
mCurSlider = LLStringUtil::null; mCurSlider = LLStringUtil::null;
if (mOrientation == HORIZONTAL) if (mOrientation == HORIZONTAL)

View File

@ -201,7 +201,6 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
mHighlightedItem(-1), mHighlightedItem(-1),
mBorder(NULL), mBorder(NULL),
mSortCallback(NULL), mSortCallback(NULL),
mPopupMenu(NULL),
mCommentTextView(NULL), mCommentTextView(NULL),
mNumDynamicWidthColumns(0), mNumDynamicWidthColumns(0),
mTotalStaticColumnWidth(0), mTotalStaticColumnWidth(0),
@ -412,6 +411,13 @@ LLScrollListCtrl::~LLScrollListCtrl()
mItemList.clear(); mItemList.clear();
clearColumns(); //clears columns and deletes headers clearColumns(); //clears columns and deletes headers
delete mIsFriendSignal; delete mIsFriendSignal;
auto menu = mPopupMenuHandle.get();
if (menu)
{
menu->die();
mPopupMenuHandle.markDead();
}
} }
@ -1423,20 +1429,20 @@ LLScrollListItem* LLScrollListCtrl::getItemByLabel(const std::string& label, BOO
} }
BOOL LLScrollListCtrl::selectItemByPrefix(const std::string& target, BOOL case_sensitive) BOOL LLScrollListCtrl::selectItemByPrefix(const std::string& target, BOOL case_sensitive, S32 column)
{ {
return selectItemByPrefix(utf8str_to_wstring(target), case_sensitive); return selectItemByPrefix(utf8str_to_wstring(target), case_sensitive, column);
} }
// Selects first enabled item that has a name where the name's first part matched the target string. // Selects first enabled item that has a name where the name's first part matched the target string.
// Returns false if item not found. // Returns false if item not found.
BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sensitive) BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sensitive, S32 column)
// <FS:Ansariel> Allow selection by substring match // <FS:Ansariel> Allow selection by substring match
{ {
return selectItemByStringMatch(target, true, case_sensitive); return selectItemByStringMatch(target, true, case_sensitive);
} }
BOOL LLScrollListCtrl::selectItemByStringMatch(const LLWString& target, bool prefix_match, BOOL case_sensitive) BOOL LLScrollListCtrl::selectItemByStringMatch(const LLWString& target, bool prefix_match, BOOL case_sensitive, S32 column)
// </FS:Ansariel> // </FS:Ansariel>
{ {
BOOL found = FALSE; BOOL found = FALSE;
@ -1452,7 +1458,7 @@ BOOL LLScrollListCtrl::selectItemByStringMatch(const LLWString& target, bool pre
{ {
LLScrollListItem* item = *iter; LLScrollListItem* item = *iter;
// Only select enabled items with matching names // Only select enabled items with matching names
LLScrollListCell* cellp = item->getColumn(getSearchColumn()); LLScrollListCell* cellp = item->getColumn(column == -1 ? getSearchColumn() : column);
BOOL select = cellp ? item->getEnabled() && ('\0' == cellp->getValue().asString()[0]) : FALSE; BOOL select = cellp ? item->getEnabled() && ('\0' == cellp->getValue().asString()[0]) : FALSE;
if (select) if (select)
{ {
@ -1475,7 +1481,7 @@ BOOL LLScrollListCtrl::selectItemByStringMatch(const LLWString& target, bool pre
LLScrollListItem* item = *iter; LLScrollListItem* item = *iter;
// Only select enabled items with matching names // Only select enabled items with matching names
LLScrollListCell* cellp = item->getColumn(getSearchColumn()); LLScrollListCell* cellp = item->getColumn(column == -1 ? getSearchColumn() : column);
if (!cellp) if (!cellp)
{ {
continue; continue;
@ -2252,17 +2258,23 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
// create the context menu from the XUI file and display it // create the context menu from the XUI file and display it
std::string menu_name = is_group ? "menu_url_group.xml" : "menu_url_agent.xml"; std::string menu_name = is_group ? "menu_url_group.xml" : "menu_url_agent.xml";
delete mPopupMenu; auto menu = mPopupMenuHandle.get();
llassert(LLMenuGL::sMenuContainer != NULL); if (menu)
mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
menu_name, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
if (mPopupMenu)
{ {
menu->die();
mPopupMenuHandle.markDead();
}
llassert(LLMenuGL::sMenuContainer != NULL);
menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
menu_name, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
if (menu)
{
mPopupMenuHandle = menu->getHandle();
if (mIsFriendSignal) if (mIsFriendSignal)
{ {
bool isFriend = *(*mIsFriendSignal)(uuid); bool isFriend = *(*mIsFriendSignal)(uuid);
LLView* addFriendButton = mPopupMenu->getChild<LLView>("add_friend"); LLView* addFriendButton = menu->getChild<LLView>("add_friend");
LLView* removeFriendButton = mPopupMenu->getChild<LLView>("remove_friend"); LLView* removeFriendButton = menu->getChild<LLView>("remove_friend");
if (addFriendButton && removeFriendButton) if (addFriendButton && removeFriendButton)
{ {
@ -2271,8 +2283,8 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
} }
} }
mPopupMenu->show(x, y); menu->show(x, y);
LLMenuGL::showPopup(this, mPopupMenu, x, y); LLMenuGL::showPopup(this, menu, x, y);
return TRUE; return TRUE;
} }
} }

View File

@ -270,12 +270,12 @@ public:
virtual LLScrollListItem* addSimpleElement(const std::string& value, EAddPosition pos = ADD_BOTTOM, const LLSD& id = LLSD()); virtual LLScrollListItem* addSimpleElement(const std::string& value, EAddPosition pos = ADD_BOTTOM, const LLSD& id = LLSD());
BOOL selectItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 ); // FALSE if item not found BOOL selectItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 ); // FALSE if item not found
BOOL selectItemByPrefix(const std::string& target, BOOL case_sensitive = TRUE); BOOL selectItemByPrefix(const std::string& target, BOOL case_sensitive = TRUE, S32 column = -1);
BOOL selectItemByPrefix(const LLWString& target, BOOL case_sensitive = TRUE); BOOL selectItemByPrefix(const LLWString& target, BOOL case_sensitive = TRUE, S32 column = -1);
// <FS:Ansariel> Allow selection by substring match // <FS:Ansariel> Allow selection by substring match
BOOL selectItemBySubstring(const std::string& target, BOOL case_sensitive = TRUE); BOOL selectItemBySubstring(const std::string& target, BOOL case_sensitive = TRUE);
BOOL selectItemBySubstring(const LLWString& target, BOOL case_sensitive = TRUE); BOOL selectItemBySubstring(const LLWString& target, BOOL case_sensitive = TRUE);
BOOL selectItemByStringMatch(const LLWString& target, bool prefix_match, BOOL case_sensitive = TRUE); BOOL selectItemByStringMatch(const LLWString& target, bool prefix_match, BOOL case_sensitive = TRUE, S32 column = -1);
// </FS:Ansariel> // </FS:Ansariel>
LLScrollListItem* getItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 ); LLScrollListItem* getItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 );
const std::string getSelectedItemLabel(S32 column = 0) const; const std::string getSelectedItemLabel(S32 column = 0) const;
@ -565,7 +565,7 @@ private:
S32 mHighlightedItem; S32 mHighlightedItem;
class LLViewBorder* mBorder; class LLViewBorder* mBorder;
LLContextMenu *mPopupMenu; LLHandle<LLContextMenu> mPopupMenuHandle;
LLView *mCommentTextView; LLView *mCommentTextView;

View File

@ -1583,12 +1583,10 @@ void LLTabContainer::selectLastTab()
void LLTabContainer::selectNextTab() void LLTabContainer::selectNextTab()
{ {
// <FS:Ansariel> FIRE-15580: Crash fix (division by 0) if (mTabList.size() == 0)
if (mTabList.size() == 0) {
{ return;
return; }
}
// </FS:Ansariel>
BOOL tab_has_focus = FALSE; BOOL tab_has_focus = FALSE;
if (mCurrentTabIdx >= 0 && mTabList[mCurrentTabIdx]->mButton->hasFocus()) if (mCurrentTabIdx >= 0 && mTabList[mCurrentTabIdx]->mButton->hasFocus())

View File

@ -308,6 +308,12 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
LLTextBase::~LLTextBase() LLTextBase::~LLTextBase()
{ {
mSegments.clear(); mSegments.clear();
LLContextMenu* menu = static_cast<LLContextMenu*>(mPopupMenuHandle.get());
if (menu)
{
menu->die();
mPopupMenuHandle.markDead();
}
delete mURLClickSignal; delete mURLClickSignal;
delete mIsFriendSignal; delete mIsFriendSignal;
delete mIsObjectBlockedSignal; delete mIsObjectBlockedSignal;

View File

@ -260,7 +260,6 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
mMouseDownY(0), mMouseDownY(0),
mTabsToNextField(p.ignore_tab), mTabsToNextField(p.ignore_tab),
mPrevalidateFunc(p.prevalidate_callback()), mPrevalidateFunc(p.prevalidate_callback()),
mContextMenu(NULL),
mShowContextMenu(p.show_context_menu), mShowContextMenu(p.show_context_menu),
mShowEmojiHelper(p.show_emoji_helper), mShowEmojiHelper(p.show_emoji_helper),
mEnableTooltipPaste(p.enable_tooltip_paste), mEnableTooltipPaste(p.enable_tooltip_paste),
@ -306,8 +305,13 @@ LLTextEditor::~LLTextEditor()
// Scrollbar is deleted by LLView // Scrollbar is deleted by LLView
std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer()); std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer());
mUndoStack.clear(); mUndoStack.clear();
// context menu is owned by menu holder, not us // Mark the menu as dead or its retained in memory till shutdown.
//delete mContextMenu; LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
if(menu)
{
menu->die();
mContextMenuHandle.markDead();
}
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -2291,19 +2295,19 @@ void LLTextEditor::setEnabled(BOOL enabled)
void LLTextEditor::showContextMenu(S32 x, S32 y, bool set_cursor_pos) void LLTextEditor::showContextMenu(S32 x, S32 y, bool set_cursor_pos)
// </FS:Ansariel> // </FS:Ansariel>
{ {
if (!mContextMenu) LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
if (!menu)
{ {
llassert(LLMenuGL::sMenuContainer != NULL); llassert(LLMenuGL::sMenuContainer != NULL);
mContextMenu = LLUICtrlFactory::instance().createFromFile<LLContextMenu>("menu_text_editor.xml", menu = LLUICtrlFactory::createFromFile<LLContextMenu>("menu_text_editor.xml",
LLMenuGL::sMenuContainer, LLMenuGL::sMenuContainer,
LLMenuHolderGL::child_registry_t::instance()); LLMenuHolderGL::child_registry_t::instance());
// <FS:Beq> FIRE-31081 defend against null this prt exception in setItemVisible found in BugSplat if(!menu)
if(!mContextMenu) {
{ LL_WARNS() << "Failed to create menu for LLTextEditor: " << getName() << LL_ENDL;
LL_WARNS() << "Failed to create context menu 'menu_text_editor'" << LL_ENDL; return;
return; }
} mContextMenuHandle = menu->getHandle();
// </FS:Beq>
} }
// Route menu to this class // Route menu to this class
@ -2350,11 +2354,11 @@ void LLTextEditor::showContextMenu(S32 x, S32 y, bool set_cursor_pos)
} }
} }
mContextMenu->setItemVisible("Suggestion Separator", (use_spellcheck) && (!mSuggestionList.empty())); menu->setItemVisible("Suggestion Separator", (use_spellcheck) && (!mSuggestionList.empty()));
mContextMenu->setItemVisible("Add to Dictionary", (use_spellcheck) && (is_misspelled)); menu->setItemVisible("Add to Dictionary", (use_spellcheck) && (is_misspelled));
mContextMenu->setItemVisible("Add to Ignore", (use_spellcheck) && (is_misspelled)); menu->setItemVisible("Add to Ignore", (use_spellcheck) && (is_misspelled));
mContextMenu->setItemVisible("Spellcheck Separator", (use_spellcheck) && (is_misspelled)); menu->setItemVisible("Spellcheck Separator", (use_spellcheck) && (is_misspelled));
mContextMenu->show(screen_x, screen_y, this); menu->show(screen_x, screen_y, this);
} }

View File

@ -352,7 +352,7 @@ private:
keystroke_signal_t mKeystrokeSignal; keystroke_signal_t mKeystrokeSignal;
LLTextValidate::validate_func_t mPrevalidateFunc; LLTextValidate::validate_func_t mPrevalidateFunc;
LLContextMenu* mContextMenu; LLHandle<LLContextMenu> mContextMenuHandle;
}; // end class LLTextEditor }; // end class LLTextEditor
// Build time optimization, generate once in .cpp file // Build time optimization, generate once in .cpp file

View File

@ -162,7 +162,12 @@ LLToolBar::LLToolBar(const LLToolBar::Params& p)
LLToolBar::~LLToolBar() LLToolBar::~LLToolBar()
{ {
delete mPopupMenuHandle.get(); auto menu = mPopupMenuHandle.get();
if (menu)
{
menu->die();
mPopupMenuHandle.markDead();
}
delete mButtonAddSignal; delete mButtonAddSignal;
delete mButtonEnterSignal; delete mButtonEnterSignal;
delete mButtonLeaveSignal; delete mButtonLeaveSignal;

View File

@ -1108,7 +1108,7 @@ LLSD LLDXHardware::getDisplayInfo()
} }
LCleanup: LCleanup:
if (ret.emptyMap()) if (!ret.isMap() || (ret.size() == 0))
{ {
LL_INFOS() << "Failed to get data, cleaning up" << LL_ENDL; LL_INFOS() << "Failed to get data, cleaning up" << LL_ENDL;
} }

View File

@ -83,7 +83,7 @@ int createNSApp(int argc, const char **argv);
void setupCocoa(); void setupCocoa();
bool pasteBoardAvailable(); bool pasteBoardAvailable();
bool copyToPBoard(const unsigned short *str, unsigned int len); bool copyToPBoard(const unsigned short *str, unsigned int len);
const unsigned short *copyFromPBoard(); unsigned short *copyFromPBoard();
CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY); CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY);
short releaseImageCursor(CursorRef ref); short releaseImageCursor(CursorRef ref);
short setImageCursor(CursorRef ref); short setImageCursor(CursorRef ref);

View File

@ -49,14 +49,12 @@ void setupCocoa()
if(!inited) if(!inited)
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @autoreleasepool {
// The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents.
// The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents. // ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr'
// ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr' // when init'ing the Cocoa App window.
// when init'ing the Cocoa App window. [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
[[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"]; }
[pool release];
inited = true; inited = true;
} }
@ -64,13 +62,13 @@ void setupCocoa()
bool copyToPBoard(const unsigned short *str, unsigned int len) bool copyToPBoard(const unsigned short *str, unsigned int len)
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; @autoreleasepool {
NSPasteboard *pboard = [NSPasteboard generalPasteboard]; NSPasteboard *pboard = [NSPasteboard generalPasteboard];
[pboard clearContents]; [pboard clearContents];
NSArray *contentsToPaste = [[NSArray alloc] initWithObjects:[NSString stringWithCharacters:str length:len], nil]; NSArray *contentsToPaste = [[[NSArray alloc] initWithObjects:[NSString stringWithCharacters:str length:len], nil] autorelease];
[pool release]; return [pboard writeObjects:contentsToPaste];
return [pboard writeObjects:contentsToPaste]; }
} }
bool pasteBoardAvailable() bool pasteBoardAvailable()
@ -79,45 +77,39 @@ bool pasteBoardAvailable()
return [[NSPasteboard generalPasteboard] canReadObjectForClasses:classArray options:[NSDictionary dictionary]]; return [[NSPasteboard generalPasteboard] canReadObjectForClasses:classArray options:[NSDictionary dictionary]];
} }
const unsigned short *copyFromPBoard() unsigned short *copyFromPBoard()
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; @autoreleasepool {
NSPasteboard *pboard = [NSPasteboard generalPasteboard]; NSPasteboard *pboard = [NSPasteboard generalPasteboard];
NSArray *classArray = [NSArray arrayWithObject:[NSString class]]; NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
NSString *str = NULL; NSString *str = NULL;
BOOL ok = [pboard canReadObjectForClasses:classArray options:[NSDictionary dictionary]]; BOOL ok = [pboard canReadObjectForClasses:classArray options:[NSDictionary dictionary]];
if (ok) if (ok)
{ {
NSArray *objToPaste = [pboard readObjectsForClasses:classArray options:[NSDictionary dictionary]]; NSArray *objToPaste = [pboard readObjectsForClasses:classArray options:[NSDictionary dictionary]];
str = [objToPaste objectAtIndex:0]; str = [objToPaste objectAtIndex:0];
} }
NSUInteger len = [str length]; NSUInteger str_len = [str length];
unichar* temp = (unichar*)calloc(str_len+1, sizeof(unichar));
// <FS:ND> add+1 for 0-terminator. [str getCharacters:temp range:NSMakeRange(0, str_len)];
// unichar* temp = (unichar*)calloc([str length]+1, sizeof(unichar)); return temp;
unichar* buffer = (unichar*)calloc(len+1, sizeof(unichar)); }
// </FS:ND>
[str getCharacters:buffer range:NSMakeRange(0, len)];
[pool release];
return buffer;
} }
CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY) CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY)
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSCursor *cursor = nil;
@autoreleasepool {
// extra retain on the NSCursor since we want it to live for the lifetime of the app. // extra retain on the NSCursor since we want it to live for the lifetime of the app.
NSCursor *cursor = cursor =
[[[NSCursor alloc] [[[NSCursor alloc]
initWithImage: initWithImage:
[[[NSImage alloc] initWithContentsOfFile: [[[NSImage alloc] initWithContentsOfFile:
[NSString stringWithUTF8String:fullpath] [NSString stringWithUTF8String:fullpath]
]autorelease] ] autorelease]
hotSpot:NSMakePoint(hotspotX, hotspotY) hotSpot:NSMakePoint(hotspotX, hotspotY)
]retain]; ] retain];
}
[pool release];
return (CursorRef)cursor; return (CursorRef)cursor;
} }
@ -184,10 +176,10 @@ OSErr releaseImageCursor(CursorRef ref)
{ {
if( ref != NULL ) if( ref != NULL )
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @autoreleasepool {
NSCursor *cursor = (NSCursor*)ref; NSCursor *cursor = (NSCursor*)ref;
[cursor release]; [cursor autorelease];
[pool release]; }
} }
else else
{ {
@ -201,10 +193,10 @@ OSErr setImageCursor(CursorRef ref)
{ {
if( ref != NULL ) if( ref != NULL )
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @autoreleasepool {
NSCursor *cursor = (NSCursor*)ref; NSCursor *cursor = (NSCursor*)ref;
[cursor set]; [cursor set];
[pool release]; }
} }
else else
{ {
@ -425,24 +417,26 @@ void requestUserAttention()
long showAlert(std::string text, std::string title, int type) long showAlert(std::string text, std::string title, int type)
{ {
NSAlert *alert = [[NSAlert alloc] init]; long ret = 0;
@autoreleasepool {
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
[alert setMessageText:[NSString stringWithCString:title.c_str() encoding:[NSString defaultCStringEncoding]]]; [alert setMessageText:[NSString stringWithCString:title.c_str() encoding:[NSString defaultCStringEncoding]]];
[alert setInformativeText:[NSString stringWithCString:text.c_str() encoding:[NSString defaultCStringEncoding]]]; [alert setInformativeText:[NSString stringWithCString:text.c_str() encoding:[NSString defaultCStringEncoding]]];
if (type == 0) if (type == 0)
{ {
[alert addButtonWithTitle:@"Okay"]; [alert addButtonWithTitle:@"Okay"];
} else if (type == 1) } else if (type == 1)
{ {
[alert addButtonWithTitle:@"Okay"]; [alert addButtonWithTitle:@"Okay"];
[alert addButtonWithTitle:@"Cancel"]; [alert addButtonWithTitle:@"Cancel"];
} else if (type == 2) } else if (type == 2)
{ {
[alert addButtonWithTitle:@"Yes"]; [alert addButtonWithTitle:@"Yes"];
[alert addButtonWithTitle:@"No"]; [alert addButtonWithTitle:@"No"];
}
ret = [alert runModal];
} }
long ret = [alert runModal];
[alert dealloc];
if (ret == NSAlertFirstButtonReturn) if (ret == NSAlertFirstButtonReturn)
{ {

View File

@ -678,11 +678,11 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
if (cgl_err != kCGLNoError ) if (cgl_err != kCGLNoError )
{ {
LL_DEBUGS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL; LL_INFOS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL;
} }
else else
{ {
LL_DEBUGS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL; LL_INFOS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL;
} }
} }
makeFirstResponder(mWindow, mGLView); makeFirstResponder(mWindow, mGLView);
@ -1257,9 +1257,12 @@ BOOL LLWindowMacOSX::isClipboardTextAvailable()
BOOL LLWindowMacOSX::pasteTextFromClipboard(LLWString &dst) BOOL LLWindowMacOSX::pasteTextFromClipboard(LLWString &dst)
{ {
//llutf16string str(copyFromPBoard()); unsigned short* pboard_data = copyFromPBoard(); // must free returned data
dst = utf16str_to_wstring(copyFromPBoard()); llutf16string str(pboard_data);
LLWStringUtil::removeCRLF(dst); // <FS:CR> free(pboard_data);
dst = utf16str_to_wstring(str);
LLWStringUtil::removeCRLF(dst); // <FS:CR>;
if (dst != L"") if (dst != L"")
{ {
return true; return true;
@ -1291,7 +1294,7 @@ LLWindow::LLWindowResolution* LLWindowMacOSX::getSupportedResolutions(S32 &num_r
{ {
if (!mSupportedResolutions) if (!mSupportedResolutions)
{ {
CFArrayRef modes = CGDisplayAvailableModes(mDisplay); CFArrayRef modes = CGDisplayCopyAllDisplayModes(mDisplay, nullptr);
if(modes != NULL) if(modes != NULL)
{ {
@ -1330,6 +1333,7 @@ LLWindow::LLWindowResolution* LLWindowMacOSX::getSupportedResolutions(S32 &num_r
} }
} }
} }
CFRelease(modes);
} }
} }

View File

@ -232,6 +232,7 @@ protected:
BOOL mLanguageTextInputAllowed; BOOL mLanguageTextInputAllowed;
LLPreeditor* mPreeditor; LLPreeditor* mPreeditor;
public:
static BOOL sUseMultGL; static BOOL sUseMultGL;
friend class LLWindowManager; friend class LLWindowManager;

View File

@ -3472,24 +3472,45 @@ BOOL LLWindowWin32::getClientRectInScreenSpace( RECT* rectp )
void LLWindowWin32::flashIcon(F32 seconds) void LLWindowWin32::flashIcon(F32 seconds)
{ {
if (mWindowHandle && (GetFocus() != mWindowHandle || GetForegroundWindow() != mWindowHandle)) // <FS:Ansariel> FIRE-32105: Application icon flashes also while viewer has focus
{ //if (mWindowHandle && (GetFocus() != mWindowHandle || GetForegroundWindow() != mWindowHandle))
mWindowThread->post([=]() //{
{ // mWindowThread->post([=]()
FLASHWINFO flash_info; // {
// FLASHWINFO flash_info;
flash_info.cbSize = sizeof(FLASHWINFO); // flash_info.cbSize = sizeof(FLASHWINFO);
flash_info.hwnd = mWindowHandle; // flash_info.hwnd = mWindowHandle;
flash_info.dwFlags = FLASHW_TRAY; // flash_info.dwFlags = FLASHW_TRAY;
// <FS:Ansariel> FIRE-23498: Tray icon flash functions randomly // // <FS:Ansariel> FIRE-23498: Tray icon flash functions randomly
//flash_info.uCount = UINT(seconds / ICON_FLASH_TIME); // //flash_info.uCount = UINT(seconds / ICON_FLASH_TIME);
//flash_info.dwTimeout = DWORD(1000.f * ICON_FLASH_TIME); // milliseconds // //flash_info.dwTimeout = DWORD(1000.f * ICON_FLASH_TIME); // milliseconds
flash_info.uCount = UINT(ll_round(seconds / ICON_FLASH_TIME)); // flash_info.uCount = UINT(ll_round(seconds / ICON_FLASH_TIME));
flash_info.dwTimeout = DWORD(ll_round(1000.f * ICON_FLASH_TIME)); // milliseconds // flash_info.dwTimeout = DWORD(ll_round(1000.f * ICON_FLASH_TIME)); // milliseconds
// </FS:Ansariel> // // </FS:Ansariel>
FlashWindowEx(&flash_info); // FlashWindowEx(&flash_info);
}); // });
} //}
mWindowThread->post([=]()
{
if (mWindowHandle && (GetFocus() != mWindowHandle || GetForegroundWindow() != mWindowHandle))
{
FLASHWINFO flash_info;
flash_info.cbSize = sizeof(FLASHWINFO);
flash_info.hwnd = mWindowHandle;
flash_info.dwFlags = FLASHW_TRAY;
// <FS:Ansariel> FIRE-23498: Tray icon flash functions randomly
//flash_info.uCount = UINT(seconds / ICON_FLASH_TIME);
//flash_info.dwTimeout = DWORD(1000.f * ICON_FLASH_TIME); // milliseconds
flash_info.uCount = UINT(ll_round(seconds / ICON_FLASH_TIME));
flash_info.dwTimeout = DWORD(ll_round(1000.f * ICON_FLASH_TIME)); // milliseconds
// </FS:Ansariel>
FlashWindowEx(&flash_info);
}
});
// </FS:Ansariel>
} }
F32 LLWindowWin32::getGamma() F32 LLWindowWin32::getGamma()

View File

@ -2241,9 +2241,9 @@ if (WINDOWS)
set_target_properties(${VIEWER_BINARY_NAME} set_target_properties(${VIEWER_BINARY_NAME}
PROPERTIES PROPERTIES
# *TODO -reenable this once we get server usage sorted out # *TODO -reenable this once we get server usage sorted out
LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /LARGEADDRESSAWARE" LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /LARGEADDRESSAWARE /LTCG"
LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO /LARGEADDRESSAWARE" LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO /LARGEADDRESSAWARE /LTCG"
LINK_FLAGS_RELEASE "/FORCE:MULTIPLE /MAP\"secondlife-bin.MAP\" /OPT:REF /LARGEADDRESSAWARE" LINK_FLAGS_RELEASE "/FORCE:MULTIPLE /MAP\"secondlife-bin.MAP\" /OPT:REF /LARGEADDRESSAWARE /LTCG"
) )
if(USE_PRECOMPILED_HEADERS) if(USE_PRECOMPILED_HEADERS)

View File

@ -1 +1 @@
6.6.9 6.6.10

View File

@ -23427,6 +23427,17 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key> <key>Value</key>
<integer>0</integer> <integer>0</integer>
</map> </map>
<key>DebugSettingsHideDefault</key>
<map>
<key>Comment</key>
<string>Show non-default settings only in Debug Settings list</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSNetMapPhantomOpacity</key> <key>FSNetMapPhantomOpacity</key>
<map> <map>
<key>Comment</key> <key>Comment</key>

View File

@ -25,6 +25,17 @@
/*[EXTRA_CODE_HERE]*/ /*[EXTRA_CODE_HERE]*/
// Inputs
VARYING vec4 vary_HazeColor;
VARYING float vary_LightNormPosDot;
uniform sampler2D rainbow_map;
uniform sampler2D halo_map;
uniform float moisture_level;
uniform float droplet_radius;
uniform float ice_level;
#ifdef DEFINE_GL_FRAGCOLOR #ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3]; out vec4 frag_data[3];
#else #else
@ -35,11 +46,34 @@ out vec4 frag_data[3];
// The fragment shader for the sky // The fragment shader for the sky
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
VARYING vec4 vary_HazeColor; vec3 rainbow(float d)
{
// 'Interesting' values of d are -0.75 .. -0.825, i.e. when view vec nearly opposite of sun vec
// Rainbox tex is mapped with REPEAT, so -.75 as tex coord is same as 0.25. -0.825 -> 0.175. etc.
// SL-13629
// Unfortunately the texture is inverted, so we need to invert the y coord, but keep the 'interesting'
// part within the same 0.175..0.250 range, i.e. d = (1 - d) - 1.575
d = clamp(-0.575 - d, 0.0, 1.0);
// With the colors in the lower 1/4 of the texture, inverting the coords leaves most of it inaccessible.
// So, we can stretch the texcoord above the colors (ie > 0.25) to fill the entire remaining coordinate
// space. This improves gradation, reduces banding within the rainbow interior. (1-0.25) / (0.425/0.25) = 4.2857
float interior_coord = max(0.0, d - 0.25) * 4.2857;
d = clamp(d, 0.0, 0.25) + interior_coord;
float rad = (droplet_radius - 5.0f) / 1024.0f;
return pow(texture2D(rainbow_map, vec2(rad+0.5, d)).rgb, vec3(1.8)) * moisture_level;
}
vec3 halo22(float d)
{
d = clamp(d, 0.1, 1.0);
float v = sqrt(clamp(1 - (d * d), 0, 1));
return texture2D(halo_map, vec2(0, v)).rgb * ice_level;
}
/// Soft clips the light with a gamma correction /// Soft clips the light with a gamma correction
vec3 scaleSoftClip(vec3 light); vec3 scaleSoftClip(vec3 light);
vec3 srgb_to_linear(vec3 c);
void main() void main()
{ {
@ -48,14 +82,18 @@ void main()
// the fragment) if the sky wouldn't show up because the clouds // the fragment) if the sky wouldn't show up because the clouds
// are fully opaque. // are fully opaque.
vec4 color; vec4 color = vary_HazeColor;
color = vary_HazeColor;
float rel_pos_lightnorm = vary_LightNormPosDot;
float optic_d = rel_pos_lightnorm;
vec3 halo_22 = halo22(optic_d);
color.rgb += rainbow(optic_d);
color.rgb += halo_22;
color.rgb *= 2.; color.rgb *= 2.;
color.rgb = scaleSoftClip(color.rgb); color.rgb = scaleSoftClip(color.rgb);
/// Gamma correct for WL (soft clip effect). // Gamma correct for WL (soft clip effect).
frag_data[0] = vec4(color.rgb, 0.0); frag_data[0] = vec4(color.rgb, 1.0);
frag_data[1] = vec4(0.0,0.0,0.0,0.0); frag_data[1] = vec4(0.0,0.0,0.0,0.0);
frag_data[2] = vec4(0.0,0.0,0.0,1.0); //1.0 in norm.w masks off fog frag_data[2] = vec4(0.0,0.0,0.0,1.0); //1.0 in norm.w masks off fog

View File

@ -33,6 +33,7 @@ ATTRIBUTE vec3 position;
// Output parameters // Output parameters
VARYING vec4 vary_HazeColor; VARYING vec4 vary_HazeColor;
VARYING float vary_LightNormPosDot;
// Inputs // Inputs
uniform vec3 camPosLocal; uniform vec3 camPosLocal;
@ -72,27 +73,29 @@ void main()
vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0); vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0);
// Adj position vector to clamp altitude // Adj position vector to clamp altitude
if (rel_pos.y > 0) if (rel_pos.y > 0.)
{ {
rel_pos *= (max_y / rel_pos.y); rel_pos *= (max_y / rel_pos.y);
} }
if (rel_pos.y < 0) if (rel_pos.y < 0.)
{ {
rel_pos *= (-32000. / rel_pos.y); rel_pos *= (-32000. / rel_pos.y);
} }
// Can normalize then // Normalized
vec3 rel_pos_norm = normalize(rel_pos); vec3 rel_pos_norm = normalize(rel_pos);
float rel_pos_len = length(rel_pos);
float rel_pos_len = length(rel_pos); // Grab this value and pass to frag shader for rainbows
float rel_pos_lightnorm_dot = dot(rel_pos_norm, lightnorm.xyz);
vary_LightNormPosDot = rel_pos_lightnorm_dot;
// Initialize temp variables // Initialize temp variables
vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color; vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
vec4 light_atten;
// Sunlight attenuation effect (hue and brightness) due to atmosphere // Sunlight attenuation effect (hue and brightness) due to atmosphere
// this is used later for sunlight modulation at various altitudes // this is used later for sunlight modulation at various altitudes
light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); vec4 light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
// Calculate relative weights // Calculate relative weights
vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density)); vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
@ -112,7 +115,7 @@ void main()
combined_haze = exp(-combined_haze * density_dist); combined_haze = exp(-combined_haze * density_dist);
// Compute haze glow // Compute haze glow
float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz); float haze_glow = 1.0 - rel_pos_lightnorm_dot;
// haze_glow is 0 at the sun and increases away from sun // haze_glow is 0 at the sun and increases away from sun
haze_glow = max(haze_glow, .001); haze_glow = max(haze_glow, .001);
// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
@ -123,30 +126,30 @@ void main()
// Add "minimum anti-solar illumination" // Add "minimum anti-solar illumination"
// For sun, add to glow. For moon, remove glow entirely. SL-13768 // For sun, add to glow. For moon, remove glow entirely. SL-13768
haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25); haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (sun_moon_glow_factor * (haze_glow + 0.25));
vec4 color = // Haze color above cloud
(blue_horizon * blue_weight * (sunlight + ambient_color) + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color)); vec4 color = (blue_horizon * blue_weight * (sunlight + ambient_color)
+ (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color));
// Final atmosphere additive // Final atmosphere additive
color *= (1. - combined_haze); color *= (1. - combined_haze);
// Increase ambient when there are more clouds // Increase ambient when there are more clouds
vec4 tmpAmbient = ambient_color; vec4 ambient = ambient_color + max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
tmpAmbient += max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
// Dim sunlight by cloud shadow percentage // Dim sunlight by cloud shadow percentage
sunlight *= max(0.0, (1. - cloud_shadow)); sunlight *= max(0.0, (1. - cloud_shadow));
// Haze color below cloud // Haze color below cloud
vec4 additiveColorBelowCloud = vec4 add_below_cloud = (blue_horizon * blue_weight * (sunlight + ambient)
(blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient)); + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient));
// Attenuate cloud color by atmosphere // Attenuate cloud color by atmosphere
combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
// At horizon, blend high altitude sky color towards the darker color below the clouds // At horizon, blend high altitude sky color towards the darker color below the clouds
color += (additiveColorBelowCloud - color) * (1. - sqrt(combined_haze)); color += (add_below_cloud - color) * (1. - sqrt(combined_haze));
// Haze color above cloud // Haze color above cloud
vary_HazeColor = color; vary_HazeColor = color;

View File

@ -1,199 +0,0 @@
/**
* @file class2/deferred/skyF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2005, 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;
// SKY ////////////////////////////////////////////////////////////////////////
// The vertex shader for creating the atmospheric sky
///////////////////////////////////////////////////////////////////////////////
// Inputs
uniform vec3 camPosLocal;
uniform vec4 lightnorm;
uniform vec4 sunlight_color;
uniform vec4 moonlight_color;
uniform int sun_up_factor;
uniform vec4 ambient_color;
uniform vec4 blue_horizon;
uniform vec4 blue_density;
uniform float haze_horizon;
uniform float haze_density;
uniform float cloud_shadow;
uniform float density_multiplier;
uniform float distance_multiplier;
uniform float max_y;
uniform vec4 glow;
uniform float sun_moon_glow_factor;
uniform vec4 cloud_color;
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
#define frag_data gl_FragData
#endif
VARYING vec3 pos;
/////////////////////////////////////////////////////////////////////////
// The fragment shader for the sky
/////////////////////////////////////////////////////////////////////////
uniform sampler2D rainbow_map;
uniform sampler2D halo_map;
uniform float moisture_level;
uniform float droplet_radius;
uniform float ice_level;
vec3 rainbow(float d)
{
// d is the dot product of view and sun directions, so ranging -1.0..1.0
// 'interesting' values of d are the range -0.75..-0.825, when view is nearly opposite of sun vec
// Rainbox texture mode is GL_REPEAT, so tc of -.75 is equiv to 0.25, -0.825 equiv to 0.175.
// SL-13629 Rainbow texture has colors within the correct .175...250 range, but order is inverted.
// Rather than replace the texture, we mirror and translate the y tc to keep the colors within the
// interesting range, but in reversed order: i.e. d = (1 - d) - 1.575
d = clamp(-0.575 - d, 0.0, 1.0);
// With the colors in the lower 1/4 of the texture, inverting the coords leaves most of it inaccessible.
// So, we can stretch the texcoord above the colors (ie > 0.25) to fill the entire remaining coordinate
// space. This improves gradation, reduces banding within the rainbow interior. (1-0.25) / (0.425/0.25) = 4.2857
float interior_coord = max(0.0, d - 0.25) * 4.2857;
d = clamp(d, 0.0, 0.25) + interior_coord;
float rad = (droplet_radius - 5.0f) / 1024.0f;
return pow(texture2D(rainbow_map, vec2(rad, d)).rgb, vec3(1.8)) * moisture_level;
}
vec3 halo22(float d)
{
d = clamp(d, 0.1, 1.0);
float v = sqrt(clamp(1 - (d * d), 0, 1));
return texture2D(halo_map, vec2(0, v)).rgb * ice_level;
}
/// Soft clips the light with a gamma correction
vec3 scaleSoftClip(vec3 light);
void main()
{
// World / view / projection
// Get relative position (offset why?)
vec3 rel_pos = pos.xyz - camPosLocal.xyz + vec3(0, 50, 0);
// Adj position vector to clamp altitude
if (rel_pos.y > 0.)
{
rel_pos *= (max_y / rel_pos.y);
}
if (rel_pos.y < 0.)
{
rel_pos *= (-32000. / rel_pos.y);
}
// Normalized
vec3 rel_pos_norm = normalize(rel_pos);
float rel_pos_len = length(rel_pos);
// Initialize temp variables
vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
// Sunlight attenuation effect (hue and brightness) due to atmosphere
// this is used later for sunlight modulation at various altitudes
vec4 light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
// Calculate relative weights
vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
vec4 blue_weight = blue_density / combined_haze;
vec4 haze_weight = haze_density / combined_haze;
// Compute sunlight from rel_pos & lightnorm (for long rays like sky)
float off_axis = 1.0 / max(1e-6, max(0, rel_pos_norm.y) + lightnorm.y);
sunlight *= exp(-light_atten * off_axis);
// Distance
float density_dist = rel_pos_len * density_multiplier;
// Transparency (-> combined_haze)
// ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
// compiler gets confused.
combined_haze = exp(-combined_haze * density_dist);
// Compute haze glow
float haze_glow = dot(rel_pos_norm, lightnorm.xyz);
haze_glow = 1. - haze_glow;
// haze_glow is 0 at the sun and increases away from sun
haze_glow = max(haze_glow, .001);
// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
haze_glow *= glow.x;
// Higher glow.x gives dimmer glow (because next step is 1 / "angle")
haze_glow = pow(haze_glow, glow.z);
// glow.z should be negative, so we're doing a sort of (1 / "angle") function
// Add "minimum anti-solar illumination"
// For sun, add to glow. For moon, remove glow entirely. SL-13768
haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (sun_moon_glow_factor * (haze_glow + 0.25));
// Haze color above cloud
vec4 color = blue_horizon * blue_weight * (sunlight + ambient_color)
+ haze_horizon * haze_weight * (sunlight * haze_glow + ambient_color);
// Final atmosphere additive
color *= (1. - combined_haze);
// Increase ambient when there are more clouds
// TODO 9/20: DJH what does this do? max(0,(1-ambient)) will change the color
vec4 ambient = ambient_color + max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
// Dim sunlight by cloud shadow percentage
sunlight *= max(0.0, (1. - cloud_shadow));
// Haze color below cloud
vec4 add_below_cloud = blue_horizon * blue_weight * (sunlight + ambient)
+ haze_horizon * haze_weight * (sunlight * haze_glow + ambient);
// Attenuate cloud color by atmosphere
combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
// At horizon, blend high altitude sky color towards the darker color below the clouds
color += (add_below_cloud - color) * (1. - sqrt(combined_haze));
float optic_d = dot(rel_pos_norm, lightnorm.xyz);
vec3 halo_22 = halo22(optic_d);
color.rgb += rainbow(optic_d);
color.rgb += halo_22;
color.rgb *= 2.;
color.rgb = scaleSoftClip(color.rgb);
// Gamma correct for WL (soft clip effect).
frag_data[0] = vec4(color.rgb, 1.0);
frag_data[1] = vec4(0.0, 0.0, 0.0, 0.0);
frag_data[2] = vec4(0.0, 0.0, 0.0, 1.0); // 1.0 in norm.w masks off fog
}

View File

@ -1,42 +0,0 @@
/**
* @file WLSkyV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2005, 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;
ATTRIBUTE vec3 position;
// SKY ////////////////////////////////////////////////////////////////////////
// The vertex shader for creating the atmospheric sky
///////////////////////////////////////////////////////////////////////////////
VARYING vec3 pos;
void main()
{
// World / view / projection
pos = position.xyz;
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
}

View File

@ -1265,9 +1265,7 @@ FSChatHistory::FSChatHistory(const FSChatHistory::Params& p)
LLSD FSChatHistory::getValue() const LLSD FSChatHistory::getValue() const
{ {
LLSD* text=new LLSD(); return LLSD(getText());
text->assign(getText());
return *text;
} }
FSChatHistory::~FSChatHistory() FSChatHistory::~FSChatHistory()

View File

@ -106,7 +106,7 @@ bool FSContactsFriendsMenu::enableContextMenuItem(const LLSD& userdata)
{ {
if (mUUIDs.size() == 1) if (mUUIDs.size() == 1)
{ {
return (FSRadar::getInstance()->getEntry(mUUIDs.front()) != NULL); return FSRadar::getInstance()->getEntry(mUUIDs.front()) != nullptr;
} }
return false; return false;
} }
@ -126,7 +126,7 @@ bool FSContactsFriendsMenu::enableContextMenuItem(const LLSD& userdata)
{ {
if (mUUIDs.size() == 1) if (mUUIDs.size() == 1)
{ {
return (FSRadar::getInstance()->getEntry(mUUIDs.front()) != NULL); return FSRadar::getInstance()->getEntry(mUUIDs.front()) != nullptr;
} }
return false; return false;
} }

View File

@ -38,12 +38,12 @@
#include "fslslpreprocviewer.h" #include "fslslpreprocviewer.h"
#include "llagent.h" #include "llagent.h"
#include "llappviewer.h" #include "llappviewer.h"
#include "llinventoryfunctions.h"
#include "lltrans.h"
#include "llfilesystem.h"
#include "llviewercontrol.h"
#include "llcompilequeue.h" #include "llcompilequeue.h"
#include "llfilesystem.h"
#include "llinventoryfunctions.h"
#include "llnotificationsutil.h" #include "llnotificationsutil.h"
#include "lltrans.h"
#include "llviewercontrol.h"
#ifdef __GNUC__ #ifdef __GNUC__
// There is a sprintf( ... "%d", size_t_value) buried inside boost::wave. In order to not mess with system header, I rather disable that warning here. // There is a sprintf( ... "%d", size_t_value) buried inside boost::wave. In order to not mess with system header, I rather disable that warning here.
@ -53,7 +53,7 @@
class ScriptMatches : public LLInventoryCollectFunctor class ScriptMatches : public LLInventoryCollectFunctor
{ {
public: public:
ScriptMatches(const std::string& name) ScriptMatches(std::string_view name)
{ {
mName = name; mName = name;
} }
@ -70,7 +70,7 @@ private:
std::string mName; std::string mName;
}; };
LLUUID FSLSLPreprocessor::findInventoryByName(std::string name) std::optional<LLUUID> FSLSLPreprocessor::findInventoryByName(std::string_view name)
{ {
LLInventoryModel::cat_array_t cats; LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items; LLInventoryModel::item_array_t items;
@ -81,17 +81,11 @@ LLUUID FSLSLPreprocessor::findInventoryByName(std::string name)
{ {
return items.front()->getUUID(); return items.front()->getUUID();
} }
return LLUUID::null; return std::nullopt;
} }
std::map<std::string,LLUUID> FSLSLPreprocessor::cached_assetids; std::map<std::string, LLUUID> FSLSLPreprocessor::cached_assetids;
#if !defined(LL_DARWIN) || defined(DARWINPREPROC)
//apparently LL #defined this function which happens to precisely match
//a boost::wave function name, destroying the internet, silly grey furries
#undef equivalent
// Work around stupid Microsoft STL warning // Work around stupid Microsoft STL warning
#ifdef LL_WINDOWS #ifdef LL_WINDOWS
@ -132,14 +126,8 @@ std::string FSLSLPreprocessor::encode(const std::string& script)
{ {
std::string otext = FSLSLPreprocessor::decode(script); std::string otext = FSLSLPreprocessor::decode(script);
bool mono = mono_directive(script);
otext = boost::regex_replace(otext, boost::regex("([/*])(?=[/*|])", boost::regex::perl), "$1|"); otext = boost::regex_replace(otext, boost::regex("([/*])(?=[/*|])", boost::regex::perl), "$1|");
//otext = curl_escape(otext.c_str(), otext.size());
otext = encode_start + otext + encode_end; otext = encode_start + otext + encode_end;
otext += "\n//nfo_preprocessor_version 0"; otext += "\n//nfo_preprocessor_version 0";
//otext += "\n//^ = determine what featureset is supported"; //otext += "\n//^ = determine what featureset is supported";
@ -156,10 +144,9 @@ std::string FSLSLPreprocessor::encode(const std::string& script)
substitution["datetime"] = (S32) utc_time; substitution["datetime"] = (S32) utc_time;
LLStringUtil::format (timeStr, substitution); LLStringUtil::format (timeStr, substitution);
otext += "\n//last_compiled " + timeStr; otext += "\n//last_compiled " + timeStr;
otext += "\n"; otext += "\n";
if (mono) if (mono_directive(script))
{ {
otext += "//mono\n"; otext += "//mono\n";
} }
@ -173,7 +160,7 @@ std::string FSLSLPreprocessor::encode(const std::string& script)
std::string FSLSLPreprocessor::decode(const std::string& script) std::string FSLSLPreprocessor::decode(const std::string& script)
{ {
static S32 startpoint = encode_start.length(); static const S32 startpoint = encode_start.length();
std::string tip = script.substr(0, startpoint); std::string tip = script.substr(0, startpoint);
@ -196,11 +183,8 @@ std::string FSLSLPreprocessor::decode(const std::string& script)
LL_DEBUGS("FSLSLPreprocessor") << "data = " << data << LL_ENDL; LL_DEBUGS("FSLSLPreprocessor") << "data = " << data << LL_ENDL;
std::string otext = data; std::string otext = data;
otext = boost::regex_replace(otext, boost::regex("([/*])\\|", boost::regex::perl), "$1"); otext = boost::regex_replace(otext, boost::regex("([/*])\\|", boost::regex::perl), "$1");
//otext = curl_unescape(otext.c_str(),otext.length());
return otext; return otext;
} }
@ -253,7 +237,7 @@ static std::string scopeript2(std::string& top, S32 fstart, char left = '{', cha
return "end out of bounds"; return "end out of bounds";
} }
return top.substr(fstart,(cursor-fstart)); return top.substr(fstart, (cursor - fstart));
} }
static inline S32 const_iterator_to_pos(std::string::const_iterator begin, std::string::const_iterator cursor) static inline S32 const_iterator_to_pos(std::string::const_iterator begin, std::string::const_iterator cursor)
@ -317,7 +301,6 @@ static void shredder(std::string& text)
std::string FSLSLPreprocessor::lslopt(std::string script) std::string FSLSLPreprocessor::lslopt(std::string script)
{ {
try try
{ {
std::string bottom; std::string bottom;
@ -409,17 +392,12 @@ std::string FSLSLPreprocessor::lslopt(std::string script)
do do
{ {
repass = false; repass = false;
std::map<std::string, std::string>::iterator func_it; for (const auto& [funcname, function] : functions)
for (func_it = functions.begin(); func_it != functions.end(); func_it++)
{ {
std::string funcname = func_it->first;
if (kept_functions.find(funcname) == kept_functions.end()) if (kept_functions.find(funcname) == kept_functions.end())
{ {
boost::smatch calls; boost::smatch calls;
//funcname has to be [a-zA-Z0-9_]+, so we know it's safe //funcname has to be [a-zA-Z0-9_]+, so we know it's safe
boost::regex findcalls(std::string() + boost::regex findcalls(std::string() +
rDOT_MATCHES_NEWLINE rDOT_MATCHES_NEWLINE
"(?<![A-Za-z0-9_])(" + funcname + ")" rOPT_SPC "\\(" // a call to the function... "(?<![A-Za-z0-9_])(" + funcname + ")" rOPT_SPC "\\(" // a call to the function...
@ -439,7 +417,6 @@ std::string FSLSLPreprocessor::lslopt(std::string script)
{ {
if (calls[1].matched) if (calls[1].matched)
{ {
std::string function = func_it->second;
kept_functions.insert(funcname); kept_functions.insert(funcname);
bottom = function + bottom; bottom = function + bottom;
repass = true; repass = true;
@ -456,11 +433,9 @@ std::string FSLSLPreprocessor::lslopt(std::string script)
while (repass); while (repass);
// Find variable invocations and add the declarations back if used. // Find variable invocations and add the declarations back if used.
std::vector<std::pair<std::string, std::string> >::reverse_iterator var_it; std::vector<std::pair<std::string, std::string> >::reverse_iterator var_it;
for (var_it = gvars.rbegin(); var_it != gvars.rend(); var_it++) for (var_it = gvars.rbegin(); var_it != gvars.rend(); var_it++)
{ {
std::string varname = var_it->first; std::string varname = var_it->first;
boost::regex findvcalls(std::string() + rDOT_MATCHES_NEWLINE boost::regex findvcalls(std::string() + rDOT_MATCHES_NEWLINE
"(?<![a-zA-Z0-9_.])(" + varname + ")(?![a-zA-Z0-9_\"])" // invocation of the variable "(?<![a-zA-Z0-9_.])(" + varname + ")(?![a-zA-Z0-9_\"])" // invocation of the variable
@ -509,6 +484,7 @@ std::string FSLSLPreprocessor::lslopt(std::string script)
display_error(err); display_error(err);
throw; throw;
} }
return script; return script;
} }
@ -546,9 +522,9 @@ struct ProcCacheInfo
FSLSLPreprocessor* self; FSLSLPreprocessor* self;
}; };
static inline std::string shortfile(std::string in) static inline std::string shortfile(const std::string& in)
{ {
return boost::filesystem::path(std::string(in)).filename().string(); return boost::filesystem::path(in).filename().string();
} }
@ -562,16 +538,15 @@ public:
mFileStack.push(proc->mMainScriptName); mFileStack.push(proc->mMainScriptName);
} }
template <typename ContextT> template <typename ContextT>
bool found_include_directive(ContextT const& ctx, std::string const &filename, bool include_next) bool found_include_directive(ContextT const& ctx, std::string const &filename, bool include_next)
{ {
std::string cfilename = filename.substr(1, filename.length() - 2); std::string cfilename = filename.substr(1, filename.length() - 2);
LL_DEBUGS("FSLSLPreprocessor") << cfilename << ":found_include_directive" << LL_ENDL; LL_DEBUGS("FSLSLPreprocessor") << cfilename << ":found_include_directive" << LL_ENDL;
LLUUID item_id = FSLSLPreprocessor::findInventoryByName(cfilename); std::optional<LLUUID> item_id = FSLSLPreprocessor::findInventoryByName(cfilename);
if (item_id.notNull()) if (item_id.has_value())
{ {
LLViewerInventoryItem* item = gInventory.getItem(item_id); LLViewerInventoryItem* item = gInventory.getItem(item_id.value());
if (item) if (item)
{ {
std::map<std::string,LLUUID>::iterator it = mProc->cached_assetids.find(cfilename); std::map<std::string,LLUUID>::iterator it = mProc->cached_assetids.find(cfilename);
@ -605,8 +580,8 @@ public:
info->self = mProc; info->self = mProc;
LLPermissions perm(((LLInventoryItem*)item)->getPermissions()); LLPermissions perm(((LLInventoryItem*)item)->getPermissions());
gAssetStorage->getInvItemAsset(LLHost(), gAssetStorage->getInvItemAsset(LLHost(),
gAgent.getID(), gAgentID,
gAgent.getSessionID(), gAgentSessionID,
perm.getOwner(), perm.getOwner(),
LLUUID::null, LLUUID::null,
item->getUUID(), item->getUUID(),
@ -624,7 +599,6 @@ public:
{ {
//todo check on HDD in user defined dir for file in question //todo check on HDD in user defined dir for file in question
} }
//++include_depth;
return false; return false;
} }
@ -633,11 +607,10 @@ public:
std::string const &relname, std::string const& absname, std::string const &relname, std::string const& absname,
bool is_system_include) bool is_system_include)
{ {
ContextT& usefulctx = const_cast<ContextT&>(ctx); ContextT& usefulctx = const_cast<ContextT&>(ctx);
std::string id; std::string id;
std::string filename = shortfile(relname);//boost::filesystem::path(std::string(relname)).filename(); std::string filename = shortfile(relname);
std::map<std::string,LLUUID>::iterator it = mProc->cached_assetids.find(filename); std::map<std::string, LLUUID>::iterator it = mProc->cached_assetids.find(filename);
if (it != mProc->cached_assetids.end()) if (it != mProc->cached_assetids.end())
{ {
id = mProc->cached_assetids[filename].asString(); id = mProc->cached_assetids[filename].asString();
@ -707,7 +680,6 @@ private:
void cache_script(std::string name, std::string content) void cache_script(std::string name, std::string content)
{ {
content += "\n";/*hack!*/ content += "\n";/*hack!*/
LL_DEBUGS("FSLSLPreprocessor") << "writing " << name << " to cache" << LL_ENDL; LL_DEBUGS("FSLSLPreprocessor") << "writing " << name << " to cache" << LL_ENDL;
std::string path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "lslpreproc", name); std::string path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "lslpreproc", name);
@ -752,15 +724,16 @@ void FSLSLPreprocessor::FSProcCacheCallback(const LLUUID& iuuid, LLAssetType::ET
args["[FILENAME]"] = name; args["[FILENAME]"] = name;
self->display_message(LLTrans::getString("fs_preprocessor_cache_completed", args)); self->display_message(LLTrans::getString("fs_preprocessor_cache_completed", args));
cache_script(name, content); cache_script(name, content);
std::set<std::string>::iterator loc = self->caching_files.find(name); if (std::set<std::string>::iterator loc = self->caching_files.find(name); loc != self->caching_files.end())
if (loc != self->caching_files.end())
{ {
LL_DEBUGS("FSLSLPreprocessor") << "finalizing cache" << LL_ENDL; LL_DEBUGS("FSLSLPreprocessor") << "finalizing cache" << LL_ENDL;
self->caching_files.erase(loc); self->caching_files.erase(loc);
//self->cached_files.insert(name); if (uuid.isNull())
if(uuid.isNull())uuid.generate(); {
uuid.generate();
}
item->setAssetUUID(uuid); item->setAssetUUID(uuid);
self->cached_assetids[name] = uuid;//.insert(uuid.asString()); self->cached_assetids[name] = uuid;
self->start_process(); self->start_process();
} }
else else
@ -798,11 +771,10 @@ void FSLSLPreprocessor::preprocess_script(BOOL close, bool sync, bool defcache)
LLStringUtil::format_map_t args; LLStringUtil::format_map_t args;
display_message(LLTrans::getString("fs_preprocessor_starting")); display_message(LLTrans::getString("fs_preprocessor_starting"));
LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"") + gDirUtilp->getDirDelimiter() + "lslpreproc"); LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "lslpreproc"));
std::string script = mCore->mEditor->getText();
if (mMainScriptName.empty())//more sanity if (mMainScriptName.empty())//more sanity
{ {
const LLInventoryItem* item = NULL; const LLInventoryItem* item = nullptr;
LLPreview* preview = (LLPreview*)mCore->mUserdata; LLPreview* preview = (LLPreview*)mCore->mUserdata;
if (preview) if (preview)
{ {
@ -818,16 +790,15 @@ void FSLSLPreprocessor::preprocess_script(BOOL close, bool sync, bool defcache)
mMainScriptName = "(Unknown)"; mMainScriptName = "(Unknown)";
} }
} }
std::string name = mMainScriptName; cached_assetids[mMainScriptName] = LLUUID::null;
cached_assetids[name] = LLUUID::null; cache_script(mMainScriptName, mCore->mEditor->getText());
cache_script(name, script);
//start the party //start the party
start_process(); start_process();
} }
void FSLSLPreprocessor::preprocess_script(const LLUUID& asset_id, LLScriptQueueData* data, LLAssetType::EType type, const std::string& script_data) void FSLSLPreprocessor::preprocess_script(const LLUUID& asset_id, LLScriptQueueData* data, LLAssetType::EType type, const std::string& script_data)
{ {
if(!data) if (!data)
{ {
return; return;
} }
@ -844,7 +815,7 @@ void FSLSLPreprocessor::preprocess_script(const LLUUID& asset_id, LLScriptQueueD
LLStringUtil::format_map_t args; LLStringUtil::format_map_t args;
display_message(LLTrans::getString("fs_preprocessor_starting")); display_message(LLTrans::getString("fs_preprocessor_starting"));
LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"") + gDirUtilp->getDirDelimiter() + "lslpreproc"); LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "lslpreproc"));
if (mData->mItem) if (mData->mItem)
{ {
@ -855,9 +826,8 @@ void FSLSLPreprocessor::preprocess_script(const LLUUID& asset_id, LLScriptQueueD
mMainScriptName = "(Unknown)"; mMainScriptName = "(Unknown)";
} }
std::string name = mMainScriptName; cached_assetids[mMainScriptName] = LLUUID::null;
cached_assetids[name] = LLUUID::null; cache_script(mMainScriptName, script);
cache_script(name, script);
//start the party //start the party
start_process(); start_process();
} }
@ -974,13 +944,6 @@ static inline std::string quicklabel()
return std::string("c") + randstr(5, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); return std::string("c") + randstr(5, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
} }
/* unused:
static std::string minimalize_whitespace(std::string in)
{
return boost::regex_replace(in, boost::regex("\\s*",boost::regex::perl), "\n");
}
*/
static std::string reformat_switch_statements(std::string script, bool &lackDefault) static std::string reformat_switch_statements(std::string script, bool &lackDefault)
{ {
std::string buffer = script; std::string buffer = script;
@ -1584,7 +1547,7 @@ void FSLSLPreprocessor::start_process()
if (mStandalone) if (mStandalone)
{ {
LLFloaterCompileQueue::scriptPreprocComplete(mAssetID, mData, mType, output); LLFloaterCompileQueue::scriptPreprocComplete(mData, mType, output);
} }
else else
{ {
@ -1605,66 +1568,20 @@ void FSLSLPreprocessor::start_process()
mWaving = false; mWaving = false;
} }
#else
std::string FSLSLPreprocessor::encode(const std::string& script) void FSLSLPreprocessor::display_message(std::string_view msg)
{
LLStringUtil::format_map_t args;
args["[WHERE]"] = "encode";
display_error(LLTrans::getString("fs_preprocessor_not_supported", args));
return script;
}
std::string FSLSLPreprocessor::decode(const std::string& script)
{
LLStringUtil::format_map_t args;
args["[WHERE]"] = "decode";
display_error(LLTrans::getString("fs_preprocessor_not_supported", args));
return script;
}
std::string FSLSLPreprocessor::lslopt(std::string script)
{
LLStringUtil::format_map_t args;
args["[WHERE]"] = "lslopt";
display_error(LLTrans::getString("fs_preprocessor_not_supported", args));
return script;
}
void FSLSLPreprocessor::FSProcCacheCallback(LLVFS *vfs, const LLUUID& uuid, LLAssetType::EType type, void *userdata, S32 result, LLExtStat extstat)
{
}
void FSLSLPreprocessor::preprocess_script(BOOL close, bool sync, bool defcache)
{
FSLSLPreProcViewer* outfield = mCore->mPostEditor;
if (outfield)
{
outfield->setText(LLStringExplicit(mCore->mEditor->getText()));
}
mCore->doSaveComplete((void*)mCore, close, sync);
}
void FSLSLPreprocessor::preprocess_script(const LLUUID& asset_id, LLScriptQueueData* data, LLAssetType::EType type, const std::string& script_data)
{
LLFloaterCompileQueue::scriptPreprocComplete(asset_id, data, type, script_data);
}
#endif
void FSLSLPreprocessor::display_message(const std::string& err)
{ {
if (mStandalone) if (mStandalone)
{ {
LLFloaterCompileQueue::scriptLogMessage(mData, err); LLFloaterCompileQueue::scriptLogMessage(mData, msg);
} }
else else
{ {
mCore->mErrorList->addCommentText(err); mCore->mErrorList->addCommentText(msg.data());
} }
} }
void FSLSLPreprocessor::display_error(const std::string& err) void FSLSLPreprocessor::display_error(std::string_view err)
{ {
if (mStandalone) if (mStandalone)
{ {
@ -1673,14 +1590,13 @@ void FSLSLPreprocessor::display_error(const std::string& err)
else else
{ {
LLSD row; LLSD row;
row["columns"][0]["value"] = err; row["columns"][0]["value"] = err.data();
row["columns"][0]["font"] = "SANSSERIF_SMALL"; row["columns"][0]["font"] = "SANSSERIF_SMALL";
mCore->mErrorList->addElement(row); mCore->mErrorList->addElement(row);
} }
} }
bool FSLSLPreprocessor::mono_directive(std::string_view text, bool agent_inv)
bool FSLSLPreprocessor::mono_directive(std::string const& text, bool agent_inv)
{ {
bool domono = agent_inv; bool domono = agent_inv;

View File

@ -37,16 +37,13 @@
#include "llviewerprecompiledheaders.h" #include "llviewerprecompiledheaders.h"
#include "llpreviewscript.h" #include "llpreviewscript.h"
#define DARWINPREPROC
//force preproc on mac
struct LLScriptQueueData; struct LLScriptQueueData;
class FSLSLPreprocessor class FSLSLPreprocessor
{ {
LOG_CLASS(FSLSLPreprocessor); LOG_CLASS(FSLSLPreprocessor);
public:
public:
FSLSLPreprocessor(LLScriptEdCore* corep) FSLSLPreprocessor(LLScriptEdCore* corep)
: mCore(corep), mWaving(false), mClose(FALSE), mSync(false), mStandalone(false) : mCore(corep), mWaving(false), mClose(FALSE), mSync(false), mStandalone(false)
{} {}
@ -55,23 +52,21 @@ public:
: mWaving(false), mClose(FALSE), mSync(false), mStandalone(true) : mWaving(false), mClose(FALSE), mSync(false), mStandalone(true)
{} {}
static bool mono_directive(std::string const& text, bool agent_inv = true); static bool mono_directive(std::string_view text, bool agent_inv = true);
std::string encode(const std::string& script); std::string encode(const std::string& script);
std::string decode(const std::string& script); std::string decode(const std::string& script);
std::string lslopt(std::string script); std::string lslopt(std::string script);
std::string lslcomp(std::string script); std::string lslcomp(std::string script);
static LLUUID findInventoryByName(std::string name); static std::optional<LLUUID> findInventoryByName(std::string_view name);
static void FSProcCacheCallback(const LLUUID& uuid, LLAssetType::EType type, static void FSProcCacheCallback(const LLUUID& uuid, LLAssetType::EType type,
void *userdata, S32 result, LLExtStat extstat); void *userdata, S32 result, LLExtStat extstat);
void preprocess_script(BOOL close = FALSE, bool sync = false, bool defcache = false); void preprocess_script(BOOL close = FALSE, bool sync = false, bool defcache = false);
void preprocess_script(const LLUUID& asset_id, LLScriptQueueData* data, LLAssetType::EType type, const std::string& script_data); void preprocess_script(const LLUUID& asset_id, LLScriptQueueData* data, LLAssetType::EType type, const std::string& script_data);
void start_process(); void start_process();
void display_message(const std::string& err); void display_message(std::string_view msg);
void display_error(const std::string& err); void display_error(std::string_view err);
std::string uncollide_string_literals(std::string script);
//dual function, determines if files have been modified this session and if we have cached them //dual function, determines if files have been modified this session and if we have cached them
//also assetids exposed in-preprocessing as a predefined macro for use in include once style include files, e.g. #define THISFILE file_ ## __ASSETIDRAW__ //also assetids exposed in-preprocessing as a predefined macro for use in include once style include files, e.g. #define THISFILE file_ ## __ASSETIDRAW__
@ -85,8 +80,6 @@ public:
//(it seems rather dumb that readable scripts don't show the asset id without a DL, but thats beside the point.) //(it seems rather dumb that readable scripts don't show the asset id without a DL, but thats beside the point.)
static std::map<std::string, LLUUID> cached_assetids; static std::map<std::string, LLUUID> cached_assetids;
static std::map<std::string, std::string> decollided_literals;
std::set<std::string> caching_files; std::set<std::string> caching_files;
std::set<std::string> defcached_files; std::set<std::string> defcached_files;
bool mDefinitionCaching; bool mDefinitionCaching;

View File

@ -85,15 +85,15 @@ LLContextMenu* FSNameListAvatarMenu::createMenu()
bool FSNameListAvatarMenu::enableContextMenuItem(const LLSD& userdata) bool FSNameListAvatarMenu::enableContextMenuItem(const LLSD& userdata)
{ {
std::string item = userdata.asString(); std::string item = userdata.asString();
bool isSelf = mUUIDs.size() > 0 && mUUIDs.front() == gAgentID; bool isSelf = !mUUIDs.empty() && mUUIDs.front() == gAgentID;
if (item == "remove_friend") if (item == "remove_friend")
{ {
bool result = (mUUIDs.size() > 0); bool result = !mUUIDs.empty();
for (uuid_vec_t::const_iterator it = mUUIDs.begin(); it != mUUIDs.end(); ++it) for (const auto& avid : mUUIDs)
{ {
if (!LLAvatarActions::isFriend(*it)) if (!LLAvatarActions::isFriend(avid))
{ {
result = false; result = false;
break; break;
@ -127,14 +127,14 @@ bool FSNameListAvatarMenu::enableContextMenuItem(const LLSD& userdata)
else if (mUUIDs.size() > 1) else if (mUUIDs.size() > 1)
{ {
// Prevent starting a conference if IMs are blocked for a member // Prevent starting a conference if IMs are blocked for a member
for (uuid_vec_t::const_iterator it = mUUIDs.begin(); it != mUUIDs.end(); ++it) for (const auto& avid : mUUIDs)
{ {
if ((*it) == gAgentID) if (avid == gAgentID)
{ {
continue; continue;
} }
if (!RlvActions::canStartIM(*it)) if (!RlvActions::canStartIM(avid))
{ {
return false; return false;
} }
@ -147,7 +147,7 @@ bool FSNameListAvatarMenu::enableContextMenuItem(const LLSD& userdata)
{ {
if (mUUIDs.size() == 1) if (mUUIDs.size() == 1)
{ {
return (!isSelf && FSRadar::getInstance()->getEntry(mUUIDs.front()) != NULL); return (!isSelf && FSRadar::getInstance()->getEntry(mUUIDs.front()) != nullptr);
} }
return false; return false;
} }
@ -167,7 +167,7 @@ bool FSNameListAvatarMenu::enableContextMenuItem(const LLSD& userdata)
{ {
if (mUUIDs.size() == 1) if (mUUIDs.size() == 1)
{ {
return (!isSelf && FSRadar::getInstance()->getEntry(mUUIDs.front()) != NULL); return (!isSelf && FSRadar::getInstance()->getEntry(mUUIDs.front()) != nullptr);
} }
return false; return false;
} }
@ -191,14 +191,14 @@ bool FSNameListAvatarMenu::enableContextMenuItem(const LLSD& userdata)
void FSNameListAvatarMenu::offerTeleport() void FSNameListAvatarMenu::offerTeleport()
{ {
uuid_vec_t uuids; uuid_vec_t uuids{};
uuids.reserve(mUUIDs.size()); uuids.reserve(mUUIDs.size());
for (uuid_vec_t::const_iterator it = mUUIDs.begin(); it != mUUIDs.end(); ++it) for (const auto& avid : mUUIDs)
{ {
// Skip ourself if sending a TP to more than one agent // Skip ourself if sending a TP to more than one agent
if ((*it) != gAgentID) if (avid != gAgentID)
{ {
uuids.push_back(*it); uuids.emplace_back(avid);
} }
} }
LLAvatarActions::offerTeleport(uuids); LLAvatarActions::offerTeleport(uuids);
@ -216,14 +216,14 @@ void FSNameListAvatarMenu::onTrackAvatarMenuItemClick()
void FSNameListAvatarMenu::addToContactSet() void FSNameListAvatarMenu::addToContactSet()
{ {
uuid_vec_t uuids; uuid_vec_t uuids{};
uuids.reserve(mUUIDs.size()); uuids.reserve(mUUIDs.size());
for (uuid_vec_t::const_iterator it = mUUIDs.begin(); it != mUUIDs.end(); ++it) for (const auto& avid : mUUIDs)
{ {
// Skip ourself if adding more than one agent // Skip ourself if adding more than one agent
if ((*it) != gAgentID) if (avid != gAgentID)
{ {
uuids.push_back(*it); uuids.emplace_back(avid);
} }
} }
LLAvatarActions::addToContactSet(uuids); LLAvatarActions::addToContactSet(uuids);

View File

@ -78,13 +78,13 @@ static LLPanelInjector<FSPanelRadar> t_fs_panel_radar("fs_panel_radar");
FSPanelRadar::FSPanelRadar() FSPanelRadar::FSPanelRadar()
: LLPanel(), : LLPanel(),
mRadarGearButton(NULL), mRadarGearButton(nullptr),
mOptionsButton(NULL), mOptionsButton(nullptr),
mMiniMap(NULL), mMiniMap(nullptr),
mFilterSubString(LLStringUtil::null), mFilterSubString(LLStringUtil::null),
mFilterSubStringOrig(LLStringUtil::null), mFilterSubStringOrig(LLStringUtil::null),
mRadarList(NULL), mRadarList(nullptr),
mVisibleCheckFunction(NULL), mVisibleCheckFunction(),
mUpdateSignalConnection(), mUpdateSignalConnection(),
mFSRadarColumnConfigConnection(), mFSRadarColumnConfigConnection(),
mLastResizeDelta(0) mLastResizeDelta(0)
@ -215,10 +215,9 @@ LLUUID FSPanelRadar::getCurrentItemID() const
void FSPanelRadar::getCurrentItemIDs(uuid_vec_t& selected_uuids) const void FSPanelRadar::getCurrentItemIDs(uuid_vec_t& selected_uuids) const
{ {
std::vector<LLScrollListItem*> selected_items = mRadarList->getAllSelected(); for (auto selected_item : mRadarList->getAllSelected())
for (std::vector<LLScrollListItem*>::iterator it = selected_items.begin(); it != selected_items.end(); ++it)
{ {
selected_uuids.push_back((*it)->getUUID()); selected_uuids.emplace_back(selected_item->getUUID());
} }
} }
@ -314,7 +313,7 @@ void FSPanelRadar::requestUpdate()
void FSPanelRadar::updateList(const std::vector<LLSD>& entries, const LLSD& stats) void FSPanelRadar::updateList(const std::vector<LLSD>& entries, const LLSD& stats)
{ {
if (mVisibleCheckFunction && !mVisibleCheckFunction()) if (!mVisibleCheckFunction.empty() && !mVisibleCheckFunction())
{ {
return; return;
} }
@ -331,11 +330,10 @@ void FSPanelRadar::updateList(const std::vector<LLSD>& entries, const LLSD& stat
{ {
last_selected_id = mRadarList->getLastSelectedItem()->getUUID(); last_selected_id = mRadarList->getLastSelectedItem()->getUUID();
} }
std::vector<LLScrollListItem*> selected_items = mRadarList->getAllSelected();
uuid_vec_t selected_ids; uuid_vec_t selected_ids;
for (std::vector<LLScrollListItem*>::iterator it = selected_items.begin(); it != selected_items.end(); ++it) for (auto selected_item : mRadarList->getAllSelected())
{ {
selected_ids.push_back((*it)->getUUID()); selected_ids.emplace_back(selected_item->getUUID());
} }
S32 lastScroll = mRadarList->getScrollPos(); S32 lastScroll = mRadarList->getScrollPos();
@ -346,11 +344,10 @@ void FSPanelRadar::updateList(const std::vector<LLSD>& entries, const LLSD& stat
mRadarList->setNeedsSort(false); mRadarList->setNeedsSort(false);
mRadarList->clearRows(); mRadarList->clearRows();
const std::vector<LLSD>::const_iterator it_end = entries.end(); for (const auto& avdata : entries)
for (std::vector<LLSD>::const_iterator it = entries.begin(); it != it_end; ++it)
{ {
LLSD entry = (*it)["entry"]; LLSD entry = avdata["entry"];
LLSD options = (*it)["options"]; LLSD options = avdata["options"];
LLSD row_data; LLSD row_data;
row_data["value"] = entry["id"]; row_data["value"] = entry["id"];
@ -480,7 +477,7 @@ void FSPanelRadar::onColumnDisplayModeChanged()
std::vector<LLScrollListColumn::Params> column_params = mRadarList->getColumnInitParams(); std::vector<LLScrollListColumn::Params> column_params = mRadarList->getColumnInitParams();
S32 column_padding = mRadarList->getColumnPadding(); S32 column_padding = mRadarList->getColumnPadding();
LLFloater* parent_floater = NULL; LLFloater* parent_floater = nullptr;
LLView* parent = getParent(); LLView* parent = getParent();
while (parent) while (parent)
{ {
@ -508,10 +505,8 @@ void FSPanelRadar::onColumnDisplayModeChanged()
mRadarList->clearColumns(); mRadarList->clearColumns();
mRadarList->updateLayout(); mRadarList->updateLayout();
std::vector<LLScrollListColumn::Params>::iterator param_it; for (const auto& p : column_params)
for (param_it = column_params.begin(); param_it != column_params.end(); ++param_it)
{ {
LLScrollListColumn::Params p = *param_it;
default_width += (p.width.pixel_width.getValue() + column_padding); default_width += (p.width.pixel_width.getValue() + column_padding);
LLScrollListColumn::Params params; LLScrollListColumn::Params params;

View File

@ -112,10 +112,9 @@ FSRadar::~FSRadar()
{ {
delete mRadarListUpdater; delete mRadarListUpdater;
entry_map_t::iterator em_it_end = mEntryList.end(); for (const auto& [av_id, entry] : mEntryList)
for (entry_map_t::iterator em_it = mEntryList.begin(); em_it != em_it_end; ++em_it)
{ {
delete em_it->second; delete entry;
} }
if (mShowUsernamesCallbackConnection.connected()) if (mShowUsernamesCallbackConnection.connected())
@ -134,7 +133,7 @@ FSRadar::~FSRadar()
} }
} }
void FSRadar::radarAlertMsg(const LLUUID& agent_id, const LLAvatarName& av_name, const std::string& postMsg) void FSRadar::radarAlertMsg(const LLUUID& agent_id, const LLAvatarName& av_name, std::string_view postMsg)
{ {
// <FS:CR> Milkshake-style radar alerts // <FS:CR> Milkshake-style radar alerts
static LLCachedControl<bool> sFSMilkshakeRadarToasts(gSavedSettings, "FSMilkshakeRadarToasts", false); static LLCachedControl<bool> sFSMilkshakeRadarToasts(gSavedSettings, "FSMilkshakeRadarToasts", false);
@ -144,7 +143,7 @@ void FSRadar::radarAlertMsg(const LLUUID& agent_id, const LLAvatarName& av_name,
LLSD payload = agent_id; LLSD payload = agent_id;
LLSD args; LLSD args;
args["NAME"] = FSRadarEntry::getRadarName(av_name); args["NAME"] = FSRadarEntry::getRadarName(av_name);
args["MESSAGE"] = postMsg; args["MESSAGE"] = static_cast<std::string>(postMsg);
LLNotificationsUtil::add("RadarAlert", LLNotificationsUtil::add("RadarAlert",
args, args,
payload.with("respond_on_mousedown", TRUE), payload.with("respond_on_mousedown", TRUE),
@ -250,20 +249,16 @@ void FSRadar::updateRadarList()
// Determine lists of new added and removed avatars // Determine lists of new added and removed avatars
uuid_vec_t current_vec, added_vec, removed_vec; uuid_vec_t current_vec, added_vec, removed_vec;
uuid_vec_t::iterator vec_it_end;
entry_map_t::iterator em_it_end = mEntryList.end();
current_vec.reserve(mEntryList.size()); current_vec.reserve(mEntryList.size());
for (entry_map_t::iterator em_it = mEntryList.begin(); em_it != em_it_end; ++em_it) for (const auto& [av_id, entry] : mEntryList)
{ {
current_vec.push_back(em_it->first); current_vec.emplace_back(av_id);
} }
LLCommonUtils::computeDifference(avatar_ids, current_vec, added_vec, removed_vec); LLCommonUtils::computeDifference(avatar_ids, current_vec, added_vec, removed_vec);
// Remove old avatars from our list // Remove old avatars from our list
vec_it_end = removed_vec.end(); for (const auto& avid : removed_vec)
for (uuid_vec_t::iterator it = removed_vec.begin(); it != vec_it_end; ++it)
{ {
LLUUID avid = *it;
entry_map_t::iterator found = mEntryList.find(avid); entry_map_t::iterator found = mEntryList.find(avid);
if (found != mEntryList.end()) if (found != mEntryList.end())
{ {
@ -273,10 +268,8 @@ void FSRadar::updateRadarList()
} }
// Add new avatars // Add new avatars
vec_it_end = added_vec.end(); for (const auto& avid : added_vec)
for (uuid_vec_t::iterator it = added_vec.begin(); it != vec_it_end; ++it)
{ {
LLUUID avid = *it;
mEntryList[avid] = new FSRadarEntry(avid); mEntryList[avid] = new FSRadarEntry(avid);
} }
@ -695,11 +688,8 @@ void FSRadar::updateRadarList()
// //
if (RlvActions::canShowNearbyAgents()) if (RlvActions::canShowNearbyAgents())
{ {
radarfields_map_t::iterator rf_it_end = mLastRadarSweep.end(); for (const auto& [prevId, rf] : mLastRadarSweep)
for (radarfields_map_t::iterator i = mLastRadarSweep.begin(); i != rf_it_end; ++i)
{ {
LLUUID prevId = i->first;
RadarFields rf = i->second;
if ((sFSRadarShowMutedAndDerendered || !rf.lastIgnore) && mEntryList.find(prevId) == mEntryList.end()) if ((sFSRadarShowMutedAndDerendered || !rf.lastIgnore) && mEntryList.find(prevId) == mEntryList.end())
{ {
if (sRadarReportChatRangeLeave && (rf.lastDistance <= chat_range_say) && rf.lastDistance > AVATAR_UNKNOWN_RANGE) if (sRadarReportChatRangeLeave && (rf.lastDistance <= chat_range_say) && rf.lastDistance > AVATAR_UNKNOWN_RANGE)
@ -797,24 +787,22 @@ void FSRadar::updateRadarList()
// //
mLastRadarSweep.clear(); mLastRadarSweep.clear();
em_it_end = mEntryList.end(); for (const auto& [avid, entry] : mEntryList)
for (entry_map_t::iterator em_it = mEntryList.begin(); em_it != em_it_end; ++em_it)
{ {
FSRadarEntry* ent = em_it->second;
RadarFields rf; RadarFields rf;
rf.lastDistance = ent->mRange; rf.lastDistance = entry->mRange;
rf.lastIgnore = ent->mIgnore; rf.lastIgnore = entry->mIgnore;
rf.lastRegion = LLUUID::null; rf.lastRegion = LLUUID::null;
if (ent->mGlobalPos != LLVector3d(0.0, 0.0, 0.0)) if (entry->mGlobalPos != LLVector3d(0.0, 0.0, 0.0))
{ {
LLViewerRegion* lastRegion = world->getRegionFromPosGlobal(ent->mGlobalPos); LLViewerRegion* lastRegion = world->getRegionFromPosGlobal(entry->mGlobalPos);
if (lastRegion) if (lastRegion)
{ {
rf.lastRegion = lastRegion->getRegionID(); rf.lastRegion = lastRegion->getRegionID();
} }
} }
mLastRadarSweep[ent->mID] = rf; mLastRadarSweep[entry->mID] = rf;
} }
// //
@ -857,7 +845,7 @@ FSRadarEntry* FSRadar::getEntry(const LLUUID& avatar_id)
entry_map_t::iterator found = mEntryList.find(avatar_id); entry_map_t::iterator found = mEntryList.find(avatar_id);
if (found == mEntryList.end()) if (found == mEntryList.end())
{ {
return NULL; return nullptr;
} }
return found->second; return found->second;
} }
@ -1026,7 +1014,7 @@ void FSRadar::updateTracking()
} }
} }
void FSRadar::zoomAvatar(const LLUUID& avatar_id, const std::string& name) void FSRadar::zoomAvatar(const LLUUID& avatar_id, std::string_view name)
{ {
if (LLAvatarActions::canZoomIn(avatar_id)) if (LLAvatarActions::canZoomIn(avatar_id))
{ {
@ -1035,7 +1023,7 @@ void FSRadar::zoomAvatar(const LLUUID& avatar_id, const std::string& name)
else else
{ {
LLStringUtil::format_map_t args; LLStringUtil::format_map_t args;
args["AVATARNAME"] = name.c_str(); args["AVATARNAME"] = static_cast<std::string>(name);
report_to_nearby_chat(LLTrans::getString("camera_no_focus", args)); report_to_nearby_chat(LLTrans::getString("camera_no_focus", args));
} }
} }
@ -1060,9 +1048,17 @@ void FSRadar::updateName(const LLUUID& avatar_id)
void FSRadar::updateAgeAlertCheck() void FSRadar::updateAgeAlertCheck()
{ {
const entry_map_t::iterator it_end = mEntryList.end(); for (auto& [av_id, entry] : mEntryList)
for (entry_map_t::iterator it = mEntryList.begin(); it != it_end; ++it)
{ {
it->second->checkAge(); entry->checkAge();
}
}
void FSRadar::updateNotes(const LLUUID& avatar_id, std::string_view notes)
{
FSRadarEntry* entry = getEntry(avatar_id);
if (entry)
{
entry->setNotes(notes);
} }
} }

View File

@ -67,11 +67,12 @@ public:
entry_map_t getRadarList() { return mEntryList; } entry_map_t getRadarList() { return mEntryList; }
void startTracking(const LLUUID& avatar_id); void startTracking(const LLUUID& avatar_id);
void zoomAvatar(const LLUUID& avatar_id, const std::string& name); void zoomAvatar(const LLUUID& avatar_id, std::string_view name);
void teleportToAvatar(const LLUUID& targetAv); void teleportToAvatar(const LLUUID& targetAv);
void requestRadarChannelAlertSync(); void requestRadarChannelAlertSync();
void updateNames(); void updateNames();
void updateName(const LLUUID& avatar_id); void updateName(const LLUUID& avatar_id);
void updateNotes(const LLUUID& avatar_id, std::string_view notes);
static void onRadarNameFmtClicked(const LLSD& userdata); static void onRadarNameFmtClicked(const LLSD& userdata);
static bool radarNameFmtCheck(const LLSD& userdata); static bool radarNameFmtCheck(const LLSD& userdata);
@ -112,7 +113,7 @@ private:
void updateRadarList(); void updateRadarList();
void updateTracking(); void updateTracking();
void checkTracking(); void checkTracking();
void radarAlertMsg(const LLUUID& agent_id, const LLAvatarName& av_name, const std::string& postMsg); void radarAlertMsg(const LLUUID& agent_id, const LLAvatarName& av_name, std::string_view postMsg);
void updateAgeAlertCheck(); void updateAgeAlertCheck();
Updater* mRadarListUpdater; Updater* mRadarListUpdater;

View File

@ -39,12 +39,12 @@ FSRadarEntry::FSRadarEntry(const LLUUID& avid)
mUserName(LLStringUtil::null), mUserName(LLStringUtil::null),
mDisplayName(LLStringUtil::null), mDisplayName(LLStringUtil::null),
mRange(0.f), mRange(0.f),
mFirstSeen(time(NULL)), mFirstSeen(time(nullptr)),
mGlobalPos(LLVector3d(0.0, 0.0, 0.0)), mGlobalPos(LLVector3d(0.0, 0.0, 0.0)),
mRegion(LLUUID::null), mRegion(LLUUID::null),
mStatus(0), mStatus(0),
mZOffset(0.f), mZOffset(0.f),
mLastZOffsetTime(time(NULL)), mLastZOffsetTime(time(nullptr)),
mAge(-1), mAge(-1),
mIsLinden(false), mIsLinden(false),
mIgnore(false), mIgnore(false),
@ -126,8 +126,7 @@ void FSRadarEntry::processProperties(void* data, EAvatarProcessorType type)
LLAvatarNotes* avatar_notes = static_cast<LLAvatarNotes*>(data); LLAvatarNotes* avatar_notes = static_cast<LLAvatarNotes*>(data);
if (avatar_notes && avatar_notes->agent_id == gAgentID && avatar_notes->target_id == mID && !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) if (avatar_notes && avatar_notes->agent_id == gAgentID && avatar_notes->target_id == mID && !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
{ {
mNotes = avatar_notes->notes; setNotes(avatar_notes->notes);
LLStringUtil::trim(mNotes);
} }
} }
} }
@ -191,3 +190,9 @@ void FSRadarEntry::checkAge()
mAgeAlertPerformed = true; mAgeAlertPerformed = true;
} }
} }
void FSRadarEntry::setNotes(std::string_view notes)
{
mNotes = notes;
LLStringUtil::trim(mNotes);
}

View File

@ -63,6 +63,8 @@ public:
static std::string getRadarName(const LLAvatarName& av_name); static std::string getRadarName(const LLAvatarName& av_name);
void setNotes(std::string_view notes);
private: private:
void updateName(); void updateName();
void onAvatarNameCache(const LLUUID& av_id, const LLAvatarName& av_name); void onAvatarNameCache(const LLUUID& av_id, const LLAvatarName& av_name);

View File

@ -96,11 +96,7 @@ void LLAccountingCostManager::accountingCostCoro(std::string url,
LLSD dataToPost = LLSD::emptyMap(); LLSD dataToPost = LLSD::emptyMap();
dataToPost[keystr.c_str()] = objectList; dataToPost[keystr.c_str()] = objectList;
LLAccountingCostObserver* observer = observerHandle.get(); LLAccountingCostObserver* observer = NULL;
LLUUID transactionId = observer->getTransactionID();
observer = NULL;
LLSD results = httpAdapter->postAndSuspend(httpRequest, url, dataToPost); LLSD results = httpAdapter->postAndSuspend(httpRequest, url, dataToPost);

View File

@ -46,6 +46,7 @@
- (void)dealloc - (void)dealloc
{ {
[currentInputLanguage release];
[super dealloc]; [super dealloc];
} }
@ -199,17 +200,17 @@
- (bool) romanScript - (bool) romanScript
{ {
// How to add support for new languages with the input window: @autoreleasepool {
// Simply append this array with the language code (ja for japanese, ko for korean, zh for chinese, etc.) // How to add support for new languages with the input window:
NSArray *nonRomanScript = [[NSArray alloc] initWithObjects:@"ja", @"ko", @"zh-Hant", @"zh-Hans", nil]; // Simply append this array with the language code (ja for japanese, ko for korean, zh for chinese, etc.)
bool ret = true; NSArray* nonRomanScript = @[@"ja", @"ko", @"zh-Hant", @"zh-Hans"];
if ([nonRomanScript containsObject:currentInputLanguage]) if ([nonRomanScript containsObject:currentInputLanguage])
{ {
ret = false; return false;
}
} }
[nonRomanScript release];
return ret; return true;
} }
#if defined(LL_BUGSPLAT) #if defined(LL_BUGSPLAT)

View File

@ -4504,7 +4504,7 @@ void LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, boo
// existence of AIS as an indicator the fix is present. Does // existence of AIS as an indicator the fix is present. Does
// not actually use AIS to create the category. // not actually use AIS to create the category.
inventory_func_type func = boost::bind(&LLAppearanceMgr::onOutfitFolderCreated,this,_1,show_panel); inventory_func_type func = boost::bind(&LLAppearanceMgr::onOutfitFolderCreated,this,_1,show_panel);
LLUUID folder_id = gInventory.createNewCategory( gInventory.createNewCategory(
parent_id, parent_id,
LLFolderType::FT_OUTFIT, LLFolderType::FT_OUTFIT,
new_folder_name, new_folder_name,

View File

@ -150,6 +150,10 @@
#include "vlc/libvlc_version.h" #include "vlc/libvlc_version.h"
#endif // LL_LINUX #endif // LL_LINUX
#if LL_DARWIN
#include "llwindowmacosx.h"
#endif
// Third party library includes // Third party library includes
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
@ -638,6 +642,7 @@ static void settings_to_globals()
LLWorldMapView::setScaleSetting(gSavedSettings.getF32("MapScale")); LLWorldMapView::setScaleSetting(gSavedSettings.getF32("MapScale"));
#if LL_DARWIN #if LL_DARWIN
LLWindowMacOSX::sUseMultGL = gSavedSettings.getBOOL("RenderAppleUseMultGL");
gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI"); gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI");
#endif #endif
} }
@ -2025,7 +2030,8 @@ bool LLAppViewer::cleanup()
{ {
if (!isSecondInstance()) if (!isSecondInstance())
{ {
LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv")); std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv");
LLSceneMonitor::instance().dumpToFile(dump_path);
} }
LLSceneMonitor::deleteSingleton(); LLSceneMonitor::deleteSingleton();
} }

View File

@ -364,11 +364,10 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi
} }
} }
// static
// Called every frame - send render weight requests to every region // Called every frame - send render weight requests to every region
void LLAvatarRenderInfoAccountant::idle() void LLAvatarRenderInfoAccountant::idle()
{ {
if (mRenderInfoScanTimer.hasExpired()) if (mRenderInfoScanTimer.hasExpired() && !LLApp::isExiting())
{ {
LL_DEBUGS("AvatarRenderInfo") << "Scanning regions for render info updates" LL_DEBUGS("AvatarRenderInfo") << "Scanning regions for render info updates"
<< LL_ENDL; << LL_ENDL;

View File

@ -43,7 +43,7 @@ class LLBuyCurrencyHTMLHandler :
{ {
public: public:
// requests will be throttled from a non-trusted browser // requests will be throttled from a non-trusted browser
LLBuyCurrencyHTMLHandler() : LLCommandHandler( "buycurrencyhtml", UNTRUSTED_ALLOW ) {} LLBuyCurrencyHTMLHandler() : LLCommandHandler( "buycurrencyhtml", UNTRUSTED_THROTTLE) {}
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
{ {

View File

@ -723,8 +723,7 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg)
{ {
if(mBuddyInfo.find(agent_id) != mBuddyInfo.end()) if(mBuddyInfo.find(agent_id) != mBuddyInfo.end())
{ {
if (((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS) if (((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS))
&& !gAgent.isDoNotDisturb())
{ {
LLSD args; LLSD args;
// <FS:Ansariel> Always show complete name in rights dialogs // <FS:Ansariel> Always show complete name in rights dialogs
@ -803,19 +802,18 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
// we were tracking someone who went offline // we were tracking someone who went offline
deleteTrackingData(); deleteTrackingData();
} }
// } <FS:Beq/> [FIRE-32324] least invasive change move this brace after the if. LL fix should follow sometime soon
//[FIX FIRE-3522 : SJ] Notify Online/Offline to Nearby Chat even if chat_notify isnt true
// <FS:PP> Attempt to speed up things a little //[FIX FIRE-3522 : SJ] Notify Online/Offline to Nearby Chat even if chat_notify isnt true
// if(chat_notify||LGGContactSets::getInstance()->notifyForFriend(agent_id)||gSavedSettings.getBOOL("OnlineOfflinetoNearbyChat")) // <FS:PP> Attempt to speed up things a little
static LLCachedControl<bool> OnlineOfflinetoNearbyChat(gSavedSettings, "OnlineOfflinetoNearbyChat"); // if(chat_notify||LGGContactSets::getInstance()->notifyForFriend(agent_id)||gSavedSettings.getBOOL("OnlineOfflinetoNearbyChat"))
if(chat_notify || LGGContactSets::getInstance()->notifyForFriend(agent_id) || OnlineOfflinetoNearbyChat) static LLCachedControl<bool> OnlineOfflinetoNearbyChat(gSavedSettings, "OnlineOfflinetoNearbyChat");
// </FS:PP> if(chat_notify || LGGContactSets::getInstance()->notifyForFriend(agent_id) || OnlineOfflinetoNearbyChat)
{ // </FS:PP>
// Look up the name of this agent for the notification {
LLAvatarNameCache::get(agent_id,boost::bind(&on_avatar_name_cache_notify,_1, _2, online, payload)); // Look up the name of this agent for the notification
LLAvatarNameCache::get(agent_id,boost::bind(&on_avatar_name_cache_notify,_1, _2, online, payload));
}
} }
} // <FS:Beq/> [FIRE-32324] least invasive change move this brace after the if
mModifyMask |= LLFriendObserver::ONLINE; mModifyMask |= LLFriendObserver::ONLINE;
instance().notifyObservers(); instance().notifyObservers();

View File

@ -155,6 +155,18 @@ public:
{ {
mAvatarNameCacheConnection.disconnect(); mAvatarNameCacheConnection.disconnect();
} }
auto menu = mPopupMenuHandleAvatar.get();
if (menu)
{
menu->die();
mPopupMenuHandleAvatar.markDead();
}
menu = mPopupMenuHandleObject.get();
if (menu)
{
menu->die();
mPopupMenuHandleObject.markDead();
}
} }
BOOL handleMouseUp(S32 x, S32 y, MASK mask) BOOL handleMouseUp(S32 x, S32 y, MASK mask)
@ -587,36 +599,6 @@ public:
BOOL postBuild() BOOL postBuild()
{ {
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar registrar_enable;
registrar.add("AvatarIcon.Action", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemClicked, this, _2));
registrar_enable.add("AvatarIcon.Check", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemChecked, this, _2));
registrar_enable.add("AvatarIcon.Enable", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemEnabled, this, _2));
registrar_enable.add("AvatarIcon.Visible", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemVisible, this, _2));
registrar.add("ObjectIcon.Action", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemClicked, this, _2));
registrar_enable.add("ObjectIcon.Visible", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemVisible, this, _2));
LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_avatar_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
if (menu)
{
mPopupMenuHandleAvatar = menu->getHandle();
}
else
{
LL_WARNS() << " Failed to create menu_avatar_icon.xml" << LL_ENDL;
}
menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_object_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
if (menu)
{
mPopupMenuHandleObject = menu->getHandle();
}
else
{
LL_WARNS() << " Failed to create menu_object_icon.xml" << LL_ENDL;
}
setDoubleClickCallback(boost::bind(&LLChatHistoryHeader::showInspector, this)); setDoubleClickCallback(boost::bind(&LLChatHistoryHeader::showInspector, this));
setMouseEnterCallback(boost::bind(&LLChatHistoryHeader::showInfoCtrl, this)); setMouseEnterCallback(boost::bind(&LLChatHistoryHeader::showInfoCtrl, this));
@ -937,13 +919,53 @@ protected:
void showObjectContextMenu(S32 x,S32 y) void showObjectContextMenu(S32 x,S32 y)
{ {
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandleObject.get(); LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandleObject.get();
if(menu) if (!menu)
{
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar registrar_enable;
registrar.add("ObjectIcon.Action", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemClicked, this, _2));
registrar_enable.add("ObjectIcon.Visible", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemVisible, this, _2));
menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_object_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
if (menu)
{
mPopupMenuHandleObject = menu->getHandle();
menu->updateParent(LLMenuGL::sMenuContainer);
LLMenuGL::showPopup(this, menu, x, y);
}
else
{
LL_WARNS() << " Failed to create menu_object_icon.xml" << LL_ENDL;
}
}
else
{
LLMenuGL::showPopup(this, menu, x, y); LLMenuGL::showPopup(this, menu, x, y);
}
} }
void showAvatarContextMenu(S32 x,S32 y) void showAvatarContextMenu(S32 x,S32 y)
{ {
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandleAvatar.get(); LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandleAvatar.get();
if (!menu)
{
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar registrar_enable;
registrar.add("AvatarIcon.Action", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemClicked, this, _2));
registrar_enable.add("AvatarIcon.Check", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemChecked, this, _2));
registrar_enable.add("AvatarIcon.Enable", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemEnabled, this, _2));
registrar_enable.add("AvatarIcon.Visible", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemVisible, this, _2));
menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_avatar_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
if (menu)
{
mPopupMenuHandleAvatar = menu->getHandle();
}
else
{
LL_WARNS() << " Failed to create menu_avatar_icon.xml" << LL_ENDL;
}
}
if(menu) if(menu)
{ {
@ -1144,10 +1166,7 @@ LLChatHistory::LLChatHistory(const LLChatHistory::Params& p)
LLSD LLChatHistory::getValue() const LLSD LLChatHistory::getValue() const
{ {
LLSD* text=new LLSD(); return LLSD(mEditor->getText());
text->assign(mEditor->getText());
return *text;
} }
LLChatHistory::~LLChatHistory() LLChatHistory::~LLChatHistory()

View File

@ -98,7 +98,6 @@ LLSysWellChiclet::LLSysWellChiclet(const Params& p)
, mMaxDisplayedCount(p.max_displayed_count) , mMaxDisplayedCount(p.max_displayed_count)
, mIsNewMessagesState(false) , mIsNewMessagesState(false)
, mFlashToLitTimer(NULL) , mFlashToLitTimer(NULL)
, mContextMenu(NULL)
{ {
LLButton::Params button_params = p.button; LLButton::Params button_params = p.button;
mButton = LLUICtrlFactory::create<LLButton>(button_params); mButton = LLUICtrlFactory::create<LLButton>(button_params);
@ -110,6 +109,12 @@ LLSysWellChiclet::LLSysWellChiclet(const Params& p)
LLSysWellChiclet::~LLSysWellChiclet() LLSysWellChiclet::~LLSysWellChiclet()
{ {
mFlashToLitTimer->unset(); mFlashToLitTimer->unset();
LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
if (menu)
{
menu->die();
mContextMenuHandle.markDead();
}
} }
void LLSysWellChiclet::setCounter(S32 counter) void LLSysWellChiclet::setCounter(S32 counter)
@ -176,14 +181,16 @@ void LLSysWellChiclet::updateWidget(bool is_window_empty)
// virtual // virtual
BOOL LLSysWellChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) BOOL LLSysWellChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
{ {
if(!mContextMenu) LLContextMenu* menu_avatar = mContextMenuHandle.get();
if(!menu_avatar)
{ {
createMenu(); createMenu();
menu_avatar = mContextMenuHandle.get();
} }
if (mContextMenu) if (menu_avatar)
{ {
mContextMenu->show(x, y); menu_avatar->show(x, y);
LLMenuGL::showPopup(this, mContextMenu, x, y); LLMenuGL::showPopup(this, menu_avatar, x, y);
} }
return TRUE; return TRUE;
} }
@ -207,6 +214,13 @@ LLIMWellChiclet::LLIMWellChiclet(const Params& p)
LLIMWellChiclet::~LLIMWellChiclet() LLIMWellChiclet::~LLIMWellChiclet()
{ {
LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
if (menu)
{
menu->die();
mContextMenuHandle.markDead();
}
LLIMWellWindow* im_well_window = LLIMWellWindow::findInstance(); LLIMWellWindow* im_well_window = LLIMWellWindow::findInstance();
if (im_well_window) if (im_well_window)
{ {
@ -237,7 +251,7 @@ bool LLIMWellChiclet::enableMenuItem(const LLSD& user_data)
void LLIMWellChiclet::createMenu() void LLIMWellChiclet::createMenu()
{ {
if(mContextMenu) if(mContextMenuHandle.get())
{ {
LL_WARNS() << "Menu already exists" << LL_ENDL; LL_WARNS() << "Menu already exists" << LL_ENDL;
return; return;
@ -251,10 +265,14 @@ void LLIMWellChiclet::createMenu()
enable_registrar.add("IMWellChicletMenu.EnableItem", enable_registrar.add("IMWellChicletMenu.EnableItem",
boost::bind(&LLIMWellChiclet::enableMenuItem, this, _2)); boost::bind(&LLIMWellChiclet::enableMenuItem, this, _2));
mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu> LLContextMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>
("menu_fs_im_well_button.xml", ("menu_fs_im_well_button.xml",
LLMenuGL::sMenuContainer, LLMenuGL::sMenuContainer,
LLViewerMenuHolderGL::child_registry_t::instance()); LLViewerMenuHolderGL::child_registry_t::instance());
if (menu)
{
mContextMenuHandle = menu->getHandle();
}
} }
void LLIMWellChiclet::messageCountChanged(const LLSD& session_data) void LLIMWellChiclet::messageCountChanged(const LLSD& session_data)
@ -358,7 +376,7 @@ bool LLNotificationChiclet::enableMenuItem(const LLSD& user_data)
void LLNotificationChiclet::createMenu() void LLNotificationChiclet::createMenu()
{ {
if(mContextMenu) if(mContextMenuHandle.get())
{ {
LL_WARNS() << "Menu already exists" << LL_ENDL; LL_WARNS() << "Menu already exists" << LL_ENDL;
return; return;
@ -373,10 +391,14 @@ void LLNotificationChiclet::createMenu()
boost::bind(&LLNotificationChiclet::enableMenuItem, this, _2)); boost::bind(&LLNotificationChiclet::enableMenuItem, this, _2));
llassert(LLMenuGL::sMenuContainer != NULL); llassert(LLMenuGL::sMenuContainer != NULL);
mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu> LLContextMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>
("menu_notification_well_button.xml", ("menu_notification_well_button.xml",
LLMenuGL::sMenuContainer, LLMenuGL::sMenuContainer,
LLViewerMenuHolderGL::child_registry_t::instance()); LLViewerMenuHolderGL::child_registry_t::instance());
if (menu)
{
mContextMenuHandle = menu->getHandle();
}
} }
/*virtual*/ /*virtual*/
@ -492,12 +514,21 @@ LLIMChiclet::LLIMChiclet(const LLIMChiclet::Params& p)
, mCounterCtrl(NULL) , mCounterCtrl(NULL)
// </FS:Ansariel> [FS communication UI] // </FS:Ansariel> [FS communication UI]
, mChicletButton(NULL) , mChicletButton(NULL)
, mPopupMenu(NULL)
{ {
// <FS:Ansariel> [FS communication UI] // <FS:Ansariel> [FS communication UI]
enableCounterControl(p.enable_counter); enableCounterControl(p.enable_counter);
} }
LLIMChiclet::~LLIMChiclet()
{
auto menu = mPopupMenuHandle.get();
if (menu)
{
menu->die();
mPopupMenuHandle.markDead();
}
}
/* virtual*/ /* virtual*/
BOOL LLIMChiclet::postBuild() BOOL LLIMChiclet::postBuild()
{ {
@ -688,16 +719,18 @@ LLIMChiclet::EType LLIMChiclet::getIMSessionType(const LLUUID& session_id)
BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
{ {
if(!mPopupMenu) auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get());
if(!menu)
{ {
createPopupMenu(); createPopupMenu();
menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get());
} }
if (mPopupMenu) if (menu)
{ {
updateMenuItems(); updateMenuItems();
mPopupMenu->arrangeAndClear(); menu->arrangeAndClear();
LLMenuGL::showPopup(this, mPopupMenu, x, y); LLMenuGL::showPopup(this, menu, x, y);
} }
return TRUE; return TRUE;
@ -705,15 +738,16 @@ BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
void LLIMChiclet::hidePopupMenu() void LLIMChiclet::hidePopupMenu()
{ {
if (mPopupMenu) auto menu = mPopupMenuHandle.get();
if (menu)
{ {
mPopupMenu->setVisible(FALSE); menu->setVisible(FALSE);
} }
} }
bool LLIMChiclet::canCreateMenu() bool LLIMChiclet::canCreateMenu()
{ {
if(mPopupMenu) if(mPopupMenuHandle.get())
{ {
LL_WARNS() << "Menu already exists" << LL_ENDL; LL_WARNS() << "Menu already exists" << LL_ENDL;
return false; return false;
@ -784,17 +818,17 @@ void LLIMP2PChiclet::setOtherParticipantId(const LLUUID& other_participant_id)
void LLIMP2PChiclet::updateMenuItems() void LLIMP2PChiclet::updateMenuItems()
{ {
if(!mPopupMenu) if(!mPopupMenuHandle.get())
return; return;
if(getSessionId().isNull()) if(getSessionId().isNull())
return; return;
FSFloaterIM* open_im_floater = FSFloaterIM::findInstance(getSessionId()); FSFloaterIM* open_im_floater = FSFloaterIM::findInstance(getSessionId());
bool open_window_exists = open_im_floater && open_im_floater->getVisible(); bool open_window_exists = open_im_floater && open_im_floater->getVisible();
mPopupMenu->getChild<LLUICtrl>("Send IM")->setEnabled(!open_window_exists); mPopupMenuHandle.get()->getChild<LLUICtrl>("Send IM")->setEnabled(!open_window_exists);
bool is_friend = LLAvatarActions::isFriend(getOtherParticipantId()); bool is_friend = LLAvatarActions::isFriend(getOtherParticipantId());
mPopupMenu->getChild<LLUICtrl>("Add Friend")->setEnabled(!is_friend); mPopupMenuHandle.get()->getChild<LLUICtrl>("Add Friend")->setEnabled(!is_friend);
} }
void LLIMP2PChiclet::createPopupMenu() void LLIMP2PChiclet::createPopupMenu()
@ -805,8 +839,12 @@ void LLIMP2PChiclet::createPopupMenu()
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
registrar.add("IMChicletMenu.Action", boost::bind(&LLIMP2PChiclet::onMenuItemClicked, this, _2)); registrar.add("IMChicletMenu.Action", boost::bind(&LLIMP2PChiclet::onMenuItemClicked, this, _2));
mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
("menu_fs_imchiclet_p2p.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); ("menu_fs_imchiclet_p2p.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
if (menu)
{
mPopupMenuHandle = menu->getHandle();
}
} }
void LLIMP2PChiclet::onMenuItemClicked(const LLSD& user_data) void LLIMP2PChiclet::onMenuItemClicked(const LLSD& user_data)
@ -925,8 +963,12 @@ void LLAdHocChiclet::createPopupMenu()
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
registrar.add("IMChicletMenu.Action", boost::bind(&LLAdHocChiclet::onMenuItemClicked, this, _2)); registrar.add("IMChicletMenu.Action", boost::bind(&LLAdHocChiclet::onMenuItemClicked, this, _2));
mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> auto menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
("menu_fs_imchiclet_adhoc.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); ("menu_fs_imchiclet_adhoc.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
if (menu)
{
mPopupMenuHandle = menu->getHandle();
}
} }
void LLAdHocChiclet::onMenuItemClicked(const LLSD& user_data) void LLAdHocChiclet::onMenuItemClicked(const LLSD& user_data)
@ -1060,14 +1102,14 @@ void LLIMGroupChiclet::changed(LLGroupChange gc)
void LLIMGroupChiclet::updateMenuItems() void LLIMGroupChiclet::updateMenuItems()
{ {
if(!mPopupMenu) if(!mPopupMenuHandle.get())
return; return;
if(getSessionId().isNull()) if(getSessionId().isNull())
return; return;
FSFloaterIM* open_im_floater = FSFloaterIM::findInstance(getSessionId()); FSFloaterIM* open_im_floater = FSFloaterIM::findInstance(getSessionId());
bool open_window_exists = open_im_floater && open_im_floater->getVisible(); bool open_window_exists = open_im_floater && open_im_floater->getVisible();
mPopupMenu->getChild<LLUICtrl>("Chat")->setEnabled(!open_window_exists); mPopupMenuHandle.get()->getChild<LLUICtrl>("Chat")->setEnabled(!open_window_exists);
} }
void LLIMGroupChiclet::createPopupMenu() void LLIMGroupChiclet::createPopupMenu()
@ -1078,8 +1120,12 @@ void LLIMGroupChiclet::createPopupMenu()
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
registrar.add("IMChicletMenu.Action", boost::bind(&LLIMGroupChiclet::onMenuItemClicked, this, _2)); registrar.add("IMChicletMenu.Action", boost::bind(&LLIMGroupChiclet::onMenuItemClicked, this, _2));
mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> auto menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
("menu_fs_imchiclet_group.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); ("menu_fs_imchiclet_group.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
if (menu)
{
mPopupMenuHandle = menu->getHandle();
}
} }
void LLIMGroupChiclet::onMenuItemClicked(const LLSD& user_data) void LLIMGroupChiclet::onMenuItemClicked(const LLSD& user_data)
@ -2010,8 +2056,13 @@ void LLScriptChiclet::createPopupMenu()
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
registrar.add("ScriptChiclet.Action", boost::bind(&LLScriptChiclet::onMenuItemClicked, this, _2)); registrar.add("ScriptChiclet.Action", boost::bind(&LLScriptChiclet::onMenuItemClicked, this, _2));
mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
("menu_script_chiclet.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); ("menu_script_chiclet.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
if (menu)
{
mPopupMenuHandle = menu->getHandle();
}
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -2095,8 +2146,12 @@ void LLInvOfferChiclet::createPopupMenu()
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
registrar.add("InvOfferChiclet.Action", boost::bind(&LLInvOfferChiclet::onMenuItemClicked, this, _2)); registrar.add("InvOfferChiclet.Action", boost::bind(&LLInvOfferChiclet::onMenuItemClicked, this, _2));
mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
("menu_inv_offer_chiclet.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); ("menu_inv_offer_chiclet.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
if (menu)
{
mPopupMenuHandle = menu->getHandle();
}
} }
// EOF // EOF

View File

@ -325,7 +325,7 @@ public:
{}; {};
virtual ~LLIMChiclet() {}; virtual ~LLIMChiclet();
/** /**
* It is used for default setting up of chicklet:click handler, etc. * It is used for default setting up of chicklet:click handler, etc.
@ -456,7 +456,7 @@ protected:
bool canCreateMenu(); bool canCreateMenu();
LLMenuGL* mPopupMenu; LLHandle<LLUICtrl> mPopupMenuHandle;
bool mShowSpeaker; bool mShowSpeaker;
bool mCounterEnabled; bool mCounterEnabled;
@ -633,6 +633,8 @@ public:
*/ */
/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); } /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
/*virtual*/ ~LLIMP2PChiclet() {};
protected: protected:
LLIMP2PChiclet(const Params& p); LLIMP2PChiclet(const Params& p);
friend class LLUICtrlFactory; friend class LLUICtrlFactory;
@ -705,6 +707,8 @@ public:
*/ */
/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); } /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
/*virtual*/ ~LLAdHocChiclet() {};
protected: protected:
LLAdHocChiclet(const Params& p); LLAdHocChiclet(const Params& p);
friend class LLUICtrlFactory; friend class LLUICtrlFactory;
@ -884,7 +888,7 @@ protected:
bool mIsNewMessagesState; bool mIsNewMessagesState;
LLFlashTimer* mFlashToLitTimer; LLFlashTimer* mFlashToLitTimer;
LLContextMenu* mContextMenu; LLHandle<LLContextMenu> mContextMenuHandle;
}; };
class LLNotificationChiclet : public LLSysWellChiclet class LLNotificationChiclet : public LLSysWellChiclet

View File

@ -39,6 +39,7 @@
#define THROTTLE_PERIOD 5 // required seconds between throttled commands #define THROTTLE_PERIOD 5 // required seconds between throttled commands
static LLCommandDispatcherListener sCommandDispatcherListener; static LLCommandDispatcherListener sCommandDispatcherListener;
const std::string LLCommandHandler::NAV_TYPE_CLICKED = "clicked";
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Underlying registry for command handlers, not directly accessible. // Underlying registry for command handlers, not directly accessible.
@ -64,6 +65,9 @@ public:
bool trusted_browser); bool trusted_browser);
private: private:
void notifySlurlBlocked();
void notifySlurlThrottled();
friend LLSD LLCommandDispatcher::enumerate(); friend LLSD LLCommandDispatcher::enumerate();
std::map<std::string, LLCommandHandlerInfo> mMap; std::map<std::string, LLCommandHandlerInfo> mMap;
}; };
@ -96,8 +100,6 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
const std::string& nav_type, const std::string& nav_type,
bool trusted_browser) bool trusted_browser)
{ {
static bool slurl_blocked = false;
static bool slurl_throttled = false;
static F64 last_throttle_time = 0.0; static F64 last_throttle_time = 0.0;
F64 cur_time = 0.0; F64 cur_time = 0.0;
std::map<std::string, LLCommandHandlerInfo>::iterator it = mMap.find(cmd); std::map<std::string, LLCommandHandlerInfo>::iterator it = mMap.find(cmd);
@ -115,44 +117,45 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
// block request from external browser, but report as // block request from external browser, but report as
// "handled" because it was well formatted. // "handled" because it was well formatted.
LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL; LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL;
if (! slurl_blocked) notifySlurlBlocked();
{
if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT)
{
// Note: commands can arrive before we initialize everything we need for Notification.
LLNotificationsUtil::add("BlockedSLURL");
}
slurl_blocked = true;
}
return true; return true;
case LLCommandHandler::UNTRUSTED_CLICK_ONLY:
if (nav_type == LLCommandHandler::NAV_TYPE_CLICKED
&& info.mHandler->canHandleUntrusted(params, query_map, web, nav_type))
{
break;
}
LL_WARNS_ONCE("SLURL") << "Blocked SLURL click-only command " << cmd << " from untrusted browser" << LL_ENDL;
notifySlurlBlocked();
return true;
case LLCommandHandler::UNTRUSTED_THROTTLE: case LLCommandHandler::UNTRUSTED_THROTTLE:
// if users actually click on a link, we don't need to throttle it
// (throttling mechanism is used to prevent an avalanche of clicks via
// javascript
if ( nav_type == "clicked" )
{
break;
}
//skip initial request from external browser before STATE_BROWSER_INIT //skip initial request from external browser before STATE_BROWSER_INIT
if (LLStartUp::getStartupState() == STATE_FIRST) if (LLStartUp::getStartupState() == STATE_FIRST)
{ {
return true; return true;
} }
if (!info.mHandler->canHandleUntrusted(params, query_map, web, nav_type))
{
LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL;
notifySlurlBlocked();
return true;
}
// if users actually click on a link, we don't need to throttle it
// (throttling mechanism is used to prevent an avalanche of clicks via
// javascript
if (nav_type == LLCommandHandler::NAV_TYPE_CLICKED)
{
break;
}
cur_time = LLTimer::getElapsedSeconds(); cur_time = LLTimer::getElapsedSeconds();
if (cur_time < last_throttle_time + THROTTLE_PERIOD) if (cur_time < last_throttle_time + THROTTLE_PERIOD)
{ {
// block request from external browser if it happened // block request from external browser if it happened
// within THROTTLE_PERIOD seconds of the last command // within THROTTLE_PERIOD seconds of the last command
LL_WARNS_ONCE("SLURL") << "Throttled SLURL command from untrusted browser" << LL_ENDL; LL_WARNS_ONCE("SLURL") << "Throttled SLURL command from untrusted browser" << LL_ENDL;
if (! slurl_throttled) notifySlurlThrottled();
{
if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT)
{
LLNotificationsUtil::add("ThrottledSLURL");
}
slurl_throttled = true;
}
return true; return true;
} }
last_throttle_time = cur_time; last_throttle_time = cur_time;
@ -163,6 +166,34 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
return info.mHandler->handle(params, query_map, web); return info.mHandler->handle(params, query_map, web);
} }
void LLCommandHandlerRegistry::notifySlurlBlocked()
{
static bool slurl_blocked = false;
if (!slurl_blocked)
{
if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT)
{
// Note: commands can arrive before we initialize everything we need for Notification.
LLNotificationsUtil::add("BlockedSLURL");
}
slurl_blocked = true;
}
}
void LLCommandHandlerRegistry::notifySlurlThrottled()
{
static bool slurl_throttled = false;
if (!slurl_throttled)
{
if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT)
{
// Note: commands can arrive before we initialize everything we need for Notification.
LLNotificationsUtil::add("ThrottledSLURL");
}
slurl_throttled = true;
}
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Automatic registration of commands, runs before main() // Automatic registration of commands, runs before main()
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -230,6 +261,7 @@ symbol_info symbols[] =
{ {
ent(LLCommandHandler::UNTRUSTED_ALLOW), // allow commands from untrusted browsers ent(LLCommandHandler::UNTRUSTED_ALLOW), // allow commands from untrusted browsers
ent(LLCommandHandler::UNTRUSTED_BLOCK), // ignore commands from untrusted browsers ent(LLCommandHandler::UNTRUSTED_BLOCK), // ignore commands from untrusted browsers
ent(LLCommandHandler::UNTRUSTED_CLICK_ONLY), // allow untrusted, but only if clicked
ent(LLCommandHandler::UNTRUSTED_THROTTLE) // allow untrusted, but only a few per min. ent(LLCommandHandler::UNTRUSTED_THROTTLE) // allow untrusted, but only a few per min.
}; };

View File

@ -65,9 +65,12 @@ public:
{ {
UNTRUSTED_ALLOW, // allow commands from untrusted browsers UNTRUSTED_ALLOW, // allow commands from untrusted browsers
UNTRUSTED_BLOCK, // ignore commands from untrusted browsers UNTRUSTED_BLOCK, // ignore commands from untrusted browsers
UNTRUSTED_CLICK_ONLY, // allow untrusted, but only if clicked
UNTRUSTED_THROTTLE // allow untrusted, but only a few per min. UNTRUSTED_THROTTLE // allow untrusted, but only a few per min.
}; };
static const std::string NAV_TYPE_CLICKED;
LLCommandHandler(const char* command, EUntrustedAccess untrusted_access); LLCommandHandler(const char* command, EUntrustedAccess untrusted_access);
// Automatically registers object to get called when // Automatically registers object to get called when
// command is executed. All commands can be processed // command is executed. All commands can be processed
@ -76,6 +79,13 @@ public:
virtual ~LLCommandHandler(); virtual ~LLCommandHandler();
virtual bool canHandleUntrusted(
const LLSD& params,
const LLSD& query_map,
LLMediaCtrl* web,
const std::string& nav_type)
{ return true; }
virtual bool handle(const LLSD& params, virtual bool handle(const LLSD& params,
const LLSD& query_map, const LLSD& query_map,
LLMediaCtrl* web) = 0; LLMediaCtrl* web) = 0;

View File

@ -1114,28 +1114,23 @@ void LLFloaterCompileQueue::finishLSLUpload(LLUUID itemId, LLUUID taskId, LLUUID
// This is the callback after the script has been processed by preproc // This is the callback after the script has been processed by preproc
// static // static
void LLFloaterCompileQueue::scriptPreprocComplete(const LLUUID& asset_id, LLScriptQueueData* data, LLAssetType::EType type, const std::string& script_text) void LLFloaterCompileQueue::scriptPreprocComplete(LLScriptQueueData* data, LLAssetType::EType type, const std::string& script_text)
{ {
LL_INFOS() << "LLFloaterCompileQueue::scriptPreprocComplete()" << LL_ENDL; LL_INFOS() << "LLFloaterCompileQueue::scriptPreprocComplete()" << LL_ENDL;
if (!data) if (!data)
{ {
return; return;
} }
LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", data->mQueueID);
LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", data->mQueueID);
if (queue) if (queue)
{ {
std::string filename; constexpr bool is_running{ true };
std::string uuid_str;
asset_id.toString(uuid_str);
filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str) + llformat(".%s",LLAssetType::lookup(type));
const bool is_running = true;
LLViewerObject* object = gObjectList.findObject(data->mTaskId); LLViewerObject* object = gObjectList.findObject(data->mTaskId);
if (object) if (object)
{ {
std::string scriptName = data->mItem->getName(); const std::string scriptName = data->mItem->getName();
std::string url = object->getRegion()->getCapability("UpdateScriptTask"); const std::string url = object->getRegion() ? object->getRegion()->getCapability("UpdateScriptTask") : std::string();
if (!url.empty()) if (!url.empty())
{ {
queue->addProcessingMessage("CompileQueuePreprocessingComplete", LLSD().with("SCRIPT", scriptName)); queue->addProcessingMessage("CompileQueuePreprocessingComplete", LLSD().with("SCRIPT", scriptName));
@ -1166,7 +1161,7 @@ void LLFloaterCompileQueue::scriptPreprocComplete(const LLUUID& asset_id, LLScri
} }
// static // static
void LLFloaterCompileQueue::scriptLogMessage(LLScriptQueueData* data, std::string message) void LLFloaterCompileQueue::scriptLogMessage(LLScriptQueueData* data, std::string_view message)
{ {
if (!data) if (!data)
{ {
@ -1175,7 +1170,7 @@ void LLFloaterCompileQueue::scriptLogMessage(LLScriptQueueData* data, std::strin
LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", data->mQueueID); LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", data->mQueueID);
if (queue) if (queue)
{ {
queue->addStringMessage(message); queue->addStringMessage(static_cast<std::string>(message));
} }
} }
// </FS:KC> // </FS:KC>

View File

@ -150,8 +150,8 @@ public:
// <FS:KC> [LSL PreProc] // <FS:KC> [LSL PreProc]
static void finishLSLUpload(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response, std::string scriptName, LLUUID queueId); static void finishLSLUpload(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response, std::string scriptName, LLUUID queueId);
static void scriptPreprocComplete(const LLUUID& asset_id, LLScriptQueueData* data, LLAssetType::EType type, const std::string& script_text); static void scriptPreprocComplete(LLScriptQueueData* data, LLAssetType::EType type, const std::string& script_text);
static void scriptLogMessage(LLScriptQueueData* data, std::string message); static void scriptLogMessage(LLScriptQueueData* data, std::string_view message);
protected: protected:
LLFloaterCompileQueue(const LLSD& key); LLFloaterCompileQueue(const LLSD& key);
virtual ~LLFloaterCompileQueue(); virtual ~LLFloaterCompileQueue();

View File

@ -691,7 +691,6 @@ namespace
if (!injection->mBlendIn) if (!injection->mBlendIn)
mix = 1.0 - mix; mix = 1.0 - mix;
stringset_t dummy; stringset_t dummy;
LLUUID cloud_noise_id = getCloudNoiseTextureId();
F64 value = this->mSettings[injection->mKeyName].asReal(); F64 value = this->mSettings[injection->mKeyName].asReal();
if (this->getCloudNoiseTextureId().isNull()) if (this->getCloudNoiseTextureId().isNull())
{ {
@ -3231,7 +3230,7 @@ bool LLEnvironment::loadFromSettings()
LL_INFOS("ENVIRONMENT") << "Unable to open previous session environment file " << user_filepath << LL_ENDL; LL_INFOS("ENVIRONMENT") << "Unable to open previous session environment file " << user_filepath << LL_ENDL;
} }
if (!env_data.isMap() || env_data.emptyMap()) if (!env_data.isMap() || (env_data.size() == 0))
{ {
LL_DEBUGS("ENVIRONMENT") << "Empty map loaded from: " << user_filepath << LL_ENDL; LL_DEBUGS("ENVIRONMENT") << "Empty map loaded from: " << user_filepath << LL_ENDL;
return false; return false;

View File

@ -643,9 +643,9 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename,
#elif LL_DARWIN #elif LL_DARWIN
std::vector<std::string>* LLFilePicker::navOpenFilterProc(ELoadFilter filter) //(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode) std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadFilter filter) //(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode)
{ {
std::vector<std::string> *allowedv = new std::vector< std::string >; std::unique_ptr<std::vector<std::string>> allowedv(new std::vector< std::string >);
switch(filter) switch(filter)
{ {
case FFLOAD_ALL: case FFLOAD_ALL:
@ -730,9 +730,9 @@ bool LLFilePicker::doNavChooseDialog(ELoadFilter filter)
gViewerWindow->getWindow()->beforeDialog(); gViewerWindow->getWindow()->beforeDialog();
std::vector<std::string> *allowed_types=navOpenFilterProc(filter); std::unique_ptr<std::vector<std::string>> allowed_types = navOpenFilterProc(filter);
std::vector<std::string> *filev = doLoadDialog(allowed_types, std::unique_ptr<std::vector<std::string>> filev = doLoadDialog(allowed_types.get(),
mPickOptions); mPickOptions);
gViewerWindow->getWindow()->afterDialog(); gViewerWindow->getWindow()->afterDialog();
@ -873,7 +873,7 @@ bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filena
gViewerWindow->getWindow()->beforeDialog(); gViewerWindow->getWindow()->beforeDialog();
// Run the dialog // Run the dialog
std::string* filev = doSaveDialog(&namestring, std::unique_ptr<std::string> filev = doSaveDialog(&namestring,
&type, &type,
&creator, &creator,
&extension, &extension,

View File

@ -182,7 +182,7 @@ private:
bool doNavChooseDialog(ELoadFilter filter); bool doNavChooseDialog(ELoadFilter filter);
bool doNavSaveDialog(ESaveFilter filter, const std::string& filename); bool doNavSaveDialog(ESaveFilter filter, const std::string& filename);
std::vector<std::string>* navOpenFilterProc(ELoadFilter filter); std::unique_ptr<std::vector<std::string>> navOpenFilterProc(ELoadFilter filter);
#endif #endif
#if LL_GTK #if LL_GTK

View File

@ -39,9 +39,9 @@
#include <vector> #include <vector>
//void modelessPicker(); //void modelessPicker();
std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types, std::unique_ptr<std::vector<std::string>> doLoadDialog(const std::vector<std::string>* allowed_types,
unsigned int flags); unsigned int flags);
std::string* doSaveDialog(const std::string* file, std::unique_ptr<std::string> doSaveDialog(const std::string* file,
const std::string* type, const std::string* type,
const std::string* creator, const std::string* creator,
const std::string* extension, const std::string* extension,

View File

@ -29,111 +29,107 @@
#include <iostream> #include <iostream>
#include "llfilepicker_mac.h" #include "llfilepicker_mac.h"
std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types, std::unique_ptr<std::vector<std::string>> doLoadDialog(const std::vector<std::string>* allowed_types,
unsigned int flags) unsigned int flags)
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // <FS> Fix mem leak by Cinder Roxley std::unique_ptr<std::vector<std::string>> outfiles;
int i, result;
//Aura TODO: We could init a small window and release it at the end of this routine @autoreleasepool {
//for a modeless interface. int i, result;
//Aura TODO: We could init a small window and release it at the end of this routine
//for a modeless interface.
NSOpenPanel *panel = [NSOpenPanel openPanel]; NSOpenPanel *panel = [NSOpenPanel openPanel];
//NSString *fileName = nil; //NSString *fileName = nil;
NSMutableArray *fileTypes = nil; NSMutableArray *fileTypes = nil;
if ( allowed_types && !allowed_types->empty())
if ( allowed_types && !allowed_types->empty())
{
fileTypes = [[NSMutableArray alloc] init];
for (i=0;i<allowed_types->size();++i)
{ {
[fileTypes addObject: fileTypes = [[[NSMutableArray alloc] init] autorelease];
[NSString stringWithCString:(*allowed_types)[i].c_str()
encoding:[NSString defaultCStringEncoding]]]; for (i=0;i<allowed_types->size();++i)
{
[fileTypes addObject:
[NSString stringWithCString:(*allowed_types)[i].c_str()
encoding:[NSString defaultCStringEncoding]]];
}
} }
}
//[panel setMessage:@"Import one or more files or directories."]; //[panel setMessage:@"Import one or more files or directories."];
[panel setAllowsMultipleSelection: ( (flags & F_MULTIPLE)?true:false ) ]; [panel setAllowsMultipleSelection: ( (flags & F_MULTIPLE)?true:false ) ];
[panel setCanChooseDirectories: ( (flags & F_DIRECTORY)?true:false ) ]; [panel setCanChooseDirectories: ( (flags & F_DIRECTORY)?true:false ) ];
[panel setCanCreateDirectories: true]; [panel setCanCreateDirectories: true];
[panel setResolvesAliases: true]; [panel setResolvesAliases: true];
[panel setCanChooseFiles: ( (flags & F_FILE)?true:false )]; [panel setCanChooseFiles: ( (flags & F_FILE)?true:false )];
[panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ]; [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
std::vector<std::string>* outfiles = NULL; if (fileTypes)
if (fileTypes)
{
[panel setAllowedFileTypes:fileTypes];
result = [panel runModal];
}
else
{
// I suggest it's better to open the last path and let this default to home dir as necessary
// for consistency with other OS X apps
//
//[panel setDirectoryURL: fileURLWithPath(NSHomeDirectory()) ];
result = [panel runModal];
}
if (result == NSOKButton)
{
NSArray *filesToOpen = [panel URLs];
int i, count = [filesToOpen count];
if (count > 0)
{ {
outfiles = new std::vector<std::string>; [panel setAllowedFileTypes:fileTypes];
result = [panel runModal];
}
else
{
// I suggest it's better to open the last path and let this default to home dir as necessary
// for consistency with other OS X apps
//
//[panel setDirectoryURL: fileURLWithPath(NSHomeDirectory()) ];
result = [panel runModal];
} }
for (i=0; i<count; i++) { if (result == NSOKButton)
NSString *aFile = [[filesToOpen objectAtIndex:i] path]; {
std::string *afilestr = new std::string([aFile UTF8String]); NSArray *filesToOpen = [panel URLs];
outfiles->push_back(*afilestr); int i, count = [filesToOpen count];
if (count > 0)
{
outfiles.reset(new std::vector<std::string>);
}
for (i=0; i<count; i++) {
NSString *aFile = [[filesToOpen objectAtIndex:i] path];
std::string afilestr = std::string([aFile UTF8String]);
outfiles->push_back(afilestr);
}
} }
} }
[pool release]; // <FS> Fix mem leak by Cinder Roxley
return outfiles; return outfiles;
} }
std::string* doSaveDialog(const std::string* file, std::unique_ptr<std::string> doSaveDialog(const std::string* file,
const std::string* type, const std::string* type,
const std::string* creator, const std::string* creator,
const std::string* extension, const std::string* extension,
unsigned int flags) unsigned int flags)
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // <FS> Fix mem leak by Cinder Roxley std::unique_ptr<std::string> outfile;
NSSavePanel *panel = [NSSavePanel savePanel]; @autoreleasepool {
NSSavePanel *panel = [NSSavePanel savePanel];
NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]]; NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]];
NSArray *fileType = [extensionns componentsSeparatedByString:@","]; NSArray *fileType = [extensionns componentsSeparatedByString:@","];
//[panel setMessage:@"Save Image File"]; //[panel setMessage:@"Save Image File"];
[panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ]; [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
[panel setCanSelectHiddenExtension:true]; [panel setCanSelectHiddenExtension:true];
[panel setAllowedFileTypes:fileType]; [panel setAllowedFileTypes:fileType];
NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]]; NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]];
std::string *outfile = NULL; NSURL* url = [NSURL fileURLWithPath:fileName];
NSURL* url = [NSURL fileURLWithPath:fileName]; [panel setNameFieldStringValue: fileName];
[panel setNameFieldStringValue: fileName]; [panel setDirectoryURL: url];
[panel setDirectoryURL: url]; if([panel runModal] ==
[panel setNameFieldStringValue: fileName]; // <FS:CR> Populate filename in the save panel NSFileHandlingPanelOKButton)
if([panel runModal] == {
NSFileHandlingPanelOKButton) NSURL* url = [panel URL];
{ NSString* p = [url path];
NSURL* url = [panel URL]; outfile.reset(new std::string([p UTF8String]));
NSString* p = [url path]; // write the file
outfile = new std::string( [p UTF8String] ); }
// write the file
} }
[pool release]; // <FS> Fix mem leak by Cinder Roxley
return outfile; return outfile;
} }

View File

@ -553,7 +553,8 @@ void LLFloater360Capture::capture360Images()
// We need to convert from the angle getYaw() gives us into something // We need to convert from the angle getYaw() gives us into something
// the XMP data field wants (N=0, E=90, S=180, W= 270 etc.) // the XMP data field wants (N=0, E=90, S=180, W= 270 etc.)
mInitialHeadingDeg = (360 + 90 - (int)(camera->getYaw() * RAD_TO_DEG)) % 360; mInitialHeadingDeg = (360 + 90 - (int)(camera->getYaw() * RAD_TO_DEG)) % 360;
LL_INFOS("360Capture") << "Recording a heading of " << (int)(mInitialHeadingDeg) << LL_ENDL; LL_INFOS("360Capture") << "Recording a heading of " << (int)(mInitialHeadingDeg)
<< " Image size: " << (S32)mSourceImageSize << LL_ENDL;
// camera constants for the square, cube map capture image // camera constants for the square, cube map capture image
camera->setAspect(1.0); // must set aspect ratio first to avoid undesirable clamping of vertical FoV camera->setAspect(1.0); // must set aspect ratio first to avoid undesirable clamping of vertical FoV
@ -603,6 +604,9 @@ void LLFloater360Capture::capture360Images()
// for each of the 6 directions we shoot... // for each of the 6 directions we shoot...
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
{ {
LLAppViewer::instance()->pauseMainloopTimeout();
LLViewerStats::instance().getRecording().stop();
// these buffers are where the raw, captured pixels are stored and // these buffers are where the raw, captured pixels are stored and
// the first time we use them, we have to make a new one // the first time we use them, we have to make a new one
if (mRawImages[i] == nullptr) if (mRawImages[i] == nullptr)
@ -640,8 +644,10 @@ void LLFloater360Capture::capture360Images()
auto duration = std::chrono::duration_cast<std::chrono::duration<double>>(t_end - t_start); auto duration = std::chrono::duration_cast<std::chrono::duration<double>>(t_end - t_start);
encode_time_total += duration.count(); encode_time_total += duration.count();
// ping the main loop in case the snapshot process takes a really long LLViewerStats::instance().getRecording().resume();
// time and we get disconnected LLAppViewer::instance()->resumeMainloopTimeout();
// update main loop timeout state
LLAppViewer::instance()->pingMainloopTimeout("LLFloater360Capture::capture360Images"); LLAppViewer::instance()->pingMainloopTimeout("LLFloater360Capture::capture360Images");
} }

View File

@ -48,12 +48,11 @@ LLFloaterAvatar::LLFloaterAvatar(const LLSD& key)
LLFloaterAvatar::~LLFloaterAvatar() LLFloaterAvatar::~LLFloaterAvatar()
{ {
LLMediaCtrl* avatar_picker = findChild<LLMediaCtrl>("avatar_picker_contents"); if (mAvatarPicker)
if (avatar_picker)
{ {
avatar_picker->navigateStop(); mAvatarPicker->navigateStop();
avatar_picker->clearCache(); //images are reloading each time already mAvatarPicker->clearCache(); //images are reloading each time already
avatar_picker->unloadMediaSource(); mAvatarPicker->unloadMediaSource();
} }
// <FS:Ansariel> Avatar chooser does not change between OpenSim grids // <FS:Ansariel> Avatar chooser does not change between OpenSim grids
@ -66,6 +65,11 @@ LLFloaterAvatar::~LLFloaterAvatar()
BOOL LLFloaterAvatar::postBuild() BOOL LLFloaterAvatar::postBuild()
{ {
mAvatarPicker = findChild<LLMediaCtrl>("avatar_picker_contents");
if (mAvatarPicker)
{
mAvatarPicker->clearCache();
}
enableResizeCtrls(true, true, false); enableResizeCtrls(true, true, false);
return TRUE; return TRUE;
} }

View File

@ -29,6 +29,7 @@
#define LL_FLOATER_AVATAR_H #define LL_FLOATER_AVATAR_H
#include "llfloater.h" #include "llfloater.h"
class LLMediaCtrl;
class LLFloaterAvatar: class LLFloaterAvatar:
public LLFloater public LLFloater
@ -39,6 +40,8 @@ private:
/*virtual*/ ~LLFloaterAvatar(); /*virtual*/ ~LLFloaterAvatar();
/*virtual*/ BOOL postBuild(); /*virtual*/ BOOL postBuild();
LLMediaCtrl* mAvatarPicker;
// <FS:Ansariel> Avatar chooser does not change between OpenSim grids // <FS:Ansariel> Avatar chooser does not change between OpenSim grids
/*virtual*/ void onOpen(const LLSD& key); /*virtual*/ void onOpen(const LLSD& key);
void handleUrlChanged(const std::string& url); void handleUrlChanged(const std::string& url);

View File

@ -81,6 +81,14 @@ LLFloaterBump::LLFloaterBump(const LLSD& key)
// Destroys the object // Destroys the object
LLFloaterBump::~LLFloaterBump() LLFloaterBump::~LLFloaterBump()
{ {
// <FS:Ansariel> Improved bump list
//auto menu = mPopupMenuHandle.get();
//if (menu)
//{
// menu->die();
// mPopupMenuHandle.markDead();
//}
// </FS:Ansariel>
} }
BOOL LLFloaterBump::postBuild() BOOL LLFloaterBump::postBuild()
@ -90,11 +98,15 @@ BOOL LLFloaterBump::postBuild()
//mList->setAllowMultipleSelection(false); //mList->setAllowMultipleSelection(false);
//mList->setRightMouseDownCallback(boost::bind(&LLFloaterBump::onScrollListRightClicked, this, _1, _2, _3)); //mList->setRightMouseDownCallback(boost::bind(&LLFloaterBump::onScrollListRightClicked, this, _1, _2, _3));
//mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_avatar_other.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); //LLContextMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_avatar_other.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
//mPopupMenu->setItemVisible(std::string("Normal"), false); //if (menu)
//mPopupMenu->setItemVisible(std::string("Always use impostor"), false); //{
//mPopupMenu->setItemVisible(std::string("Never use impostor"), false); // mPopupMenuHandle = menu->getHandle();
//mPopupMenu->setItemVisible(std::string("Impostor seperator"), false); // menu->setItemVisible(std::string("Normal"), false);
// menu->setItemVisible(std::string("Always use impostor"), false);
// menu->setItemVisible(std::string("Never use impostor"), false);
// menu->setItemVisible(std::string("Impostor seperator"), false);
//}
//return TRUE; //return TRUE;
mList = getChild<FSScrollListCtrl>("bump_list"); mList = getChild<FSScrollListCtrl>("bump_list");
@ -227,18 +239,19 @@ void LLFloaterBump::onScrollListRightClicked(LLUICtrl* ctrl, S32 x, S32 y)
if (!gMeanCollisionList.empty()) if (!gMeanCollisionList.empty())
{ {
LLScrollListItem* item = mList->hitItem(x, y); LLScrollListItem* item = mList->hitItem(x, y);
if (item && mPopupMenu) auto menu = mPopupMenuHandle.get();
if (item && menu)
{ {
mItemUUID = item->getUUID(); mItemUUID = item->getUUID();
mPopupMenu->buildDrawLabels(); menu->buildDrawLabels();
mPopupMenu->updateParent(LLMenuGL::sMenuContainer); menu->updateParent(LLMenuGL::sMenuContainer);
std::string mute_msg = (LLMuteList::getInstance()->isMuted(mItemUUID, mNames[mItemUUID])) ? "UnmuteAvatar" : "MuteAvatar"; std::string mute_msg = (LLMuteList::getInstance()->isMuted(mItemUUID, mNames[mItemUUID])) ? "UnmuteAvatar" : "MuteAvatar";
mPopupMenu->getChild<LLUICtrl>("Avatar Mute")->setValue(LLTrans::getString(mute_msg)); menu->getChild<LLUICtrl>("Avatar Mute")->setValue(LLTrans::getString(mute_msg));
mPopupMenu->setItemEnabled(std::string("Zoom In"), bool(gObjectList.findObject(mItemUUID))); menu->setItemEnabled(std::string("Zoom In"), bool(gObjectList.findObject(mItemUUID)));
((LLContextMenu*)mPopupMenu)->show(x, y); menu->show(x, y);
LLMenuGL::showPopup(ctrl, mPopupMenu, x, y); LLMenuGL::showPopup(ctrl, menu, x, y);
} }
} }
} }

View File

@ -76,7 +76,7 @@ private:
// <FS:Ansariel> Improved bump list // <FS:Ansariel> Improved bump list
//LLScrollListCtrl* mList; //LLScrollListCtrl* mList;
//LLMenuGL* mPopupMenu; //LLHandle<LLContextMenu> mPopupMenuHandle;
//LLUUID mItemUUID; //LLUUID mItemUUID;
//typedef std::map<LLUUID, std::string> uuid_map_t; //typedef std::map<LLUUID, std::string> uuid_map_t;

View File

@ -324,7 +324,6 @@ void LLFloaterCreateLandmark::onSaveClicked()
LLStringUtil::trim(current_title_value); LLStringUtil::trim(current_title_value);
LLStringUtil::trim(current_notes_value); LLStringUtil::trim(current_notes_value);
LLUUID item_id = mItem->getUUID();
LLUUID folder_id = mFolderCombo->getValue().asUUID(); LLUUID folder_id = mFolderCombo->getValue().asUUID();
bool change_parent = folder_id != mItem->getParentUUID(); bool change_parent = folder_id != mItem->getParentUUID();

View File

@ -215,6 +215,7 @@ BOOL LLFloaterIMContainer::postBuild()
p.options_menu = "menu_conversation.xml"; p.options_menu = "menu_conversation.xml";
mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p); mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar); mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
mConversationsRoot->setEnableRegistrar(&mEnableCallbackRegistrar);
// Add listener to conversation model events // Add listener to conversation model events
mConversationsEventStream.listen("ConversationsRefresh", boost::bind(&LLFloaterIMContainer::onConversationModelEvent, this, _1)); mConversationsEventStream.listen("ConversationsRefresh", boost::bind(&LLFloaterIMContainer::onConversationModelEvent, this, _1));

View File

@ -318,6 +318,7 @@ BOOL LLFloaterIMSessionTab::postBuild()
p.name = "root"; p.name = "root";
mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p); mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar); mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
mConversationsRoot->setEnableRegistrar(&mEnableCallbackRegistrar);
// Attach that root to the scroller // Attach that root to the scroller
mScroller->addChild(mConversationsRoot); mScroller->addChild(mConversationsRoot);
mConversationsRoot->setScrollContainer(mScroller); mConversationsRoot->setScrollContainer(mScroller);

View File

@ -1938,7 +1938,7 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible)
childSetTextArg("download_weight", "[ST]", tbd); childSetTextArg("download_weight", "[ST]", tbd);
childSetTextArg("server_weight", "[SIM]", tbd); childSetTextArg("server_weight", "[SIM]", tbd);
childSetTextArg("physics_weight", "[PH]", tbd); childSetTextArg("physics_weight", "[PH]", tbd);
if (!mModelPhysicsFee.isMap() || mModelPhysicsFee.emptyMap()) if (!mModelPhysicsFee.isMap() || (mModelPhysicsFee.size() == 0))
{ {
childSetTextArg("upload_fee", "[FEE]", tbd); childSetTextArg("upload_fee", "[FEE]", tbd);
} }

View File

@ -59,8 +59,6 @@ LLFloaterOpenObject::LLFloaterOpenObject(const LLSD& key)
{ {
// <FS:Ansariel> Cinder's fly-out button // <FS:Ansariel> Cinder's fly-out button
//mCommitCallbackRegistrar.add("OpenObject.MoveToInventory", boost::bind(&LLFloaterOpenObject::onClickMoveToInventory, this)); //mCommitCallbackRegistrar.add("OpenObject.MoveToInventory", boost::bind(&LLFloaterOpenObject::onClickMoveToInventory, this));
//mCommitCallbackRegistrar.add("OpenObject.MoveAndWear", boost::bind(&LLFloaterOpenObject::onClickMoveAndWear, this));
//mCommitCallbackRegistrar.add("OpenObject.ReplaceOutfit", boost::bind(&LLFloaterOpenObject::onClickReplace, this));
mCommitCallbackRegistrar.add("OpenObject.CopyAction", boost::bind(&LLFloaterOpenObject::onClickCopy, this, _2)); mCommitCallbackRegistrar.add("OpenObject.CopyAction", boost::bind(&LLFloaterOpenObject::onClickCopy, this, _2));
// </FS:Ansariel> // </FS:Ansariel>
mCommitCallbackRegistrar.add("OpenObject.Cancel", boost::bind(&LLFloaterOpenObject::onClickCancel, this)); mCommitCallbackRegistrar.add("OpenObject.Cancel", boost::bind(&LLFloaterOpenObject::onClickCancel, this));
@ -260,18 +258,6 @@ void LLFloaterOpenObject::callbackMoveInventory(S32 result, void* data)
// moveToInventory(false); // moveToInventory(false);
// closeFloater(); // closeFloater();
//} //}
//
//void LLFloaterOpenObject::onClickMoveAndWear()
//{
// moveToInventory(true, false);
// closeFloater();
//}
//
//void LLFloaterOpenObject::onClickReplace()
//{
// moveToInventory(true, true);
// closeFloater();
//}
// </FS:Ansariel> // </FS:Ansariel>
void LLFloaterOpenObject::onClickCancel() void LLFloaterOpenObject::onClickCancel()

View File

@ -64,8 +64,6 @@ protected:
// <FS:Ansariel> Cinder's fly-out button // <FS:Ansariel> Cinder's fly-out button
//void onClickMoveToInventory(); //void onClickMoveToInventory();
//void onClickMoveAndWear();
//void onClickReplace();
void onClickCopy(const LLSD& value); void onClickCopy(const LLSD& value);
// </FS:Ansariel> // </FS:Ansariel>
void onClickCancel(); void onClickCancel();

View File

@ -234,7 +234,6 @@ void LLFloaterOutfitPhotoPreview::updateImageID()
if(item) if(item)
{ {
mImageID = item->getAssetUUID(); mImageID = item->getAssetUUID();
LLPermissions perm(item->getPermissions());
} }
else else
{ {

Some files were not shown because too many files have changed in this diff Show More