diff --git a/indra/newview/llfloatermessagebuilder.cpp b/indra/newview/llfloatermessagebuilder.cpp
index 9825833cd..d78a29f3e 100644
--- a/indra/newview/llfloatermessagebuilder.cpp
+++ b/indra/newview/llfloatermessagebuilder.cpp
@@ -1,810 +1,965 @@
-//
-#include "llviewerprecompiledheaders.h"
-#include "llfloatermessagebuilder.h"
-#include "lluictrlfactory.h"
-#include "llmessagetemplate.h"
-#include "llagent.h"
-#include "llchat.h"
-#include "llfloaterchat.h"
-#include "llviewerregion.h" // getHandle
-#include "llcombobox.h"
-#include "llselectmgr.h" // fill in stuff about selected object
-#include "llparcel.h"
-#include "llviewerparcelmgr.h" // same for parcel
-LLFloaterMessageBuilder::LLFloaterMessageBuilder(std::string initial_text)
-: LLFloater(),
- mInitialText(initial_text)
-{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_message_builder.xml");
-}
-LLFloaterMessageBuilder::~LLFloaterMessageBuilder()
-{
-}
-void LLFloaterMessageBuilder::show(std::string initial_text)
-{
- (new LLFloaterMessageBuilder(initial_text))->open();
-}
-BOOL LLFloaterMessageBuilder::postBuild()
-{
- childSetText("message_edit", mInitialText);
- childSetAction("send_btn", onClickSend, this);
- std::vector names;
- LLComboBox* combo;
- LLMessageSystem::message_template_name_map_t::iterator temp_end = gMessageSystem->mMessageTemplates.end();
- LLMessageSystem::message_template_name_map_t::iterator temp_iter;
- std::vector::iterator names_end;
- std::vector::iterator names_iter;
- for(temp_iter = gMessageSystem->mMessageTemplates.begin(); temp_iter != temp_end; ++temp_iter)
- if((*temp_iter).second->getTrust() == MT_NOTRUST)
- names.push_back((*temp_iter).second->mName);
- std::sort(names.begin(), names.end());
- combo = getChild("untrusted_message_combo");
- names_end = names.end();
- for(names_iter = names.begin(); names_iter != names_end; ++names_iter)
- combo->add((*names_iter));
- names.clear();
- for(temp_iter = gMessageSystem->mMessageTemplates.begin(); temp_iter != temp_end; ++temp_iter)
- if((*temp_iter).second->getTrust() == MT_TRUST)
- names.push_back((*temp_iter).second->mName);
- std::sort(names.begin(), names.end());
- combo = getChild("trusted_message_combo");
- names_end = names.end();
- for(names_iter = names.begin(); names_iter != names_end; ++names_iter)
- combo->add((*names_iter));
- childSetCommitCallback("untrusted_message_combo", onCommitPacketCombo, this);
- childSetCommitCallback("trusted_message_combo", onCommitPacketCombo, this);
- return TRUE;
-}
-inline std::vector split(std::string input, std::string separator)
-{
- S32 size = input.length();
- char* buffer = new char[size + 1];
- strncpy(buffer, input.c_str(), size);
- buffer[size] = '\0';
- std::vector lines;
- char* result = strtok(buffer, separator.c_str());
- while(result)
- {
- lines.push_back(result);
- result = strtok(NULL, separator.c_str());
- }
- delete[] buffer;
- return lines;
-}
-std::string mvtstr(e_message_variable_type var_type)
-{
- switch(var_type)
- {
- case MVT_U8:
- return "U8";
- break;
- case MVT_U16:
- return "U16";
- break;
- case MVT_U32:
- return "U32";
- break;
- case MVT_U64:
- return "U64";
- break;
- case MVT_S8:
- return "S8";
- break;
- case MVT_S16:
- return "S16";
- break;
- case MVT_S32:
- return "S32";
- break;
- case MVT_S64:
- return "S64";
- break;
- case MVT_F32:
- return "F32";
- break;
- case MVT_F64:
- return "F64";
- break;
- case MVT_LLVector3:
- return "LLVector3";
- break;
- case MVT_LLVector3d:
- return "LLVector3d";
- break;
- case MVT_LLVector4:
- return "LLVector4";
- break;
- case MVT_LLQuaternion:
- return "LLQuaternion";
- break;
- case MVT_LLUUID:
- return "LLUUID";
- break;
- case MVT_BOOL:
- return "BOOL";
- break;
- case MVT_IP_ADDR:
- return "IPADDR";
- break;
- case MVT_IP_PORT:
- return "IPPORT";
- break;
- case MVT_VARIABLE:
- return "Variable";
- break;
- case MVT_FIXED:
- return "Fixed";
- break;
- default:
- return "Missingno.";
- break;
- }
-}
-// static
-BOOL LLFloaterMessageBuilder::addField(e_message_variable_type var_type, const char* var_name, std::string input, BOOL hex)
-{
- LLStringUtil::trim(input);
- if(input.length() < 1 && var_type != MVT_VARIABLE)
- return FALSE;
- U8 valueU8;
- U16 valueU16;
- U32 valueU32;
- U64 valueU64;
- S8 valueS8;
- S16 valueS16;
- S32 valueS32;
- // S64 valueS64;
- F32 valueF32;
- F64 valueF64;
- LLVector3 valueVector3;
- LLVector3d valueVector3d;
- LLVector4 valueVector4;
- LLQuaternion valueQuaternion;
- LLUUID valueLLUUID;
- BOOL valueBOOL;
- std::string input_lower = input;
- LLStringUtil::toLower(input_lower);
- if(input_lower == "$agentid")
- input = gAgent.getID().asString();
- else if(input_lower == "$sessionid")
- input = gAgent.getSessionID().asString();
- else if(input_lower == "$uuid")
- {
- LLUUID id;
- id.generate();
- input = id.asString();
- }
- else if(input_lower == "$circuitcode")
- {
- std::stringstream temp_stream;
- temp_stream << gMessageSystem->mOurCircuitCode;
- input = temp_stream.str();
- }
- else if(input_lower == "$regionhandle")
- {
- std::stringstream temp_stream;
- temp_stream << (gAgent.getRegion() ? gAgent.getRegion()->getHandle() : 0);
- input = temp_stream.str();
- }
- else if(input_lower == "$position" || input_lower == "$pos")
- {
- std::stringstream temp_stream;
- valueVector3 = gAgent.getPositionAgent();
- temp_stream << "<" << valueVector3[0] << ", " << valueVector3[1] << ", " << valueVector3[2] << ">";
- input = temp_stream.str();
- }
- if(hex)
- {
- if(var_type != MVT_VARIABLE && var_type != MVT_FIXED)
- return FALSE;
- int len = input_lower.length();
- const char* cstr = input_lower.c_str();
- std::string new_input("");
- BOOL nibble = FALSE;
- char byte = 0;
- for(int i = 0; i < len; i++)
- {
- char c = cstr[i];
- if(c >= 0x30 && c <= 0x39)
- c -= 0x30;
- else if(c >= 0x61 && c <= 0x66)
- c -= 0x57;
- else if(c != 0x20)
- return FALSE;
- else
- continue;
- if(!nibble)
- byte = c << 4;
- else
- new_input.push_back(byte | c);
- nibble = !nibble;
- }
- if(nibble)
- return FALSE;
- input = new_input;
- }
- std::stringstream stream(input);
- std::vector tokens;
- switch(var_type)
- {
- case MVT_U8:
- if(input.substr(0, 1) == "-")
- return FALSE;
- if((stream >> valueU32).fail())
- return FALSE;
- valueU8 = (U8)valueU32;
- gMessageSystem->addU8(var_name, valueU8);
- return TRUE;
- break;
- case MVT_U16:
- if(input.substr(0, 1) == "-")
- return FALSE;
- if((stream >> valueU16).fail())
- return FALSE;
- gMessageSystem->addU16(var_name, valueU16);
- return TRUE;
- break;
- case MVT_U32:
- if(input.substr(0, 1) == "-")
- return FALSE;
- if((stream >> valueU32).fail())
- return FALSE;
- gMessageSystem->addU32(var_name, valueU32);
- return TRUE;
- break;
- case MVT_U64:
- if(input.substr(0, 1) == "-")
- return FALSE;
- if((stream >> valueU64).fail())
- return FALSE;
- gMessageSystem->addU64(var_name, valueU64);
- return TRUE;
- break;
- case MVT_S8:
- if((stream >> valueS8).fail())
- return FALSE;
- gMessageSystem->addS8(var_name, valueS8);
- return TRUE;
- break;
- case MVT_S16:
- if((stream >> valueS16).fail())
- return FALSE;
- gMessageSystem->addS16(var_name, valueS16);
- return TRUE;
- break;
- case MVT_S32:
- if((stream >> valueS32).fail())
- return FALSE;
- gMessageSystem->addS32(var_name, valueS32);
- return TRUE;
- break;
- /*
- case MVT_S64:
- if((stream >> valueS64).fail())
- return FALSE;
- gMessageSystem->addS64(var_name, valueS64);
- return TRUE;
- break;
- */
- case MVT_F32:
- if((stream >> valueF32).fail())
- return FALSE;
- gMessageSystem->addF32(var_name, valueF32);
- return TRUE;
- break;
- case MVT_F64:
- if((stream >> valueF64).fail())
- return FALSE;
- gMessageSystem->addF64(var_name, valueF64);
- return TRUE;
- break;
- case MVT_LLVector3:
- LLStringUtil::trim(input);
- if(input.substr(0, 1) != "<" || input.substr(input.length() - 1, 1) != ">")
- return FALSE;
- tokens = split(input.substr(1, input.length() - 2), ",");
- if(tokens.size() != 3)
- return FALSE;
- for(int i = 0; i < 3; i++)
- {
- stream.clear();
- stream.str(tokens[i]);
- if((stream >> valueF32).fail())
- return FALSE;
- valueVector3.mV[i] = valueF32;
- }
- gMessageSystem->addVector3(var_name, valueVector3);
- return TRUE;
- break;
- case MVT_LLVector3d:
- LLStringUtil::trim(input);
- if(input.substr(0, 1) != "<" || input.substr(input.length() - 1, 1) != ">")
- return FALSE;
- tokens = split(input.substr(1, input.length() - 2), ",");
- if(tokens.size() != 3)
- return FALSE;
- for(int i = 0; i < 3; i++)
- {
- stream.clear();
- stream.str(tokens[i]);
- if((stream >> valueF64).fail())
- return FALSE;
- valueVector3d.mdV[i] = valueF64;
- }
- gMessageSystem->addVector3d(var_name, valueVector3d);
- return TRUE;
- break;
- case MVT_LLVector4:
- LLStringUtil::trim(input);
- if(input.substr(0, 1) != "<" || input.substr(input.length() - 1, 1) != ">")
- return FALSE;
- tokens = split(input.substr(1, input.length() - 2), ",");
- if(tokens.size() != 4)
- return FALSE;
- for(int i = 0; i < 4; i++)
- {
- stream.clear();
- stream.str(tokens[i]);
- if((stream >> valueF32).fail())
- return FALSE;
- valueVector4.mV[i] = valueF32;
- }
- gMessageSystem->addVector4(var_name, valueVector4);
- return TRUE;
- break;
- case MVT_LLQuaternion:
- LLStringUtil::trim(input);
- if(input.substr(0, 1) != "<" || input.substr(input.length() - 1, 1) != ">")
- return FALSE;
- tokens = split(input.substr(1, input.length() - 2), ",");
- if(tokens.size() != 3)
- return FALSE;
- for(int i = 0; i < 3; i++)
- {
- stream.clear();
- stream.str(tokens[i]);
- if((stream >> valueF32).fail())
- return FALSE;
- valueVector3.mV[i] = valueF32;
- }
- valueQuaternion.unpackFromVector3(valueVector3);
- gMessageSystem->addQuat(var_name, valueQuaternion);
- return TRUE;
- break;
- case MVT_LLUUID:
- if((stream >> valueLLUUID).fail())
- return FALSE;
- gMessageSystem->addUUID(var_name, valueLLUUID);
- return TRUE;
- break;
- case MVT_BOOL:
- if(input_lower == "true")
- valueBOOL = TRUE;
- else if(input_lower == "false")
- valueBOOL = FALSE;
- else if((stream >> valueBOOL).fail())
- return FALSE;
- //gMessageSystem->addBOOL(var_name, valueBOOL);
- gMessageSystem->addU8(var_name, (U8)valueBOOL);
- return TRUE;
- break;
- case MVT_IP_ADDR:
- if((stream >> valueU32).fail())
- return FALSE;
- gMessageSystem->addIPAddr(var_name, valueU32);
- return TRUE;
- break;
- case MVT_IP_PORT:
- if((stream >> valueU16).fail())
- return FALSE;
- gMessageSystem->addIPPort(var_name, valueU16);
- return TRUE;
- break;
- case MVT_VARIABLE:
- if(!hex)
- {
- char* buffer = new char[input.size() + 1];
- strncpy(buffer, input.c_str(), input.size());
- buffer[input.size()] = '\0';
- gMessageSystem->addBinaryData(var_name, buffer, input.size() + 1);
- delete[] buffer;
- }
- else
- gMessageSystem->addBinaryData(var_name, input.c_str(), input.size());
- return TRUE;
- break;
- case MVT_FIXED:
- if(!hex)
- {
- char* buffer = new char[input.size() + 1];
- strncpy(buffer, input.c_str(), input.size());
- buffer[input.size()] = '\0';
- gMessageSystem->addBinaryData(var_name, buffer, input.size());
- delete[] buffer;
- }
- else
- gMessageSystem->addBinaryData(var_name, input.c_str(), input.size());
- return TRUE;
- break;
- default:
- break;
- }
- return FALSE;
-}
-// 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::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(std::string("0123456789abcdef").substr(si & 0xf, 1));
- 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);
-}
-// static
-void LLFloaterMessageBuilder::onClickSend(void* user_data)
-{
- LLFloaterMessageBuilder* floaterp = (LLFloaterMessageBuilder*)user_data;
- std::vector lines = split(floaterp->childGetText("message_edit"), "\n");
- if(!lines.size())
- {
- LLFloaterChat::addChat(LLChat("Not enough information :O"));
- return;
- }
- std::vector tokens = split(lines[0], " ");
- if(!tokens.size())
- {
- LLFloaterChat::addChat(LLChat("Not enough information :O"));
- return;
- }
- 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
- {
- LLFloaterChat::addChat(LLChat("Expected direction 'in' or 'out'"));
- return;
- }
- // Message
- std::string message = "Invalid";
- if(tokens.size() > 1)
- {
- if(tokens.size() > 2)
- {
- LLFloaterChat::addChat(LLChat("Unexpected extra stuff at the top"));
- return;
- }
- message = tokens[1];
- LLStringUtil::trim(message);
- }
- // Body
- std::vector parts;
- if(lines.size() > 1)
- {
- std::vector::iterator line_end = lines.end();
- std::vector::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);
- if(!line.length())
- continue;
- 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);
- }
- else
- {
- if(current_block.empty())
- {
- LLFloaterChat::addChat(LLChat("Unexpected field when no block yet"));
- return;
- }
- int eqpos = line.find("=");
- if(eqpos == line.npos)
- {
- LLFloaterChat::addChat(LLChat("Missing an equal sign"));
- return;
- }
- std::string field = line.substr(0, eqpos);
- LLStringUtil::trim(field);
- if(!field.length())
- {
- LLFloaterChat::addChat(LLChat("Missing name of field"));
- return;
- }
- std::string value = line.substr(eqpos + 1);
- LLStringUtil::trim(value);
- parts_var pv;
- 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);
- }
- }
- }
- // Verification
- std::map::iterator template_iter;
- template_iter = gMessageSystem->mMessageTemplates.find( LLMessageStringTable::getInstance()->getString(message.c_str()) );
- if(template_iter == gMessageSystem->mMessageTemplates.end())
- {
- LLFloaterChat::addChat(LLChat(llformat("Don't know how to build a '%s' message", message.c_str())));
- return;
- }
- LLMessageTemplate* temp = (*template_iter).second;
- std::vector::iterator parts_end = parts.end();
- std::vector::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;
- if(parts_iter == parts_end)
- {
- if(block->mType != MBT_VARIABLE)
- LLFloaterChat::addChat(LLChat(llformat("Expected '%s' block", block_name)));
- else
- {
- ++blocks_iter;
- continue;
- }
- return;
- }
- else if((*parts_iter).name != block_name)
- {
- if(block->mType != MBT_VARIABLE)
- LLFloaterChat::addChat(LLChat(llformat("Expected '%s' block", block_name)));
- else
- {
- ++blocks_iter;
- continue;
- }
- return;
- }
- std::vector::iterator part_var_end = (*parts_iter).vars.end();
- std::vector::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();
- if(part_var_iter == part_var_end)
- {
- LLFloaterChat::addChat(LLChat(llformat("Expected '%s' field under '%s' block", var_name, block_name)));
- return;
- }
- else if((*part_var_iter).name != var_name)
- {
- LLFloaterChat::addChat(LLChat(llformat("Expected '%s' field under '%s' block", var_name, block_name)));
- return;
- }
- (*part_var_iter).var_type = variable->getType();
- ++part_var_iter;
- }
- if(part_var_iter != part_var_end)
- {
- LLFloaterChat::addChat(LLChat(llformat("Unexpected field(s) at end of '%s' block", block_name)));
- return;
- }
- ++parts_iter;
- // test
- if((block->mType != MBT_SINGLE) && (parts_iter != parts_end) && ((*parts_iter).name == block_name))
- {
- // block will repeat
- }
- else ++blocks_iter;
- }
- if(parts_iter != parts_end)
- {
- LLFloaterChat::addChat(LLChat("Unexpected block(s) at end"));
- return;
- }
- // Build and send
- if(outgoing)
- {
- 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::iterator part_var_end = (*parts_iter).vars.end();
- for(std::vector::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))
- {
- LLFloaterChat::addChat(LLChat(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;
- }
- }
- }
- gMessageSystem->sendMessage(gAgent.getRegionHost());
- }
- else
- {
- LLFloaterChat::addChat(LLChat("Incoming message isn't supported yet :("));
- return;
- }
-}
-BOOL LLFloaterMessageBuilder::handleKeyHere(KEY key, MASK mask)
-{
- if(key == KEY_RETURN && (mask & MASK_CONTROL))
- {
- onClickSend(this);
- return TRUE;
- }
- if(key == KEY_ESCAPE)
- {
- releaseFocus();
- return TRUE;
- }
- return FALSE;
-}
-//
+//
+#include "llviewerprecompiledheaders.h"
+#include "llfloatermessagebuilder.h"
+#include "lluictrlfactory.h"
+#include "llmessagetemplate.h"
+#include "llagent.h"
+#include "llchat.h"
+#include "llfloaterchat.h"
+#include "llviewerregion.h" // getHandle
+#include "llcombobox.h"
+#include "llselectmgr.h" // fill in stuff about selected object
+#include "llparcel.h"
+#include "llviewerparcelmgr.h" // same for parcel
+#include "llscrolllistctrl.h"
+#include "llworld.h"
+
+////////////////////////////////
+// LLNetListItem
+////////////////////////////////
+LLNetListItem::LLNetListItem(LLUUID id)
+: mID(id),
+ mAutoName(TRUE),
+ mName("No name"),
+ mPreviousRegionName(""),
+ mCircuitData(NULL)
+{
+}
+
+////////////////////////////////
+// LLFloaterMessageBuilder
+////////////////////////////////
+std::list LLFloaterMessageBuilder::sNetListItems;
+
+LLFloaterMessageBuilder::LLFloaterMessageBuilder(std::string initial_text)
+: LLFloater(),
+ LLEventTimer(1.0f),
+ mNetInfoMode(NI_NET),
+ mInitialText(initial_text)
+{
+ LLUICtrlFactory::getInstance()->buildFloater(this, "floater_message_builder.xml");
+}
+LLFloaterMessageBuilder::~LLFloaterMessageBuilder()
+{
+}
+void LLFloaterMessageBuilder::show(std::string initial_text)
+{
+ (new LLFloaterMessageBuilder(initial_text))->open();
+}
+BOOL LLFloaterMessageBuilder::tick()
+{
+ refreshNetList();
+ return FALSE;
+}
+LLNetListItem* LLFloaterMessageBuilder::findNetListItem(LLHost host)
+{
+ std::list::iterator end = sNetListItems.end();
+ for(std::list::iterator iter = sNetListItems.begin(); iter != end; ++iter)
+ if((*iter)->mCircuitData && (*iter)->mCircuitData->getHost() == host)
+ return (*iter);
+ return NULL;
+}
+LLNetListItem* LLFloaterMessageBuilder::findNetListItem(LLUUID id)
+{
+ std::list::iterator end = sNetListItems.end();
+ for(std::list::iterator iter = sNetListItems.begin(); iter != end; ++iter)
+ if((*iter)->mID == id)
+ return (*iter);
+ return NULL;
+}
+void LLFloaterMessageBuilder::refreshNetList()
+{
+ LLScrollListCtrl* scrollp = getChild("net_list");
+ // Update circuit data of net list items
+ std::vector circuits = gMessageSystem->getCircuit()->getCircuitDataList();
+ std::vector::iterator circuits_end = circuits.end();
+ for(std::vector::iterator iter = circuits.begin(); iter != circuits_end; ++iter)
+ {
+ LLNetListItem* itemp = findNetListItem((*iter)->getHost());
+ if(!itemp)
+ {
+ LLUUID id; id.generate();
+ itemp = new LLNetListItem(id);
+ sNetListItems.push_back(itemp);
+ }
+ itemp->mCircuitData = (*iter);
+ }
+ // Clear circuit data of items whose circuits are gone
+ std::list::iterator items_end = sNetListItems.end();
+ for(std::list::iterator iter = sNetListItems.begin(); iter != items_end; ++iter)
+ {
+ if(std::find(circuits.begin(), circuits.end(), (*iter)->mCircuitData) == circuits.end())
+ (*iter)->mCircuitData = NULL;
+ }
+ // Remove net list items that are totally useless now
+ for(std::list::iterator iter = sNetListItems.begin(); iter != sNetListItems.end();)
+ {
+ if((*iter)->mCircuitData == NULL)
+ iter = sNetListItems.erase(iter);
+ else ++iter;
+ }
+ // Update names of net list items
+ items_end = sNetListItems.end();
+ for(std::list::iterator iter = sNetListItems.begin(); iter != items_end; ++iter)
+ {
+ LLNetListItem* itemp = (*iter);
+ if(itemp->mAutoName)
+ {
+ if(itemp->mCircuitData)
+ {
+ LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(itemp->mCircuitData->getHost());
+ if(regionp)
+ {
+ std::string name = regionp->getName();
+ if(name == "") name = llformat("%s (awaiting region name)", itemp->mCircuitData->getHost().getString().c_str());
+ itemp->mName = name;
+ itemp->mPreviousRegionName = name;
+ }
+ else
+ {
+ itemp->mName = itemp->mCircuitData->getHost().getString();
+ if(itemp->mPreviousRegionName != "")
+ itemp->mName.append(llformat(" (was %s)", itemp->mPreviousRegionName.c_str()));
+ }
+ }
+ else
+ {
+ // an item just for an event queue, not handled yet
+ itemp->mName = "Something else";
+ }
+ }
+ }
+ // Rebuild scroll list from scratch
+ LLUUID selected_id = scrollp->getFirstSelected() ? scrollp->getFirstSelected()->getUUID() : LLUUID::null;
+ S32 scroll_pos = scrollp->getScrollPos();
+ scrollp->clearRows();
+ for(std::list::iterator iter = sNetListItems.begin(); iter != items_end; ++iter)
+ {
+ LLNetListItem* itemp = (*iter);
+ LLSD element;
+ element["id"] = itemp->mID;
+ LLSD& text_column = element["columns"][0];
+ text_column["column"] = "text";
+ text_column["value"] = itemp->mName + (itemp->mCircuitData->getHost() == gAgent.getRegionHost() ? " (main)" : "");
+
+ LLSD& state_column = element["columns"][ 1];
+ state_column["column"] = "state";
+ state_column["value"] = "";
+
+ LLScrollListItem* scroll_itemp = scrollp->addElement(element);
+ BOOL has_live_circuit = itemp->mCircuitData && itemp->mCircuitData->isAlive();
+
+ LLScrollListText* state = (LLScrollListText*)scroll_itemp->getColumn(1);
+
+ if(has_live_circuit)
+ state->setText(std::string("Alive"));
+ else
+ state->setText(std::string("Alive"));
+ }
+ if(selected_id.notNull()) scrollp->selectByID(selected_id);
+ if(scroll_pos < scrollp->getItemCount()) scrollp->setScrollPos(scroll_pos);
+}
+BOOL LLFloaterMessageBuilder::postBuild()
+{
+ childSetText("message_edit", mInitialText);
+ childSetAction("send_btn", onClickSend, this);
+ std::vector names;
+ LLComboBox* combo;
+ LLMessageSystem::message_template_name_map_t::iterator temp_end = gMessageSystem->mMessageTemplates.end();
+ LLMessageSystem::message_template_name_map_t::iterator temp_iter;
+ std::vector::iterator names_end;
+ std::vector::iterator names_iter;
+ for(temp_iter = gMessageSystem->mMessageTemplates.begin(); temp_iter != temp_end; ++temp_iter)
+ if((*temp_iter).second->getTrust() == MT_NOTRUST)
+ names.push_back((*temp_iter).second->mName);
+ std::sort(names.begin(), names.end());
+ combo = getChild("untrusted_message_combo");
+ names_end = names.end();
+ for(names_iter = names.begin(); names_iter != names_end; ++names_iter)
+ combo->add((*names_iter));
+ names.clear();
+ for(temp_iter = gMessageSystem->mMessageTemplates.begin(); temp_iter != temp_end; ++temp_iter)
+ if((*temp_iter).second->getTrust() == MT_TRUST)
+ names.push_back((*temp_iter).second->mName);
+ std::sort(names.begin(), names.end());
+ combo = getChild("trusted_message_combo");
+ names_end = names.end();
+ for(names_iter = names.begin(); names_iter != names_end; ++names_iter)
+ combo->add((*names_iter));
+ childSetCommitCallback("untrusted_message_combo", onCommitPacketCombo, this);
+ childSetCommitCallback("trusted_message_combo", onCommitPacketCombo, this);
+ return TRUE;
+}
+inline std::vector split(std::string input, std::string separator)
+{
+ S32 size = input.length();
+ char* buffer = new char[size + 1];
+ strncpy(buffer, input.c_str(), size);
+ buffer[size] = '\0';
+ std::vector lines;
+ char* result = strtok(buffer, separator.c_str());
+ while(result)
+ {
+ lines.push_back(result);
+ result = strtok(NULL, separator.c_str());
+ }
+ delete[] buffer;
+ return lines;
+}
+std::string mvtstr(e_message_variable_type var_type)
+{
+ switch(var_type)
+ {
+ case MVT_U8:
+ return "U8";
+ break;
+ case MVT_U16:
+ return "U16";
+ break;
+ case MVT_U32:
+ return "U32";
+ break;
+ case MVT_U64:
+ return "U64";
+ break;
+ case MVT_S8:
+ return "S8";
+ break;
+ case MVT_S16:
+ return "S16";
+ break;
+ case MVT_S32:
+ return "S32";
+ break;
+ case MVT_S64:
+ return "S64";
+ break;
+ case MVT_F32:
+ return "F32";
+ break;
+ case MVT_F64:
+ return "F64";
+ break;
+ case MVT_LLVector3:
+ return "LLVector3";
+ break;
+ case MVT_LLVector3d:
+ return "LLVector3d";
+ break;
+ case MVT_LLVector4:
+ return "LLVector4";
+ break;
+ case MVT_LLQuaternion:
+ return "LLQuaternion";
+ break;
+ case MVT_LLUUID:
+ return "LLUUID";
+ break;
+ case MVT_BOOL:
+ return "BOOL";
+ break;
+ case MVT_IP_ADDR:
+ return "IPADDR";
+ break;
+ case MVT_IP_PORT:
+ return "IPPORT";
+ break;
+ case MVT_VARIABLE:
+ return "Variable";
+ break;
+ case MVT_FIXED:
+ return "Fixed";
+ break;
+ default:
+ return "Missingno.";
+ break;
+ }
+}
+// static
+BOOL LLFloaterMessageBuilder::addField(e_message_variable_type var_type, const char* var_name, std::string input, BOOL hex)
+{
+ LLStringUtil::trim(input);
+ if(input.length() < 1 && var_type != MVT_VARIABLE)
+ return FALSE;
+ U8 valueU8;
+ U16 valueU16;
+ U32 valueU32;
+ U64 valueU64;
+ S8 valueS8;
+ S16 valueS16;
+ S32 valueS32;
+ // S64 valueS64;
+ F32 valueF32;
+ F64 valueF64;
+ LLVector3 valueVector3;
+ LLVector3d valueVector3d;
+ LLVector4 valueVector4;
+ LLQuaternion valueQuaternion;
+ LLUUID valueLLUUID;
+ BOOL valueBOOL;
+ std::string input_lower = input;
+ LLStringUtil::toLower(input_lower);
+ if(input_lower == "$agentid")
+ input = gAgent.getID().asString();
+ else if(input_lower == "$sessionid")
+ input = gAgent.getSessionID().asString();
+ else if(input_lower == "$uuid")
+ {
+ LLUUID id;
+ id.generate();
+ input = id.asString();
+ }
+ else if(input_lower == "$circuitcode")
+ {
+ std::stringstream temp_stream;
+ temp_stream << gMessageSystem->mOurCircuitCode;
+ input = temp_stream.str();
+ }
+ else if(input_lower == "$regionhandle")
+ {
+ std::stringstream temp_stream;
+ temp_stream << (gAgent.getRegion() ? gAgent.getRegion()->getHandle() : 0);
+ input = temp_stream.str();
+ }
+ else if(input_lower == "$position" || input_lower == "$pos")
+ {
+ std::stringstream temp_stream;
+ valueVector3 = gAgent.getPositionAgent();
+ temp_stream << "<" << valueVector3[0] << ", " << valueVector3[1] << ", " << valueVector3[2] << ">";
+ input = temp_stream.str();
+ }
+ if(hex)
+ {
+ if(var_type != MVT_VARIABLE && var_type != MVT_FIXED)
+ return FALSE;
+ int len = input_lower.length();
+ const char* cstr = input_lower.c_str();
+ std::string new_input("");
+ BOOL nibble = FALSE;
+ char byte = 0;
+ for(int i = 0; i < len; i++)
+ {
+ char c = cstr[i];
+ if(c >= 0x30 && c <= 0x39)
+ c -= 0x30;
+ else if(c >= 0x61 && c <= 0x66)
+ c -= 0x57;
+ else if(c != 0x20)
+ return FALSE;
+ else
+ continue;
+ if(!nibble)
+ byte = c << 4;
+ else
+ new_input.push_back(byte | c);
+ nibble = !nibble;
+ }
+ if(nibble)
+ return FALSE;
+ input = new_input;
+ }
+ std::stringstream stream(input);
+ std::vector tokens;
+ switch(var_type)
+ {
+ case MVT_U8:
+ if(input.substr(0, 1) == "-")
+ return FALSE;
+ if((stream >> valueU32).fail())
+ return FALSE;
+ valueU8 = (U8)valueU32;
+ gMessageSystem->addU8(var_name, valueU8);
+ return TRUE;
+ break;
+ case MVT_U16:
+ if(input.substr(0, 1) == "-")
+ return FALSE;
+ if((stream >> valueU16).fail())
+ return FALSE;
+ gMessageSystem->addU16(var_name, valueU16);
+ return TRUE;
+ break;
+ case MVT_U32:
+ if(input.substr(0, 1) == "-")
+ return FALSE;
+ if((stream >> valueU32).fail())
+ return FALSE;
+ gMessageSystem->addU32(var_name, valueU32);
+ return TRUE;
+ break;
+ case MVT_U64:
+ if(input.substr(0, 1) == "-")
+ return FALSE;
+ if((stream >> valueU64).fail())
+ return FALSE;
+ gMessageSystem->addU64(var_name, valueU64);
+ return TRUE;
+ break;
+ case MVT_S8:
+ if((stream >> valueS8).fail())
+ return FALSE;
+ gMessageSystem->addS8(var_name, valueS8);
+ return TRUE;
+ break;
+ case MVT_S16:
+ if((stream >> valueS16).fail())
+ return FALSE;
+ gMessageSystem->addS16(var_name, valueS16);
+ return TRUE;
+ break;
+ case MVT_S32:
+ if((stream >> valueS32).fail())
+ return FALSE;
+ gMessageSystem->addS32(var_name, valueS32);
+ return TRUE;
+ break;
+ /*
+ case MVT_S64:
+ if((stream >> valueS64).fail())
+ return FALSE;
+ gMessageSystem->addS64(var_name, valueS64);
+ return TRUE;
+ break;
+ */
+ case MVT_F32:
+ if((stream >> valueF32).fail())
+ return FALSE;
+ gMessageSystem->addF32(var_name, valueF32);
+ return TRUE;
+ break;
+ case MVT_F64:
+ if((stream >> valueF64).fail())
+ return FALSE;
+ gMessageSystem->addF64(var_name, valueF64);
+ return TRUE;
+ break;
+ case MVT_LLVector3:
+ LLStringUtil::trim(input);
+ if(input.substr(0, 1) != "<" || input.substr(input.length() - 1, 1) != ">")
+ return FALSE;
+ tokens = split(input.substr(1, input.length() - 2), ",");
+ if(tokens.size() != 3)
+ return FALSE;
+ for(int i = 0; i < 3; i++)
+ {
+ stream.clear();
+ stream.str(tokens[i]);
+ if((stream >> valueF32).fail())
+ return FALSE;
+ valueVector3.mV[i] = valueF32;
+ }
+ gMessageSystem->addVector3(var_name, valueVector3);
+ return TRUE;
+ break;
+ case MVT_LLVector3d:
+ LLStringUtil::trim(input);
+ if(input.substr(0, 1) != "<" || input.substr(input.length() - 1, 1) != ">")
+ return FALSE;
+ tokens = split(input.substr(1, input.length() - 2), ",");
+ if(tokens.size() != 3)
+ return FALSE;
+ for(int i = 0; i < 3; i++)
+ {
+ stream.clear();
+ stream.str(tokens[i]);
+ if((stream >> valueF64).fail())
+ return FALSE;
+ valueVector3d.mdV[i] = valueF64;
+ }
+ gMessageSystem->addVector3d(var_name, valueVector3d);
+ return TRUE;
+ break;
+ case MVT_LLVector4:
+ LLStringUtil::trim(input);
+ if(input.substr(0, 1) != "<" || input.substr(input.length() - 1, 1) != ">")
+ return FALSE;
+ tokens = split(input.substr(1, input.length() - 2), ",");
+ if(tokens.size() != 4)
+ return FALSE;
+ for(int i = 0; i < 4; i++)
+ {
+ stream.clear();
+ stream.str(tokens[i]);
+ if((stream >> valueF32).fail())
+ return FALSE;
+ valueVector4.mV[i] = valueF32;
+ }
+ gMessageSystem->addVector4(var_name, valueVector4);
+ return TRUE;
+ break;
+ case MVT_LLQuaternion:
+ LLStringUtil::trim(input);
+ if(input.substr(0, 1) != "<" || input.substr(input.length() - 1, 1) != ">")
+ return FALSE;
+ tokens = split(input.substr(1, input.length() - 2), ",");
+ if(tokens.size() != 3)
+ return FALSE;
+ for(int i = 0; i < 3; i++)
+ {
+ stream.clear();
+ stream.str(tokens[i]);
+ if((stream >> valueF32).fail())
+ return FALSE;
+ valueVector3.mV[i] = valueF32;
+ }
+ valueQuaternion.unpackFromVector3(valueVector3);
+ gMessageSystem->addQuat(var_name, valueQuaternion);
+ return TRUE;
+ break;
+ case MVT_LLUUID:
+ if((stream >> valueLLUUID).fail())
+ return FALSE;
+ gMessageSystem->addUUID(var_name, valueLLUUID);
+ return TRUE;
+ break;
+ case MVT_BOOL:
+ if(input_lower == "true")
+ valueBOOL = TRUE;
+ else if(input_lower == "false")
+ valueBOOL = FALSE;
+ else if((stream >> valueBOOL).fail())
+ return FALSE;
+ //gMessageSystem->addBOOL(var_name, valueBOOL);
+ gMessageSystem->addU8(var_name, (U8)valueBOOL);
+ return TRUE;
+ break;
+ case MVT_IP_ADDR:
+ if((stream >> valueU32).fail())
+ return FALSE;
+ gMessageSystem->addIPAddr(var_name, valueU32);
+ return TRUE;
+ break;
+ case MVT_IP_PORT:
+ if((stream >> valueU16).fail())
+ return FALSE;
+ gMessageSystem->addIPPort(var_name, valueU16);
+ return TRUE;
+ break;
+ case MVT_VARIABLE:
+ if(!hex)
+ {
+ char* buffer = new char[input.size() + 1];
+ strncpy(buffer, input.c_str(), input.size());
+ buffer[input.size()] = '\0';
+ gMessageSystem->addBinaryData(var_name, buffer, input.size() + 1);
+ delete[] buffer;
+ }
+ else
+ gMessageSystem->addBinaryData(var_name, input.c_str(), input.size());
+ return TRUE;
+ break;
+ case MVT_FIXED:
+ if(!hex)
+ {
+ char* buffer = new char[input.size() + 1];
+ strncpy(buffer, input.c_str(), input.size());
+ buffer[input.size()] = '\0';
+ gMessageSystem->addBinaryData(var_name, buffer, input.size());
+ delete[] buffer;
+ }
+ else
+ gMessageSystem->addBinaryData(var_name, input.c_str(), input.size());
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+// 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::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(std::string("0123456789abcdef").substr(si & 0xf, 1));
+ 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);
+}
+// static
+void LLFloaterMessageBuilder::onClickSend(void* user_data)
+{
+ LLFloaterMessageBuilder* floaterp = (LLFloaterMessageBuilder*)user_data;
+ std::vector lines = split(floaterp->childGetText("message_edit"), "\n");
+ if(!lines.size())
+ {
+ LLFloaterChat::addChat(LLChat("Not enough information :O"));
+ return;
+ }
+ std::vector tokens = split(lines[0], " ");
+ if(!tokens.size())
+ {
+ LLFloaterChat::addChat(LLChat("Not enough information :O"));
+ return;
+ }
+ 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
+ {
+ LLFloaterChat::addChat(LLChat("Expected direction 'in' or 'out'"));
+ return;
+ }
+ // Message
+ std::string message = "Invalid";
+ if(tokens.size() > 1)
+ {
+ if(tokens.size() > 2)
+ {
+ LLFloaterChat::addChat(LLChat("Unexpected extra stuff at the top"));
+ return;
+ }
+ message = tokens[1];
+ LLStringUtil::trim(message);
+ }
+ // Body
+ std::vector parts;
+ if(lines.size() > 1)
+ {
+ std::vector::iterator line_end = lines.end();
+ std::vector::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);
+ if(!line.length())
+ continue;
+ 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);
+ }
+ else
+ {
+ if(current_block.empty())
+ {
+ LLFloaterChat::addChat(LLChat("Unexpected field when no block yet"));
+ return;
+ }
+ int eqpos = line.find("=");
+ if(eqpos == line.npos)
+ {
+ LLFloaterChat::addChat(LLChat("Missing an equal sign"));
+ return;
+ }
+ std::string field = line.substr(0, eqpos);
+ LLStringUtil::trim(field);
+ if(!field.length())
+ {
+ LLFloaterChat::addChat(LLChat("Missing name of field"));
+ return;
+ }
+ std::string value = line.substr(eqpos + 1);
+ LLStringUtil::trim(value);
+ parts_var pv;
+ 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);
+ }
+ }
+ }
+ // Verification
+ std::map::iterator template_iter;
+ template_iter = gMessageSystem->mMessageTemplates.find( LLMessageStringTable::getInstance()->getString(message.c_str()) );
+ if(template_iter == gMessageSystem->mMessageTemplates.end())
+ {
+ LLFloaterChat::addChat(LLChat(llformat("Don't know how to build a '%s' message", message.c_str())));
+ return;
+ }
+ LLMessageTemplate* temp = (*template_iter).second;
+ std::vector::iterator parts_end = parts.end();
+ std::vector::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;
+ if(parts_iter == parts_end)
+ {
+ if(block->mType != MBT_VARIABLE)
+ LLFloaterChat::addChat(LLChat(llformat("Expected '%s' block", block_name)));
+ else
+ {
+ ++blocks_iter;
+ continue;
+ }
+ return;
+ }
+ else if((*parts_iter).name != block_name)
+ {
+ if(block->mType != MBT_VARIABLE)
+ LLFloaterChat::addChat(LLChat(llformat("Expected '%s' block", block_name)));
+ else
+ {
+ ++blocks_iter;
+ continue;
+ }
+ return;
+ }
+ std::vector::iterator part_var_end = (*parts_iter).vars.end();
+ std::vector::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();
+ if(part_var_iter == part_var_end)
+ {
+ LLFloaterChat::addChat(LLChat(llformat("Expected '%s' field under '%s' block", var_name, block_name)));
+ return;
+ }
+ else if((*part_var_iter).name != var_name)
+ {
+ LLFloaterChat::addChat(LLChat(llformat("Expected '%s' field under '%s' block", var_name, block_name)));
+ return;
+ }
+ (*part_var_iter).var_type = variable->getType();
+ ++part_var_iter;
+ }
+ if(part_var_iter != part_var_end)
+ {
+ LLFloaterChat::addChat(LLChat(llformat("Unexpected field(s) at end of '%s' block", block_name)));
+ return;
+ }
+ ++parts_iter;
+ // test
+ if((block->mType != MBT_SINGLE) && (parts_iter != parts_end) && ((*parts_iter).name == block_name))
+ {
+ // block will repeat
+ }
+ else ++blocks_iter;
+ }
+ if(parts_iter != parts_end)
+ {
+ LLFloaterChat::addChat(LLChat("Unexpected block(s) at end"));
+ return;
+ }
+ // Build and send
+ if(outgoing)
+ {
+ 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::iterator part_var_end = (*parts_iter).vars.end();
+ for(std::vector::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))
+ {
+ LLFloaterChat::addChat(LLChat(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;
+ }
+ }
+ }
+
+ LLScrollListCtrl* scrollp = floaterp->getChild("net_list");
+ LLScrollListItem* selected_itemp = scrollp->getFirstSelected();
+
+ //if a specific circuit is selected, send it to that, otherwise send it to the current sim
+ if(selected_itemp)
+ {
+ LLNetListItem* itemp = findNetListItem(selected_itemp->getUUID());
+ LLScrollListText* textColumn = (LLScrollListText*)selected_itemp->getColumn(1);
+
+ //why would you send data through a dead circuit?
+ if(textColumn->getValue().asString() == "Dead")
+ {
+ LLFloaterChat::addChat(LLChat("No sending messages through dead circuits!"));
+ return;
+ }
+
+ gMessageSystem->sendMessage(itemp->mCircuitData->getHost());
+ } else {
+ gMessageSystem->sendMessage(gAgent.getRegionHost());
+ }
+ }
+ else
+ {
+ LLFloaterChat::addChat(LLChat("Incoming message isn't supported yet :("));
+ return;
+ }
+}
+BOOL LLFloaterMessageBuilder::handleKeyHere(KEY key, MASK mask)
+{
+ if(key == KEY_RETURN && (mask & MASK_CONTROL))
+ {
+ onClickSend(this);
+ return TRUE;
+ }
+ if(key == KEY_ESCAPE)
+ {
+ releaseFocus();
+ return TRUE;
+ }
+ return FALSE;
+}
+//
diff --git a/indra/newview/llfloatermessagebuilder.h b/indra/newview/llfloatermessagebuilder.h
index 65b040420..5dc9b4297 100644
--- a/indra/newview/llfloatermessagebuilder.h
+++ b/indra/newview/llfloatermessagebuilder.h
@@ -1,32 +1,55 @@
-// ]
-#ifndef LL_LLFLOATERMESSAGEBUILDER_H
-#define LL_LLFLOATERMESSAGEBUILDER_H
-#include "llfloater.h"
-class LLFloaterMessageBuilder : public LLFloater
-{
-public:
- LLFloaterMessageBuilder(std::string initial_text);
- ~LLFloaterMessageBuilder();
- static void show(std::string initial_text);
- BOOL postBuild();
- static BOOL addField(e_message_variable_type var_type, const char* var_name, std::string input, BOOL hex);
- static void onClickSend(void* user_data);
- static void onCommitPacketCombo(LLUICtrl* ctrl, void* user_data);
- static LLFloaterMessageBuilder* sInstance;
- BOOL handleKeyHere(KEY key, MASK mask);
- std::string mInitialText;
- struct parts_var
- {
- std::string name;
- std::string value;
- BOOL hex;
- e_message_variable_type var_type;
- };
- struct parts_block
- {
- std::string name;
- std::vector vars;
- };
-};
-#endif
-//
+// ]
+#ifndef LL_LLFLOATERMESSAGEBUILDER_H
+#define LL_LLFLOATERMESSAGEBUILDER_H
+#include "llfloater.h"
+#include "lltemplatemessagereader.h"
+#include "llmessagelog.h"
+
+class LLNetListItem
+{
+public:
+ LLNetListItem(LLUUID id);
+ LLUUID mID;
+ BOOL mAutoName;
+ std::string mName;
+ std::string mPreviousRegionName;
+ LLCircuitData* mCircuitData;
+};
+
+class LLFloaterMessageBuilder : public LLFloater, public LLEventTimer
+{
+public:
+ LLFloaterMessageBuilder(std::string initial_text);
+ ~LLFloaterMessageBuilder();
+ static void show(std::string initial_text);
+ static std::list sNetListItems;
+ BOOL postBuild();
+ BOOL tick();
+ static BOOL addField(e_message_variable_type var_type, const char* var_name, std::string input, BOOL hex);
+ static void onClickSend(void* user_data);
+ static void onCommitPacketCombo(LLUICtrl* ctrl, void* user_data);
+ static LLFloaterMessageBuilder* sInstance;
+ BOOL handleKeyHere(KEY key, MASK mask);
+ std::string mInitialText;
+ struct parts_var
+ {
+ std::string name;
+ std::string value;
+ BOOL hex;
+ e_message_variable_type var_type;
+ };
+ struct parts_block
+ {
+ std::string name;
+ std::vector vars;
+ };
+ static LLNetListItem* findNetListItem(LLHost host);
+ static LLNetListItem* findNetListItem(LLUUID id);
+ void refreshNetList();
+ enum ENetInfoMode { NI_NET, NI_LOG };
+ ENetInfoMode mNetInfoMode;
+ static void onCommitMessageLog(LLUICtrl* ctrl, void* user_data);
+ static void onCommitFilter(LLUICtrl* ctrl, void* user_data);
+};
+#endif
+//
diff --git a/indra/newview/llfloatermessagelog.cpp b/indra/newview/llfloatermessagelog.cpp
index 38d6f031b..357495ca3 100644
--- a/indra/newview/llfloatermessagelog.cpp
+++ b/indra/newview/llfloatermessagelog.cpp
@@ -13,17 +13,6 @@
#include "llfloatermessagebuilder.h"
#include "llagent.h"
////////////////////////////////
-// LLNetListItem
-////////////////////////////////
-LLNetListItem::LLNetListItem(LLUUID id)
-: mID(id),
- mAutoName(TRUE),
- mName("No name"),
- mPreviousRegionName(""),
- mCircuitData(NULL)
-{
-}
-////////////////////////////////
// LLFloaterMessageLogItem
////////////////////////////////
#define MAX_PACKET_LEN (0x2000)
@@ -619,7 +608,7 @@ void LLFloaterMessageLog::refreshNetList()
LLSD& text_column = element["columns"][0];
text_column["column"] = "text";
text_column["value"] = itemp->mName + (itemp->mCircuitData->getHost() == gAgent.getRegionHost() ? " (main)" : "");
- for(int i = 0; i < 3; i++)
+ for(int i = 0; i < 2; i++)
{
LLSD& icon_column = element["columns"][i + 1];
icon_column["column"] = llformat("icon%d", i);
@@ -630,18 +619,18 @@ void LLFloaterMessageLog::refreshNetList()
BOOL has_live_circuit = itemp->mCircuitData && itemp->mCircuitData->isAlive();
if(has_live_circuit)
{
- LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(2);
+ LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(1);
icon->setValue("icon_net_close_circuit.tga");
icon->setClickCallback(onClickCloseCircuit, itemp);
}
else
{
- LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(2);
+ LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(1);
icon->setValue("icon_net_close_circuit_gray.tga");
icon->setClickCallback(NULL, NULL);
}
// Event queue isn't even supported yet... FIXME
- LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(3);
+ LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(2);
icon->setValue("icon_net_close_eventpoll_gray.tga");
icon->setClickCallback(NULL, NULL);
}
diff --git a/indra/newview/llfloatermessagelog.h b/indra/newview/llfloatermessagelog.h
index b87ffaa6f..82d82f772 100644
--- a/indra/newview/llfloatermessagelog.h
+++ b/indra/newview/llfloatermessagelog.h
@@ -2,16 +2,8 @@
#include "llfloater.h"
#include "llmessagelog.h"
#include "lltemplatemessagereader.h"
-class LLNetListItem
-{
-public:
- LLNetListItem(LLUUID id);
- LLUUID mID;
- BOOL mAutoName;
- std::string mName;
- std::string mPreviousRegionName;
- LLCircuitData* mCircuitData;
-};
+#include "llfloatermessagebuilder.h"
+
class LLFloaterMessageLogItem : public LLMessageLogEntry
{
public:
diff --git a/indra/newview/skins/default/xui/en-us/floater_message_builder.xml b/indra/newview/skins/default/xui/en-us/floater_message_builder.xml
index 41c58a542..c7c49d839 100755
--- a/indra/newview/skins/default/xui/en-us/floater_message_builder.xml
+++ b/indra/newview/skins/default/xui/en-us/floater_message_builder.xml
@@ -3,9 +3,7 @@
-
-
-
+
diff --git a/indra/newview/skins/default/xui/en-us/floater_message_log.xml b/indra/newview/skins/default/xui/en-us/floater_message_log.xml
index 40dc09f21..e1ebfe2f1 100755
--- a/indra/newview/skins/default/xui/en-us/floater_message_log.xml
+++ b/indra/newview/skins/default/xui/en-us/floater_message_log.xml
@@ -5,7 +5,6 @@
-