Merge
commit
e5aeaa659a
2
.hgtags
2
.hgtags
|
|
@ -538,3 +538,5 @@ ad0e15543836d64d6399d28b32852510435e344a 5.1.0-release
|
|||
7b6b020fd5ad9a8dc3670c5c92d1ca92e55fc485 5.1.4-release
|
||||
2ea47f358b171178eb9a95503a1670d519c2886f 5.1.5-release
|
||||
04538b8157c1f5cdacd9403f0a395452d4a93689 5.1.6-release
|
||||
ac3b1332ad4f55b7182a8cbcc1254535a0069f75 5.1.7-release
|
||||
23ea0fe36fadf009a60c080392ce80e4bf8af8d9 5.1.8-release
|
||||
|
|
|
|||
|
|
@ -1692,7 +1692,7 @@
|
|||
<key>darwin</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>3855bd40f950e3c22739ae8f3ee2afc9</string>
|
||||
<key>url</key>
|
||||
|
|
@ -1705,10 +1705,10 @@
|
|||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<key>hash</key>
|
||||
<string>d1521becaf21bf7233173722af63f57d</string>
|
||||
<key>url</key>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15257/98440/kdu-7.10.4.513518-darwin64-513518.tar.bz2</string>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15257/98440/kdu-7.10.4.513518-darwin64-513518.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -1717,10 +1717,10 @@
|
|||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<key>hash</key>
|
||||
<string>43d7a6a69a54534a736f132e9c81795b</string>
|
||||
<key>url</key>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15255/98451/kdu-7.10.4.513518-linux-513518.tar.bz2</string>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15255/98451/kdu-7.10.4.513518-linux-513518.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux</string>
|
||||
|
|
@ -1752,11 +1752,11 @@
|
|||
<key>windows64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>da3b1ea90797b189d80ab5d50fdf05d4</string>
|
||||
<key>url</key>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15260/98469/kdu-7.10.4.513518-windows64-513518.tar.bz2</string>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15260/98469/kdu-7.10.4.513518-windows64-513518.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
|
|
@ -3032,9 +3032,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>b1b0134bc55f55a7c1a04ee78d70c64d</string>
|
||||
<string>a605ec940768c878527d3b8f2ff61288</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12438/73598/slvoice-4.9.0002.27586.511884-darwin64-511884.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/21421/157284/slvoice-4.9.0002.30313.517593-darwin64-517593.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -3068,9 +3068,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>ec50c31efce74bdedee470b5388aeeec</string>
|
||||
<string>5a78539626b5f23522d0b466247f48b4</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12434/73576/slvoice-4.9.0002.27586.511884-windows-511884.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/21422/157291/slvoice-4.9.0002.30313.517593-windows-517593.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
@ -3080,16 +3080,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>4bf45d641bf5b2bd6b2cc39edcb01a6e</string>
|
||||
<string>1f8e09c053c00d9dc44ea74568e63dc1</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12433/73570/slvoice-4.9.0002.27586.511884-windows64-511884.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/21423/157298/slvoice-4.9.0002.30313.517593-windows64-517593.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>4.9.0002.27586.511884</string>
|
||||
<string>4.9.0002.30313.517593</string>
|
||||
</map>
|
||||
<key>tut</key>
|
||||
<map>
|
||||
|
|
@ -3260,9 +3260,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>86f6708f393c162cd4f92426b0a3cde7</string>
|
||||
<string>f45c0a5e7b4601b355e163bf62f5718e</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/15341/99062/viewer_manager-1.0.513570-darwin64-513570.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/20587/147509/viewer_manager-1.0.517052-darwin64-517052.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -3284,9 +3284,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>c4dec51062ad78c09b11f7432aff4d1d</string>
|
||||
<string>d2443caf062697430071d458a965f611</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/17857/121832/viewer_manager-1.0.515286-windows-515286.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/20588/147516/viewer_manager-1.0.517052-windows-517052.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
@ -3297,7 +3297,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>source_type</key>
|
||||
<string>hg</string>
|
||||
<key>version</key>
|
||||
<string>1.0.515286</string>
|
||||
<string>1.0.517052</string>
|
||||
</map>
|
||||
<key>vlc-bin</key>
|
||||
<map>
|
||||
|
|
@ -3548,6 +3548,8 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
</map>
|
||||
<key>package_description</key>
|
||||
<map>
|
||||
<key>canonical_repo</key>
|
||||
<string>https://bitbucket.org/lindenlab/viewer-release</string>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (c) 2014, Linden Research, Inc.</string>
|
||||
<key>description</key>
|
||||
|
|
@ -3662,10 +3664,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<map>
|
||||
<key>command</key>
|
||||
<string>xcodebuild</string>
|
||||
<key>filters</key>
|
||||
<array>
|
||||
<string>setenv</string>
|
||||
</array>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>-configuration</string>
|
||||
|
|
@ -3722,10 +3720,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<map>
|
||||
<key>command</key>
|
||||
<string>xcodebuild</string>
|
||||
<key>filters</key>
|
||||
<array>
|
||||
<string>setenv</string>
|
||||
</array>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>-configuration</string>
|
||||
|
|
|
|||
1
build.sh
1
build.sh
|
|
@ -114,7 +114,6 @@ pre_build()
|
|||
-DRELEASE_CRASH_REPORTING:BOOL="$RELEASE_CRASH_REPORTING" \
|
||||
-DVIEWER_CHANNEL:STRING="${viewer_channel}" \
|
||||
-DGRID:STRING="\"$viewer_grid\"" \
|
||||
-DLL_TESTS:BOOL="$run_tests" \
|
||||
-DTEMPLATE_VERIFIER_OPTIONS:STRING="$template_verifier_options" $template_verifier_master_url \
|
||||
"${SIGNING[@]}" \
|
||||
|| fatal "$variant configuration failed"
|
||||
|
|
|
|||
|
|
@ -220,7 +220,6 @@ Ansariel Hiller
|
|||
STORM-2151
|
||||
MAINT-6917
|
||||
MAINT-8085
|
||||
STORM-2122
|
||||
Aralara Rajal
|
||||
Arare Chantilly
|
||||
CHUIBUG-191
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -335,6 +335,7 @@ const U8 CLICK_ACTION_OPEN = 4;
|
|||
const U8 CLICK_ACTION_PLAY = 5;
|
||||
const U8 CLICK_ACTION_OPEN_MEDIA = 6;
|
||||
const U8 CLICK_ACTION_ZOOM = 7;
|
||||
const U8 CLICK_ACTION_DISABLED = 8;
|
||||
// DO NOT CHANGE THE SEQUENCE OF THIS LIST!!
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
// external library headers
|
||||
#include <boost/bind.hpp>
|
||||
// other Linden headers
|
||||
#include "lltimer.h"
|
||||
#include "llevents.h"
|
||||
#include "llerror.h"
|
||||
#include "stringize.h"
|
||||
|
|
@ -280,6 +281,25 @@ void LLCoros::setStackSize(S32 stacksize)
|
|||
mStackSize = stacksize;
|
||||
}
|
||||
|
||||
void LLCoros::printActiveCoroutines()
|
||||
{
|
||||
LL_INFOS("LLCoros") << "Number of active coroutines: " << (S32)mCoros.size() << LL_ENDL;
|
||||
if (mCoros.size() > 0)
|
||||
{
|
||||
LL_INFOS("LLCoros") << "-------------- List of active coroutines ------------";
|
||||
CoroMap::iterator iter;
|
||||
CoroMap::iterator end = mCoros.end();
|
||||
F64 time = LLTimer::getTotalSeconds();
|
||||
for (iter = mCoros.begin(); iter != end; iter++)
|
||||
{
|
||||
F64 life_time = time - iter->second->mCreationTime;
|
||||
LL_CONT << LL_NEWLINE << "Name: " << iter->first << " life: " << life_time;
|
||||
}
|
||||
LL_CONT << LL_ENDL;
|
||||
LL_INFOS("LLCoros") << "-----------------------------------------------------" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
#if LL_WINDOWS
|
||||
|
||||
static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
|
||||
|
|
@ -375,7 +395,8 @@ LLCoros::CoroData::CoroData(CoroData* prev, const std::string& name,
|
|||
mCoro(boost::bind(toplevel, _1, this, callable), stacksize),
|
||||
// don't consume events unless specifically directed
|
||||
mConsuming(false),
|
||||
mSelf(0)
|
||||
mSelf(0),
|
||||
mCreationTime(LLTimer::getTotalSeconds())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -384,7 +405,13 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl
|
|||
std::string name(generateDistinctName(prefix));
|
||||
Current current;
|
||||
// pass the current value of Current as previous context
|
||||
CoroData* newCoro = new CoroData(current, name, callable, mStackSize);
|
||||
CoroData* newCoro = new(std::nothrow) CoroData(current, name, callable, mStackSize);
|
||||
if (newCoro == NULL)
|
||||
{
|
||||
// Out of memory?
|
||||
printActiveCoroutines();
|
||||
LL_ERRS("LLCoros") << "Failed to start coroutine: " << name << " Stacksize: " << mStackSize << " Total coroutines: " << mCoros.size() << LL_ENDL;
|
||||
}
|
||||
// Store it in our pointer map
|
||||
mCoros.insert(name, newCoro);
|
||||
// also set it as current
|
||||
|
|
|
|||
|
|
@ -151,6 +151,9 @@ public:
|
|||
/// for delayed initialization
|
||||
void setStackSize(S32 stacksize);
|
||||
|
||||
/// for delayed initialization
|
||||
void printActiveCoroutines();
|
||||
|
||||
/// get the current coro::self& for those who really really care
|
||||
static coro::self& get_self();
|
||||
|
||||
|
|
@ -223,6 +226,7 @@ private:
|
|||
// function signature down to that point -- and of course through every
|
||||
// other caller of every such function.
|
||||
LLCoros::coro::self* mSelf;
|
||||
F64 mCreationTime; // since epoch
|
||||
};
|
||||
typedef boost::ptr_map<std::string, CoroData> CoroMap;
|
||||
CoroMap mCoros;
|
||||
|
|
|
|||
|
|
@ -249,23 +249,13 @@ namespace LLError
|
|||
{
|
||||
#ifdef __GNUC__
|
||||
// GCC: type_info::name() returns a mangled class name,st demangle
|
||||
|
||||
static size_t abi_name_len = 100;
|
||||
static char* abi_name_buf = (char*)malloc(abi_name_len);
|
||||
// warning: above is voodoo inferred from the GCC manual,
|
||||
// do NOT change
|
||||
|
||||
int status;
|
||||
// We don't use status, and shouldn't have to pass apointer to it
|
||||
// but gcc 3.3 libstc++'s implementation of demangling is broken
|
||||
// and fails without.
|
||||
|
||||
char* name = abi::__cxa_demangle(mangled,
|
||||
abi_name_buf, &abi_name_len, &status);
|
||||
// this call can realloc the abi_name_buf pointer (!)
|
||||
|
||||
return name ? name : mangled;
|
||||
|
||||
// passing nullptr, 0 forces allocation of a unique buffer we can free
|
||||
// fixing MAINT-8724 on OSX 10.14
|
||||
int status = -1;
|
||||
char* name = abi::__cxa_demangle(mangled, nullptr, 0, &status);
|
||||
std::string result(name ? name : mangled);
|
||||
free(name);
|
||||
return result;
|
||||
#elif LL_WINDOWS
|
||||
// DevStudio: type_info::name() includes the text "class " at the start
|
||||
|
||||
|
|
|
|||
|
|
@ -95,10 +95,12 @@ HttpService::~HttpService()
|
|||
if (! mThread->timedJoin(250))
|
||||
{
|
||||
// Failed to join, expect problems ahead so do a hard termination.
|
||||
mThread->cancel();
|
||||
LL_WARNS(LOG_CORE) << "Destroying HttpService with running thread. Expect problems." << LL_NEWLINE
|
||||
<< "State: " << S32(sState)
|
||||
<< " Last policy: " << U32(mLastPolicy)
|
||||
<< LL_ENDL;
|
||||
|
||||
LL_WARNS(LOG_CORE) << "Destroying HttpService with running thread. Expect problems."
|
||||
<< LL_ENDL;
|
||||
mThread->cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -192,7 +192,13 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
|
|||
ret = (U8*) ll_aligned_malloc<64>(size);
|
||||
if (!ret)
|
||||
{
|
||||
LL_ERRS() << "Failed to allocate for LLVBOPool buffer" << LL_ENDL;
|
||||
LL_ERRS() << "Failed to allocate "<< size << " bytes for LLVBOPool buffer " << name <<"." << LL_NEWLINE
|
||||
<< "Free list size: " << mFreeList.size() // this happens if we are out of memory so a solution might be to clear some from freelist
|
||||
<< " Allocated Bytes: " << LLVertexBuffer::sAllocatedBytes
|
||||
<< " Allocated Index Bytes: " << LLVertexBuffer::sAllocatedIndexBytes
|
||||
<< " Pooled Bytes: " << sBytesPooled
|
||||
<< " Pooled Index Bytes: " << sIndexBytesPooled
|
||||
<< LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2784,7 +2784,6 @@ void LLScrollListCtrl::onClickColumn(void *userdata)
|
|||
}
|
||||
|
||||
// if this column is the primary sort key, reverse the direction
|
||||
sort_column_t cur_sort_column;
|
||||
if (!parent->mSortColumns.empty() && parent->mSortColumns.back().first == column_index)
|
||||
{
|
||||
ascending = !parent->mSortColumns.back().second;
|
||||
|
|
|
|||
|
|
@ -201,6 +201,7 @@ set(viewer_SOURCE_FILES
|
|||
llflickrconnect.cpp
|
||||
llfloaterabout.cpp
|
||||
llfloaterbvhpreview.cpp
|
||||
llfloaterauction.cpp
|
||||
llfloaterautoreplacesettings.cpp
|
||||
llfloateravatar.cpp
|
||||
llfloateravatarpicker.cpp
|
||||
|
|
@ -822,6 +823,7 @@ set(viewer_HEADER_FILES
|
|||
llflickrconnect.h
|
||||
llfloaterabout.h
|
||||
llfloaterbvhpreview.h
|
||||
llfloaterauction.h
|
||||
llfloaterautoreplacesettings.h
|
||||
llfloateravatar.h
|
||||
llfloateravatarpicker.h
|
||||
|
|
@ -2055,7 +2057,12 @@ if (DARWIN)
|
|||
# These all get set with PROPERTIES
|
||||
set(product "Second Life")
|
||||
# this is the setting for the Python wrapper, see SL-322 and WRAPPER line in Info-SecondLife.plist
|
||||
set(MACOSX_WRAPPER_EXECUTABLE_NAME "SL_Launcher")
|
||||
if (PACKAGE)
|
||||
set(MACOSX_WRAPPER_EXECUTABLE_NAME "SL_Launcher")
|
||||
else (PACKAGE)
|
||||
# force the name of the actual executable to allow running it within Xcode for debugging
|
||||
set(MACOSX_WRAPPER_EXECUTABLE_NAME "../Resources/Second Life Viewer.app/Contents/MacOS/Second Life")
|
||||
endif (PACKAGE)
|
||||
set(MACOSX_BUNDLE_INFO_STRING "Second Life Viewer")
|
||||
set(MACOSX_BUNDLE_ICON_FILE "secondlife.icns")
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer")
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
5.1.7
|
||||
5.1.9
|
||||
|
|
|
|||
|
|
@ -3703,13 +3703,13 @@
|
|||
<key>FeatureManagerHTTPTable</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Base directory for HTTP feature/gpu table fetches</string>
|
||||
<string>Deprecated</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>http://viewer-settings.secondlife.com</string>
|
||||
<string></string>
|
||||
</map>
|
||||
<key>FPSLogFrequency</key>
|
||||
<map>
|
||||
|
|
@ -12280,7 +12280,7 @@
|
|||
<key>Comment</key>
|
||||
<string>If TRUE, always load textures at full resolution (discard = 0)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
|
|
|
|||
|
|
@ -76,6 +76,8 @@ const F32 AVATAR_ZOOM_MIN_Y_FACTOR = 0.7f;
|
|||
const F32 AVATAR_ZOOM_MIN_Z_FACTOR = 1.15f;
|
||||
|
||||
const F32 MAX_CAMERA_DISTANCE_FROM_AGENT = 50.f;
|
||||
const F32 MAX_CAMERA_DISTANCE_FROM_OBJECT = 496.f;
|
||||
const F32 CAMERA_FUDGE_FROM_OBJECT = 16.f;
|
||||
|
||||
const F32 MAX_CAMERA_SMOOTH_DISTANCE = 50.0f;
|
||||
|
||||
|
|
@ -738,10 +740,7 @@ F32 LLAgentCamera::getCameraZoomFraction()
|
|||
else
|
||||
{
|
||||
F32 min_zoom;
|
||||
const F32 DIST_FUDGE = 16.f; // meters
|
||||
F32 max_zoom = llmin(mDrawDistance - DIST_FUDGE,
|
||||
LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE,
|
||||
MAX_CAMERA_DISTANCE_FROM_AGENT);
|
||||
F32 max_zoom = getCameraMaxZoomDistance();
|
||||
|
||||
F32 distance = (F32)mCameraFocusOffsetTarget.magVec();
|
||||
if (mFocusObject.notNull())
|
||||
|
|
@ -787,23 +786,17 @@ void LLAgentCamera::setCameraZoomFraction(F32 fraction)
|
|||
else
|
||||
{
|
||||
F32 min_zoom = LAND_MIN_ZOOM;
|
||||
const F32 DIST_FUDGE = 16.f; // meters
|
||||
F32 max_zoom = llmin(mDrawDistance - DIST_FUDGE,
|
||||
LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE,
|
||||
MAX_CAMERA_DISTANCE_FROM_AGENT);
|
||||
F32 max_zoom = getCameraMaxZoomDistance();
|
||||
|
||||
if (mFocusObject.notNull())
|
||||
{
|
||||
if (mFocusObject.notNull())
|
||||
if (mFocusObject->isAvatar())
|
||||
{
|
||||
if (mFocusObject->isAvatar())
|
||||
{
|
||||
min_zoom = AVATAR_MIN_ZOOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
min_zoom = OBJECT_MIN_ZOOM;
|
||||
}
|
||||
min_zoom = AVATAR_MIN_ZOOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
min_zoom = OBJECT_MIN_ZOOM;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -909,10 +902,7 @@ void LLAgentCamera::cameraZoomIn(const F32 fraction)
|
|||
|
||||
new_distance = llmax(new_distance, min_zoom);
|
||||
|
||||
// Don't zoom too far back
|
||||
const F32 DIST_FUDGE = 16.f; // meters
|
||||
F32 max_distance = llmin(mDrawDistance - DIST_FUDGE,
|
||||
LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE );
|
||||
F32 max_distance = getCameraMaxZoomDistance();
|
||||
|
||||
max_distance = llmin(max_distance, current_distance * 4.f); //Scaled max relative to current distance. MAINT-3154
|
||||
|
||||
|
|
@ -978,10 +968,7 @@ void LLAgentCamera::cameraOrbitIn(const F32 meters)
|
|||
|
||||
new_distance = llmax(new_distance, min_zoom);
|
||||
|
||||
// Don't zoom too far back
|
||||
const F32 DIST_FUDGE = 16.f; // meters
|
||||
F32 max_distance = llmin(mDrawDistance - DIST_FUDGE,
|
||||
LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE );
|
||||
F32 max_distance = getCameraMaxZoomDistance();
|
||||
|
||||
if (new_distance > max_distance)
|
||||
{
|
||||
|
|
@ -1946,6 +1933,13 @@ LLVector3 LLAgentCamera::getCameraOffsetInitial()
|
|||
return convert_from_llsd<LLVector3>(mCameraOffsetInitial[mCameraPreset]->get(), TYPE_VEC3, "");
|
||||
}
|
||||
|
||||
F32 LLAgentCamera::getCameraMaxZoomDistance()
|
||||
{
|
||||
// Ignore "DisableCameraConstraints", we don't want to be out of draw range when we focus onto objects or avatars
|
||||
return llmin(MAX_CAMERA_DISTANCE_FROM_OBJECT,
|
||||
mDrawDistance - 1, // convenience, don't hit draw limit when focusing on something
|
||||
LLWorld::getInstance()->getRegionWidthInMeters() - CAMERA_FUDGE_FROM_OBJECT);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// handleScrollWheel()
|
||||
|
|
|
|||
|
|
@ -112,6 +112,8 @@ public:
|
|||
private:
|
||||
/** Determines default camera offset depending on the current camera preset */
|
||||
LLVector3 getCameraOffsetInitial();
|
||||
/** Determines maximum camera distance from target for mouselook, opposite to LAND_MIN_ZOOM */
|
||||
F32 getCameraMaxZoomDistance();
|
||||
|
||||
/** Camera preset in Third Person Mode */
|
||||
ECameraPreset mCameraPreset;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include "llagentlanguage.h"
|
||||
#include "llagentui.h"
|
||||
#include "llagentwearables.h"
|
||||
#include "lldirpicker.h"
|
||||
#include "llfloaterimcontainer.h"
|
||||
#include "llimprocessing.h"
|
||||
#include "llwindow.h"
|
||||
|
|
@ -1082,6 +1083,8 @@ bool LLAppViewer::init()
|
|||
}
|
||||
}
|
||||
|
||||
// don't nag developers who need to run the executable directly
|
||||
#if LL_RELEASE_FOR_DOWNLOAD
|
||||
// MAINT-8305: If we're processing a SLURL, skip the launcher check.
|
||||
if (gSavedSettings.getString("CmdLineLoginLocation").empty())
|
||||
{
|
||||
|
|
@ -1098,6 +1101,7 @@ bool LLAppViewer::init()
|
|||
LLNotificationsUtil::add("RunLauncher");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LL_WINDOWS
|
||||
if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion())
|
||||
|
|
@ -1577,6 +1581,11 @@ bool LLAppViewer::doFrame()
|
|||
saveFinalSnapshot();
|
||||
}
|
||||
|
||||
if (LLVoiceClient::instanceExists())
|
||||
{
|
||||
LLVoiceClient::getInstance()->terminate();
|
||||
}
|
||||
|
||||
delete gServicePump;
|
||||
|
||||
destroyMainloopTimeout();
|
||||
|
|
@ -1676,11 +1685,6 @@ bool LLAppViewer::cleanup()
|
|||
// Give any remaining SLPlugin instances a chance to exit cleanly.
|
||||
LLPluginProcessParent::shutdown();
|
||||
|
||||
if (LLVoiceClient::instanceExists())
|
||||
{
|
||||
LLVoiceClient::getInstance()->terminate();
|
||||
}
|
||||
|
||||
disconnectViewer();
|
||||
|
||||
LL_INFOS() << "Viewer disconnected" << LL_ENDL;
|
||||
|
|
@ -1794,6 +1798,8 @@ bool LLAppViewer::cleanup()
|
|||
// (Deleted observers should have already removed themselves)
|
||||
gInventory.cleanupInventory();
|
||||
|
||||
LLCoros::getInstance()->printActiveCoroutines();
|
||||
|
||||
LL_INFOS() << "Cleaning up Selections" << LL_ENDL;
|
||||
|
||||
// Clean up selection managers after UI is destroyed, as UI may be observing them.
|
||||
|
|
@ -1980,6 +1986,7 @@ bool LLAppViewer::cleanup()
|
|||
mAppCoreHttp.cleanup();
|
||||
|
||||
SUBSYSTEM_CLEANUP(LLFilePickerThread);
|
||||
SUBSYSTEM_CLEANUP(LLDirPickerThread);
|
||||
|
||||
//MUST happen AFTER SUBSYSTEM_CLEANUP(LLCurl)
|
||||
delete sTextureCache;
|
||||
|
|
@ -2150,6 +2157,7 @@ bool LLAppViewer::initThreads()
|
|||
gMeshRepo.init();
|
||||
|
||||
LLFilePickerThread::initClass();
|
||||
LLDirPickerThread::initClass();
|
||||
|
||||
// *FIX: no error handling here!
|
||||
return true;
|
||||
|
|
@ -4584,7 +4592,7 @@ void LLAppViewer::idle()
|
|||
LLSmoothInterpolation::updateInterpolants();
|
||||
LLMortician::updateClass();
|
||||
LLFilePickerThread::clearDead(); //calls LLFilePickerThread::notify()
|
||||
|
||||
LLDirPickerThread::clearDead();
|
||||
F32 dt_raw = idle_timer.getElapsedTimeAndResetF32();
|
||||
|
||||
// Cap out-of-control frame times
|
||||
|
|
|
|||
|
|
@ -528,10 +528,24 @@ public:
|
|||
registrar_enable.add("ObjectIcon.Visible", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemVisible, this, _2));
|
||||
|
||||
LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_avatar_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
|
||||
mPopupMenuHandleAvatar = menu->getHandle();
|
||||
if (menu)
|
||||
{
|
||||
mPopupMenuHandleAvatar = menu->getHandle();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << " Failed to create menu_avatar_icon.xml" << LL_ENDL;
|
||||
}
|
||||
|
||||
menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_object_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
|
||||
mPopupMenuHandleObject = menu->getHandle();
|
||||
if (menu)
|
||||
{
|
||||
mPopupMenuHandleObject = menu->getHandle();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << " Failed to create menu_object_icon.xml" << LL_ENDL;
|
||||
}
|
||||
|
||||
setDoubleClickCallback(boost::bind(&LLChatHistoryHeader::showInspector, this));
|
||||
|
||||
|
|
@ -619,7 +633,12 @@ public:
|
|||
}
|
||||
|
||||
mUserNameFont = style_params.font();
|
||||
LLTextBox* user_name = getChild<LLTextBox>("user_name");
|
||||
if (!mUserNameTextBox)
|
||||
{
|
||||
mUserNameTextBox = getChild<LLTextBox>("user_name");
|
||||
mTimeBoxTextBox = getChild<LLTextBox>("time_box");
|
||||
}
|
||||
LLTextBox* user_name = mUserNameTextBox;
|
||||
user_name->setReadOnlyColor(style_params.readonly_color());
|
||||
user_name->setColor(style_params.color());
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,14 @@ LLDirPicker::LLDirPicker() :
|
|||
mFileName(NULL),
|
||||
mLocked(false)
|
||||
{
|
||||
bi.hwndOwner = NULL;
|
||||
bi.pidlRoot = NULL;
|
||||
bi.pszDisplayName = NULL;
|
||||
bi.lpszTitle = NULL;
|
||||
bi.ulFlags = BIF_USENEWUI;
|
||||
bi.lpfn = NULL;
|
||||
bi.lParam = NULL;
|
||||
bi.iImage = 0;
|
||||
}
|
||||
|
||||
LLDirPicker::~LLDirPicker()
|
||||
|
|
@ -84,7 +92,7 @@ LLDirPicker::~LLDirPicker()
|
|||
// nothing
|
||||
}
|
||||
|
||||
BOOL LLDirPicker::getDir(std::string* filename)
|
||||
BOOL LLDirPicker::getDir(std::string* filename, bool blocking)
|
||||
{
|
||||
if( mLocked )
|
||||
{
|
||||
|
|
@ -99,39 +107,39 @@ BOOL LLDirPicker::getDir(std::string* filename)
|
|||
|
||||
BOOL success = FALSE;
|
||||
|
||||
// Modal, so pause agent
|
||||
send_agent_pause();
|
||||
|
||||
if (blocking)
|
||||
{
|
||||
// Modal, so pause agent
|
||||
send_agent_pause();
|
||||
}
|
||||
|
||||
BROWSEINFO bi;
|
||||
memset(&bi, 0, sizeof(bi));
|
||||
bi.hwndOwner = (HWND)gViewerWindow->getPlatformWindow();
|
||||
|
||||
bi.ulFlags = BIF_USENEWUI;
|
||||
bi.hwndOwner = (HWND)gViewerWindow->getPlatformWindow();
|
||||
bi.lpszTitle = NULL;
|
||||
::OleInitialize(NULL);
|
||||
LPITEMIDLIST pIDL = ::SHBrowseForFolder(&bi);
|
||||
|
||||
::OleInitialize(NULL);
|
||||
if(pIDL != NULL)
|
||||
{
|
||||
WCHAR buffer[_MAX_PATH] = {'\0'};
|
||||
|
||||
LPITEMIDLIST pIDL = ::SHBrowseForFolder(&bi);
|
||||
if(::SHGetPathFromIDList(pIDL, buffer) != 0)
|
||||
{
|
||||
// Set the string value.
|
||||
|
||||
if(pIDL != NULL)
|
||||
{
|
||||
WCHAR buffer[_MAX_PATH] = {'\0'};
|
||||
mDir = utf16str_to_utf8str(llutf16string(buffer));
|
||||
success = TRUE;
|
||||
}
|
||||
// free the item id list
|
||||
CoTaskMemFree(pIDL);
|
||||
}
|
||||
|
||||
if(::SHGetPathFromIDList(pIDL, buffer) != 0)
|
||||
{
|
||||
// Set the string value.
|
||||
::OleUninitialize();
|
||||
|
||||
mDir = utf16str_to_utf8str(llutf16string(buffer));
|
||||
success = TRUE;
|
||||
}
|
||||
|
||||
// free the item id list
|
||||
CoTaskMemFree(pIDL);
|
||||
}
|
||||
|
||||
::OleUninitialize();
|
||||
|
||||
send_agent_resume();
|
||||
if (blocking)
|
||||
{
|
||||
send_agent_resume();
|
||||
}
|
||||
|
||||
// Account for the fact that the app has been stalled.
|
||||
LLFrameTimer::updateFrameTime();
|
||||
|
|
@ -167,7 +175,7 @@ void LLDirPicker::reset()
|
|||
|
||||
|
||||
//static
|
||||
BOOL LLDirPicker::getDir(std::string* filename)
|
||||
BOOL LLDirPicker::getDir(std::string* filename, bool blocking)
|
||||
{
|
||||
LLFilePicker::ELoadFilter filter=LLFilePicker::FFLOAD_DIRECTORY;
|
||||
|
||||
|
|
@ -201,7 +209,7 @@ void LLDirPicker::reset()
|
|||
mFilePicker->reset();
|
||||
}
|
||||
|
||||
BOOL LLDirPicker::getDir(std::string* filename)
|
||||
BOOL LLDirPicker::getDir(std::string* filename, bool blocking)
|
||||
{
|
||||
reset();
|
||||
|
||||
|
|
@ -256,7 +264,7 @@ void LLDirPicker::reset()
|
|||
{
|
||||
}
|
||||
|
||||
BOOL LLDirPicker::getDir(std::string* filename)
|
||||
BOOL LLDirPicker::getDir(std::string* filename, bool blocking)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -267,3 +275,94 @@ std::string LLDirPicker::getDirName()
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
LLMutex* LLDirPickerThread::sMutex = NULL;
|
||||
std::queue<LLDirPickerThread*> LLDirPickerThread::sDeadQ;
|
||||
|
||||
void LLDirPickerThread::getFile()
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
start();
|
||||
#else
|
||||
run();
|
||||
#endif
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLDirPickerThread::run()
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
bool blocking = false;
|
||||
#else
|
||||
bool blocking = true; // modal
|
||||
#endif
|
||||
|
||||
LLDirPicker picker;
|
||||
|
||||
if (picker.getDir(&mProposedName, blocking))
|
||||
{
|
||||
mResponses.push_back(picker.getDirName());
|
||||
}
|
||||
|
||||
{
|
||||
LLMutexLock lock(sMutex);
|
||||
sDeadQ.push(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//static
|
||||
void LLDirPickerThread::initClass()
|
||||
{
|
||||
sMutex = new LLMutex(NULL);
|
||||
}
|
||||
|
||||
//static
|
||||
void LLDirPickerThread::cleanupClass()
|
||||
{
|
||||
clearDead();
|
||||
|
||||
delete sMutex;
|
||||
sMutex = NULL;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLDirPickerThread::clearDead()
|
||||
{
|
||||
if (!sDeadQ.empty())
|
||||
{
|
||||
LLMutexLock lock(sMutex);
|
||||
while (!sDeadQ.empty())
|
||||
{
|
||||
LLDirPickerThread* thread = sDeadQ.front();
|
||||
thread->notify(thread->mResponses);
|
||||
delete thread;
|
||||
sDeadQ.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLDirPickerThread::LLDirPickerThread(const dir_picked_signal_t::slot_type& cb, const std::string &proposed_name)
|
||||
: LLThread("dir picker"),
|
||||
mFilePickedSignal(NULL)
|
||||
{
|
||||
mFilePickedSignal = new dir_picked_signal_t();
|
||||
mFilePickedSignal->connect(cb);
|
||||
}
|
||||
|
||||
LLDirPickerThread::~LLDirPickerThread()
|
||||
{
|
||||
delete mFilePickedSignal;
|
||||
}
|
||||
|
||||
void LLDirPickerThread::notify(const std::vector<std::string>& filenames)
|
||||
{
|
||||
if (!filenames.empty())
|
||||
{
|
||||
if (mFilePickedSignal)
|
||||
{
|
||||
(*mFilePickedSignal)(filenames, mProposedName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,13 @@
|
|||
|
||||
#include "stdtypes.h"
|
||||
|
||||
#include "llthread.h"
|
||||
#include <queue>
|
||||
|
||||
#if LL_WINDOWS
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
|
||||
#if LL_DARWIN
|
||||
|
||||
// AssertMacros.h does bad things.
|
||||
|
|
@ -53,7 +60,7 @@ public:
|
|||
// calling this before main() is undefined
|
||||
static LLDirPicker& instance( void ) { return sInstance; }
|
||||
|
||||
BOOL getDir(std::string* filename);
|
||||
BOOL getDir(std::string* filename, bool blocking = true);
|
||||
std::string getDirName();
|
||||
|
||||
// clear any lists of buffers or whatever, and make sure the dir
|
||||
|
|
@ -76,11 +83,15 @@ private:
|
|||
LLFilePicker *mFilePicker;
|
||||
#endif
|
||||
|
||||
|
||||
std::string* mFileName;
|
||||
std::string mDir;
|
||||
bool mLocked;
|
||||
|
||||
static LLDirPicker sInstance;
|
||||
#if LL_WINDOWS
|
||||
BROWSEINFO bi;
|
||||
#endif
|
||||
|
||||
public:
|
||||
// don't call these directly please.
|
||||
|
|
@ -88,4 +99,33 @@ public:
|
|||
~LLDirPicker();
|
||||
};
|
||||
|
||||
class LLDirPickerThread : public LLThread
|
||||
{
|
||||
public:
|
||||
|
||||
static std::queue<LLDirPickerThread*> sDeadQ;
|
||||
static LLMutex* sMutex;
|
||||
|
||||
static void initClass();
|
||||
static void cleanupClass();
|
||||
static void clearDead();
|
||||
|
||||
std::vector<std::string> mResponses;
|
||||
std::string mProposedName;
|
||||
|
||||
typedef boost::signals2::signal<void(const std::vector<std::string>& filenames, std::string proposed_name)> dir_picked_signal_t;
|
||||
|
||||
LLDirPickerThread(const dir_picked_signal_t::slot_type& cb, const std::string &proposed_name);
|
||||
~LLDirPickerThread();
|
||||
|
||||
void getFile();
|
||||
|
||||
virtual void run();
|
||||
|
||||
virtual void notify(const std::vector<std::string>& filenames);
|
||||
|
||||
private:
|
||||
dir_picked_signal_t* mFilePickedSignal;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -328,6 +328,9 @@ void LLDrawPoolAlpha::render(S32 pass)
|
|||
gGL.diffuseColor4f(0, 0, 1, 1);
|
||||
pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
|
||||
|
||||
gGL.diffuseColor4f(0, 1, 0, 1);
|
||||
pushBatches(LLRenderPass::PASS_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
|
||||
|
||||
if(shaders)
|
||||
{
|
||||
gHighlightProgram.unbind();
|
||||
|
|
|
|||
|
|
@ -62,13 +62,10 @@
|
|||
|
||||
#if LL_DARWIN
|
||||
const char FEATURE_TABLE_FILENAME[] = "featuretable_mac.txt";
|
||||
const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_mac.%s.txt";
|
||||
#elif LL_LINUX
|
||||
const char FEATURE_TABLE_FILENAME[] = "featuretable_linux.txt";
|
||||
const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_linux.%s.txt";
|
||||
#else
|
||||
const char FEATURE_TABLE_FILENAME[] = "featuretable.txt";
|
||||
const char FEATURE_TABLE_VER_FILENAME[] = "featuretable.%s.txt";
|
||||
#endif
|
||||
|
||||
#if 0 // consuming code in #if 0 below
|
||||
|
|
@ -273,33 +270,11 @@ bool LLFeatureManager::loadFeatureTables()
|
|||
app_path += gDirUtilp->getDirDelimiter();
|
||||
|
||||
std::string filename;
|
||||
std::string http_filename;
|
||||
filename = FEATURE_TABLE_FILENAME;
|
||||
http_filename = llformat(FEATURE_TABLE_VER_FILENAME, LLVersionInfo::getVersion().c_str());
|
||||
|
||||
app_path += filename;
|
||||
|
||||
// second table is downloaded with HTTP - note that this will only be used on the run _after_ it is downloaded
|
||||
std::string http_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, http_filename);
|
||||
|
||||
// use HTTP table if it exists
|
||||
std::string path;
|
||||
bool parse_ok = false;
|
||||
if (gDirUtilp->fileExists(http_path))
|
||||
{
|
||||
parse_ok = parseFeatureTable(http_path);
|
||||
if (!parse_ok)
|
||||
{
|
||||
// the HTTP table failed to parse, so delete it
|
||||
LLFile::remove(http_path);
|
||||
LL_WARNS("RenderInit") << "Removed invalid feature table '" << http_path << "'" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!parse_ok)
|
||||
{
|
||||
parse_ok = parseFeatureTable(app_path);
|
||||
}
|
||||
bool parse_ok = parseFeatureTable(app_path);
|
||||
|
||||
return parse_ok;
|
||||
}
|
||||
|
|
@ -407,7 +382,16 @@ bool LLFeatureManager::loadGPUClass()
|
|||
if (!gSavedSettings.getBOOL("SkipBenchmark"))
|
||||
{
|
||||
//get memory bandwidth from benchmark
|
||||
F32 gbps = gpu_benchmark();
|
||||
F32 gbps;
|
||||
try
|
||||
{
|
||||
gbps = gpu_benchmark();
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
gbps = -1.f;
|
||||
LL_WARNS("RenderInit") << "GPU benchmark failed: " << e.what() << LL_ENDL;
|
||||
}
|
||||
|
||||
if (gbps < 0.f)
|
||||
{ //couldn't bench, use GLVersion
|
||||
|
|
@ -486,70 +470,6 @@ bool LLFeatureManager::loadGPUClass()
|
|||
return true; // indicates that a gpu value was established
|
||||
}
|
||||
|
||||
void LLFeatureManager::fetchFeatureTableCoro(std::string tableName)
|
||||
{
|
||||
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
|
||||
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
|
||||
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FeatureManagerHTTPTable", httpPolicy));
|
||||
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
|
||||
|
||||
const std::string base = gSavedSettings.getString("FeatureManagerHTTPTable");
|
||||
|
||||
|
||||
#if LL_WINDOWS
|
||||
std::string os_string = LLOSInfo::instance().getOSStringSimple();
|
||||
std::string filename;
|
||||
|
||||
if (os_string.find("Microsoft Windows XP") == 0)
|
||||
{
|
||||
filename = llformat(tableName.c_str(), "_xp", LLVersionInfo::getVersion().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = llformat(tableName.c_str(), "", LLVersionInfo::getVersion().c_str());
|
||||
}
|
||||
#else
|
||||
const std::string filename = llformat(tableName.c_str(), LLVersionInfo::getVersion().c_str());
|
||||
#endif
|
||||
|
||||
std::string url = base + "/" + filename;
|
||||
// testing url below
|
||||
//url = "http://viewer-settings.secondlife.com/featuretable.2.1.1.208406.txt";
|
||||
const std::string path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename);
|
||||
|
||||
|
||||
LL_INFOS() << "LLFeatureManager fetching " << url << " into " << path << LL_ENDL;
|
||||
|
||||
LLSD result = httpAdapter->getRawAndSuspend(httpRequest, url);
|
||||
|
||||
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
|
||||
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
|
||||
|
||||
if (status)
|
||||
{ // There was a newer feature table on the server. We've grabbed it and now should write it.
|
||||
// write to file
|
||||
const LLSD::Binary &raw = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary();
|
||||
|
||||
LL_INFOS() << "writing feature table to " << path << LL_ENDL;
|
||||
|
||||
S32 size = raw.size();
|
||||
if (size > 0)
|
||||
{
|
||||
// write to file
|
||||
LLAPRFile out(path, LL_APR_WB);
|
||||
out.write(raw.data(), size);
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fetch table(s) from a website (S3)
|
||||
void LLFeatureManager::fetchHTTPTables()
|
||||
{
|
||||
LLCoros::instance().launch("LLFeatureManager::fetchFeatureTableCoro",
|
||||
boost::bind(&LLFeatureManager::fetchFeatureTableCoro, this, FEATURE_TABLE_VER_FILENAME));
|
||||
}
|
||||
|
||||
void LLFeatureManager::cleanupFeatureTables()
|
||||
{
|
||||
std::for_each(mMaskList.begin(), mMaskList.end(), DeletePairedPointer());
|
||||
|
|
|
|||
|
|
@ -145,9 +145,6 @@ public:
|
|||
// in the skip list if true
|
||||
void applyFeatures(bool skipFeatures);
|
||||
|
||||
// load the dynamic GPU/feature table from a website
|
||||
void fetchHTTPTables();
|
||||
|
||||
LLSD getRecommendedSettingsMap();
|
||||
|
||||
protected:
|
||||
|
|
@ -158,8 +155,6 @@ protected:
|
|||
|
||||
void initBaseMask();
|
||||
|
||||
void fetchFeatureTableCoro(std::string name);
|
||||
|
||||
std::map<std::string, LLFeatureList *> mMaskList;
|
||||
std::set<std::string> mSkippedFeatures;
|
||||
BOOL mInited;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,552 @@
|
|||
/**
|
||||
* @file llfloaterauction.cpp
|
||||
* @author James Cook, Ian Wilkes
|
||||
* @brief Implementation of the auction floater.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "llfloaterauction.h"
|
||||
|
||||
#include "llgl.h"
|
||||
#include "llimagej2c.h"
|
||||
#include "llimagetga.h"
|
||||
#include "llparcel.h"
|
||||
#include "llvfile.h"
|
||||
#include "llvfs.h"
|
||||
#include "llwindow.h"
|
||||
#include "message.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llassetstorage.h"
|
||||
#include "llcombobox.h"
|
||||
#include "llestateinfomodel.h"
|
||||
#include "llmimetypes.h"
|
||||
#include "llnotifications.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llsavedsettingsglue.h"
|
||||
#include "llviewertexturelist.h"
|
||||
#include "llviewerparcelmgr.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llviewerdisplay.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llui.h"
|
||||
#include "llrender.h"
|
||||
#include "llsdutil.h"
|
||||
#include "llsdutil_math.h"
|
||||
#include "lltrans.h"
|
||||
#include "llcorehttputil.h"
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Local function declarations, constants, enums, and typedefs
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
void auction_j2c_upload_done(const LLUUID& asset_id,
|
||||
void* user_data, S32 status, LLExtStat ext_status);
|
||||
void auction_tga_upload_done(const LLUUID& asset_id,
|
||||
void* user_data, S32 status, LLExtStat ext_status);
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class llfloaterauction
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
// Default constructor
|
||||
LLFloaterAuction::LLFloaterAuction(const LLSD& key)
|
||||
: LLFloater(key),
|
||||
mParcelID(-1)
|
||||
{
|
||||
mCommitCallbackRegistrar.add("ClickSnapshot", boost::bind(&LLFloaterAuction::onClickSnapshot, this));
|
||||
mCommitCallbackRegistrar.add("ClickSellToAnyone", boost::bind(&LLFloaterAuction::onClickSellToAnyone, this));
|
||||
mCommitCallbackRegistrar.add("ClickStartAuction", boost::bind(&LLFloaterAuction::onClickStartAuction, this));
|
||||
mCommitCallbackRegistrar.add("ClickResetParcel", boost::bind(&LLFloaterAuction::onClickResetParcel, this));
|
||||
}
|
||||
|
||||
// Destroys the object
|
||||
LLFloaterAuction::~LLFloaterAuction()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLFloaterAuction::postBuild()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLFloaterAuction::onOpen(const LLSD& key)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
void LLFloaterAuction::initialize()
|
||||
{
|
||||
mParcelUpdateCapUrl.clear();
|
||||
|
||||
mParcelp = LLViewerParcelMgr::getInstance()->getParcelSelection();
|
||||
LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
|
||||
LLParcel* parcelp = mParcelp->getParcel();
|
||||
if(parcelp && region && !parcelp->getForSale())
|
||||
{
|
||||
mParcelHost = region->getHost();
|
||||
mParcelID = parcelp->getLocalID();
|
||||
mParcelUpdateCapUrl = region->getCapability("ParcelPropertiesUpdate");
|
||||
|
||||
getChild<LLUICtrl>("parcel_text")->setValue(parcelp->getName());
|
||||
getChildView("snapshot_btn")->setEnabled(TRUE);
|
||||
getChildView("reset_parcel_btn")->setEnabled(TRUE);
|
||||
getChildView("start_auction_btn")->setEnabled(TRUE);
|
||||
|
||||
U32 estate_id = LLEstateInfoModel::instance().getID();
|
||||
// Only enable "Sell to Anyone" on Teen grid or if we don't know the ID yet
|
||||
getChildView("sell_to_anyone_btn")->setEnabled(estate_id == ESTATE_TEEN || estate_id == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
mParcelHost.invalidate();
|
||||
if(parcelp && parcelp->getForSale())
|
||||
{
|
||||
getChild<LLUICtrl>("parcel_text")->setValue(getString("already for sale"));
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLUICtrl>("parcel_text")->setValue(LLStringUtil::null);
|
||||
}
|
||||
mParcelID = -1;
|
||||
getChildView("snapshot_btn")->setEnabled(false);
|
||||
getChildView("reset_parcel_btn")->setEnabled(false);
|
||||
getChildView("sell_to_anyone_btn")->setEnabled(false);
|
||||
getChildView("start_auction_btn")->setEnabled(false);
|
||||
}
|
||||
|
||||
mImageID.setNull();
|
||||
mImage = NULL;
|
||||
}
|
||||
|
||||
void LLFloaterAuction::draw()
|
||||
{
|
||||
LLFloater::draw();
|
||||
|
||||
if(!isMinimized() && mImage.notNull())
|
||||
{
|
||||
LLView* snapshot_icon = findChildView("snapshot_icon");
|
||||
if (snapshot_icon)
|
||||
{
|
||||
LLRect rect = snapshot_icon->getRect();
|
||||
{
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gl_rect_2d(rect, LLColor4(0.f, 0.f, 0.f, 1.f));
|
||||
rect.stretch(-1);
|
||||
}
|
||||
{
|
||||
LLGLSUIDefault gls_ui;
|
||||
gGL.color3f(1.f, 1.f, 1.f);
|
||||
gl_draw_scaled_image(rect.mLeft,
|
||||
rect.mBottom,
|
||||
rect.getWidth(),
|
||||
rect.getHeight(),
|
||||
mImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLFloaterAuction::onClickSnapshot(void* data)
|
||||
{
|
||||
LLFloaterAuction* self = (LLFloaterAuction*)(data);
|
||||
|
||||
LLPointer<LLImageRaw> raw = new LLImageRaw;
|
||||
|
||||
gForceRenderLandFence = self->getChild<LLUICtrl>("fence_check")->getValue().asBoolean();
|
||||
BOOL success = gViewerWindow->rawSnapshot(raw,
|
||||
gViewerWindow->getWindowWidthScaled(),
|
||||
gViewerWindow->getWindowHeightScaled(),
|
||||
TRUE, FALSE,
|
||||
FALSE, FALSE);
|
||||
gForceRenderLandFence = FALSE;
|
||||
|
||||
if (success)
|
||||
{
|
||||
self->mTransactionID.generate();
|
||||
self->mImageID = self->mTransactionID.makeAssetID(gAgent.getSecureSessionID());
|
||||
|
||||
if(!gSavedSettings.getBOOL("QuietSnapshotsToDisk"))
|
||||
{
|
||||
gViewerWindow->playSnapshotAnimAndSound();
|
||||
}
|
||||
LL_INFOS() << "Writing TGA..." << LL_ENDL;
|
||||
|
||||
LLPointer<LLImageTGA> tga = new LLImageTGA;
|
||||
tga->encode(raw);
|
||||
LLVFile::writeFile(tga->getData(), tga->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_IMAGE_TGA);
|
||||
|
||||
raw->biasedScaleToPowerOfTwo(LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT);
|
||||
|
||||
LL_INFOS() << "Writing J2C..." << LL_ENDL;
|
||||
|
||||
LLPointer<LLImageJ2C> j2c = new LLImageJ2C;
|
||||
j2c->encode(raw, 0.0f);
|
||||
LLVFile::writeFile(j2c->getData(), j2c->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_TEXTURE);
|
||||
|
||||
self->mImage = LLViewerTextureManager::getLocalTexture((LLImageRaw*)raw, FALSE);
|
||||
gGL.getTexUnit(0)->bind(self->mImage);
|
||||
self->mImage->setAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "Unable to take snapshot" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterAuction::onClickStartAuction(void* data)
|
||||
{
|
||||
LLFloaterAuction* self = (LLFloaterAuction*)(data);
|
||||
|
||||
if(self->mImageID.notNull())
|
||||
{
|
||||
LLSD parcel_name = self->getChild<LLUICtrl>("parcel_text")->getValue();
|
||||
|
||||
// create the asset
|
||||
std::string* name = new std::string(parcel_name.asString());
|
||||
gAssetStorage->storeAssetData(self->mTransactionID, LLAssetType::AT_IMAGE_TGA,
|
||||
&auction_tga_upload_done,
|
||||
(void*)name,
|
||||
FALSE);
|
||||
self->getWindow()->incBusyCount();
|
||||
|
||||
std::string* j2c_name = new std::string(parcel_name.asString());
|
||||
gAssetStorage->storeAssetData(self->mTransactionID, LLAssetType::AT_TEXTURE,
|
||||
&auction_j2c_upload_done,
|
||||
(void*)j2c_name,
|
||||
FALSE);
|
||||
self->getWindow()->incBusyCount();
|
||||
|
||||
LLNotificationsUtil::add("UploadingAuctionSnapshot");
|
||||
|
||||
}
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
|
||||
msg->newMessage("ViewerStartAuction");
|
||||
|
||||
msg->nextBlock("AgentData");
|
||||
msg->addUUID("AgentID", gAgent.getID());
|
||||
msg->addUUID("SessionID", gAgent.getSessionID());
|
||||
msg->nextBlock("ParcelData");
|
||||
msg->addS32("LocalID", self->mParcelID);
|
||||
msg->addUUID("SnapshotID", self->mImageID);
|
||||
msg->sendReliable(self->mParcelHost);
|
||||
|
||||
// clean up floater, and get out
|
||||
self->cleanupAndClose();
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterAuction::cleanupAndClose()
|
||||
{
|
||||
mImageID.setNull();
|
||||
mImage = NULL;
|
||||
mParcelID = -1;
|
||||
mParcelHost.invalidate();
|
||||
closeFloater();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// static glue
|
||||
void LLFloaterAuction::onClickResetParcel(void* data)
|
||||
{
|
||||
LLFloaterAuction* self = (LLFloaterAuction*)(data);
|
||||
if (self)
|
||||
{
|
||||
self->doResetParcel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Reset all the values for the parcel in preparation for a sale
|
||||
void LLFloaterAuction::doResetParcel()
|
||||
{
|
||||
LLParcel* parcelp = mParcelp->getParcel();
|
||||
LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
|
||||
|
||||
if (parcelp
|
||||
&& region
|
||||
&& !mParcelUpdateCapUrl.empty())
|
||||
{
|
||||
LLSD body;
|
||||
std::string empty;
|
||||
|
||||
// request new properties update from simulator
|
||||
U32 message_flags = 0x01;
|
||||
body["flags"] = ll_sd_from_U32(message_flags);
|
||||
|
||||
// Set all the default parcel properties for auction
|
||||
body["local_id"] = parcelp->getLocalID();
|
||||
|
||||
U32 parcel_flags = PF_ALLOW_LANDMARK |
|
||||
PF_ALLOW_FLY |
|
||||
PF_CREATE_GROUP_OBJECTS |
|
||||
PF_ALLOW_ALL_OBJECT_ENTRY |
|
||||
PF_ALLOW_GROUP_OBJECT_ENTRY |
|
||||
PF_ALLOW_GROUP_SCRIPTS |
|
||||
PF_RESTRICT_PUSHOBJECT |
|
||||
PF_SOUND_LOCAL |
|
||||
PF_ALLOW_VOICE_CHAT |
|
||||
PF_USE_ESTATE_VOICE_CHAN;
|
||||
|
||||
body["parcel_flags"] = ll_sd_from_U32(parcel_flags);
|
||||
|
||||
// Build a parcel name like "Ahern (128,128) PG 4032m"
|
||||
std::ostringstream parcel_name;
|
||||
LLVector3 center_point( parcelp->getCenterpoint() );
|
||||
center_point.snap(0); // Get rid of fractions
|
||||
parcel_name << region->getName()
|
||||
<< " ("
|
||||
<< (S32) center_point.mV[VX]
|
||||
<< ","
|
||||
<< (S32) center_point.mV[VY]
|
||||
<< ") "
|
||||
<< region->getSimAccessString()
|
||||
<< " "
|
||||
<< parcelp->getArea()
|
||||
<< "m";
|
||||
|
||||
std::string new_name(parcel_name.str().c_str());
|
||||
body["name"] = new_name;
|
||||
getChild<LLUICtrl>("parcel_text")->setValue(new_name); // Set name in dialog as well, since it won't get updated otherwise
|
||||
|
||||
body["sale_price"] = (S32) 0;
|
||||
body["description"] = empty;
|
||||
body["music_url"] = empty;
|
||||
body["media_url"] = empty;
|
||||
body["media_desc"] = empty;
|
||||
body["media_type"] = LLMIMETypes::getDefaultMimeType();
|
||||
body["media_width"] = (S32) 0;
|
||||
body["media_height"] = (S32) 0;
|
||||
body["auto_scale"] = (S32) 0;
|
||||
body["media_loop"] = (S32) 0;
|
||||
body["obscure_media"] = (S32) 0; // OBSOLETE - no longer used
|
||||
body["obscure_music"] = (S32) 0; // OBSOLETE - no longer used
|
||||
body["media_id"] = LLUUID::null;
|
||||
body["group_id"] = MAINTENANCE_GROUP_ID; // Use maintenance group
|
||||
body["pass_price"] = (S32) 10; // Defaults to $10
|
||||
body["pass_hours"] = 0.0f;
|
||||
body["category"] = (U8) LLParcel::C_NONE;
|
||||
body["auth_buyer_id"] = LLUUID::null;
|
||||
body["snapshot_id"] = LLUUID::null;
|
||||
body["user_location"] = ll_sd_from_vector3( LLVector3::zero );
|
||||
body["user_look_at"] = ll_sd_from_vector3( LLVector3::zero );
|
||||
body["landing_type"] = (U8) LLParcel::L_DIRECT;
|
||||
|
||||
LL_INFOS() << "Sending parcel update to reset for auction via capability to: "
|
||||
<< mParcelUpdateCapUrl << LL_ENDL;
|
||||
|
||||
LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(mParcelUpdateCapUrl, body,
|
||||
"Parcel reset for auction",
|
||||
"Parcel not set for auction.");
|
||||
|
||||
// Send a message to clear the object return time
|
||||
LLMessageSystem *msg = gMessageSystem;
|
||||
msg->newMessageFast(_PREHASH_ParcelSetOtherCleanTime);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
msg->nextBlockFast(_PREHASH_ParcelData);
|
||||
msg->addS32Fast(_PREHASH_LocalID, parcelp->getLocalID());
|
||||
msg->addS32Fast(_PREHASH_OtherCleanTime, 5); // 5 minute object auto-return
|
||||
|
||||
msg->sendReliable(region->getHost());
|
||||
|
||||
// Clear the access lists
|
||||
clearParcelAccessList(parcelp, region, AL_ACCESS);
|
||||
clearParcelAccessList(parcelp, region, AL_BAN);
|
||||
clearParcelAccessList(parcelp, region, AL_ALLOW_EXPERIENCE);
|
||||
clearParcelAccessList(parcelp, region, AL_BLOCK_EXPERIENCE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LLFloaterAuction::clearParcelAccessList(LLParcel* parcel, LLViewerRegion* region, U32 list)
|
||||
{
|
||||
if (!region || !parcel) return;
|
||||
|
||||
LLUUID transactionUUID;
|
||||
transactionUUID.generate();
|
||||
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
|
||||
msg->newMessageFast(_PREHASH_ParcelAccessListUpdate);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
|
||||
msg->nextBlockFast(_PREHASH_Data);
|
||||
msg->addU32Fast(_PREHASH_Flags, list);
|
||||
msg->addS32(_PREHASH_LocalID, parcel->getLocalID() );
|
||||
msg->addUUIDFast(_PREHASH_TransactionID, transactionUUID);
|
||||
msg->addS32Fast(_PREHASH_SequenceID, 1); // sequence_id
|
||||
msg->addS32Fast(_PREHASH_Sections, 0); // num_sections
|
||||
|
||||
// pack an empty block since there will be no data
|
||||
msg->nextBlockFast(_PREHASH_List);
|
||||
msg->addUUIDFast(_PREHASH_ID, LLUUID::null );
|
||||
msg->addS32Fast(_PREHASH_Time, 0 );
|
||||
msg->addU32Fast(_PREHASH_Flags, 0 );
|
||||
|
||||
msg->sendReliable( region->getHost() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
// static - 'Sell to Anyone' clicked, throw up a confirmation dialog
|
||||
void LLFloaterAuction::onClickSellToAnyone(void* data)
|
||||
{
|
||||
LLFloaterAuction* self = (LLFloaterAuction*)(data);
|
||||
if (self)
|
||||
{
|
||||
LLParcel* parcelp = self->mParcelp->getParcel();
|
||||
|
||||
// Do a confirmation
|
||||
S32 sale_price = parcelp->getArea(); // Selling for L$1 per meter
|
||||
S32 area = parcelp->getArea();
|
||||
|
||||
LLSD args;
|
||||
args["LAND_SIZE"] = llformat("%d", area);
|
||||
args["SALE_PRICE"] = llformat("%d", sale_price);
|
||||
args["NAME"] = LLTrans::getString("Anyone");
|
||||
|
||||
LLNotification::Params params("ConfirmLandSaleChange"); // Re-use existing dialog
|
||||
params.substitutions(args)
|
||||
.functor.function(boost::bind(&LLFloaterAuction::onSellToAnyoneConfirmed, self, _1, _2));
|
||||
|
||||
params.name("ConfirmLandSaleToAnyoneChange");
|
||||
|
||||
// ask away
|
||||
LLNotifications::instance().add(params);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Sell confirmation clicked
|
||||
bool LLFloaterAuction::onSellToAnyoneConfirmed(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if (option == 0)
|
||||
{
|
||||
doSellToAnyone();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Reset all the values for the parcel in preparation for a sale
|
||||
void LLFloaterAuction::doSellToAnyone()
|
||||
{
|
||||
LLParcel* parcelp = mParcelp->getParcel();
|
||||
LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
|
||||
|
||||
if (parcelp
|
||||
&& region
|
||||
&& !mParcelUpdateCapUrl.empty())
|
||||
{
|
||||
LLSD body;
|
||||
std::string empty;
|
||||
|
||||
// request new properties update from simulator
|
||||
U32 message_flags = 0x01;
|
||||
body["flags"] = ll_sd_from_U32(message_flags);
|
||||
|
||||
// Set all the default parcel properties for auction
|
||||
body["local_id"] = parcelp->getLocalID();
|
||||
|
||||
// Set 'for sale' flag
|
||||
U32 parcel_flags = parcelp->getParcelFlags() | PF_FOR_SALE;
|
||||
// Ensure objects not included
|
||||
parcel_flags &= ~PF_FOR_SALE_OBJECTS;
|
||||
body["parcel_flags"] = ll_sd_from_U32(parcel_flags);
|
||||
|
||||
body["sale_price"] = parcelp->getArea(); // Sell for L$1 per square meter
|
||||
body["auth_buyer_id"] = LLUUID::null; // To anyone
|
||||
|
||||
LL_INFOS() << "Sending parcel update to sell to anyone for L$1 via capability to: "
|
||||
<< mParcelUpdateCapUrl << LL_ENDL;
|
||||
|
||||
LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(mParcelUpdateCapUrl, body,
|
||||
"Parcel set as sell to everyone.",
|
||||
"Parcel sell to everyone failed.");
|
||||
|
||||
// clean up floater, and get out
|
||||
cleanupAndClose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Local function definitions
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
void auction_tga_upload_done(const LLUUID& asset_id, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
|
||||
{
|
||||
std::string* name = (std::string*)(user_data);
|
||||
LL_INFOS() << "Upload of asset '" << *name << "' " << asset_id
|
||||
<< " returned " << status << LL_ENDL;
|
||||
delete name;
|
||||
|
||||
gViewerWindow->getWindow()->decBusyCount();
|
||||
|
||||
if (0 == status)
|
||||
{
|
||||
LLNotificationsUtil::add("UploadWebSnapshotDone");
|
||||
}
|
||||
else
|
||||
{
|
||||
LLSD args;
|
||||
args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
|
||||
LLNotificationsUtil::add("UploadAuctionSnapshotFail", args);
|
||||
}
|
||||
}
|
||||
|
||||
void auction_j2c_upload_done(const LLUUID& asset_id, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
|
||||
{
|
||||
std::string* name = (std::string*)(user_data);
|
||||
LL_INFOS() << "Upload of asset '" << *name << "' " << asset_id
|
||||
<< " returned " << status << LL_ENDL;
|
||||
delete name;
|
||||
|
||||
gViewerWindow->getWindow()->decBusyCount();
|
||||
|
||||
if (0 == status)
|
||||
{
|
||||
LLNotificationsUtil::add("UploadSnapshotDone");
|
||||
}
|
||||
else
|
||||
{
|
||||
LLSD args;
|
||||
args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
|
||||
LLNotificationsUtil::add("UploadAuctionSnapshotFail", args);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/**
|
||||
* @file llfloaterauction.h
|
||||
* @author James Cook, Ian Wilkes
|
||||
* @brief llfloaterauction class header file
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLFLOATERAUCTION_H
|
||||
#define LL_LLFLOATERAUCTION_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "lluuid.h"
|
||||
#include "llpointer.h"
|
||||
#include "llviewertexture.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLFloaterAuction
|
||||
//
|
||||
// Class which holds the functionality to start auctions.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLParcelSelection;
|
||||
class LLParcel;
|
||||
class LLViewerRegion;
|
||||
|
||||
class LLFloaterAuction : public LLFloater
|
||||
{
|
||||
friend class LLFloaterReg;
|
||||
public:
|
||||
// LLFloater interface
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
/*virtual*/ void draw();
|
||||
|
||||
private:
|
||||
|
||||
LLFloaterAuction(const LLSD& key);
|
||||
~LLFloaterAuction();
|
||||
|
||||
void initialize();
|
||||
|
||||
static void onClickSnapshot(void* data);
|
||||
static void onClickResetParcel(void* data);
|
||||
static void onClickSellToAnyone(void* data); // Sell to anyone clicked
|
||||
bool onSellToAnyoneConfirmed(const LLSD& notification, const LLSD& response); // Sell confirmation clicked
|
||||
static void onClickStartAuction(void* data);
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
|
||||
void doResetParcel();
|
||||
void doSellToAnyone();
|
||||
void clearParcelAccessList( LLParcel* parcel, LLViewerRegion* region, U32 list);
|
||||
void cleanupAndClose();
|
||||
|
||||
private:
|
||||
|
||||
LLTransactionID mTransactionID;
|
||||
LLAssetID mImageID;
|
||||
LLPointer<LLViewerTexture> mImage;
|
||||
LLSafeHandle<LLParcelSelection> mParcelp;
|
||||
S32 mParcelID;
|
||||
LLHost mParcelHost;
|
||||
|
||||
std::string mParcelUpdateCapUrl; // "ParcelPropertiesUpdate" capability
|
||||
};
|
||||
|
||||
|
||||
#endif // LL_LLFLOATERAUCTION_H
|
||||
|
|
@ -45,6 +45,7 @@
|
|||
#include "llcombobox.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfloateravatarpicker.h"
|
||||
#include "llfloaterauction.h"
|
||||
#include "llfloatergroups.h"
|
||||
#include "llfloaterscriptlimits.h"
|
||||
#include "llavataractions.h"
|
||||
|
|
@ -78,7 +79,6 @@
|
|||
#include "llpanelexperiencelisteditor.h"
|
||||
#include "llpanelexperiencepicker.h"
|
||||
#include "llexperiencecache.h"
|
||||
#include "llweb.h"
|
||||
|
||||
#include "llgroupactions.h"
|
||||
|
||||
|
|
@ -542,6 +542,7 @@ void LLPanelLandGeneral::refresh()
|
|||
|
||||
mBtnDeedToGroup->setEnabled(FALSE);
|
||||
mBtnSetGroup->setEnabled(FALSE);
|
||||
mBtnStartAuction->setEnabled(FALSE);
|
||||
|
||||
mCheckDeedToGroup ->set(FALSE);
|
||||
mCheckDeedToGroup ->setEnabled(FALSE);
|
||||
|
|
@ -639,6 +640,7 @@ void LLPanelLandGeneral::refresh()
|
|||
mTextClaimDate->setEnabled(FALSE);
|
||||
mTextGroup->setText(getString("none_text"));
|
||||
mTextGroup->setEnabled(FALSE);
|
||||
mBtnStartAuction->setEnabled(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -690,6 +692,11 @@ void LLPanelLandGeneral::refresh()
|
|||
LLStringUtil::format (claim_date_str, substitution);
|
||||
mTextClaimDate->setText(claim_date_str);
|
||||
mTextClaimDate->setEnabled(is_leased);
|
||||
|
||||
BOOL enable_auction = (gAgent.getGodLevel() >= GOD_LIAISON)
|
||||
&& (owner_id == GOVERNOR_LINDEN_ID)
|
||||
&& (parcel->getAuctionID() == 0);
|
||||
mBtnStartAuction->setEnabled(enable_auction);
|
||||
}
|
||||
|
||||
// Display options
|
||||
|
|
@ -1017,8 +1024,20 @@ void LLPanelLandGeneral::onClickBuyPass(void* data)
|
|||
// static
|
||||
void LLPanelLandGeneral::onClickStartAuction(void* data)
|
||||
{
|
||||
std::string auction_url = "https://places.[GRID]/auctions/";
|
||||
LLWeb::loadURLExternal(LLWeb::expandURLSubstitutions(auction_url, LLSD()));
|
||||
LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)data;
|
||||
LLParcel* parcelp = panelp->mParcel->getParcel();
|
||||
if(parcelp)
|
||||
{
|
||||
if(parcelp->getForSale())
|
||||
{
|
||||
LLNotificationsUtil::add("CannotStartAuctionAlreadyForSale");
|
||||
}
|
||||
else
|
||||
{
|
||||
//LLFloaterAuction::showInstance();
|
||||
LLFloaterReg::showInstance("auction");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
|||
|
|
@ -1096,16 +1096,15 @@ void LLFloaterPreference::onClickSetCache()
|
|||
|
||||
std::string proposed_name(cur_name);
|
||||
|
||||
LLDirPicker& picker = LLDirPicker::instance();
|
||||
if (! picker.getDir(&proposed_name ) )
|
||||
{
|
||||
return; //Canceled!
|
||||
}
|
||||
(new LLDirPickerThread(boost::bind(&LLFloaterPreference::changeCachePath, this, _1, _2), proposed_name))->getFile();
|
||||
}
|
||||
|
||||
std::string dir_name = picker.getDirName();
|
||||
if (!dir_name.empty() && dir_name != cur_name)
|
||||
void LLFloaterPreference::changeCachePath(const std::vector<std::string>& filenames, std::string proposed_name)
|
||||
{
|
||||
std::string dir_name = filenames[0];
|
||||
if (!dir_name.empty() && dir_name != proposed_name)
|
||||
{
|
||||
std::string new_top_folder(gDirUtilp->getBaseFileName(dir_name));
|
||||
std::string new_top_folder(gDirUtilp->getBaseFileName(dir_name));
|
||||
LLNotificationsUtil::add("CacheWillBeMoved");
|
||||
gSavedSettings.setString("NewCacheLocation", dir_name);
|
||||
gSavedSettings.setString("NewCacheLocationTopFolder", new_top_folder);
|
||||
|
|
@ -1744,25 +1743,21 @@ void LLFloaterPreference::onClickLogPath()
|
|||
std::string proposed_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
|
||||
mPriorInstantMessageLogPath.clear();
|
||||
|
||||
LLDirPicker& picker = LLDirPicker::instance();
|
||||
//Launches a directory picker and waits for feedback
|
||||
if (!picker.getDir(&proposed_name ) )
|
||||
{
|
||||
return; //Canceled!
|
||||
}
|
||||
|
||||
//Gets the path from the directory picker
|
||||
std::string dir_name = picker.getDirName();
|
||||
|
||||
//Path changed
|
||||
if(proposed_name != dir_name)
|
||||
{
|
||||
gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name);
|
||||
mPriorInstantMessageLogPath = proposed_name;
|
||||
|
||||
// enable/disable 'Delete transcripts button
|
||||
updateDeleteTranscriptsButton();
|
||||
(new LLDirPickerThread(boost::bind(&LLFloaterPreference::changeLogPath, this, _1, _2), proposed_name))->getFile();
|
||||
}
|
||||
|
||||
void LLFloaterPreference::changeLogPath(const std::vector<std::string>& filenames, std::string proposed_name)
|
||||
{
|
||||
//Path changed
|
||||
if (proposed_name != filenames[0])
|
||||
{
|
||||
gSavedPerAccountSettings.setString("InstantMessageLogPath", filenames[0]);
|
||||
mPriorInstantMessageLogPath = proposed_name;
|
||||
|
||||
// enable/disable 'Delete transcripts button
|
||||
updateDeleteTranscriptsButton();
|
||||
}
|
||||
}
|
||||
|
||||
bool LLFloaterPreference::moveTranscriptsAndLog()
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ public:
|
|||
void setCacheLocation(const LLStringExplicit& location);
|
||||
|
||||
void onClickSetCache();
|
||||
void changeCachePath(const std::vector<std::string>& filenames, std::string proposed_name);
|
||||
void onClickResetCache();
|
||||
void onClickSkin(LLUICtrl* ctrl,const LLSD& userdata);
|
||||
void onSelectSkin();
|
||||
|
|
@ -145,6 +146,7 @@ public:
|
|||
void resetAllIgnored();
|
||||
void setAllIgnored();
|
||||
void onClickLogPath();
|
||||
void changeLogPath(const std::vector<std::string>& filenames, std::string proposed_name);
|
||||
bool moveTranscriptsAndLog();
|
||||
void enableHistory();
|
||||
void setPersonalInfo(const std::string& visibility, bool im_via_email, bool is_verified_email);
|
||||
|
|
|
|||
|
|
@ -1309,17 +1309,15 @@ void LLFloaterSnapshot::saveTexture()
|
|||
previewp->saveTexture();
|
||||
}
|
||||
|
||||
BOOL LLFloaterSnapshot::saveLocal()
|
||||
void LLFloaterSnapshot::saveLocal(const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb)
|
||||
{
|
||||
LL_DEBUGS() << "saveLocal" << LL_ENDL;
|
||||
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||
if (!previewp)
|
||||
llassert(previewp != NULL);
|
||||
if (previewp)
|
||||
{
|
||||
llassert(previewp != NULL);
|
||||
return FALSE;
|
||||
previewp->saveLocal(success_cb, failure_cb);
|
||||
}
|
||||
|
||||
return previewp->saveLocal();
|
||||
}
|
||||
|
||||
void LLFloaterSnapshotBase::postSave()
|
||||
|
|
|
|||
|
|
@ -156,7 +156,9 @@ public:
|
|||
static LLFloaterSnapshot* getInstance();
|
||||
static LLFloaterSnapshot* findInstance();
|
||||
/*virtual*/ void saveTexture();
|
||||
BOOL saveLocal();
|
||||
|
||||
typedef boost::signals2::signal<void(void)> snapshot_saved_signal_t;
|
||||
void saveLocal(const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb);
|
||||
static void setAgentEmail(const std::string& email);
|
||||
|
||||
BOOL isWaitingState();
|
||||
|
|
|
|||
|
|
@ -966,15 +966,6 @@ private:
|
|||
//-----------------------------------------------------------------------------
|
||||
F32 gpu_benchmark()
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
if (gGLManager.mIsIntel
|
||||
&& std::string::npos != LLOSInfo::instance().getOSStringSimple().find("Microsoft Windows 8")) // or 8.1
|
||||
{ // don't run benchmark on Windows 8/8.1 based PCs with Intel GPU (MAINT-8197)
|
||||
LL_WARNS() << "Skipping gpu_benchmark() for Intel graphics on Windows 8." << LL_ENDL;
|
||||
return -1.f;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!gGLManager.mHasShaderObjects || !gGLManager.mHasTimerQuery)
|
||||
{ // don't bother benchmarking the fixed function
|
||||
// or venerable drivers which don't support accurate timing anyway
|
||||
|
|
|
|||
|
|
@ -1166,72 +1166,72 @@ void LLOutfitGallery::refreshTextures(const LLUUID& category_id)
|
|||
|
||||
void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
|
||||
{
|
||||
outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id);
|
||||
if (outfit_it == mOutfitMap.end() || outfit_it->first.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id);
|
||||
if (outfit_it == mOutfitMap.end() || outfit_it->first.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
(new LLFilePickerReplyThread(boost::bind(&LLOutfitGallery::uploadOutfitImage, this, _1, outfit_id), LLFilePicker::FFLOAD_IMAGE, false))->getFile();
|
||||
}
|
||||
|
||||
LLFilePicker& picker = LLFilePicker::instance();
|
||||
if (picker.getOpenFile(LLFilePicker::FFLOAD_IMAGE))
|
||||
void LLOutfitGallery::uploadOutfitImage(const std::vector<std::string>& filenames, LLUUID outfit_id)
|
||||
{
|
||||
std::string filename = filenames[0];
|
||||
LLLocalBitmap* unit = new LLLocalBitmap(filename);
|
||||
if (unit->getValid())
|
||||
{
|
||||
std::string filename = picker.getFirstFile();
|
||||
LLLocalBitmap* unit = new LLLocalBitmap(filename);
|
||||
if (unit->getValid())
|
||||
std::string exten = gDirUtilp->getExtension(filename);
|
||||
U32 codec = LLImageBase::getCodecFromExtension(exten);
|
||||
|
||||
LLImageDimensionsInfo image_info;
|
||||
std::string image_load_error;
|
||||
if (!image_info.load(filename, codec))
|
||||
{
|
||||
std::string exten = gDirUtilp->getExtension(filename);
|
||||
U32 codec = LLImageBase::getCodecFromExtension(exten);
|
||||
|
||||
LLImageDimensionsInfo image_info;
|
||||
std::string image_load_error;
|
||||
if (!image_info.load(filename, codec))
|
||||
{
|
||||
image_load_error = image_info.getLastError();
|
||||
}
|
||||
|
||||
S32 max_width = MAX_OUTFIT_PHOTO_WIDTH;
|
||||
S32 max_height = MAX_OUTFIT_PHOTO_HEIGHT;
|
||||
|
||||
if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height))
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["WIDTH"] = llformat("%d", max_width);
|
||||
args["HEIGHT"] = llformat("%d", max_height);
|
||||
|
||||
image_load_error = LLTrans::getString("outfit_photo_load_dimensions_error", args);
|
||||
}
|
||||
|
||||
if (!image_load_error.empty())
|
||||
{
|
||||
LLSD subst;
|
||||
subst["REASON"] = image_load_error;
|
||||
LLNotificationsUtil::add("OutfitPhotoLoadError", subst);
|
||||
return;
|
||||
}
|
||||
|
||||
S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass).
|
||||
void *nruserdata = NULL;
|
||||
nruserdata = (void *)&outfit_id;
|
||||
|
||||
LLViewerInventoryCategory *outfit_cat = gInventory.getCategory(outfit_id);
|
||||
if (!outfit_cat) return;
|
||||
updateSnapshotFolderObserver();
|
||||
checkRemovePhoto(outfit_id);
|
||||
std::string upload_pending_name = outfit_id.asString();
|
||||
std::string upload_pending_desc = "";
|
||||
LLAssetStorage::LLStoreAssetCallback callback = NULL;
|
||||
LLUUID photo_id = upload_new_resource(filename, // file
|
||||
upload_pending_name,
|
||||
upload_pending_desc,
|
||||
0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
|
||||
LLFloaterPerms::getNextOwnerPerms("Uploads"),
|
||||
LLFloaterPerms::getGroupPerms("Uploads"),
|
||||
LLFloaterPerms::getEveryonePerms("Uploads"),
|
||||
upload_pending_name, callback, expected_upload_cost, nruserdata);
|
||||
mOutfitLinkPending = outfit_id;
|
||||
image_load_error = image_info.getLastError();
|
||||
}
|
||||
delete unit;
|
||||
|
||||
S32 max_width = MAX_OUTFIT_PHOTO_WIDTH;
|
||||
S32 max_height = MAX_OUTFIT_PHOTO_HEIGHT;
|
||||
|
||||
if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height))
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["WIDTH"] = llformat("%d", max_width);
|
||||
args["HEIGHT"] = llformat("%d", max_height);
|
||||
|
||||
image_load_error = LLTrans::getString("outfit_photo_load_dimensions_error", args);
|
||||
}
|
||||
|
||||
if (!image_load_error.empty())
|
||||
{
|
||||
LLSD subst;
|
||||
subst["REASON"] = image_load_error;
|
||||
LLNotificationsUtil::add("OutfitPhotoLoadError", subst);
|
||||
return;
|
||||
}
|
||||
|
||||
S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass).
|
||||
void *nruserdata = NULL;
|
||||
nruserdata = (void *)&outfit_id;
|
||||
|
||||
LLViewerInventoryCategory *outfit_cat = gInventory.getCategory(outfit_id);
|
||||
if (!outfit_cat) return;
|
||||
updateSnapshotFolderObserver();
|
||||
checkRemovePhoto(outfit_id);
|
||||
std::string upload_pending_name = outfit_id.asString();
|
||||
std::string upload_pending_desc = "";
|
||||
LLAssetStorage::LLStoreAssetCallback callback = NULL;
|
||||
LLUUID photo_id = upload_new_resource(filename, // file
|
||||
upload_pending_name,
|
||||
upload_pending_desc,
|
||||
0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
|
||||
LLFloaterPerms::getNextOwnerPerms("Uploads"),
|
||||
LLFloaterPerms::getGroupPerms("Uploads"),
|
||||
LLFloaterPerms::getEveryonePerms("Uploads"),
|
||||
upload_pending_name, callback, expected_upload_cost, nruserdata);
|
||||
mOutfitLinkPending = outfit_id;
|
||||
}
|
||||
delete unit;
|
||||
}
|
||||
|
||||
void LLOutfitGallery::linkPhotoToOutfit(LLUUID photo_id, LLUUID outfit_id)
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ protected:
|
|||
private:
|
||||
void loadPhotos();
|
||||
void uploadPhoto(LLUUID outfit_id);
|
||||
void uploadOutfitImage(const std::vector<std::string>& filenames, LLUUID outfit_id);
|
||||
void updateSnapshotFolderObserver();
|
||||
LLUUID getPhotoAssetId(const LLUUID& outfit_id);
|
||||
LLUUID getDefaultPhoto();
|
||||
|
|
|
|||
|
|
@ -204,6 +204,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
|
|||
|
||||
// change z sort of clickable text to be behind buttons
|
||||
sendChildToBack(getChildView("forgot_password_text"));
|
||||
sendChildToBack(getChildView("sign_up_text"));
|
||||
|
||||
LLComboBox* favorites_combo = getChild<LLComboBox>("start_location_combo");
|
||||
updateLocationSelectorsVisibility(); // separate so that it can be called from preferences
|
||||
|
|
@ -271,6 +272,9 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
|
|||
LLTextBox* forgot_password_text = getChild<LLTextBox>("forgot_password_text");
|
||||
forgot_password_text->setClickedCallback(onClickForgotPassword, NULL);
|
||||
|
||||
LLTextBox* sign_up_text = getChild<LLTextBox>("sign_up_text");
|
||||
sign_up_text->setClickedCallback(onClickSignUp, NULL);
|
||||
|
||||
// get the web browser control
|
||||
LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html");
|
||||
web_browser->addObserver(this);
|
||||
|
|
@ -921,6 +925,15 @@ void LLPanelLogin::onClickForgotPassword(void*)
|
|||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLPanelLogin::onClickSignUp(void*)
|
||||
{
|
||||
if (sInstance)
|
||||
{
|
||||
LLWeb::loadURLExternal(sInstance->getString("sign_up_url"));
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ private:
|
|||
static void onClickNewAccount(void*);
|
||||
static void onClickVersion(void*);
|
||||
static void onClickForgotPassword(void*);
|
||||
static void onClickSignUp(void*);
|
||||
static void onPassKey(LLLineEditor* caller, void* user_data);
|
||||
static void updateServerCombo();
|
||||
|
||||
|
|
|
|||
|
|
@ -1168,12 +1168,12 @@ void LLPanelNearByMedia::onClickSelectedMediaMute()
|
|||
F32 volume = impl->getVolume();
|
||||
if(volume > 0.0)
|
||||
{
|
||||
impl->setVolume(0.0);
|
||||
impl->setMute(true);
|
||||
}
|
||||
else if (mVolumeSlider->getValueF32() == 0.0)
|
||||
{
|
||||
impl->setVolume(1.0);
|
||||
mVolumeSlider->setValue(1.0);
|
||||
impl->setMute(false);
|
||||
mVolumeSlider->setValue(impl->getVolume());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -100,6 +100,10 @@ U8 string_value_to_click_action(std::string p_value)
|
|||
{
|
||||
return CLICK_ACTION_ZOOM;
|
||||
}
|
||||
if (p_value == "None")
|
||||
{
|
||||
return CLICK_ACTION_DISABLED;
|
||||
}
|
||||
return CLICK_ACTION_TOUCH;
|
||||
}
|
||||
|
||||
|
|
@ -126,6 +130,9 @@ std::string click_action_to_string_value( U8 action)
|
|||
case CLICK_ACTION_ZOOM:
|
||||
return "Zoom";
|
||||
break;
|
||||
case CLICK_ACTION_DISABLED:
|
||||
return "None";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1203,23 +1210,34 @@ void LLPanelPermissions::setAllSaleInfo()
|
|||
LLSaleInfo new_sale_info(sale_type, price);
|
||||
LLSelectMgr::getInstance()->selectionSetObjectSaleInfo(new_sale_info);
|
||||
|
||||
struct f : public LLSelectedObjectFunctor
|
||||
// Note: won't work right if a root and non-root are both single-selected (here and other places).
|
||||
BOOL is_perm_modify = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
|
||||
&& LLSelectMgr::getInstance()->selectGetRootsModify())
|
||||
|| LLSelectMgr::getInstance()->selectGetModify();
|
||||
BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
|
||||
&& LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced())
|
||||
|| LLSelectMgr::getInstance()->selectGetNonPermanentEnforced();
|
||||
|
||||
if (is_perm_modify && is_nonpermanent_enforced)
|
||||
{
|
||||
virtual bool apply(LLViewerObject* object)
|
||||
struct f : public LLSelectedObjectFunctor
|
||||
{
|
||||
return object->getClickAction() == CLICK_ACTION_BUY
|
||||
|| object->getClickAction() == CLICK_ACTION_TOUCH;
|
||||
virtual bool apply(LLViewerObject* object)
|
||||
{
|
||||
return object->getClickAction() == CLICK_ACTION_BUY
|
||||
|| object->getClickAction() == CLICK_ACTION_TOUCH;
|
||||
}
|
||||
} check_actions;
|
||||
|
||||
// Selection should only contain objects that are of target
|
||||
// action already or of action we are aiming to remove.
|
||||
bool default_actions = LLSelectMgr::getInstance()->getSelection()->applyToObjects(&check_actions);
|
||||
|
||||
if (default_actions && old_sale_info.isForSale() != new_sale_info.isForSale())
|
||||
{
|
||||
U8 new_click_action = new_sale_info.isForSale() ? CLICK_ACTION_BUY : CLICK_ACTION_TOUCH;
|
||||
LLSelectMgr::getInstance()->selectionSetClickAction(new_click_action);
|
||||
}
|
||||
} check_actions;
|
||||
|
||||
// Selection should only contain objects that are of target
|
||||
// action already or of action we are aiming to remove.
|
||||
bool default_actions = LLSelectMgr::getInstance()->getSelection()->applyToObjects(&check_actions);
|
||||
|
||||
if (default_actions && old_sale_info.isForSale() != new_sale_info.isForSale())
|
||||
{
|
||||
U8 new_click_action = new_sale_info.isForSale() ? CLICK_ACTION_BUY : CLICK_ACTION_TOUCH;
|
||||
LLSelectMgr::getInstance()->selectionSetClickAction(new_click_action);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,6 +65,9 @@ private:
|
|||
void onFormatComboCommit(LLUICtrl* ctrl);
|
||||
void onQualitySliderCommit(LLUICtrl* ctrl);
|
||||
void onSaveFlyoutCommit(LLUICtrl* ctrl);
|
||||
|
||||
void onLocalSaved();
|
||||
void onLocalCanceled();
|
||||
};
|
||||
|
||||
static LLPanelInjector<LLPanelSnapshotLocal> panel_class("llpanelsnapshotlocal");
|
||||
|
|
@ -164,19 +167,22 @@ void LLPanelSnapshotLocal::onSaveFlyoutCommit(LLUICtrl* ctrl)
|
|||
LLFloaterSnapshot* floater = LLFloaterSnapshot::getInstance();
|
||||
|
||||
floater->notify(LLSD().with("set-working", true));
|
||||
BOOL saved = floater->saveLocal();
|
||||
if (saved)
|
||||
{
|
||||
mSnapshotFloater->postSave();
|
||||
floater->notify(LLSD().with("set-finished", LLSD().with("ok", true).with("msg", "local")));
|
||||
}
|
||||
else
|
||||
{
|
||||
cancel();
|
||||
floater->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "local")));
|
||||
}
|
||||
floater->saveLocal((boost::bind(&LLPanelSnapshotLocal::onLocalSaved, this)), (boost::bind(&LLPanelSnapshotLocal::onLocalCanceled, this)));
|
||||
}
|
||||
|
||||
void LLPanelSnapshotLocal::onLocalSaved()
|
||||
{
|
||||
mSnapshotFloater->postSave();
|
||||
LLFloaterSnapshot::getInstance()->notify(LLSD().with("set-finished", LLSD().with("ok", true).with("msg", "local")));
|
||||
}
|
||||
|
||||
void LLPanelSnapshotLocal::onLocalCanceled()
|
||||
{
|
||||
cancel();
|
||||
LLFloaterSnapshot::getInstance()->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "local")));
|
||||
}
|
||||
|
||||
|
||||
LLSnapshotModel::ESnapshotType LLPanelSnapshotLocal::getSnapshotType()
|
||||
{
|
||||
return LLSnapshotModel::SNAPSHOT_LOCAL;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@
|
|||
// Library includes (after viewer)
|
||||
#include "lluictrlfactory.h"
|
||||
|
||||
|
||||
static LLPanelInjector<LLPanelVoiceDeviceSettings> t_panel_group_general("panel_voice_device_settings");
|
||||
static const std::string DEFAULT_DEVICE("Default");
|
||||
|
||||
|
|
@ -233,18 +232,18 @@ void LLPanelVoiceDeviceSettings::refresh()
|
|||
}
|
||||
else if (LLVoiceClient::getInstance()->deviceSettingsUpdated())
|
||||
{
|
||||
LLVoiceDeviceList::const_iterator iter;
|
||||
LLVoiceDeviceList::const_iterator device;
|
||||
|
||||
if(mCtrlInputDevices)
|
||||
{
|
||||
mCtrlInputDevices->removeall();
|
||||
mCtrlInputDevices->add(getLocalizedDeviceName(DEFAULT_DEVICE), DEFAULT_DEVICE, ADD_BOTTOM);
|
||||
|
||||
for(iter=LLVoiceClient::getInstance()->getCaptureDevices().begin();
|
||||
iter != LLVoiceClient::getInstance()->getCaptureDevices().end();
|
||||
iter++)
|
||||
for(device=LLVoiceClient::getInstance()->getCaptureDevices().begin();
|
||||
device != LLVoiceClient::getInstance()->getCaptureDevices().end();
|
||||
device++)
|
||||
{
|
||||
mCtrlInputDevices->add(getLocalizedDeviceName(*iter), *iter, ADD_BOTTOM);
|
||||
mCtrlInputDevices->add(getLocalizedDeviceName(device->display_name), device->full_name, ADD_BOTTOM);
|
||||
}
|
||||
|
||||
// Fix invalid input audio device preference.
|
||||
|
|
@ -261,10 +260,11 @@ void LLPanelVoiceDeviceSettings::refresh()
|
|||
mCtrlOutputDevices->removeall();
|
||||
mCtrlOutputDevices->add(getLocalizedDeviceName(DEFAULT_DEVICE), DEFAULT_DEVICE, ADD_BOTTOM);
|
||||
|
||||
for(iter= LLVoiceClient::getInstance()->getRenderDevices().begin();
|
||||
iter != LLVoiceClient::getInstance()->getRenderDevices().end(); iter++)
|
||||
for(device = LLVoiceClient::getInstance()->getRenderDevices().begin();
|
||||
device != LLVoiceClient::getInstance()->getRenderDevices().end();
|
||||
device++)
|
||||
{
|
||||
mCtrlOutputDevices->add(getLocalizedDeviceName(*iter), *iter, ADD_BOTTOM);
|
||||
mCtrlOutputDevices->add(getLocalizedDeviceName(device->display_name), device->full_name, ADD_BOTTOM);
|
||||
}
|
||||
|
||||
// Fix invalid output audio device preference.
|
||||
|
|
|
|||
|
|
@ -1741,14 +1741,22 @@ void LLPreviewLSL::onLoadComplete( LLVFS *vfs, const LLUUID& asset_uuid, LLAsset
|
|||
buffer[file_length] = 0;
|
||||
preview->mScriptEd->setScriptText(LLStringExplicit(&buffer[0]), TRUE);
|
||||
preview->mScriptEd->mEditor->makePristine();
|
||||
|
||||
std::string script_name = DEFAULT_SCRIPT_NAME;
|
||||
LLInventoryItem* item = gInventory.getItem(*item_uuid);
|
||||
BOOL is_modifiable = FALSE;
|
||||
if(item
|
||||
&& gAgent.allowOperation(PERM_MODIFY, item->getPermissions(),
|
||||
GP_OBJECT_MANIPULATE))
|
||||
if (item)
|
||||
{
|
||||
is_modifiable = TRUE;
|
||||
if (!item->getName().empty())
|
||||
{
|
||||
script_name = item->getName();
|
||||
}
|
||||
if (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE))
|
||||
{
|
||||
is_modifiable = TRUE;
|
||||
}
|
||||
}
|
||||
preview->mScriptEd->setScriptName(script_name);
|
||||
preview->mScriptEd->setEnableEditing(is_modifiable);
|
||||
preview->mAssetStatus = PREVIEW_ASSET_LOADED;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1130,6 +1130,8 @@ static U8 string_value_to_click_action(std::string p_value)
|
|||
return CLICK_ACTION_OPEN;
|
||||
if (p_value == "Zoom")
|
||||
return CLICK_ACTION_ZOOM;
|
||||
if (p_value == "None")
|
||||
return CLICK_ACTION_DISABLED;
|
||||
return CLICK_ACTION_TOUCH;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ S32 BORDER_WIDTH = 6;
|
|||
const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512
|
||||
|
||||
std::set<LLSnapshotLivePreview*> LLSnapshotLivePreview::sList;
|
||||
LLPointer<LLImageFormatted> LLSnapshotLivePreview::sSaveLocalImage = NULL;
|
||||
|
||||
LLSnapshotLivePreview::LLSnapshotLivePreview (const LLSnapshotLivePreview::Params& p)
|
||||
: LLView(p),
|
||||
|
|
@ -131,6 +132,7 @@ LLSnapshotLivePreview::~LLSnapshotLivePreview()
|
|||
|
||||
// gIdleCallbacks.deleteFunction( &LLSnapshotLivePreview::onIdle, (void*)this );
|
||||
sList.erase(this);
|
||||
sSaveLocalImage = NULL;
|
||||
}
|
||||
|
||||
void LLSnapshotLivePreview::setMaxImageSize(S32 size)
|
||||
|
|
@ -1065,53 +1067,19 @@ void LLSnapshotLivePreview::saveTexture(BOOL outfit_snapshot, std::string name)
|
|||
mDataSize = 0;
|
||||
}
|
||||
|
||||
BOOL LLSnapshotLivePreview::saveLocal()
|
||||
void LLSnapshotLivePreview::saveLocal(const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb)
|
||||
{
|
||||
// Update mFormattedImage if necessary
|
||||
getFormattedImage();
|
||||
|
||||
// Save the formatted image
|
||||
BOOL success = saveLocal(mFormattedImage);
|
||||
|
||||
if(success)
|
||||
{
|
||||
gViewerWindow->playSnapshotAnimAndSound();
|
||||
}
|
||||
return success;
|
||||
saveLocal(mFormattedImage, success_cb, failure_cb);
|
||||
}
|
||||
|
||||
//Check if failed due to insufficient memory
|
||||
BOOL LLSnapshotLivePreview::saveLocal(LLPointer<LLImageFormatted> mFormattedImage)
|
||||
void LLSnapshotLivePreview::saveLocal(LLPointer<LLImageFormatted> image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb)
|
||||
{
|
||||
BOOL insufficient_memory;
|
||||
BOOL success = gViewerWindow->saveImageNumbered(mFormattedImage, FALSE, insufficient_memory);
|
||||
sSaveLocalImage = image;
|
||||
|
||||
if (insufficient_memory)
|
||||
{
|
||||
std::string lastSnapshotDir = LLViewerWindow::getLastSnapshotDir();
|
||||
|
||||
#ifdef LL_WINDOWS
|
||||
boost::filesystem::path b_path(utf8str_to_utf16str(lastSnapshotDir));
|
||||
#else
|
||||
boost::filesystem::path b_path(lastSnapshotDir);
|
||||
#endif
|
||||
boost::filesystem::space_info b_space = boost::filesystem::space(b_path);
|
||||
if (b_space.free < mFormattedImage->getDataSize())
|
||||
{
|
||||
LLSD args;
|
||||
args["PATH"] = lastSnapshotDir;
|
||||
|
||||
std::string needM_bytes_string;
|
||||
LLResMgr::getInstance()->getIntegerString(needM_bytes_string, (mFormattedImage->getDataSize()) >> 10);
|
||||
args["NEED_MEMORY"] = needM_bytes_string;
|
||||
|
||||
std::string freeM_bytes_string;
|
||||
LLResMgr::getInstance()->getIntegerString(freeM_bytes_string, (b_space.free) >> 10);
|
||||
args["FREE_MEMORY"] = freeM_bytes_string;
|
||||
|
||||
LLNotificationsUtil::add("SnapshotToComputerFailed", args);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
gViewerWindow->saveImageNumbered(sSaveLocalImage, FALSE, success_cb, failure_cb);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,8 +40,9 @@ class LLSnapshotLivePreview : public LLView
|
|||
{
|
||||
LOG_CLASS(LLSnapshotLivePreview);
|
||||
public:
|
||||
typedef boost::signals2::signal<void(void)> snapshot_saved_signal_t;
|
||||
|
||||
static BOOL saveLocal(LLPointer<LLImageFormatted>);
|
||||
static void saveLocal(LLPointer<LLImageFormatted> image, const snapshot_saved_signal_t::slot_type& success_cb = snapshot_saved_signal_t(), const snapshot_saved_signal_t::slot_type& failure_cb = snapshot_saved_signal_t());
|
||||
struct Params : public LLInitParam::Block<Params, LLView::Params>
|
||||
{
|
||||
Params()
|
||||
|
|
@ -101,7 +102,7 @@ public:
|
|||
std::string getFilter() const { return mFilterName; }
|
||||
void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE, F32 delay = 0.f);
|
||||
void saveTexture(BOOL outfit_snapshot = FALSE, std::string name = "");
|
||||
BOOL saveLocal();
|
||||
void saveLocal(const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb);
|
||||
|
||||
LLPointer<LLImageFormatted> getFormattedImage();
|
||||
LLPointer<LLImageRaw> getEncodedImage();
|
||||
|
|
@ -170,7 +171,9 @@ private:
|
|||
LLQuaternion mCameraRot;
|
||||
BOOL mSnapshotActive;
|
||||
LLSnapshotModel::ESnapshotLayerType mSnapshotBufferType;
|
||||
std::string mFilterName;
|
||||
std::string mFilterName;
|
||||
|
||||
static LLPointer<LLImageFormatted> sSaveLocalImage;
|
||||
|
||||
public:
|
||||
static std::set<LLSnapshotLivePreview*> sList;
|
||||
|
|
|
|||
|
|
@ -615,7 +615,7 @@ bool LLTextureCacheRemoteWorker::doWrite()
|
|||
if(idx >= 0)
|
||||
{
|
||||
// write to the fast cache.
|
||||
if(!mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel))
|
||||
if(!mCache->writeToFastCache(mID, idx, mRawImage, mRawDiscardLevel))
|
||||
{
|
||||
LL_WARNS() << "writeToFastCache failed" << LL_ENDL;
|
||||
mDataSize = -1; // failed
|
||||
|
|
@ -1998,8 +1998,48 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
|
|||
return raw;
|
||||
}
|
||||
|
||||
#if LL_WINDOWS
|
||||
|
||||
static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
|
||||
|
||||
U32 exception_dupe_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
|
||||
{
|
||||
if (code == STATUS_MSC_EXCEPTION)
|
||||
{
|
||||
// C++ exception, go on
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
else
|
||||
{
|
||||
// handle it
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
}
|
||||
|
||||
//due to unwinding
|
||||
void dupe(LLPointer<LLImageRaw> &raw)
|
||||
{
|
||||
raw = raw->duplicate();
|
||||
}
|
||||
|
||||
void logExceptionDupplicate(LLPointer<LLImageRaw> &raw)
|
||||
{
|
||||
__try
|
||||
{
|
||||
dupe(raw);
|
||||
}
|
||||
__except (exception_dupe_filter(GetExceptionCode(), GetExceptionInformation()))
|
||||
{
|
||||
// convert to C++ styled exception
|
||||
char integer_string[32];
|
||||
sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode());
|
||||
throw std::exception(integer_string);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//return the fast cache location
|
||||
bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel)
|
||||
bool LLTextureCache::writeToFastCache(LLUUID image_id, S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel)
|
||||
{
|
||||
//rescale image if needed
|
||||
if (raw.isNull() || raw->isBufferInvalid() || !raw->getData())
|
||||
|
|
@ -2027,13 +2067,39 @@ bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 dis
|
|||
if(w * h *c > 0) //valid
|
||||
{
|
||||
//make a duplicate to keep the original raw image untouched.
|
||||
raw = raw->scaled(w, h);
|
||||
|
||||
try
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
// Temporary diagnostics for scale/duplicate crash
|
||||
logExceptionDupplicate(raw);
|
||||
#else
|
||||
raw = raw->duplicate();
|
||||
#endif
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
removeFromCache(image_id);
|
||||
LL_ERRS() << "Failed to cache image: " << image_id
|
||||
<< " local id: " << id
|
||||
<< " Exception: " << boost::current_exception_diagnostic_information()
|
||||
<< " Image new width: " << w
|
||||
<< " Image new height: " << h
|
||||
<< " Image new components: " << c
|
||||
<< " Image discard difference: " << i
|
||||
<< LL_ENDL;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (raw->isBufferInvalid())
|
||||
{
|
||||
LL_WARNS() << "Invalid image duplicate buffer" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
raw->scale(w, h);
|
||||
|
||||
discardlevel += i ;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ private:
|
|||
|
||||
void openFastCache(bool first_time = false);
|
||||
void closeFastCache(bool forced = false);
|
||||
bool writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel);
|
||||
bool writeToFastCache(LLUUID image_id, S32 cache_id, LLPointer<LLImageRaw> raw, S32 discardlevel);
|
||||
|
||||
private:
|
||||
// Internal
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary()
|
|||
addEntry(DAD_CLOTHING, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearItem, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
|
||||
addEntry(DAD_OBJECT, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dRezAttachmentFromInv, &LLToolDragAndDrop::dad3dGiveInventoryObject, &LLToolDragAndDrop::dad3dRezObjectOnObject, &LLToolDragAndDrop::dad3dRezObjectOnLand));
|
||||
addEntry(DAD_NOTECARD, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
|
||||
addEntry(DAD_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearCategory, &LLToolDragAndDrop::dad3dGiveInventoryCategory, &LLToolDragAndDrop::dad3dUpdateInventoryCategory, &LLToolDragAndDrop::dad3dNULL));
|
||||
addEntry(DAD_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearCategory, &LLToolDragAndDrop::dad3dGiveInventoryCategory, &LLToolDragAndDrop::dad3dRezCategoryOnObject, &LLToolDragAndDrop::dad3dNULL));
|
||||
addEntry(DAD_ROOT_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL));
|
||||
addEntry(DAD_BODYPART, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearItem, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
|
||||
addEntry(DAD_ANIMATION, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
|
||||
|
|
@ -2335,6 +2335,21 @@ EAcceptance LLToolDragAndDrop::dad3dUpdateInventoryCategory(
|
|||
return rv;
|
||||
}
|
||||
|
||||
|
||||
EAcceptance LLToolDragAndDrop::dad3dRezCategoryOnObject(
|
||||
LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
|
||||
{
|
||||
if ((mask & MASK_CONTROL))
|
||||
{
|
||||
return dad3dUpdateInventoryCategory(obj, face, mask, drop);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ACCEPT_NO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL LLToolDragAndDrop::dadUpdateInventoryCategory(LLViewerObject* obj,
|
||||
BOOL drop)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -162,6 +162,8 @@ protected:
|
|||
MASK mask, BOOL drop);
|
||||
EAcceptance dad3dRezObjectOnObject(LLViewerObject* obj, S32 face,
|
||||
MASK mask, BOOL drop);
|
||||
EAcceptance dad3dRezCategoryOnObject(LLViewerObject* obj, S32 face,
|
||||
MASK mask, BOOL drop);
|
||||
EAcceptance dad3dRezScript(LLViewerObject* obj, S32 face,
|
||||
MASK mask, BOOL drop);
|
||||
EAcceptance dad3dTextureObject(LLViewerObject* obj, S32 face,
|
||||
|
|
|
|||
|
|
@ -300,6 +300,8 @@ BOOL LLToolPie::handleLeftClickPick()
|
|||
}
|
||||
}
|
||||
return TRUE;
|
||||
case CLICK_ACTION_DISABLED:
|
||||
return TRUE;
|
||||
default:
|
||||
// nothing
|
||||
break;
|
||||
|
|
@ -463,6 +465,8 @@ ECursorType LLToolPie::cursorFromObject(LLViewerObject* object)
|
|||
case CLICK_ACTION_OPEN_MEDIA:
|
||||
cursor = cursor_from_parcel_media(click_action);
|
||||
break;
|
||||
case CLICK_ACTION_DISABLED:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -528,6 +532,8 @@ void LLToolPie::selectionPropertiesReceived()
|
|||
case CLICK_ACTION_OPEN:
|
||||
LLFloaterReg::showInstance("openobject");
|
||||
break;
|
||||
case CLICK_ACTION_DISABLED:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "llcompilequeue.h"
|
||||
#include "llfasttimerview.h"
|
||||
#include "llfloaterabout.h"
|
||||
#include "llfloaterauction.h"
|
||||
#include "llfloaterautoreplacesettings.h"
|
||||
#include "llfloateravatar.h"
|
||||
#include "llfloateravatarpicker.h"
|
||||
|
|
@ -193,6 +194,7 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
LLFloaterReg::add("about_land", "floater_about_land.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLand>);
|
||||
LLFloaterReg::add("appearance", "floater_my_appearance.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
|
||||
LLFloaterReg::add("associate_listing", "floater_associate_listing.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAssociateListing>);
|
||||
LLFloaterReg::add("auction", "floater_auction.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAuction>);
|
||||
LLFloaterReg::add("avatar", "floater_avatar.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatar>);
|
||||
LLFloaterReg::add("avatar_picker", "floater_avatar_picker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarPicker>);
|
||||
LLFloaterReg::add("avatar_render_settings", "floater_avatar_render_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarRenderSettings>);
|
||||
|
|
|
|||
|
|
@ -1555,6 +1555,7 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id,
|
|||
mNavigateServerRequest(false),
|
||||
mMediaSourceFailed(false),
|
||||
mRequestedVolume(1.0f),
|
||||
mPreviousVolume(1.0f),
|
||||
mIsMuted(false),
|
||||
mNeedsMuteCheck(false),
|
||||
mPreviousMediaState(MEDIA_NONE),
|
||||
|
|
@ -2081,6 +2082,20 @@ void LLViewerMediaImpl::setVolume(F32 volume)
|
|||
updateVolume();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void LLViewerMediaImpl::setMute(bool mute)
|
||||
{
|
||||
if (mute)
|
||||
{
|
||||
mPreviousVolume = mRequestedVolume;
|
||||
setVolume(0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
setVolume(mPreviousVolume);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void LLViewerMediaImpl::updateVolume()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -216,6 +216,7 @@ public:
|
|||
void skipBack(F32 step_scale);
|
||||
void skipForward(F32 step_scale);
|
||||
void setVolume(F32 volume);
|
||||
void setMute(bool mute);
|
||||
void updateVolume();
|
||||
F32 getVolume();
|
||||
void focus(bool focus);
|
||||
|
|
@ -448,6 +449,7 @@ private:
|
|||
bool mNavigateServerRequest;
|
||||
bool mMediaSourceFailed;
|
||||
F32 mRequestedVolume;
|
||||
F32 mPreviousVolume;
|
||||
bool mIsMuted;
|
||||
bool mNeedsMuteCheck;
|
||||
int mPreviousMediaState;
|
||||
|
|
|
|||
|
|
@ -3649,9 +3649,16 @@ class LLSelfSitDown : public view_listener_t
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool show_sitdown_self()
|
||||
{
|
||||
return isAgentAvatarValid() && !gAgentAvatarp->isSitting();
|
||||
}
|
||||
|
||||
bool enable_sitdown_self()
|
||||
{
|
||||
return isAgentAvatarValid() && !gAgentAvatarp->isSitting() && !gAgentAvatarp->isEditingAppearance() && !gAgent.getFlying();
|
||||
return show_sitdown_self() && !gAgentAvatarp->isEditingAppearance() && !gAgent.getFlying();
|
||||
}
|
||||
|
||||
class LLCheckPanelPeopleTab : public view_listener_t
|
||||
|
|
@ -9068,7 +9075,8 @@ void initialize_menus()
|
|||
view_listener_t::addMenu(new LLSelfStandUp(), "Self.StandUp");
|
||||
enable.add("Self.EnableStandUp", boost::bind(&enable_standup_self));
|
||||
view_listener_t::addMenu(new LLSelfSitDown(), "Self.SitDown");
|
||||
enable.add("Self.EnableSitDown", boost::bind(&enable_sitdown_self));
|
||||
enable.add("Self.EnableSitDown", boost::bind(&enable_sitdown_self));
|
||||
enable.add("Self.ShowSitDown", boost::bind(&show_sitdown_self));
|
||||
view_listener_t::addMenu(new LLSelfRemoveAllAttachments(), "Self.RemoveAllAttachments");
|
||||
|
||||
view_listener_t::addMenu(new LLSelfEnableRemoveAllAttachments(), "Self.EnableRemoveAllAttachments");
|
||||
|
|
|
|||
|
|
@ -203,38 +203,55 @@ void LLFilePickerThread::clearDead()
|
|||
}
|
||||
}
|
||||
|
||||
LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple)
|
||||
LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type& failure_cb)
|
||||
: LLFilePickerThread(filter, get_multiple),
|
||||
mLoadFilter(filter),
|
||||
mSaveFilter(LLFilePicker::FFSAVE_ALL),
|
||||
mFilePickedSignal(NULL)
|
||||
mFilePickedSignal(NULL),
|
||||
mFailureSignal(NULL)
|
||||
{
|
||||
mFilePickedSignal = new file_picked_signal_t();
|
||||
mFilePickedSignal->connect(cb);
|
||||
|
||||
mFailureSignal = new file_picked_signal_t();
|
||||
mFailureSignal->connect(failure_cb);
|
||||
}
|
||||
|
||||
LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name)
|
||||
LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name, const file_picked_signal_t::slot_type& failure_cb)
|
||||
: LLFilePickerThread(filter, proposed_name),
|
||||
mLoadFilter(LLFilePicker::FFLOAD_ALL),
|
||||
mSaveFilter(filter),
|
||||
mFilePickedSignal(NULL)
|
||||
mFilePickedSignal(NULL),
|
||||
mFailureSignal(NULL)
|
||||
{
|
||||
mFilePickedSignal = new file_picked_signal_t();
|
||||
mFilePickedSignal->connect(cb);
|
||||
|
||||
mFailureSignal = new file_picked_signal_t();
|
||||
mFailureSignal->connect(failure_cb);
|
||||
}
|
||||
|
||||
LLFilePickerReplyThread::~LLFilePickerReplyThread()
|
||||
{
|
||||
delete mFilePickedSignal;
|
||||
delete mFailureSignal;
|
||||
}
|
||||
|
||||
void LLFilePickerReplyThread::notify(const std::vector<std::string>& filenames)
|
||||
{
|
||||
if (filenames.empty()) return;
|
||||
|
||||
if (mFilePickedSignal)
|
||||
if (filenames.empty())
|
||||
{
|
||||
(*mFilePickedSignal)(filenames, mLoadFilter, mSaveFilter);
|
||||
if (mFailureSignal)
|
||||
{
|
||||
(*mFailureSignal)(filenames, mLoadFilter, mSaveFilter);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mFilePickedSignal)
|
||||
{
|
||||
(*mFilePickedSignal)(filenames, mLoadFilter, mSaveFilter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -592,7 +609,6 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
|
|||
gSavedSettings.getBOOL("RenderUIInSnapshot"),
|
||||
FALSE))
|
||||
{
|
||||
gViewerWindow->playSnapshotAnimAndSound();
|
||||
LLPointer<LLImageFormatted> formatted;
|
||||
LLSnapshotModel::ESnapshotFormat fmt = (LLSnapshotModel::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat");
|
||||
switch (fmt)
|
||||
|
|
|
|||
|
|
@ -113,8 +113,8 @@ public:
|
|||
|
||||
typedef boost::signals2::signal<void(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter load_filter, LLFilePicker::ESaveFilter save_filter)> file_picked_signal_t;
|
||||
|
||||
LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple);
|
||||
LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name);
|
||||
LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
|
||||
LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
|
||||
~LLFilePickerReplyThread();
|
||||
|
||||
virtual void notify(const std::vector<std::string>& filenames);
|
||||
|
|
@ -123,6 +123,7 @@ private:
|
|||
LLFilePicker::ELoadFilter mLoadFilter;
|
||||
LLFilePicker::ESaveFilter mSaveFilter;
|
||||
file_picked_signal_t* mFilePickedSignal;
|
||||
file_picked_signal_t* mFailureSignal;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -153,6 +153,98 @@ const U8 AU_FLAGS_NONE = 0x00;
|
|||
const U8 AU_FLAGS_HIDETITLE = 0x01;
|
||||
const U8 AU_FLAGS_CLIENT_AUTOPILOT = 0x02;
|
||||
|
||||
void accept_friendship_coro(std::string url, LLSD notification)
|
||||
{
|
||||
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
|
||||
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
|
||||
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("friendshipResponceErrorProcessing", httpPolicy));
|
||||
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
|
||||
if (url.empty())
|
||||
{
|
||||
LL_WARNS("Friendship") << "Empty capability!" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
LLSD payload = notification["payload"];
|
||||
url += "?from=" + payload["from_id"].asString();
|
||||
url += "&agent_name=\"" + LLURI::escape(gAgentAvatarp->getFullname()) + "\"";
|
||||
|
||||
LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
|
||||
|
||||
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
|
||||
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
LL_WARNS("Friendship") << "HTTP status, " << status.toTerseString() <<
|
||||
". friendship offer accept failed." << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!result.has("success") || result["success"].asBoolean() == false)
|
||||
{
|
||||
LL_WARNS("Friendship") << "Server failed to process accepted friendship. " << httpResults << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("Friendship") << "Adding friend to list" << httpResults << LL_ENDL;
|
||||
// add friend to recent people list
|
||||
LLRecentPeople::instance().add(payload["from_id"]);
|
||||
|
||||
LLNotificationsUtil::add("FriendshipAcceptedByMe",
|
||||
notification["substitutions"], payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void decline_friendship_coro(std::string url, LLSD notification, S32 option)
|
||||
{
|
||||
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
|
||||
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
|
||||
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("friendshipResponceErrorProcessing", httpPolicy));
|
||||
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
|
||||
if (url.empty())
|
||||
{
|
||||
LL_WARNS("Friendship") << "Empty capability!" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
LLSD payload = notification["payload"];
|
||||
url += "?from=" + payload["from_id"].asString();
|
||||
|
||||
LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
|
||||
|
||||
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
|
||||
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
LL_WARNS("Friendship") << "HTTP status, " << status.toTerseString() <<
|
||||
". friendship offer decline failed." << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!result.has("success") || result["success"].asBoolean() == false)
|
||||
{
|
||||
LL_WARNS("Friendship") << "Server failed to process declined friendship. " << httpResults << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("Friendship") << "Friendship declined" << httpResults << LL_ENDL;
|
||||
if (option == 1)
|
||||
{
|
||||
LLNotificationsUtil::add("FriendshipDeclinedByMe",
|
||||
notification["substitutions"], payload);
|
||||
}
|
||||
else if (option == 2)
|
||||
{
|
||||
// start IM session
|
||||
LLAvatarActions::startIM(payload["from_id"].asUUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
|
|
@ -163,9 +255,6 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
|
|||
// this will be skipped if the user offering friendship is blocked
|
||||
if (notification_ptr)
|
||||
{
|
||||
// add friend to recent people list
|
||||
LLRecentPeople::instance().add(payload["from_id"]);
|
||||
|
||||
switch(option)
|
||||
{
|
||||
case 0:
|
||||
|
|
@ -176,46 +265,79 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
|
|||
const LLUUID fid = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
|
||||
|
||||
// This will also trigger an onlinenotification if the user is online
|
||||
msg->newMessageFast(_PREHASH_AcceptFriendship);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
msg->nextBlockFast(_PREHASH_TransactionBlock);
|
||||
msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
|
||||
msg->nextBlockFast(_PREHASH_FolderData);
|
||||
msg->addUUIDFast(_PREHASH_FolderID, fid);
|
||||
msg->sendReliable(LLHost(payload["sender"].asString()));
|
||||
std::string url = gAgent.getRegionCapability("AcceptFriendship");
|
||||
LL_DEBUGS("Friendship") << "Cap string: " << url << LL_ENDL;
|
||||
if (!url.empty() && payload.has("online") && payload["online"].asBoolean() == false)
|
||||
{
|
||||
LL_DEBUGS("Friendship") << "Accepting friendship via capability" << LL_ENDL;
|
||||
LLCoros::instance().launch("LLMessageSystem::acceptFriendshipOffer",
|
||||
boost::bind(accept_friendship_coro, url, notification));
|
||||
}
|
||||
else if (payload.has("session_id") && payload["session_id"].asUUID().notNull())
|
||||
{
|
||||
LL_DEBUGS("Friendship") << "Accepting friendship via viewer message" << LL_ENDL;
|
||||
msg->newMessageFast(_PREHASH_AcceptFriendship);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
msg->nextBlockFast(_PREHASH_TransactionBlock);
|
||||
msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
|
||||
msg->nextBlockFast(_PREHASH_FolderData);
|
||||
msg->addUUIDFast(_PREHASH_FolderID, fid);
|
||||
msg->sendReliable(LLHost(payload["sender"].asString()));
|
||||
|
||||
LLSD payload = notification["payload"];
|
||||
LLNotificationsUtil::add("FriendshipAcceptedByMe",
|
||||
notification["substitutions"], payload);
|
||||
// add friend to recent people list
|
||||
LLRecentPeople::instance().add(payload["from_id"]);
|
||||
LLNotificationsUtil::add("FriendshipAcceptedByMe",
|
||||
notification["substitutions"], payload);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Friendship") << "Failed to accept friendship offer, neither capability nor transaction id are accessible" << LL_ENDL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1: // Decline
|
||||
{
|
||||
LLSD payload = notification["payload"];
|
||||
LLNotificationsUtil::add("FriendshipDeclinedByMe",
|
||||
notification["substitutions"], payload);
|
||||
}
|
||||
// fall-through
|
||||
case 2: // Send IM - decline and start IM session
|
||||
{
|
||||
// decline
|
||||
// We no longer notify other viewers, but we DO still send
|
||||
// the rejection to the simulator to delete the pending userop.
|
||||
msg->newMessageFast(_PREHASH_DeclineFriendship);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
msg->nextBlockFast(_PREHASH_TransactionBlock);
|
||||
msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
|
||||
msg->sendReliable(LLHost(payload["sender"].asString()));
|
||||
// the rejection to the simulator to delete the pending userop.
|
||||
std::string url = gAgent.getRegionCapability("DeclineFriendship");
|
||||
LL_DEBUGS("Friendship") << "Cap string: " << url << LL_ENDL;
|
||||
if (!url.empty() && payload.has("online") && payload["online"].asBoolean() == false)
|
||||
{
|
||||
LL_DEBUGS("Friendship") << "Declining friendship via capability" << LL_ENDL;
|
||||
LLCoros::instance().launch("LLMessageSystem::declineFriendshipOffer",
|
||||
boost::bind(decline_friendship_coro, url, notification, option));
|
||||
}
|
||||
else if (payload.has("session_id") && payload["session_id"].asUUID().notNull())
|
||||
{
|
||||
LL_DEBUGS("Friendship") << "Declining friendship via viewer message" << LL_ENDL;
|
||||
msg->newMessageFast(_PREHASH_DeclineFriendship);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
msg->nextBlockFast(_PREHASH_TransactionBlock);
|
||||
msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
|
||||
msg->sendReliable(LLHost(payload["sender"].asString()));
|
||||
|
||||
// start IM session
|
||||
if(2 == option)
|
||||
{
|
||||
LLAvatarActions::startIM(payload["from_id"].asUUID());
|
||||
}
|
||||
if (option == 1) // due to fall-through
|
||||
{
|
||||
LLNotificationsUtil::add("FriendshipDeclinedByMe",
|
||||
notification["substitutions"], payload);
|
||||
}
|
||||
else if (option == 2)
|
||||
{
|
||||
// start IM session
|
||||
LLAvatarActions::startIM(payload["from_id"].asUUID());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Friendship") << "Failed to decline friendship offer, neither capability nor transaction id are accessible" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
default:
|
||||
// close button probably, possibly timed out
|
||||
|
|
@ -3258,6 +3380,110 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
|
|||
}
|
||||
|
||||
|
||||
// sounds can arrive before objects, store them for a short time
|
||||
// Note: this is a workaround for MAINT-4743, real fix would be to make
|
||||
// server send sound along with object update that creates (rezes) the object
|
||||
class PostponedSoundData
|
||||
{
|
||||
public:
|
||||
PostponedSoundData() :
|
||||
mExpirationTime(0)
|
||||
{}
|
||||
PostponedSoundData(const LLUUID &object_id, const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, const U8 flags);
|
||||
bool hasExpired() { return LLFrameTimer::getTotalSeconds() > mExpirationTime; }
|
||||
|
||||
LLUUID mObjectId;
|
||||
LLUUID mSoundId;
|
||||
LLUUID mOwnerId;
|
||||
F32 mGain;
|
||||
U8 mFlags;
|
||||
static const F64 MAXIMUM_PLAY_DELAY;
|
||||
|
||||
private:
|
||||
F64 mExpirationTime; //seconds since epoch
|
||||
};
|
||||
const F64 PostponedSoundData::MAXIMUM_PLAY_DELAY = 15.0;
|
||||
static F64 postponed_sounds_update_expiration = 0.0;
|
||||
static std::map<LLUUID, PostponedSoundData> postponed_sounds;
|
||||
|
||||
void set_attached_sound(LLViewerObject *objectp, const LLUUID &object_id, const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, const U8 flags)
|
||||
{
|
||||
if (LLMuteList::getInstance()->isMuted(object_id)) return;
|
||||
|
||||
if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return;
|
||||
|
||||
// Don't play sounds from a region with maturity above current agent maturity
|
||||
LLVector3d pos = objectp->getPositionGlobal();
|
||||
if (!gAgent.canAccessMaturityAtGlobal(pos))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
objectp->setAttachedSound(sound_id, owner_id, gain, flags);
|
||||
}
|
||||
|
||||
PostponedSoundData::PostponedSoundData(const LLUUID &object_id, const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, const U8 flags)
|
||||
:
|
||||
mObjectId(object_id),
|
||||
mSoundId(sound_id),
|
||||
mOwnerId(owner_id),
|
||||
mGain(gain),
|
||||
mFlags(flags),
|
||||
mExpirationTime(LLFrameTimer::getTotalSeconds() + MAXIMUM_PLAY_DELAY)
|
||||
{
|
||||
}
|
||||
|
||||
// static
|
||||
void update_attached_sounds()
|
||||
{
|
||||
if (postponed_sounds.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::map<LLUUID, PostponedSoundData>::iterator iter = postponed_sounds.begin();
|
||||
std::map<LLUUID, PostponedSoundData>::iterator end = postponed_sounds.end();
|
||||
while (iter != end)
|
||||
{
|
||||
std::map<LLUUID, PostponedSoundData>::iterator cur_iter = iter++;
|
||||
PostponedSoundData* data = &cur_iter->second;
|
||||
if (data->hasExpired())
|
||||
{
|
||||
postponed_sounds.erase(cur_iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLViewerObject *objectp = gObjectList.findObject(data->mObjectId);
|
||||
if (objectp)
|
||||
{
|
||||
set_attached_sound(objectp, data->mObjectId, data->mSoundId, data->mOwnerId, data->mGain, data->mFlags);
|
||||
postponed_sounds.erase(cur_iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
postponed_sounds_update_expiration = LLFrameTimer::getTotalSeconds() + 2 * PostponedSoundData::MAXIMUM_PLAY_DELAY;
|
||||
}
|
||||
|
||||
//static
|
||||
void clear_expired_postponed_sounds()
|
||||
{
|
||||
if (postponed_sounds_update_expiration > LLFrameTimer::getTotalSeconds())
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::map<LLUUID, PostponedSoundData>::iterator iter = postponed_sounds.begin();
|
||||
std::map<LLUUID, PostponedSoundData>::iterator end = postponed_sounds.end();
|
||||
while (iter != end)
|
||||
{
|
||||
std::map<LLUUID, PostponedSoundData>::iterator cur_iter = iter++;
|
||||
PostponedSoundData* data = &cur_iter->second;
|
||||
if (data->hasExpired())
|
||||
{
|
||||
postponed_sounds.erase(cur_iter);
|
||||
}
|
||||
}
|
||||
postponed_sounds_update_expiration = LLFrameTimer::getTotalSeconds() + 2 * PostponedSoundData::MAXIMUM_PLAY_DELAY;
|
||||
}
|
||||
|
||||
// *TODO: Remove this dependency, or figure out a better way to handle
|
||||
// this hack.
|
||||
|
|
@ -3276,7 +3502,12 @@ void process_object_update(LLMessageSystem *mesgsys, void **user_data)
|
|||
}
|
||||
|
||||
// Update the object...
|
||||
S32 old_num_objects = gObjectList.mNumNewObjects;
|
||||
gObjectList.processObjectUpdate(mesgsys, user_data, OUT_FULL);
|
||||
if (old_num_objects != gObjectList.mNumNewObjects)
|
||||
{
|
||||
update_attached_sounds();
|
||||
}
|
||||
}
|
||||
|
||||
void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data)
|
||||
|
|
@ -3292,7 +3523,12 @@ void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data
|
|||
}
|
||||
|
||||
// Update the object...
|
||||
S32 old_num_objects = gObjectList.mNumNewObjects;
|
||||
gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_FULL_COMPRESSED);
|
||||
if (old_num_objects != gObjectList.mNumNewObjects)
|
||||
{
|
||||
update_attached_sounds();
|
||||
}
|
||||
}
|
||||
|
||||
void process_cached_object_update(LLMessageSystem *mesgsys, void **user_data)
|
||||
|
|
@ -3323,7 +3559,12 @@ void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_
|
|||
gObjectData += (U32Bytes)mesgsys->getReceiveSize();
|
||||
}
|
||||
|
||||
S32 old_num_objects = gObjectList.mNumNewObjects;
|
||||
gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_TERSE_IMPROVED);
|
||||
if (old_num_objects != gObjectList.mNumNewObjects)
|
||||
{
|
||||
update_attached_sounds();
|
||||
}
|
||||
}
|
||||
|
||||
static LLTrace::BlockTimerStatHandle FTM_PROCESS_OBJECTS("Process Kill Objects");
|
||||
|
|
@ -3545,28 +3786,27 @@ void process_attached_sound(LLMessageSystem *msg, void **user_data)
|
|||
msg->getU8Fast(_PREHASH_DataBlock, _PREHASH_Flags, flags);
|
||||
|
||||
LLViewerObject *objectp = gObjectList.findObject(object_id);
|
||||
if (!objectp)
|
||||
if (objectp)
|
||||
{
|
||||
// we don't know about this object, just bail
|
||||
return;
|
||||
set_attached_sound(objectp, object_id, sound_id, owner_id, gain, flags);
|
||||
}
|
||||
|
||||
if (LLMuteList::getInstance()->isMuted(object_id)) return;
|
||||
|
||||
if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return;
|
||||
|
||||
|
||||
// Don't play sounds from a region with maturity above current agent maturity
|
||||
LLVector3d pos = objectp->getPositionGlobal();
|
||||
if( !gAgent.canAccessMaturityAtGlobal(pos) )
|
||||
else if (sound_id.notNull())
|
||||
{
|
||||
return;
|
||||
// we don't know about this object yet, probably it has yet to arrive
|
||||
// std::map for dupplicate prevention.
|
||||
postponed_sounds[object_id] = (PostponedSoundData(object_id, sound_id, owner_id, gain, flags));
|
||||
clear_expired_postponed_sounds();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::map<LLUUID, PostponedSoundData>::iterator iter = postponed_sounds.find(object_id);
|
||||
if (iter != postponed_sounds.end())
|
||||
{
|
||||
postponed_sounds.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
objectp->setAttachedSound(sound_id, owner_id, gain, flags);
|
||||
}
|
||||
|
||||
|
||||
void process_attached_sound_gain_change(LLMessageSystem *mesgsys, void **user_data)
|
||||
{
|
||||
F32 gain = 0;
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ const std::string GRID_LOGIN_IDENTIFIER_TYPES = "login_identifier_types";
|
|||
const std::string GRID_SLURL_BASE = "slurl_base";
|
||||
const std::string GRID_APP_SLURL_BASE = "app_slurl_base";
|
||||
|
||||
const std::string DEFAULT_LOGIN_PAGE = "http://viewer-login.agni.lindenlab.com/";
|
||||
const std::string DEFAULT_LOGIN_PAGE = "https://viewer-splash.secondlife.com/";
|
||||
|
||||
const std::string MAIN_GRID_LOGIN_URI = "https://login.agni.lindenlab.com/cgi-bin/login.cgi";
|
||||
|
||||
|
|
|
|||
|
|
@ -1877,7 +1877,7 @@ void LLViewerRegion::updateNetStats()
|
|||
mLastPacketsLost = mPacketsLost;
|
||||
|
||||
mPacketsIn = cdp->getPacketsIn();
|
||||
mBitsIn = cdp->getBytesIn();
|
||||
mBitsIn = 8 * cdp->getBytesIn();
|
||||
mPacketsOut = cdp->getPacketsOut();
|
||||
mPacketsLost = cdp->getPacketsLost();
|
||||
mPingDelay = cdp->getPingDelay();
|
||||
|
|
@ -2817,6 +2817,7 @@ void LLViewerRegion::unpackRegionHandshake()
|
|||
void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
|
||||
{
|
||||
capabilityNames.append("AbuseCategories");
|
||||
//capabilityNames.append("AcceptFriendship");
|
||||
capabilityNames.append("AgentPreferences");
|
||||
capabilityNames.append("AgentState");
|
||||
capabilityNames.append("AttachmentResources");
|
||||
|
|
@ -2826,6 +2827,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
|
|||
capabilityNames.append("ChatSessionRequest");
|
||||
capabilityNames.append("CopyInventoryFromNotecard");
|
||||
capabilityNames.append("CreateInventoryCategory");
|
||||
//capabilityNames.append("DeclineFriendship");
|
||||
capabilityNames.append("DispatchRegionInfo");
|
||||
capabilityNames.append("DirectDelivery");
|
||||
capabilityNames.append("EnvironmentSettings");
|
||||
|
|
|
|||
|
|
@ -193,6 +193,7 @@
|
|||
#include "llviewerdisplay.h"
|
||||
#include "llspatialpartition.h"
|
||||
#include "llviewerjoystick.h"
|
||||
#include "llviewermenufile.h" // LLFilePickerReplyThread
|
||||
#include "llviewernetwork.h"
|
||||
#include "llpostprocess.h"
|
||||
#include "llfloaterimnearbychat.h"
|
||||
|
|
@ -4365,77 +4366,110 @@ BOOL LLViewerWindow::mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d
|
|||
}
|
||||
|
||||
// Saves an image to the harddrive as "SnapshotX" where X >= 1.
|
||||
BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image, BOOL force_picker, BOOL& insufficient_memory)
|
||||
void LLViewerWindow::saveImageNumbered(LLImageFormatted *image, BOOL force_picker, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb)
|
||||
{
|
||||
insufficient_memory = FALSE;
|
||||
|
||||
if (!image)
|
||||
{
|
||||
LL_WARNS() << "No image to save" << LL_ENDL;
|
||||
return FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
LLFilePicker::ESaveFilter pick_type;
|
||||
std::string extension("." + image->getExtension());
|
||||
if (extension == ".j2c")
|
||||
pick_type = LLFilePicker::FFSAVE_J2C;
|
||||
else if (extension == ".bmp")
|
||||
pick_type = LLFilePicker::FFSAVE_BMP;
|
||||
else if (extension == ".jpg")
|
||||
pick_type = LLFilePicker::FFSAVE_JPEG;
|
||||
else if (extension == ".png")
|
||||
pick_type = LLFilePicker::FFSAVE_PNG;
|
||||
else if (extension == ".tga")
|
||||
pick_type = LLFilePicker::FFSAVE_TGA;
|
||||
else
|
||||
pick_type = LLFilePicker::FFSAVE_ALL; // ???
|
||||
|
||||
BOOL is_snapshot_name_loc_set = isSnapshotLocSet();
|
||||
|
||||
LLImageFormatted* formatted_image = image;
|
||||
// Get a base file location if needed.
|
||||
if (force_picker || !isSnapshotLocSet())
|
||||
{
|
||||
std::string proposed_name( sSnapshotBaseName );
|
||||
std::string proposed_name(sSnapshotBaseName);
|
||||
|
||||
// getSaveFile will append an appropriate extension to the proposed name, based on the ESaveFilter constant passed in.
|
||||
LLFilePicker::ESaveFilter pick_type;
|
||||
|
||||
// pick a directory in which to save
|
||||
LLFilePicker& picker = LLFilePicker::instance();
|
||||
if (!picker.getSaveFile(pick_type, proposed_name))
|
||||
{
|
||||
// Clicked cancel
|
||||
return FALSE;
|
||||
}
|
||||
if (extension == ".j2c")
|
||||
pick_type = LLFilePicker::FFSAVE_J2C;
|
||||
else if (extension == ".bmp")
|
||||
pick_type = LLFilePicker::FFSAVE_BMP;
|
||||
else if (extension == ".jpg")
|
||||
pick_type = LLFilePicker::FFSAVE_JPEG;
|
||||
else if (extension == ".png")
|
||||
pick_type = LLFilePicker::FFSAVE_PNG;
|
||||
else if (extension == ".tga")
|
||||
pick_type = LLFilePicker::FFSAVE_TGA;
|
||||
else
|
||||
pick_type = LLFilePicker::FFSAVE_ALL;
|
||||
|
||||
// Copy the directory + file name
|
||||
std::string filepath = picker.getFirstFile();
|
||||
|
||||
gSavedPerAccountSettings.setString("SnapshotBaseName", gDirUtilp->getBaseFileName(filepath, true));
|
||||
gSavedPerAccountSettings.setString("SnapshotBaseDir", gDirUtilp->getDirName(filepath));
|
||||
(new LLFilePickerReplyThread(boost::bind(&LLViewerWindow::onDirectorySelected, this, _1, formatted_image, success_cb, failure_cb), pick_type, proposed_name,
|
||||
boost::bind(&LLViewerWindow::onSelectionFailure, this, failure_cb)))->getFile();
|
||||
}
|
||||
|
||||
std::string snapshot_dir = sSnapshotDir;
|
||||
if(snapshot_dir.empty())
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
saveImageLocal(formatted_image, success_cb, failure_cb);
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerWindow::onDirectorySelected(const std::vector<std::string>& filenames, LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb)
|
||||
{
|
||||
// Copy the directory + file name
|
||||
std::string filepath = filenames[0];
|
||||
|
||||
gSavedPerAccountSettings.setString("SnapshotBaseName", gDirUtilp->getBaseFileName(filepath, true));
|
||||
gSavedPerAccountSettings.setString("SnapshotBaseDir", gDirUtilp->getDirName(filepath));
|
||||
saveImageLocal(image, success_cb, failure_cb);
|
||||
}
|
||||
|
||||
void LLViewerWindow::onSelectionFailure(const snapshot_saved_signal_t::slot_type& failure_cb)
|
||||
{
|
||||
failure_cb();
|
||||
}
|
||||
|
||||
|
||||
void LLViewerWindow::saveImageLocal(LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb)
|
||||
{
|
||||
std::string lastSnapshotDir = LLViewerWindow::getLastSnapshotDir();
|
||||
if (lastSnapshotDir.empty())
|
||||
{
|
||||
failure_cb();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if there is enough free space to save snapshot
|
||||
#ifdef LL_WINDOWS
|
||||
boost::filesystem::space_info b_space = boost::filesystem::space(utf8str_to_utf16str(snapshot_dir));
|
||||
boost::filesystem::path b_path(utf8str_to_utf16str(lastSnapshotDir));
|
||||
#else
|
||||
boost::filesystem::space_info b_space = boost::filesystem::space(snapshot_dir);
|
||||
boost::filesystem::path b_path(lastSnapshotDir);
|
||||
#endif
|
||||
if (!boost::filesystem::is_directory(b_path))
|
||||
{
|
||||
LLSD args;
|
||||
args["PATH"] = lastSnapshotDir;
|
||||
LLNotificationsUtil::add("SnapshotToLocalDirNotExist", args);
|
||||
resetSnapshotLoc();
|
||||
failure_cb();
|
||||
return;
|
||||
}
|
||||
boost::filesystem::space_info b_space = boost::filesystem::space(b_path);
|
||||
if (b_space.free < image->getDataSize())
|
||||
{
|
||||
insufficient_memory = TRUE;
|
||||
return FALSE;
|
||||
LLSD args;
|
||||
args["PATH"] = lastSnapshotDir;
|
||||
|
||||
std::string needM_bytes_string;
|
||||
LLResMgr::getInstance()->getIntegerString(needM_bytes_string, (image->getDataSize()) >> 10);
|
||||
args["NEED_MEMORY"] = needM_bytes_string;
|
||||
|
||||
std::string freeM_bytes_string;
|
||||
LLResMgr::getInstance()->getIntegerString(freeM_bytes_string, (b_space.free) >> 10);
|
||||
args["FREE_MEMORY"] = freeM_bytes_string;
|
||||
|
||||
LLNotificationsUtil::add("SnapshotToComputerFailed", args);
|
||||
|
||||
failure_cb();
|
||||
}
|
||||
|
||||
// Look for an unused file name
|
||||
BOOL is_snapshot_name_loc_set = isSnapshotLocSet();
|
||||
std::string filepath;
|
||||
S32 i = 1;
|
||||
S32 err = 0;
|
||||
|
||||
std::string extension("." + image->getExtension());
|
||||
do
|
||||
{
|
||||
filepath = sSnapshotDir;
|
||||
|
|
@ -4457,7 +4491,15 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image, BOOL force_picke
|
|||
&& is_snapshot_name_loc_set); // Or stop if we are rewriting.
|
||||
|
||||
LL_INFOS() << "Saving snapshot to " << filepath << LL_ENDL;
|
||||
return image->save(filepath);
|
||||
if (image->save(filepath))
|
||||
{
|
||||
playSnapshotAnimAndSound();
|
||||
success_cb();
|
||||
}
|
||||
else
|
||||
{
|
||||
failure_cb();
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerWindow::resetSnapshotLoc()
|
||||
|
|
|
|||
|
|
@ -352,7 +352,13 @@ public:
|
|||
BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type);
|
||||
BOOL isSnapshotLocSet() const;
|
||||
void resetSnapshotLoc() const;
|
||||
BOOL saveImageNumbered(LLImageFormatted *image, BOOL force_picker, BOOL& insufficient_memory);
|
||||
|
||||
typedef boost::signals2::signal<void(void)> snapshot_saved_signal_t;
|
||||
|
||||
void saveImageNumbered(LLImageFormatted *image, BOOL force_picker, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb);
|
||||
void onDirectorySelected(const std::vector<std::string>& filenames, LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb);
|
||||
void saveImageLocal(LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb);
|
||||
void onSelectionFailure(const snapshot_saved_signal_t::slot_type& failure_cb);
|
||||
|
||||
// Reset the directory where snapshots are saved.
|
||||
// Client will open directory picker on next snapshot save.
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ LLVoiceHandler gVoiceHandler;
|
|||
|
||||
std::string LLVoiceClientStatusObserver::status2string(LLVoiceClientStatusObserver::EStatusType inStatus)
|
||||
{
|
||||
std::string result = "UNKNOWN";
|
||||
std::string result = "UNTRANSLATED";
|
||||
|
||||
// Prevent copy-paste errors when updating this list...
|
||||
#define CASE(x) case x: result = #x; break
|
||||
|
|
@ -92,12 +92,18 @@ std::string LLVoiceClientStatusObserver::status2string(LLVoiceClientStatusObserv
|
|||
CASE(STATUS_JOINED);
|
||||
CASE(STATUS_LEFT_CHANNEL);
|
||||
CASE(STATUS_VOICE_DISABLED);
|
||||
CASE(STATUS_VOICE_ENABLED);
|
||||
CASE(BEGIN_ERROR_STATUS);
|
||||
CASE(ERROR_CHANNEL_FULL);
|
||||
CASE(ERROR_CHANNEL_LOCKED);
|
||||
CASE(ERROR_NOT_AVAILABLE);
|
||||
CASE(ERROR_UNKNOWN);
|
||||
default:
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << "UNKNOWN(" << (int)inStatus << ")";
|
||||
result = stream.str();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,8 +40,19 @@ class LLVOAvatar;
|
|||
|
||||
// devices
|
||||
|
||||
typedef std::vector<std::string> LLVoiceDeviceList;
|
||||
class LLVoiceDevice
|
||||
{
|
||||
public:
|
||||
std::string display_name; // friendly value for the user
|
||||
std::string full_name; // internal value for selection
|
||||
|
||||
LLVoiceDevice(const std::string& display_name, const std::string& full_name)
|
||||
:display_name(display_name)
|
||||
,full_name(full_name)
|
||||
{
|
||||
};
|
||||
};
|
||||
typedef std::vector<LLVoiceDevice> LLVoiceDeviceList;
|
||||
|
||||
class LLVoiceClientParticipantObserver
|
||||
{
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ namespace {
|
|||
const int CONNECT_RETRY_MAX = 3;
|
||||
|
||||
const F32 LOGIN_ATTEMPT_TIMEOUT = 30.0f;
|
||||
const F32 LOGOUT_ATTEMPT_TIMEOUT = 5.0f;
|
||||
const int LOGIN_RETRY_MAX = 3;
|
||||
|
||||
const F32 PROVISION_RETRY_TIMEOUT = 2.0;
|
||||
|
|
@ -259,9 +260,16 @@ static void killGateway()
|
|||
{
|
||||
if (sGatewayPtr)
|
||||
{
|
||||
LL_DEBUGS("Voice") << "SLVoice " << sGatewayPtr->getStatusString() << LL_ENDL;
|
||||
|
||||
sGatewayPump.stopListening("VivoxDaemonPump");
|
||||
sGatewayPtr->kill();
|
||||
sGatewayPtr->kill(__FUNCTION__);
|
||||
sGatewayPtr=NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("Voice") << "no gateway" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -283,7 +291,7 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
|
|||
mDevicesListUpdated(false),
|
||||
|
||||
mAreaVoiceDisabled(false),
|
||||
mAudioSession(),
|
||||
mAudioSession(), // TBD - should be NULL
|
||||
mAudioSessionChanged(false),
|
||||
mNextAudioSession(),
|
||||
|
||||
|
|
@ -416,6 +424,7 @@ void LLVivoxVoiceClient::cleanUp()
|
|||
deleteAllSessions();
|
||||
deleteAllVoiceFonts();
|
||||
deleteVoiceFontTemplates();
|
||||
LL_DEBUGS("Voice") << "exiting" << LL_ENDL;
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
|
|
@ -542,6 +551,10 @@ void LLVivoxVoiceClient::connectorShutdown()
|
|||
|
||||
writeString(stream.str());
|
||||
}
|
||||
else
|
||||
{
|
||||
mShutdownComplete = true;
|
||||
}
|
||||
}
|
||||
|
||||
void LLVivoxVoiceClient::userAuthorized(const std::string& user_id, const LLUUID &agentID)
|
||||
|
|
@ -641,18 +654,18 @@ void LLVivoxVoiceClient::idle(void* user_data)
|
|||
//
|
||||
void LLVivoxVoiceClient::voiceControlCoro()
|
||||
{
|
||||
LL_DEBUGS("Voice") << "starting" << LL_ENDL;
|
||||
mIsCoroutineActive = true;
|
||||
LLCoros::set_consuming(true);
|
||||
|
||||
while (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
|
||||
{
|
||||
LL_INFOS("Voice") << "Suspending voiceControlCoro() due to teleport. Tuning: " << mTuningMode << ". Relog: " << mRelogRequested << LL_ENDL;
|
||||
LL_DEBUGS("Voice") << "Suspending voiceControlCoro() momentarily for teleport. Tuning: " << mTuningMode << ". Relog: " << mRelogRequested << LL_ENDL;
|
||||
llcoro::suspendUntilTimeout(1.0);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
|
||||
if (startAndConnectSession())
|
||||
{
|
||||
if (mTuningMode)
|
||||
|
|
@ -662,6 +675,7 @@ void LLVivoxVoiceClient::voiceControlCoro()
|
|||
|
||||
waitForChannel(); // this doesn't normally return unless relog is needed or shutting down
|
||||
|
||||
LL_DEBUGS("Voice") << "lost channel RelogRequested=" << mRelogRequested << LL_ENDL;
|
||||
endAndDisconnectSession();
|
||||
}
|
||||
|
||||
|
|
@ -669,16 +683,23 @@ void LLVivoxVoiceClient::voiceControlCoro()
|
|||
// that we attempted to relog into Vivox and were rejected.
|
||||
// Rather than just quit out of voice, we will tear it down (above)
|
||||
// and then reconstruct the voice connecion from scratch.
|
||||
LL_DEBUGS("Voice")
|
||||
<< "disconnected"
|
||||
<< " RelogRequested=" << mRelogRequested
|
||||
<< LL_ENDL;
|
||||
if (mRelogRequested)
|
||||
{
|
||||
LL_INFOS("Voice") << "will attempt to reconnect to voice" << LL_ENDL;
|
||||
while (isGatewayRunning() || gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
|
||||
{
|
||||
LL_INFOS("Voice") << "waiting for SLVoice to exit" << LL_ENDL;
|
||||
llcoro::suspendUntilTimeout(1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (mRelogRequested);
|
||||
while (mVoiceEnabled && mRelogRequested);
|
||||
mIsCoroutineActive = false;
|
||||
LL_INFOS("Voice") << "exiting" << LL_ENDL;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -710,6 +731,8 @@ bool LLVivoxVoiceClient::startAndConnectSession()
|
|||
|
||||
bool LLVivoxVoiceClient::endAndDisconnectSession()
|
||||
{
|
||||
LL_DEBUGS("Voice") << LL_ENDL;
|
||||
|
||||
breakVoiceConnection(true);
|
||||
|
||||
killGateway();
|
||||
|
|
@ -719,13 +742,15 @@ bool LLVivoxVoiceClient::endAndDisconnectSession()
|
|||
|
||||
bool LLVivoxVoiceClient::callbackEndDaemon(const LLSD& data)
|
||||
{
|
||||
if (!LLAppViewer::isExiting())
|
||||
if (!LLAppViewer::isExiting() && mVoiceEnabled)
|
||||
{
|
||||
LL_WARNS("Voice") << "SLVoice terminated " << ll_stream_notation_sd(data) << LL_ENDL;
|
||||
terminateAudioSession(false);
|
||||
closeSocket();
|
||||
cleanUp();
|
||||
LLVoiceClient::getInstance()->setUserPTTState(false);
|
||||
gAgent.setVoiceConnected(false);
|
||||
mRelogRequested = true;
|
||||
}
|
||||
sGatewayPump.stopListening("VivoxDaemonPump");
|
||||
return false;
|
||||
|
|
@ -737,6 +762,7 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
|
|||
if (!voiceEnabled())
|
||||
{
|
||||
// Voice is locked out, we must not launch the vivox daemon.
|
||||
LL_WARNS("Voice") << "voice disabled; not starting daemon" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -744,11 +770,6 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
|
|||
{
|
||||
#ifndef VIVOXDAEMON_REMOTEHOST
|
||||
// Launch the voice daemon
|
||||
|
||||
// *FIX:Mani - Using the executable dir instead
|
||||
// of mAppRODataDir, the working directory from which the app
|
||||
// is launched.
|
||||
//std::string exe_path = gDirUtilp->getAppRODataDir();
|
||||
std::string exe_path = gDirUtilp->getExecutableDir();
|
||||
exe_path += gDirUtilp->getDirDelimiter();
|
||||
#if LL_WINDOWS
|
||||
|
|
@ -803,13 +824,16 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
|
|||
params.postend = sGatewayPump.getName();
|
||||
sGatewayPump.listen("VivoxDaemonPump", boost::bind(&LLVivoxVoiceClient::callbackEndDaemon, this, _1));
|
||||
|
||||
LL_INFOS("Voice") << "Launching SLVoice" << LL_ENDL;
|
||||
LL_DEBUGS("Voice") << "SLVoice params " << params << LL_ENDL;
|
||||
|
||||
sGatewayPtr = LLProcess::create(params);
|
||||
|
||||
mDaemonHost = LLHost(gSavedSettings.getString("VivoxVoiceHost").c_str(), gSavedSettings.getU32("VivoxVoicePort"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_INFOS("Voice") << exe_path << " not found." << LL_ENDL;
|
||||
LL_WARNS("Voice") << exe_path << " not found." << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
|
|
@ -832,6 +856,10 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
|
|||
|
||||
mMainSessionGroupHandle.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("Voice") << " gateway running; not attempting to start" << LL_ENDL;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS);
|
||||
|
|
@ -896,12 +924,15 @@ bool LLVivoxVoiceClient::provisionVoiceAccount()
|
|||
|
||||
while (!gAgent.getRegion() || !gAgent.getRegion()->capabilitiesReceived())
|
||||
{
|
||||
LL_DEBUGS("Voice") << "no capabilities for voice provisioning; waiting " << LL_ENDL;
|
||||
// *TODO* Pump a message for wake up.
|
||||
llcoro::suspend();
|
||||
}
|
||||
|
||||
std::string url = gAgent.getRegionCapability("ProvisionVoiceAccountRequest");
|
||||
|
||||
LL_DEBUGS("Voice") << "region ready for voice provisioning; url=" << url << LL_ENDL;
|
||||
|
||||
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
|
||||
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
|
||||
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("voiceAccountProvision", httpPolicy));
|
||||
|
|
@ -949,14 +980,23 @@ bool LLVivoxVoiceClient::provisionVoiceAccount()
|
|||
std::string voiceUserName = result["username"].asString();
|
||||
std::string voicePassword = result["password"].asString();
|
||||
|
||||
//LL_DEBUGS("Voice") << "ProvisionVoiceAccountRequest response:" << dumpResponse() << LL_ENDL;
|
||||
|
||||
if (result.has("voice_sip_uri_hostname"))
|
||||
{
|
||||
voiceSipUriHostname = result["voice_sip_uri_hostname"].asString();
|
||||
|
||||
}
|
||||
|
||||
// this key is actually misnamed -- it will be an entire URI, not just a hostname.
|
||||
if (result.has("voice_account_server_name"))
|
||||
{
|
||||
voiceAccountServerUri = result["voice_account_server_name"].asString();
|
||||
}
|
||||
|
||||
LL_DEBUGS("Voice") << "ProvisionVoiceAccountRequest response"
|
||||
<< " user " << (voiceUserName.empty() ? "not set" : "set")
|
||||
<< " password " << (voicePassword.empty() ? "not set" : "set")
|
||||
<< " sip uri " << voiceSipUriHostname
|
||||
<< " account uri " << voiceAccountServerUri
|
||||
<< LL_ENDL;
|
||||
|
||||
setLoginInfo(voiceUserName, voicePassword, voiceSipUriHostname, voiceAccountServerUri);
|
||||
|
||||
|
|
@ -968,8 +1008,11 @@ bool LLVivoxVoiceClient::establishVoiceConnection()
|
|||
LLEventPump &voiceConnectPump = LLEventPumps::instance().obtain("vivoxClientPump");
|
||||
|
||||
if (!mVoiceEnabled && mIsInitialized)
|
||||
{
|
||||
LL_WARNS("Voice") << "cannot establish connection; enabled "<<mVoiceEnabled<<" initialized "<<mIsInitialized<<LL_ENDL;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
LLSD result;
|
||||
bool connected(false);
|
||||
bool giving_up(false);
|
||||
|
|
@ -1031,7 +1074,7 @@ bool LLVivoxVoiceClient::establishVoiceConnection()
|
|||
|
||||
bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait)
|
||||
{
|
||||
LL_DEBUGS("Voice") << LL_ENDL;
|
||||
LL_DEBUGS("Voice") << "( wait=" << corowait << ")" << LL_ENDL;
|
||||
LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
|
||||
bool retval(true);
|
||||
|
||||
|
|
@ -1040,26 +1083,38 @@ bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait)
|
|||
|
||||
if (corowait)
|
||||
{
|
||||
LLSD result = llcoro::suspendUntilEventOn(voicePump);
|
||||
LLSD timeoutResult(LLSDMap("connector", "timeout"));
|
||||
|
||||
LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult);
|
||||
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
|
||||
|
||||
retval = result.has("connector");
|
||||
}
|
||||
else
|
||||
{ // If we are not doing a corowait then we must sleep until the connector has responded
|
||||
{
|
||||
mRelogRequested = false; //stop the control coro
|
||||
// If we are not doing a corowait then we must sleep until the connector has responded
|
||||
// otherwise we may very well close the socket too early.
|
||||
#if LL_WINDOWS
|
||||
int count = 0;
|
||||
while (!mShutdownComplete && 10 > count++)
|
||||
{ // Rider: This comes out to a max wait time of 10 seconds.
|
||||
// The situation that brings us here is a call from ::terminate()
|
||||
// and so the viewer is attempting to go away. Don't slow it down
|
||||
// longer than this.
|
||||
if (!mShutdownComplete)
|
||||
{
|
||||
// The situation that brings us here is a call from ::terminate()
|
||||
// At this point message system is already down so we can't wait for
|
||||
// the message, yet we need to receive "connector shutdown response".
|
||||
// Either wait a bit and emulate it or check gMessageSystem for specific message
|
||||
_sleep(1000);
|
||||
if (mConnected)
|
||||
{
|
||||
mConnected = false;
|
||||
LLSD vivoxevent(LLSDMap("connector", LLSD::Boolean(false)));
|
||||
LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
|
||||
}
|
||||
mShutdownComplete = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
LL_DEBUGS("Voice") << "closing SLVoice socket" << LL_ENDL;
|
||||
closeSocket(); // Need to do this now -- bad things happen if the destructor does it later.
|
||||
cleanUp();
|
||||
mConnected = false;
|
||||
|
|
@ -1161,31 +1216,35 @@ bool LLVivoxVoiceClient::loginToVivox()
|
|||
|
||||
void LLVivoxVoiceClient::logoutOfVivox(bool wait)
|
||||
{
|
||||
|
||||
if (!mIsLoggedIn)
|
||||
return;
|
||||
|
||||
// Ensure that we'll re-request provisioning before logging in again
|
||||
mAccountPassword.clear();
|
||||
mVoiceAccountServerURI.clear();
|
||||
|
||||
logoutSendMessage();
|
||||
|
||||
if (wait)
|
||||
if (mIsLoggedIn)
|
||||
{
|
||||
LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
|
||||
LLSD timeoutResult(LLSDMap("lougout", "timeout"));
|
||||
// Ensure that we'll re-request provisioning before logging in again
|
||||
mAccountPassword.clear();
|
||||
mVoiceAccountServerURI.clear();
|
||||
|
||||
LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGIN_ATTEMPT_TIMEOUT, timeoutResult);
|
||||
logoutSendMessage();
|
||||
|
||||
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
|
||||
|
||||
if (result.has("logout"))
|
||||
if (wait)
|
||||
{
|
||||
}
|
||||
}
|
||||
LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
|
||||
LLSD timeoutResult(LLSDMap("logout", "timeout"));
|
||||
|
||||
mIsLoggedIn = false;
|
||||
LL_DEBUGS("Voice")
|
||||
<< "waiting for logout response on "
|
||||
<< voicePump.getName()
|
||||
<< LL_ENDL;
|
||||
|
||||
LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult);
|
||||
|
||||
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("Voice") << "not waiting for logout" << LL_ENDL;
|
||||
}
|
||||
|
||||
mIsLoggedIn = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1256,6 +1315,10 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo()
|
|||
// state. If the cap request is still pending,
|
||||
// the responder will check to see if we've moved
|
||||
// to a new session and won't change any state.
|
||||
LL_DEBUGS("Voice") << "terminate requested " << mSessionTerminateRequested
|
||||
<< " enabled " << mVoiceEnabled
|
||||
<< " initialized " << mIsInitialized
|
||||
<< LL_ENDL;
|
||||
terminateAudioSession(true);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1280,17 +1343,30 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo()
|
|||
LLSD voice_credentials = result["voice_credentials"];
|
||||
if (voice_credentials.has("channel_uri"))
|
||||
{
|
||||
LL_DEBUGS("Voice") << "got voice channel uri" << LL_ENDL;
|
||||
uri = voice_credentials["channel_uri"].asString();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Voice") << "No voice channel uri" << LL_ENDL;
|
||||
}
|
||||
|
||||
if (voice_credentials.has("channel_credentials"))
|
||||
{
|
||||
LL_DEBUGS("Voice") << "got voice channel credentials" << LL_ENDL;
|
||||
credentials =
|
||||
voice_credentials["channel_credentials"].asString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Voice") << "No voice channel credentials" << LL_ENDL;
|
||||
|
||||
if (!uri.empty())
|
||||
LL_INFOS("Voice") << "Voice URI is " << uri << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Voice") << "No voice credentials" << LL_ENDL;
|
||||
}
|
||||
|
||||
// set the spatial channel. If no voice credentials or uri are
|
||||
// available, then we simply drop out of voice spatially.
|
||||
|
|
@ -1353,7 +1429,10 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
|
|||
|
||||
if (!mVoiceEnabled && mIsInitialized)
|
||||
{
|
||||
LL_DEBUGS("Voice") << "Voice no longer enabled. Exiting." << LL_ENDL;
|
||||
LL_DEBUGS("Voice") << "Voice no longer enabled. Exiting"
|
||||
<< " enabled " << mVoiceEnabled
|
||||
<< " initialized " << mIsInitialized
|
||||
<< LL_ENDL;
|
||||
mIsJoiningSession = false;
|
||||
// User bailed out during connect -- jump straight to teardown.
|
||||
terminateAudioSession(true);
|
||||
|
|
@ -1476,7 +1555,7 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait)
|
|||
|
||||
if (mAudioSession)
|
||||
{
|
||||
LL_INFOS("Voice") << "Terminating current voice session " << mAudioSession->mHandle << LL_ENDL;
|
||||
LL_INFOS("Voice") << "terminateAudioSession(" << wait << ") Terminating current voice session " << mAudioSession->mHandle << LL_ENDL;
|
||||
|
||||
if (mIsLoggedIn)
|
||||
{
|
||||
|
|
@ -1506,7 +1585,9 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait)
|
|||
LLSD result;
|
||||
do
|
||||
{
|
||||
result = llcoro::suspendUntilEventOn(voicePump);
|
||||
LLSD timeoutResult(LLSDMap("session", "timeout"));
|
||||
|
||||
result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult);
|
||||
|
||||
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
|
||||
if (result.has("session"))
|
||||
|
|
@ -1521,7 +1602,7 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait)
|
|||
}
|
||||
|
||||
std::string message = result["session"].asString();
|
||||
if (message == "removed")
|
||||
if (message == "removed" || message == "timeout")
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
|
|
@ -1546,11 +1627,10 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait)
|
|||
|
||||
// The old session may now need to be deleted.
|
||||
reapSession(oldSession);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Voice") << "stateSessionTerminated with NULL mAudioSession" << LL_ENDL;
|
||||
LL_WARNS("Voice") << "terminateAudioSession(" << wait << ") with NULL mAudioSession" << LL_ENDL;
|
||||
}
|
||||
|
||||
notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL);
|
||||
|
|
@ -1560,13 +1640,15 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait)
|
|||
// the region chat.
|
||||
mSessionTerminateRequested = false;
|
||||
|
||||
if ((mVoiceEnabled || !mIsInitialized) && !mRelogRequested && !LLApp::isExiting())
|
||||
{
|
||||
// Just leaving a channel, go back to stateNoChannel (the "logged in but have no channel" state).
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
bool status=((mVoiceEnabled || !mIsInitialized) && !mRelogRequested && !LLApp::isExiting());
|
||||
LL_DEBUGS("Voice") << "exiting"
|
||||
<< " VoiceEnabled " << mVoiceEnabled
|
||||
<< " IsInitialized " << mIsInitialized
|
||||
<< " RelogRequested " << mRelogRequested
|
||||
<< " AppExiting " << LLApp::isExiting()
|
||||
<< " returning " << status
|
||||
<< LL_ENDL;
|
||||
return status;
|
||||
}
|
||||
|
||||
bool LLVivoxVoiceClient::waitForChannel()
|
||||
|
|
@ -1627,7 +1709,18 @@ bool LLVivoxVoiceClient::waitForChannel()
|
|||
sessionStatePtr_t joinSession = mNextAudioSession;
|
||||
mNextAudioSession.reset();
|
||||
if (!runSession(joinSession))
|
||||
{
|
||||
LL_DEBUGS("Voice") << "runSession returned false; leaving inner loop" << LL_ENDL;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("Voice")
|
||||
<< "runSession returned true to inner loop"
|
||||
<< " RelogRequested=" << mRelogRequested
|
||||
<< " VoiceEnabled=" << mVoiceEnabled
|
||||
<< LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mNextAudioSession)
|
||||
|
|
@ -1636,20 +1729,33 @@ bool LLVivoxVoiceClient::waitForChannel()
|
|||
}
|
||||
} while (mVoiceEnabled && !mRelogRequested);
|
||||
|
||||
LL_DEBUGS("Voice")
|
||||
<< "leaving inner waitForChannel loop"
|
||||
<< " RelogRequested=" << mRelogRequested
|
||||
<< " VoiceEnabled=" << mVoiceEnabled
|
||||
<< LL_ENDL;
|
||||
|
||||
mIsProcessingChannels = false;
|
||||
|
||||
logoutOfVivox(true);
|
||||
|
||||
if (mRelogRequested)
|
||||
{
|
||||
LL_DEBUGS("Voice") << "Relog Requested, restarting provisioning" << LL_ENDL;
|
||||
if (!provisionVoiceAccount())
|
||||
{
|
||||
LL_WARNS("Voice") << "provisioning voice failed; giving up" << LL_ENDL;
|
||||
giveUp();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} while (mVoiceEnabled && mRelogRequested);
|
||||
} while (mVoiceEnabled && mRelogRequested && isGatewayRunning());
|
||||
|
||||
LL_DEBUGS("Voice")
|
||||
<< "exiting"
|
||||
<< " RelogRequested=" << mRelogRequested
|
||||
<< " VoiceEnabled=" << mVoiceEnabled
|
||||
<< LL_ENDL;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1663,6 +1769,7 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
|
|||
|
||||
if (mSessionTerminateRequested)
|
||||
{
|
||||
LL_DEBUGS("Voice") << "runSession terminate requested " << LL_ENDL;
|
||||
terminateAudioSession(true);
|
||||
}
|
||||
// if a relog has been requested then addAndJoineSession
|
||||
|
|
@ -1681,7 +1788,7 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
|
|||
mIsInChannel = true;
|
||||
mMuteMicDirty = true;
|
||||
|
||||
while (mVoiceEnabled && !mSessionTerminateRequested && !mTuningMode)
|
||||
while (mVoiceEnabled && isGatewayRunning() && !mSessionTerminateRequested && !mTuningMode)
|
||||
{
|
||||
sendCaptureAndRenderDevices();
|
||||
if (mAudioSession && mAudioSession->mParticipantsChanged)
|
||||
|
|
@ -1731,7 +1838,9 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
|
|||
mIsInitialized = true;
|
||||
LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, UPDATE_THROTTLE_SECONDS, timeoutEvent);
|
||||
if (!result.has("timeout")) // logging the timeout event spams the log
|
||||
{
|
||||
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
|
||||
}
|
||||
if (result.has("session"))
|
||||
{
|
||||
if (result.has("handle"))
|
||||
|
|
@ -1752,6 +1861,7 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
|
|||
|
||||
if (message == "removed")
|
||||
{
|
||||
LL_DEBUGS("Voice") << "session removed" << LL_ENDL;
|
||||
notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL);
|
||||
break;
|
||||
}
|
||||
|
|
@ -1761,15 +1871,16 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
|
|||
std::string message = result["login"];
|
||||
if (message == "account_logout")
|
||||
{
|
||||
LL_DEBUGS("Voice") << "logged out" << LL_ENDL;
|
||||
mIsLoggedIn = false;
|
||||
mRelogRequested = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mIsInChannel = false;
|
||||
LL_DEBUGS("Voice") << "terminating at end of runSession" << LL_ENDL;
|
||||
terminateAudioSession(true);
|
||||
|
||||
return true;
|
||||
|
|
@ -1965,6 +2076,7 @@ bool LLVivoxVoiceClient::performMicTuning()
|
|||
|
||||
if (mTuningSpeakerVolumeDirty)
|
||||
{
|
||||
LL_INFOS("Voice") << "setting tuning speaker level to " << mTuningSpeakerVolume << LL_ENDL;
|
||||
stream
|
||||
<< "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetSpeakerLevel.1\">"
|
||||
<< "<Level>" << mTuningSpeakerVolume << "</Level>"
|
||||
|
|
@ -2322,11 +2434,10 @@ void LLVivoxVoiceClient::clearCaptureDevices()
|
|||
mCaptureDevices.clear();
|
||||
}
|
||||
|
||||
void LLVivoxVoiceClient::addCaptureDevice(const std::string& name)
|
||||
void LLVivoxVoiceClient::addCaptureDevice(const LLVoiceDevice& device)
|
||||
{
|
||||
LL_DEBUGS("Voice") << name << LL_ENDL;
|
||||
|
||||
mCaptureDevices.push_back(name);
|
||||
LL_DEBUGS("Voice") << "display: '" << device.display_name << "' device: '" << device.full_name << "'" << LL_ENDL;
|
||||
mCaptureDevices.push_back(device);
|
||||
}
|
||||
|
||||
LLVoiceDeviceList& LLVivoxVoiceClient::getCaptureDevices()
|
||||
|
|
@ -2364,10 +2475,10 @@ void LLVivoxVoiceClient::clearRenderDevices()
|
|||
mRenderDevices.clear();
|
||||
}
|
||||
|
||||
void LLVivoxVoiceClient::addRenderDevice(const std::string& name)
|
||||
void LLVivoxVoiceClient::addRenderDevice(const LLVoiceDevice& device)
|
||||
{
|
||||
LL_DEBUGS("Voice") << name << LL_ENDL;
|
||||
mRenderDevices.push_back(name);
|
||||
LL_DEBUGS("Voice") << "display: '" << device.display_name << "' device: '" << device.full_name << "'" << LL_ENDL;
|
||||
mRenderDevices.push_back(device);
|
||||
}
|
||||
|
||||
LLVoiceDeviceList& LLVivoxVoiceClient::getRenderDevices()
|
||||
|
|
@ -2515,13 +2626,13 @@ bool LLVivoxVoiceClient::deviceSettingsAvailable()
|
|||
}
|
||||
bool LLVivoxVoiceClient::deviceSettingsUpdated()
|
||||
{
|
||||
bool updated = mDevicesListUpdated;
|
||||
if (mDevicesListUpdated)
|
||||
{
|
||||
// a hot swap event or a polling of the audio devices has been parsed since the last redraw of the input and output device panel.
|
||||
mDevicesListUpdated = !mDevicesListUpdated; // toggle the setting
|
||||
return true;
|
||||
mDevicesListUpdated = false; // toggle the setting
|
||||
}
|
||||
return false;
|
||||
return updated;
|
||||
}
|
||||
|
||||
void LLVivoxVoiceClient::refreshDeviceLists(bool clearCurrentList)
|
||||
|
|
@ -2540,8 +2651,7 @@ void LLVivoxVoiceClient::daemonDied()
|
|||
// The daemon died, so the connection is gone. Reset everything and start over.
|
||||
LL_WARNS("Voice") << "Connection to vivox daemon lost. Resetting state."<< LL_ENDL;
|
||||
|
||||
// Try to relaunch the daemon
|
||||
/*TODO:*/
|
||||
//TODO: Try to relaunch the daemon
|
||||
}
|
||||
|
||||
void LLVivoxVoiceClient::giveUp()
|
||||
|
|
@ -2902,7 +3012,6 @@ void LLVivoxVoiceClient::sendPositionAndVolumeUpdate(void)
|
|||
}
|
||||
}
|
||||
|
||||
//sendLocalAudioUpdates(); obsolete, used to send volume setting on position updates
|
||||
std::string update(stream.str());
|
||||
if(!update.empty())
|
||||
{
|
||||
|
|
@ -2947,7 +3056,6 @@ void LLVivoxVoiceClient::sendLocalAudioUpdates()
|
|||
{
|
||||
// Check all of the dirty states and then send messages to those needing to be changed.
|
||||
// Tuningmode hands its own mute settings.
|
||||
|
||||
std::ostringstream stream;
|
||||
|
||||
if (mMuteMicDirty && !mTuningMode)
|
||||
|
|
@ -2956,7 +3064,7 @@ void LLVivoxVoiceClient::sendLocalAudioUpdates()
|
|||
|
||||
// Send a local mute command.
|
||||
|
||||
LL_DEBUGS("Voice") << "Sending MuteLocalMic command with parameter " << (mMuteMic ? "true" : "false") << LL_ENDL;
|
||||
LL_INFOS("Voice") << "Sending MuteLocalMic command with parameter " << (mMuteMic ? "true" : "false") << LL_ENDL;
|
||||
|
||||
stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Connector.MuteLocalMic.1\">"
|
||||
<< "<ConnectorHandle>" << LLVivoxSecurity::getInstance()->connectorHandle() << "</ConnectorHandle>"
|
||||
|
|
@ -3218,8 +3326,6 @@ void LLVivoxVoiceClient::sessionConnectResponse(std::string &requestId, int stat
|
|||
{
|
||||
LL_DEBUGS("Voice") << "Session.Connect response received (success)" << LL_ENDL;
|
||||
}
|
||||
|
||||
/*TODO: Post response?*/
|
||||
}
|
||||
|
||||
void LLVivoxVoiceClient::logoutResponse(int statusCode, std::string &statusString)
|
||||
|
|
@ -3243,6 +3349,7 @@ void LLVivoxVoiceClient::connectorShutdownResponse(int statusCode, std::string &
|
|||
}
|
||||
|
||||
mConnected = false;
|
||||
mShutdownComplete = true;
|
||||
|
||||
LLSD vivoxevent(LLSDMap("connector", LLSD::Boolean(false)));
|
||||
|
||||
|
|
@ -4023,7 +4130,7 @@ void LLVivoxVoiceClient::sessionNotificationEvent(std::string &sessionHandle, st
|
|||
|
||||
void LLVivoxVoiceClient::auxAudioPropertiesEvent(F32 energy)
|
||||
{
|
||||
LL_DEBUGS("Voice") << "got energy " << energy << LL_ENDL;
|
||||
LL_DEBUGS("VoiceEnergy") << "got energy " << energy << LL_ENDL;
|
||||
mTuningEnergy = energy;
|
||||
}
|
||||
|
||||
|
|
@ -4975,6 +5082,12 @@ void LLVivoxVoiceClient::setMuteMic(bool muted)
|
|||
|
||||
void LLVivoxVoiceClient::setVoiceEnabled(bool enabled)
|
||||
{
|
||||
LL_DEBUGS("Voice")
|
||||
<< "( " << (enabled ? "enabled" : "disabled") << " )"
|
||||
<< " was "<< (mVoiceEnabled ? "enabled" : "disabled")
|
||||
<< " coro "<< (mIsCoroutineActive ? "active" : "inactive")
|
||||
<< LL_ENDL;
|
||||
|
||||
if (enabled != mVoiceEnabled)
|
||||
{
|
||||
// TODO: Refactor this so we don't call into LLVoiceChannel, but simply
|
||||
|
|
@ -4984,6 +5097,7 @@ void LLVivoxVoiceClient::setVoiceEnabled(bool enabled)
|
|||
|
||||
if (enabled)
|
||||
{
|
||||
LL_DEBUGS("Voice") << "enabling" << LL_ENDL;
|
||||
LLVoiceChannel::getCurrentVoiceChannel()->activate();
|
||||
status = LLVoiceClientStatusObserver::STATUS_VOICE_ENABLED;
|
||||
|
||||
|
|
@ -4991,6 +5105,10 @@ void LLVivoxVoiceClient::setVoiceEnabled(bool enabled)
|
|||
{
|
||||
LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro();",
|
||||
boost::bind(&LLVivoxVoiceClient::voiceControlCoro, LLVivoxVoiceClient::getInstance()));
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("Voice") << "coro should be active.. not launching" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -4999,8 +5117,13 @@ void LLVivoxVoiceClient::setVoiceEnabled(bool enabled)
|
|||
LLVoiceChannel::getCurrentVoiceChannel()->deactivate();
|
||||
status = LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED;
|
||||
}
|
||||
notifyStatusObservers(status);
|
||||
|
||||
notifyStatusObservers(status);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("Voice") << " no-op" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLVivoxVoiceClient::voiceEnabled()
|
||||
|
|
@ -5704,7 +5827,7 @@ void LLVivoxVoiceClient::deleteSession(const sessionStatePtr_t &session)
|
|||
|
||||
void LLVivoxVoiceClient::deleteAllSessions()
|
||||
{
|
||||
LL_DEBUGS("Voice") << "called" << LL_ENDL;
|
||||
LL_DEBUGS("Voice") << LL_ENDL;
|
||||
|
||||
while (!mSessionsByHandle.empty())
|
||||
{
|
||||
|
|
@ -5755,6 +5878,10 @@ void LLVivoxVoiceClient::removeObserver(LLVoiceClientStatusObserver* observer)
|
|||
|
||||
void LLVivoxVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::EStatusType status)
|
||||
{
|
||||
LL_DEBUGS("Voice") << "( " << LLVoiceClientStatusObserver::status2string(status) << " )"
|
||||
<< " mAudioSession=" << mAudioSession
|
||||
<< LL_ENDL;
|
||||
|
||||
if(mAudioSession)
|
||||
{
|
||||
if(status == LLVoiceClientStatusObserver::ERROR_UNKNOWN)
|
||||
|
|
@ -5799,8 +5926,8 @@ void LLVivoxVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::ESta
|
|||
LL_DEBUGS("Voice")
|
||||
<< " " << LLVoiceClientStatusObserver::status2string(status)
|
||||
<< ", session URI " << getAudioSessionURI()
|
||||
<< (inSpatialChannel()?", proximal is true":", proximal is false")
|
||||
<< LL_ENDL;
|
||||
<< ", proximal is " << inSpatialChannel()
|
||||
<< LL_ENDL;
|
||||
|
||||
for (status_observer_set_t::iterator it = mStatusObservers.begin();
|
||||
it != mStatusObservers.end();
|
||||
|
|
@ -6193,6 +6320,7 @@ void LLVivoxVoiceClient::expireVoiceFonts()
|
|||
|
||||
LLSD args;
|
||||
args["URL"] = LLTrans::getString("voice_morphing_url");
|
||||
args["PREMIUM_URL"] = LLTrans::getString("premium_voice_morphing_url");
|
||||
|
||||
// Give a notification if any voice fonts have expired.
|
||||
if (have_expired)
|
||||
|
|
@ -7007,16 +7135,20 @@ void LLVivoxProtocolParser::EndTag(const char *tag)
|
|||
else if (!stricmp("Presence", tag))
|
||||
statusString = string;
|
||||
else if (!stricmp("CaptureDevices", tag))
|
||||
{
|
||||
LLVivoxVoiceClient::getInstance()->setDevicesListUpdated(true);
|
||||
}
|
||||
else if (!stricmp("RenderDevices", tag))
|
||||
{
|
||||
LLVivoxVoiceClient::getInstance()->setDevicesListUpdated(true);
|
||||
}
|
||||
else if (!stricmp("CaptureDevice", tag))
|
||||
{
|
||||
LLVivoxVoiceClient::getInstance()->addCaptureDevice(deviceString);
|
||||
LLVivoxVoiceClient::getInstance()->addCaptureDevice(LLVoiceDevice(displayNameString, deviceString));
|
||||
}
|
||||
else if (!stricmp("RenderDevice", tag))
|
||||
{
|
||||
LLVivoxVoiceClient::getInstance()->addRenderDevice(deviceString);
|
||||
LLVivoxVoiceClient::getInstance()->addRenderDevice(LLVoiceDevice(displayNameString, deviceString));
|
||||
}
|
||||
else if (!stricmp("BlockMask", tag))
|
||||
blockMask = string;
|
||||
|
|
|
|||
|
|
@ -432,10 +432,10 @@ protected:
|
|||
//----------------------------------
|
||||
// devices
|
||||
void clearCaptureDevices();
|
||||
void addCaptureDevice(const std::string& name);
|
||||
void addCaptureDevice(const LLVoiceDevice& device);
|
||||
void clearRenderDevices();
|
||||
void setDevicesListUpdated(bool state);
|
||||
void addRenderDevice(const std::string& name);
|
||||
void addRenderDevice(const LLVoiceDevice& device);
|
||||
void buildSetAudioDevices(std::ostringstream &stream);
|
||||
|
||||
void getCaptureDevicesSendMessage();
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
<text name="AvatarPhysicsDetailText">
|
||||
Niedrig
|
||||
</text>
|
||||
<text name="ShadersText">
|
||||
<text name="HardwareText">
|
||||
Hardware
|
||||
</text>
|
||||
<slider label="Texturen-Cache (MB):" name="GraphicsCardTextureMemory" tool_tip="Speicherplatz, der für Texturen zur Verfügung steht. In der Regel handelt es sich um Grafikkartenspeicher. Ein kleinerer Wert kann die Geschwindigkeit erhöhen, aber auch zu Texturunschärfen führen."/>
|
||||
|
|
@ -56,6 +56,9 @@
|
|||
<text name="antialiasing restart">
|
||||
(Neustart erforderlich)
|
||||
</text>
|
||||
<text name="MeshText">
|
||||
Netz
|
||||
</text>
|
||||
<slider label="Gitterdetails Terrain:" name="TerrainMeshDetail"/>
|
||||
<text name="TerrainMeshDetailText">
|
||||
Niedrig
|
||||
|
|
@ -72,6 +75,9 @@
|
|||
<text name="FlexibleMeshDetailText">
|
||||
Niedrig
|
||||
</text>
|
||||
<text name="ShadersText">
|
||||
Shader
|
||||
</text>
|
||||
<check_box initial_value="true" label="Transparentes Wasser" name="TransparentWater"/>
|
||||
<check_box initial_value="true" label="Bumpmapping und Glanz" name="BumpShiny"/>
|
||||
<check_box initial_value="true" label="Lokale Lichtquellen" name="LocalLights"/>
|
||||
|
|
@ -111,5 +117,6 @@
|
|||
<button label="Auf empfohlene Einstellungen zurücksetzen" name="Defaults"/>
|
||||
<button label="OK" label_selected="OK" name="OK"/>
|
||||
<button label="Abbrechen" label_selected="Abbrechen" name="Cancel"/>
|
||||
<check_box label="RenderAvatarMaxComplexity" name="RenderAvatarMaxNonImpostors"/>
|
||||
<check_box label="RenderAvatarMaxComplexity" name="RenderAvatarMaxComplexity"/>
|
||||
<check_box label="RenderAvatarMaxNonImpostors" name="RenderAvatarMaxNonImpostors"/>
|
||||
</floater>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
<menu_item_call label="Nicht mehr ignorieren" name="unblock"/>
|
||||
<menu_item_check label="Voice ignorieren" name="BlockVoice"/>
|
||||
<menu_item_check label="Text ignorieren" name="MuteText"/>
|
||||
<menu_item_check label="Partikel blockieren" name="MuteParticles"/>
|
||||
<menu_item_check label="Objektsounds ignorieren" name="BlockObjectSounds"/>
|
||||
<menu_item_call label="Profil..." name="profile"/>
|
||||
</toggleable_menu>
|
||||
|
|
|
|||
|
|
@ -4317,7 +4317,7 @@ Wählen Sie eine kleinere Landfläche aus.
|
|||
Aufgrund eines internen Fehlers konnte Ihr Viewer nicht ordnungsgemäß aktualisiert werden. Der in Ihrem Viewer angezeigte L$-Kontostand oder Parzellenbesitz stimmt möglicherweise nicht mit dem aktuellen Stand auf den Servern überein.
|
||||
</notification>
|
||||
<notification name="LargePrimAgentIntersect">
|
||||
Große Prims, die sich mit anderen Spielern überschneiden, können nicht erstellt werden. Bitte erneut versuchen, wenn sich die anderen Spieler bewegt haben.
|
||||
Große Prims, die sich mit anderen Einwohnern überschneiden, können nicht erstellt werden. Bitte erneut versuchen, wenn sich die anderen Einwohner fort bewegt haben.
|
||||
</notification>
|
||||
<notification name="PreferenceChatClearLog">
|
||||
Dadurch werden die Protokolle vorheriger Unterhaltungen und alle Backups dieser Datei gelöscht.
|
||||
|
|
|
|||
|
|
@ -96,6 +96,11 @@ um mehrere Mitglieder auszuwählen.
|
|||
<scroll_list.columns label="" name="action"/>
|
||||
</scroll_list>
|
||||
</panel>
|
||||
<panel name="members_header">
|
||||
<text_editor name="member_action_description">
|
||||
Diese Fähigkeit wird als „Mitglieder dieser Gruppe verweisen“ bezeichnet. Eigentümer können nur von anderen Eigentümern verwiesen werden.
|
||||
</text_editor>
|
||||
</panel>
|
||||
<panel name="roles_footer">
|
||||
<text name="static">
|
||||
Rolle:
|
||||
|
|
@ -121,6 +126,11 @@ um mehrere Mitglieder auszuwählen.
|
|||
<scroll_list.columns label="" name="action"/>
|
||||
</scroll_list>
|
||||
</panel>
|
||||
<panel name="roles_header">
|
||||
<text_editor name="role_action_description">
|
||||
Diese Fähigkeit wird als „Mitglieder dieser Gruppe verweisen“ bezeichnet. Eigentümer können nur von anderen Eigentümern verwiesen werden.
|
||||
</text_editor>
|
||||
</panel>
|
||||
<panel name="actions_footer">
|
||||
<text_editor name="action_description">
|
||||
Diese Fähigkeit heißt „Mitglieder aus dieser Gruppe werfen“. Eigentümer können nur von anderen Eigentümern hinausgeworfen werden.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<panel.string name="log_in_to_change">
|
||||
Anmelden, um Änderungen vorzunehmen
|
||||
</panel.string>
|
||||
<button label="Cache leeren" name="clear_cache" tool_tip="Bild bei Anmeldung, letzter Standort, Teleport-Liste, Internet- und Texturen-Cache löschen"/>
|
||||
<button label="Cache leeren" name="clear_cache" tool_tip="Anmeldungsbild, letzten Standort, Teleport-Liste, Internet- und Texturen-Cache löschen"/>
|
||||
<text name="cache_size_label_l">
|
||||
(Standorte, Bilder, Web, Suchverlauf)
|
||||
</text>
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@
|
|||
Web:
|
||||
</text>
|
||||
<radio_group name="preferred_browser_behavior">
|
||||
<radio_item label="Meinen Browser (Chrome, Firefox, IE) für alle Links verwenden" name="internal" tool_tip="Standard-Browser für Hilfe, Weblinks usw. verwenden. Im Vollbildmodus nicht empfohlen." value="0"/>
|
||||
<radio_item label="Integrierten Browser nur für Linden Lab-/Second Life-Links verwenden" name="external" tool_tip="Verwenden Sie den Standard-Webbrowser Ihres Systems für Hilfe, Weblinks usw. Der integrierte Browser wird nur für Linden Lab-/Second Life-Links verwendet." value="1"/>
|
||||
<radio_item label="Standard-Systembrowser für alle Links verwenden" name="internal" tool_tip="Standard-Browser für Hilfe, Weblinks usw. verwenden. Im Vollbildmodus nicht empfohlen." value="0"/>
|
||||
<radio_item label="Integrierten Browser nur für Second Life-Links verwenden" name="external" tool_tip="Standard-Systembrowser für Hilfe, Weblinks usw. verwenden. Der integrierte Browser wird nur für LindenLab-/Second Life-Links verwendet." value="1"/>
|
||||
<radio_item label="Integrierten Browser für alle Links verwenden" name="external_all" tool_tip="Integrierten Browser für Hilfe, Internetlinks, usw. verwenden. Der Browser wird als eigenständiges Fenster in [APP_NAME] geöffnet." value="2"/>
|
||||
</radio_group>
|
||||
<check_box initial_value="true" label="Plugins aktivieren" name="browser_plugins_enabled"/>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@
|
|||
<text name="title_animation">
|
||||
Animationen
|
||||
</text>
|
||||
<text name="title_model">
|
||||
Modelle
|
||||
</text>
|
||||
<text name="upload_help">
|
||||
Um einen Zielordner zu ändern, klicken Sie im Inventar mit der rechten Maustaste auf den Ordner und wählen Sie „Als Standard verwenden für“.
|
||||
</text>
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<role_actions>
|
||||
<action_set description="Diese Fähigkeiten ermöglichen das Hinzufügen und Entfernen von Mitgliedern sowie den Beitritt ohne Einladung." name="Membership">
|
||||
<action description="Personen in diese Gruppe einladen" longdescription="Leute in diese Gruppe mit der Schaltfläche „Einladen“ im Abschnitt „Rollen“ > Registerkarte „Mitglieder“ in die Gruppe einladen." name="member invite" value="1"/>
|
||||
<action description="Mitglieder aus dieser Gruppe werfen" longdescription="Leute aus dieser Gruppe mit der Schaltfläche „Hinauswerfen“ im Abschnitt „Rollen“ > Registerkarte „Mitglieder“ aus der Gruppe werfen. Ein Eigentümer kann jeden, außer einen anderen Eigentümer, ausschließen. Wenn Sie kein Eigentümer sind, können Sie ein Mitglied nur dann aus der Gruppe werfen, wenn es die Rolle Jeder inne hat, jedoch KEINE andere Rolle. Um Mitgliedern Rollen entziehen zu können, müssen Sie über die Fähigkeit „Mitgliedern Rollen entziehen“ verfügen." name="member eject" value="2"/>
|
||||
<action description="Personen in diese Gruppe einladen" longdescription="Andere Personen über die Schaltfläche "Einladen" im Bereich "Rollen und Mitglieder" > Registerkarte "Mitglieder" in diese Gruppe einladen." name="member invite" value="1"/>
|
||||
<action description="Mitglieder mit der Rolle "Jeder" dieser Gruppe verweisen" longdescription="Mitglieder mithilfe der Schaltfläche „Hinauswerfen“ im Abschnitt „Rollen und Mitglieder“ > Registerkarte „Mitglieder“ der Gruppe verweisen. Ein Eigentümer kann, mit Ausnahme eines anderen Eigentümers, jedes Mitglied ausschließen. Wenn Sie kein Eigentümer sind, können Sie ein Mitglied nur dann aus der Gruppe ausschließen, wenn es über die Rolle "Jeder", ansonsten jedoch über KEINE weitere Rolle verfügt. Um Mitgliedern Rollen entziehen zu können, müssen Sie über die Fähigkeit „Mitgliedern Rollen entziehen“ verfügen." name="member eject" value="2"/>
|
||||
<action description="Bannliste verwalten" longdescription="Gruppenmitglied das Verbannen/Zulassen von Einwohnern aus dieser Gruppe gestatten." name="allow ban" value="51"/>
|
||||
<action description="„Registrierung offen“ aktivieren/deaktivieren und „Beitrittsgebühr“ ändern." longdescription="„Registrierung offen“ aktivieren, um damit neue Mitglieder ohne Einladung beitreten können, und die „Beitrittsgebühr“ im Abschnitt „Allgemein“ ändern." name="member options" value="3"/>
|
||||
</action_set>
|
||||
<action_set description="Diese Fähigkeiten ermöglichen das Hinzufügen, Entfernen und Ändern von Gruppenrollen, das Zuweisen und Entfernen von Rollen und das Zuweisen von Fähigkeiten zu Rollen." name="Roles">
|
||||
<action description="Neue Rollen erstellen" longdescription="Neue Rollen im Abschnitt „Rollen“ > Registerkarte „Rollen“ erstellen." name="role create" value="4"/>
|
||||
<action description="Rollen löschen" longdescription="Neue Rollen im Abschnitt „Rollen“ > Registerkarte „Rollen“ löschen." name="role delete" value="5"/>
|
||||
<action description="Rollennamen, Titel, Beschreibungen und ob die Rolleninhaber öffentlich bekannt sein sollen, ändern." longdescription="Rollennamen, Titel, Beschreibungen und ob die Rolleninhaber öffentlich bekannt sein sollen, ändern. Dies wird im unteren Bereich des Abschnitts „Rollen“ > Registerkarte „Rollen“ eingestellt, nachdem eine Rolle ausgewählt wurde." name="role properties" value="6"/>
|
||||
<action description="Mitgliedern nur eigene Rollen zuweisen" longdescription="In der Liste „Rollen“ (Abschnitt „Rollen“ > Registerkarte „Mitglieder“) können Mitgliedern Rollen zugewiesen werden. Ein Mitglied mit dieser Fähigkeit kann anderen Mitgliedern nur die eigenen Rollen zuweisen." name="role assign member limited" value="7"/>
|
||||
<action description="Mitgliedern beliebige Rolle zuweisen" longdescription="Sie können Mitglieder jede beliebige Rolle der Liste „Rollen“ (Abschnitt „Rollen“ > Registerkarte „Mitglieder“) zuweisen. *WARNUNG* Jedes Mitglied in einer Rolle mit dieser Fähigkeit kann sich selbst und jedem anderen Mitglied (außer dem Eigentümer) Rollen mit weitreichenden Fähigkeiten zuweisen und damit fast Eigentümerrechte erreichen. Überlegen Sie sich gut, wem Sie diese Fähigkeit verleihen." name="role assign member" value="8"/>
|
||||
<action description="Mitgliedern Rollen entziehen" longdescription="In der Liste „Rollen“ (Abschnitt „Rollen“ > Registerkarte „Mitglieder“) können Mitgliedern Rollen abgenommen werden. Eigentümer können nicht entfernt werden." name="role remove member" value="9"/>
|
||||
<action description="Rollenfähigkeiten zuweisen und entfernen" longdescription="Fähigkeiten für jede Rolle können in der Liste „Zulässige Fähigkeiten" (Abschnitt „Rollen" > Registerkarte „Rollen“) zugewiesen und auch entzogen werden. *WARNUNG* Jedes Mitglied in einer Rolle mit dieser Fähigkeit kann sich selbst und jedem anderen Mitglied (außer dem Eigentümer) alle Fähigkeiten zuweisen und damit fast Eigentümerrechte erreichen. Überlegen Sie sich gut, wem Sie diese Fähigkeit verleihen." name="role change actions" value="10"/>
|
||||
<action description="Neue Rollen erstellen" longdescription="Erstellen neuer Rollen im Abschnitt „Rollen und Mitglieder“ > Registerkarte „Rollen“." name="role create" value="4"/>
|
||||
<action description="Rollen löschen" longdescription="Löschen von Rollen im Abschnitt „Rollen und Mitglieder“ > Registerkarte „Rollen“." name="role delete" value="5"/>
|
||||
<action description="Rollennamen, Titel, Beschreibungen und ob die Rolleninhaber öffentlich bekannt sein sollen, ändern." longdescription="Ändern von Rollennamen, Titeln, Beschreibungen und öffentlicher Bekanntgabe der Rolleninhaber. Dies wird im unteren Bereich des Abschnitts „Rollen und Mitglieder“ > Registerkarte „Rollen“ eingestellt, nachdem eine Rolle ausgewählt wurde." name="role properties" value="6"/>
|
||||
<action description="Mitgliedern nur eigene Rollen zuweisen" longdescription="In der Liste „Zugewiesene Rollen“ (Abschnitt „Rollen und Mitglieder“ > Registerkarte „Mitglieder“) können Mitgliedern Rollen zugewiesen werden. Ein Mitglied mit dieser Fähigkeit kann anderen Mitgliedern nur die eigene Rolle zuweisen." name="role assign member limited" value="7"/>
|
||||
<action description="Mitgliedern beliebige Rolle zuweisen" longdescription="Sie können Mitgliedern in der Liste „Zugewiesene Rollen“ (Abschnitt „Rollen und Mitglieder“ > Registerkarte „Mitglieder“) jede beliebige Rolle zuweisen.*WARNUNG* Jedes Mitglied in einer Rolle mit dieser Fähigkeit kann sich selbst und jedem anderen Mitglied (außer dem Eigentümer) Rollen mit weitreichenden Berechtigungen zuweisen und damit nahezu Eigentümerrechte erreichen. Überlegen Sie also genau, wem Sie diese Berechtigung erteilen." name="role assign member" value="8"/>
|
||||
<action description="Mitgliedern Rollen entziehen" longdescription="In der Liste „Zugewiesene Rollen“ (Abschnitt „Rollen und Mitglieder“ > Registerkarte „Mitglieder“) können Mitglieder aus Rollenzuweisungen entfernt werden. Eigentümer können nicht entfernt werden." name="role remove member" value="9"/>
|
||||
<action description="Rollenfähigkeiten zuweisen und entfernen" longdescription="In der Liste "Zulässige Fähigkeiten" (Bereich "Rollen und Mitglieder" > Registerkarte "Rollen") können für jede Rolle Fähigkeiten hinzugefügt und entfernt werden. *WARNUNG* Jedes Mitglied in einer Rolle mit dieser Fähigkeit kann sich selbst und jedem anderen Mitglied (außer dem Eigentümer) alle Fähigkeiten zuweisen und damit nahezu Eigentümerrechte erreichen. Überlegen Sie also genau, wem Sie diese Fähigkeit zuweisen." name="role change actions" value="10"/>
|
||||
</action_set>
|
||||
<action_set description="Diese Fähigkeiten ermöglichen es, die Gruppenidentität zu ändern, z. B. öffentliche Sichtbarkeit, Charta und Insignien." name="Group Identity">
|
||||
<action description="Charta, Insignien und „Im Web veröffentlichen“ ändern und festlegen, welche Mitglieder in der Gruppeninfo öffentlich sichtbar sind." longdescription="Charta, Insignien und „In Suche anzeigen" ändern. Diese Einstellungen werden im Abschnitt „Allgemein" vorgenommen." name="group change identity" value="11"/>
|
||||
|
|
|
|||
|
|
@ -502,7 +502,7 @@
|
|||
name="Buy Land..."
|
||||
width="130" />
|
||||
<button
|
||||
enabled="true"
|
||||
enabled="false"
|
||||
follows="left|top"
|
||||
height="23"
|
||||
label="Linden Sale"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater
|
||||
legacy_header_height="18"
|
||||
can_resize="true"
|
||||
height="412"
|
||||
layout="topleft"
|
||||
min_height="412"
|
||||
min_width="420"
|
||||
name="floater_auction"
|
||||
help_topic="floater_auction"
|
||||
title="START LINDEN LAND SALE"
|
||||
width="420">
|
||||
<floater.string
|
||||
name="already for sale">
|
||||
You cannot auction parcels which are already for sale.
|
||||
</floater.string>
|
||||
<icon
|
||||
bottom="280"
|
||||
follows="left|right|top|bottom"
|
||||
layout="topleft"
|
||||
left="4"
|
||||
name="snapshot_icon"
|
||||
right="-4"
|
||||
top="24" />
|
||||
<text
|
||||
follows="left|right|bottom"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="parcel_text"
|
||||
top_pad="12"
|
||||
width="400" />
|
||||
<check_box
|
||||
control_name="AuctionShowFence"
|
||||
follows="left|bottom"
|
||||
height="16"
|
||||
initial_value="true"
|
||||
label="Include yellow selection fence"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="fence_check"
|
||||
top_pad="12"
|
||||
width="199" />
|
||||
<button
|
||||
follows="left|bottom"
|
||||
height="20"
|
||||
label="Snapshot"
|
||||
label_selected="Snapshot"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="snapshot_btn"
|
||||
top_pad="4"
|
||||
width="150">
|
||||
<button.commit_callback
|
||||
function="ClickSnapshot" />
|
||||
</button>
|
||||
<button
|
||||
follows="left|bottom"
|
||||
height="20"
|
||||
label="Sell to Anyone"
|
||||
label_selected="Sell to Anyone"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="sell_to_anyone_btn"
|
||||
top_pad="4"
|
||||
width="150">
|
||||
<button.commit_callback
|
||||
function="ClickSellToAnyone" />
|
||||
</button>
|
||||
<button
|
||||
follows="left|bottom"
|
||||
height="20"
|
||||
label="Clear Settings"
|
||||
label_selected="Clear Settings"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="reset_parcel_btn"
|
||||
top_pad="4"
|
||||
width="150">
|
||||
<button.commit_callback
|
||||
function="ClickResetParcel" />
|
||||
</button>
|
||||
<button
|
||||
follows="left|bottom"
|
||||
height="20"
|
||||
label="Start Auction"
|
||||
label_selected="Start Auction"
|
||||
layout="topleft"
|
||||
left_pad="4"
|
||||
name="start_auction_btn"
|
||||
top_delta="0"
|
||||
width="150">
|
||||
<button.commit_callback
|
||||
function="ClickStartAuction" />
|
||||
</button>
|
||||
</floater>
|
||||
|
|
@ -1115,6 +1115,10 @@
|
|||
label="Zoom"
|
||||
name="Zoom"
|
||||
value="Zoom" />
|
||||
<combo_box.item
|
||||
label="None"
|
||||
name="None"
|
||||
value="None" />
|
||||
</combo_box>
|
||||
<check_box
|
||||
height="23"
|
||||
|
|
|
|||
|
|
@ -92,11 +92,24 @@
|
|||
shortcut="alt|shift|S"
|
||||
name="Sit Down Here">
|
||||
<menu_item_call.on_click
|
||||
function="Self.SitDown"
|
||||
parameter="" />
|
||||
function="Self.SitDown"/>
|
||||
<menu_item_call.on_visible
|
||||
function="Self.ShowSitDown"/>
|
||||
<menu_item_call.on_enable
|
||||
function="Self.EnableSitDown" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Stand Up"
|
||||
layout="topleft"
|
||||
shortcut="alt|shift|S"
|
||||
name="Stand up">
|
||||
<menu_item_call.on_click
|
||||
function="Self.StandUp"/>
|
||||
<menu_item_call.on_visible
|
||||
function="Self.EnableStandUp"/>
|
||||
<menu_item_call.on_enable
|
||||
function="Self.EnableStandUp" />
|
||||
</menu_item_call>
|
||||
<menu_item_check
|
||||
label="Fly"
|
||||
name="Fly"
|
||||
|
|
|
|||
|
|
@ -8102,6 +8102,8 @@ Failed to connect to [VOICE_CHANNEL_NAME], please try again later. You will now
|
|||
<unique/>
|
||||
One or more of your subscribed Voice Morphs has expired.
|
||||
[[URL] Click here] to renew your subscription.
|
||||
|
||||
If you are a Premium Member, [[PREMIUM_URL] click here] to receive your voice morphing perk.
|
||||
<tag>fail</tag>
|
||||
<tag>voice</tag>
|
||||
</notification>
|
||||
|
|
@ -8115,6 +8117,8 @@ One or more of your subscribed Voice Morphs has expired.
|
|||
<unique/>
|
||||
The active Voice Morph has expired, your normal voice settings have been applied.
|
||||
[[URL] Click here] to renew your subscription.
|
||||
|
||||
If you are a Premium Member, [[PREMIUM_URL] click here] to receive your voice morphing perk.
|
||||
<tag>fail</tag>
|
||||
<tag>voice</tag>
|
||||
</notification>
|
||||
|
|
@ -8128,6 +8132,8 @@ The active Voice Morph has expired, your normal voice settings have been applied
|
|||
<unique/>
|
||||
One or more of your Voice Morphs will expire in less than [INTERVAL] days.
|
||||
[[URL] Click here] to renew your subscription.
|
||||
|
||||
If you are a Premium Member, [[PREMIUM_URL] click here] to receive your voice morphing perk.
|
||||
<tag>fail</tag>
|
||||
<tag>voice</tag>
|
||||
</notification>
|
||||
|
|
@ -8260,6 +8266,11 @@ Failed to save appearance to XML.
|
|||
Failed to save snapshot to [PATH]: Disk is full. [NEED_MEMORY]KB is required but only [FREE_MEMORY]KB is free.
|
||||
</notification>
|
||||
|
||||
<notification icon="notifytip.tga"
|
||||
name="SnapshotToLocalDirNotExist" type="notifytip">
|
||||
Failed to save snapshot to [PATH]: Directory does not exist.
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="notifytip.tga"
|
||||
name="PresetNotSaved"
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@
|
|||
name="forgot_password_url">
|
||||
http://secondlife.com/account/request.php
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="sign_up_url">
|
||||
https://join.secondlife.com/
|
||||
</panel.string>
|
||||
<layout_stack
|
||||
follows="left|right|top"
|
||||
height="172"
|
||||
|
|
@ -149,7 +153,18 @@
|
|||
label="Select grid"
|
||||
layout="topleft"
|
||||
name="server_combo"
|
||||
width="149" />
|
||||
width="149" />
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifMedium"
|
||||
text_color="EmphasisColor"
|
||||
height="16"
|
||||
name="sign_up_text"
|
||||
left="778"
|
||||
bottom_delta="-10"
|
||||
width="200">
|
||||
Sign up
|
||||
</text>
|
||||
</layout_panel>
|
||||
<layout_panel
|
||||
height="172"
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@
|
|||
name="forgot_password_url">
|
||||
http://secondlife.com/account/request.php
|
||||
</panel.string>
|
||||
<panel.string
|
||||
name="sign_up_url">
|
||||
https://join.secondlife.com/
|
||||
</panel.string>
|
||||
<layout_stack
|
||||
follows="left|right|top|bottom"
|
||||
width="1024"
|
||||
|
|
@ -168,6 +172,17 @@
|
|||
width="200">
|
||||
Forgotten password
|
||||
</text>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifLarge"
|
||||
text_color="EmphasisColor"
|
||||
height="16"
|
||||
name="sign_up_text"
|
||||
left="432"
|
||||
top="34"
|
||||
width="200">
|
||||
Sign up
|
||||
</text>
|
||||
</layout_panel>
|
||||
<layout_panel
|
||||
height="100"
|
||||
|
|
|
|||
|
|
@ -292,10 +292,14 @@
|
|||
label="Open"
|
||||
name="Open"
|
||||
value="Open" />
|
||||
<combo_box.item
|
||||
label="Zoom"
|
||||
name="Zoom"
|
||||
value="Zoom" />
|
||||
<combo_box.item
|
||||
label="Zoom"
|
||||
name="Zoom"
|
||||
value="Zoom" />
|
||||
<combo_box.item
|
||||
label="None"
|
||||
name="None"
|
||||
value="None" />
|
||||
</combo_box>
|
||||
<panel
|
||||
border="false"
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
<text name="AvatarPhysicsDetailText">
|
||||
Bajo
|
||||
</text>
|
||||
<text name="ShadersText">
|
||||
<text name="HardwareText">
|
||||
Hardware
|
||||
</text>
|
||||
<slider label="Memoria para texturas (MB):" name="GraphicsCardTextureMemory" tool_tip="Cantidad de memoria asignada a las texturas. Por defecto es la memoria de la tarjeta de vídeo. Reducir esta cantidad puede mejorar el rendimiento, pero también hacer que las texturas se vean borrosas."/>
|
||||
|
|
@ -56,6 +56,9 @@
|
|||
<text name="antialiasing restart">
|
||||
(requiere reiniciar)
|
||||
</text>
|
||||
<text name="MeshText">
|
||||
Malla
|
||||
</text>
|
||||
<slider label="Detalle de la malla del terreno:" name="TerrainMeshDetail"/>
|
||||
<text name="TerrainMeshDetailText">
|
||||
Bajo
|
||||
|
|
@ -72,6 +75,9 @@
|
|||
<text name="FlexibleMeshDetailText">
|
||||
Bajo
|
||||
</text>
|
||||
<text name="ShadersText">
|
||||
Shaders
|
||||
</text>
|
||||
<check_box initial_value="true" label="Agua transparente" name="TransparentWater"/>
|
||||
<check_box initial_value="true" label="Efecto de relieve y brillo" name="BumpShiny"/>
|
||||
<check_box initial_value="true" label="Puntos de luz locales" name="LocalLights"/>
|
||||
|
|
@ -111,5 +117,6 @@
|
|||
<button label="Restablecer la configuración recomendada" name="Defaults"/>
|
||||
<button label="OK" label_selected="OK" name="OK"/>
|
||||
<button label="Cancelar" label_selected="Cancelar" name="Cancel"/>
|
||||
<check_box label="RenderAvatarMaxComplexity" name="RenderAvatarMaxNonImpostors"/>
|
||||
<check_box label="RenderAvatarMaxComplexity" name="RenderAvatarMaxComplexity"/>
|
||||
<check_box label="RenderAvatarMaxNonImpostors" name="RenderAvatarMaxNonImpostors"/>
|
||||
</floater>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
<menu_item_call label="No ignorar" name="unblock"/>
|
||||
<menu_item_check label="Bloquear la voz" name="BlockVoice"/>
|
||||
<menu_item_check label="Bloquear el texto" name="MuteText"/>
|
||||
<menu_item_check label="Bloquear partículas" name="MuteParticles"/>
|
||||
<menu_item_check label="Bloquear los sonidos de objeto" name="BlockObjectSounds"/>
|
||||
<menu_item_call label="Perfil..." name="profile"/>
|
||||
</toggleable_menu>
|
||||
|
|
|
|||
|
|
@ -4299,7 +4299,7 @@ Prueba a seleccionar un terreno más pequeño.
|
|||
Un error interno nos ha impedido actualizar tu visor correctamente. El saldo en L$ o las parcelas en propiedad presentadas en el visor podrían no coincidir con tu saldo real en los servidores.
|
||||
</notification>
|
||||
<notification name="LargePrimAgentIntersect">
|
||||
No se pueden crear prims grandes que intersectan a otros jugadores. Reinténtalo cuando se hayan movido otros jugadores.
|
||||
No se pudo crear primitivas grandes que se crucen con otros residentes. Por favor, vuelve a intentar cuando otros residentes se hayan desplazado.
|
||||
</notification>
|
||||
<notification name="PreferenceChatClearLog">
|
||||
Esto eliminará los registros de conversaciones anteriores y las copias de seguridad de ese archivo.
|
||||
|
|
|
|||
|
|
@ -91,6 +91,11 @@ Seleccione varios nombres manteniendo pulsada la tecla Ctrl y pulsando en cada u
|
|||
<scroll_list.columns label="" name="action"/>
|
||||
</scroll_list>
|
||||
</panel>
|
||||
<panel name="members_header">
|
||||
<text_editor name="member_action_description">
|
||||
Esta habilidad es 'Expulsar miembros de este grupo'. Sólo un propietario puede expulsar a otro propietario.
|
||||
</text_editor>
|
||||
</panel>
|
||||
<panel name="roles_footer">
|
||||
<text name="static">
|
||||
Nombre del rol
|
||||
|
|
@ -117,6 +122,11 @@ Seleccione varios nombres manteniendo pulsada la tecla Ctrl y pulsando en cada u
|
|||
<scroll_list.columns label="" name="action"/>
|
||||
</scroll_list>
|
||||
</panel>
|
||||
<panel name="roles_header">
|
||||
<text_editor name="role_action_description">
|
||||
Esta habilidad es 'Expulsar miembros de este grupo'. Sólo un propietario puede expulsar a otro propietario.
|
||||
</text_editor>
|
||||
</panel>
|
||||
<panel name="actions_footer">
|
||||
<text_editor name="action_description">
|
||||
Esta capacidad es la de 'Expulsar miembros de este grupo'. Sólo un propietario puede expulsar a otro.
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@
|
|||
Web:
|
||||
</text>
|
||||
<radio_group name="preferred_browser_behavior">
|
||||
<radio_item label="Usar mi navegador (Chrome, Firefox, IE) para todos los enlaces" name="internal" tool_tip="Usa el navegador predeterminado para obtener ayuda, visitar enlaces web, etc. No es aconsejable si estás a pantalla completa." value="0"/>
|
||||
<radio_item label="Usar el navegador integrado solo para los enlaces de Second Life" name="external" tool_tip="Usa el navegador predeterminado del sistema para obtener ayuda, visitar enlaces web, etc. El navegador integrado solo se utilizará para los enlaces de LindenLab/SecondLife." value="1"/>
|
||||
<radio_item label="Usar el navegador incorporado para todos los enlaces" name="internal" tool_tip="Usa el navegador predeterminado para obtener ayuda, visitar enlaces web, etc. No es aconsejable si estás a pantalla completa." value="0"/>
|
||||
<radio_item label="Usar el navegador integrado solo para los enlaces de Second Life" name="external" tool_tip="Usa el navegador predeterminado para obtener ayuda, visitar enlaces web, etc. Se utilizará el navegador incorporado sólo para los enlaces LindenLab/Second Life." value="1"/>
|
||||
<radio_item label="Usar el navegador incorporado para todos los vínculos" name="external_all" tool_tip="Usa el navegador incorporado para ayuda, enlaces web, etc. Este navegador se abre en una nueva ventana dentro de [APP_NAME]." value="2"/>
|
||||
</radio_group>
|
||||
<check_box initial_value="true" label="Activar plugins" name="browser_plugins_enabled"/>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@
|
|||
<text name="title_animation">
|
||||
Animaciones
|
||||
</text>
|
||||
<text name="title_model">
|
||||
Modelos
|
||||
</text>
|
||||
<text name="upload_help">
|
||||
Para cambiar una carpeta de destino, pulsa con el botón derecho en ella en el inventario y elige
|
||||
"Usar como valor predeterminado para"
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<role_actions>
|
||||
<action_set description="Estas capacidades incluyen poderes para añadir o quitar miembros del grupo, y para pemitir que se sumen nuevos miembros sin necesidad de invitación." name="Membership">
|
||||
<action description="Invitar personas al grupo" longdescription="Invitar a gente a este grupo usando el botón 'Invitar' en la sección Roles > pestaña Miembros." name="member invite" value="1"/>
|
||||
<action description="Expulsar a miembros del grupo" longdescription="Expulsar a miembros de este grupo usando el botón 'Expulsar' en la sección Roles > pestaña Miembros. Un propietario puede expulsar a cualquiera, excepto a otro propietario. Si no eres un propietario, un miembro puede ser expulsado única y exclusivamente si está en el rol de Cualquiera y NO en otros roles. Para quitar roles a los miembros, tienes que tener la capacidad de 'Quitar roles a los miembros'." name="member eject" value="2"/>
|
||||
<action description="Invitar personas al grupo" longdescription="Invitar a gente a este grupo usando el botón 'Invitar' en la sección Roles y Miembros > pestaña Miembros." name="member invite" value="1"/>
|
||||
<action description="Expulsar miembros que pertenecen al rol 'Todos' en este grupo." longdescription="Expulsar a miembros de este grupo usando el botón 'Expulsar' en la sección Roles y Miembros > pestaña Miembros. Un propietario puede expulsar a cualquiera, excepto a otro propietario. Si no eres un propietario, un miembro puede ser expulsado única y exclusivamente si está en el rol de Todos y NO en otros roles. Para quitar roles a los miembros, tienes que tener la capacidad de 'Quitar roles a los miembros'." name="member eject" value="2"/>
|
||||
<action description="Administra la lista de expulsados" longdescription="Permite que el miembro del grupo expulse a residentes de este grupo o los readmita." name="allow ban" value="51"/>
|
||||
<action description="Cambiar 'Inscripción abierta' y 'Cuota de inscripción'" longdescription="En la sección General, cambiar la 'Inscripción abierta' -que permite entrar al grupo sin invitación- y la 'Cuota de inscripción'." name="member options" value="3"/>
|
||||
</action_set>
|
||||
<action_set description="Estas habilidades incluyen el poder añadir, quitar y cambiar roles, asignarlos a miembros, y darles capacidades." name="Roles">
|
||||
<action description="Crear nuevos roles" longdescription="Crear roles nuevos en la sección Roles > pestaña Roles." name="role create" value="4"/>
|
||||
<action description="Borrar roles" longdescription="Borrar roles en la sección Roles > pestaña Roles." name="role delete" value="5"/>
|
||||
<action description="Cambiar el nombre, la etiqueta y la descripción de los roles, así como qué miembros se muestran públicamente en ese rol" longdescription="Cambiar el nombre, la etiqueta y la descripción de los roles, así como qué miembros se muestran públicamente en ese rol. Se hace seleccionando el rol, dentro de la sección Roles > pestaña Roles." name="role properties" value="6"/>
|
||||
<action description="Designar miembros para el rol del asignador" longdescription="Añadir miembros a los roles en la lista de Roles asignados (sección Roles > pestaña Miembros). Un miembro con esta capacidad sólo puede añadir miembros a los roles que tenga él mismo." name="role assign member limited" value="7"/>
|
||||
<action description="Designar miembros para cualquier rol" longdescription="Designar miembros para cualquier rol en la lista de Roles asignados (sección Roles > pestaña Miembros). *AVISO* Todos los miembros que tengan un rol con esta capacidad podrán asignarse a sí mismos -y a otros miembros que no sean los propietarios- roles con mayores poderes de los que actualmente tienen. Potencialmente, podrían elevarse hasta poderes cercanos a los del propietario. Asegúrate de lo que estás haciendo antes de otorgar esta capacidad." name="role assign member" value="8"/>
|
||||
<action description="Quitar capacidades a los miembros" longdescription="Quitar miembros de los roles en la lista de roles asignados (sección Roles > pestaña Miembros). No se puede quitar a los Propietarios." name="role remove member" value="9"/>
|
||||
<action description="Añadir o quitar capacidades a los roles" longdescription="Asignar y quitar capacidades a cada rol en la lista de capacidades permitidas (sección Roles > pestaña Roles). *AVISO* Todos los miembros que tengan un rol con esta capacidad podrán asignarse a sí mismos -y a otros miembros que no sean los propietarios- todas las capacidades. Potencialmente, podrían elevarse hasta poderes cercanos a los del propietario. Asegúrate de lo que estás haciendo antes de otorgar esta capacidad." name="role change actions" value="10"/>
|
||||
<action description="Crear nuevos roles" longdescription="Crear roles nuevos en la sección Roles y Miembros > pestaña Roles." name="role create" value="4"/>
|
||||
<action description="Borrar roles" longdescription="Borrar roles en la sección Roles y Miembros > pestaña Roles." name="role delete" value="5"/>
|
||||
<action description="Cambiar el nombre, la etiqueta y la descripción de los roles, así como qué miembros se muestran públicamente en ese rol" longdescription="Cambiar el nombre, la etiqueta y la descripción de los roles, y si los miembros se muestran públicamente en ese rol. Esto se hace al final de la sección Roles y Miembros > pestaña Roles, luego de seleccionar un Rol." name="role properties" value="6"/>
|
||||
<action description="Designar miembros para el rol del asignador" longdescription="Añadir miembros a los roles en la lista de Roles asignados (sección Roles y Miembros > pestaña Miembros). Un miembro con esta capacidad sólo puede añadir miembros a los roles que tenga él mismo." name="role assign member limited" value="7"/>
|
||||
<action description="Designar miembros para cualquier rol" longdescription="Asignar miembros a cualquier rol en la lista de roles asignados (Sección Roles y miembros > pestaña Miembros) *AVISO* Todos los miembros que tengan un rol con esta capacidad podrán asignarse a sí mismos -y a otros miembros que no sean los propietarios- roles con mayores poderes de los que actualmente tienen. Potencialmente, podrían elevarse hasta poderes cercanos a los del propietario. Asegúrate de lo que estás haciendo antes de otorgar esta capacidad." name="role assign member" value="8"/>
|
||||
<action description="Quitar capacidades a los miembros" longdescription="Quitar miembros de los roles en la lista de roles asignados (sección Roles y Miembros > pestaña Miembros). No se puede quitar a los Propietarios." name="role remove member" value="9"/>
|
||||
<action description="Añadir o quitar capacidades a los roles" longdescription="Asignar y quitar habilidades para cada Rol en la lista de capacidades permitidas (Sección Roles y Miembros > pestaña Roles). *AVISO* Todos los miembros que tengan un rol con esta capacidad podrán asignarse a sí mismos -y a otros miembros que no sean los propietarios- todas las capacidades. Potencialmente, podrían elevarse hasta poderes cercanos a los del propietario. Asegúrate de lo que estás haciendo antes de otorgar esta capacidad." name="role change actions" value="10"/>
|
||||
</action_set>
|
||||
<action_set description="Estas capacidades incluyen poderes para modificar la identidad del grupo, como su visibilidad pública, su carta o su emblema." name="Group Identity">
|
||||
<action description="Cambiar la carta, emblema, 'Mostrar en la búsqueda', y qué miembros serán visibles en la información del grupo" longdescription="Cambia la carta, emblema y 'Mostrar en la búsqueda'. Se hace en la sección General." name="group change identity" value="11"/>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
<text name="AvatarPhysicsDetailText">
|
||||
Faible
|
||||
</text>
|
||||
<text name="ShadersText">
|
||||
<text name="HardwareText">
|
||||
Matériel
|
||||
</text>
|
||||
<slider label="Mémoire textures (Mo) :" name="GraphicsCardTextureMemory" tool_tip="Quantité de mémoire à affecter aux textures. Utilise la mémoire de la carte vidéo par défaut. Si vous réduisez ce paramètre, cela peut améliorer les performances, mais les textures risquent d’être floues."/>
|
||||
|
|
@ -56,6 +56,9 @@
|
|||
<text name="antialiasing restart">
|
||||
(redémarrage requis)
|
||||
</text>
|
||||
<text name="MeshText">
|
||||
Maillage
|
||||
</text>
|
||||
<slider label="Détails des rendus des terrains :" name="TerrainMeshDetail"/>
|
||||
<text name="TerrainMeshDetailText">
|
||||
Faible
|
||||
|
|
@ -72,6 +75,9 @@
|
|||
<text name="FlexibleMeshDetailText">
|
||||
Faible
|
||||
</text>
|
||||
<text name="ShadersText">
|
||||
Effets
|
||||
</text>
|
||||
<check_box initial_value="true" label="Eau transparente" name="TransparentWater"/>
|
||||
<check_box initial_value="true" label="Placage de relief et brillance" name="BumpShiny"/>
|
||||
<check_box initial_value="true" label="Lumières locales" name="LocalLights"/>
|
||||
|
|
@ -111,5 +117,6 @@
|
|||
<button label="Réinitialiser les paramètres recommandés" name="Defaults"/>
|
||||
<button label="OK" label_selected="OK" name="OK"/>
|
||||
<button label="Annuler" label_selected="Annuler" name="Cancel"/>
|
||||
<check_box label="RenderAvatarMaxComplexity" name="RenderAvatarMaxNonImpostors"/>
|
||||
<check_box label="RenderAvatarMaxComplexity" name="RenderAvatarMaxComplexity"/>
|
||||
<check_box label="RenderAvatarMaxNonImpostors" name="RenderAvatarMaxNonImpostors"/>
|
||||
</floater>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
<menu_item_call label="Ne plus ignorer" name="unblock"/>
|
||||
<menu_item_check label="Bloquer le chat vocal" name="BlockVoice"/>
|
||||
<menu_item_check label="Ignorer le texte" name="MuteText"/>
|
||||
<menu_item_check label="Ignorez les particules" name="MuteParticles"/>
|
||||
<menu_item_check label="Bloquer les sons des objets" name="BlockObjectSounds"/>
|
||||
<menu_item_call label="Profil..." name="profile"/>
|
||||
</toggleable_menu>
|
||||
|
|
|
|||
|
|
@ -4302,7 +4302,7 @@ Veuillez sélectionner un terrain plus petit.
|
|||
Une erreur interne nous a empêchés de mettre votre client à jour correctement. Le solde de L$ et le patrimoine affichés dans votre client peuvent ne pas correspondre à votre solde réel sur les serveurs.
|
||||
</notification>
|
||||
<notification name="LargePrimAgentIntersect">
|
||||
Impossible de créer de grandes prims qui coupent d'autres joueurs. Réessayez une fois que les autres joueurs se seront déplacés.
|
||||
Impossible de créer de grands prims qui rejoignent d'autres résidents. Veuillez essayer à nouveau lorsque les autres résidents seront partis.
|
||||
</notification>
|
||||
<notification name="PreferenceChatClearLog">
|
||||
Cela supprimera les journaux des conversations précédentes, ainsi que toute copie de sauvegarde de ce fichier.
|
||||
|
|
|
|||
|
|
@ -95,6 +95,11 @@ Pour sélectionner plusieurs membres, cliquez sur leurs noms en maintenant la to
|
|||
<scroll_list.columns label="" name="action"/>
|
||||
</scroll_list>
|
||||
</panel>
|
||||
<panel name="members_header">
|
||||
<text_editor name="member_action_description">
|
||||
Ce pouvoir permet « d'expulser des membres de ce groupe ». Seul un propriétaire peut expulser un autre propriétaire.
|
||||
</text_editor>
|
||||
</panel>
|
||||
<panel name="roles_footer">
|
||||
<text name="static">
|
||||
Nom du rôle
|
||||
|
|
@ -120,6 +125,11 @@ Pour sélectionner plusieurs membres, cliquez sur leurs noms en maintenant la to
|
|||
<scroll_list.columns label="" name="action"/>
|
||||
</scroll_list>
|
||||
</panel>
|
||||
<panel name="roles_header">
|
||||
<text_editor name="role_action_description">
|
||||
Ce pouvoir permet « d'expulser des membres de ce groupe ». Seul un propriétaire peut expulser un autre propriétaire.
|
||||
</text_editor>
|
||||
</panel>
|
||||
<panel name="actions_footer">
|
||||
<text_editor name="action_description">
|
||||
Ce pouvoir permet d'expulser des membres du groupe. Seul un propriétaire peut expulser un autre propriétaire.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<panel.string name="log_in_to_change">
|
||||
se connecter pour changer
|
||||
</panel.string>
|
||||
<button label="Vider l'historique" name="clear_cache" tool_tip="Effacer le cache de l'image de connexion, du dernier lieu, de l'historique des téléportations, Web et de texture."/>
|
||||
<button label="Vider l'historique" name="clear_cache" tool_tip="Effacez le cache de l'image de connexion, du dernier lieu, de l'historique des téléportations, du Web et des textures."/>
|
||||
<text name="cache_size_label_l">
|
||||
(endroits, images, web, historique des recherches)
|
||||
</text>
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@
|
|||
Web :
|
||||
</text>
|
||||
<radio_group name="preferred_browser_behavior">
|
||||
<radio_item label="Utiliser mon navigateur (Chrome, Firefox, IE) pour tous les liens" name="internal" tool_tip="Utiliser le navigateur web système par défaut pour l'aide, les liens, etc. Non recommandé en mode plein écran." value="0"/>
|
||||
<radio_item label="Utiliser le navigateur intégré pour les liens Second Life uniquement" name="external" tool_tip="Utilisez le navigateur web système par défaut pour l'aide, les liens Web, etc. Le navigateur intégré sera uniquement utilisé pour les liens LindenLab/SecondLife." value="1"/>
|
||||
<radio_item label="Utiliser le navigateur intégré pour tous les liens" name="external_all" tool_tip="Utilisez le navigateur intégré pour obtenir de l’aide, ouvrir des liens etc. Ce navigateur s’ouvre dans [APP_NAME]." value="2"/>
|
||||
<radio_item label="Utilisez le navigateur intégré par défaut pour tous les liens" name="internal" tool_tip="Utiliser le navigateur web système par défaut pour l'aide, les liens, etc. Non recommandé en mode plein écran." value="0"/>
|
||||
<radio_item label="Utilisez le navigateur intégré pour les liens Second Life uniquement" name="external" tool_tip="Utilisez le navigateur web système par défaut pour trouver de l'aide, les liens web, etc. Le navigateur intégré ne sera utilisé que pour les liens LindenLab / SeconLife." value="1"/>
|
||||
<radio_item label="Utilisez le navigateur intégré pour tous les liens" name="external_all" tool_tip="Utilisez le navigateur intégré pour obtenir de l’aide, ouvrir des liens etc. Ce navigateur s’ouvre dans [APP_NAME]." value="2"/>
|
||||
</radio_group>
|
||||
<check_box initial_value="true" label="Activer les plugins" name="browser_plugins_enabled"/>
|
||||
<check_box initial_value="true" label="Accepter les cookies" name="cookies_enabled"/>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@
|
|||
<text name="title_animation">
|
||||
Animations
|
||||
</text>
|
||||
<text name="title_model">
|
||||
Modèles
|
||||
</text>
|
||||
<text name="upload_help">
|
||||
Pour modifier un dossier de destination, cliquez-droit sur ce dossier dans l’inventaire et faites votre choix
|
||||
"Utiliser comme défaut pour"
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<role_actions>
|
||||
<action_set description="Ces pouvoirs permettent d'ajouter et de supprimer des membres du groupe et permettent aux nouveaux membres de rejoindre le groupe sans recevoir d'invitation." name="Membership">
|
||||
<action description="Inviter des membres dans ce groupe" longdescription="Invitez des personnes à rejoindre ce groupe en utilisant le bouton Inviter dans l'onglet Membres de la section Rôles." name="member invite" value="1"/>
|
||||
<action description="Expulser des membres du groupe" longdescription="Expulsez des personnes de ce groupe en utilisant le bouton Expulser dans l'onglet Membres de la section Rôles. Un propriétaire peut expulser tout le monde à l'exception des autres propriétaires. Si vous n'êtes pas propriétaire, vous pouvez expulser un membre d'un groupe uniquement si il n'a que le rôle Tous et AUCUN autre rôle. Pour supprimer des membres des rôles, vous devez disposer du pouvoir correspondant." name="member eject" value="2"/>
|
||||
<action description="Inviter des membres dans ce groupe" longdescription="Invitez des personnes à rejoindre ce groupe en utilisant le bouton « Inviter » dans la section Rôles et membres > onglet Membres" name="member invite" value="1"/>
|
||||
<action description="Expulser les Membres appartenant du rôle « Tous » de ce groupe" longdescription="Expulsez des personnes de ce groupe en utilisant le bouton « Expulser » dans la section Rôles et membres > onglet Membres Un propriétaire peut expulser tout le monde à l’exception des autres propriétaires. Si vous n’êtes pas propriétaire, vous pouvez expulser un membre d’un groupe si, et uniquement s'il n’a que le rôle Tous et AUCUN autre rôle. Pour supprimer des membres des rôles, vous devez disposer du pouvoir « Supprimer des membres des rôles »" name="member eject" value="2"/>
|
||||
<action description="Gérer la liste des résidents bannis" longdescription="Permet au membre du groupe de bannir / d'annuler le bannissement des résidents de ce groupe." name="allow ban" value="51"/>
|
||||
<action description="Activer Inscription libre et modifier les frais d'inscription" longdescription="Activez Inscription libre pour permettre aux nouveaux membres de s'inscrire sans invitation, et changez les frais d'inscription dans la section Général." name="member options" value="3"/>
|
||||
</action_set>
|
||||
<action_set description="Ces pouvoirs permettent d'ajouter, de supprimer et de modifier les rôles dans le groupe et d'y assigner des membres et des pouvoirs." name="Roles">
|
||||
<action description="Créer des rôles" longdescription="Créez de nouveaux rôles dans l'onglet Rôles de la section Rôles." name="role create" value="4"/>
|
||||
<action description="Supprimer des rôles" longdescription="Supprimez des rôles dans l'onglet Rôles de la section Rôles." name="role delete" value="5"/>
|
||||
<action description="Changer les noms, les titres et les descriptions des rôles et indiquer si les membres des rôles sont rendus publics" longdescription="Changez les noms, les titres et les descriptions des rôles, et indiquez si les membres des rôles sont rendus publics. Vous pouvez le faire au bas de l'onglet Rôles dans la section Rôles, après avoir sélectionné un rôle." name="role properties" value="6"/>
|
||||
<action description="Attribuer des rôles limités" longdescription="Assignez des membres aux rôles dans la liste Rôles assignés (section Rôles > onglet Membres). Un membre avec ce pouvoir peut uniquement ajouter des membres à un rôle dans lequel le responsable de l'assignation est déjà présent." name="role assign member limited" value="7"/>
|
||||
<action description="Attribuer tous les rôles" longdescription="Assignez des membres à n'importe quel rôle dans la liste Rôles assignés (section Rôles > onglet Membres). *AVERTISSEMENT* Tout membre disposant de ce pouvoir peut s'assigner lui-même, ainsi que tout autre membre non-propriétaire, à des rôles disposant de pouvoirs plus importants, et accéder potentiellement à des pouvoirs proches de ceux d'un propriétaire. Assurez-vous de bien comprendre ce que vous faites avant d'attribuer ce pouvoir." name="role assign member" value="8"/>
|
||||
<action description="Destituer des membres de leurs rôles" longdescription="Supprimez des membres des rôles dans la liste Rôles assignés (section Rôles > onglet Membres). Les propriétaires ne peuvent pas être supprimés." name="role remove member" value="9"/>
|
||||
<action description="Modifier les pouvoirs d'un rôle" longdescription="Attribuez et supprimez des pouvoirs pour chaque rôle dans la liste Pouvoirs attribués (section Rôles > onglet Rôles). *AVERTISSEMENT* Tout membre dans un rôle avec ce pouvoir peut s'attribuer à lui-même, ainsi qu'à tout autre membre non-propriétaire, tous les pouvoirs, et accéder potentiellement à des pouvoirs proches de ceux d'un propriétaire. Assurez-vous de bien comprendre ce que vous faites avant d'attribuer ce pouvoir." name="role change actions" value="10"/>
|
||||
<action description="Créer des rôles" longdescription="Créez de nouveaux rôles dans la section Rôles et membres > onglet Rôles" name="role create" value="4"/>
|
||||
<action description="Supprimer des rôles" longdescription="Supprimez des rôles dans la section Rôles et membres > onglet Rôles" name="role delete" value="5"/>
|
||||
<action description="Changer les noms, les titres et les descriptions des rôles et indiquer si les membres des rôles sont rendus publics" longdescription="Changez les noms, les titres et les descriptions des rôles, et indiquez si les membres des rôles sont rendus publics. Vous pouvez le faire au bas de la section Rôles et membres > onglet Rôles après avoir sélectionné un rôle." name="role properties" value="6"/>
|
||||
<action description="Attribuer des rôles limités" longdescription="Assignez des membres aux rôles dans la liste Rôles assignés (section Rôles et membres > onglet Membres). Un membre avec ce pouvoir peut uniquement ajouter des membres à un rôle dans lequel le responsable de l’assignation est déjà présent." name="role assign member limited" value="7"/>
|
||||
<action description="Attribuer tous les rôles" longdescription="Attribuez aux membres tout rôle dans la liste des Rôles assignés (Section Rôles et membres > onglet Membres). AVERTISSEMENT* Tout membre disposant de ce pouvoir peut s’assigner lui-même, ainsi que tout autre membre non-propriétaire, à des rôles disposant de pouvoirs plus importants que ceux dont ils disposent actuellement, et accéder potentiellement à des pouvoirs proches de ceux d'un propriétaire. Assurez-vous de bien comprendre ce que vous faites avant d'attribuer ce pouvoir." name="role assign member" value="8"/>
|
||||
<action description="Destituer des membres de leurs rôles" longdescription="Supprimez des membres des rôles dans la liste Rôles assignés (section Rôles et membres > onglet Membres). Les propriétaires ne peuvent pas être supprimés." name="role remove member" value="9"/>
|
||||
<action description="Modifier les pouvoirs d'un rôle" longdescription="Attribuez et Supprimez des pouvoirs pour chaque rôle figurant dans la liste Pouvoirs assignés (Section Rôles et membres > onglet Rôles). *AVERTISSEMENT* Tout membre dans un rôle avec ce pouvoir peut s'attribuer à lui-même, ainsi qu'à tout autre membre non-propriétaire, tous les pouvoirs, et accéder potentiellement à des pouvoirs proches de ceux d'un propriétaire. Assurez-vous de bien comprendre ce que vous faites avant d'attribuer ce pouvoir." name="role change actions" value="10"/>
|
||||
</action_set>
|
||||
<action_set description="Ces pouvoirs permettent de modifier le profil public du groupe, sa charte et son logo." name="Group Identity">
|
||||
<action description="Modifier le profil public du groupe" longdescription="Modifiez la charte, le logo et l'affichage dans les résultats de recherche. Vous pouvez faire cela dans la section Général." name="group change identity" value="11"/>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
<text name="AvatarPhysicsDetailText">
|
||||
Basso
|
||||
</text>
|
||||
<text name="ShadersText">
|
||||
<text name="HardwareText">
|
||||
Hardware
|
||||
</text>
|
||||
<slider label="Memoria texture (MB):" name="GraphicsCardTextureMemory" tool_tip="Spazio di memoria da assegnare alle texture. Utilizza la memoria della scheda video come impostazione predefinita. La riduzione di questa impostazione potrebbe migliorare il rendimento ma potrebbe anche rendere le texture poco definite."/>
|
||||
|
|
@ -56,6 +56,9 @@
|
|||
<text name="antialiasing restart">
|
||||
(richiede il riavvio)
|
||||
</text>
|
||||
<text name="MeshText">
|
||||
Mesh
|
||||
</text>
|
||||
<slider label="Dettagli mesh terreno:" name="TerrainMeshDetail"/>
|
||||
<text name="TerrainMeshDetailText">
|
||||
Basso
|
||||
|
|
@ -72,6 +75,9 @@
|
|||
<text name="FlexibleMeshDetailText">
|
||||
Basso
|
||||
</text>
|
||||
<text name="ShadersText">
|
||||
Shader
|
||||
</text>
|
||||
<check_box initial_value="true" label="Acqua trasparente" name="TransparentWater"/>
|
||||
<check_box initial_value="true" label="Mappatura urti e brillantezza" name="BumpShiny"/>
|
||||
<check_box initial_value="true" label="Luci locali" name="LocalLights"/>
|
||||
|
|
@ -111,5 +117,6 @@
|
|||
<button label="Ripristina impostazioni consigliate" name="Defaults"/>
|
||||
<button label="OK" label_selected="OK" name="OK"/>
|
||||
<button label="Annulla" label_selected="Annulla" name="Cancel"/>
|
||||
<check_box label="RenderAvatarMaxComplexity" name="RenderAvatarMaxNonImpostors"/>
|
||||
<check_box label="RenderAvatarMaxComplexity" name="RenderAvatarMaxComplexity"/>
|
||||
<check_box label="RenderAvatarMaxNonImpostors" name="RenderAvatarMaxNonImpostors"/>
|
||||
</floater>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
<menu_item_call label="Sblocca" name="unblock"/>
|
||||
<menu_item_check label="Blocca voce" name="BlockVoice"/>
|
||||
<menu_item_check label="Blocca testo" name="MuteText"/>
|
||||
<menu_item_check label="Blocca Particelle" name="MuteParticles"/>
|
||||
<menu_item_check label="Blocca suoni oggetto" name="BlockObjectSounds"/>
|
||||
<menu_item_call label="Profilo..." name="profile"/>
|
||||
</toggleable_menu>
|
||||
|
|
|
|||
|
|
@ -4301,7 +4301,7 @@ Prova a selezionare un pezzo di terreno più piccolo.
|
|||
Un errore interno ha impedito l'aggiornamento del Viewer. Il saldo in L$ o i lotti posseduti mostrati nel Viewer potrebbero non corrispondere ai valori correnti sui server.
|
||||
</notification>
|
||||
<notification name="LargePrimAgentIntersect">
|
||||
Non puoi creare prim grandi che intersecano altri giocatori. Riprova quando gli altri giocatori si sono spostati.
|
||||
Impossibile creare prim larghi che si intersechino con altri residenti. Si prega di riprovare quando gli altri residenti si saranno mossi.
|
||||
</notification>
|
||||
<notification name="PreferenceChatClearLog">
|
||||
Verranno cancellati i registri delle conversazioni precedenti e tutti gli eventuali backup di quel file.
|
||||
|
|
|
|||
|
|
@ -82,6 +82,11 @@ cliccando sui loro nomi.
|
|||
</text>
|
||||
<scroll_list name="member_allowed_actions" tool_tip="Per i dettagli di ogni abilità consentita vedi la scheda abilità."/>
|
||||
</panel>
|
||||
<panel name="members_header">
|
||||
<text_editor name="member_action_description">
|
||||
Questa abilità è “Espelli membri da questo gruppo”. Solo un proprietario può espellere un altro proprietario.
|
||||
</text_editor>
|
||||
</panel>
|
||||
<panel name="roles_footer">
|
||||
<text name="static">
|
||||
Nome del ruolo
|
||||
|
|
@ -104,6 +109,11 @@ cliccando sui loro nomi.
|
|||
</text>
|
||||
<scroll_list name="role_allowed_actions" tool_tip="Per i dettagli di ogni abilità consentita vedi la scheda abilità."/>
|
||||
</panel>
|
||||
<panel name="roles_header">
|
||||
<text_editor name="role_action_description">
|
||||
Questa abilità è “Espelli membri da questo gruppo”. Solo un proprietario può espellere un altro proprietario.
|
||||
</text_editor>
|
||||
</panel>
|
||||
<panel name="actions_footer">
|
||||
<text_editor name="action_description">
|
||||
Questa abilità è 'Espelli i membri dal gruppo'. Solo un Capogruppo puo espellere un'altro Capogruppo.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<panel.string name="log_in_to_change">
|
||||
accedi per cambiare
|
||||
</panel.string>
|
||||
<button label="Pulisci la cronologia" name="clear_cache" tool_tip="Elimina immagine login, ultimo luogo, cronologia teleport, web e texture cache"/>
|
||||
<button label="Pulisci la cronologia" name="clear_cache" tool_tip="Elimina immagine login, ultimo luogo, cronologia teletrasporto, cache web e texture"/>
|
||||
<text name="cache_size_label_l">
|
||||
(Luoghi, immagini, web, cronologia ricerche)
|
||||
</text>
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue