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); }