Merge branch 'master' into DRTVWR-544-maint

# Conflicts:
#	indra/newview/app_settings/settings.xml
#	indra/newview/llfloatersearch.cpp
#	indra/newview/llgroupactions.cpp
#	indra/newview/llvovolume.cpp
master
Andrey Lihatskiy 2022-04-18 20:43:49 +03:00
commit 026ad511ea
73 changed files with 1110 additions and 406 deletions

17
.pre-commit-config.yaml Normal file
View File

@ -0,0 +1,17 @@
repos:
- repo: https://bitbucket.org/lindenlab/git-hooks.git
rev: v1.0.0-beta2
hooks:
- id: opensource-license
- id: jira-issue
- id: llsd
- id: no-trigraphs
- id: copyright
- id: end-of-file
files: \.(cpp|c|h|py|glsl|cmake|txt)$
exclude: language.txt
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.5.0
hooks:
- id: check-xml
- id: mixed-line-ending

View File

@ -2201,18 +2201,18 @@
<key>archive</key>
<map>
<key>hash</key>
<string>95cb09a712b7b61e992fe68ab7bf8c72</string>
<string>d6e7ab8483c348f223fd24028e27a52f</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/92744/837149/llca-202201010217.567162-common-567162.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/93933/844890/llca-202202010217.567974-common-567974.tar.bz2</string>
</map>
<key>name</key>
<string>common</string>
</map>
</map>
<key>version</key>
<string>202201010217.567162</string>
<string>202202010217.567974</string>
</map>
<key>llphysicsextensions_source</key>
<map>
@ -3272,9 +3272,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>33ed1bb3e24fbd3462da04fb3e917e94</string>
<string>1dda5fb3bb649b0ab5a93f22df7cb11e</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/94814/850320/viewer_manager-3.0.568552-darwin64-568552.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/96998/862110/viewer_manager-3.0.569958-darwin64-569958.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -3296,9 +3296,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>2ad8e04965ac8bddb7d351abe09bee07</string>
<string>30d1386d0a6883d898fc56757a789b8b</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/94813/850316/viewer_manager-3.0.568552-windows-568552.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/97002/862130/viewer_manager-3.0.569958-windows-569958.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -3309,7 +3309,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>source_type</key>
<string>hg</string>
<key>version</key>
<string>3.0.568552</string>
<string>3.0.569958</string>
</map>
<key>vlc-bin</key>
<map>

View File

@ -1403,6 +1403,15 @@ bool LLAudioSource::setupChannel()
return true;
}
void LLAudioSource::stop()
{
play(LLUUID::null);
if (mCurrentDatap)
{
// always reset data if something wants us to stop
mCurrentDatap = nullptr;
}
}
bool LLAudioSource::play(const LLUUID &audio_uuid)
{

View File

@ -304,7 +304,13 @@ public:
LLAudioBuffer *getCurrentBuffer();
bool setupChannel();
bool play(const LLUUID &audio_id); // Start the audio source playing
// Stop the audio source, reset audio id even if muted
void stop();
// Start the audio source playing,
// takes mute into account to preserve previous id if nessesary
bool play(const LLUUID &audio_id);
bool hasPendingPreloads() const; // Has preloads that haven't been done yet

View File

@ -266,14 +266,25 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl
// protected_fixedsize_stack sets a guard page past the end of the new
// stack so that stack underflow will result in an access violation
// instead of weird, subtle, possibly undiagnosed memory stomps.
boost::fibers::fiber newCoro(boost::fibers::launch::dispatch,
std::allocator_arg,
boost::fibers::protected_fixedsize_stack(mStackSize),
[this, &name, &callable](){ toplevel(name, callable); });
// You have two choices with a fiber instance: you can join() it or you
// can detach() it. If you try to destroy the instance before doing
// either, the program silently terminates. We don't need this handle.
newCoro.detach();
try
{
boost::fibers::fiber newCoro(boost::fibers::launch::dispatch,
std::allocator_arg,
boost::fibers::protected_fixedsize_stack(mStackSize),
[this, &name, &callable]() { toplevel(name, callable); });
// You have two choices with a fiber instance: you can join() it or you
// can detach() it. If you try to destroy the instance before doing
// either, the program silently terminates. We don't need this handle.
newCoro.detach();
}
catch (std::bad_alloc&)
{
// Out of memory on stack allocation?
LL_ERRS("LLCoros") << "Bad memory allocation in LLCoros::launch(" << prefix << ")!" << LL_ENDL;
}
return name;
}

View File

@ -101,7 +101,7 @@ void storeToLLSDPath(LLSD& dest, const LLSD& path, const LLSD& value)
}
// Drill down to where we should store 'value'.
llsd::drill(dest, path) = value;
llsd::drill_ref(dest, path) = value;
}
} // anonymous

View File

@ -29,6 +29,7 @@
#include "linden_common.h"
#include "llsdutil.h"
#include <sstream>
#if LL_WINDOWS
# define WIN32_LEAN_AND_MEAN
@ -862,7 +863,7 @@ bool llsd_equals(const LLSD& lhs, const LLSD& rhs, int bits)
namespace llsd
{
LLSD& drill(LLSD& blob, const LLSD& rawPath)
LLSD& drill_ref(LLSD& blob, const LLSD& rawPath)
{
// Treat rawPath uniformly as an array. If it's not already an array,
// store it as the only entry in one. (But let's say Undefined means an
@ -917,9 +918,9 @@ LLSD& drill(LLSD& blob, const LLSD& rawPath)
LLSD drill(const LLSD& blob, const LLSD& path)
{
// non-const drill() does exactly what we want. Temporarily cast away
// drill_ref() does exactly what we want. Temporarily cast away
// const-ness and use that.
return drill(const_cast<LLSD&>(blob), path);
return drill_ref(const_cast<LLSD&>(blob), path);
}
} // namespace llsd

View File

@ -184,10 +184,10 @@ namespace llsd
* - Anything else is an error.
*
* By implication, if path.isUndefined() or otherwise equivalent to an empty
* LLSD::Array, drill() returns 'blob' as is.
* LLSD::Array, drill[_ref]() returns 'blob' as is.
*/
LLSD drill(const LLSD& blob, const LLSD& path);
LLSD& drill( LLSD& blob, const LLSD& path);
LLSD& drill_ref( LLSD& blob, const LLSD& path);
}

View File

@ -195,18 +195,6 @@ LLOSInfo::LLOSInfo() :
GetSystemInfo(&si); //if it fails get regular system info
//(Warning: If GetSystemInfo it may result in incorrect information in a WOW64 machine, if the kernel fails to load)
//msdn microsoft finds 32 bit and 64 bit flavors this way..
//http://msdn.microsoft.com/en-us/library/ms724429(VS.85).aspx (example code that contains quite a few more flavors
//of windows than this code does (in case it is needed for the future)
if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) //check for 64 bit
{
mOSStringSimple += "64-bit ";
}
else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
{
mOSStringSimple += "32-bit ";
}
// Try calling GetVersionEx using the OSVERSIONINFOEX structure.
OSVERSIONINFOEX osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
@ -253,9 +241,21 @@ LLOSInfo::LLOSInfo() :
// Query WMI's Win32_OperatingSystem for OS string. Slow
// and likely to return 'compatibility' string.
// Check presence of dlls/libs or may be their version.
mOSStringSimple = "Microsoft Windows 10/11";
mOSStringSimple = "Microsoft Windows 10/11 ";
}
}
}
//msdn microsoft finds 32 bit and 64 bit flavors this way..
//http://msdn.microsoft.com/en-us/library/ms724429(VS.85).aspx (example code that contains quite a few more flavors
//of windows than this code does (in case it is needed for the future)
if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) //check for 64 bit
{
mOSStringSimple += "64-bit ";
}
else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
{
mOSStringSimple += "32-bit ";
}
mOSString = mOSStringSimple;
if (mBuild > 0)

View File

@ -5745,7 +5745,16 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
resizeIndices(grid_size*grid_size*6);
if (!volume->isMeshAssetLoaded())
{
mEdge.resize(grid_size*grid_size * 6);
S32 size = grid_size * grid_size * 6;
try
{
mEdge.resize(size);
}
catch (std::bad_alloc&)
{
LL_WARNS("LLVOLUME") << "Resize of mEdge to " << size << " failed" << LL_ENDL;
return false;
}
}
U16* out = mIndices;
@ -6554,7 +6563,15 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
if (!volume->isMeshAssetLoaded())
{
mEdge.resize(num_indices);
try
{
mEdge.resize(num_indices);
}
catch (std::bad_alloc&)
{
LL_WARNS("LLVOLUME") << "Resize of mEdge to " << num_indices << " failed" << LL_ENDL;
return false;
}
}
}
@ -6782,7 +6799,15 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
LLVector4a* norm = mNormals;
static LLAlignedArray<LLVector4a, 64> triangle_normals;
triangle_normals.resize(count);
try
{
triangle_normals.resize(count);
}
catch (std::bad_alloc&)
{
LL_WARNS("LLVOLUME") << "Resize of triangle_normals to " << count << " failed" << LL_ENDL;
return false;
}
LLVector4a* output = triangle_normals.mArray;
LLVector4a* end_output = output+count;

View File

@ -175,6 +175,14 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
mTripleClickTimer.reset();
setText(p.default_text());
if (p.initial_value.isProvided()
&& !p.control_name.isProvided())
{
// Initial value often is descriptive, like "Type some ID here"
// and can be longer than size limitation, ignore size
setText(p.initial_value.getValue().asString(), false);
}
// Initialize current history line iterator
mCurrentHistoryLine = mLineHistory.begin();
@ -389,6 +397,11 @@ void LLLineEditor::updateTextPadding()
void LLLineEditor::setText(const LLStringExplicit &new_text)
{
setText(new_text, true);
}
void LLLineEditor::setText(const LLStringExplicit &new_text, bool use_size_limit)
{
// If new text is identical, don't copy and don't move insertion point
if (mText.getString() == new_text)
@ -407,13 +420,13 @@ void LLLineEditor::setText(const LLStringExplicit &new_text)
all_selected = all_selected || (len == 0 && hasFocus() && mSelectAllonFocusReceived);
std::string truncated_utf8 = new_text;
if (truncated_utf8.size() > (U32)mMaxLengthBytes)
if (use_size_limit && truncated_utf8.size() > (U32)mMaxLengthBytes)
{
truncated_utf8 = utf8str_truncate(new_text, mMaxLengthBytes);
}
mText.assign(truncated_utf8);
if (mMaxLengthChars)
if (use_size_limit && mMaxLengthChars)
{
mText.assign(utf8str_symbol_truncate(truncated_utf8, mMaxLengthChars));
}

View File

@ -320,6 +320,8 @@ private:
virtual S32 getPreeditFontSize() const;
virtual LLWString getPreeditString() const { return getWText(); }
void setText(const LLStringExplicit &new_text, bool use_size_limit);
void setContextMenu(LLContextMenu* new_context_menu);
protected:

View File

@ -2362,6 +2362,16 @@ void LLMenuGL::arrange( void )
(*item_iter)->setRect( rect );
}
}
if (getTornOff())
{
LLTearOffMenu * torn_off_menu = dynamic_cast<LLTearOffMenu*>(getParent());
if (torn_off_menu)
{
torn_off_menu->updateSize();
}
}
}
if (mKeepFixedSize)
{
@ -3879,7 +3889,8 @@ void LLMenuHolderGL::setActivatedItem(LLMenuItemGL* item)
/// Class LLTearOffMenu
///============================================================================
LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) :
LLFloater(LLSD())
LLFloater(LLSD()),
mQuitRequested(false)
{
S32 floater_header_size = getHeaderHeight();
@ -3894,7 +3905,7 @@ LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) :
LLRect rect;
menup->localRectToOtherView(LLRect(-1, menup->getRect().getHeight(), menup->getRect().getWidth() + 3, 0), &rect, gFloaterView);
// make sure this floater is big enough for menu
mTargetHeight = (F32)(rect.getHeight() + floater_header_size);
mTargetHeight = rect.getHeight() + floater_header_size;
reshape(rect.getWidth(), rect.getHeight());
setRect(rect);
@ -3926,19 +3937,24 @@ LLTearOffMenu::~LLTearOffMenu()
void LLTearOffMenu::draw()
{
mMenu->setBackgroundVisible(isBackgroundOpaque());
mMenu->needsArrange();
if (getRect().getHeight() != mTargetHeight)
{
// animate towards target height
reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), mTargetHeight, LLSmoothInterpolation::getInterpolant(0.05f))));
reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), (F32)mTargetHeight, LLSmoothInterpolation::getInterpolant(0.05f))));
mMenu->needsArrange();
}
LLFloater::draw();
}
void LLTearOffMenu::onFocusReceived()
{
// if nothing is highlighted, just highlight first item
if (mQuitRequested)
{
return;
}
// if nothing is highlighted, just highlight first item
if (!mMenu->getHighlightedItem())
{
mMenu->highlightNextItem(NULL);
@ -4014,6 +4030,31 @@ LLTearOffMenu* LLTearOffMenu::create(LLMenuGL* menup)
return tearoffp;
}
void LLTearOffMenu::updateSize()
{
if (mMenu)
{
S32 floater_header_size = getHeaderHeight();
const LLRect &floater_rect = getRect();
LLRect new_rect;
mMenu->localRectToOtherView(LLRect(-1, mMenu->getRect().getHeight() + floater_header_size, mMenu->getRect().getWidth() + 3, 0), &new_rect, gFloaterView);
if (floater_rect.getWidth() != new_rect.getWidth()
|| mTargetHeight != new_rect.getHeight())
{
// make sure this floater is big enough for menu
mTargetHeight = new_rect.getHeight();
reshape(new_rect.getWidth(), mTargetHeight);
// Restore menu position
LLRect menu_rect = mMenu->getRect();
menu_rect.setOriginAndSize(1, 1,
menu_rect.getWidth(), menu_rect.getHeight());
mMenu->setRect(menu_rect);
}
}
}
void LLTearOffMenu::closeTearOff()
{
removeChild(mMenu);
@ -4024,6 +4065,7 @@ void LLTearOffMenu::closeTearOff()
mMenu->setVisible(FALSE);
mMenu->setTornOff(FALSE);
mMenu->setDropShadowed(TRUE);
mQuitRequested = true;
}
LLContextMenuBranch::LLContextMenuBranch(const LLContextMenuBranch::Params& p)

View File

@ -873,6 +873,8 @@ public:
virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual void translate(S32 x, S32 y);
void updateSize();
private:
LLTearOffMenu(LLMenuGL* menup);
@ -880,7 +882,8 @@ private:
LLView* mOldParent;
LLMenuGL* mMenu;
F32 mTargetHeight;
S32 mTargetHeight;
bool mQuitRequested;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -1017,6 +1017,24 @@ std::string LLUrlEntryObjectIM::getLocation(const std::string &url) const
return LLUrlEntryBase::getLocation(url);
}
//
// LLUrlEntryChat Describes a Second Life chat Url, e.g.,
// secondlife:///app/chat/42/This%20Is%20a%20test
//
LLUrlEntryChat::LLUrlEntryChat()
{
mPattern = boost::regex("secondlife:///app/chat/\\d+/\\S+",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_slapp.xml";
mTooltip = LLTrans::getString("TooltipSLAPP");
}
std::string LLUrlEntryChat::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
{
return unescapeUrl(url);
}
// LLUrlEntryParcel statics.
LLUUID LLUrlEntryParcel::sAgentID(LLUUID::null);
LLUUID LLUrlEntryParcel::sSessionID(LLUUID::null);

View File

@ -370,6 +370,17 @@ public:
private:
};
//
// LLUrlEntryChat Describes a Second Life chat Url, e.g.,
// secondlife:///app/chat/42/This%20Is%20a%20test
//
class LLUrlEntryChat : public LLUrlEntryBase
{
public:
LLUrlEntryChat();
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
};
///
/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about

View File

@ -63,6 +63,7 @@ LLUrlRegistry::LLUrlRegistry()
// LLUrlEntryAgent*Name must appear before LLUrlEntryAgent since
// LLUrlEntryAgent is a less specific (catchall for agent urls)
registerUrl(new LLUrlEntryAgent());
registerUrl(new LLUrlEntryChat());
registerUrl(new LLUrlEntryGroup());
registerUrl(new LLUrlEntryParcel());
registerUrl(new LLUrlEntryTeleport());
@ -71,7 +72,6 @@ LLUrlRegistry::LLUrlRegistry()
registerUrl(new LLUrlEntryObjectIM());
registerUrl(new LLUrlEntryPlace());
registerUrl(new LLUrlEntryInventory());
registerUrl(new LLUrlEntryObjectIM());
registerUrl(new LLUrlEntryExperienceProfile());
//LLUrlEntrySL and LLUrlEntrySLLabel have more common pattern,
//so it should be registered in the end of list

View File

@ -4262,7 +4262,8 @@ BOOL LLWindowWin32::handleImeRequests(WPARAM request, LPARAM param, LRESULT *res
S32 context_offset;
LLWString context = find_context(wtext, preedit, preedit_length, &context_offset);
preedit -= context_offset;
if (preedit_length)
preedit_length = llmin(preedit_length, (S32)context.length() - preedit);
if (preedit_length && preedit >= 0)
{
// IMR_DOCUMENTFEED may be called when we have an active preedit.
// We should pass the context string *excluding* the preedit string.

View File

@ -1922,9 +1922,7 @@ if (WINDOWS)
add_dependencies(${VIEWER_BINARY_NAME} copy_win_scripts)
endif (EXISTS ${CMAKE_SOURCE_DIR}/copy_win_scripts)
add_dependencies(${VIEWER_BINARY_NAME}
SLPlugin
)
add_dependencies(${VIEWER_BINARY_NAME} SLPlugin)
# sets the 'working directory' for debugging from visual studio.
# Condition for version can be moved to requirements once build agents will be updated (see TOOL-3865)
@ -2274,7 +2272,7 @@ endif (INSTALL)
# Note that the conventional VIEWER_SYMBOL_FILE is set by ../../build.sh
if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIEWER_SYMBOL_FILE)
if (BUGSPLAT_DB)
if (USE_BUGSPLAT)
# BugSplat symbol-file generation
if (WINDOWS)
# Just pack up a tarball containing only the .pdb file for the
@ -2358,7 +2356,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
if (LINUX)
# TBD
endif (LINUX)
endif (BUGSPLAT_DB)
endif (USE_BUGSPLAT)
# for both Bugsplat and Breakpad
add_dependencies(llpackage generate_symbols)

View File

@ -1 +1 @@
6.5.4
6.5.5

View File

@ -207,14 +207,6 @@
<map>
<key>map-to</key>
<string>NoAudio</string>
</map>
<key>noinvlib</key>
<map>
<key>desc</key>
<string>Do not request the inventory library.</string>
<key>map-to</key>
<string>NoInventoryLibrary</string>
</map>
<key>nonotifications</key>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<keys>
<keys xml_version="1">
<first_person>
<binding key="A" mask="NONE" command="slide_left"/>
<binding key="D" mask="NONE" command="slide_right"/>
@ -17,22 +17,13 @@
<binding key="PGDN" mask="NONE" command="push_down"/>
<binding key="HOME" mask="NONE" command="toggle_fly"/>
<binding key="PAD_LEFT" mask="NONE" command="slide_left"/>
<binding key="PAD_RIGHT" mask="NONE" command="slide_right"/>
<binding key="PAD_UP" mask="NONE" command="push_forward"/>
<binding key="PAD_DOWN" mask="NONE" command="push_backward"/>
<binding key="PAD_PGUP" mask="NONE" command="jump"/>
<binding key="PAD_PGDN" mask="NONE" command="push_down"/>
<binding key="PAD_HOME" mask="NONE" command="toggle_fly"/>
<binding key="PAD_CENTER" mask="NONE" command="stop_moving"/>
<binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
<binding key="SPACE" mask="NONE" command="stop_moving"/>
<binding key="ENTER" mask="NONE" command="start_chat"/>
<binding key="DIVIDE" mask="NONE" command="start_gesture"/>
<binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
<binding key="" mask="NONE" mouse="LMB" command="script_trigger_lbutton"/>
</first_person>
<third_person>
<binding key="A" mask="NONE" command="turn_left"/>
@ -60,19 +51,6 @@
<binding key="PGDN" mask="NONE" command="push_down"/>
<binding key="HOME" mask="NONE" command="toggle_fly"/>
<binding key="PAD_LEFT" mask="NONE" command="turn_left"/>
<binding key="PAD_LEFT" mask="SHIFT" command="slide_left"/>
<binding key="PAD_RIGHT" mask="NONE" command="turn_right"/>
<binding key="PAD_RIGHT" mask="SHIFT" command="slide_right"/>
<binding key="PAD_UP" mask="NONE" command="push_forward"/>
<binding key="PAD_DOWN" mask="NONE" command="push_backward"/>
<binding key="PAD_PGUP" mask="NONE" command="jump"/>
<binding key="PAD_PGDN" mask="NONE" command="push_down"/>
<binding key="PAD_HOME" mask="NONE" command="toggle_fly"/>
<binding key="PAD_CENTER" mask="NONE" command="stop_moving"/>
<binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
<!--Camera controls in third person on Alt-->
<binding key="LEFT" mask="ALT" command="spin_around_cw"/>
<binding key="RIGHT" mask="ALT" command="spin_around_ccw"/>
@ -88,15 +66,6 @@
<binding key="E" mask="ALT" command="spin_over"/>
<binding key="C" mask="ALT" command="spin_under"/>
<binding key="PAD_LEFT" mask="ALT" command="spin_around_cw"/>
<binding key="PAD_RIGHT" mask="ALT" command="spin_around_ccw"/>
<binding key="PAD_UP" mask="ALT" command="move_forward"/>
<binding key="PAD_DOWN" mask="ALT" command="move_backward"/>
<binding key="PAD_PGUP" mask="ALT" command="spin_over"/>
<binding key="PAD_PGDN" mask="ALT" command="spin_under"/>
<binding key="PAD_ENTER" mask="ALT" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="ALT" command="start_gesture"/>
<!--mimic alt zoom behavior with keyboard only-->
<binding key="W" mask="CTL_ALT" command="spin_over"/>
<binding key="S" mask="CTL_ALT" command="spin_under"/>
@ -104,9 +73,6 @@
<binding key="UP" mask="CTL_ALT" command="spin_over"/>
<binding key="DOWN" mask="CTL_ALT" command="spin_under"/>
<binding key="PAD_UP" mask="CTL_ALT" command="spin_over"/>
<binding key="PAD_DOWN" mask="CTL_ALT" command="spin_under"/>
<!--Therefore pan on Alt-Shift-->
<binding key="A" mask="CTL_ALT_SHIFT" command="pan_left"/>
<binding key="D" mask="CTL_ALT_SHIFT" command="pan_right"/>
@ -118,14 +84,10 @@
<binding key="UP" mask="CTL_ALT_SHIFT" command="pan_up"/>
<binding key="DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>
<binding key="PAD_LEFT" mask="CTL_ALT_SHIFT" command="pan_left"/>
<binding key="PAD_RIGHT" mask="CTL_ALT_SHIFT" command="pan_right"/>
<binding key="PAD_UP" mask="CTL_ALT_SHIFT" command="pan_up"/>
<binding key="PAD_DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>
<binding key="PAD_ENTER" mask="CTL_ALT_SHIFT" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="CTL_ALT_SHIFT" command="start_gesture"/>
<binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
<binding key="" mask="NONE" mouse="LMB" command="walk_to"/>
<binding key="" mask="NONE" mouse="LMB" command="script_trigger_lbutton"/>
</third_person>
<sitting>
<binding key="A" mask="ALT" command="spin_around_cw"/>
@ -167,16 +129,6 @@
<binding key="PGUP" mask="NONE" command="spin_over_sitting"/>
<binding key="PGDN" mask="NONE" command="spin_under_sitting"/>
<binding key="PAD_LEFT" mask="NONE" command="spin_around_cw_sitting"/>
<binding key="PAD_RIGHT" mask="NONE" command="spin_around_ccw_sitting"/>
<binding key="PAD_UP" mask="NONE" command="move_forward_sitting"/>
<binding key="PAD_DOWN" mask="NONE" command="move_backward_sitting"/>
<binding key="PAD_PGUP" mask="NONE" command="spin_over_sitting"/>
<binding key="PAD_PGDN" mask="NONE" command="spin_under_sitting"/>
<binding key="PAD_CENTER" mask="NONE" command="stop_moving"/>
<binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
<!--these are for passing controls when sitting on vehicles-->
<binding key="A" mask="SHIFT" command="slide_left"/>
<binding key="D" mask="SHIFT" command="slide_right"/>
@ -192,15 +144,6 @@
<binding key="PGUP" mask="SHIFT" command="spin_over_sitting"/>
<binding key="PGDN" mask="SHIFT" command="spin_under_sitting"/>
<binding key="PAD_LEFT" mask="SHIFT" command="slide_left"/>
<binding key="PAD_RIGHT" mask="SHIFT" command="slide_right"/>
<binding key="PAD_UP" mask="SHIFT" command="move_forward_sitting"/>
<binding key="PAD_DOWN" mask="SHIFT" command="move_backward_sitting"/>
<binding key="PAD_PGUP" mask="SHIFT" command="spin_over_sitting"/>
<binding key="PAD_PGDN" mask="SHIFT" command="spin_under_sitting"/>
<binding key="PAD_ENTER" mask="SHIFT" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="SHIFT" command="start_gesture"/>
<!--pan on Alt-Shift-->
<binding key="A" mask="CTL_ALT_SHIFT" command="pan_left"/>
<binding key="D" mask="CTL_ALT_SHIFT" command="pan_right"/>
@ -212,17 +155,12 @@
<binding key="UP" mask="CTL_ALT_SHIFT" command="pan_up"/>
<binding key="DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>
<binding key="PAD_LEFT" mask="CTL_ALT_SHIFT" command="pan_left"/>
<binding key="PAD_RIGHT" mask="CTL_ALT_SHIFT" command="pan_right"/>
<binding key="PAD_UP" mask="CTL_ALT_SHIFT" command="pan_up"/>
<binding key="PAD_DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>
<binding key="PAD_ENTER" mask="CTL_ALT_SHIFT" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="CTL_ALT_SHIFT" command="start_gesture"/>
<binding key="ENTER" mask="NONE" command="start_chat"/>
<binding key="DIVIDE" mask="NONE" command="start_gesture"/>
<binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
<binding key="" mask="NONE" mouse="LMB" command="script_trigger_lbutton"/>
</sitting>
<edit_avatar>
<!--Avatar editing camera controls-->
@ -240,15 +178,9 @@
<binding key="PGDN" mask="NONE" command="edit_avatar_spin_under"/>
<binding key="ENTER" mask="NONE" command="start_chat"/>
<binding key="DIVIDE" mask="NONE" command="start_gesture"/>
<binding key="PAD_LEFT" mask="NONE" command="edit_avatar_spin_cw"/>
<binding key="PAD_RIGHT" mask="NONE" command="edit_avatar_spin_ccw"/>
<binding key="PAD_UP" mask="NONE" command="edit_avatar_move_forward"/>
<binding key="PAD_DOWN" mask="NONE" command="edit_avatar_move_backward"/>
<binding key="PAD_PGUP" mask="NONE" command="edit_avatar_spin_over"/>
<binding key="PAD_PGDN" mask="NONE" command="edit_avatar_spin_under"/>
<binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
<binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
<binding key="" mask="NONE" mouse="LMB" command="script_trigger_lbutton"/>
</edit_avatar>
</keys>

View File

@ -5895,17 +5895,6 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>LoginAsGod</key>
<map>
<key>Comment</key>
<string>Attempt to login with god powers (Linden accounts only)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>LoginLocation</key>
<map>
<key>Comment</key>
@ -6964,6 +6953,17 @@
<key>Value</key>
<integer>1000</integer>
</map>
<key>FakeInitialOutfitName</key>
<map>
<key>Comment</key>
<string>Pretend that this is first time login and specified name was chosen</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string />
</map>
<key>MyOutfitsAutofill</key>
<map>
<key>Comment</key>
@ -7066,7 +7066,7 @@
<key>NoInventoryLibrary</key>
<map>
<key>Comment</key>
<string>Do not request inventory library.</string>
<string>(Deprecated) Do not request inventory library.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>

View File

@ -1988,7 +1988,8 @@ void LLAgent::propagate(const F32 dt)
//-----------------------------------------------------------------------------
void LLAgent::updateAgentPosition(const F32 dt, const F32 yaw_radians, const S32 mouse_x, const S32 mouse_y)
{
if (mMoveTimer.getStarted() && mMoveTimer.getElapsedTimeF32() > gSavedSettings.getF32("NotMovingHintTimeout"))
static LLCachedControl<F32> hint_timeout(gSavedSettings, "NotMovingHintTimeout");
if (mMoveTimer.getStarted() && mMoveTimer.getElapsedTimeF32() > hint_timeout)
{
LLFirstUse::notMoving();
}
@ -2159,7 +2160,8 @@ void LLAgent::endAnimationUpdateUI()
LLNavigationBar::getInstance()->setVisible(TRUE && gSavedSettings.getBOOL("ShowNavbarNavigationPanel"));
gStatusBar->setVisibleForMouselook(true);
if (gSavedSettings.getBOOL("ShowMiniLocationPanel"))
static LLCachedControl<bool> show_mini_location_panel(gSavedSettings, "ShowMiniLocationPanel");
if (show_mini_location_panel)
{
LLPanelTopInfoBar::getInstance()->setVisible(TRUE);
}
@ -3901,10 +3903,6 @@ bool LLAgent::teleportCore(bool is_local)
// yet if the teleport will succeed. Look in
// process_teleport_location_reply
// close the map panel so we can see our destination.
// we don't close search floater, see EXT-5840.
LLFloaterReg::hideInstance("world_map");
// hide land floater too - it'll be out of date
LLFloaterReg::hideInstance("about_land");

View File

@ -5360,14 +5360,18 @@ void LLAppViewer::disconnectViewer()
}
// save inventory if appropriate
gInventory.cache(gInventory.getRootFolderID(), gAgent.getID());
if (gInventory.getLibraryRootFolderID().notNull()
&& gInventory.getLibraryOwnerID().notNull())
{
gInventory.cache(
gInventory.getLibraryRootFolderID(),
gInventory.getLibraryOwnerID());
}
if (gInventory.isInventoryUsable()
&& gAgent.getID().notNull()) // Shouldn't be null at this stage
{
gInventory.cache(gInventory.getRootFolderID(), gAgent.getID());
if (gInventory.getLibraryRootFolderID().notNull()
&& gInventory.getLibraryOwnerID().notNull())
{
gInventory.cache(
gInventory.getLibraryRootFolderID(),
gInventory.getLibraryOwnerID());
}
}
saveNameCache();
if (LLExperienceCache::instanceExists())

View File

@ -51,8 +51,8 @@ protected:
bool initHardwareTest() override; // Win32 uses DX9 to test hardware.
bool initParseCommandLine(LLCommandLineParser& clp) override;
virtual bool beingDebugged();
virtual bool restoreErrorTrap();
bool beingDebugged() override;
bool restoreErrorTrap() override;
bool sendURLToOtherInstance(const std::string& url) override;

View File

@ -359,6 +359,8 @@ void LLAvatarRenderInfoAccountant::idle()
&& regionp->capabilitiesReceived())
{
// each of these is further governed by and resets its own timer
// Note: We can have multiple regions, each launches up to two coroutines,
// it likely is expensive
sendRenderInfoToRegion(regionp);
getRenderInfoFromRegion(regionp);
}

View File

@ -645,7 +645,8 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg)
{
if(mBuddyInfo.find(agent_id) != mBuddyInfo.end())
{
if((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS)
if (((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS)
&& !gAgent.isDoNotDisturb())
{
LLSD args;
args["NAME"] = LLSLURL("agent", agent_id, "displayname").getSLURLString();

View File

@ -96,10 +96,14 @@ LLConversationViewSession::~LLConversationViewSession()
{
mActiveVoiceChannelConnection.disconnect();
if(LLVoiceClient::instanceExists() && mVoiceClientObserver)
{
LLVoiceClient::getInstance()->removeObserver(mVoiceClientObserver);
}
if (mVoiceClientObserver)
{
if (LLVoiceClient::instanceExists())
{
LLVoiceClient::getInstance()->removeObserver(mVoiceClientObserver);
}
delete mVoiceClientObserver;
}
mFlashTimer->unset();
}
@ -255,7 +259,12 @@ BOOL LLConversationViewSession::postBuild()
mIsInActiveVoiceChannel = true;
if(LLVoiceClient::instanceExists())
{
LLNearbyVoiceClientStatusObserver* mVoiceClientObserver = new LLNearbyVoiceClientStatusObserver(this);
if (mVoiceClientObserver)
{
LLVoiceClient::getInstance()->removeObserver(mVoiceClientObserver);
delete mVoiceClientObserver;
}
mVoiceClientObserver = new LLNearbyVoiceClientStatusObserver(this);
LLVoiceClient::getInstance()->addObserver(mVoiceClientObserver);
}
break;

View File

@ -615,12 +615,12 @@ void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissi
void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
{
BOOL batch_fullbrights = gSavedSettings.getBOOL("RenderAlphaBatchFullbrights");
BOOL batch_emissives = gSavedSettings.getBOOL("RenderAlphaBatchEmissives");
BOOL initialized_lighting = FALSE;
BOOL light_enabled = TRUE;
static LLCachedControl<bool> batch_fullbrights(gSavedSettings, "RenderAlphaBatchFullbrights");
static LLCachedControl<bool> batch_emissives(gSavedSettings, "RenderAlphaBatchEmissives");
bool initialized_lighting = FALSE;
bool light_enabled = TRUE;
BOOL use_shaders = gPipeline.canUseVertexShaders();
bool use_shaders = gPipeline.canUseVertexShaders();
for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
{

View File

@ -574,18 +574,8 @@ void LLDrawPoolWater::shade2(bool edge, LLGLSLShader* shader, const LLColor3& li
shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp);
if (LLEnvironment::instance().isCloudScrollPaused())
{
static const std::array<F32, 2> zerowave{ {0.0f, 0.0f} };
shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, zerowave.data());
shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, zerowave.data());
}
else
{
shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV);
shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV);
}
shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV);
shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV);
shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV);

View File

@ -453,18 +453,18 @@ void LLFloaterCamera::setMode(ECameraControlMode mode)
void LLFloaterCamera::switchMode(ECameraControlMode mode)
{
setMode(mode);
switch (mode)
{
case CAMERA_CTRL_MODE_PRESETS:
case CAMERA_CTRL_MODE_PAN:
sFreeCamera = false;
setMode(mode); // depends onto sFreeCamera
clear_camera_tool();
break;
case CAMERA_CTRL_MODE_FREE_CAMERA:
sFreeCamera = true;
setMode(mode);
activate_camera_tool();
break;

View File

@ -582,8 +582,7 @@ void LLFloaterGesture::onCopyPasteAction(const LLSD& command)
LLInventoryItem* item = gInventory.getItem(*it);
if(item && item->getInventoryType() == LLInventoryType::IT_GESTURE)
{
LLWString item_name = utf8str_to_wstring(item->getName());
LLClipboard::instance().addToClipboard(item_name, 0, item_name.size());
LLClipboard::instance().addToClipboard(*it);
}
}
}

View File

@ -384,7 +384,7 @@ void LLFloaterIMSessionTab::draw()
void LLFloaterIMSessionTab::enableDisableCallBtn()
{
if (LLVoiceClient::instanceExists())
if (LLVoiceClient::instanceExists() && mVoiceButton)
{
mVoiceButton->setEnabled(
mSessionID.notNull()

View File

@ -2399,7 +2399,16 @@ void LLPanelPreference::saveSettings()
{
view_stack.push_back(*iter);
}
}
}
if (LLStartUp::getStartupState() == STATE_STARTED)
{
LLControlVariable* control = gSavedPerAccountSettings.getControl("VoiceCallsFriendsOnly");
if (control)
{
mSavedValues[control] = control->getValue();
}
}
}
void LLPanelPreference::showMultipleViewersWarning(LLUICtrl* checkbox, const LLSD& value)

View File

@ -56,10 +56,12 @@
#include "llscrolllistctrl.h"
#include "llslurl.h"
#include "lltextbox.h"
#include "lltoolbarview.h"
#include "lltracker.h"
#include "lltrans.h"
#include "llviewerinventory.h" // LLViewerInventoryItem
#include "llviewermenu.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
#include "llviewerstats.h"
#include "llviewertexture.h"
@ -87,6 +89,9 @@ static const F32 MAP_ZOOM_TIME = 0.2f;
// Currently (01/26/09), this value allows the whole grid to be visible in a 1024x1024 window.
static const S32 MAX_VISIBLE_REGIONS = 512;
const S32 HIDE_BEACON_PAD = 133;
// It would be more logical to have this inside the method where it is used but to compile under gcc this
// struct has to be here.
struct SortRegionNames
@ -326,6 +331,8 @@ LLFloaterWorldMap::~LLFloaterWorldMap()
mFriendObserver = NULL;
gFloaterWorldMap = NULL;
mTeleportFinishConnection.disconnect();
}
//static
@ -339,12 +346,16 @@ void LLFloaterWorldMap::onClose(bool app_quitting)
{
// While we're not visible, discard the overlay images we're using
LLWorldMap::getInstance()->clearImageRefs();
mTeleportFinishConnection.disconnect();
}
// virtual
void LLFloaterWorldMap::onOpen(const LLSD& key)
{
bool center_on_target = (key.asString() == "center");
mTeleportFinishConnection = LLViewerParcelMgr::getInstance()->
setTeleportFinishedCallback(boost::bind(&LLFloaterWorldMap::onTeleportFinished, this));
bool center_on_target = (key.asString() == "center");
mIsClosing = FALSE;
@ -1566,6 +1577,13 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim)
}
}
void LLFloaterWorldMap::onTeleportFinished()
{
if(isInVisibleChain())
{
LLWorldMapView::setPan(0, 0, TRUE);
}
}
void LLFloaterWorldMap::onCommitSearchResult()
{
@ -1642,3 +1660,103 @@ void LLFloaterWorldMap::onFocusLost()
LLWorldMapView* map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel;
map_panel->mPanning = FALSE;
}
LLPanelHideBeacon::LLPanelHideBeacon() :
mHideButton(NULL)
{
}
// static
LLPanelHideBeacon* LLPanelHideBeacon::getInstance()
{
static LLPanelHideBeacon* panel = getPanelHideBeacon();
return panel;
}
BOOL LLPanelHideBeacon::postBuild()
{
mHideButton = getChild<LLButton>("hide_beacon_btn");
mHideButton->setCommitCallback(boost::bind(&LLPanelHideBeacon::onHideButtonClick, this));
gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLPanelHideBeacon::updatePosition, this));
return TRUE;
}
//virtual
void LLPanelHideBeacon::draw()
{
if (!LLTracker::isTracking(NULL))
{
mHideButton->setVisible(false);
return;
}
mHideButton->setVisible(true);
updatePosition();
LLPanel::draw();
}
//virtual
void LLPanelHideBeacon::setVisible(BOOL visible)
{
if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) visible = false;
if (visible)
{
updatePosition();
}
LLPanel::setVisible(visible);
}
//static
LLPanelHideBeacon* LLPanelHideBeacon::getPanelHideBeacon()
{
LLPanelHideBeacon* panel = new LLPanelHideBeacon();
panel->buildFromFile("panel_hide_beacon.xml");
LL_INFOS() << "Build LLPanelHideBeacon panel" << LL_ENDL;
panel->updatePosition();
return panel;
}
void LLPanelHideBeacon::onHideButtonClick()
{
LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance();
if (instance)
{
instance->onClearBtn();
}
}
/**
* Updates position of the panel (similar to Stand & Stop Flying panel).
*/
void LLPanelHideBeacon::updatePosition()
{
S32 bottom_tb_center = 0;
if (LLToolBar* toolbar_bottom = gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_BOTTOM))
{
bottom_tb_center = toolbar_bottom->getRect().getCenterX();
}
S32 left_tb_width = 0;
if (LLToolBar* toolbar_left = gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_LEFT))
{
left_tb_width = toolbar_left->getRect().getWidth();
}
if (gToolBarView != NULL && gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_LEFT)->hasButtons())
{
S32 x_pos = bottom_tb_center - getRect().getWidth() / 2 - left_tb_width;
setOrigin( x_pos + HIDE_BEACON_PAD, 0);
}
else
{
S32 x_pos = bottom_tb_center - getRect().getWidth() / 2;
setOrigin( x_pos + HIDE_BEACON_PAD, 0);
}
}

View File

@ -107,7 +107,8 @@ public:
// teleport to the tracked item, if there is one
void teleport();
void onChangeMaturity();
void onClearBtn();
//Slapp instigated avatar tracking
void avatarTrackFromSlapp( const LLUUID& id );
@ -124,7 +125,6 @@ protected:
void onComboTextEntry( );
void onSearchTextEntry( );
void onClearBtn();
void onClickTeleportBtn();
void onShowTargetBtn();
void onShowAgentBtn();
@ -151,7 +151,7 @@ protected:
void onCoordinatesCommit();
void onCommitSearchResult();
void cacheLandmarkPosition();
void onTeleportFinished();
private:
LLPanel* mPanel; // Panel displaying the map
@ -195,9 +195,31 @@ private:
LLCtrlListInterface * mListFriendCombo;
LLCtrlListInterface * mListLandmarkCombo;
LLCtrlListInterface * mListSearchResults;
boost::signals2::connection mTeleportFinishConnection;
};
extern LLFloaterWorldMap* gFloaterWorldMap;
class LLPanelHideBeacon : public LLPanel
{
public:
static LLPanelHideBeacon* getInstance();
LLPanelHideBeacon();
/*virtual*/ BOOL postBuild();
/*virtual*/ void setVisible(BOOL visible);
/*virtual*/ void draw();
private:
static LLPanelHideBeacon* getPanelHideBeacon();
void onHideButtonClick();
void updatePosition();
LLButton* mHideButton;
};
#endif

View File

@ -483,8 +483,13 @@ void LLGestureMgr::replaceGesture(const LLUUID& item_id, LLMultiGesture* new_ges
mActive[base_item_id] = new_gesture;
delete old_gesture;
old_gesture = NULL;
// replaceGesture(const LLUUID& item_id, const LLUUID& new_asset_id)
// replaces ids without repalcing gesture
if (old_gesture != new_gesture)
{
delete old_gesture;
old_gesture = NULL;
}
if (asset_id.notNull())
{
@ -910,7 +915,7 @@ void LLGestureMgr::stepGesture(LLMultiGesture* gesture)
else if (gesture->mWaitTimer.getElapsedTimeF32() > MAX_WAIT_ANIM_SECS)
{
// we've waited too long for an animation
LL_INFOS() << "Waited too long for animations to stop, continuing gesture."
LL_INFOS("GestureMgr") << "Waited too long for animations to stop, continuing gesture."
<< LL_ENDL;
gesture->mWaitingAnimations = FALSE;
gesture->mCurrentStep++;
@ -1097,6 +1102,34 @@ void LLGestureMgr::onLoadComplete(const LLUUID& asset_uuid,
self.setFetchID(item_id);
self.startFetch();
}
item_map_t::iterator it = self.mActive.find(item_id);
if (it == self.mActive.end())
{
// Gesture is supposed to be present, active, but NULL
LL_DEBUGS("GestureMgr") << "Gesture " << item_id << " not found in active list" << LL_ENDL;
}
else
{
LLMultiGesture* old_gesture = (*it).second;
if (old_gesture && old_gesture != gesture)
{
LL_DEBUGS("GestureMgr") << "Received dupplicate " << item_id << " callback" << LL_ENDL;
// In case somebody managest to activate, deactivate and
// then activate gesture again, before asset finishes loading.
// LLLoadInfo will have a different pointer, asset storage will
// see it as a different request, resulting in two callbacks.
// deactivateSimilarGestures() did not turn this one off
// because of matching item_id
self.stopGesture(old_gesture);
self.mActive.erase(item_id);
delete old_gesture;
old_gesture = NULL;
}
}
self.mActive[item_id] = gesture;
// Everything has been successful. Add to the active list.
@ -1131,9 +1164,23 @@ void LLGestureMgr::onLoadComplete(const LLUUID& asset_uuid,
}
else
{
LL_WARNS() << "Unable to load gesture" << LL_ENDL;
LL_WARNS("GestureMgr") << "Unable to load gesture" << LL_ENDL;
self.mActive.erase(item_id);
item_map_t::iterator it = self.mActive.find(item_id);
if (it != self.mActive.end())
{
LLMultiGesture* old_gesture = (*it).second;
if (old_gesture)
{
// Shouldn't happen, just in case
LL_WARNS("GestureMgr") << "Gesture " << item_id << " existed when it shouldn't" << LL_ENDL;
self.stopGesture(old_gesture);
delete old_gesture;
old_gesture = NULL;
}
self.mActive.erase(item_id);
}
delete gesture;
gesture = NULL;
@ -1151,9 +1198,23 @@ void LLGestureMgr::onLoadComplete(const LLUUID& asset_uuid,
LLDelayedGestureError::gestureFailedToLoad( item_id );
}
LL_WARNS() << "Problem loading gesture: " << status << LL_ENDL;
LLGestureMgr::instance().mActive.erase(item_id);
LL_WARNS("GestureMgr") << "Problem loading gesture: " << status << LL_ENDL;
item_map_t::iterator it = self.mActive.find(item_id);
if (it != self.mActive.end())
{
LLMultiGesture* old_gesture = (*it).second;
if (old_gesture)
{
// Shouldn't happen, just in case
LL_WARNS("GestureMgr") << "Gesture " << item_id << " existed when it shouldn't" << LL_ENDL;
self.stopGesture(old_gesture);
delete old_gesture;
old_gesture = NULL;
}
self.mActive.erase(item_id);
}
}
}

View File

@ -138,6 +138,8 @@ bool LLCanCache::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
LLInventoryValidationInfo::LLInventoryValidationInfo():
mFatalErrorCount(0),
mWarningCount(0),
mLoopCount(0),
mOrphanedCount(0),
mInitialized(false),
mFatalNoRootFolder(false),
mFatalNoLibraryRootFolder(false),
@ -147,7 +149,10 @@ LLInventoryValidationInfo::LLInventoryValidationInfo():
void LLInventoryValidationInfo::toOstream(std::ostream& os) const
{
os << "mFatalErrorCount " << mFatalErrorCount << " mWarningCount " << mWarningCount;
os << "mFatalErrorCount " << mFatalErrorCount
<< " mWarningCount " << mWarningCount
<< " mLoopCount " << mLoopCount
<< " mOrphanedCount " << mOrphanedCount;
}
@ -161,6 +166,8 @@ void LLInventoryValidationInfo::asLLSD(LLSD& sd) const
{
sd["fatal_error_count"] = mFatalErrorCount;
sd["warning_count"] = mWarningCount;
sd["loop_count"] = mLoopCount;
sd["orphaned_count"] = mOrphanedCount;
sd["initialized"] = mInitialized;
sd["missing_system_folders_count"] = LLSD::Integer(mMissingRequiredSystemFolders.size());
sd["fatal_no_root_folder"] = mFatalNoRootFolder;
@ -337,21 +344,35 @@ const LLViewerInventoryCategory* LLInventoryModel::getFirstDescendantOf(const LL
return NULL;
}
bool LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const
LLInventoryModel::EAnscestorResult LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const
{
LLInventoryObject *object = getObject(object_id);
while (object && object->getParentUUID().notNull())
{
LLInventoryObject *parent_object = getObject(object->getParentUUID());
if (!object)
{
LL_WARNS(LOG_INV) << "Unable to trace topmost ancestor, initial object " << object_id << " does not exist" << LL_ENDL;
return ANSCESTOR_MISSING;
}
std::set<LLUUID> object_ids{ object_id }; // loop protection
while (object->getParentUUID().notNull())
{
LLUUID parent_id = object->getParentUUID();
if (object_ids.find(parent_id) != object_ids.end())
{
LL_WARNS(LOG_INV) << "Detected a loop on an object " << parent_id << " when searching for ancestor of " << object_id << LL_ENDL;
return ANSCESTOR_LOOP;
}
object_ids.insert(parent_id);
LLInventoryObject *parent_object = getObject(parent_id);
if (!parent_object)
{
LL_WARNS(LOG_INV) << "unable to trace topmost ancestor, missing item for uuid " << object->getParentUUID() << LL_ENDL;
return false;
LL_WARNS(LOG_INV) << "unable to trace topmost ancestor of " << object_id << ", missing item for uuid " << parent_id << LL_ENDL;
return ANSCESTOR_MISSING;
}
object = parent_object;
}
result = object->getUUID();
return true;
return ANSCESTOR_OK;
}
// Get the object by id. Returns NULL if not found.
@ -2956,42 +2977,69 @@ bool LLInventoryModel::saveToFile(const std::string& filename,
LL_INFOS(LOG_INV) << "saving inventory to: (" << filename << ")" << LL_ENDL;
llofstream fileXML(filename.c_str());
if (!fileXML.is_open())
{
LL_WARNS(LOG_INV) << "unable to save inventory to: " << filename << LL_ENDL;
return false;
}
try
{
llofstream fileXML(filename.c_str());
if (!fileXML.is_open())
{
LL_WARNS(LOG_INV) << "Failed to open file. Unable to save inventory to: " << filename << LL_ENDL;
return false;
}
LLSD cache_ver;
cache_ver["inv_cache_version"] = sCurrentInvCacheVersion;
LLSD cache_ver;
cache_ver["inv_cache_version"] = sCurrentInvCacheVersion;
fileXML << LLSDOStreamer<LLSDNotationFormatter>(cache_ver) << std::endl;
if (fileXML.fail())
{
LL_WARNS(LOG_INV) << "Failed to write cache version to file. Unable to save inventory to: " << filename << LL_ENDL;
return false;
}
S32 count = categories.size();
S32 cat_count = 0;
S32 i;
for(i = 0; i < count; ++i)
{
LLViewerInventoryCategory* cat = categories[i];
if(cat->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN)
{
fileXML << LLSDOStreamer<LLSDNotationFormatter>(cat->exportLLSD()) << std::endl;
cat_count++;
}
}
fileXML << LLSDOStreamer<LLSDNotationFormatter>(cache_ver) << std::endl;
S32 it_count = items.size();
for(i = 0; i < it_count; ++i)
{
fileXML << LLSDOStreamer<LLSDNotationFormatter>(items[i]->asLLSD()) << std::endl;
}
S32 count = categories.size();
S32 cat_count = 0;
S32 i;
for (i = 0; i < count; ++i)
{
LLViewerInventoryCategory* cat = categories[i];
if (cat->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN)
{
fileXML << LLSDOStreamer<LLSDNotationFormatter>(cat->exportLLSD()) << std::endl;
cat_count++;
}
fileXML.close();
if (fileXML.fail())
{
LL_WARNS(LOG_INV) << "Failed to write a folder to file. Unable to save inventory to: " << filename << LL_ENDL;
return false;
}
}
LL_INFOS(LOG_INV) << "Inventory saved: " << cat_count << " categories, " << it_count << " items." << LL_ENDL;
S32 it_count = items.size();
for (i = 0; i < it_count; ++i)
{
fileXML << LLSDOStreamer<LLSDNotationFormatter>(items[i]->asLLSD()) << std::endl;
return true;
if (fileXML.fail())
{
LL_WARNS(LOG_INV) << "Failed to write an item to file. Unable to save inventory to: " << filename << LL_ENDL;
return false;
}
}
fileXML.close();
LL_INFOS(LOG_INV) << "Inventory saved: " << cat_count << " categories, " << it_count << " items." << LL_ENDL;
}
catch (...)
{
LOG_UNHANDLED_EXCEPTION("");
LL_INFOS(LOG_INV) << "Failed to save inventory to: (" << filename << ")" << LL_ENDL;
return false;
}
return true;
}
// message handling functionality
@ -3859,20 +3907,23 @@ void LLInventoryModel::dumpInventory() const
LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LLPointer<LLInventoryValidationInfo> validation_info = new LLInventoryValidationInfo;
S32 fatalities = 0;
S32 fatal_errs = 0;
S32 warnings = 0;
S32 loops = 0;
S32 orphaned = 0;
if (getRootFolderID().isNull())
{
LL_WARNS("Inventory") << "Fatal inventory corruption: no root folder id" << LL_ENDL;
validation_info->mFatalNoRootFolder = true;
fatalities++;
fatal_errs++;
}
if (getLibraryRootFolderID().isNull())
{
// Probably shouldn't be a fatality, inventory can function without a library
LL_WARNS("Inventory") << "Fatal inventory corruption: no library root folder id" << LL_ENDL;
validation_info->mFatalNoLibraryRootFolder = true;
fatalities++;
fatal_errs++;
}
if (mCategoryMap.size() + 1 != mParentChildCategoryTree.size())
@ -3904,7 +3955,23 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
}
LLUUID topmost_ancestor_id;
// Will leave as null uuid on failure
getObjectTopmostAncestor(cat_id, topmost_ancestor_id);
EAnscestorResult res = getObjectTopmostAncestor(cat_id, topmost_ancestor_id);
switch (res)
{
case ANSCESTOR_MISSING:
orphaned++;
break;
case ANSCESTOR_LOOP:
loops++;
break;
case ANSCESTOR_OK:
break;
default:
LL_WARNS("Inventory") << "Unknown ancestor error for " << cat_id << LL_ENDL;
warnings++;
break;
}
if (cat_id != cat->getUUID())
{
LL_WARNS("Inventory") << "cat id/index mismatch " << cat_id << " " << cat->getUUID() << LL_ENDL;
@ -4004,8 +4071,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// Topmost ancestor should be root or library.
LLUUID topmost_ancestor_id;
bool found = getObjectTopmostAncestor(item_id, topmost_ancestor_id);
if (!found)
EAnscestorResult found = getObjectTopmostAncestor(item_id, topmost_ancestor_id);
if (found != ANSCESTOR_OK)
{
LL_WARNS("Inventory") << "unable to find topmost ancestor for " << item_id << LL_ENDL;
warnings++;
@ -4035,7 +4102,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName()
<< "] orphaned - no child cat array for alleged parent " << parent_id << LL_ENDL;
warnings++;
orphaned++;
}
else
{
@ -4053,6 +4120,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName()
<< "] orphaned - not found in child cat array of alleged parent " << parent_id << LL_ENDL;
orphaned++;
}
}
}
@ -4061,7 +4129,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LLFolderType::EType folder_type = cat->getPreferredType();
bool cat_is_in_library = false;
LLUUID topmost_id;
if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) && topmost_id == getLibraryRootFolderID())
if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) == ANSCESTOR_OK && topmost_id == getLibraryRootFolderID())
{
cat_is_in_library = true;
}
@ -4101,6 +4169,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (parent_id.isNull())
{
LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName() << "] has null parent id!" << LL_ENDL;
orphaned++;
}
else
{
@ -4111,6 +4180,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName()
<< "] orphaned - alleged parent has no child items list " << parent_id << LL_ENDL;
orphaned++;
}
else
{
@ -4127,6 +4197,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName()
<< "] orphaned - not found as child of alleged parent " << parent_id << LL_ENDL;
orphaned++;
}
}
@ -4144,15 +4215,18 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LL_WARNS("Inventory") << "link " << item->getUUID() << " type " << item->getActualType()
<< " missing backlink info at target_id " << target_id
<< LL_ENDL;
orphaned++;
}
// Links should have referents.
if (item->getActualType() == LLAssetType::AT_LINK && !target_item)
{
LL_WARNS("Inventory") << "broken item link " << item->getName() << " id " << item->getUUID() << LL_ENDL;
orphaned++;
}
else if (item->getActualType() == LLAssetType::AT_LINK_FOLDER && !target_cat)
{
LL_WARNS("Inventory") << "broken folder link " << item->getName() << " id " << item->getUUID() << LL_ENDL;
orphaned++;
}
if (target_item && target_item->getIsLinkType())
{
@ -4224,8 +4298,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (is_automatic)
{
LL_WARNS("Inventory") << "Fatal inventory corruption: cannot create system folder of type " << ft << LL_ENDL;
fatalities++;
validation_info->mMissingRequiredSystemFolders.insert(LLFolderType::EType(ft));
fatal_errs++;
validation_info->mMissingRequiredSystemFolders.insert(folder_type);
}
else
{
@ -4236,8 +4310,20 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
else if (count_under_root > 1)
{
LL_WARNS("Inventory") << "Fatal inventory corruption: system folder type has excess copies under root, type " << ft << " count " << count_under_root << LL_ENDL;
validation_info->mDuplicateRequiredSystemFolders.insert(LLFolderType::EType(ft));
fatalities++;
validation_info->mDuplicateRequiredSystemFolders.insert(folder_type);
if (!is_automatic && folder_type != LLFolderType::FT_SETTINGS)
{
// It is a fatal problem or can lead to fatal problems for COF,
// outfits, trash and other non-automatic folders.
fatal_errs++;
}
else
{
// For automatic folders it's not a fatal issue and shouldn't
// break inventory or other functionality further
// Exception: FT_SETTINGS is not automatic, but only deserves a warning.
warnings++;
}
}
if (count_elsewhere > 0)
{
@ -4263,11 +4349,13 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
}
// FIXME need to fail login and tell user to retry, contact support if problem persists.
bool valid = (fatalities == 0);
LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatalities << ", warnings: " << warnings << ", valid: " << valid << LL_ENDL;
bool valid = (fatal_errs == 0);
LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatal_errs << ", warnings: " << warnings << ", valid: " << valid << LL_ENDL;
validation_info->mFatalErrorCount = fatalities;
validation_info->mFatalErrorCount = fatal_errs;
validation_info->mWarningCount = warnings;
validation_info->mLoopCount = loops;
validation_info->mOrphanedCount = orphaned;
return validation_info;
}

View File

@ -68,6 +68,8 @@ public:
S32 mFatalErrorCount;
S32 mWarningCount;
S32 mLoopCount; // Presence of folders whose ansestors loop onto themselves
S32 mOrphanedCount; // Missing or orphaned items, links and folders
bool mInitialized;
bool mFatalNoRootFolder;
bool mFatalNoLibraryRootFolder;
@ -283,9 +285,14 @@ public:
// Check if one object has a parent chain up to the category specified by UUID.
BOOL isObjectDescendentOf(const LLUUID& obj_id, const LLUUID& cat_id) const;
enum EAnscestorResult{
ANSCESTOR_OK = 0,
ANSCESTOR_MISSING = 1,
ANSCESTOR_LOOP = 2,
};
// Follow parent chain to the top.
bool getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const;
EAnscestorResult getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const;
//--------------------------------------------------------------------
// Find

View File

@ -411,8 +411,16 @@ void LLKeyConflictHandler::loadFromSettings(ESourceMode load_mode)
filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_default);
if (!gDirUtilp->fileExists(filename) || !loadFromSettings(load_mode, filename, &mControlsMap))
{
// mind placeholders
mControlsMap.insert(mDefaultsMap.begin(), mDefaultsMap.end());
// Mind placeholders
// Do not use mControlsMap.insert(mDefaultsMap) since mControlsMap has
// placeholders that won't be added over(to) by insert.
// Or instead move generatePlaceholders call to be after copying
control_map_t::iterator iter = mDefaultsMap.begin();
while (iter != mDefaultsMap.end())
{
mControlsMap[iter->first].mKeyBind = iter->second.mKeyBind;
iter++;
}
}
}
mLoadMode = load_mode;
@ -575,6 +583,8 @@ void LLKeyConflictHandler::saveToSettings(bool temporary)
break;
}
keys.xml_version.set(keybindings_xml_version, true);
if (temporary)
{
// write to temporary xml and use it for gViewerInput
@ -667,13 +677,19 @@ void LLKeyConflictHandler::resetToDefault(const std::string &control_name, U32 i
{
return;
}
LLKeyConflict &type_data = mControlsMap[control_name];
if (!type_data.mAssignable)
{
return;
}
LLKeyData data = getDefaultControl(control_name, index);
if (data != mControlsMap[control_name].getKeyData(index))
if (data != type_data.getKeyData(index))
{
// reset controls that might have been switched to our current control
removeConflicts(data, mControlsMap[control_name].mConflictMask);
mControlsMap[control_name].setKeyData(data, index);
mHasUnsavedChanges = true;
}
}
@ -730,9 +746,9 @@ void LLKeyConflictHandler::resetToDefault(const std::string &control_name)
resetToDefaultAndResolve(control_name, false);
}
void LLKeyConflictHandler::resetToDefaults(ESourceMode mode)
void LLKeyConflictHandler::resetToDefaultsAndResolve()
{
if (mode == MODE_SAVED_SETTINGS)
if (mLoadMode == MODE_SAVED_SETTINGS)
{
control_map_t::iterator iter = mControlsMap.begin();
control_map_t::iterator end = mControlsMap.end();
@ -745,8 +761,16 @@ void LLKeyConflictHandler::resetToDefaults(ESourceMode mode)
else
{
mControlsMap.clear();
generatePlaceholders(mode);
// Set key combinations.
// Copy from mDefaultsMap before doing generatePlaceholders, otherwise
// insert() will fail to add some keys into pre-existing values from
// generatePlaceholders()
mControlsMap.insert(mDefaultsMap.begin(), mDefaultsMap.end());
// Set conflict masks and mark functions (un)assignable
generatePlaceholders(mLoadMode);
}
mHasUnsavedChanges = true;
@ -756,7 +780,7 @@ void LLKeyConflictHandler::resetToDefaults()
{
if (!empty())
{
resetToDefaults(mLoadMode);
resetToDefaultsAndResolve();
}
else
{
@ -766,7 +790,7 @@ void LLKeyConflictHandler::resetToDefaults()
// 3. We are loading 'current' only to replace it
// but it is reliable and works Todo: consider optimizing.
loadFromSettings(mLoadMode);
resetToDefaults(mLoadMode);
resetToDefaultsAndResolve();
}
}
@ -799,7 +823,7 @@ void LLKeyConflictHandler::resetKeyboardBindings()
void LLKeyConflictHandler::generatePlaceholders(ESourceMode load_mode)
{
// These controls are meant to cause conflicts when user tries to assign same control somewhere else
// These placeholders are meant to cause conflict resolution when user tries to assign same control somewhere else
// also this can be used to pre-record controls that should not conflict or to assign conflict groups/masks
if (load_mode == MODE_FIRST_PERSON)
@ -859,24 +883,60 @@ void LLKeyConflictHandler::generatePlaceholders(ESourceMode load_mode)
registerTemporaryControl("spin_around_ccw_sitting");
registerTemporaryControl("spin_around_cw_sitting");
}
// Special case, mouse clicks passed to scripts have 'lowest' piority
// thus do not conflict, everything else has a chance before them
// also in ML they have highest priority, but only when script-grabbed,
// thus do not conflict
// (see AGENT_CONTROL_ML_LBUTTON_DOWN and CONTROL_LBUTTON_DOWN_INDEX)
LLKeyConflict *type_data = &mControlsMap[script_mouse_handler_name];
type_data->mAssignable = true;
type_data->mConflictMask = U32_MAX - CONFLICT_LMOUSE;
}
bool LLKeyConflictHandler::removeConflicts(const LLKeyData &data, const U32 &conlict_mask)
bool LLKeyConflictHandler::removeConflicts(const LLKeyData &data, U32 conlict_mask)
{
if (conlict_mask == CONFLICT_NOTHING)
{
// Can't conflict
return true;
}
if (data.mMouse == CLICK_LEFT
&& data.mMask == MASK_NONE
&& data.mKey == KEY_NONE)
{
if ((conlict_mask & CONFLICT_LMOUSE) == 0)
{
// Can't conflict
return true;
}
else
{
// simplify conflict mask
conlict_mask = CONFLICT_LMOUSE;
}
}
else
{
// simplify conflict mask
conlict_mask &= ~CONFLICT_LMOUSE;
}
std::map<std::string, S32> conflict_list;
control_map_t::iterator cntrl_iter = mControlsMap.begin();
control_map_t::iterator cntrl_end = mControlsMap.end();
for (; cntrl_iter != cntrl_end; ++cntrl_iter)
{
const U32 cmp_mask = cntrl_iter->second.mConflictMask;
if ((cmp_mask & conlict_mask) == 0)
{
// can't conflict
continue;
}
S32 index = cntrl_iter->second.mKeyBind.findKeyData(data);
if (index >= 0
&& cntrl_iter->second.mConflictMask != CONFLICT_NOTHING
&& (cntrl_iter->second.mConflictMask & conlict_mask) != 0)
if (index >= 0)
{
if (cntrl_iter->second.mAssignable)
{

View File

@ -66,6 +66,7 @@ public:
};
const U32 CONFLICT_NOTHING = 0;
const U32 CONFLICT_LMOUSE = 0x1 << 1;
// at the moment this just means that key will conflict with everything that is identical
const U32 CONFLICT_ANY = U32_MAX;
@ -128,23 +129,24 @@ public:
// resets current mode to defaults
void resetToDefaults();
bool empty() { return mControlsMap.empty(); }
bool empty() const { return mControlsMap.empty(); }
void clear();
// reloads bindings from last valid user's xml or from default xml
// to keyboard's handler
static void resetKeyboardBindings();
bool hasUnsavedChanges() { return mHasUnsavedChanges; }
bool hasUnsavedChanges() const { return mHasUnsavedChanges; }
void setLoadMode(ESourceMode mode) { mLoadMode = mode; }
ESourceMode getLoadMode() { return mLoadMode; }
ESourceMode getLoadMode() const { return mLoadMode; }
private:
void resetToDefaultAndResolve(const std::string &control_name, bool ignore_conflicts);
void resetToDefaults(ESourceMode mode);
void resetToDefaultsAndResolve();
// at the moment these kind of control is not savable, but takes part in conflict resolution
void registerTemporaryControl(const std::string &control_name, EMouseClickType mouse_ind, KEY key, MASK mask, U32 conflict_mask);
// conflict mask 0 means that any conflicts will be ignored
void registerTemporaryControl(const std::string &control_name, U32 conflict_mask = 0);
typedef std::map<std::string, LLKeyConflict> control_map_t;
@ -152,7 +154,7 @@ private:
bool loadFromSettings(const ESourceMode &load_mode, const std::string &filename, control_map_t *destination);
void generatePlaceholders(ESourceMode load_mode); //E.x. non-assignable values
// returns false in case user is trying to reuse control that can't be reassigned
bool removeConflicts(const LLKeyData &data, const U32 &conlict_mask);
bool removeConflicts(const LLKeyData &data, U32 conlict_mask);
// removes flags and removes temporary file, returns 'true' if file was removed
bool clearUnsavedChanges();

View File

@ -165,13 +165,12 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
//requested_options.append("inventory-meat");
//requested_options.append("inventory-skel-targets");
#if (!defined LL_MINIMIAL_REQUESTED_OPTIONS)
if(FALSE == gSavedSettings.getBOOL("NoInventoryLibrary"))
{
requested_options.append("inventory-lib-root");
requested_options.append("inventory-lib-owner");
requested_options.append("inventory-skel-lib");
// Not requesting library will trigger mFatalNoLibraryRootFolder
requested_options.append("inventory-lib-root");
requested_options.append("inventory-lib-owner");
requested_options.append("inventory-skel-lib");
// requested_options.append("inventory-meat-lib");
}
requested_options.append("initial-outfit");
requested_options.append("gestures");

View File

@ -1146,6 +1146,11 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
}
else
{
// Media might be blocked, waiting for a file,
// send an empty response to unblock it
const std::vector<std::string> empty_response;
self->sendPickFileResponse(empty_response);
LLNotificationsUtil::add("MediaFileDownloadUnsupported");
}
};

View File

@ -2548,7 +2548,9 @@ void LLModelPreview::lookupLODModelFiles(S32 lod)
std::string lod_filename = mLODFile[LLModel::LOD_HIGH];
std::string ext = ".dae";
std::string::size_type i = lod_filename.rfind(ext);
std::string lod_filename_lower(lod_filename);
LLStringUtil::toLower(lod_filename_lower);
std::string::size_type i = lod_filename_lower.rfind(ext);
if (i != std::string::npos)
{
lod_filename.replace(i, lod_filename.size() - ext.size(), getLodSuffix(next_lod) + ext);

View File

@ -61,7 +61,7 @@
#define CAP_SERVICE_NAVMESH_STATUS "NavMeshGenerationStatus"
#define CAP_SERVICE_OBJECT_LINKSETS "ObjectNavMeshProperties"
#define CAP_SERVICE_OBJECT_LINKSETS "RegionObjects"
#define CAP_SERVICE_TERRAIN_LINKSETS "TerrainNavMeshProperties"
#define CAP_SERVICE_CHARACTERS "CharacterProperties"

View File

@ -1029,7 +1029,6 @@ void LLPreviewGesture::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId)
// active map with the new pointer.
if (LLGestureMgr::instance().isGestureActive(itemId))
{
//*TODO: This is crashing for some reason. Fix it.
// Active gesture edited from menu.
LLGestureMgr::instance().replaceGesture(itemId, newAssetId);
gInventory.notifyObservers();

View File

@ -132,8 +132,11 @@ void ll::statusbar::SearchableItem::setNotHighlighted( )
{
mCtrl->setHighlighted( false );
if( mWasHiddenBySearch )
mMenu->setVisible( TRUE );
if (mWasHiddenBySearch)
{
mMenu->setVisible(TRUE);
mWasHiddenBySearch = false;
}
}
}

View File

@ -2240,10 +2240,6 @@ bool idle_startup()
// Have the agent start watching the friends list so we can update proxies
gAgent.observeFriends();
if (gSavedSettings.getBOOL("LoginAsGod"))
{
gAgent.requestEnterGodMode();
}
// Start automatic replay if the flag is set.
if (gSavedSettings.getBOOL("StatsAutoRun") || gAgentPilot.getReplaySession())
@ -2752,19 +2748,34 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
gAgentAvatarp->setSex(gender);
// try to find the outfit - if not there, create some default
// wearables.
// try to find the requested outfit or folder
// -- check for existing outfit in My Outfits
bool do_copy = false;
LLUUID cat_id = findDescendentCategoryIDByName(
gInventory.getLibraryRootFolderID(),
gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS),
outfit_folder_name);
// -- check for existing folder in Library
if (cat_id.isNull())
{
cat_id = findDescendentCategoryIDByName(
gInventory.getLibraryRootFolderID(),
outfit_folder_name);
if (!cat_id.isNull())
{
do_copy = true;
}
}
if (cat_id.isNull())
{
// -- final fallback: create standard wearables
LL_DEBUGS() << "standard wearables" << LL_ENDL;
gAgentWearables.createStandardWearables();
}
else
{
bool do_copy = true;
bool do_append = false;
LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
// Need to fetch cof contents before we can wear.
@ -3639,6 +3650,19 @@ bool process_login_success_response()
}
}
std::string fake_initial_outfit_name = gSavedSettings.getString("FakeInitialOutfitName");
if (!fake_initial_outfit_name.empty())
{
gAgent.setFirstLogin(TRUE);
sInitialOutfit = fake_initial_outfit_name;
if (sInitialOutfitGender.empty())
{
sInitialOutfitGender = "female"; // just guess, will get overridden when outfit is worn anyway.
}
LL_WARNS() << "Faking first-time login with initial outfit " << sInitialOutfit << LL_ENDL;
}
// set the location of the Agent Appearance service, from which we can request
// avatar baked textures if they are supported by the current region
std::string agent_appearance_url = response["agent_appearance_service"];

View File

@ -44,6 +44,7 @@
#include "lltoolmgr.h"
#include "lltoolselectrect.h"
#include "lltoolplacer.h"
#include "llviewerinput.h"
#include "llviewermenu.h"
#include "llviewerobject.h"
#include "llviewerwindow.h"
@ -745,7 +746,7 @@ BOOL LLToolCompGun::handleHover(S32 x, S32 y, MASK mask)
BOOL LLToolCompGun::handleMouseDown(S32 x, S32 y, MASK mask)
{
// if the left button is grabbed, don't put up the pie menu
if (gAgent.leftButtonGrabbed())
if (gAgent.leftButtonGrabbed() && gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON))
{
gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN);
return FALSE;
@ -762,7 +763,7 @@ BOOL LLToolCompGun::handleMouseDown(S32 x, S32 y, MASK mask)
BOOL LLToolCompGun::handleDoubleClick(S32 x, S32 y, MASK mask)
{
// if the left button is grabbed, don't put up the pie menu
if (gAgent.leftButtonGrabbed())
if (gAgent.leftButtonGrabbed() && gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON))
{
gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN);
return FALSE;
@ -796,7 +797,10 @@ BOOL LLToolCompGun::handleRightMouseDown(S32 x, S32 y, MASK mask)
BOOL LLToolCompGun::handleMouseUp(S32 x, S32 y, MASK mask)
{
gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP);
if (gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON))
{
gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP);
}
setCurrentTool( (LLTool*) mGun );
return TRUE;
}

View File

@ -51,6 +51,7 @@
#include "lltoolmgr.h"
#include "lltoolpie.h"
#include "llviewercamera.h"
#include "llviewerinput.h"
#include "llviewerobject.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
@ -140,7 +141,6 @@ BOOL LLToolGrabBase::handleMouseDown(S32 x, S32 y, MASK mask)
LL_INFOS() << "LLToolGrab handleMouseDown" << LL_ENDL;
}
// call the base class to propogate info to sim
LLTool::handleMouseDown(x, y, mask);
// leftButtonGrabbed() checks if controls are reserved by scripts, but does not take masks into account
@ -150,6 +150,19 @@ BOOL LLToolGrabBase::handleMouseDown(S32 x, S32 y, MASK mask)
gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE);
}
mClickedInMouselook = gAgentCamera.cameraMouselook();
if (mClickedInMouselook && gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON))
{
// LLToolCompGun::handleMouseDown handles the event if ML controls are grabed,
// but LLToolGrabBase is often the end point for mouselook clicks if ML controls
// are not grabbed and LLToolGrabBase::handleMouseDown consumes the event,
// so send clicks from here.
// We are sending specifically CONTROL_LBUTTON_DOWN instead of _ML_ version.
gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN);
// Todo: LLToolGrabBase probably shouldn't consume the event if there is nothing
// to grab in Mouselook, it intercepts handling in scanMouse
}
return TRUE;
}
@ -953,9 +966,18 @@ void LLToolGrabBase::handleHoverFailed(S32 x, S32 y, MASK mask)
BOOL LLToolGrabBase::handleMouseUp(S32 x, S32 y, MASK mask)
{
// call the base class to propogate info to sim
LLTool::handleMouseUp(x, y, mask);
if (gAgentCamera.cameraMouselook() && gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON))
{
// LLToolCompGun::handleMouseUp handles the event if ML controls are grabed,
// but LLToolGrabBase is often the end point for mouselook clicks if ML controls
// are not grabbed and LToolGrabBase::handleMouseUp consumes the event,
// so send clicks from here.
// We are sending specifically CONTROL_LBUTTON_UP instead of _ML_ version.
gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP);
}
if( hasMouseCapture() )
{
setMouseCapture( FALSE );

View File

@ -394,8 +394,9 @@ BOOL LLToolPie::handleLeftClickPick()
gFocusMgr.setKeyboardFocus(NULL);
}
BOOL touchable = (object && object->flagHandleTouch())
|| (parent && parent->flagHandleTouch());
bool touchable = object
&& (object->getClickAction() != CLICK_ACTION_DISABLED)
&& (object->flagHandleTouch() || (parent && parent->flagHandleTouch()));
// Switch to grab tool if physical or triggerable
if (object &&
@ -656,6 +657,12 @@ bool LLToolPie::teleportToClickedLocation()
LLViewerObject* objp = mHoverPick.getObject();
LLViewerObject* parentp = objp ? objp->getRootEdit() : NULL;
if (objp && (objp->getAvatar() == gAgentAvatarp || objp == gAgentAvatarp)) // ex: nametag
{
// Don't teleport to self, teleporting to other avatars is fine
return false;
}
bool is_in_world = mHoverPick.mObjectID.notNull() && objp && !objp->isHUDAttachment();
bool is_land = mHoverPick.mPickType == LLPickInfo::PICK_LAND;
bool pos_non_zero = !mHoverPick.mPosGlobal.isExactlyZero();
@ -750,7 +757,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
else if (!mMouseOutsideSlop
&& mMouseButtonDown
// disable camera steering if click on land is not used for moving
&& gViewerInput.isMouseBindUsed(CLICK_LEFT))
&& gViewerInput.isMouseBindUsed(CLICK_LEFT, MASK_NONE, MODE_THIRD_PERSON))
{
S32 delta_x = x - mMouseDownX;
S32 delta_y = y - mMouseDownY;

View File

@ -353,7 +353,7 @@ void LLViewerAssetStorage::checkForTimeouts()
// Restore requests
LLCoprocedureManager* manager = LLCoprocedureManager::getInstance();
while (mCoroWaitList.size() > 0
&& manager->count(VIEWER_ASSET_STORAGE_CORO_POOL) < LLCoprocedureManager::DEFAULT_QUEUE_SIZE)
&& manager->count(VIEWER_ASSET_STORAGE_CORO_POOL) < (LLCoprocedureManager::DEFAULT_QUEUE_SIZE - 1))
{
CoroWaitList &request = mCoroWaitList.front();
@ -425,13 +425,14 @@ void LLViewerAssetStorage::queueRequestHttp(
if (!duplicate)
{
// Coroutine buffer has fixed size (synchronization buffer, so we have no alternatives), so buffer any request above limit
if (LLCoprocedureManager::instance().count(VIEWER_ASSET_STORAGE_CORO_POOL) < LLCoprocedureManager::DEFAULT_QUEUE_SIZE)
LLCoprocedureManager* manager = LLCoprocedureManager::getInstance();
if (manager->count(VIEWER_ASSET_STORAGE_CORO_POOL) < (LLCoprocedureManager::DEFAULT_QUEUE_SIZE - 1))
{
bool with_http = true;
bool is_temp = false;
LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp);
LLCoprocedureManager::instance().enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro",
manager->enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro",
boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data));
}
else

View File

@ -816,13 +816,20 @@ bool toggle_enable_media(EKeystate s)
bool walk_to(EKeystate s)
{
if (KEYSTATE_DOWN != s) return true;
if (KEYSTATE_DOWN != s)
{
// teleport/walk is usually on mouseclick, mouseclick needs
// to let AGENT_CONTROL_LBUTTON_UP happen if teleport didn't,
// so return false, but if it causes issues, do some kind of
// "return !has_teleported"
return false;
}
return LLToolPie::getInstance()->walkToClickedLocation();
}
bool teleport_to(EKeystate s)
{
if (KEYSTATE_DOWN != s) return true;
if (KEYSTATE_DOWN != s) return false;
return LLToolPie::getInstance()->teleportToClickedLocation();
}
@ -850,7 +857,47 @@ bool voice_follow_key(EKeystate s)
return false;
}
bool agen_control_lbutton_handle(EKeystate s)
bool script_trigger_lbutton(EKeystate s)
{
// Check for script overriding/expecting left mouse button.
// Note that this does not pass event further and depends onto mouselook.
// Checks CONTROL_ML_LBUTTON_DOWN_INDEX for mouselook,
// CONTROL_LBUTTON_DOWN_INDEX for normal camera
if (gAgent.leftButtonGrabbed())
{
bool mouselook = gAgentCamera.cameraMouselook();
switch (s)
{
case KEYSTATE_DOWN:
if (mouselook)
{
gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN);
}
else
{
gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN);
}
return true;
case KEYSTATE_UP:
if (mouselook)
{
gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP);
}
else
{
gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP);
}
return true;
default:
break;
}
}
return false;
}
// Used by scripts, for overriding/handling left mouse button
// see mControlsTakenCount
bool agent_control_lbutton_handle(EKeystate s)
{
switch (s)
{
@ -922,6 +969,7 @@ REGISTER_KEYBOARD_ACTION("teleport_to", teleport_to);
REGISTER_KEYBOARD_ACTION("walk_to", walk_to);
REGISTER_KEYBOARD_GLOBAL_ACTION("toggle_voice", toggle_voice);
REGISTER_KEYBOARD_GLOBAL_ACTION("voice_follow_key", voice_follow_key);
REGISTER_KEYBOARD_ACTION(script_mouse_handler_name, script_trigger_lbutton);
#undef REGISTER_KEYBOARD_ACTION
LLViewerInput::LLViewerInput()
@ -1193,6 +1241,20 @@ BOOL LLViewerInput::bindMouse(const S32 mode, const EMouseClickType mouse, const
typedef boost::function<bool(EKeystate)> function_t;
function_t function = NULL;
if (mouse == CLICK_LEFT
&& mask == MASK_NONE
&& function_name == script_mouse_handler_name)
{
// Special case
// Left click has script overrides and by default
// is handled via agent_control_lbutton as last option
// In case of mouselook and present overrides it has highest
// priority even over UI and is handled in LLToolCompGun::handleMouseDown
// so just mark it as having default handler
mLMouseDefaultHandling[mode] = true;
return TRUE;
}
LLKeybindFunctionData* result = LLKeyboardActionRegistry::getValue(function_name);
if (result)
{
@ -1269,7 +1331,8 @@ LLViewerInput::Keys::Keys()
: first_person("first_person"),
third_person("third_person"),
sitting("sitting"),
edit_avatar("edit_avatar")
edit_avatar("edit_avatar"),
xml_version("xml_version", 0)
{}
void LLViewerInput::resetBindings()
@ -1280,6 +1343,7 @@ void LLViewerInput::resetBindings()
mGlobalMouseBindings[i].clear();
mKeyBindings[i].clear();
mMouseBindings[i].clear();
mLMouseDefaultHandling[i] = false;
}
}
@ -1298,6 +1362,65 @@ S32 LLViewerInput::loadBindingsXML(const std::string& filename)
binding_count += loadBindingMode(keys.third_person, MODE_THIRD_PERSON);
binding_count += loadBindingMode(keys.sitting, MODE_SITTING);
binding_count += loadBindingMode(keys.edit_avatar, MODE_EDIT_AVATAR);
// verify version
if (keys.xml_version < 1)
{
// updating from a version that was not aware of LMouse bindings
for (S32 i = 0; i < MODE_COUNT; i++)
{
mLMouseDefaultHandling[i] = true;
}
// fix missing values
KeyBinding mouse_binding;
mouse_binding.key = "";
mouse_binding.mask = "NONE";
mouse_binding.mouse = "LMB";
mouse_binding.command = script_mouse_handler_name;
if (keys.third_person.isProvided())
{
keys.third_person.bindings.add(mouse_binding);
}
if (keys.first_person.isProvided())
{
keys.first_person.bindings.add(mouse_binding);
}
if (keys.sitting.isProvided())
{
keys.sitting.bindings.add(mouse_binding);
}
if (keys.edit_avatar.isProvided())
{
keys.edit_avatar.bindings.add(mouse_binding);
}
// fix version
keys.xml_version.set(keybindings_xml_version, true);
// Write the resulting XML to file
LLXMLNodePtr output_node = new LLXMLNode("keys", false);
LLXUIParser write_parser;
write_parser.writeXUI(output_node, keys);
if (!output_node->isNull())
{
// file in app_settings is supposed to be up to date
// this is only for the file from user_settings
LL_INFOS("ViewerInput") << "Updating file " << filename << " to a newer version" << LL_ENDL;
LLFILE *fp = LLFile::fopen(filename, "w");
if (fp != NULL)
{
LLXMLNode::writeHeaderToFile(fp);
output_node->writeToFile(fp);
fclose(fp);
}
}
}
}
return binding_count;
}
@ -1469,17 +1592,6 @@ bool LLViewerInput::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
bool res = scanKey(mKeyBindings[mode], mKeyBindings[mode].size(), key, mask, key_down, key_up, key_level, repeat);
if (!res && agent_control_lbutton.canHandle(CLICK_NONE, key, mask))
{
if (key_down && !repeat)
{
res = agen_control_lbutton_handle(KEYSTATE_DOWN);
}
if (key_up)
{
res = agen_control_lbutton_handle(KEYSTATE_UP);
}
}
return res;
}
@ -1603,29 +1715,36 @@ bool LLViewerInput::scanMouse(EMouseClickType click, EMouseState state) const
bool res = false;
S32 mode = getMode();
MASK mask = gKeyboard->currentMask(TRUE);
// By default mouse clicks require exact mask
// Todo: support for mIgnoreMasks because some functions like teleports
// expect to be canceled, but for voice it's prefered to ignore mask.
res = scanMouse(mMouseBindings[mode], mMouseBindings[mode].size(), click, mask, state, false);
// no user defined actions found or those actions can't handle the key/button, handle control if nessesary
if (!res && agent_control_lbutton.canHandle(click, KEY_NONE, mask))
// No user defined actions found or those actions can't handle the key/button,
// so handle CONTROL_LBUTTON if nessesary.
//
// Default handling for MODE_FIRST_PERSON is in LLToolCompGun::handleMouseDown,
// and sends AGENT_CONTROL_ML_LBUTTON_DOWN, but it only applies if ML controls
// are leftButtonGrabbed(), send a normal click otherwise.
if (!res
&& mLMouseDefaultHandling[mode]
&& (mode != MODE_FIRST_PERSON || !gAgent.leftButtonGrabbed())
&& (click == CLICK_LEFT || click == CLICK_DOUBLELEFT)
)
{
switch (state)
{
case MOUSE_STATE_DOWN:
agen_control_lbutton_handle(KEYSTATE_DOWN);
agent_control_lbutton_handle(KEYSTATE_DOWN);
res = true;
break;
case MOUSE_STATE_CLICK:
// might not work best with some functions,
// but some function need specific states too specifically
agen_control_lbutton_handle(KEYSTATE_DOWN);
agen_control_lbutton_handle(KEYSTATE_UP);
agent_control_lbutton_handle(KEYSTATE_DOWN);
agent_control_lbutton_handle(KEYSTATE_UP);
res = true;
break;
case MOUSE_STATE_UP:
agen_control_lbutton_handle(KEYSTATE_UP);
agent_control_lbutton_handle(KEYSTATE_UP);
res = true;
break;
default:
@ -1655,7 +1774,7 @@ void LLViewerInput::scanMouse()
}
}
bool LLViewerInput::isMouseBindUsed(const EMouseClickType mouse, const MASK mask, const S32 mode)
bool LLViewerInput::isMouseBindUsed(const EMouseClickType mouse, const MASK mask, const S32 mode) const
{
S32 size = mMouseBindings[mode].size();
for (S32 index = 0; index < size; index++)

View File

@ -31,6 +31,8 @@
#include "llinitparam.h"
const S32 MAX_KEY_BINDINGS = 128; // was 60
const S32 keybindings_xml_version = 1;
const std::string script_mouse_handler_name = "script_trigger_lbutton";
class LLNamedFunction
{
@ -100,7 +102,7 @@ public:
third_person,
sitting,
edit_avatar;
Optional<S32> xml_version; // 'xml', because 'version' appears to be reserved
Keys();
};
@ -131,7 +133,8 @@ public:
BOOL handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down);
void scanMouse();
bool isMouseBindUsed(const EMouseClickType mouse, const MASK mask = MASK_NONE, const S32 mode = MODE_THIRD_PERSON);
bool isMouseBindUsed(const EMouseClickType mouse, const MASK mask, const S32 mode) const;
bool isLMouseHandlingDefault(const S32 mode) const { return mLMouseDefaultHandling[mode]; }
private:
bool scanKey(const std::vector<LLKeyboardBinding> &binding,
@ -171,6 +174,7 @@ private:
// to send what we think function wants based on collection of bools (mKeyRepeated, mKeyLevel, mKeyDown)
std::vector<LLKeyboardBinding> mKeyBindings[MODE_COUNT];
std::vector<LLMouseBinding> mMouseBindings[MODE_COUNT];
bool mLMouseDefaultHandling[MODE_COUNT]; // Due to having special priority
// keybindings that do not consume event and are handled earlier, before floaters
std::vector<LLKeyboardBinding> mGlobalKeyBindings[MODE_COUNT];

View File

@ -3198,10 +3198,6 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
case LLViewerMediaObserver::MEDIA_EVENT_FILE_DOWNLOAD:
{
LL_DEBUGS("Media") << "Media event - file download requested - filename is " << plugin->getFileDownloadFilename() << LL_ENDL;
//unblock media plugin
const std::vector<std::string> empty_response;
plugin->sendPickFileResponse(empty_response);
}
break;

View File

@ -1271,6 +1271,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num, MAX_OBJECT_BINARY_DATA_SIZE);
mTotalCRC = crc;
// Might need to update mSourceMuted here to properly pick up new radius
mSoundCutOffRadius = cutoff;
// Owner ID used for sound muting or particle system muting
@ -5888,7 +5889,7 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow
else if (flags & LL_SOUND_FLAG_STOP)
{
// Just shut off the sound
mAudioSourcep->play(LLUUID::null);
mAudioSourcep->stop();
}
return;
}
@ -5927,7 +5928,7 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow
mAudioSourcep->setQueueSounds(queue);
if(!queue) // stop any current sound first to avoid "farts of doom" (SL-1541) -MG
{
mAudioSourcep->play(LLUUID::null);
mAudioSourcep->stop();
}
// Play this sound if region maturity permits

View File

@ -2990,12 +2990,12 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("ObjectAnimation");
capabilityNames.append("ObjectMedia");
capabilityNames.append("ObjectMediaNavigate");
capabilityNames.append("ObjectNavMeshProperties");
capabilityNames.append("ParcelPropertiesUpdate");
capabilityNames.append("ParcelVoiceInfoRequest");
capabilityNames.append("ProductInfoRequest");
capabilityNames.append("ProvisionVoiceAccountRequest");
capabilityNames.append("ReadOfflineMsgs"); // Requires to respond reliably: AcceptFriendship, AcceptGroupInvite, DeclineFriendship, DeclineGroupInvite
capabilityNames.append("RegionObjects");
capabilityNames.append("RemoteParcelRequest");
capabilityNames.append("RenderMaterials");
capabilityNames.append("RequestTextureDownload");

View File

@ -2299,6 +2299,9 @@ void LLViewerWindow::initWorldUI()
LLPanelStandStopFlying* panel_stand_stop_flying = LLPanelStandStopFlying::getInstance();
panel_ssf_container->addChild(panel_stand_stop_flying);
LLPanelHideBeacon* panel_hide_beacon = LLPanelHideBeacon::getInstance();
panel_ssf_container->addChild(panel_hide_beacon);
panel_ssf_container->setVisible(TRUE);
LLMenuOptionPathfindingRebakeNavmesh::getInstance()->initialize();

View File

@ -1319,7 +1319,8 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
{
LL_RECORD_BLOCK_TIME(FTM_AVATAR_EXTENT_UPDATE);
S32 box_detail = gSavedSettings.getS32("AvatarBoundingBoxComplexity");
static LLCachedControl<S32> box_detail_cache(gSavedSettings, "AvatarBoundingBoxComplexity");
S32 box_detail = box_detail_cache;
if (getOverallAppearance() != AOA_NORMAL)
{
if (isControlAvatar())
@ -2528,10 +2529,11 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
{
LL_INFOS() << "Warning! Idle on dead avatar" << LL_ENDL;
return;
}
}
static LLCachedControl<bool> disable_all_render_types(gSavedSettings, "DisableAllRenderTypes");
if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR))
&& !(gSavedSettings.getBOOL("DisableAllRenderTypes")) && !isSelf())
&& !disable_all_render_types && !isSelf())
{
return;
}
@ -2672,7 +2674,8 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
// Don't render the user's own voice visualizer when in mouselook, or when opening the mic is disabled.
if(isSelf())
{
if(gAgentCamera.cameraMouselook() || gSavedSettings.getBOOL("VoiceDisableMic"))
static LLCachedControl<bool> voice_disable_mic(gSavedSettings, "VoiceDisableMic");
if(gAgentCamera.cameraMouselook() || voice_disable_mic)
{
render_visualizer = false;
}
@ -3141,11 +3144,14 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
}
const F32 time_visible = mTimeVisible.getElapsedTimeF32();
const F32 NAME_SHOW_TIME = gSavedSettings.getF32("RenderNameShowTime"); // seconds
const F32 FADE_DURATION = gSavedSettings.getF32("RenderNameFadeDuration"); // seconds
BOOL visible_avatar = isVisible() || mNeedsAnimUpdate;
BOOL visible_chat = gSavedSettings.getBOOL("UseChatBubbles") && (mChats.size() || mTyping);
BOOL render_name = visible_chat ||
static LLCachedControl<F32> NAME_SHOW_TIME(gSavedSettings, "RenderNameShowTime"); // seconds
static LLCachedControl<F32> FADE_DURATION(gSavedSettings, "RenderNameFadeDuration"); // seconds
static LLCachedControl<bool> use_chat_bubbles(gSavedSettings, "UseChatBubbles");
bool visible_avatar = isVisible() || mNeedsAnimUpdate;
bool visible_chat = use_chat_bubbles && (mChats.size() || mTyping);
bool render_name = visible_chat ||
(visible_avatar &&
((sRenderName == RENDER_NAME_ALWAYS) ||
(sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME)));
@ -3153,10 +3159,11 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
// draw if we're specifically hiding our own name.
if (isSelf())
{
static LLCachedControl<bool> render_name_show_self(gSavedSettings, "RenderNameShowSelf");
static LLCachedControl<S32> name_tag_mode(gSavedSettings, "AvatarNameTagMode");
render_name = render_name
&& !gAgentCamera.cameraMouselook()
&& (visible_chat || (gSavedSettings.getBOOL("RenderNameShowSelf")
&& gSavedSettings.getS32("AvatarNameTagMode") ));
&& (visible_chat || (render_name_show_self && name_tag_mode));
}
if ( !render_name )
@ -3171,7 +3178,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
return;
}
BOOL new_name = FALSE;
bool new_name = FALSE;
if (visible_chat != mVisibleChat)
{
mVisibleChat = visible_chat;
@ -3236,7 +3243,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
idleUpdateNameTagAlpha(new_name, alpha);
}
void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
void LLVOAvatar::idleUpdateNameTagText(bool new_name)
{
LLNameValue *title = getNVPair("Title");
LLNameValue* firstname = getNVPair("FirstName");
@ -3546,7 +3553,7 @@ void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
mNameText->setPositionAgent(name_position);
}
void LLVOAvatar::idleUpdateNameTagAlpha(BOOL new_name, F32 alpha)
void LLVOAvatar::idleUpdateNameTagAlpha(bool new_name, F32 alpha)
{
llassert(mNameText);
@ -3689,7 +3696,8 @@ void LLVOAvatar::updateAppearanceMessageDebugText()
{
debug_line += llformat(" - cof: %d req: %d rcv:%d",
curr_cof_version, last_request_cof_version, last_received_cof_version);
if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure"))
static LLCachedControl<bool> debug_force_failure(gSavedSettings, "DebugForceAppearanceRequestFailure");
if (debug_force_failure)
{
debug_line += " FORCING ERRS";
}
@ -5886,7 +5894,8 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL
//}
//else
{
LLUUID sound_id = LLUUID(gSavedSettings.getString("UISndTyping"));
static LLCachedControl<std::string> ui_snd_string(gSavedSettings, "UISndTyping");
LLUUID sound_id = LLUUID(ui_snd_string);
gAudiop->triggerSound(sound_id, getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_SFX, char_pos_global);
}
}
@ -5954,7 +5963,7 @@ void LLVOAvatar::resetAnimations()
// animations.
LLUUID LLVOAvatar::remapMotionID(const LLUUID& id)
{
BOOL use_new_walk_run = gSavedSettings.getBOOL("UseNewWalkRun");
static LLCachedControl<bool> use_new_walk_run(gSavedSettings, "UseNewWalkRun");
LLUUID result = id;
// start special case female walk for female avatars
@ -8142,7 +8151,8 @@ BOOL LLVOAvatar::isFullyLoaded() const
bool LLVOAvatar::isTooComplex() const
{
bool too_complex;
bool render_friend = (LLAvatarTracker::instance().isBuddy(getID()) && gSavedSettings.getBOOL("AlwaysRenderFriends"));
static LLCachedControl<bool> always_render_friends(gSavedSettings, "AlwaysRenderFriends");
bool render_friend = (LLAvatarTracker::instance().isBuddy(getID()) && always_render_friends);
if (isSelf() || render_friend || mVisuallyMuteSetting == AV_ALWAYS_RENDER)
{
@ -8995,7 +9005,8 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe
// Parse visual params, if any.
S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);
bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing
static LLCachedControl<bool> block_some_avatars(gSavedSettings, "BlockSomeAvatarAppearanceVisualParams");
bool drop_visual_params_debug = block_some_avatars && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing
if( num_blocks > 1 && !drop_visual_params_debug)
{
//LL_DEBUGS("Avatar") << avString() << " handle visual params, num_blocks " << num_blocks << LL_ENDL;
@ -9100,10 +9111,12 @@ bool resolve_appearance_version(const LLAppearanceMessageContents& contents, S32
void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
{
LL_DEBUGS("Avatar") << "starts" << LL_ENDL;
bool enable_verbose_dumps = gSavedSettings.getBOOL("DebugAvatarAppearanceMessage");
static LLCachedControl<bool> enable_verbose_dumps(gSavedSettings, "DebugAvatarAppearanceMessage");
static LLCachedControl<bool> block_avatar_appearance_messages(gSavedSettings, "BlockAvatarAppearanceMessages");
std::string dump_prefix = getFullname() + "_" + (isSelf()?"s":"o") + "_";
if (gSavedSettings.getBOOL("BlockAvatarAppearanceMessages"))
if (block_avatar_appearance_messages)
{
LL_WARNS() << "Blocking AvatarAppearance message" << LL_ENDL;
return;

View File

@ -284,9 +284,9 @@ public:
void idleUpdateLoadingEffect();
void idleUpdateWindEffect();
void idleUpdateNameTag(const LLVector3& root_pos_last);
void idleUpdateNameTagText(BOOL new_name);
void idleUpdateNameTagText(bool new_name);
void idleUpdateNameTagPosition(const LLVector3& root_pos_last);
void idleUpdateNameTagAlpha(BOOL new_name, F32 alpha);
void idleUpdateNameTagAlpha(bool new_name, F32 alpha);
LLColor4 getNameTagColor(bool is_friend);
void clearNameTag();
static void invalidateNameTag(const LLUUID& agent_id);
@ -899,7 +899,7 @@ public:
void startTyping() { mTyping = TRUE; mTypingTimer.reset(); }
void stopTyping() { mTyping = FALSE; }
private:
BOOL mVisibleChat;
bool mVisibleChat;
//--------------------------------------------------------------------
// Lip synch morphs

View File

@ -2964,8 +2964,15 @@ void LLVOVolume::mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin,
break;
case LLViewerMediaObserver::MEDIA_EVENT_FILE_DOWNLOAD:
{
// Media might be blocked, waiting for a file,
// send an empty response to unblock it
const std::vector<std::string> empty_response;
plugin->sendPickFileResponse(empty_response);
LLNotificationsUtil::add("MediaFileDownloadUnsupported");
break;
}
break;
default:
break;

View File

@ -199,19 +199,16 @@ std::string LLWeb::expandURLSubstitutions(const std::string &url,
// find the grid
std::string current_grid = LLGridManager::getInstance()->getGridId();
std::transform(current_grid.begin(), current_grid.end(), current_grid.begin(), ::tolower);
if (current_grid == "agni")
if (current_grid == "damballah")
{
substitution["GRID"] = "secondlife.com";
}
else if (current_grid == "damballah")
{
// Staging grid has its own naming scheme.
substitution["GRID"] = "secondlife-staging.com";
}
else
{
substitution["GRID"] = llformat("%s.lindenlab.com", current_grid.c_str());
}
// Staging grid has its own naming scheme.
substitution["GRID"] = "secondlife-staging.com";
}
else
{
substitution["GRID"] = "secondlife.com";
}
// expand all of the substitution strings and escape the url
std::string expanded_url = url;
LLStringUtil::format(expanded_url, substitution);

View File

@ -1195,6 +1195,16 @@ public:
virtual void post(ResponsePtr response, const LLSD& context, const LLSD& input) const
{
if (LLApp::isExiting())
{
return;
}
if (gDisconnected)
{
return;
}
if (!LLWorld::instanceExists())
{
return;
}
@ -1207,8 +1217,13 @@ public:
return;
}
LLHost sim(input["body"]["sim-ip-and-port"].asString());
LLHost sim(input["body"]["sim-ip-and-port"].asString());
if (sim.isInvalid())
{
LL_WARNS() << "Got EstablishAgentCommunication with invalid host" << LL_ENDL;
return;
}
LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(sim);
if (!regionp)
{
@ -1217,7 +1232,7 @@ public:
return;
}
LL_DEBUGS("CrossingCaps") << "Calling setSeedCapability from LLEstablishAgentCommunication::post. Seed cap == "
<< input["body"]["seed-capability"] << LL_ENDL;
<< input["body"]["seed-capability"] << " for region " << regionp->getRegionID() << LL_ENDL;
regionp->setSeedCapability(input["body"]["seed-capability"]);
}
};

View File

@ -73,4 +73,14 @@
name="lst_action"
value="Start Gesture" />
</rows>
<rows
name="script_trigger_lbutton"
value="script_trigger_lbutton">
<columns
column="lst_action"
font="SansSerif"
halign="left"
name="lst_action"
value="Interact (Script LMB)" />
</rows>
</contents>

View File

@ -20,9 +20,10 @@
name="message">
Listing ID:
</text>
<!--listing_id is a positive S32-->
<line_editor
type="string"
length="1"
max_length_bytes="10"
follows="top|right"
font="SansSerif"
height="20"

View File

@ -2309,6 +2309,7 @@ Please try again later.
<notification
icon="notifytip.tga"
name="LandmarkCreated"
log_to_chat="false"
type="notifytip">
You have added "[LANDMARK_NAME]" to your [FOLDER_NAME] folder.
</notification>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
height="25"
layout="topleft"
name="panel_hide_beacon"
mouse_opaque="false"
visible="true"
width="133">
<button
follows="left|bottom"
height="19"
label="Hide beacon"
layout="topleft"
left="10"
name="hide_beacon_btn"
tool_tip="Stop tracking and hide beacon"
top="2"
visible="false"
width="113" />
</panel>

View File

@ -28,7 +28,7 @@
height="15"
increment="0.025"
initial_value="0.5"
label="Master volume"
label="All volume"
label_width="120"
layout="topleft"
left="0"
@ -386,7 +386,7 @@
left="25"
name="voice_chat_settings"
width="200"
top_pad="7">
top_pad="16">
Voice Chat Settings
</text>
<text

View File

@ -95,7 +95,7 @@
tab_stop="false"
name="state_management_buttons_container"
visible="false"
width="200"/>
width="350"/>
</layout_panel>
<layout_panel name="right_toolbar_panel"
auto_resize="false"

View File

@ -19,7 +19,7 @@
height="15"
increment="0.025"
initial_value="0.5"
label="Master"
label="All"
label_width="60"
left="10"
width="160"

View File

@ -1312,9 +1312,8 @@ class DarwinManifest(ViewerManifest):
]
for attempt in range(3):
if attempt: # second or subsequent iteration
print >> sys.stderr, \
("codesign failed, waiting %d seconds before retrying" %
sign_retry_wait)
print("codesign failed, waiting {:d} seconds before retrying".format(sign_retry_wait),
file=sys.stderr)
time.sleep(sign_retry_wait)
sign_retry_wait*=2
@ -1344,7 +1343,7 @@ class DarwinManifest(ViewerManifest):
# 'err' goes out of scope
sign_failed = err
else:
print >> sys.stderr, "Maximum codesign attempts exceeded; giving up"
print("Maximum codesign attempts exceeded; giving up", file=sys.stderr)
raise sign_failed
self.run_command(['spctl', '-a', '-texec', '-vvvv', app_in_dmg])
self.run_command([self.src_path_of("installers/darwin/apple-notarize.sh"), app_in_dmg])

View File

@ -89,25 +89,26 @@ public:
/// suspend until "somebody else" has bumped mCond by n steps
void yield(int n=1)
{
return yield_until(STRINGIZE("Sync::yield_for(" << n << ") timed out after "
<< int(mTimeout.value()) << "ms"),
mCond.get() + n);
return yield_until("Sync::yield_for", n, mCond.get() + n);
}
/// suspend until "somebody else" has bumped mCond to a specific value
void yield_until(int until)
{
return yield_until(STRINGIZE("Sync::yield_until(" << until << ") timed out after "
<< int(mTimeout.value()) << "ms"),
until);
return yield_until("Sync::yield_until", until, until);
}
private:
void yield_until(const std::string& desc, int until)
void yield_until(const char* func, int arg, int until)
{
std::string name(llcoro::logname());
LL_DEBUGS() << name << " yield_until(" << until << ") suspending" << LL_ENDL;
tut::ensure(name + ' ' + desc, mCond.wait_for_equal(mTimeout, until));
if (! mCond.wait_for_equal(mTimeout, until))
{
tut::fail(STRINGIZE(name << ' ' << func << '(' << arg << ") timed out after "
<< int(mTimeout.value()) << "ms (expected " << until
<< ", actual " << mCond.get() << ')'));
}
// each time we wake up, bump mCond
bump();
}