EFFECTIVE MERGE: svn merge -r 68118:68999 svn+ssh://svn/svn/linden/branches/maintenance
ACTUAL MERGE: svn merge -r 69685:69687 svn+ssh://svn/svn/linden/branches/release-r69649-maintenance-sync EQUIVALENT TO: svn merge -r 68118:69663 svn+ssh://svn/svn/linden/branches/maintenance-r68999master
parent
b3d807d5ff
commit
13c391f198
|
|
@ -1,32 +1,49 @@
|
|||
Linden Lab would like to acknowledge source code contributions from the
|
||||
following residents. The Second Life resident name is given below,
|
||||
along with the issue identifier corresponding to the patches we've
|
||||
received from them. To see more about these contributions, visit
|
||||
http://jira.secondlife.com/ and enter the issue identifier.
|
||||
received from them. To see more about these contributions, visit the
|
||||
browsable version: http://wiki.secondlife.com/wiki/Source_contributions
|
||||
|
||||
Able Whitman
|
||||
VWR-650
|
||||
VWR-1460
|
||||
VWR-1691
|
||||
Alejandro Rosenthal
|
||||
VWR-1184
|
||||
Alissa Sabre
|
||||
VWR-81
|
||||
VWR-83
|
||||
VWR-109
|
||||
VWR-157
|
||||
VWR-171
|
||||
VWR-177
|
||||
VWR-213
|
||||
VWR-251
|
||||
VWR-286
|
||||
VWR-414
|
||||
VWR-415
|
||||
VWR-459
|
||||
VWR-606
|
||||
VWR-652
|
||||
VWR-738
|
||||
VWR-1109
|
||||
VWR-1351
|
||||
VWR-1353
|
||||
VWR-1410
|
||||
VWR-2116
|
||||
Argent Stonecutter
|
||||
VWR-68
|
||||
Benja Kepler
|
||||
VWR-746
|
||||
Blakar Ogre
|
||||
VWR-881
|
||||
VWR-1612
|
||||
VWR-1613
|
||||
blino Nakamura
|
||||
VWR-17
|
||||
Boroondas Gupte
|
||||
VWR-233
|
||||
WEB-262
|
||||
bushing Spatula
|
||||
VWR-119
|
||||
VWR-424
|
||||
|
|
@ -35,16 +52,25 @@ Catherine Pfeffer
|
|||
Dale Glass
|
||||
VWR-120
|
||||
VWR-560
|
||||
VWR-1358
|
||||
VWR-2041
|
||||
Drewan Keats
|
||||
VWR-28
|
||||
VWR-248
|
||||
VWR-412
|
||||
VWR-638
|
||||
VWR-660
|
||||
Dylan Haskell
|
||||
VWR-72
|
||||
Dzonatas Sol
|
||||
VWR-187
|
||||
VWR-198
|
||||
VWR-777
|
||||
VWR-878
|
||||
VWR-962
|
||||
VWR-975
|
||||
VWR-1061
|
||||
VWR-1062
|
||||
VWR-1704
|
||||
VWR-1705
|
||||
VWR-1729
|
||||
|
|
@ -53,15 +79,25 @@ Eddy Stryker
|
|||
VWR-23
|
||||
VWR-1468
|
||||
EponymousDylan Ra
|
||||
VWR-1289
|
||||
VWR-1465
|
||||
Farallon Greyskin
|
||||
VWR-2036
|
||||
Feep Larsson
|
||||
VWR-447
|
||||
VWR-1314
|
||||
Fremont Cunningham
|
||||
VWR-1147
|
||||
Gigs Taggart
|
||||
SVC-493
|
||||
VWR-38
|
||||
VWR-71
|
||||
VWR-101
|
||||
VWR-166
|
||||
VWR-234
|
||||
VWR-326
|
||||
VWR-493
|
||||
VWR-1203
|
||||
VWR-1217
|
||||
VWR-1434
|
||||
VWR-1987
|
||||
|
|
@ -71,10 +107,15 @@ Grazer Kline
|
|||
VWR-1092
|
||||
Gudmund Shepherd
|
||||
VWR-1594
|
||||
Hamncheese Omlet
|
||||
VWR-333
|
||||
Henri Beauchamp
|
||||
VWR-1406
|
||||
Hikkoshi Sakai
|
||||
VWR-429
|
||||
Hiro Sommambulist
|
||||
VWR-66
|
||||
VWR-67
|
||||
VWR-97
|
||||
VWR-100
|
||||
VWR-105
|
||||
|
|
@ -83,6 +124,8 @@ Hiro Sommambulist
|
|||
VWR-132
|
||||
VWR-136
|
||||
VWR-143
|
||||
Hoze Menges
|
||||
VWR-255
|
||||
Iskar Ariantho
|
||||
VWR-1223
|
||||
Jacek Antonelli
|
||||
|
|
@ -96,9 +139,11 @@ Kage Pixel
|
|||
VWR-11
|
||||
Kunnis Basiat
|
||||
VWR-82
|
||||
VWR-102
|
||||
Matthew Dowd
|
||||
VWR-1344
|
||||
VWR-1736
|
||||
VWR-1737
|
||||
VWR-1761
|
||||
McCabe Maxsted
|
||||
VWR-1318
|
||||
|
|
@ -107,38 +152,51 @@ Mr Greggan
|
|||
Nicholaz Beresford
|
||||
VWR-132
|
||||
VWR-176
|
||||
VWR-193
|
||||
VWR-349
|
||||
VWR-353
|
||||
VWR-364
|
||||
VWR-546
|
||||
VWR-691
|
||||
VWR-727
|
||||
VWR-793
|
||||
VWR-794
|
||||
VWR-802
|
||||
VWR-803
|
||||
VWR-804
|
||||
VWR-805
|
||||
VWR-807
|
||||
VWR-808
|
||||
VWR-809
|
||||
VWR-810
|
||||
VWR-823
|
||||
VWR-849
|
||||
VWR-856
|
||||
VWR-865
|
||||
VWR-869
|
||||
VWR-870
|
||||
VWR-871
|
||||
VWR-873
|
||||
VWR-908
|
||||
VWR-966
|
||||
VWR-1105
|
||||
VWR-1221
|
||||
VWR-1230
|
||||
VWR-1270
|
||||
VWR-1294
|
||||
VWR-1296
|
||||
VWR-1354
|
||||
VWR-1410
|
||||
VWR-1418
|
||||
VWR-1436
|
||||
VWR-1453
|
||||
VWR-1455
|
||||
VWR-1470
|
||||
VWR-1471
|
||||
VWR-1566
|
||||
VWR-1578
|
||||
VWR-1626
|
||||
VWR-1646
|
||||
VWR-1655
|
||||
VWR-1698
|
||||
VWR-1706
|
||||
|
|
@ -151,6 +209,8 @@ Nicholaz Beresford
|
|||
VWR-1872
|
||||
VWR-1968
|
||||
VWR-2152
|
||||
Nounouch Hapmouche
|
||||
VWR-238
|
||||
Paul Churchill
|
||||
VWR-20
|
||||
VWR-493
|
||||
|
|
@ -158,9 +218,12 @@ Paul Churchill
|
|||
VWR-1567
|
||||
VWR-1647
|
||||
VWR-1880
|
||||
VWR-2072
|
||||
Paula Innis
|
||||
VWR-30
|
||||
VWR-293
|
||||
VWR-1049
|
||||
VWR-1562
|
||||
Peekay Semyorka
|
||||
VWR-7
|
||||
VWR-19
|
||||
|
|
@ -170,27 +233,42 @@ Renault Clio
|
|||
VWR-1976
|
||||
Ryozu Kojima
|
||||
VWR-287
|
||||
Seg Baphomet
|
||||
VWR-1525
|
||||
VWR-1585
|
||||
VWR-1586
|
||||
SignpostMarv Martin
|
||||
VWR-153
|
||||
VWR-154
|
||||
VWR-155
|
||||
VWR-218
|
||||
VWR-373
|
||||
Simon Nolan
|
||||
VWR-409
|
||||
SpacedOut Frye
|
||||
VWR-34
|
||||
VWR-45
|
||||
VWR-57
|
||||
VWR-94
|
||||
VWR-113
|
||||
VWR-121
|
||||
VWR-123
|
||||
VWR-130
|
||||
VWR-1823
|
||||
Stevex Janus
|
||||
VWR-1182
|
||||
Still Defiant
|
||||
VWR-207
|
||||
VWR-227
|
||||
VWR-446
|
||||
Strife Onizuka
|
||||
SVC-9
|
||||
VWR-14
|
||||
VWR-74
|
||||
VWR-85
|
||||
VWR-148
|
||||
WEB-164
|
||||
VWR-183
|
||||
VWR-2265
|
||||
tenebrous pau
|
||||
VWR-247
|
||||
|
|
@ -200,6 +278,7 @@ TBBle Kurosawa
|
|||
VWR-942
|
||||
VWR-944
|
||||
VWR-945
|
||||
VWR-1891
|
||||
VWR-1892
|
||||
Tharax Ferraris
|
||||
VWR-605
|
||||
|
|
@ -207,10 +286,14 @@ Thraxis Epsilon
|
|||
SVC-371
|
||||
VWR-383
|
||||
Whoops Babii
|
||||
VWR-631
|
||||
VWR-1640
|
||||
Zarkonnen Decosta
|
||||
VWR-253
|
||||
Zi Ree
|
||||
VWR-671
|
||||
VWR-682
|
||||
VWR-684
|
||||
VWR-1140
|
||||
Zipherius Turas
|
||||
VWR-76
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ void ll_init_apr()
|
|||
apr_pool_create(&gAPRPoolp, NULL);
|
||||
|
||||
// Initialize the logging mutex
|
||||
apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_DEFAULT, gAPRPoolp);
|
||||
apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "apr-1/apr_atomic.h"
|
||||
#include "llstring.h"
|
||||
|
||||
extern apr_thread_mutex_t* gLogMutexp;
|
||||
|
||||
/**
|
||||
* @brief initialize the common apr constructs -- apr itself, the
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
#include "llapp.h"
|
||||
#include "llapr.h"
|
||||
extern apr_thread_mutex_t *gLogMutexp;
|
||||
#include "llfile.h"
|
||||
#include "llfixedbuffer.h"
|
||||
#include "lllivefile.h"
|
||||
|
|
|
|||
|
|
@ -8,6 +8,21 @@
|
|||
|
||||
#include "linden_common.h"
|
||||
|
||||
#if defined(LL_WINDOWS)
|
||||
# include <windows.h>
|
||||
# include <psapi.h>
|
||||
#elif defined(LL_DARWIN)
|
||||
# include <sys/types.h>
|
||||
# include <sys/sysctl.h>
|
||||
# include <mach/task.h>
|
||||
# include <mach/vm_map.h>
|
||||
# include <mach/mach_init.h>
|
||||
# include <mach/vm_region.h>
|
||||
# include <mach/mach_port.h>
|
||||
#elif defined(LL_LINUX)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "llmemory.h"
|
||||
#include "llmemtype.h"
|
||||
|
||||
|
|
@ -258,3 +273,131 @@ LLRefCount::~LLRefCount()
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#if defined(LL_WINDOWS)
|
||||
|
||||
U64 getCurrentRSS()
|
||||
{
|
||||
HANDLE self = GetCurrentProcess();
|
||||
PROCESS_MEMORY_COUNTERS counters;
|
||||
|
||||
if (!GetProcessMemoryInfo(self, &counters, sizeof(counters)))
|
||||
{
|
||||
llwarns << "GetProcessMemoryInfo failed" << llendl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return counters.WorkingSetSize;
|
||||
}
|
||||
|
||||
#elif defined(LL_DARWIN)
|
||||
|
||||
static U32 getPageSize()
|
||||
{
|
||||
int ctl[2] = { CTL_HW, HW_PAGESIZE };
|
||||
int page_size;
|
||||
size_t size = sizeof(page_size);
|
||||
|
||||
if (sysctl(ctl, 2, &page_size, &size, NULL, 0) == -1)
|
||||
{
|
||||
llwarns << "Couldn't get page size" << llendl;
|
||||
return 0;
|
||||
} else {
|
||||
return page_size;
|
||||
}
|
||||
}
|
||||
|
||||
U64 getCurrentRSS()
|
||||
{
|
||||
task_t task = mach_task_self();
|
||||
vm_address_t addr = VM_MIN_ADDRESS;
|
||||
vm_size_t size = 0;
|
||||
U64 residentPages = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
mach_msg_type_number_t bcount = VM_REGION_BASIC_INFO_COUNT;
|
||||
vm_region_basic_info binfo;
|
||||
mach_port_t bobj;
|
||||
kern_return_t ret;
|
||||
|
||||
addr += size;
|
||||
|
||||
ret = vm_region(task, &addr, &size, VM_REGION_BASIC_INFO,
|
||||
(vm_region_info_t) &binfo, &bcount, &bobj);
|
||||
|
||||
if (ret != KERN_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (bobj != MACH_PORT_NULL)
|
||||
{
|
||||
mach_port_deallocate(task, bobj);
|
||||
}
|
||||
|
||||
mach_msg_type_number_t ecount = VM_REGION_EXTENDED_INFO_COUNT;
|
||||
vm_region_extended_info einfo;
|
||||
mach_port_t eobj;
|
||||
|
||||
ret = vm_region(task, &addr, &size, VM_REGION_EXTENDED_INFO,
|
||||
(vm_region_info_t) &einfo, &ecount, &eobj);
|
||||
|
||||
if (ret != KERN_SUCCESS)
|
||||
{
|
||||
llwarns << "vm_region failed" << llendl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (eobj != MACH_PORT_NULL)
|
||||
{
|
||||
mach_port_deallocate(task, eobj);
|
||||
}
|
||||
|
||||
residentPages += einfo.pages_resident;
|
||||
}
|
||||
|
||||
return residentPages * getPageSize();
|
||||
}
|
||||
|
||||
#elif defined(LL_LINUX)
|
||||
|
||||
U64 getCurrentRSS()
|
||||
{
|
||||
static const char statPath[] = "/proc/self/stat";
|
||||
FILE *fp = fopen(statPath, "r");
|
||||
U64 rss = 0;
|
||||
|
||||
if (fp == NULL)
|
||||
{
|
||||
llwarns << "couldn't open " << statPath << llendl;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
// Eee-yew! See Documentation/filesystems/proc.txt in your
|
||||
// nearest friendly kernel tree for details.
|
||||
|
||||
{
|
||||
int ret = fscanf(fp, "%*d (%*[^)]) %*c %*d %*d %*d %*d %*d %*d %*d "
|
||||
"%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %Lu",
|
||||
&rss);
|
||||
if (ret != 1)
|
||||
{
|
||||
llwarns << "couldn't parse contents of " << statPath << llendl;
|
||||
rss = 0;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
bail:
|
||||
return rss;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
U64 getCurrentRSS()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -395,5 +395,8 @@ public:
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
// Return the resident set size of the current process, in bytes.
|
||||
// Return value is zero if not known.
|
||||
U64 getCurrentRSS();
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ LLMutex::LLMutex(apr_pool_t *poolp) :
|
|||
mIsLocalPool = TRUE;
|
||||
apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
|
||||
}
|
||||
apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_DEFAULT, mAPRPoolp);
|
||||
apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -727,6 +727,7 @@ BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque
|
|||
U32* dst_pixels = (U32*) dst;
|
||||
|
||||
U8* src = getData() + mDataOffset;
|
||||
U8* last_src = src + getDataSize();
|
||||
|
||||
U32 rgba;
|
||||
U8* rgba_byte_p = (U8*) &rgba;
|
||||
|
|
@ -735,6 +736,10 @@ BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque
|
|||
while( dst_pixels <= last_dst_pixel )
|
||||
{
|
||||
// Read RLE block header
|
||||
|
||||
if (src >= last_src)
|
||||
return FALSE;
|
||||
|
||||
U8 block_header_byte = *src;
|
||||
src++;
|
||||
|
||||
|
|
@ -742,6 +747,10 @@ BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque
|
|||
if( block_header_byte & 0x80 )
|
||||
{
|
||||
// Encoded (duplicate-pixel) block
|
||||
|
||||
if (src + 3 >= last_src)
|
||||
return FALSE;
|
||||
|
||||
rgba_byte_p[0] = src[2];
|
||||
rgba_byte_p[1] = src[1];
|
||||
rgba_byte_p[2] = src[0];
|
||||
|
|
@ -766,6 +775,9 @@ BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque
|
|||
// Unencoded block
|
||||
do
|
||||
{
|
||||
if (src + 3 >= last_src)
|
||||
return FALSE;
|
||||
|
||||
((U8*)dst_pixels)[0] = src[2];
|
||||
((U8*)dst_pixels)[1] = src[1];
|
||||
((U8*)dst_pixels)[2] = src[0];
|
||||
|
|
@ -793,10 +805,16 @@ BOOL LLImageTGA::decodeTruecolorRle15( LLImageRaw* raw_image )
|
|||
U8* dst = raw_image->getData();
|
||||
U8* src = getData() + mDataOffset;
|
||||
|
||||
U8* last_src = src + getDataSize();
|
||||
U8* last_dst = dst + getComponents() * (getHeight() * getWidth() - 1);
|
||||
|
||||
while( dst <= last_dst )
|
||||
{
|
||||
// Read RLE block header
|
||||
|
||||
if (src >= last_src)
|
||||
return FALSE;
|
||||
|
||||
U8 block_header_byte = *src;
|
||||
src++;
|
||||
|
||||
|
|
@ -806,6 +824,9 @@ BOOL LLImageTGA::decodeTruecolorRle15( LLImageRaw* raw_image )
|
|||
// Encoded (duplicate-pixel) block
|
||||
do
|
||||
{
|
||||
if (src + 2 >= last_src)
|
||||
return FALSE;
|
||||
|
||||
decodeTruecolorPixel15( dst, src ); // slow
|
||||
dst += 3;
|
||||
block_pixel_count--;
|
||||
|
|
@ -818,6 +839,9 @@ BOOL LLImageTGA::decodeTruecolorRle15( LLImageRaw* raw_image )
|
|||
// Unencoded block
|
||||
do
|
||||
{
|
||||
if (src + 2 >= last_src)
|
||||
return FALSE;
|
||||
|
||||
decodeTruecolorPixel15( dst, src );
|
||||
dst += 3;
|
||||
src += 2;
|
||||
|
|
@ -839,10 +863,16 @@ BOOL LLImageTGA::decodeTruecolorRle24( LLImageRaw* raw_image )
|
|||
U8* dst = raw_image->getData();
|
||||
U8* src = getData() + mDataOffset;
|
||||
|
||||
U8* last_src = src + getDataSize();
|
||||
U8* last_dst = dst + getComponents() * (getHeight() * getWidth() - 1);
|
||||
|
||||
while( dst <= last_dst )
|
||||
{
|
||||
// Read RLE block header
|
||||
|
||||
if (src >= last_src)
|
||||
return FALSE;
|
||||
|
||||
U8 block_header_byte = *src;
|
||||
src++;
|
||||
|
||||
|
|
@ -852,6 +882,8 @@ BOOL LLImageTGA::decodeTruecolorRle24( LLImageRaw* raw_image )
|
|||
// Encoded (duplicate-pixel) block
|
||||
do
|
||||
{
|
||||
if (src + 2 >= last_src)
|
||||
return FALSE;
|
||||
dst[0] = src[2];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[0];
|
||||
|
|
@ -866,6 +898,9 @@ BOOL LLImageTGA::decodeTruecolorRle24( LLImageRaw* raw_image )
|
|||
// Unencoded block
|
||||
do
|
||||
{
|
||||
if (src + 2 >= last_src)
|
||||
return FALSE;
|
||||
|
||||
dst[0] = src[2];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[0];
|
||||
|
|
@ -888,16 +923,25 @@ BOOL LLImageTGA::decodeTruecolorRle8( LLImageRaw* raw_image )
|
|||
U8* dst = raw_image->getData();
|
||||
U8* src = getData() + mDataOffset;
|
||||
|
||||
U8* last_src = src + getDataSize();
|
||||
U8* last_dst = dst + getHeight() * getWidth() - 1;
|
||||
|
||||
while( dst <= last_dst )
|
||||
{
|
||||
// Read RLE block header
|
||||
|
||||
if (src >= last_src)
|
||||
return FALSE;
|
||||
|
||||
U8 block_header_byte = *src;
|
||||
src++;
|
||||
|
||||
U8 block_pixel_count = (block_header_byte & 0x7F) + 1;
|
||||
if( block_header_byte & 0x80 )
|
||||
{
|
||||
if (src >= last_src)
|
||||
return FALSE;
|
||||
|
||||
// Encoded (duplicate-pixel) block
|
||||
memset( dst, *src, block_pixel_count );
|
||||
dst += block_pixel_count;
|
||||
|
|
@ -908,6 +952,9 @@ BOOL LLImageTGA::decodeTruecolorRle8( LLImageRaw* raw_image )
|
|||
// Unencoded block
|
||||
do
|
||||
{
|
||||
if (src >= last_src)
|
||||
return FALSE;
|
||||
|
||||
*dst = *src;
|
||||
dst++;
|
||||
src++;
|
||||
|
|
|
|||
|
|
@ -160,84 +160,129 @@ BOOL LLXform::setParent(LLXform* parent)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Don't blow up on release versions
|
||||
#if LL_RELEASE_FOR_DOWNLOAD
|
||||
#define llxformtrouble(msg, num) llwarning(msg, num)
|
||||
#else
|
||||
#define llxformtrouble(msg, num) llerror(msg, num)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CHECK_FOR_FINITE
|
||||
void LLXform::setPosition(const LLVector3& pos)
|
||||
{
|
||||
setChanged(TRANSLATED);
|
||||
if (pos.isFinite())
|
||||
{
|
||||
mPosition = pos;
|
||||
}
|
||||
else
|
||||
llerror("Non Finite in LLXform::setPosition(LLVector3)", 0);
|
||||
{
|
||||
llxformtrouble("Non Finite in LLXform::setPosition(LLVector3)", 0);
|
||||
}
|
||||
}
|
||||
|
||||
void LLXform::setPosition(const F32 x, const F32 y, const F32 z)
|
||||
{
|
||||
setChanged(TRANSLATED);
|
||||
if (llfinite(x) && llfinite(y) && llfinite(z))
|
||||
{
|
||||
mPosition.setVec(x,y,z);
|
||||
}
|
||||
else
|
||||
llerror("Non Finite in LLXform::setPosition(F32,F32,F32)", 0);
|
||||
{
|
||||
llxformtrouble("Non Finite in LLXform::setPosition(F32,F32,F32)", 0);
|
||||
}
|
||||
}
|
||||
|
||||
void LLXform::setPositionX(const F32 x)
|
||||
{
|
||||
setChanged(TRANSLATED);
|
||||
if (llfinite(x))
|
||||
{
|
||||
mPosition.mV[VX] = x;
|
||||
}
|
||||
else
|
||||
llerror("Non Finite in LLXform::setPositionX", 0);
|
||||
{
|
||||
llxformtrouble("Non Finite in LLXform::setPositionX", 0);
|
||||
}
|
||||
}
|
||||
|
||||
void LLXform::setPositionY(const F32 y)
|
||||
{
|
||||
setChanged(TRANSLATED);
|
||||
if (llfinite(y))
|
||||
{
|
||||
mPosition.mV[VY] = y;
|
||||
}
|
||||
else
|
||||
llerror("Non Finite in LLXform::setPositionY", 0);
|
||||
{
|
||||
llxformtrouble("Non Finite in LLXform::setPositionY", 0);
|
||||
}
|
||||
}
|
||||
|
||||
void LLXform::setPositionZ(const F32 z)
|
||||
{
|
||||
setChanged(TRANSLATED);
|
||||
if (llfinite(z))
|
||||
{
|
||||
mPosition.mV[VZ] = z;
|
||||
}
|
||||
else
|
||||
llerror("Non Finite in LLXform::setPositionZ", 0);
|
||||
{
|
||||
llxformtrouble("Non Finite in LLXform::setPositionZ", 0);
|
||||
}
|
||||
}
|
||||
|
||||
void LLXform::addPosition(const LLVector3& pos)
|
||||
{
|
||||
setChanged(TRANSLATED);
|
||||
if (pos.isFinite())
|
||||
{
|
||||
mPosition += pos;
|
||||
}
|
||||
else
|
||||
llerror("Non Finite in LLXform::addPosition", 0);
|
||||
{
|
||||
llxformtrouble("Non Finite in LLXform::addPosition", 0);
|
||||
}
|
||||
}
|
||||
|
||||
void LLXform::setScale(const LLVector3& scale)
|
||||
{
|
||||
setChanged(SCALED);
|
||||
if (scale.isFinite())
|
||||
{
|
||||
mScale = scale;
|
||||
}
|
||||
else
|
||||
llerror("Non Finite in LLXform::setScale", 0);
|
||||
{
|
||||
llxformtrouble("Non Finite in LLXform::setScale(LLVector)", 0);
|
||||
}
|
||||
}
|
||||
void LLXform::setScale(const F32 x, const F32 y, const F32 z)
|
||||
{
|
||||
setChanged(SCALED);
|
||||
if (llfinite(x) && llfinite(y) && llfinite(z))
|
||||
{
|
||||
mScale.setVec(x,y,z);
|
||||
}
|
||||
else
|
||||
llerror("Non Finite in LLXform::setScale", 0);
|
||||
{
|
||||
llxformtrouble("Non Finite in LLXform::setScale(F32,F32,F32)", 0);
|
||||
}
|
||||
}
|
||||
void LLXform::setRotation(const LLQuaternion& rot)
|
||||
{
|
||||
setChanged(ROTATED);
|
||||
if (rot.isFinite())
|
||||
{
|
||||
mRotation = rot;
|
||||
}
|
||||
else
|
||||
llerror("Non Finite in LLXform::setRotation", 0);
|
||||
{
|
||||
llxformtrouble("Non Finite in LLXform::setRotation(LLQuaternion)", 0);
|
||||
}
|
||||
}
|
||||
void LLXform::setRotation(const F32 x, const F32 y, const F32 z)
|
||||
{
|
||||
|
|
@ -248,7 +293,7 @@ void LLXform::setRotation(const F32 x, const F32 y, const F32 z)
|
|||
}
|
||||
else
|
||||
{
|
||||
llerror("Non Finite in LLXform::setRotation", 0);
|
||||
llxformtrouble("Non Finite in LLXform::setRotation(F32,F32,F32)", 0);
|
||||
}
|
||||
}
|
||||
void LLXform::setRotation(const F32 x, const F32 y, const F32 z, const F32 s)
|
||||
|
|
@ -260,7 +305,7 @@ void LLXform::setRotation(const F32 x, const F32 y, const F32 z, const F32 s)
|
|||
}
|
||||
else
|
||||
{
|
||||
llerror("Non Finite in LLXform::setRotation", 0);
|
||||
llxformtrouble("Non Finite in LLXform::setRotation(F32,F32,F32,F32)", 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -321,8 +321,15 @@ size_t LLHTTPAssetRequest::readCompressedData(void* data, size_t size)
|
|||
S32 to_read = llmin(COMPRESSED_INPUT_BUFFER_SIZE,
|
||||
(S32)(mVFile->getSize() - mVFile->tell()));
|
||||
|
||||
mVFile->read((U8*)mZInputBuffer, to_read); /*Flawfinder: ignore*/
|
||||
|
||||
if ( to_read > 0 )
|
||||
{
|
||||
mVFile->read((U8*)mZInputBuffer, to_read); /*Flawfinder: ignore*/
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "LLHTTPAssetRequest::readCompressedData has zero read length" << llendl;
|
||||
break;
|
||||
}
|
||||
mZStream.next_in = (Bytef*)mZInputBuffer;
|
||||
mZStream.avail_in = mVFile->getLastBytesRead();
|
||||
|
||||
|
|
@ -332,7 +339,7 @@ size_t LLHTTPAssetRequest::readCompressedData(void* data, size_t size)
|
|||
int r = deflate(&mZStream,
|
||||
mZInputExhausted ? Z_FINISH : Z_NO_FLUSH);
|
||||
|
||||
if (r == Z_STREAM_END)
|
||||
if (r == Z_STREAM_END || r < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
@ -345,15 +352,20 @@ size_t LLHTTPAssetRequest::readCompressedData(void* data, size_t size)
|
|||
size_t LLHTTPAssetRequest::curlCompressedUploadCallback(
|
||||
void *data, size_t size, size_t nmemb, void *user_data)
|
||||
{
|
||||
if (!gAssetStorage)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
CURL *curl_handle = (CURL *)user_data;
|
||||
LLHTTPAssetRequest *req = NULL;
|
||||
curl_easy_getinfo(curl_handle, CURLINFO_PRIVATE, &req);
|
||||
size_t num_read = 0;
|
||||
|
||||
return req->readCompressedData(data, size * nmemb);
|
||||
if (gAssetStorage)
|
||||
{
|
||||
CURL *curl_handle = (CURL *)user_data;
|
||||
LLHTTPAssetRequest *req = NULL;
|
||||
curl_easy_getinfo(curl_handle, CURLINFO_PRIVATE, &req);
|
||||
if (req)
|
||||
{
|
||||
num_read = req->readCompressedData(data, size * nmemb);
|
||||
}
|
||||
}
|
||||
|
||||
return num_read;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -511,9 +523,8 @@ void LLHTTPAssetStorage::storeAssetData(
|
|||
{
|
||||
callback(LLUUID::null, user_data, LL_ERR_CANNOT_OPEN_FILE, LL_EXSTAT_BLOCKED_FILE);
|
||||
}
|
||||
delete legacy;
|
||||
}
|
||||
// Coverity CID-269 says there's a leak of 'legacy' here, but
|
||||
// legacyStoreDataCallback() will delete it somewhere down the line.
|
||||
}
|
||||
|
||||
// virtual
|
||||
|
|
|
|||
|
|
@ -30,10 +30,10 @@ class LLMessageConfigFile : public LLLiveFile
|
|||
{
|
||||
public:
|
||||
LLMessageConfigFile()
|
||||
: LLLiveFile(fileName(), messageConfigRefreshRate)
|
||||
: LLLiveFile(filename(), messageConfigRefreshRate)
|
||||
{ }
|
||||
|
||||
static std::string fileName();
|
||||
static std::string filename();
|
||||
|
||||
LLSD mMessages;
|
||||
std::string mServerDefault;
|
||||
|
|
@ -52,7 +52,7 @@ public:
|
|||
LLSD mCapBans;
|
||||
};
|
||||
|
||||
std::string LLMessageConfigFile::fileName()
|
||||
std::string LLMessageConfigFile::filename()
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << sConfigDir//gAppSimp->getOption("configdir").asString()
|
||||
|
|
@ -73,9 +73,10 @@ void LLMessageConfigFile::loadFile()
|
|||
LLSD data;
|
||||
{
|
||||
llifstream file(filename().c_str());
|
||||
|
||||
if (file.is_open())
|
||||
{
|
||||
llinfos << "Loading message.xml file at " << fileName() << llendl;
|
||||
llinfos << "Loading message.xml file at " << filename() << llendl;
|
||||
LLSDSerialize::fromXML(data, file);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -664,8 +664,9 @@ void LLPumpIO::initialize(apr_pool_t* pool)
|
|||
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
|
||||
if(!pool) return;
|
||||
#if LL_THREADS_APR
|
||||
apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_DEFAULT, pool);
|
||||
apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_DEFAULT, pool);
|
||||
// SJB: Windows defaults to NESTED and OSX defaults to UNNESTED, so use UNNESTED explicitly.
|
||||
apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, pool);
|
||||
apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, pool);
|
||||
#endif
|
||||
mPool = pool;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1135,9 +1135,11 @@ LLHTTPClient::ResponderPtr LLMessageSystem::createResponder(const std::string& n
|
|||
}
|
||||
else
|
||||
{
|
||||
llwarns << "LLMessageSystem::sendMessage: Sending unreliable "
|
||||
<< mMessageBuilder->getMessageName() << " message via HTTP"
|
||||
<< llendl;
|
||||
// These messages aren't really unreliable, they just weren't
|
||||
// explicitly sent as reliable, so they don't have a callback
|
||||
// llwarns << "LLMessageSystem::sendMessage: Sending unreliable "
|
||||
// << mMessageBuilder->getMessageName() << " message via HTTP"
|
||||
// << llendl;
|
||||
return new LLFnPtrResponder(NULL, NULL,
|
||||
mMessageBuilder->getMessageName());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1273,9 +1273,9 @@ LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor
|
|||
child->getAttributeBOOL("auto_resize", auto_resize);
|
||||
|
||||
LLPanel* panelp = (LLPanel*)LLPanel::fromXML(child, layout_stackp, factory);
|
||||
panelp->setFollowsNone();
|
||||
if (panelp)
|
||||
{
|
||||
panelp->setFollowsNone();
|
||||
layout_stackp->addPanel(panelp, min_width, min_height, auto_resize);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -600,6 +600,7 @@ std::vector<LLScrollListItem*> LLScrollListCtrl::getAllData() const
|
|||
|
||||
void LLScrollListCtrl::reshape( S32 width, S32 height, BOOL called_from_parent )
|
||||
{
|
||||
S32 old_height = mRect.getHeight();
|
||||
LLUICtrl::reshape( width, height, called_from_parent );
|
||||
|
||||
S32 heading_size = (mDisplayColumnHeaders ? mHeadingHeight : 0);
|
||||
|
|
@ -611,9 +612,13 @@ void LLScrollListCtrl::reshape( S32 width, S32 height, BOOL called_from_parent )
|
|||
mRect.getHeight() - 2*( mBorderThickness + LIST_BORDER_PAD ) - heading_size );
|
||||
|
||||
mPageLines = mLineHeight? mItemListRect.getHeight() / mLineHeight : 0;
|
||||
if(old_height < height && getScrollPos() == mScrollbar->getDocPosMax())
|
||||
{
|
||||
setScrollPos(mScrollbar->getDocPosMax());
|
||||
}
|
||||
mScrollbar->setVisible(mPageLines < getItemCount());
|
||||
mScrollbar->setPageSize( mPageLines );
|
||||
|
||||
|
||||
updateColumns();
|
||||
}
|
||||
|
||||
|
|
@ -750,6 +755,7 @@ void LLScrollListCtrl::updateColumns()
|
|||
mColumnsIndexed.resize(mColumns.size());
|
||||
|
||||
std::map<LLString, LLScrollListColumn>::iterator column_itor;
|
||||
bool first_dynamic = true;
|
||||
for (column_itor = mColumns.begin(); column_itor != mColumns.end(); ++column_itor)
|
||||
{
|
||||
LLScrollListColumn *column = &column_itor->second;
|
||||
|
|
@ -761,6 +767,11 @@ void LLScrollListCtrl::updateColumns()
|
|||
else if (column->mDynamicWidth)
|
||||
{
|
||||
new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth) / mNumDynamicWidthColumns;
|
||||
if(first_dynamic)
|
||||
{
|
||||
first_dynamic = false;
|
||||
new_width += (mScrollbar->getVisible() ? 0 : SCROLLBAR_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
if (new_width != column->mWidth)
|
||||
|
|
@ -790,9 +801,10 @@ void LLScrollListCtrl::updateColumns()
|
|||
LLColumnHeader* last_header = NULL;
|
||||
for (column_ordered_it = mColumnsIndexed.begin(); column_ordered_it != mColumnsIndexed.end(); ++column_ordered_it)
|
||||
{
|
||||
if ((*column_ordered_it)->mWidth <= 0)
|
||||
if ((*column_ordered_it)->mWidth < 0)
|
||||
{
|
||||
// skip hidden columns
|
||||
// skip hidden columns
|
||||
continue;
|
||||
}
|
||||
LLScrollListColumn* column = *column_ordered_it;
|
||||
|
||||
|
|
@ -807,9 +819,8 @@ void LLScrollListCtrl::updateColumns()
|
|||
right += mColumnPadding;
|
||||
}
|
||||
right = llmax(left, llmin(mItemListRect.getWidth(), right));
|
||||
|
||||
S32 header_width = right - left;
|
||||
|
||||
|
||||
last_header->reshape(header_width, mHeadingHeight);
|
||||
last_header->translate(left - last_header->getRect().mLeft, top - last_header->getRect().mBottom);
|
||||
last_header->setVisible(mDisplayColumnHeaders && header_width > 0);
|
||||
|
|
@ -818,12 +829,15 @@ void LLScrollListCtrl::updateColumns()
|
|||
}
|
||||
|
||||
// expand last column header we encountered to full list width
|
||||
|
||||
if (last_header)
|
||||
{
|
||||
S32 header_strip_width = mItemListRect.getWidth() + (mScrollbar->getVisible() ? 0 : SCROLLBAR_SIZE);
|
||||
S32 new_width = llmax(0, mItemListRect.mLeft + header_strip_width - last_header->getRect().mLeft);
|
||||
last_header->reshape(new_width, last_header->getRect().getHeight());
|
||||
last_header->setVisible(mDisplayColumnHeaders && new_width > 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLScrollListCtrl::setDisplayHeading(BOOL display)
|
||||
|
|
@ -1433,7 +1447,9 @@ void LLScrollListCtrl::drawItems()
|
|||
LLGLSUIDefault gls_ui;
|
||||
|
||||
{
|
||||
LLLocalClipRect clip(mItemListRect);
|
||||
LLRect clip_rect = mItemListRect;
|
||||
if(!mScrollbar->getVisible()) clip_rect.mRight += SCROLLBAR_SIZE;
|
||||
LLLocalClipRect clip(clip_rect);
|
||||
|
||||
S32 cur_x = x;
|
||||
S32 cur_y = y;
|
||||
|
|
@ -1452,10 +1468,10 @@ void LLScrollListCtrl::drawItems()
|
|||
item_rect.setOriginAndSize(
|
||||
cur_x,
|
||||
cur_y,
|
||||
mScrollbar->getVisible() ? mItemListRect.getWidth() : mItemListRect.getWidth() + mScrollbar->getRect().getWidth(),
|
||||
mScrollbar->getVisible() ? mItemListRect.getWidth() : mItemListRect.getWidth() + SCROLLBAR_SIZE,
|
||||
mLineHeight );
|
||||
|
||||
lldebugs << mItemListRect.getWidth() << llendl;
|
||||
//llinfos << item_rect.getWidth() << llendl;
|
||||
|
||||
if (item->getSelected())
|
||||
{
|
||||
|
|
@ -1503,22 +1519,31 @@ void LLScrollListCtrl::drawItems()
|
|||
S32 cur_col = 0;
|
||||
S32 dynamic_width = 0;
|
||||
S32 dynamic_remainder = 0;
|
||||
bool first_dynamic = true;
|
||||
if(mNumDynamicWidthColumns > 0)
|
||||
{
|
||||
dynamic_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth) / mNumDynamicWidthColumns;
|
||||
dynamic_remainder = (mItemListRect.getWidth() - mTotalStaticColumnWidth) % mNumDynamicWidthColumns;
|
||||
}
|
||||
|
||||
for (LLScrollListCell* cell = item->getColumn(0); cur_col < num_cols; cell = item->getColumn(++cur_col))
|
||||
{
|
||||
S32 cell_width = cell->getWidth();
|
||||
|
||||
if(mColumnsIndexed.size() > (U32)cur_col && mColumnsIndexed[cur_col] && mColumnsIndexed[cur_col]->mDynamicWidth)
|
||||
{
|
||||
cell_width = dynamic_width + (--dynamic_remainder ? 1 : 0);
|
||||
if(first_dynamic)
|
||||
{
|
||||
cell_width += mScrollbar->getVisible() ? 0 : SCROLLBAR_SIZE;
|
||||
first_dynamic = false;
|
||||
}
|
||||
cell->setWidth(cell_width);
|
||||
}
|
||||
// Two ways a cell could be hidden
|
||||
if (cell_width < 0
|
||||
|| !cell->getVisible()) continue;
|
||||
|
||||
LLUI::pushMatrix();
|
||||
LLUI::translate((F32) cur_x, (F32) cur_y, 0.0f);
|
||||
S32 space_left = mItemListRect.mRight - cur_x;
|
||||
|
|
|
|||
|
|
@ -2689,6 +2689,7 @@ void spawn_web_browser(const char* escaped_url)
|
|||
cmd += "launch_url.sh";
|
||||
char* const argv[] = {(char*)cmd.c_str(), (char*)escaped_url, NULL};
|
||||
|
||||
fflush(NULL);
|
||||
pid_t pid = fork();
|
||||
if (pid == 0)
|
||||
{ // child
|
||||
|
|
|
|||
|
|
@ -99,8 +99,6 @@ the Alpha release of the Linux client.
|
|||
|
||||
* VOICE COMMUNICATION - this is not yet available in the Linux client.
|
||||
|
||||
* STREAMING MOVIES - these are currently disabled while we work on some issues.
|
||||
|
||||
* VISUAL EFFECTS AND PERFORMANCE - many Linux graphics drivers are not as
|
||||
robust as their counterparts for other operating systems, so some advanced
|
||||
Second Life graphical features have been DISABLED by default to aid
|
||||
|
|
|
|||
|
|
@ -33,6 +33,10 @@ export LL_GL_BASICEXT=x
|
|||
## LL_GL_BLACKLIST which solves your problems.
|
||||
#export LL_GL_BLACKLIST=abcdefghijklmno
|
||||
|
||||
|
||||
## Everything below this line is just for advanced troubleshooters.
|
||||
##-------------------------------------------------------------------
|
||||
|
||||
## - For advanced debugging cases, you can run the viewer under the
|
||||
## control of another program, such as strace, gdb, or valgrind. If
|
||||
## you're building your own viewer, bear in mind that the executable
|
||||
|
|
@ -47,6 +51,12 @@ export SDL_VIDEO_X11_DGAMOUSE=0
|
|||
## - Works around a problem with misconfigured 64-bit systems not finding GL
|
||||
export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}":/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri
|
||||
|
||||
## - The 'scim' GTK IM module widely crashes the viewer. Avoid it.
|
||||
if [ "$GTK_IM_MODULE" = "scim" ]; then
|
||||
export GTK_IM_MODULE=xim
|
||||
fi
|
||||
|
||||
|
||||
## Nothing worth editing below this line.
|
||||
##-------------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -1838,7 +1838,7 @@ void LLAgent::cameraOrbitIn(const F32 meters)
|
|||
if (new_distance > max_distance)
|
||||
{
|
||||
// Unless camera is unlocked
|
||||
if (!LLViewerCamera::sDisableCameraConstraints)
|
||||
if (!gSavedSettings.getBOOL("DisableCameraConstraints"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -3754,7 +3754,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit)
|
|||
camera_position_global = focusPosGlobal + mCameraFocusOffset;
|
||||
}
|
||||
|
||||
if (!LLViewerCamera::sDisableCameraConstraints && !gAgent.isGodlike())
|
||||
if (!gSavedSettings.getBOOL("DisableCameraConstraints") && !gAgent.isGodlike())
|
||||
{
|
||||
LLViewerRegion* regionp = gWorldPointer->getRegionFromPosGlobal(
|
||||
camera_position_global);
|
||||
|
|
@ -3878,7 +3878,7 @@ F32 LLAgent::getCameraMinOffGround()
|
|||
}
|
||||
else
|
||||
{
|
||||
if (LLViewerCamera::sDisableCameraConstraints)
|
||||
if (gSavedSettings.getBOOL("DisableCameraConstraints"))
|
||||
{
|
||||
return -1000.f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@
|
|||
#include "llpermissionsflags.h"
|
||||
#include "llpreviewnotecard.h"
|
||||
#include "llpreviewscript.h"
|
||||
#include "llpreviewgesture.h"
|
||||
#include "llgesturemgr.h"
|
||||
#include "llscrolllistctrl.h"
|
||||
#include "lluploaddialog.h"
|
||||
#include "llviewerobject.h"
|
||||
|
|
@ -361,6 +363,27 @@ void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content)
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LLInventoryType::IT_GESTURE:
|
||||
{
|
||||
// If this gesture is active, then we need to update the in-memory
|
||||
// active map with the new pointer.
|
||||
if (gGestureManager.isGestureActive(item_id))
|
||||
{
|
||||
LLUUID asset_id = new_item->getAssetUUID();
|
||||
gGestureManager.replaceGesture(item_id, asset_id);
|
||||
gInventory.notifyObservers();
|
||||
}
|
||||
|
||||
//gesture will have a new asset_id
|
||||
LLPreviewGesture* previewp = (LLPreviewGesture*)LLPreview::find(item_id);
|
||||
if(previewp)
|
||||
{
|
||||
previewp->onUpdateSucceeded();
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case LLInventoryType::IT_WEARABLE:
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -50,7 +50,23 @@ void LLAudioSourceVO::updateGain()
|
|||
BOOL mute = FALSE;
|
||||
if (gParcelMgr)
|
||||
{
|
||||
LLVector3d pos_global = mObjectp->getPositionGlobal();
|
||||
LLVector3d pos_global;
|
||||
|
||||
if (mObjectp->isAttachment())
|
||||
{
|
||||
LLViewerObject* parent = mObjectp;
|
||||
while (parent
|
||||
&& !parent->isAvatar())
|
||||
{
|
||||
parent = (LLViewerObject*)parent->getParent();
|
||||
}
|
||||
if (parent)
|
||||
pos_global = parent->getPositionGlobal();
|
||||
}
|
||||
|
||||
else
|
||||
pos_global = mObjectp->getPositionGlobal();
|
||||
|
||||
if (!gParcelMgr->canHearSound(pos_global))
|
||||
{
|
||||
mute = TRUE;
|
||||
|
|
|
|||
|
|
@ -470,6 +470,11 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isMinimized() )
|
||||
{ // SL looks odd if we draw the tools while the window is minimized
|
||||
return;
|
||||
}
|
||||
|
||||
// Focus buttons
|
||||
BOOL focus_visible = ( tool == gToolCamera );
|
||||
|
|
|
|||
|
|
@ -2924,12 +2924,10 @@ BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected)
|
|||
|
||||
if(selected && !on_list)
|
||||
{
|
||||
mNumDescendantsSelected++;
|
||||
addToSelectionList(selection);
|
||||
}
|
||||
if(!selected && on_list)
|
||||
{
|
||||
mNumDescendantsSelected--;
|
||||
removeFromSelectionList(selection);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -416,6 +416,19 @@ void LLGestureManager::replaceGesture(const LLUUID& item_id, LLMultiGesture* new
|
|||
notifyObservers();
|
||||
}
|
||||
|
||||
void LLGestureManager::replaceGesture(const LLUUID& item_id, const LLUUID& new_asset_id)
|
||||
{
|
||||
item_map_t::iterator it = gGestureManager.mActive.find(item_id);
|
||||
if (it == mActive.end())
|
||||
{
|
||||
llwarns << "replaceGesture for inactive gesture " << item_id << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
// mActive owns this gesture pointer, so clean up memory.
|
||||
LLMultiGesture* gesture = (*it).second;
|
||||
gGestureManager.replaceGesture(item_id, gesture, new_asset_id);
|
||||
}
|
||||
|
||||
void LLGestureManager::playGesture(LLMultiGesture* gesture)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ public:
|
|||
// If you change a gesture, you need to build a new multigesture
|
||||
// and call this method.
|
||||
void replaceGesture(const LLUUID& item_id, LLMultiGesture* new_gesture, const LLUUID& asset_id);
|
||||
void replaceGesture(const LLUUID& item_id, const LLUUID& asset_id);
|
||||
|
||||
// Load gesture into in-memory active form.
|
||||
// Can be called even if the inventory item isn't loaded yet.
|
||||
|
|
|
|||
|
|
@ -914,7 +914,7 @@ void LLFloaterIMPanel::init(const LLString& session_label)
|
|||
|
||||
session_start.setArg("[NAME]", getTitle());
|
||||
mSessionStartMsgPos =
|
||||
mHistoryEditor->getText().length();
|
||||
mHistoryEditor->getWText().length();
|
||||
|
||||
addHistoryLine(
|
||||
session_start,
|
||||
|
|
@ -966,6 +966,7 @@ BOOL LLFloaterIMPanel::postBuild()
|
|||
childSetAction("end_call_btn", onClickEndCall, this);
|
||||
childSetAction("send_btn", onClickSend, this);
|
||||
childSetAction("toggle_active_speakers_btn", onClickToggleActiveSpeakers, this);
|
||||
childSetAction("offer_tp_btn", onClickOfferTeleport, this);
|
||||
|
||||
//LLButton* close_btn = LLUICtrlFactory::getButtonByName(this, "close_btn");
|
||||
//close_btn->setClickedCallback(&LLFloaterIMPanel::onClickClose, this);
|
||||
|
|
@ -1059,6 +1060,13 @@ void LLFloaterIMPanel::draw()
|
|||
childSetEnabled("start_call_btn", enable_connect);
|
||||
childSetEnabled("send_btn", !childGetValue("chat_editor").asString().empty());
|
||||
|
||||
const LLRelationship* info = NULL;
|
||||
info = LLAvatarTracker::instance().getBuddyInfo(mOtherParticipantUUID);
|
||||
if (info)
|
||||
{
|
||||
childSetEnabled("offer_tp_btn", info->isOnline());
|
||||
}
|
||||
|
||||
if (mAutoConnect && enable_connect)
|
||||
{
|
||||
onClickStartCall(this);
|
||||
|
|
@ -1385,6 +1393,13 @@ void LLFloaterIMPanel::onTabClick(void* userdata)
|
|||
self->setInputFocus(TRUE);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterIMPanel::onClickOfferTeleport(void* userdata)
|
||||
{
|
||||
LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
|
||||
|
||||
handle_lure(self->mOtherParticipantUUID);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterIMPanel::onClickProfile( void* userdata )
|
||||
|
|
@ -1646,7 +1661,7 @@ void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id)
|
|||
//we assume the history editor hasn't moved at all since
|
||||
//we added the starting session message
|
||||
//so, we count how many characters to remove
|
||||
S32 chars_to_remove = mHistoryEditor->getText().length() -
|
||||
S32 chars_to_remove = mHistoryEditor->getWText().length() -
|
||||
mSessionStartMsgPos;
|
||||
mHistoryEditor->removeTextFromEnd(chars_to_remove);
|
||||
|
||||
|
|
@ -1744,7 +1759,7 @@ void LLFloaterIMPanel::addTypingIndicator(const std::string &name)
|
|||
// we may have lost a "stop-typing" packet, don't add it twice
|
||||
if (!mOtherTyping)
|
||||
{
|
||||
mTypingLineStartIndex = mHistoryEditor->getText().length();
|
||||
mTypingLineStartIndex = mHistoryEditor->getWText().length();
|
||||
LLUIString typing_start = sTypingStartString;
|
||||
typing_start.setArg("[NAME]", name);
|
||||
addHistoryLine(typing_start, gSavedSettings.getColor4("SystemChatColor"), false);
|
||||
|
|
@ -1764,7 +1779,7 @@ void LLFloaterIMPanel::removeTypingIndicator(const LLIMInfo* im_info)
|
|||
// Must do this first, otherwise addHistoryLine calls us again.
|
||||
mOtherTyping = FALSE;
|
||||
|
||||
S32 chars_to_remove = mHistoryEditor->getText().length() - mTypingLineStartIndex;
|
||||
S32 chars_to_remove = mHistoryEditor->getWText().length() - mTypingLineStartIndex;
|
||||
mHistoryEditor->removeTextFromEnd(chars_to_remove);
|
||||
if (im_info)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@ public:
|
|||
|
||||
static void onClickProfile( void* userdata );
|
||||
static void onClickGroupInfo( void* userdata );
|
||||
static void onClickOfferTeleport( void* userdata );
|
||||
static void onClickClose( void* userdata );
|
||||
static void onClickStartCall( void* userdata );
|
||||
static void onClickEndCall( void* userdata );
|
||||
|
|
|
|||
|
|
@ -152,7 +152,8 @@ LLInventoryModel gInventory;
|
|||
// Default constructor
|
||||
LLInventoryModel::LLInventoryModel() :
|
||||
mModifyMask(LLInventoryObserver::ALL),
|
||||
mLastItem(NULL)
|
||||
mLastItem(NULL),
|
||||
mIsAgentInvUsable(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -269,13 +270,9 @@ void LLInventoryModel::getDirectDescendentsOf(const LLUUID& cat_id,
|
|||
LLUUID LLInventoryModel::findCategoryUUIDForType(LLAssetType::EType t)
|
||||
{
|
||||
LLUUID rv = findCatUUID(t);
|
||||
if(rv.isNull())
|
||||
if(rv.isNull() && isInventoryUsable())
|
||||
{
|
||||
rv = gAgent.getInventoryRootID();
|
||||
if(rv.notNull())
|
||||
{
|
||||
rv = createNewCategory(rv, t, NULL);
|
||||
}
|
||||
rv = createNewCategory(rv, t, NULL);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
@ -317,6 +314,12 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
|
|||
const LLString& pname)
|
||||
{
|
||||
LLUUID id;
|
||||
if(!isInventoryUsable())
|
||||
{
|
||||
llwarns << "Inventory is broken." << llendl;
|
||||
return id;
|
||||
}
|
||||
|
||||
id.generate();
|
||||
LLString name = pname;
|
||||
if(!pname.empty())
|
||||
|
|
@ -450,6 +453,16 @@ void LLInventoryModel::appendPath(const LLUUID& id, LLString& path)
|
|||
path.append(temp);
|
||||
}
|
||||
|
||||
bool LLInventoryModel::isInventoryUsable()
|
||||
{
|
||||
bool result = false;
|
||||
if(gAgent.getInventoryRootID().notNull() && mIsAgentInvUsable)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Calling this method with an inventory item will either change an
|
||||
// existing item with a matching item_id, or will add the item to the
|
||||
// current inventory.
|
||||
|
|
@ -460,6 +473,13 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item)
|
|||
{
|
||||
return mask;
|
||||
}
|
||||
|
||||
if(!isInventoryUsable())
|
||||
{
|
||||
llwarns << "Inventory is broken." << llendl;
|
||||
return mask;
|
||||
}
|
||||
|
||||
LLViewerInventoryItem* old_item = getItem(item->getUUID());
|
||||
if(old_item)
|
||||
{
|
||||
|
|
@ -568,6 +588,13 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat)
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(!isInventoryUsable())
|
||||
{
|
||||
llwarns << "Inventory is broken." << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
LLViewerInventoryCategory* old_cat = getCategory(cat->getUUID());
|
||||
if(old_cat)
|
||||
{
|
||||
|
|
@ -625,6 +652,12 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat)
|
|||
void LLInventoryModel::moveObject(const LLUUID& object_id, const LLUUID& cat_id)
|
||||
{
|
||||
lldebugs << "LLInventoryModel::moveObject()" << llendl;
|
||||
if(!isInventoryUsable())
|
||||
{
|
||||
llwarns << "Inventory is broken." << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
if((object_id == cat_id) || !is_in_map(mCategoryMap, cat_id))
|
||||
{
|
||||
llwarns << "Could not move inventory object " << object_id << " to "
|
||||
|
|
@ -1066,7 +1099,7 @@ void LLInventoryModel::backgroundFetch(void*)
|
|||
{
|
||||
// finished with this category, remove from queue
|
||||
sFetchQueue.pop_front();
|
||||
|
||||
|
||||
// add all children to queue
|
||||
parent_cat_map_t::iterator cat_it = gInventory.mParentChildCategoryTree.find(cat->getUUID());
|
||||
if (cat_it != gInventory.mParentChildCategoryTree.end())
|
||||
|
|
@ -1843,6 +1876,19 @@ void LLInventoryModel::buildParentChildMap()
|
|||
gAgent.sendReliableMessage();
|
||||
}
|
||||
}
|
||||
|
||||
const LLUUID& agent_inv_root_id = gAgent.getInventoryRootID();
|
||||
if (agent_inv_root_id.notNull())
|
||||
{
|
||||
cat_array_t* catsp = get_ptr_in_map(mParentChildCategoryTree, agent_inv_root_id);
|
||||
if(catsp)
|
||||
{
|
||||
// 'My Inventory',
|
||||
// root of the agent's inv found.
|
||||
// The inv tree is built.
|
||||
mIsAgentInvUsable = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct LLUUIDAndName
|
||||
|
|
@ -2675,7 +2721,6 @@ void LLInventoryModel::dumpInventory()
|
|||
llinfos << "\n**********************\nEnd Inventory Dump" << llendl;
|
||||
}
|
||||
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// LLInventoryCollectFunctor implementations
|
||||
///----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -142,6 +142,11 @@ public:
|
|||
BOOL include_trash,
|
||||
LLInventoryCollectFunctor& add);
|
||||
|
||||
// This method will return false if this inventory model is in an usabel state.
|
||||
// The inventory model usage is sensitive to the initial construction of the
|
||||
// model.
|
||||
bool isInventoryUsable();
|
||||
|
||||
//
|
||||
// Mutators
|
||||
//
|
||||
|
|
@ -408,6 +413,9 @@ protected:
|
|||
static F32 sMinTimeBetweenFetches;
|
||||
static F32 sMaxTimeBetweenFetches;
|
||||
|
||||
// This flag is used to handle an invalid inventory state.
|
||||
bool mIsAgentInvUsable;
|
||||
|
||||
public:
|
||||
// *NOTE: DEBUG functionality
|
||||
void dumpInventory();
|
||||
|
|
@ -777,3 +785,4 @@ protected:
|
|||
|
||||
|
||||
#endif // LL_LLINVENTORYMODEL_H
|
||||
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags)
|
|||
//Kill all particle systems owned by muted task
|
||||
if(localmute.mType == LLMute::AGENT || localmute.mType == LLMute::OBJECT)
|
||||
{
|
||||
gWorldPointer->mPartSim.cleanMutedParticles(localmute.mID);
|
||||
gWorldPointer->mPartSim.clearParticlesByOwnerID(localmute.mID);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
|
|
|
|||
|
|
@ -594,7 +594,7 @@ void LLPanelPermissions::refresh()
|
|||
{
|
||||
childSetValue("checkbox share with group",TRUE);
|
||||
childSetTentative("checkbox share with group",FALSE);
|
||||
childSetEnabled("button deed",gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && (owner_mask_on & PERM_TRANSFER) && !group_owned);
|
||||
childSetEnabled("button deed",gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && (owner_mask_on & PERM_TRANSFER) && !group_owned && can_transfer);
|
||||
}
|
||||
else if((group_mask_off & PERM_COPY) && (group_mask_off & PERM_MODIFY) && (group_mask_off & PERM_MOVE))
|
||||
{
|
||||
|
|
@ -606,7 +606,7 @@ void LLPanelPermissions::refresh()
|
|||
{
|
||||
childSetValue("checkbox share with group",TRUE);
|
||||
childSetTentative("checkbox share with group",true);
|
||||
childSetEnabled("button deed",gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && (group_mask_on & PERM_MOVE) && (owner_mask_on & PERM_TRANSFER) && !group_owned);
|
||||
childSetEnabled("button deed",gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && (group_mask_on & PERM_MOVE) && (owner_mask_on & PERM_TRANSFER) && !group_owned && can_transfer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -268,6 +268,12 @@ void LLPreviewGesture::onClose(bool app_quitting)
|
|||
LLPreview::onClose(app_quitting);
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPreviewGesture::onUpdateSucceeded()
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPreviewGesture::setMinimized(BOOL minimize)
|
||||
{
|
||||
|
|
@ -1100,19 +1106,29 @@ void LLPreviewGesture::saveIfNeeded()
|
|||
file.setMaxSize(size);
|
||||
file.write((U8*)buffer, size);
|
||||
|
||||
BOOL delayedUpload = FALSE;
|
||||
|
||||
// Upload that asset to the database
|
||||
const LLInventoryItem* item = getItem();
|
||||
LLViewerInventoryItem* item = (LLViewerInventoryItem*) getItem();
|
||||
if (item)
|
||||
{
|
||||
std::string agent_url = gAgent.getRegion()->getCapability("UpdateGestureAgentInventory");
|
||||
std::string task_url = gAgent.getRegion()->getCapability("UpdateGestureTaskInventory");
|
||||
if (mObjectUUID.isNull() && !agent_url.empty())
|
||||
{
|
||||
//need to disable the preview floater so item
|
||||
//isn't re-saved before new asset arrives
|
||||
//fake out refresh.
|
||||
item->setComplete(FALSE);
|
||||
refresh();
|
||||
item->setComplete(TRUE);
|
||||
|
||||
// Saving into agent inventory
|
||||
LLSD body;
|
||||
body["item_id"] = mItemUUID;
|
||||
LLHTTPClient::post(agent_url, body,
|
||||
new LLUpdateAgentInventoryResponder(body, asset_id, LLAssetType::AT_GESTURE));
|
||||
delayedUpload = TRUE;
|
||||
}
|
||||
else if (!mObjectUUID.isNull() && !task_url.empty())
|
||||
{
|
||||
|
|
@ -1133,7 +1149,7 @@ void LLPreviewGesture::saveIfNeeded()
|
|||
|
||||
// If this gesture is active, then we need to update the in-memory
|
||||
// active map with the new pointer.
|
||||
if (gGestureManager.isGestureActive(mItemUUID))
|
||||
if (!delayedUpload && gGestureManager.isGestureActive(mItemUUID))
|
||||
{
|
||||
// gesture manager now owns the pointer
|
||||
gGestureManager.replaceGesture(mItemUUID, gesture, asset_id);
|
||||
|
|
@ -1150,7 +1166,12 @@ void LLPreviewGesture::saveIfNeeded()
|
|||
}
|
||||
|
||||
mDirty = FALSE;
|
||||
refresh();
|
||||
// refresh will be called when callback
|
||||
// if triggered when delayedUpload
|
||||
if(!delayedUpload)
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
delete [] buffer;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ public:
|
|||
virtual BOOL canClose();
|
||||
virtual void setMinimized(BOOL minimize);
|
||||
virtual void onClose(bool app_quitting);
|
||||
virtual void onUpdateSucceeded();
|
||||
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -1643,7 +1643,6 @@ LLLiveLSLEditor::LLLiveLSLEditor(const std::string& name,
|
|||
|
||||
|
||||
setTitle(title);
|
||||
|
||||
}
|
||||
|
||||
LLLiveLSLEditor::~LLLiveLSLEditor()
|
||||
|
|
@ -1695,9 +1694,8 @@ void LLLiveLSLEditor::loadAsset(BOOL is_new)
|
|||
{
|
||||
// HACK! we "know" that mItemID refers to a LLViewerInventoryItem...
|
||||
LLViewerInventoryItem* item = (LLViewerInventoryItem*)object->getInventoryObject(mItemID);
|
||||
if(item
|
||||
&& (gAgent.allowOperation(PERM_COPY, item->getPermissions(),
|
||||
GP_OBJECT_MANIPULATE)
|
||||
if(item
|
||||
&& (gAgent.allowOperation(PERM_COPY, item->getPermissions(), GP_OBJECT_MANIPULATE)
|
||||
|| gAgent.isGodlike()))
|
||||
{
|
||||
mItem = new LLViewerInventoryItem(item);
|
||||
|
|
@ -1706,12 +1704,10 @@ void LLLiveLSLEditor::loadAsset(BOOL is_new)
|
|||
|
||||
if(!gAgent.isGodlike()
|
||||
&& (item
|
||||
&& (!gAgent.allowOperation(PERM_COPY, item->getPermissions(),
|
||||
GP_OBJECT_MANIPULATE)
|
||||
|| !gAgent.allowOperation(PERM_MODIFY,
|
||||
item->getPermissions(), GP_OBJECT_MANIPULATE))))
|
||||
|
||||
&& (!gAgent.allowOperation(PERM_COPY, item->getPermissions(), GP_OBJECT_MANIPULATE)
|
||||
|| !gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE))))
|
||||
{
|
||||
mItem = new LLViewerInventoryItem(item);
|
||||
mScriptEd->mEditor->setText("You are not allowed to view this script.");
|
||||
mScriptEd->mEditor->makePristine();
|
||||
mScriptEd->mEditor->setEnabled(FALSE);
|
||||
|
|
@ -1769,6 +1765,20 @@ void LLLiveLSLEditor::loadAsset(BOOL is_new)
|
|||
gMessageSystem->sendReliable(host);
|
||||
*/
|
||||
}
|
||||
|
||||
// Initialization of the asset failed. Probably the result
|
||||
// of a bug somewhere else. Set up this editor in a no-go mode.
|
||||
if(mItem.isNull())
|
||||
{
|
||||
// Set the inventory item to an incomplete item.
|
||||
// This may be better than having a accessible null pointer around,
|
||||
// though this newly allocated object will most likely be replaced.
|
||||
mItem = new LLViewerInventoryItem();
|
||||
mScriptEd->mEditor->setText("");
|
||||
mScriptEd->mEditor->makePristine();
|
||||
mScriptEd->mEditor->setEnabled(FALSE);
|
||||
mAssetStatus = PREVIEW_ASSET_LOADED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2016,6 +2026,14 @@ void LLLiveLSLEditor::saveIfNeeded()
|
|||
return;
|
||||
}
|
||||
|
||||
if(mItem.isNull() || !mItem->isComplete())
|
||||
{
|
||||
// $NOTE: While the error message may not be exactly correct,
|
||||
// it's pretty close.
|
||||
gViewerWindow->alertXml("SaveScriptFailObjectNotFound");
|
||||
return;
|
||||
}
|
||||
|
||||
// get the latest info about it. We used to be losing the script
|
||||
// name on save, because the viewer object version of the item,
|
||||
// and the editor version would get out of synch. Here's a good
|
||||
|
|
@ -2279,6 +2297,11 @@ void LLLiveLSLEditor::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* use
|
|||
delete data;
|
||||
}
|
||||
|
||||
void LLLiveLSLEditor::open()
|
||||
{
|
||||
LLFloater::open(); /*Flawfinder: ignore*/
|
||||
}
|
||||
|
||||
BOOL LLLiveLSLEditor::canClose()
|
||||
{
|
||||
return (mScriptEd->canClose());
|
||||
|
|
|
|||
|
|
@ -193,6 +193,9 @@ public:
|
|||
bool is_script_running);
|
||||
virtual void callbackLSLCompileFailed(const LLSD& compile_errors);
|
||||
|
||||
// Overide LLPreview::open() to avoid calling loadAsset twice.
|
||||
/*virtual*/ void open(); /*Flawfinder: ignore*/
|
||||
|
||||
protected:
|
||||
virtual BOOL canClose();
|
||||
void closeIfNeeded();
|
||||
|
|
|
|||
|
|
@ -4170,11 +4170,21 @@ void LLSelectMgr::sendListToRegions(const LLString& message_name,
|
|||
switch(send_type)
|
||||
{
|
||||
case SEND_ONLY_ROOTS:
|
||||
node = mSelectedObjects->getFirstRootNode();
|
||||
while(node)
|
||||
{
|
||||
nodes_to_send.push(node);
|
||||
node = mSelectedObjects->getNextRootNode();
|
||||
node = mSelectedObjects->getFirstRootNode();
|
||||
|
||||
while(node)
|
||||
{
|
||||
// look and see if this object is actually modifiable by the current agent, because if it's not, then there's little
|
||||
// point in pushing it up to the server to be updated, since we couldn't change it anywa.
|
||||
// That just results in errors on screen when this function gets called by other things, like pulling down a drop down menu
|
||||
LLViewerObject* object = node->getObject();
|
||||
if( object && (object->permModify() || gAgent.allowOperation(PERM_MODIFY, *node->mPermissions) || gAgent.allowOperation(PERM_MOVE, *node->mPermissions)))
|
||||
{
|
||||
nodes_to_send.push(node);
|
||||
}
|
||||
node = mSelectedObjects->getNextRootNode();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SEND_INDIVIDUALS:
|
||||
|
|
|
|||
|
|
@ -9,347 +9,25 @@
|
|||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llsrv.h"
|
||||
#include "llares.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#if LL_WINDOWS
|
||||
|
||||
#undef UNICODE
|
||||
#include <winsock2.h>
|
||||
#include <windns.h>
|
||||
|
||||
vector<LLSRVRecord> LLSRV::query(const string& name)
|
||||
struct Responder : public LLAres::UriRewriteResponder
|
||||
{
|
||||
vector<LLSRVRecord> recs;
|
||||
DNS_RECORD *rec;
|
||||
DNS_STATUS status;
|
||||
|
||||
status = DnsQuery(name.c_str(), DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &rec, NULL);
|
||||
if (!status)
|
||||
{
|
||||
for (DNS_RECORD *cur = rec; cur != NULL; cur = cur->pNext)
|
||||
std::vector<std::string> mUris;
|
||||
void rewriteResult(const std::vector<std::string> &uris) {
|
||||
for (size_t i = 0; i < uris.size(); i++)
|
||||
{
|
||||
if (cur->wType != DNS_TYPE_SRV)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
recs.push_back(LLSRVRecord(cur->Data.Srv.wPriority,
|
||||
cur->Data.Srv.wWeight,
|
||||
cur->Data.Srv.pNameTarget,
|
||||
cur->Data.Srv.wPort));
|
||||
llinfos << "[" << i << "] " << uris[i] << llendl;
|
||||
}
|
||||
DnsRecordListFree(rec, DnsFreeRecordListDeep);
|
||||
mUris = uris;
|
||||
}
|
||||
};
|
||||
|
||||
return recs;
|
||||
}
|
||||
|
||||
#else // !LL_WINDOWS
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <arpa/nameser_compat.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <netdb.h>
|
||||
|
||||
#ifdef HOMEGROWN_RESPONSE_PARSER
|
||||
|
||||
// We ought to be using libresolv's ns_initparse and ns_parserr to
|
||||
// parse the result of our query. However, libresolv isn't packaged
|
||||
// correctly on Linux (as of BIND 9), so neither of these functions is
|
||||
// available without statically linking against libresolv. Ugh! This
|
||||
// fallback function is available if we need to parse the response
|
||||
// ourselves without relying too much on libresolv. It is NOT THE
|
||||
// DEFAULT.
|
||||
|
||||
vector<LLSRVRecord> LLSRV::parseResponse(const unsigned char *response,
|
||||
int resp_len)
|
||||
std::vector<std::string> LLSRV::rewriteURI(const std::string& uri)
|
||||
{
|
||||
vector<LLSRVRecord> recs;
|
||||
LLPointer<Responder> resp = new Responder;
|
||||
|
||||
const unsigned char *pos = response + sizeof(HEADER);
|
||||
const unsigned char *end = response + resp_len;
|
||||
const HEADER *hdr = (const HEADER *) response;
|
||||
char name[1024];
|
||||
|
||||
// Skip over the query embedded in the response.
|
||||
|
||||
for (int q = ntohs(hdr->qdcount); q > 0; --q)
|
||||
{
|
||||
int len = dn_expand(response, end, pos, name, sizeof(name));
|
||||
|
||||
if (len == -1)
|
||||
{
|
||||
llinfos << "Could not expand queried name in RR response"
|
||||
<< llendl;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
pos += len + NS_QFIXEDSZ;
|
||||
}
|
||||
|
||||
for (int a = ntohs(hdr->ancount); a > 0; --a)
|
||||
{
|
||||
static const ns_rr *rr;
|
||||
|
||||
int len = dn_expand(response, end, pos, name, sizeof(name) - 1);
|
||||
if (len == -1)
|
||||
{
|
||||
llinfos << "Could not expand response name in RR response"
|
||||
<< llendl;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
// Skip over the resource name and headers we don't care about.
|
||||
|
||||
pos += len + sizeof(rr->type) + sizeof(rr->rr_class) +
|
||||
sizeof(rr->ttl) + sizeof(rr->rdlength);
|
||||
|
||||
U16 prio;
|
||||
U16 weight;
|
||||
U16 port;
|
||||
|
||||
NS_GET16(prio, pos);
|
||||
NS_GET16(weight, pos);
|
||||
NS_GET16(port, pos);
|
||||
|
||||
len = dn_expand(response, end, pos, name, sizeof(name) - 1);
|
||||
|
||||
if (len == -1)
|
||||
{
|
||||
llinfos << "Could not expand name in RR response" << llendl;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
recs.push_back(LLSRVRecord(prio, weight, name, port));
|
||||
}
|
||||
|
||||
// There are likely to be more records in the response, but we
|
||||
// don't care about those, at least for now.
|
||||
bail:
|
||||
return reorder(recs);
|
||||
}
|
||||
|
||||
#else // HOMEGROWN_RESPONSE_PARSER
|
||||
|
||||
// This version of the response parser is the one to use if libresolv
|
||||
// is available and behaving itself.
|
||||
|
||||
vector<LLSRVRecord> LLSRV::parseResponse(const unsigned char *response,
|
||||
int resp_len)
|
||||
{
|
||||
vector<LLSRVRecord> recs;
|
||||
ns_msg hdr;
|
||||
|
||||
if (ns_initparse(response, resp_len, &hdr))
|
||||
{
|
||||
llinfos << "Could not parse response" << llendl;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ns_msg_count(hdr, ns_s_an); i++)
|
||||
{
|
||||
ns_rr rr;
|
||||
|
||||
if (ns_parserr(&hdr, ns_s_an, i, &rr))
|
||||
{
|
||||
llinfos << "Could not parse RR" << llendl;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (ns_rr_type(rr) != ns_t_srv)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const unsigned char *pos = ns_rr_rdata(rr);
|
||||
U16 prio, weight, port;
|
||||
char name[1024];
|
||||
int ret;
|
||||
|
||||
NS_GET16(prio, pos);
|
||||
NS_GET16(weight, pos);
|
||||
NS_GET16(port, pos);
|
||||
|
||||
ret = dn_expand(ns_msg_base(hdr), ns_msg_end(hdr), pos,
|
||||
name, sizeof(name));
|
||||
|
||||
if (ret == -1)
|
||||
{
|
||||
llinfos << "Could not decompress name" << llendl;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
recs.push_back(LLSRVRecord(prio, weight, name, port));
|
||||
}
|
||||
|
||||
bail:
|
||||
return reorder(recs);
|
||||
}
|
||||
|
||||
#endif // HOMEGROWN_RESPONSE_PARSER
|
||||
|
||||
vector<LLSRVRecord> LLSRV::query(const string& queryName)
|
||||
{
|
||||
unsigned char response[16384];
|
||||
vector<LLSRVRecord> recs;
|
||||
int len;
|
||||
|
||||
len = res_query(queryName.c_str(), ns_c_in, ns_t_srv, response,
|
||||
sizeof(response));
|
||||
|
||||
if (len == -1)
|
||||
{
|
||||
llinfos << "Query failed for " << queryName << llendl;
|
||||
goto bail;
|
||||
}
|
||||
else if (len > (int) sizeof(response))
|
||||
{
|
||||
llinfos << "Response too big for " << queryName
|
||||
<< " (capacity " << sizeof(response)
|
||||
<< ", response " << len << ")" << llendl;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
recs = parseResponse(response, len);
|
||||
bail:
|
||||
return reorder(recs);
|
||||
}
|
||||
|
||||
#endif // LL_WINDOWS
|
||||
|
||||
// Implement the algorithm specified in RFC 2782 for dealing with RRs
|
||||
// of differing priorities and weights.
|
||||
vector<LLSRVRecord> LLSRV::reorder(vector<LLSRVRecord>& recs)
|
||||
{
|
||||
typedef list<const LLSRVRecord *> reclist_t;
|
||||
typedef map<U16, reclist_t> bucket_t;
|
||||
vector<LLSRVRecord> newRecs;
|
||||
bucket_t buckets;
|
||||
|
||||
// Don't rely on the DNS server to shuffle responses.
|
||||
|
||||
random_shuffle(recs.begin(), recs.end());
|
||||
|
||||
for (vector<LLSRVRecord>::const_iterator iter = recs.begin();
|
||||
iter != recs.end(); ++iter)
|
||||
{
|
||||
buckets[iter->priority()].push_back(&*iter);
|
||||
}
|
||||
|
||||
// Priorities take precedence over weights.
|
||||
|
||||
for (bucket_t::iterator iter = buckets.begin();
|
||||
iter != buckets.end(); ++iter)
|
||||
{
|
||||
reclist_t& myPrio = iter->second;
|
||||
reclist_t r;
|
||||
|
||||
// RRs with weight zero go to the front of the intermediate
|
||||
// list, so they'll have little chance of being chosen.
|
||||
// Larger weights have a higher likelihood of selection.
|
||||
|
||||
for (reclist_t::iterator i = myPrio.begin(); i != myPrio.end(); )
|
||||
{
|
||||
if ((*i)->weight() == 0)
|
||||
{
|
||||
r.push_back(*i);
|
||||
i = myPrio.erase(i);
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
r.insert(r.end(), myPrio.begin(), myPrio.end());
|
||||
|
||||
while (!r.empty())
|
||||
{
|
||||
U32 total = 0;
|
||||
|
||||
for (reclist_t::const_iterator i = r.begin(); i != r.end(); ++i)
|
||||
{
|
||||
total += (*i)->weight();
|
||||
}
|
||||
|
||||
U32 target = total > 1 ? (rand() % total) : 0;
|
||||
U32 partial = 0;
|
||||
|
||||
for (reclist_t::iterator i = r.begin(); i != r.end(); )
|
||||
{
|
||||
partial += (*i)->weight();
|
||||
if (partial >= target)
|
||||
{
|
||||
newRecs.push_back(**i);
|
||||
i = r.erase(i);
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Order RRs by lowest numeric priority. The stable sort
|
||||
// preserves the weight choices we made above.
|
||||
|
||||
stable_sort(newRecs.begin(), newRecs.end(),
|
||||
LLSRVRecord::ComparePriorityLowest());
|
||||
|
||||
return newRecs;
|
||||
}
|
||||
|
||||
vector<string> LLSRV::rewriteURI(const string& uriStr)
|
||||
{
|
||||
LLURI uri(uriStr);
|
||||
const string& scheme = uri.scheme();
|
||||
llinfos << "Rewriting " << uriStr << llendl;
|
||||
string serviceName("_" + scheme + "._tcp." + uri.hostName());
|
||||
llinfos << "Querying for " << serviceName << llendl;
|
||||
vector<LLSRVRecord> srvs(LLSRV::query(serviceName));
|
||||
vector<string> rewritten;
|
||||
|
||||
if (srvs.empty())
|
||||
{
|
||||
llinfos << "No query results; using " << uriStr << llendl;
|
||||
rewritten.push_back(uriStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
vector<LLSRVRecord>::const_iterator iter;
|
||||
size_t maxSrvs = 3;
|
||||
size_t i;
|
||||
|
||||
llinfos << "Got " << srvs.size() << " results" << llendl;
|
||||
for (iter = srvs.begin(); iter != srvs.end(); ++iter)
|
||||
{
|
||||
lldebugs << "host " << iter->target() << ':' << iter->port()
|
||||
<< " prio " << iter->priority()
|
||||
<< " weight " << iter->weight()
|
||||
<< llendl;
|
||||
}
|
||||
|
||||
if (srvs.size() > maxSrvs)
|
||||
{
|
||||
llinfos << "Clamping to " << maxSrvs << llendl;
|
||||
}
|
||||
|
||||
for (iter = srvs.begin(), i = 0;
|
||||
iter != srvs.end() && i < maxSrvs; ++iter, ++i)
|
||||
{
|
||||
LLURI newUri(scheme,
|
||||
uri.userName(),
|
||||
uri.password(),
|
||||
iter->target(),
|
||||
uri.defaultPort() ? iter->port() : uri.hostPort(),
|
||||
uri.escapedPath(),
|
||||
uri.escapedQuery());
|
||||
string newUriStr(newUri.asString());
|
||||
|
||||
llinfos << "Rewrite[" << i << "] " << newUriStr << llendl;
|
||||
|
||||
rewritten.push_back(newUriStr);
|
||||
}
|
||||
}
|
||||
|
||||
return rewritten;
|
||||
gAres->rewriteURI(uri, resp);
|
||||
gAres->processAll();
|
||||
return resp->mUris;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,52 +9,9 @@
|
|||
#ifndef LL_LLSRV_H
|
||||
#define LL_LLSRV_H
|
||||
|
||||
class LLSRV;
|
||||
|
||||
class LLSRVRecord
|
||||
{
|
||||
friend class LLSRV;
|
||||
|
||||
protected:
|
||||
U16 mPriority;
|
||||
U16 mWeight;
|
||||
std::string mTarget;
|
||||
U16 mPort;
|
||||
|
||||
public:
|
||||
LLSRVRecord(U16 priority, U16 weight, const std::string& target,
|
||||
U16 port) :
|
||||
mPriority(priority),
|
||||
mWeight(weight),
|
||||
mTarget(target),
|
||||
mPort(port) {
|
||||
}
|
||||
|
||||
U16 priority() const { return mPriority; }
|
||||
U16 weight() const { return mWeight; }
|
||||
const std::string& target() const { return mTarget; }
|
||||
U16 port() const { return mPort; }
|
||||
|
||||
struct ComparePriorityLowest
|
||||
{
|
||||
bool operator()(const LLSRVRecord& lhs, const LLSRVRecord& rhs)
|
||||
{
|
||||
return lhs.mPriority < rhs.mPriority;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class LLSRV
|
||||
{
|
||||
protected:
|
||||
#ifndef LL_WINDOWS
|
||||
static std::vector<LLSRVRecord> parseResponse(const unsigned char *response,
|
||||
int resp_len);
|
||||
#endif
|
||||
static std::vector<LLSRVRecord> reorder(std::vector<LLSRVRecord>& recs);
|
||||
|
||||
public:
|
||||
static std::vector<LLSRVRecord> query(const std::string& name);
|
||||
static std::vector<std::string> rewriteURI(const std::string& uri);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#endif
|
||||
|
||||
#include "audiosettings.h"
|
||||
#include "llares.h"
|
||||
#include "llcachename.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "lldir.h"
|
||||
|
|
@ -53,7 +54,6 @@
|
|||
|
||||
#include "llagent.h"
|
||||
#include "llagentpilot.h"
|
||||
#include "llasynchostbyname.h"
|
||||
#include "llfloateravatarpicker.h"
|
||||
#include "llcallbacklist.h"
|
||||
#include "llcallingcard.h"
|
||||
|
|
@ -269,6 +269,9 @@ void update_texture_fetch()
|
|||
gImageList.updateImages(0.10f);
|
||||
}
|
||||
|
||||
static std::vector<std::string> sAuthUris;
|
||||
static int sAuthUriNum = -1;
|
||||
|
||||
// Returns FALSE to skip other idle processing. Should only return
|
||||
// TRUE when all initialization done.
|
||||
BOOL idle_startup()
|
||||
|
|
@ -287,8 +290,6 @@ BOOL idle_startup()
|
|||
// auth/transform loop will do.
|
||||
static F32 progress = 0.10f;
|
||||
|
||||
static std::vector<std::string> auth_uris;
|
||||
static int auth_uri_num = -1;
|
||||
static std::string auth_method;
|
||||
static std::string auth_desc;
|
||||
static std::string auth_message;
|
||||
|
|
@ -402,6 +403,11 @@ BOOL idle_startup()
|
|||
// Load the throttle settings
|
||||
gViewerThrottle.load();
|
||||
|
||||
if (ll_init_ares() == NULL)
|
||||
{
|
||||
llerrs << "Could not start address resolution system" << llendl;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize messaging system
|
||||
//
|
||||
|
|
@ -548,7 +554,10 @@ BOOL idle_startup()
|
|||
#endif // LL_LINUX
|
||||
|
||||
std::ostringstream codec;
|
||||
codec << "[Second Life " << LL_VERSION_MAJOR << "." << LL_VERSION_MINOR << "." << LL_VERSION_PATCH << "." << LL_VERSION_BUILD << "]";
|
||||
codec << "[Second Life ";
|
||||
codec << "(" << gChannelName << ")";
|
||||
codec << " - " << LL_VERSION_MAJOR << "." << LL_VERSION_MINOR << "." << LL_VERSION_PATCH << "." << LL_VERSION_BUILD;
|
||||
codec << "]";
|
||||
LLMozLib::getInstance()->setBrowserAgentId( codec.str() );
|
||||
#endif
|
||||
|
||||
|
|
@ -758,7 +767,7 @@ BOOL idle_startup()
|
|||
|
||||
if ( user_picked_server )
|
||||
{ // User picked a grid from the popup, so clear the stored urls and they will be re-generated from gUserServerChoice
|
||||
auth_uris.clear();
|
||||
sAuthUris.clear();
|
||||
resetURIs();
|
||||
}
|
||||
|
||||
|
|
@ -872,11 +881,11 @@ BOOL idle_startup()
|
|||
gSavedSettings.setBOOL("UseDebugMenus", TRUE);
|
||||
requested_options.push_back("god-connect");
|
||||
}
|
||||
if (auth_uris.empty())
|
||||
if (sAuthUris.empty())
|
||||
{
|
||||
auth_uris = getLoginURIs();
|
||||
sAuthUris = getLoginURIs();
|
||||
}
|
||||
auth_uri_num = 0;
|
||||
sAuthUriNum = 0;
|
||||
auth_method = "login_to_simulator";
|
||||
auth_desc = "Logging in. ";
|
||||
auth_desc += gSecondLife;
|
||||
|
|
@ -919,7 +928,7 @@ BOOL idle_startup()
|
|||
hashed_mac.hex_digest(hashed_mac_string);
|
||||
|
||||
gUserAuthp->authenticate(
|
||||
auth_uris[auth_uri_num].c_str(),
|
||||
sAuthUris[sAuthUriNum].c_str(),
|
||||
auth_method.c_str(),
|
||||
firstname.c_str(),
|
||||
lastname.c_str(),
|
||||
|
|
@ -1015,8 +1024,8 @@ BOOL idle_startup()
|
|||
else if(login_response && (0 == strcmp(login_response, "indeterminate")))
|
||||
{
|
||||
llinfos << "Indeterminate login..." << llendl;
|
||||
auth_uris = LLSRV::rewriteURI(gUserAuthp->getResponse("next_url"));
|
||||
auth_uri_num = 0;
|
||||
sAuthUris = LLSRV::rewriteURI(gUserAuthp->getResponse("next_url"));
|
||||
sAuthUriNum = 0;
|
||||
auth_method = gUserAuthp->getResponse("next_method");
|
||||
auth_message = gUserAuthp->getResponse("message");
|
||||
if(auth_method.substr(0, 5) == "login")
|
||||
|
|
@ -1121,18 +1130,18 @@ BOOL idle_startup()
|
|||
case LLUserAuth::E_SSL_CACERT:
|
||||
case LLUserAuth::E_SSL_CONNECT_ERROR:
|
||||
default:
|
||||
if (auth_uri_num >= (int) auth_uris.size() - 1)
|
||||
if (sAuthUriNum >= (int) sAuthUris.size() - 1)
|
||||
{
|
||||
emsg << "Unable to connect to " << gSecondLife << ".\n";
|
||||
emsg << gUserAuthp->errorMessage();
|
||||
} else {
|
||||
auth_uri_num++;
|
||||
sAuthUriNum++;
|
||||
std::ostringstream s;
|
||||
s << "Previous login attempt failed. Logging in, attempt "
|
||||
<< (auth_uri_num + 1) << ". ";
|
||||
<< (sAuthUriNum + 1) << ". ";
|
||||
auth_desc = s.str();
|
||||
LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE );
|
||||
auth_uri_num++;
|
||||
sAuthUriNum++;
|
||||
return do_normal_idle;
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -25,8 +25,6 @@
|
|||
#include "llvovolume.h"
|
||||
#include "llworld.h"
|
||||
|
||||
BOOL LLViewerCamera::sDisableCameraConstraints = FALSE;
|
||||
|
||||
LLViewerCamera *gCamera = NULL;
|
||||
|
||||
LLViewerCamera::LLViewerCamera() : LLCamera()
|
||||
|
|
|
|||
|
|
@ -83,7 +83,6 @@ protected:
|
|||
S16 mZoomSubregion;
|
||||
|
||||
public:
|
||||
static BOOL sDisableCameraConstraints;
|
||||
F64 mGLProjectionMatrix[16];
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -748,9 +748,12 @@ void init_client_menu(LLMenuGL* menu)
|
|||
NULL,
|
||||
&menu_check_control,
|
||||
(void*)"HighResSnapshot"));
|
||||
|
||||
menu->append(new LLMenuItemToggleGL("Quiet Snapshots to Disk",
|
||||
&gQuietSnapshot));
|
||||
|
||||
menu->append(new LLMenuItemCheckGL( "Quiet Snapshots to Disk",
|
||||
&menu_toggle_control,
|
||||
NULL,
|
||||
&menu_check_control,
|
||||
(void*)"QuietSnapshotsToDisk"));
|
||||
|
||||
menu->append(new LLMenuItemCheckGL( "Compress Snapshots to Disk",
|
||||
&menu_toggle_control,
|
||||
|
|
@ -877,8 +880,11 @@ void init_client_menu(LLMenuGL* menu)
|
|||
&menu_check_control,
|
||||
(void*)"LimitSelectDistance"));
|
||||
|
||||
menu->append(new LLMenuItemToggleGL("Disable Camera Constraints",
|
||||
&LLViewerCamera::sDisableCameraConstraints, 'C', MASK_ALT | MASK_CONTROL ));
|
||||
menu->append(new LLMenuItemCheckGL("Disable Camera Constraints",
|
||||
&menu_toggle_control,
|
||||
NULL,
|
||||
&menu_check_control,
|
||||
(void*)"DisableCameraConstraints"));
|
||||
|
||||
menu->append(new LLMenuItemCheckGL("Joystick Flycam",
|
||||
&handle_toggle_flycam,NULL,&check_flycam,NULL));
|
||||
|
|
|
|||
|
|
@ -379,7 +379,7 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
|
|||
gSavedSettings.getBOOL("RenderUIInSnapshot"),
|
||||
FALSE))
|
||||
{
|
||||
if (!gQuietSnapshot)
|
||||
if (!gSavedSettings.getBOOL("QuietSnapshotsToDisk"))
|
||||
{
|
||||
gViewerWindow->playSnapshotAnimAndSound();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1084,7 +1084,7 @@ void inventory_offer_callback(S32 button, void* user_data)
|
|||
// Generates IM_INVENTORY_DECLINED, IM_TASK_INVENTORY_DECLINED,
|
||||
// or IM_GROUP_NOTICE_INVENTORY_DECLINED
|
||||
default:
|
||||
// close button probably
|
||||
// close button probably (or any of the fall-throughs from above)
|
||||
msg->addU8Fast(_PREHASH_Dialog, (U8)(info->mIM + 2));
|
||||
msg->addBinaryDataFast(_PREHASH_BinaryBucket, EMPTY_BINARY_BUCKET, EMPTY_BINARY_BUCKET_SIZE);
|
||||
// send the message
|
||||
|
|
@ -1119,7 +1119,7 @@ void inventory_offer_callback(S32 button, void* user_data)
|
|||
}
|
||||
|
||||
}
|
||||
if (busy || (!info->mFromGroup && !info->mFromObject))
|
||||
if (busy && (!info->mFromGroup && !info->mFromObject))
|
||||
{
|
||||
busy_message(msg,info->mFromID);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -625,6 +625,29 @@ BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp)
|
|||
return ret;
|
||||
}
|
||||
|
||||
// Show or hide particles, icon and HUD
|
||||
void LLViewerObject::hideExtraDisplayItems( BOOL hidden )
|
||||
{
|
||||
if( mPartSourcep.notNull() )
|
||||
{
|
||||
LLViewerPartSourceScript *partSourceScript = mPartSourcep.get();
|
||||
partSourceScript->setSuspended( hidden );
|
||||
}
|
||||
|
||||
if( mText.notNull() )
|
||||
{
|
||||
LLHUDText *hudText = mText.get();
|
||||
hudText->setHidden( hidden );
|
||||
}
|
||||
|
||||
if( mIcon.notNull() )
|
||||
{
|
||||
LLHUDIcon *hudIcon = mIcon.get();
|
||||
hudIcon->setHidden( hidden );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
||||
void **user_data,
|
||||
U32 block_num,
|
||||
|
|
@ -1576,23 +1599,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
sent_parentp->addChild(this);
|
||||
}
|
||||
|
||||
if( mPartSourcep.notNull() )
|
||||
{
|
||||
LLViewerPartSourceScript *partSourceScript = mPartSourcep.get();
|
||||
partSourceScript->setSuspended( FALSE );
|
||||
}
|
||||
|
||||
if( mText.notNull() )
|
||||
{
|
||||
LLHUDText *hudText = mText.get();
|
||||
hudText->setHidden( FALSE );
|
||||
}
|
||||
|
||||
if( mIcon.notNull() )
|
||||
{
|
||||
LLHUDIcon *hudIcon = mIcon.get();
|
||||
hudIcon->setHidden( FALSE );
|
||||
}
|
||||
// Show particles, icon and HUD
|
||||
hideExtraDisplayItems( FALSE );
|
||||
|
||||
setChanged(MOVED | SILHOUETTE);
|
||||
}
|
||||
|
|
@ -1608,23 +1616,9 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
U32 port = mesgsys->getSenderPort();
|
||||
|
||||
gObjectList.orphanize(this, parent_id, ip, port);
|
||||
if( mPartSourcep.notNull() )
|
||||
{
|
||||
LLViewerPartSourceScript *partSourceScript = mPartSourcep.get();
|
||||
partSourceScript->setSuspended( TRUE );
|
||||
}
|
||||
|
||||
if( mText.notNull() )
|
||||
{
|
||||
LLHUDText *hudText = mText.get();
|
||||
hudText->setHidden( TRUE );
|
||||
}
|
||||
|
||||
if( mIcon.notNull() )
|
||||
{
|
||||
LLHUDIcon *hudIcon = mIcon.get();
|
||||
hudIcon->setHidden( TRUE );
|
||||
}
|
||||
// Hide particles, icon and HUD
|
||||
hideExtraDisplayItems( TRUE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -517,6 +517,9 @@ protected:
|
|||
|
||||
BOOL setData(const U8 *datap, const U32 data_size);
|
||||
|
||||
// Hide or show HUD, icon and particles
|
||||
void hideExtraDisplayItems( BOOL hidden );
|
||||
|
||||
//////////////////////////
|
||||
//
|
||||
// inventory functionality
|
||||
|
|
|
|||
|
|
@ -1439,6 +1439,10 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port)
|
|||
childp->mDrawable->setState(LLDrawable::CLEAR_INVISIBLE);
|
||||
childp->setDrawableParent(objectp->mDrawable); // LLViewerObjectList::findOrphans()
|
||||
}
|
||||
|
||||
// Make certain particles, icon and HUD aren't hidden
|
||||
childp->hideExtraDisplayItems( FALSE );
|
||||
|
||||
objectp->addChild(childp);
|
||||
orphans_found = TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -397,6 +397,18 @@ void LLViewerPartGroup::shift(const LLVector3 &offset)
|
|||
}
|
||||
}
|
||||
|
||||
void LLViewerPartGroup::removeParticlesByID(const U32 source_id)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_PARTICLES);
|
||||
S32 end = (S32) mParticles.size();
|
||||
for (int i = 0; i < end; i++)
|
||||
{
|
||||
if(mParticles[i]->mPartSourcep->getID() == source_id)
|
||||
{
|
||||
mParticles[i]->mFlags = LLViewerPart::LL_PART_DEAD_MASK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
//
|
||||
|
|
@ -664,6 +676,10 @@ void LLViewerPartSim::addPartSource(LLPointer<LLViewerPartSource> sourcep)
|
|||
mViewerPartSources.push_back(sourcep);
|
||||
}
|
||||
|
||||
void LLViewerPartSim::removeLastCreatedSource()
|
||||
{
|
||||
mViewerPartSources.pop_back();
|
||||
}
|
||||
|
||||
void LLViewerPartSim::cleanupRegion(LLViewerRegion *regionp)
|
||||
{
|
||||
|
|
@ -680,16 +696,32 @@ void LLViewerPartSim::cleanupRegion(LLViewerRegion *regionp)
|
|||
}
|
||||
}
|
||||
|
||||
void LLViewerPartSim::cleanMutedParticles(const LLUUID& task_id)
|
||||
void LLViewerPartSim::clearParticlesByID(const U32 system_id)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_PARTICLES);
|
||||
for (source_list_t::iterator i = mViewerPartSources.begin(); i != mViewerPartSources.end(); )
|
||||
for (group_list_t::iterator g = mViewerPartGroups.begin(); g != mViewerPartGroups.end(); ++g)
|
||||
{
|
||||
source_list_t::iterator iter = i++;
|
||||
(*g)->removeParticlesByID(system_id);
|
||||
}
|
||||
for (source_list_t::iterator i = mViewerPartSources.begin(); i != mViewerPartSources.end(); ++i)
|
||||
{
|
||||
if ((*i)->getID() == system_id)
|
||||
{
|
||||
(*i)->setDead();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLViewerPartSim::clearParticlesByOwnerID(const LLUUID& task_id)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_PARTICLES);
|
||||
for (source_list_t::iterator iter = mViewerPartSources.begin(); iter != mViewerPartSources.end(); ++iter)
|
||||
{
|
||||
if ((*iter)->getOwnerUUID() == task_id)
|
||||
{
|
||||
i = mViewerPartSources.erase(iter);
|
||||
clearParticlesByID((*iter)->getID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,6 +87,8 @@ public:
|
|||
S32 getCount() const { return (S32) mParticles.size(); }
|
||||
LLViewerRegion *getRegion() const { return mRegionp; }
|
||||
|
||||
void removeParticlesByID(const U32 source_id);
|
||||
|
||||
LLPointer<LLVOPartGroup> mVOPartGroupp;
|
||||
|
||||
BOOL mUniformParticles;
|
||||
|
|
@ -106,10 +108,14 @@ protected:
|
|||
|
||||
class LLViewerPartSim
|
||||
{
|
||||
|
||||
public:
|
||||
LLViewerPartSim();
|
||||
virtual ~LLViewerPartSim();
|
||||
|
||||
typedef std::vector<LLViewerPartGroup *> group_list_t;
|
||||
typedef std::vector<LLPointer<LLViewerPartSource> > source_list_t;
|
||||
|
||||
void shift(const LLVector3 &offset);
|
||||
|
||||
void updateSimulation();
|
||||
|
|
@ -120,7 +126,11 @@ public:
|
|||
|
||||
BOOL shouldAddPart(); // Just decides whether this particle should be added or not (for particle count capping)
|
||||
void addPart(LLViewerPart* part);
|
||||
void cleanMutedParticles(const LLUUID& task_id);
|
||||
void clearParticlesByID(const U32 system_id);
|
||||
void clearParticlesByOwnerID(const LLUUID& task_id);
|
||||
void removeLastCreatedSource();
|
||||
|
||||
const source_list_t* getParticleSystemList() const { return &mViewerPartSources; }
|
||||
|
||||
friend class LLViewerPartGroup;
|
||||
|
||||
|
|
@ -138,8 +148,6 @@ protected:
|
|||
LLViewerPartGroup *put(LLViewerPart* part);
|
||||
|
||||
protected:
|
||||
typedef std::vector<LLViewerPartGroup *> group_list_t;
|
||||
typedef std::vector<LLPointer<LLViewerPartSource> > source_list_t;
|
||||
group_list_t mViewerPartGroups;
|
||||
source_list_t mViewerPartSources;
|
||||
LLFrameTimer mSimulationTimer;
|
||||
|
|
|
|||
|
|
@ -47,7 +47,15 @@ void LLViewerPartSource::update(const F32 dt)
|
|||
llerrs << "Creating default part source!" << llendl;
|
||||
}
|
||||
|
||||
|
||||
LLUUID LLViewerPartSource::getImageUUID() const
|
||||
{
|
||||
LLViewerImage* imagep = mImagep;
|
||||
if(imagep)
|
||||
{
|
||||
return imagep->getID();
|
||||
}
|
||||
return LLUUID::null;
|
||||
}
|
||||
|
||||
LLViewerPartSourceScript::LLViewerPartSourceScript(LLViewerObject *source_objp) :
|
||||
LLViewerPartSource(LL_PART_SOURCE_SCRIPT)
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ public:
|
|||
static void updatePart(LLViewerPart &part, const F32 dt);
|
||||
void setOwnerUUID(const LLUUID& owner_id) { mOwnerUUID = owner_id; }
|
||||
LLUUID getOwnerUUID() const { return mOwnerUUID; }
|
||||
U32 getID() const { return mID; }
|
||||
LLUUID getImageUUID() const;
|
||||
|
||||
LLVector3 mPosAgent; // Location of the particle source
|
||||
LLVector3 mTargetPosAgent; // Location of the target position
|
||||
|
|
@ -62,7 +64,8 @@ protected:
|
|||
F32 mLastUpdateTime;
|
||||
F32 mLastPartTime;
|
||||
LLUUID mOwnerUUID;
|
||||
|
||||
LLPointer<LLViewerImage> mImagep;
|
||||
|
||||
// Particle information
|
||||
U32 mPartFlags; // Flags for the particle
|
||||
};
|
||||
|
|
@ -100,7 +103,6 @@ public:
|
|||
|
||||
protected:
|
||||
LLQuaternion mRotation; // Current rotation for particle source
|
||||
LLPointer<LLViewerImage> mImagep; // Cached image pointer of the mPartSysData UUID
|
||||
LLPointer<LLViewerObject> mTargetObjectp; // Target object for the particle source
|
||||
};
|
||||
|
||||
|
|
@ -125,7 +127,6 @@ public:
|
|||
static void updatePart(LLViewerPart &part, const F32 dt);
|
||||
LLColor4 mColor;
|
||||
protected:
|
||||
LLPointer<LLViewerImage> mImagep;
|
||||
LLVector3d mLKGSourcePosGlobal;
|
||||
};
|
||||
|
||||
|
|
@ -151,7 +152,6 @@ public:
|
|||
void setColor(const LLColor4 &color);
|
||||
|
||||
static void updatePart(LLViewerPart &part, const F32 dt);
|
||||
LLPointer<LLViewerImage> mImagep;
|
||||
LLPointer<LLViewerObject> mTargetObjectp;
|
||||
LLVector3d mLKGTargetPosGlobal;
|
||||
LLColor4 mColor;
|
||||
|
|
@ -177,11 +177,9 @@ public:
|
|||
|
||||
void setSourceObject(LLViewerObject *objp);
|
||||
void setColor(const LLColor4 &color);
|
||||
|
||||
static void updatePart(LLViewerPart &part, const F32 dt);
|
||||
LLColor4 mColor;
|
||||
protected:
|
||||
LLPointer<LLViewerImage> mImagep;
|
||||
LLVector3d mLKGSourcePosGlobal;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -365,7 +365,6 @@ void reset_viewer_state_on_sim(void);
|
|||
|
||||
extern LLVelocityBar* gVelocityBar;
|
||||
extern LLViewerWindow* gViewerWindow;
|
||||
extern BOOL gQuietSnapshot;
|
||||
|
||||
extern LLFrameTimer gMouseIdleTimer; // how long has it been since the mouse last moved?
|
||||
extern LLFrameTimer gAwayTimer; // tracks time before setting the avatar away state to true
|
||||
|
|
|
|||
|
|
@ -1361,7 +1361,7 @@ void LLVoiceClient::stateMachine()
|
|||
sGatewayPID = id;
|
||||
}
|
||||
#endif // LL_WINDOWS
|
||||
mDaemonHost = LLHost("127.0.0.1", 44124);
|
||||
mDaemonHost = LLHost(gSavedSettings.getString("VoiceHost").c_str(), gSavedSettings.getU32("VoicePort"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1374,7 +1374,7 @@ void LLVoiceClient::stateMachine()
|
|||
// To do this, launch the gateway on a nearby host like this:
|
||||
// vivox-gw.exe -p tcp -i 0.0.0.0:44124
|
||||
// and put that host's IP address here.
|
||||
mDaemonHost = LLHost("127.0.0.1", 44124);
|
||||
mDaemonHost = LLHost(gSavedSettings.getString("VoiceHost").c_str(), gSavedSettings.getU32("VoicePort"));
|
||||
}
|
||||
|
||||
mUpdateTimer.start();
|
||||
|
|
|
|||
|
|
@ -258,7 +258,7 @@ class WindowsManifest(ViewerManifest):
|
|||
if self.default_channel():
|
||||
if self.default_grid():
|
||||
# release viewer
|
||||
installer_file = "Second Life %(version_dashes)s Setup.exe"
|
||||
installer_file = "Second_Life_%(version_dashes)s_Setup.exe"
|
||||
grid_vars_template = """
|
||||
OutFile "%(installer_file)s"
|
||||
!define INSTFLAGS "%(flags)s"
|
||||
|
|
@ -269,7 +269,7 @@ class WindowsManifest(ViewerManifest):
|
|||
"""
|
||||
else:
|
||||
# beta grid viewer
|
||||
installer_file = "Second Life %(version_dashes)s (%(grid_caps)s) Setup.exe"
|
||||
installer_file = "Second_Life_%(version_dashes)s_(%(grid_caps)s)_Setup.exe"
|
||||
grid_vars_template = """
|
||||
OutFile "%(installer_file)s"
|
||||
!define INSTFLAGS "%(flags)s"
|
||||
|
|
@ -281,7 +281,7 @@ class WindowsManifest(ViewerManifest):
|
|||
"""
|
||||
else:
|
||||
# some other channel on some grid
|
||||
installer_file = "Second Life %(version_dashes)s %(channel_unique)s Setup.exe"
|
||||
installer_file = "Second_Life_%(version_dashes)s_%(channel_oneword)s_Setup.exe"
|
||||
grid_vars_template = """
|
||||
OutFile "%(installer_file)s"
|
||||
!define INSTFLAGS "%(flags)s"
|
||||
|
|
@ -475,11 +475,6 @@ class Linux_i686Manifest(LinuxManifest):
|
|||
self.path("libapr-1.so.0")
|
||||
self.path("libaprutil-1.so.0")
|
||||
self.path("libdb-4.2.so")
|
||||
self.path("libogg.so.0")
|
||||
self.path("libvorbis.so.0")
|
||||
self.path("libvorbisfile.so.0")
|
||||
self.path("libvorbisenc.so.0")
|
||||
self.path("libcurl.so.4")
|
||||
self.path("libcrypto.so.0.9.7")
|
||||
self.path("libssl.so.0.9.7")
|
||||
self.path("libexpat.so.1")
|
||||
|
|
@ -487,7 +482,6 @@ class Linux_i686Manifest(LinuxManifest):
|
|||
self.path("libuuid.so", "libuuid.so.1")
|
||||
self.path("libSDL-1.2.so.0")
|
||||
self.path("libELFIO.so")
|
||||
self.path("libresolv.so", "libresolv.so.2")
|
||||
#self.path("libtcmalloc.so.0") - bugged
|
||||
#self.path("libstacktrace.so.0") - probably bugged
|
||||
self.path("libllkdu.so", "../bin/libllkdu.so") # llkdu goes in bin for some reason
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include "lldir.h"
|
||||
#include "lltimer.h"
|
||||
#include "llframetimer.h"
|
||||
#include "llsdutil.h"
|
||||
|
||||
namespace tut
|
||||
{
|
||||
|
|
@ -23,30 +24,30 @@ namespace tut
|
|||
|
||||
LLMessageConfigTestData()
|
||||
{
|
||||
LLUUID random;
|
||||
random.generate();
|
||||
// generate temp dir
|
||||
mTestConfigDir = "/tmp/llmessage-config-test";
|
||||
std::ostringstream oStr;
|
||||
oStr << "/tmp/llmessage-config-test-" << random;
|
||||
mTestConfigDir = oStr.str();
|
||||
LLFile::mkdir(mTestConfigDir.c_str());
|
||||
|
||||
writeConfigFile(LLSD());
|
||||
LLMessageConfig::initClass("simulator", mTestConfigDir);
|
||||
}
|
||||
|
||||
~LLMessageConfigTestData()
|
||||
{
|
||||
// rm contents of temp dir
|
||||
gDirUtilp->deleteFilesInDir(mTestConfigDir, "*");
|
||||
int rmfile = LLFile::remove((mTestConfigDir + "/message.xml").c_str());
|
||||
ensure_equals("rmfile value", rmfile, 0);
|
||||
// rm temp dir
|
||||
LLFile::rmdir(mTestConfigDir.c_str());
|
||||
int rmdir = LLFile::rmdir(mTestConfigDir.c_str());
|
||||
ensure_equals("rmdir value", rmdir, 0);
|
||||
}
|
||||
|
||||
void reloadConfig(const LLSD& config)
|
||||
{
|
||||
LLMessageConfig::useConfig(config);
|
||||
}
|
||||
|
||||
void writeConfigFile(const LLSD& config)
|
||||
{
|
||||
std::string configFile = mTestConfigDir + "/message.xml";
|
||||
llofstream file(configFile.c_str());
|
||||
llofstream file((mTestConfigDir + "/message.xml").c_str());
|
||||
if (file.is_open())
|
||||
{
|
||||
LLSDSerialize::toPrettyXML(config, file);
|
||||
|
|
@ -65,7 +66,7 @@ namespace tut
|
|||
{
|
||||
LLSD config;
|
||||
config["serverDefaults"]["simulator"] = "template";
|
||||
reloadConfig(config);
|
||||
LLMessageConfig::useConfig(config);
|
||||
ensure_equals("Ensure server default is not template",
|
||||
LLMessageConfig::getServerDefaultFlavor(),
|
||||
LLMessageConfig::TEMPLATE_FLAVOR);
|
||||
|
|
@ -79,7 +80,7 @@ namespace tut
|
|||
config["serverDefaults"]["simulator"] = "template";
|
||||
config["messages"]["msg1"]["flavor"] = "template";
|
||||
config["messages"]["msg2"]["flavor"] = "llsd";
|
||||
reloadConfig(config);
|
||||
LLMessageConfig::useConfig(config);
|
||||
ensure_equals("Ensure msg template flavor",
|
||||
LLMessageConfig::getMessageFlavor("msg1"),
|
||||
LLMessageConfig::TEMPLATE_FLAVOR);
|
||||
|
|
@ -95,7 +96,7 @@ namespace tut
|
|||
LLSD config;
|
||||
config["serverDefaults"]["simulator"] = "llsd";
|
||||
config["messages"]["msg1"]["trusted-sender"] = true;
|
||||
reloadConfig(config);
|
||||
LLMessageConfig::useConfig(config);
|
||||
ensure_equals("Ensure missing message gives no flavor",
|
||||
LLMessageConfig::getMessageFlavor("Test"),
|
||||
LLMessageConfig::NO_FLAVOR);
|
||||
|
|
@ -117,7 +118,7 @@ namespace tut
|
|||
config["messages"]["msg1"]["trusted-sender"] = false;
|
||||
config["messages"]["msg2"]["flavor"] = "llsd";
|
||||
config["messages"]["msg2"]["trusted-sender"] = true;
|
||||
reloadConfig(config);
|
||||
LLMessageConfig::useConfig(config);
|
||||
ensure_equals("Ensure untrusted is untrusted",
|
||||
LLMessageConfig::getSenderTrustedness("msg1"),
|
||||
LLMessageConfig::UNTRUSTED);
|
||||
|
|
@ -136,7 +137,7 @@ namespace tut
|
|||
LLSD config;
|
||||
config["serverDefaults"]["simulator"] = "template";
|
||||
config["messages"]["msg1"]["flavor"] = "llsd";
|
||||
reloadConfig(config);
|
||||
LLMessageConfig::useConfig(config);
|
||||
ensure_equals("Ensure msg1 exists, has llsd flavor",
|
||||
LLMessageConfig::getMessageFlavor("msg1"),
|
||||
LLMessageConfig::LLSD_FLAVOR);
|
||||
|
|
@ -151,7 +152,7 @@ namespace tut
|
|||
LLSD config;
|
||||
config["capBans"]["MapLayer"] = true;
|
||||
config["capBans"]["MapLayerGod"] = false;
|
||||
reloadConfig(config);
|
||||
LLMessageConfig::useConfig(config);
|
||||
ensure_equals("Ensure cap ban true MapLayer",
|
||||
LLMessageConfig::isCapBanned("MapLayer"),
|
||||
true);
|
||||
|
|
|
|||
Loading…
Reference in New Issue