コード例 #1
0
void LLMsgVarData::addData(const void *data, S32 size, EMsgVariableType type, S32 data_size)
{
	mSize = size;
	mDataSize = data_size;
	if ( (type != MVT_VARIABLE) && (type != MVT_FIXED) 
		 && (mType != MVT_VARIABLE) && (mType != MVT_FIXED))
	{
		if (mType != type)
		{
			llwarns << "Type mismatch in LLMsgVarData::addData for " << mName
					<< llendl;
		}
	}
	if(size)
	{
		delete mData; // Delete it if it already exists
		mData = new U8[size];
		htonmemcpy(mData, data, mType, size);
	}
}
コード例 #2
0
ファイル: llgesture.cpp プロジェクト: Boy/rainbow
U8 *LLGestureList::deserialize(U8 *buffer, S32 max_size)
{
	deleteAll();

	S32 count;
	U8 *tmp = buffer;

	if (tmp + sizeof(count) > buffer + max_size)
	{
		llwarns << "Invalid max_size" << llendl;
		return buffer;
	}

	htonmemcpy(&count, tmp, MVT_S32, 4);

	if (count > MAX_GESTURES)
	{
		llwarns << "Unreasonably large gesture list count in deserialize: " << count << llendl;
		return tmp;
	}

	tmp += sizeof(count);

	mList.reserve_block(count);

	for (S32 i = 0; i < count; i++)
	{
		mList[i] = create_gesture(&tmp, max_size - (S32)(tmp - buffer));
		if (tmp - buffer > max_size)
		{
			llwarns << "Deserialization read past end of buffer, bad data!!!!" << llendl;
			return tmp;
		}
	}

	return tmp;
}
コード例 #3
0
//-----------------------------------------------------------------------------
// packData()
//-----------------------------------------------------------------------------
void LLHUDEffectLookAt::packData(LLMessageSystem *mesgsys)
{
	// Pack the default data
	LLHUDEffect::packData(mesgsys);

	// Pack the type-specific data.  Uses a fun packed binary format.  Whee!
	U8 packed_data[PKT_SIZE];
	memset(packed_data, 0, PKT_SIZE);

	if (mSourceObject)
	{
		htonmemcpy(&(packed_data[SOURCE_AVATAR]), mSourceObject->mID.mData, MVT_LLUUID, 16);
	}
	else
	{
		htonmemcpy(&(packed_data[SOURCE_AVATAR]), LLUUID::null.mData, MVT_LLUUID, 16);
	}

	// pack both target object and position
	// position interpreted as offset if target object is non-null
	if (mTargetObject)
	{
		htonmemcpy(&(packed_data[TARGET_OBJECT]), mTargetObject->mID.mData, MVT_LLUUID, 16);
	}
	else
	{
		htonmemcpy(&(packed_data[TARGET_OBJECT]), LLUUID::null.mData, MVT_LLUUID, 16);
	}

	htonmemcpy(&(packed_data[TARGET_POS]), mTargetOffsetGlobal.mdV, MVT_LLVector3d, 24);

	U8 lookAtTypePacked = (U8)mTargetType;
	
	htonmemcpy(&(packed_data[LOOKAT_TYPE]), &lookAtTypePacked, MVT_U8, 1);

	mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, PKT_SIZE);

	mLastSendTime = mTimer.getElapsedTimeF32();
}
コード例 #4
0
ファイル: llhudeffecttrail.cpp プロジェクト: Boy/rainbow
void LLHUDEffectSpiral::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
{
	const size_t EFFECT_SIZE = 56;
	U8 packed_data[EFFECT_SIZE];

	LLHUDEffect::unpackData(mesgsys, blocknum);
	LLUUID object_id, target_object_id;
	S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData);
	if (size != EFFECT_SIZE)
	{
		llwarns << "Spiral effect with bad size " << size << llendl;
		return;
	}
	mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, 
		packed_data, EFFECT_SIZE, blocknum, EFFECT_SIZE);
	
	htonmemcpy(object_id.mData, packed_data, MVT_LLUUID, 16);
	htonmemcpy(target_object_id.mData, packed_data + 16, MVT_LLUUID, 16);
	htonmemcpy(mPositionGlobal.mdV, packed_data + 32, MVT_LLVector3d, 24);

	LLViewerObject *objp = NULL;

	if (object_id.isNull())
	{
		setSourceObject(NULL);
	}
	else
	{
		LLViewerObject *objp = gObjectList.findObject(object_id);
		if (objp)
		{
			setSourceObject(objp);
		}
		else
		{
			// We don't have this object, kill this effect
			markDead();
			return;
		}
	}

	if (target_object_id.isNull())
	{
		setTargetObject(NULL);
	}
	else
	{
		objp = gObjectList.findObject(target_object_id);
		if (objp)
		{
			setTargetObject(objp);
		}
		else
		{
			// We don't have this object, kill this effect
			markDead();
			return;
		}
	}

	triggerLocal();
}
コード例 #5
0
static S32 buildBlock(U8* buffer, S32 buffer_size, const LLMessageBlock* template_data, LLMsgData* message_data)
{
	S32 result = 0;
	LLMsgData::msg_blk_data_map_t::const_iterator block_iter = message_data->mMemberBlocks.find(template_data->mName);
	const LLMsgBlkData* mbci = block_iter->second;
		
	// ok, if this is the first block of a repeating pack, set
	// block_count and, if it's type MBT_VARIABLE encode a byte
	// for how many there are
	S32 block_count = mbci->mBlockNumber;
	if (template_data->mType == MBT_VARIABLE)
	{
		// remember that mBlockNumber is a S32
		U8 temp_block_number = (U8)mbci->mBlockNumber;
		if ((S32)(result + sizeof(U8)) < MAX_BUFFER_SIZE)
		{
			memcpy(&buffer[result], &temp_block_number, sizeof(U8));
			result += sizeof(U8);
		}
		else
		{
			// Just reporting error is likely not enough. Need
			// to check how to abort or error out gracefully
			// from this function. XXXTBD
			llerrs << "buildBlock failed. Message excedding "
					<< "sendBuffersize." << llendl;
		}
	}
	else if (template_data->mType == MBT_MULTIPLE)
	{
		if (block_count != template_data->mNumber)
		{
			// nope!  need to fill it in all the way!
			llerrs << "Block " << mbci->mName
				<< " is type MBT_MULTIPLE but only has data for "
				<< block_count << " out of its "
				<< template_data->mNumber << " blocks" << llendl;
		}
	}

	while(block_count > 0)
	{
		// now loop through the variables
		for (LLMsgBlkData::msg_var_data_map_t::const_iterator iter = mbci->mMemberVarData.begin();
			 iter != mbci->mMemberVarData.end(); iter++)
		{
			const LLMsgVarData& mvci = *iter;
			if (mvci.getSize() == -1)
			{
				// oops, this variable wasn't ever set!
				llerrs << "The variable " << mvci.getName() << " in block "
					<< mbci->mName << " of message "
					<< template_data->mName
					<< " wasn't set prior to buildMessage call" << llendl;
			}
			else
			{
				S32 data_size = mvci.getDataSize();
				if(data_size > 0)
				{
					// The type is MVT_VARIABLE, which means that we
					// need to encode a size argument. Otherwise,
					// there is no need.
					S32 size = mvci.getSize();
					U8 sizeb;
					U16 sizeh;
					switch(data_size)
					{
					case 1:
						sizeb = size;
						htonmemcpy(&buffer[result], &sizeb, MVT_U8, 1);
						break;
					case 2:
						sizeh = size;
						htonmemcpy(&buffer[result], &sizeh, MVT_U16, 2);
						break;
					case 4:
						htonmemcpy(&buffer[result], &size, MVT_S32, 4);
						break;
					default:
						llerrs << "Attempting to build variable field with unknown size of " << size << llendl;
						break;
					}
					result += mvci.getDataSize();
				}

				// if there is any data to pack, pack it
				if((mvci.getData() != NULL) && mvci.getSize())
				{
					if(result + mvci.getSize() < buffer_size)
					{
					    memcpy(
							&buffer[result],
							mvci.getData(),
							mvci.getSize());
					    result += mvci.getSize();
					}
					else
					{
					    // Just reporting error is likely not
					    // enough. Need to check how to abort or error
					    // out gracefully from this function. XXXTBD
						llerrs << "buildBlock failed. "
							<< "Attempted to pack "
							<< result + mvci.getSize()
							<< " bytes into a buffer with size "
							<< buffer_size << "." << llendl;
					}						
				}
			}
		}

		--block_count;
		++block_iter;
		if (block_iter != message_data->mMemberBlocks.end())
		{
			mbci = block_iter->second;
		}
	}

	return result;
}
コード例 #6
0
//-----------------------------------------------------------------------------
// unpackData()
//-----------------------------------------------------------------------------
void LLHUDEffectLookAt::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
{
	LLVector3d new_target;
	U8 packed_data[PKT_SIZE];

	LLUUID dataId;
	mesgsys->getUUIDFast(_PREHASH_Effect, _PREHASH_ID, dataId, blocknum);

	if (!gAgentCamera.mLookAt.isNull() && dataId == gAgentCamera.mLookAt->getID())
	{
		return;
	}

	LLHUDEffect::unpackData(mesgsys, blocknum);
	LLUUID source_id;
	LLUUID target_id;
	S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData);
	if (size != PKT_SIZE)
	{
		llwarns << "LookAt effect with bad size " << size << llendl;
		return;
	}
	mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, PKT_SIZE, blocknum);
	
	htonmemcpy(source_id.mData, &(packed_data[SOURCE_AVATAR]), MVT_LLUUID, 16);

	LLViewerObject *objp = gObjectList.findObject(source_id);
	if (objp && objp->isAvatar())
	{
		setSourceObject(objp);
	}
	else
	{
		//llwarns << "Could not find source avatar for lookat effect" << llendl;
		return;
	}

	htonmemcpy(target_id.mData, &(packed_data[TARGET_OBJECT]), MVT_LLUUID, 16);

	objp = gObjectList.findObject(target_id);

	htonmemcpy(new_target.mdV, &(packed_data[TARGET_POS]), MVT_LLVector3d, 24);

	if (objp)
	{
		setTargetObjectAndOffset(objp, new_target);
	}
	else if (target_id.isNull())
	{
		setTargetPosGlobal(new_target);
	}
	else
	{
		//llwarns << "Could not find target object for lookat effect" << llendl;
	}

	U8 lookAtTypeUnpacked = 0;
	htonmemcpy(&lookAtTypeUnpacked, &(packed_data[LOOKAT_TYPE]), MVT_U8, 1);
	mTargetType = (ELookAtType)lookAtTypeUnpacked;

	if (mTargetType == LOOKAT_TARGET_NONE)
	{
		clearLookAtTarget();
	}
}
コード例 #7
0
// decode a given message
BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender )
{
	llassert( mReceiveSize >= 0 );
	llassert( mCurrentRMessageTemplate);
	llassert( !mCurrentRMessageData );
	delete mCurrentRMessageData; // just to make sure

	// The offset tells us how may bytes to skip after the end of the
	// message name.
	U8 offset = buffer[PHL_OFFSET];
	S32 decode_pos = LL_PACKET_ID_SIZE + (S32)(mCurrentRMessageTemplate->mFrequency) + offset;

	// create base working data set
	mCurrentRMessageData = new LLMsgData(mCurrentRMessageTemplate->mName);
	
	// loop through the template building the data structure as we go
	LLMessageTemplate::message_block_map_t::const_iterator iter;
	for(iter = mCurrentRMessageTemplate->mMemberBlocks.begin();
		iter != mCurrentRMessageTemplate->mMemberBlocks.end();
		++iter)
	{
		LLMessageBlock* mbci = *iter;
		U8	repeat_number;
		S32	i;

		// how many of this block?

		if (mbci->mType == MBT_SINGLE)
		{
			// just one
			repeat_number = 1;
		}
		else if (mbci->mType == MBT_MULTIPLE)
		{
			// a known number
			repeat_number = mbci->mNumber;
		}
		else if (mbci->mType == MBT_VARIABLE)
		{
			// need to read the number from the message
			// repeat number is a single byte
			if (decode_pos >= mReceiveSize)
			{
				// commented out - hetgrid says that missing variable blocks
				// at end of message are legal
				// logRanOffEndOfPacket(sender, decode_pos, 1);

				// default to 0 repeats
				repeat_number = 0;
			}
			else
			{
				repeat_number = buffer[decode_pos];
				decode_pos++;
			}
		}
		else
		{
			llerrs << "Unknown block type" << llendl;
			return FALSE;
		}

		LLMsgBlkData* cur_data_block = NULL;

		// now loop through the block
		for (i = 0; i < repeat_number; i++)
		{
			if (i)
			{
				// build new name to prevent collisions
				// TODO: This should really change to a vector
				cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number);
				cur_data_block->mName = mbci->mName + i;
			}
			else
			{
				cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number);
			}

			// add the block to the message
			mCurrentRMessageData->addBlock(cur_data_block);

			// now read the variables
			for (LLMessageBlock::message_variable_map_t::const_iterator iter = 
					 mbci->mMemberVariables.begin();
				 iter != mbci->mMemberVariables.end(); iter++)
			{
				const LLMessageVariable& mvci = **iter;

				// ok, build out the variables
				// add variable block
				cur_data_block->addVariable(mvci.getName(), mvci.getType());

				// what type of variable?
				if (mvci.getType() == MVT_VARIABLE)
				{
					// variable, get the number of bytes to read from the template
					S32 data_size = mvci.getSize();
					U8 tsizeb = 0;
					U16 tsizeh = 0;
					U32 tsize = 0;

					if ((decode_pos + data_size) > mReceiveSize)
					{
						logRanOffEndOfPacket(sender, decode_pos, data_size);

						// default to 0 length variable blocks
						tsize = 0;
					}
					else
					{
						switch(data_size)
						{
						case 1:
							htonmemcpy(&tsizeb, &buffer[decode_pos], MVT_U8, 1);
							tsize = tsizeb;
							break;
						case 2:
							htonmemcpy(&tsizeh, &buffer[decode_pos], MVT_U16, 2);
							tsize = tsizeh;
							break;
						case 4:
							htonmemcpy(&tsize, &buffer[decode_pos], MVT_U32, 4);
							break;
						default:
							llerrs << "Attempting to read variable field with unknown size of " << data_size << llendl;
							break;
						}
					}
					decode_pos += data_size;

					cur_data_block->addData(mvci.getName(), &buffer[decode_pos], tsize, mvci.getType());
					decode_pos += tsize;
				}
				else
				{
					// fixed!
					// so, copy data pointer and set data size to fixed size
					if ((decode_pos + mvci.getSize()) > mReceiveSize)
					{
						logRanOffEndOfPacket(sender, decode_pos, mvci.getSize());

						// default to 0s.
						U32 size = mvci.getSize();
						std::vector<U8> data(size);
						if (size) memset(&(data[0]), 0, size);
						cur_data_block->addData(mvci.getName(), &(data[0]), 
												size, mvci.getType());
					}
					else
					{
						cur_data_block->addData(mvci.getName(), 
												&buffer[decode_pos], 
												mvci.getSize(), 
												mvci.getType());
					}
					decode_pos += mvci.getSize();
				}
			}
		}
	}

	if (mCurrentRMessageData->mMemberBlocks.empty()
		&& !mCurrentRMessageTemplate->mMemberBlocks.empty())
	{
		lldebugs << "Empty message '" << mCurrentRMessageTemplate->mName << "' (no blocks)" << llendl;
		return FALSE;
	}

	{
		static LLTimer decode_timer;

		if(LLMessageReader::getTimeDecodes() || gMessageSystem->getTimingCallback())
		{
			decode_timer.reset();
		}

		{
			LLFastTimer t(LLFastTimer::FTM_PROCESS_MESSAGES);
			if( !mCurrentRMessageTemplate->callHandlerFunc(gMessageSystem) )
			{
				llwarns << "Message from " << sender << " with no handler function received: " << mCurrentRMessageTemplate->mName << llendl;
			}
		}

		if(LLMessageReader::getTimeDecodes() || gMessageSystem->getTimingCallback())
		{
			F32 decode_time = decode_timer.getElapsedTimeF32();

			if (gMessageSystem->getTimingCallback())
			{
				(gMessageSystem->getTimingCallback())(mCurrentRMessageTemplate->mName,
								decode_time,
								gMessageSystem->getTimingCallbackData());
			}

			if (LLMessageReader::getTimeDecodes())
			{
				mCurrentRMessageTemplate->mDecodeTimeThisFrame += decode_time;

				mCurrentRMessageTemplate->mTotalDecoded++;
				mCurrentRMessageTemplate->mTotalDecodeTime += decode_time;

				if( mCurrentRMessageTemplate->mMaxDecodeTimePerMsg < decode_time )
				{
					mCurrentRMessageTemplate->mMaxDecodeTimePerMsg = decode_time;
				}


				if(decode_time > LLMessageReader::getTimeDecodesSpamThreshold())
				{
					lldebugs << "--------- Message " << mCurrentRMessageTemplate->mName << " decode took " << decode_time << " seconds. (" <<
						mCurrentRMessageTemplate->mMaxDecodeTimePerMsg << " max, " <<
						(mCurrentRMessageTemplate->mTotalDecodeTime / mCurrentRMessageTemplate->mTotalDecoded) << " avg)" << llendl;
				}
			}
		}
	}
	return TRUE;
}
コード例 #8
0
ファイル: llxfer.cpp プロジェクト: HizWylder/GIS
void LLXfer::sendPacket(S32 packet_num)
{
    char fdata_buf[LL_XFER_LARGE_PAYLOAD+4];		/* Flawfinder: ignore */
    S32 fdata_size = mChunkSize;
    BOOL last_packet = FALSE;
    S32 num_copy = 0;

    // if the desired packet is not in our current buffered excerpt from the file. . .
    if (((U32)packet_num*fdata_size < mBufferStartOffset)
            || ((U32)llmin((U32)mXferSize,(U32)((U32)(packet_num+1)*fdata_size)) > mBufferStartOffset + mBufferLength))

    {
        if (suck(packet_num*fdata_size))  // returns non-zero on failure
        {
            abort(LL_ERR_EOF);
            return;
        }
    }

    S32 desired_read_position = 0;

    desired_read_position = packet_num * fdata_size - mBufferStartOffset;

    fdata_size = llmin((S32)mBufferLength-desired_read_position, mChunkSize);

    if (fdata_size < 0)
    {
        llwarns << "negative data size in xfer send, aborting" << llendl;
        abort(LL_ERR_EOF);
        return;
    }

    if (((U32)(desired_read_position + fdata_size) >= (U32)mBufferLength) && (mBufferContainsEOF))
    {
        last_packet = TRUE;
    }

    if (packet_num)
    {
        num_copy = llmin(fdata_size, (S32)sizeof(fdata_buf));
        num_copy = llmin(num_copy, (S32)(mBufferLength - desired_read_position));
        if (num_copy > 0)
        {
            memcpy(fdata_buf,&mBuffer[desired_read_position],num_copy);	/*Flawfinder: ignore*/
        }
    }
    else
    {
        // if we're the first packet, encode size as an additional S32
        // at start of data.
        num_copy = llmin(fdata_size, (S32)(sizeof(fdata_buf)-sizeof(S32)));
        num_copy = llmin(
                       num_copy,
                       (S32)(mBufferLength - desired_read_position));
        if (num_copy > 0)
        {
            memcpy(	/*Flawfinder: ignore*/
                fdata_buf + sizeof(S32),
                &mBuffer[desired_read_position],
                num_copy);
        }
        fdata_size += sizeof(S32);
        htonmemcpy(fdata_buf,&mXferSize, MVT_S32, sizeof(S32));
    }

    S32 encoded_packetnum = encodePacketNum(packet_num,last_packet);

    if (fdata_size)
    {
        // send the packet
        gMessageSystem->newMessageFast(_PREHASH_SendXferPacket);
        gMessageSystem->nextBlockFast(_PREHASH_XferID);

        gMessageSystem->addU64Fast(_PREHASH_ID, mID);
        gMessageSystem->addU32Fast(_PREHASH_Packet, encoded_packetnum);

        gMessageSystem->nextBlockFast(_PREHASH_DataPacket);
        gMessageSystem->addBinaryDataFast(_PREHASH_Data, &fdata_buf,fdata_size);

        gMessageSystem->sendMessage(mRemoteHost);

        ACKTimer.reset();
        mWaitingForACK = TRUE;
    }
    if (last_packet)
    {
        mStatus = e_LL_XFER_COMPLETE;
    }
    else
    {
        mStatus = e_LL_XFER_IN_PROGRESS;
    }
}