Exemplo n.º 1
0
void LLMessageTemplateParserTestObject::test<4>()
// tests variable parsing method
{
    LLTemplateTokenizer tokens(std::string("{    Test0  \n\t\n   U32 \n\n }"));
    LLMessageVariable * var = LLTemplateParser::parseVariable(tokens);

    ensure("test0 var parsed", var != 0);
    ensure_equals("name of variable", std::string(var->getName()), std::string("Test0"));
    ensure_equals("type of variable is U32", var->getType(), MVT_U32);
    ensure_equals("size of variable", var->getSize(), 4);

    delete var;

    std::string message_string("\n\t{ \t   Test1 Fixed \n 523 }\n\n");
    tokens = LLTemplateTokenizer(message_string);
    var = LLTemplateParser::parseVariable(tokens);

    ensure("test1 var parsed", var != 0);
    ensure_equals("name of variable", std::string(var->getName()), std::string("Test1"));
    ensure_equals("type of variable is Fixed", var->getType(), MVT_FIXED);
    ensure_equals("size of variable", var->getSize(), 523);

    delete var;

    // *NOTE: the parsers call llerrs on invalid input, so we can't really
    // test that  :-(
}
LLFloaterMessageLogItem::LLFloaterMessageLogItem(LLMessageLogEntry entry)
:	LLMessageLogEntry(entry.mType, entry.mFromHost, entry.mToHost, entry.mData, entry.mDataSize)
{
	if(!sTemplateMessageReader)
	{
		sTemplateMessageReader = new LLTemplateMessageReader(gMessageSystem->mMessageNumbers);
	}
	mID.generate();
	mSequenceID = 0;
	if(mType == TEMPLATE)
	{
		BOOL decode_invalid = FALSE;
		S32 decode_len = mDataSize;
		std::vector<U8> DecodeBuffer(MAX_PACKET_LEN,0);
		memcpy(&(DecodeBuffer[0]),&(mData[0]),decode_len);
		U8* decodep = &(DecodeBuffer[0]);
		mFlags = DecodeBuffer[0];
		gMessageSystem->zeroCodeExpand(&decodep, &decode_len);
		if(decode_len < 7)
			decode_invalid = TRUE;
		else
		{
			mSequenceID = ntohl(*((U32*)(&decodep[1])));
			sTemplateMessageReader->clearMessage();
			if(!sTemplateMessageReader->validateMessage(decodep, decode_len, mFromHost, TRUE))
				decode_invalid = TRUE;
			else
			{
				if(!sTemplateMessageReader->decodeData(decodep, mFromHost, true))
					decode_invalid = TRUE;
				else
				{
					LLMessageTemplate* temp = sTemplateMessageReader->mCurrentRMessageTemplate;
					mName = temp->mName;
					mSummary = "";
					
					if(mFlags)
					{
						mSummary.append(" [ ");
						if(mFlags & LL_ZERO_CODE_FLAG)
							mSummary.append(" Zer ");
						if(mFlags & LL_RELIABLE_FLAG)
							mSummary.append(" Rel ");
						if(mFlags & LL_RESENT_FLAG)
							mSummary.append(" Rsd ");
						if(mFlags & LL_ACK_FLAG)
							mSummary.append(" Ack ");
						mSummary.append(" ] ");
					}
					
					LLMessageTemplate::message_block_map_t::iterator blocks_end = temp->mMemberBlocks.end();
					for (LLMessageTemplate::message_block_map_t::iterator blocks_iter = temp->mMemberBlocks.begin();
						 blocks_iter != blocks_end; ++blocks_iter)
					{
						LLMessageBlock* block = (*blocks_iter);
						const char* block_name = block->mName;
						S32 num_blocks = sTemplateMessageReader->getNumberOfBlocks(block_name);
						if(!num_blocks)
							mSummary.append(" { } ");
						else if(num_blocks > 1)
							mSummary.append(llformat(" %s [ %d ] { ... } ", block_name, num_blocks));
						else for(S32 i = 0; i < 1; i++)
						{
							mSummary.append(" { ");
							LLMessageBlock::message_variable_map_t::iterator var_end = block->mMemberVariables.end();
							for (LLMessageBlock::message_variable_map_t::iterator var_iter = block->mMemberVariables.begin();
								 var_iter != var_end; ++var_iter)
							{
								LLMessageVariable* variable = (*var_iter);
								const char* var_name = variable->getName();
								BOOL returned_hex;
								std::string value = getString(sTemplateMessageReader, block_name, i, var_name, variable->getType(), returned_hex, TRUE);
								mSummary.append(llformat(" %s=%s ", var_name, value.c_str()));
							}
							mSummary.append(" } ");
							if(mSummary.length() > 255) break;
						}
						if(mSummary.length() > 255)
						{
							mSummary.append(" ... ");
							break;
						}
					} // blocks_iter
				} // decode_valid
			}
		}
		if(decode_invalid)
		{
			mName = "Invalid";
			mSummary = "";
			for(S32 i = 0; i < mDataSize; i++)
				mSummary.append(llformat("%02X ", mData[i]));
		}
	}
	else // not template
	{
		mName = "SOMETHING ELSE";
		mSummary = "TODO: SOMETHING ELSE";
	}
}
bool LLEasyMessageSender::sendMessage(const LLHost& region_host, const std::string& str_message)
{
	std::vector<std::string> lines = split(str_message, "\n");
	if(!lines.size())
	{
		printError("Not enough information :O");
		return false;
	}
	std::vector<std::string> tokens = split(lines[0], " ");
	if(!tokens.size())
	{
		printError("Not enough information :O");
		return false;
	}
	std::string dir_str = tokens[0];
	LLStringUtil::toLower(dir_str);
	// Direction
	BOOL outgoing;
	if(dir_str == "out")
		outgoing = TRUE;
	else if(dir_str == "in")
		outgoing = FALSE;
	else
	{
		printError("Expected direction 'in' or 'out'");
		return false;
	}
	// Message
	std::string message = "Invalid";
	if(tokens.size() > 1)
	{
		if(tokens.size() > 2)
		{
			printError("Unexpected extra stuff at the top");
			return false;
		}
		message = tokens[1];
		LLStringUtil::trim(message);
	}
	// Body
	std::vector<parts_block> parts;
	if(lines.size() > 1)
	{
		std::vector<std::string>::iterator line_end = lines.end();
		std::vector<std::string>::iterator line_iter = lines.begin();
		++line_iter;
		std::string current_block("");
		int current_block_index = -1;
		for( ; line_iter != line_end; ++line_iter)
		{
			std::string line = (*line_iter);
			LLStringUtil::trim(line);

			//skip empty lines
			if(!line.length())
				continue;

			//check if this line is the start of a new block
			if(line.substr(0, 1) == "[" && line.substr(line.size() - 1, 1) == "]")
			{
				current_block = line.substr(1, line.length() - 2);
				LLStringUtil::trim(current_block);
				++current_block_index;
				parts_block pb;
				pb.name = current_block;
				parts.push_back(pb);
			}
			//should be a key->value pair
			else
			{
				if(current_block.empty())
				{
					printError("Got a field before the start of a block");
					return false;
				}

				int eqpos = line.find("=");
				if(eqpos == line.npos)
				{
					printError("Missing an equal sign");
					return false;
				}

				std::string field = line.substr(0, eqpos);
				LLStringUtil::trim(field);
				if(!field.length())
				{
					printError("Missing name of field");
					return false;
				}

				std::string value = line.substr(eqpos + 1);
				LLStringUtil::trim(value);
				parts_var pv;

				//check if this is a hex value
				if(value.substr(0, 1) == "|")
				{
					pv.hex = TRUE;
					value = value.substr(1);
					LLStringUtil::trim(value);
				}
				else
					pv.hex = FALSE;

				pv.name = field;
				pv.value = value;
				parts[current_block_index].vars.push_back(pv);
			}
		}
	}

	//Make sure everything's kosher with the message we built

	//check if the message type is one that we know about
	std::map<const char *, LLMessageTemplate*>::iterator template_iter;
	template_iter = gMessageSystem->mMessageTemplates.find( LLMessageStringTable::getInstance()->getString(message.c_str()) );
	if(template_iter == gMessageSystem->mMessageTemplates.end())
	{
		printError(llformat("Don't know how to build a '%s' message", message.c_str()));
		return false;
	}

	LLMessageTemplate* temp = (*template_iter).second;

	std::vector<parts_block>::iterator parts_end = parts.end();
	std::vector<parts_block>::iterator parts_iter = parts.begin();
	LLMessageTemplate::message_block_map_t::iterator blocks_end = temp->mMemberBlocks.end();

	for (LLMessageTemplate::message_block_map_t::iterator blocks_iter = temp->mMemberBlocks.begin();
		 blocks_iter != blocks_end; )
	{
		LLMessageBlock* block = (*blocks_iter);
		const char* block_name = block->mName;

		//are we at the end of the block or does this block belongs at this spot in the message?
		if(parts_iter == parts_end || (*parts_iter).name != block_name)
		{
			//did the block end too early?
			if(block->mType != MBT_VARIABLE)
			{
				printError(llformat("Expected '%s' block", block_name));
				return false;
			}

			//skip to the next block
			++blocks_iter;
			continue;
		}

		std::vector<parts_var>::iterator part_var_end = (*parts_iter).vars.end();
		std::vector<parts_var>::iterator part_var_iter = (*parts_iter).vars.begin();
		LLMessageBlock::message_variable_map_t::iterator var_end = block->mMemberVariables.end();
		for (LLMessageBlock::message_variable_map_t::iterator var_iter = block->mMemberVariables.begin();
			 var_iter != var_end; ++var_iter)
		{
			LLMessageVariable* variable = (*var_iter);
			const char* var_name = variable->getName();

			//are there less keypairs in this block than there should be?
			if(part_var_iter == part_var_end || (*part_var_iter).name != var_name)
			{
				printError(llformat("Expected '%s' field under '%s' block", var_name, block_name));
				return false;
			}

			//keep the type of data that this value is supposed to contain for later
			(*part_var_iter).var_type = variable->getType();

			++part_var_iter;
		}

		//there were more keypairs in the block than there should have been
		if(part_var_iter != part_var_end)
		{
			printError(llformat("Unexpected field(s) at end of '%s' block", block_name));
			return false;
		}

		++parts_iter;

		//if this block isn't going to repeat, change to the next block
		if(!((block->mType != MBT_SINGLE) && (parts_iter != parts_end) && ((*parts_iter).name == block_name)))
			++blocks_iter;

	}

	//there were more blocks specified in the message than there should have been
	if(parts_iter != parts_end)
	{
		printError(llformat("Unexpected block(s) at end: %s", (*parts_iter).name.c_str()));
		return false;
	}

	// Build and send
	gMessageSystem->newMessage( message.c_str() );
	for(parts_iter = parts.begin(); parts_iter != parts_end; ++parts_iter)
	{
		const char* block_name = (*parts_iter).name.c_str();
		gMessageSystem->nextBlock(block_name);
		std::vector<parts_var>::iterator part_var_end = (*parts_iter).vars.end();
		for(std::vector<parts_var>::iterator part_var_iter = (*parts_iter).vars.begin();
			part_var_iter != part_var_end; ++part_var_iter)
		{
			parts_var pv = (*part_var_iter);
			if(!addField(pv.var_type, pv.name.c_str(), pv.value, pv.hex))
			{
				printError(llformat("Error adding the provided data for %s '%s' to '%s' block", mvtstr(pv.var_type).c_str(), pv.name.c_str(), block_name));
				gMessageSystem->clearMessage();
				return false;
			}
		}
	}


	if(outgoing)
		return(gMessageSystem->sendMessage(region_host) > 0);
	else
	{
		U8 builtMessageBuffer[MAX_BUFFER_SIZE];

		S32 message_size = gMessageSystem->mTemplateMessageBuilder->buildMessage(builtMessageBuffer, MAX_BUFFER_SIZE, 0);
		gMessageSystem->clearMessage();
		return gMessageSystem->checkMessages(0, true, builtMessageBuffer, region_host, message_size);
	}
}
std::string LLFloaterMessageLogItem::getFull(BOOL show_header)
{
	std::string full("");
	if(mType == TEMPLATE)
	{
		BOOL decode_invalid = FALSE;
		S32 decode_len = mDataSize;
		std::vector<U8> DecodeBuffer(MAX_PACKET_LEN,0);
		memcpy(&(DecodeBuffer[0]),&(mData[0]),decode_len);
		U8* decodep = &(DecodeBuffer[0]);
		gMessageSystem->zeroCodeExpand(&decodep, &decode_len);
		if(decode_len < 7)
			decode_invalid = TRUE;
		else
		{
			sTemplateMessageReader->clearMessage();
			if(!sTemplateMessageReader->validateMessage(decodep, decode_len, mFromHost, TRUE))
				decode_invalid = TRUE;
			else
			{
				if(!sTemplateMessageReader->decodeData(decodep, mFromHost, TRUE))
					decode_invalid = TRUE;
				else
				{
					LLMessageTemplate* temp = sTemplateMessageReader->mCurrentRMessageTemplate;
					full.append(isOutgoing() ? "out " : "in ");
					full.append(llformat("%s\n", temp->mName));
					if(show_header)
					{
						full.append("[Header]\n");
						full.append(llformat("SequenceID = %u\n", mSequenceID));
						full.append(llformat("LL_ZERO_CODE_FLAG = %s\n", (mFlags & LL_ZERO_CODE_FLAG) ? "True" : "False"));
						full.append(llformat("LL_RELIABLE_FLAG = %s\n", (mFlags & LL_RELIABLE_FLAG) ? "True" : "False"));
						full.append(llformat("LL_RESENT_FLAG = %s\n", (mFlags & LL_RESENT_FLAG) ? "True" : "False"));
						full.append(llformat("LL_ACK_FLAG = %s\n", (mFlags & LL_ACK_FLAG) ? "True" : "False"));
					}
					LLMessageTemplate::message_block_map_t::iterator blocks_end = temp->mMemberBlocks.end();
					for (LLMessageTemplate::message_block_map_t::iterator blocks_iter = temp->mMemberBlocks.begin();
						 blocks_iter != blocks_end; ++blocks_iter)
					{
						LLMessageBlock* block = (*blocks_iter);
						const char* block_name = block->mName;
						S32 num_blocks = sTemplateMessageReader->getNumberOfBlocks(block_name);
						for(S32 i = 0; i < num_blocks; i++)
						{
							full.append(llformat("[%s]\n", block->mName));
							LLMessageBlock::message_variable_map_t::iterator var_end = block->mMemberVariables.end();
							for (LLMessageBlock::message_variable_map_t::iterator var_iter = block->mMemberVariables.begin();
								 var_iter != var_end; ++var_iter)
							{
								LLMessageVariable* variable = (*var_iter);
								const char* var_name = variable->getName();
								BOOL returned_hex;
								std::string value = getString(sTemplateMessageReader, block_name, i, var_name, variable->getType(), returned_hex);
								if(returned_hex)
									full.append(llformat("%s =| ", var_name));
								else
									full.append(llformat("%s = ", var_name));
								// llformat has a 1024 char limit!?
								full.append(value);
								full.append("\n");
							}
						}
					} // blocks_iter
				} // decode_valid
			}
		}
		if(decode_invalid)
		{
			full = isOutgoing() ? "out" : "in";
			full.append("\n");
			for(S32 i = 0; i < mDataSize; i++)
				full.append(llformat("%02X ", mData[i]));
		}
	}
	else // not template
	{
		full = "FIXME";
	}
	return full;
}
// static
void LLFloaterMessageBuilder::onCommitPacketCombo(LLUICtrl* ctrl, void* user_data)
{
	LLFloaterMessageBuilder* floaterp = (LLFloaterMessageBuilder*)user_data;
	LLViewerObject* selected_objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
	LLParcel* agent_parcelp = LLViewerParcelMgr::getInstance()->getAgentParcel();
	std::string message = ctrl->getValue();
	std::map<const char *, LLMessageTemplate*>::iterator template_iter;
	template_iter = gMessageSystem->mMessageTemplates.find( LLMessageStringTable::getInstance()->getString(message.c_str()) );
	if(template_iter == gMessageSystem->mMessageTemplates.end())
	{
		floaterp->childSetText("message_edit", std::string(""));
		return;
	}
	std::string text(llformat((*template_iter).second->getTrust() == MT_NOTRUST ? "out %s\n" : "in %s\n", message.c_str()));
	LLMessageTemplate* temp = (*template_iter).second;
	LLMessageTemplate::message_block_map_t::iterator blocks_end = temp->mMemberBlocks.end();
	for (LLMessageTemplate::message_block_map_t::iterator blocks_iter = temp->mMemberBlocks.begin();
		 blocks_iter != blocks_end; ++blocks_iter)
	{
		LLMessageBlock* block = (*blocks_iter);
		const char* block_name = block->mName;
		std::string block_name_string = std::string(block_name);
		S32 num_blocks = 1;
		if(block->mType == MBT_MULTIPLE)
			num_blocks = block->mNumber;
		else if(("ObjectLink" == message && "ObjectData" == block_name_string))
			num_blocks = 2;
		for(S32 i = 0; i < num_blocks; i++)
		{
			text.append(llformat("[%s]\n", block_name));
			LLMessageBlock::message_variable_map_t::iterator var_end = block->mMemberVariables.end();
			for (LLMessageBlock::message_variable_map_t::iterator var_iter = block->mMemberVariables.begin();
				 var_iter != var_end; ++var_iter)
			{
				LLMessageVariable* variable = (*var_iter);
				const char* var_name = variable->getName();
				std::string var_name_string = std::string(var_name);
				text.append(llformat("%s = ", var_name));
				std::string value("");
				S32 size = variable->getSize();
				switch(variable->getType())
				{
				case MVT_U8:
				case MVT_U16:
				case MVT_U32:
				case MVT_U64:
				case MVT_S8:
				case MVT_S16:
				case MVT_S32:
				case MVT_IP_ADDR:
				case MVT_IP_PORT:
					if("RegionHandle" == var_name_string || "Handle" == var_name_string)
						value = "$RegionHandle";
					else if("CircuitCode" == var_name_string || "ViewerCircuitCode" == var_name_string
						|| ("Code" == var_name_string && "CircuitCode" == block_name_string) )
					{
						value = "$CircuitCode";
					}
					else if(selected_objectp && 
							(
								   "ObjectLocalID" == var_name_string
								|| "TaskLocalID" == var_name_string
								|| ("LocalID" == var_name_string && 
										(
											   "ObjectData" == block_name_string
											|| "UpdateData" == block_name_string
											|| "InventoryData" == block_name_string
										)
									)
							)
						)
					{
						std::stringstream temp_stream;
						temp_stream << selected_objectp->getLocalID();
						value = temp_stream.str();
					}
					else if( agent_parcelp &&
						"LocalID" == var_name_string &&
						(
							"ParcelData" == block_name_string
							|| message.find("Parcel") != message.npos
						)
					)
					{
						std::stringstream temp_stream;
						temp_stream << agent_parcelp->getLocalID();
						value = temp_stream.str();
					}
					else if("PCode" == var_name_string)
						value = "9";
					else if("PathCurve" == var_name_string)
						value = "16";
					else if("ProfileCurve" == var_name_string)
						value = "1";
					else if("PathScaleX" == var_name_string || "PathScaleY" == var_name_string)
						value = "100";
					else if("BypassRaycast" == var_name_string)
						value = "1";
					else
						value = "0";
					break;
				case MVT_F32:
				case MVT_F64:
					value = "0.0";
					break;
				case MVT_LLVector3:
				case MVT_LLVector3d:
				case MVT_LLQuaternion:
					if("Position" == var_name_string || "RayStart" == var_name_string || "RayEnd" == var_name_string)
						value = "$Position";
					else if("Scale" == var_name_string)
						value = "<0.5, 0.5, 0.5>";
					else
						value = "<0, 0, 0>";
					break;
				case MVT_LLVector4:
					value = "<0, 0, 0, 0>";
					break;
				case MVT_LLUUID:
					if("AgentID" == var_name_string)
						value = "$AgentID";
					else if("SessionID" == var_name_string)
						value = "$SessionID";
					else if("ObjectID" == var_name_string && selected_objectp)
						value = selected_objectp->getID().asString();
					else if("ParcelID" == var_name_string && agent_parcelp)
						value = agent_parcelp->getID().asString();
					else
						value = "00000000-0000-0000-0000-000000000000";
					break;
				case MVT_BOOL:
					value = "false";
					break;
				case MVT_VARIABLE:
					value = "Hello, world!";
					break;
				case MVT_FIXED:
					for(S32 si = 0; si < size; si++)
						value.append("a");
					break;
				default:
					value = "";
					break;
				}
				text.append(llformat("%s\n", value.c_str()));
			}
		}
	}
	text = text.substr(0, text.length() - 1);
	floaterp->childSetText("message_edit", text);
}