diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llmessage/message.cpp | 3 | ||||
| -rw-r--r-- | indra/newview/llappviewer.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/llviewercontrol.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.cpp | 324 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.h | 2 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.cpp | 21 | 
6 files changed, 124 insertions, 228 deletions
| diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index 31acc65642..5de29ba66f 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -307,12 +307,15 @@ void LLMessageSystem::loadTemplateFile(const std::string& filename, bool failure  	LLTemplateTokenizer tokens(template_body);  	LLTemplateParser parsed(tokens);  	mMessageFileVersionNumber = parsed.getVersion(); +    S32 count                 = 0;  	for(LLTemplateParser::message_iterator iter = parsed.getMessagesBegin();  		iter != parsed.getMessagesEnd();  		iter++)  	{  		addTemplate(*iter); +        count++;  	} +    LL_INFOS("Messaging") << "Read " << count << " messages from " << filename << LL_ENDL;  } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 4a43133ff6..557ee1ab16 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2342,6 +2342,7 @@ void LLAppViewer::initLoggingAndGetLastDuration()          // Set the log file to SecondLife.log          LLError::logToFile(log_file); +        LL_INFOS() << "Started logging to " << log_file << LL_ENDL;          if (!duration_log_msg.empty())          {              LL_WARNS("MarkerFile") << duration_log_msg << LL_ENDL; diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 7738cb904e..61cc1dee25 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -450,6 +450,7 @@ static bool handleLogFileChanged(const LLSD& newvalue)  	std::string log_filename = newvalue.asString();  	LLFile::remove(log_filename);  	LLError::logToFile(log_filename); +    LL_INFOS() << "Logging switched to " << log_filename << LL_ENDL;  	return true;  } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index d4346ee2d9..c4e5fcc7b6 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -1159,6 +1159,20 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,      LL_DEBUGS("ObjectUpdate") << " mesgsys " << mesgsys << " dp " << dp << " id " << getID() << " update_type " << (S32) update_type << LL_ENDL;      dumpStack("ObjectUpdateStack"); +    // The new OBJECTDATA_FIELD_SIZE_124, OBJECTDATA_FIELD_SIZE_140, OBJECTDATA_FIELD_SIZE_80 +    // and OBJECTDATA_FIELD_SIZE_64 lengths should be supported in the existing cases below. +    // Each case should start at the beginning of the buffer and extract all known +    // values, and ignore any unknown data at the end of the buffer. +    // This allows new data in the future without breaking current viewers. +    const S32 OBJECTDATA_FIELD_SIZE_140 = 140;  // Full precision avatar update for future extended data +    const S32 OBJECTDATA_FIELD_SIZE_124 = 124;  // Full precision object update for future extended data +    const S32 OBJECTDATA_FIELD_SIZE_76  =  76;  // Full precision avatar update +    const S32 OBJECTDATA_FIELD_SIZE_60  =  60;  // Full precision object update +    const S32 OBJECTDATA_FIELD_SIZE_80 =   80;  // Terse avatar update, 16 bit precision for future extended data +    const S32 OBJECTDATA_FIELD_SIZE_64  =  64;  // Terse object update, 16 bit precision for future extended data +    const S32 OBJECTDATA_FIELD_SIZE_48  =  48;  // Terse avatar update, 16 bit precision +    const S32 OBJECTDATA_FIELD_SIZE_32  =  32;  // Terse object update, 16 bit precision +  	U32 retval = 0x0;  	// If region is removed from the list it is also deleted. @@ -1206,7 +1220,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  		U32 x, y;  		from_region_handle(region_handle, &x, &y); -		LL_ERRS() << "Object has invalid region " << x << ":" << y << "!" << LL_ENDL; +		LL_WARNS("UpdateFail") << "Object has invalid region " << x << ":" << y << "!" << LL_ENDL;  		return retval;  	} @@ -1233,8 +1247,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  	const F32 size = LLWorld::getInstance()->getRegionWidthInMeters();	  	const F32 MAX_HEIGHT = LLWorld::getInstance()->getRegionMaxHeight();  	const F32 MIN_HEIGHT = LLWorld::getInstance()->getRegionMinHeight(); -	S32 length; -	S32	count; +    S32 length = 0; +    S32 count = 0;  	S32 this_update_precision = 32;		// in bits  	// Temporaries, because we need to compare w/ previous to set dirty flags... @@ -1295,6 +1309,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  				mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_Scale, new_scale, block_num );  				length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ObjectData);  				mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num, MAX_OBJECT_BINARY_DATA_SIZE); +                length = llmin(length, MAX_OBJECT_BINARY_DATA_SIZE);  // getBinaryDataFast() safely fills the buffer to max_size  				mTotalCRC = crc;                  // Might need to update mSourceMuted here to properly pick up new radius @@ -1314,20 +1329,22 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  				}  				setClickAction(click_action); -				count = 0; -				LLVector4 collision_plane; -				 +                count = 0; +                LLVector4 collision_plane; +  				switch(length)  				{ -				case (60 + 16): +                case OBJECTDATA_FIELD_SIZE_140: +                case OBJECTDATA_FIELD_SIZE_76:  					// pull out collision normal for avatar  					htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));  					((LLVOAvatar*)this)->setFootPlane(collision_plane);  					count += sizeof(LLVector4); -					// fall through -				case 60: + +                case OBJECTDATA_FIELD_SIZE_124: +                case OBJECTDATA_FIELD_SIZE_60:  					this_update_precision = 32; -					// this is a terse update +					// this is a full precision update  					// pos  					htolememcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));  					count += sizeof(LLVector3); @@ -1352,117 +1369,21 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  						resetRot();  					}  					setAngularVelocity(new_angv); +                    count += sizeof(LLVector3);  #if LL_DARWIN -					if (length == 76) +                    if (length == OBJECTDATA_FIELD_SIZE_76 || +                        length == OBJECTDATA_FIELD_SIZE_140)  					{  						setAngularVelocity(LLVector3::zero);  					}  #endif  					break; -				case(32 + 16): -					// pull out collision normal for avatar -					htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4)); -					((LLVOAvatar*)this)->setFootPlane(collision_plane); -					count += sizeof(LLVector4); -					// fall through -				case 32: -					this_update_precision = 16; -					test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT); -					// This is a terse 16 update, so treat data as an array of U16's. -#ifdef LL_BIG_ENDIAN -					htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);  -					val = valswizzle; -#else -					val = (U16 *) &data[count]; -#endif -					count += sizeof(U16)*3; -					new_pos_parent.mV[VX] = U16_to_F32(val[VX], -0.5f*size, 1.5f*size); -					new_pos_parent.mV[VY] = U16_to_F32(val[VY], -0.5f*size, 1.5f*size); -					new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT); - -#ifdef LL_BIG_ENDIAN -					htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);  -					val = valswizzle; -#else -					val = (U16 *) &data[count]; -#endif -					count += sizeof(U16)*3; -					setVelocity(LLVector3(U16_to_F32(val[VX], -size, size), -													   U16_to_F32(val[VY], -size, size), -													   U16_to_F32(val[VZ], -size, size))); - -#ifdef LL_BIG_ENDIAN -					htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);  -					val = valswizzle; -#else -					val = (U16 *) &data[count]; -#endif -					count += sizeof(U16)*3; -					setAcceleration(LLVector3(U16_to_F32(val[VX], -size, size), -														   U16_to_F32(val[VY], -size, size), -														   U16_to_F32(val[VZ], -size, size))); - -#ifdef LL_BIG_ENDIAN -					htolememcpy(valswizzle, &data[count], MVT_U16Quat, 4);  -					val = valswizzle; -#else -					val = (U16 *) &data[count]; -#endif -					count += sizeof(U16)*4; -					new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f); -					new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f); -					new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f); -					new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f); - -#ifdef LL_BIG_ENDIAN -					htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);  -					val = valswizzle; -#else -					val = (U16 *) &data[count]; -#endif -					new_angv.setVec(U16_to_F32(val[VX], -size, size), -										U16_to_F32(val[VY], -size, size), -										U16_to_F32(val[VZ], -size, size)); -					if (new_angv.isExactlyZero()) -					{ -						// reset rotation time -						resetRot(); -					} -					setAngularVelocity(new_angv); -					break; - -				case 16: -					this_update_precision = 8; -					test_pos_parent.quantize8(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT); -					// this is a terse 8 update -					new_pos_parent.mV[VX] = U8_to_F32(data[0], -0.5f*size, 1.5f*size); -					new_pos_parent.mV[VY] = U8_to_F32(data[1], -0.5f*size, 1.5f*size); -					new_pos_parent.mV[VZ] = U8_to_F32(data[2], MIN_HEIGHT, MAX_HEIGHT); - -					setVelocity(U8_to_F32(data[3], -size, size), -								U8_to_F32(data[4], -size, size), -								U8_to_F32(data[5], -size, size) ); - -					setAcceleration(U8_to_F32(data[6], -size, size), -									U8_to_F32(data[7], -size, size), -									U8_to_F32(data[8], -size, size) ); - -					new_rot.mQ[VX] = U8_to_F32(data[9], -1.f, 1.f); -					new_rot.mQ[VY] = U8_to_F32(data[10], -1.f, 1.f); -					new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f); -					new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f); - -					new_angv.setVec(U8_to_F32(data[13], -size, size), -										U8_to_F32(data[14], -size, size), -										U8_to_F32(data[15], -size, size) ); -					if (new_angv.isExactlyZero()) -					{ -						// reset rotation time -						resetRot(); -					} -					setAngularVelocity(new_angv); -					break; +                // length values 48, 32 and 16 were once in viewer code but +                //   are never sent by the SL simulator +                default: +                    LL_WARNS("UpdateFail") << "Unexpected ObjectData buffer size " << length +						<< " for " << getID() << " with OUT_FULL message" << LL_ENDL;  				}  				//////////////////////////////////////////////////// @@ -1496,20 +1417,45 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  				if (mData)  				{  					delete [] mData; -				} +                    mData = NULL; +                } -				// Check for appended generic data -				S32 data_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Data); -				if (data_size <= 0) -				{ -					mData = NULL; -				} -				else -				{ -					// ...has generic data -					mData = new U8[data_size]; -					mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, mData, data_size, block_num); -				} +                // Dec 2023 new generic data: +                //    Trees work as before, this field contains genome data +                //    Not a tree:  root objects send 1 byte with the number of +                //      total prims in the linkset +                //    If the generic data size is zero, then number of prims is 1 +                // +                // Viewers should not check for specific data sizes exactly, but if +                // the field has data, process it from the start and ignore the remainder. + +                // Check for appended generic data +                const S32 GENERIC_DATA_BUFFER_SIZE = 16; +                S32 data_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Data); +                if (data_size > 0) +                {    // has generic data +                    if (getPCode() == LL_PCODE_LEGACY_TREE || getPCode() == LL_PCODE_TREE_NEW) +                    { +                        mData = new U8[data_size]; +                        mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, mData, data_size, block_num); +                        LL_DEBUGS("NewObjectData") << "Read " << data_size << " bytes tree genome data for " << getID() << ", pcode " +                                             << getPCodeString() << ", value " << (S32) mData[0] << LL_ENDL; +                    } +                    else +                    {   // Extract number of prims +                        U8 generic_data[GENERIC_DATA_BUFFER_SIZE]; +                        mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, +                            &generic_data[0], llmin(data_size, GENERIC_DATA_BUFFER_SIZE), block_num); +                        // This is sample code to extract the number of prims +                        //    Future viewers should use it for their own purposes +                        if (!isAvatar()) +                        { +                            S32 num_prims = (S32) generic_data[0]; +                            LL_DEBUGS("NewObjectData") << "Root prim " << getID() << " has " +                                << num_prims << " prims in linkset" << LL_ENDL; +                        } +                    } +                }  				S32 text_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Text);  				if (text_size > 1) @@ -1605,60 +1551,23 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  #endif  				length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ObjectData);  				mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num, MAX_OBJECT_BINARY_DATA_SIZE); -				count = 0; +                length = llmin(length, MAX_OBJECT_BINARY_DATA_SIZE);	// getBinaryDataFast() safely fills the buffer to max_size +                count  = 0;  				LLVector4 collision_plane; -				 +  				switch(length)  				{ -				case(60 + 16): -					// pull out collision normal for avatar -					htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4)); -					((LLVOAvatar*)this)->setFootPlane(collision_plane); -					count += sizeof(LLVector4); -					// fall through -				case 60: -					// this is a terse 32 update -					// pos -					this_update_precision = 32; -					htolememcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); -					count += sizeof(LLVector3); -					// vel -					htolememcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); -					count += sizeof(LLVector3); -					// acc -					htolememcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); -					count += sizeof(LLVector3); -					// theta -					{ -						LLVector3 vec; -						htolememcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); -						new_rot.unpackFromVector3(vec); -					} -					count += sizeof(LLVector3); -					// omega -					htolememcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3)); -					if (new_angv.isExactlyZero()) -					{ -						// reset rotation time -						resetRot(); -					} -					setAngularVelocity(new_angv); -#if LL_DARWIN -					if (length == 76) -					{ -						setAngularVelocity(LLVector3::zero); -					} -#endif -					break; -				case(32 + 16): +                    case OBJECTDATA_FIELD_SIZE_80: +                    case OBJECTDATA_FIELD_SIZE_48:  					// pull out collision normal for avatar  					htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));  					((LLVOAvatar*)this)->setFootPlane(collision_plane);  					count += sizeof(LLVector4); -					// fall through -				case 32: -					// this is a terse 16 update -					this_update_precision = 16; + +                case OBJECTDATA_FIELD_SIZE_64: +                case OBJECTDATA_FIELD_SIZE_32: +					// this is a terse 16 bit quantized update +                    this_update_precision = 16;  					test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);  #ifdef LL_BIG_ENDIAN @@ -1718,33 +1627,14 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  					setAngularVelocity(new_angv);  					break; -				case 16: -					// this is a terse 8 update -					this_update_precision = 8; -					test_pos_parent.quantize8(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT); -					new_pos_parent.mV[VX] = U8_to_F32(data[0], -0.5f*size, 1.5f*size); -					new_pos_parent.mV[VY] = U8_to_F32(data[1], -0.5f*size, 1.5f*size); -					new_pos_parent.mV[VZ] = U8_to_F32(data[2], MIN_HEIGHT, MAX_HEIGHT); - -					setVelocity(U8_to_F32(data[3], -size, size), -								U8_to_F32(data[4], -size, size), -								U8_to_F32(data[5], -size, size) ); - -					setAcceleration(U8_to_F32(data[6], -size, size), -									U8_to_F32(data[7], -size, size), -									U8_to_F32(data[8], -size, size) ); - -					new_rot.mQ[VX] = U8_to_F32(data[9], -1.f, 1.f); -					new_rot.mQ[VY] = U8_to_F32(data[10], -1.f, 1.f); -					new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f); -					new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f); - -					new_angv.set(U8_to_F32(data[13], -size, size), -										U8_to_F32(data[14], -size, size), -										U8_to_F32(data[15], -size, size) ); -					setAngularVelocity(new_angv); -					break; -				} +                // Previous viewers had code for length 76, 60 or 16 byte length +                // with full precision or 8 bit quanitzation, but the +                // SL servers will never send those data formats.  If you ever see this +                // warning in Second Life, please file a bug report +                default: +                    LL_WARNS("UpdateFail") << "Unexpected ObjectData buffer size " << length << " for " << getID() +                                           << " with OUT_FULL message" << LL_ENDL; +                }  				U8 state;  				mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num ); @@ -1753,13 +1643,13 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  			}  		default: +            LL_WARNS("UpdateFail") << "Unknown uncompressed update type " << update_type << " for " << getID() << LL_ENDL;  			break; -  		}  	}  	else  	{ -		// handle the compressed case +		// handle the compressed case - have dp datapacker  		LLUUID sound_uuid;  		LLUUID	owner_id;  		F32    gain = 0; @@ -2013,6 +1903,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  			break;  		default: +            LL_WARNS("UpdateFail") << "Unknown compressed update type " << update_type << " for " << getID() << LL_ENDL;  			break;  		}  	} @@ -2060,7 +1951,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  				if (sent_parentp && sent_parentp->getParent() == this)  				{  					// Try to recover if we attempt to attach a parent to its child -					LL_WARNS() << "Attempt to attach a parent to it's child: " << this->getID() << " to " << sent_parentp->getID() << LL_ENDL; +                    LL_WARNS("UpdateFail") << "Attempt to attach a parent to it's child: " << this->getID() << " to " +                                           << sent_parentp->getID() << LL_ENDL;  					this->removeChild(sent_parentp);  					sent_parentp->setDrawableParent(NULL);  				} @@ -2084,7 +1976,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  					{  						if (mDrawable->isDead() || !mDrawable->getVObj())  						{ -							LL_WARNS() << "Drawable is dead or no VObj!" << LL_ENDL; +                            LL_WARNS("UpdateFail") << "Drawable is dead or no VObj!" << LL_ENDL;  							sent_parentp->addChild(this);  						}  						else @@ -2094,9 +1986,9 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  								// Bad, we got a cycle somehow.  								// Kill both the parent and the child, and  								// set cache misses for both of them. -								LL_WARNS() << "Attempting to recover from parenting cycle!" << LL_ENDL; -								LL_WARNS() << "Killing " << sent_parentp->getID() << " and " << getID() << LL_ENDL; -								LL_WARNS() << "Adding to cache miss list" << LL_ENDL; +                                LL_WARNS("UpdateFail") << "Attempting to recover from parenting cycle!  " +                                            << "Killing " << sent_parentp->getID() << " and " << getID() +                                            << ", Adding to cache miss list" << LL_ENDL;  								setParent(NULL);  								sent_parentp->setParent(NULL);  								getRegion()->addCacheMissFull(getLocalID()); @@ -2751,22 +2643,6 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& frame_tim -BOOL LLViewerObject::setData(const U8 *datap, const U32 data_size) -{ -	delete [] mData; - -	if (datap) -	{ -		mData = new U8[data_size]; -		if (!mData) -		{ -			return FALSE; -		} -		memcpy(mData, datap, data_size);		/* Flawfinder: ignore */ -	} -	return TRUE; -} -  // delete an item in the inventory, but don't tell the server. This is  // used internally by remove, update, and savescript.  // This will only delete the first item with an item_id in the list diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 80da7b2f73..b85dcc5da2 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -779,8 +779,6 @@ protected:  	static LLViewerObject *createObject(const LLUUID &id, LLPCode pcode, LLViewerRegion *regionp, S32 flags = 0); -	BOOL setData(const U8 *datap, const U32 data_size); -  	// Hide or show HUD, icon and particles  	void	hideExtraDisplayItems( BOOL hidden ); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 8ab7cda28c..c95648d62e 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -9269,7 +9269,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe  		//mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0);  	} -	// Parse the AppearanceData field, if any. +	// Parse the AppearanceHover field, if any.  	contents.mHoverOffsetWasSet = false;  	if (mesgsys->has(_PREHASH_AppearanceHover))  	{ @@ -9279,7 +9279,24 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe  		contents.mHoverOffset = hover;  		contents.mHoverOffsetWasSet = true;  	} -	 + +    // Get attachment info, if sent +    LLUUID attachment_id; +    U8     attach_point; +    S32    attach_count = mesgsys->getNumberOfBlocksFast(_PREHASH_AttachmentBlock); +    LL_DEBUGS("AVAppearanceAttachments") << "Agent " << getID() << " has " +                                         << attach_count << " attachments" << LL_ENDL; + +    for (S32 attach_i = 0; attach_i < attach_count; attach_i++) +    { +        mesgsys->getUUIDFast(_PREHASH_AttachmentBlock, _PREHASH_ID, attachment_id, attach_i); +        mesgsys->getU8Fast(_PREHASH_AttachmentBlock, _PREHASH_AttachmentPoint, attach_point, attach_i); +        LL_DEBUGS("AVAppearanceAttachments") << "AV " << getID() << " has attachment " << attach_i << " " +            << (attachment_id.isNull() ? "pending" : attachment_id.asString()) +            << " on point " << (S32)attach_point << LL_ENDL; +        // To do - store and use this information as needed +	} +  	// Parse visual params, if any.  	S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);      static LLCachedControl<bool> block_some_avatars(gSavedSettings, "BlockSomeAvatarAppearanceVisualParams"); | 
