aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llfloatermessagebuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/llfloatermessagebuilder.cpp978
1 files changed, 978 insertions, 0 deletions
diff --git a/linden/indra/newview/llfloatermessagebuilder.cpp b/linden/indra/newview/llfloatermessagebuilder.cpp
new file mode 100644
index 0000000..90c0f9e
--- /dev/null
+++ b/linden/indra/newview/llfloatermessagebuilder.cpp
@@ -0,0 +1,978 @@
1// <edit>
2#include "llviewerprecompiledheaders.h"
3#include "llfloatermessagebuilder.h"
4#include "lluictrlfactory.h"
5#include "llmessagetemplate.h"
6#include "llagent.h"
7#include "llchat.h"
8#include "llfloaterchat.h"
9#include "llviewerregion.h" // getHandle
10#include "llcombobox.h"
11#include "llselectmgr.h" // fill in stuff about selected object
12#include "llparcel.h"
13#include "llviewerparcelmgr.h" // same for parcel
14#include "llscrolllistctrl.h"
15#include "llworld.h"
16#include "lltemplatemessagebuilder.h"
17
18////////////////////////////////
19// LLNetListItem
20////////////////////////////////
21LLNetListItem::LLNetListItem(LLUUID id)
22: mID(id),
23 mAutoName(TRUE),
24 mName("No name"),
25 mPreviousRegionName(""),
26 mCircuitData(NULL)
27{
28}
29
30////////////////////////////////
31// LLFloaterMessageBuilder
32////////////////////////////////
33std::list<LLNetListItem*> LLFloaterMessageBuilder::sNetListItems;
34
35LLFloaterMessageBuilder::LLFloaterMessageBuilder(std::string initial_text)
36: LLFloater(),
37 LLEventTimer(1.0f),
38 mNetInfoMode(NI_NET),
39 mInitialText(initial_text)
40{
41 LLUICtrlFactory::getInstance()->buildFloater(this, "floater_message_builder.xml");
42}
43LLFloaterMessageBuilder::~LLFloaterMessageBuilder()
44{
45}
46void LLFloaterMessageBuilder::show(std::string initial_text)
47{
48 (new LLFloaterMessageBuilder(initial_text))->open();
49}
50BOOL LLFloaterMessageBuilder::tick()
51{
52 refreshNetList();
53 return FALSE;
54}
55LLNetListItem* LLFloaterMessageBuilder::findNetListItem(LLHost host)
56{
57 std::list<LLNetListItem*>::iterator end = sNetListItems.end();
58 for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != end; ++iter)
59 if((*iter)->mCircuitData && (*iter)->mCircuitData->getHost() == host)
60 return (*iter);
61 return NULL;
62}
63LLNetListItem* LLFloaterMessageBuilder::findNetListItem(LLUUID id)
64{
65 std::list<LLNetListItem*>::iterator end = sNetListItems.end();
66 for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != end; ++iter)
67 if((*iter)->mID == id)
68 return (*iter);
69 return NULL;
70}
71void LLFloaterMessageBuilder::refreshNetList()
72{
73 LLScrollListCtrl* scrollp = getChild<LLScrollListCtrl>("net_list");
74 // Update circuit data of net list items
75 std::vector<LLCircuitData*> circuits = gMessageSystem->getCircuit()->getCircuitDataList();
76 std::vector<LLCircuitData*>::iterator circuits_end = circuits.end();
77 for(std::vector<LLCircuitData*>::iterator iter = circuits.begin(); iter != circuits_end; ++iter)
78 {
79 LLNetListItem* itemp = findNetListItem((*iter)->getHost());
80 if(!itemp)
81 {
82 LLUUID id; id.generate();
83 itemp = new LLNetListItem(id);
84 sNetListItems.push_back(itemp);
85 }
86 itemp->mCircuitData = (*iter);
87 }
88 // Clear circuit data of items whose circuits are gone
89 std::list<LLNetListItem*>::iterator items_end = sNetListItems.end();
90 for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != items_end; ++iter)
91 {
92 if(std::find(circuits.begin(), circuits.end(), (*iter)->mCircuitData) == circuits.end())
93 (*iter)->mCircuitData = NULL;
94 }
95 // Remove net list items that are totally useless now
96 for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != sNetListItems.end();)
97 {
98 if((*iter)->mCircuitData == NULL)
99 iter = sNetListItems.erase(iter);
100 else ++iter;
101 }
102 // Update names of net list items
103 items_end = sNetListItems.end();
104 for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != items_end; ++iter)
105 {
106 LLNetListItem* itemp = (*iter);
107 if(itemp->mAutoName)
108 {
109 if(itemp->mCircuitData)
110 {
111 LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(itemp->mCircuitData->getHost());
112 if(regionp)
113 {
114 std::string name = regionp->getName();
115 if(name == "") name = llformat("%s (awaiting region name)", itemp->mCircuitData->getHost().getString().c_str());
116 itemp->mName = name;
117 itemp->mPreviousRegionName = name;
118 }
119 else
120 {
121 itemp->mName = itemp->mCircuitData->getHost().getString();
122 if(itemp->mPreviousRegionName != "")
123 itemp->mName.append(llformat(" (was %s)", itemp->mPreviousRegionName.c_str()));
124 }
125 }
126 else
127 {
128 // an item just for an event queue, not handled yet
129 itemp->mName = "Something else";
130 }
131 }
132 }
133 // Rebuild scroll list from scratch
134 LLUUID selected_id = scrollp->getFirstSelected() ? scrollp->getFirstSelected()->getUUID() : LLUUID::null;
135 S32 scroll_pos = scrollp->getScrollPos();
136 scrollp->clearRows();
137 for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != items_end; ++iter)
138 {
139 LLNetListItem* itemp = (*iter);
140 LLSD element;
141 element["id"] = itemp->mID;
142 LLSD& text_column = element["columns"][0];
143 text_column["column"] = "text";
144 text_column["value"] = itemp->mName + (itemp->mCircuitData->getHost() == gAgent.getRegionHost() ? " (main)" : "");
145
146 LLSD& state_column = element["columns"][ 1];
147 state_column["column"] = "state";
148 state_column["value"] = "";
149
150 LLScrollListItem* scroll_itemp = scrollp->addElement(element);
151 BOOL has_live_circuit = itemp->mCircuitData && itemp->mCircuitData->isAlive();
152
153 LLScrollListText* state = (LLScrollListText*)scroll_itemp->getColumn(1);
154
155 if(has_live_circuit)
156 state->setText(std::string("Alive"));
157 else
158 state->setText(std::string("Alive"));
159 }
160 if(selected_id.notNull()) scrollp->selectByID(selected_id);
161 if(scroll_pos < scrollp->getItemCount()) scrollp->setScrollPos(scroll_pos);
162}
163BOOL LLFloaterMessageBuilder::postBuild()
164{
165 childSetText("message_edit", mInitialText);
166 childSetAction("send_btn", onClickSend, this);
167 std::vector<std::string> names;
168 LLComboBox* combo;
169 LLMessageSystem::message_template_name_map_t::iterator temp_end = gMessageSystem->mMessageTemplates.end();
170 LLMessageSystem::message_template_name_map_t::iterator temp_iter;
171 std::vector<std::string>::iterator names_end;
172 std::vector<std::string>::iterator names_iter;
173 for(temp_iter = gMessageSystem->mMessageTemplates.begin(); temp_iter != temp_end; ++temp_iter)
174 if((*temp_iter).second->getTrust() == MT_NOTRUST)
175 names.push_back((*temp_iter).second->mName);
176 std::sort(names.begin(), names.end());
177 combo = getChild<LLComboBox>("untrusted_message_combo");
178 names_end = names.end();
179 for(names_iter = names.begin(); names_iter != names_end; ++names_iter)
180 combo->add((*names_iter));
181 names.clear();
182 for(temp_iter = gMessageSystem->mMessageTemplates.begin(); temp_iter != temp_end; ++temp_iter)
183 if((*temp_iter).second->getTrust() == MT_TRUST)
184 names.push_back((*temp_iter).second->mName);
185 std::sort(names.begin(), names.end());
186 combo = getChild<LLComboBox>("trusted_message_combo");
187 names_end = names.end();
188 for(names_iter = names.begin(); names_iter != names_end; ++names_iter)
189 combo->add((*names_iter));
190 childSetCommitCallback("untrusted_message_combo", onCommitPacketCombo, this);
191 childSetCommitCallback("trusted_message_combo", onCommitPacketCombo, this);
192 return TRUE;
193}
194inline std::vector<std::string> split(std::string input, std::string separator)
195{
196 S32 size = input.length();
197 char* buffer = new char[size + 1];
198 strncpy(buffer, input.c_str(), size);
199 buffer[size] = '\0';
200 std::vector<std::string> lines;
201 char* result = strtok(buffer, separator.c_str());
202 while(result)
203 {
204 lines.push_back(result);
205 result = strtok(NULL, separator.c_str());
206 }
207 delete[] buffer;
208 return lines;
209}
210std::string mvtstr(e_message_variable_type var_type)
211{
212 switch(var_type)
213 {
214 case MVT_U8:
215 return "U8";
216 break;
217 case MVT_U16:
218 return "U16";
219 break;
220 case MVT_U32:
221 return "U32";
222 break;
223 case MVT_U64:
224 return "U64";
225 break;
226 case MVT_S8:
227 return "S8";
228 break;
229 case MVT_S16:
230 return "S16";
231 break;
232 case MVT_S32:
233 return "S32";
234 break;
235 case MVT_S64:
236 return "S64";
237 break;
238 case MVT_F32:
239 return "F32";
240 break;
241 case MVT_F64:
242 return "F64";
243 break;
244 case MVT_LLVector3:
245 return "LLVector3";
246 break;
247 case MVT_LLVector3d:
248 return "LLVector3d";
249 break;
250 case MVT_LLVector4:
251 return "LLVector4";
252 break;
253 case MVT_LLQuaternion:
254 return "LLQuaternion";
255 break;
256 case MVT_LLUUID:
257 return "LLUUID";
258 break;
259 case MVT_BOOL:
260 return "BOOL";
261 break;
262 case MVT_IP_ADDR:
263 return "IPADDR";
264 break;
265 case MVT_IP_PORT:
266 return "IPPORT";
267 break;
268 case MVT_VARIABLE:
269 return "Variable";
270 break;
271 case MVT_FIXED:
272 return "Fixed";
273 break;
274 default:
275 return "Missingno.";
276 break;
277 }
278}
279// static
280BOOL LLFloaterMessageBuilder::addField(e_message_variable_type var_type, const char* var_name, std::string input, BOOL hex)
281{
282 LLStringUtil::trim(input);
283 if(input.length() < 1 && var_type != MVT_VARIABLE)
284 return FALSE;
285 U8 valueU8;
286 U16 valueU16;
287 U32 valueU32;
288 U64 valueU64;
289 S8 valueS8;
290 S16 valueS16;
291 S32 valueS32;
292 // S64 valueS64;
293 F32 valueF32;
294 F64 valueF64;
295 LLVector3 valueVector3;
296 LLVector3d valueVector3d;
297 LLVector4 valueVector4;
298 LLQuaternion valueQuaternion;
299 LLUUID valueLLUUID;
300 BOOL valueBOOL;
301 std::string input_lower = input;
302 LLStringUtil::toLower(input_lower);
303 if(input_lower == "$agentid")
304 input = gAgent.getID().asString();
305 else if(input_lower == "$sessionid")
306 input = gAgent.getSessionID().asString();
307 else if(input_lower == "$uuid")
308 {
309 LLUUID id;
310 id.generate();
311 input = id.asString();
312 }
313 else if(input_lower == "$circuitcode")
314 {
315 std::stringstream temp_stream;
316 temp_stream << gMessageSystem->mOurCircuitCode;
317 input = temp_stream.str();
318 }
319 else if(input_lower == "$regionhandle")
320 {
321 std::stringstream temp_stream;
322 temp_stream << (gAgent.getRegion() ? gAgent.getRegion()->getHandle() : 0);
323 input = temp_stream.str();
324 }
325 else if(input_lower == "$position" || input_lower == "$pos")
326 {
327 std::stringstream temp_stream;
328 valueVector3 = gAgent.getPositionAgent();
329 temp_stream << "<" << valueVector3[0] << ", " << valueVector3[1] << ", " << valueVector3[2] << ">";
330 input = temp_stream.str();
331 }
332 if(hex)
333 {
334 if(var_type != MVT_VARIABLE && var_type != MVT_FIXED)
335 return FALSE;
336 int len = input_lower.length();
337 const char* cstr = input_lower.c_str();
338 std::string new_input("");
339 BOOL nibble = FALSE;
340 char byte = 0;
341 for(int i = 0; i < len; i++)
342 {
343 char c = cstr[i];
344 if(c >= 0x30 && c <= 0x39)
345 c -= 0x30;
346 else if(c >= 0x61 && c <= 0x66)
347 c -= 0x57;
348 else if(c != 0x20)
349 return FALSE;
350 else
351 continue;
352 if(!nibble)
353 byte = c << 4;
354 else
355 new_input.push_back(byte | c);
356 nibble = !nibble;
357 }
358 if(nibble)
359 return FALSE;
360 input = new_input;
361 }
362 std::stringstream stream(input);
363 std::vector<std::string> tokens;
364 switch(var_type)
365 {
366 case MVT_U8:
367 if(input.substr(0, 1) == "-")
368 return FALSE;
369 if((stream >> valueU32).fail())
370 return FALSE;
371 valueU8 = (U8)valueU32;
372 gMessageSystem->addU8(var_name, valueU8);
373 return TRUE;
374 break;
375 case MVT_U16:
376 if(input.substr(0, 1) == "-")
377 return FALSE;
378 if((stream >> valueU16).fail())
379 return FALSE;
380 gMessageSystem->addU16(var_name, valueU16);
381 return TRUE;
382 break;
383 case MVT_U32:
384 if(input.substr(0, 1) == "-")
385 return FALSE;
386 if((stream >> valueU32).fail())
387 return FALSE;
388 gMessageSystem->addU32(var_name, valueU32);
389 return TRUE;
390 break;
391 case MVT_U64:
392 if(input.substr(0, 1) == "-")
393 return FALSE;
394 if((stream >> valueU64).fail())
395 return FALSE;
396 gMessageSystem->addU64(var_name, valueU64);
397 return TRUE;
398 break;
399 case MVT_S8:
400 if((stream >> valueS8).fail())
401 return FALSE;
402 gMessageSystem->addS8(var_name, valueS8);
403 return TRUE;
404 break;
405 case MVT_S16:
406 if((stream >> valueS16).fail())
407 return FALSE;
408 gMessageSystem->addS16(var_name, valueS16);
409 return TRUE;
410 break;
411 case MVT_S32:
412 if((stream >> valueS32).fail())
413 return FALSE;
414 gMessageSystem->addS32(var_name, valueS32);
415 return TRUE;
416 break;
417 /*
418 case MVT_S64:
419 if((stream >> valueS64).fail())
420 return FALSE;
421 gMessageSystem->addS64(var_name, valueS64);
422 return TRUE;
423 break;
424 */
425 case MVT_F32:
426 if((stream >> valueF32).fail())
427 return FALSE;
428 gMessageSystem->addF32(var_name, valueF32);
429 return TRUE;
430 break;
431 case MVT_F64:
432 if((stream >> valueF64).fail())
433 return FALSE;
434 gMessageSystem->addF64(var_name, valueF64);
435 return TRUE;
436 break;
437 case MVT_LLVector3:
438 LLStringUtil::trim(input);
439 if(input.substr(0, 1) != "<" || input.substr(input.length() - 1, 1) != ">")
440 return FALSE;
441 tokens = split(input.substr(1, input.length() - 2), ",");
442 if(tokens.size() != 3)
443 return FALSE;
444 for(int i = 0; i < 3; i++)
445 {
446 stream.clear();
447 stream.str(tokens[i]);
448 if((stream >> valueF32).fail())
449 return FALSE;
450 valueVector3.mV[i] = valueF32;
451 }
452 gMessageSystem->addVector3(var_name, valueVector3);
453 return TRUE;
454 break;
455 case MVT_LLVector3d:
456 LLStringUtil::trim(input);
457 if(input.substr(0, 1) != "<" || input.substr(input.length() - 1, 1) != ">")
458 return FALSE;
459 tokens = split(input.substr(1, input.length() - 2), ",");
460 if(tokens.size() != 3)
461 return FALSE;
462 for(int i = 0; i < 3; i++)
463 {
464 stream.clear();
465 stream.str(tokens[i]);
466 if((stream >> valueF64).fail())
467 return FALSE;
468 valueVector3d.mdV[i] = valueF64;
469 }
470 gMessageSystem->addVector3d(var_name, valueVector3d);
471 return TRUE;
472 break;
473 case MVT_LLVector4:
474 LLStringUtil::trim(input);
475 if(input.substr(0, 1) != "<" || input.substr(input.length() - 1, 1) != ">")
476 return FALSE;
477 tokens = split(input.substr(1, input.length() - 2), ",");
478 if(tokens.size() != 4)
479 return FALSE;
480 for(int i = 0; i < 4; i++)
481 {
482 stream.clear();
483 stream.str(tokens[i]);
484 if((stream >> valueF32).fail())
485 return FALSE;
486 valueVector4.mV[i] = valueF32;
487 }
488 gMessageSystem->addVector4(var_name, valueVector4);
489 return TRUE;
490 break;
491 case MVT_LLQuaternion:
492 LLStringUtil::trim(input);
493 if(input.substr(0, 1) != "<" || input.substr(input.length() - 1, 1) != ">")
494 return FALSE;
495 tokens = split(input.substr(1, input.length() - 2), ",");
496 if(tokens.size() != 3)
497 return FALSE;
498 for(int i = 0; i < 3; i++)
499 {
500 stream.clear();
501 stream.str(tokens[i]);
502 if((stream >> valueF32).fail())
503 return FALSE;
504 valueVector3.mV[i] = valueF32;
505 }
506 valueQuaternion.unpackFromVector3(valueVector3);
507 gMessageSystem->addQuat(var_name, valueQuaternion);
508 return TRUE;
509 break;
510 case MVT_LLUUID:
511 if((stream >> valueLLUUID).fail())
512 return FALSE;
513 gMessageSystem->addUUID(var_name, valueLLUUID);
514 return TRUE;
515 break;
516 case MVT_BOOL:
517 if(input_lower == "true")
518 valueBOOL = TRUE;
519 else if(input_lower == "false")
520 valueBOOL = FALSE;
521 else if((stream >> valueBOOL).fail())
522 return FALSE;
523 //gMessageSystem->addBOOL(var_name, valueBOOL);
524 gMessageSystem->addU8(var_name, (U8)valueBOOL);
525 return TRUE;
526 break;
527 case MVT_IP_ADDR:
528 if((stream >> valueU32).fail())
529 return FALSE;
530 gMessageSystem->addIPAddr(var_name, valueU32);
531 return TRUE;
532 break;
533 case MVT_IP_PORT:
534 if((stream >> valueU16).fail())
535 return FALSE;
536 gMessageSystem->addIPPort(var_name, valueU16);
537 return TRUE;
538 break;
539 case MVT_VARIABLE:
540 if(!hex)
541 {
542 char* buffer = new char[input.size() + 1];
543 strncpy(buffer, input.c_str(), input.size());
544 buffer[input.size()] = '\0';
545 gMessageSystem->addBinaryData(var_name, buffer, input.size() + 1);
546 delete[] buffer;
547 }
548 else
549 gMessageSystem->addBinaryData(var_name, input.c_str(), input.size());
550 return TRUE;
551 break;
552 case MVT_FIXED:
553 if(!hex)
554 {
555 char* buffer = new char[input.size() + 1];
556 strncpy(buffer, input.c_str(), input.size());
557 buffer[input.size()] = '\0';
558 gMessageSystem->addBinaryData(var_name, buffer, input.size());
559 delete[] buffer;
560 }
561 else
562 gMessageSystem->addBinaryData(var_name, input.c_str(), input.size());
563 return TRUE;
564 break;
565 default:
566 break;
567 }
568 return FALSE;
569}
570// static
571void LLFloaterMessageBuilder::onCommitPacketCombo(LLUICtrl* ctrl, void* user_data)
572{
573 LLFloaterMessageBuilder* floaterp = (LLFloaterMessageBuilder*)user_data;
574 LLViewerObject* selected_objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
575 LLParcel* agent_parcelp = LLViewerParcelMgr::getInstance()->getAgentParcel();
576 std::string message = ctrl->getValue();
577 std::map<const char *, LLMessageTemplate*>::iterator template_iter;
578 template_iter = gMessageSystem->mMessageTemplates.find( LLMessageStringTable::getInstance()->getString(message.c_str()) );
579 if(template_iter == gMessageSystem->mMessageTemplates.end())
580 {
581 floaterp->childSetText("message_edit", std::string(""));
582 return;
583 }
584 std::string text(llformat((*template_iter).second->getTrust() == MT_NOTRUST ? "out %s\n" : "in %s\n", message.c_str()));
585 LLMessageTemplate* temp = (*template_iter).second;
586 LLMessageTemplate::message_block_map_t::iterator blocks_end = temp->mMemberBlocks.end();
587 for (LLMessageTemplate::message_block_map_t::iterator blocks_iter = temp->mMemberBlocks.begin();
588 blocks_iter != blocks_end; ++blocks_iter)
589 {
590 LLMessageBlock* block = (*blocks_iter);
591 const char* block_name = block->mName;
592 std::string block_name_string = std::string(block_name);
593 S32 num_blocks = 1;
594 if(block->mType == MBT_MULTIPLE)
595 num_blocks = block->mNumber;
596 else if(("ObjectLink" == message && "ObjectData" == block_name_string))
597 num_blocks = 2;
598 for(S32 i = 0; i < num_blocks; i++)
599 {
600 text.append(llformat("[%s]\n", block_name));
601 LLMessageBlock::message_variable_map_t::iterator var_end = block->mMemberVariables.end();
602 for (LLMessageBlock::message_variable_map_t::iterator var_iter = block->mMemberVariables.begin();
603 var_iter != var_end; ++var_iter)
604 {
605 LLMessageVariable* variable = (*var_iter);
606 const char* var_name = variable->getName();
607 std::string var_name_string = std::string(var_name);
608 text.append(llformat("%s = ", var_name));
609 std::string value("");
610 S32 size = variable->getSize();
611 switch(variable->getType())
612 {
613 case MVT_U8:
614 case MVT_U16:
615 case MVT_U32:
616 case MVT_U64:
617 case MVT_S8:
618 case MVT_S16:
619 case MVT_S32:
620 case MVT_IP_ADDR:
621 case MVT_IP_PORT:
622 if("RegionHandle" == var_name_string || "Handle" == var_name_string)
623 value = "$RegionHandle";
624 else if("CircuitCode" == var_name_string || "ViewerCircuitCode" == var_name_string
625 || ("Code" == var_name_string && "CircuitCode" == block_name_string) )
626 {
627 value = "$CircuitCode";
628 }
629 else if(selected_objectp &&
630 (
631 "ObjectLocalID" == var_name_string
632 || "TaskLocalID" == var_name_string
633 || ("LocalID" == var_name_string &&
634 (
635 "ObjectData" == block_name_string
636 || "UpdateData" == block_name_string
637 || "InventoryData" == block_name_string
638 )
639 )
640 )
641 )
642 {
643 std::stringstream temp_stream;
644 temp_stream << selected_objectp->getLocalID();
645 value = temp_stream.str();
646 }
647 else if( agent_parcelp &&
648 "LocalID" == var_name_string &&
649 (
650 "ParcelData" == block_name_string
651 || message.find("Parcel") != message.npos
652 )
653 )
654 {
655 std::stringstream temp_stream;
656 temp_stream << agent_parcelp->getLocalID();
657 value = temp_stream.str();
658 }
659 else if("PCode" == var_name_string)
660 value = "9";
661 else if("PathCurve" == var_name_string)
662 value = "16";
663 else if("ProfileCurve" == var_name_string)
664 value = "1";
665 else if("PathScaleX" == var_name_string || "PathScaleY" == var_name_string)
666 value = "100";
667 else if("BypassRaycast" == var_name_string)
668 value = "1";
669 else
670 value = "0";
671 break;
672 case MVT_F32:
673 case MVT_F64:
674 value = "0.0";
675 break;
676 case MVT_LLVector3:
677 case MVT_LLVector3d:
678 case MVT_LLQuaternion:
679 if("Position" == var_name_string || "RayStart" == var_name_string || "RayEnd" == var_name_string)
680 value = "$Position";
681 else if("Scale" == var_name_string)
682 value = "<0.5, 0.5, 0.5>";
683 else
684 value = "<0, 0, 0>";
685 break;
686 case MVT_LLVector4:
687 value = "<0, 0, 0, 0>";
688 break;
689 case MVT_LLUUID:
690 if("AgentID" == var_name_string)
691 value = "$AgentID";
692 else if("SessionID" == var_name_string)
693 value = "$SessionID";
694 else if("ObjectID" == var_name_string && selected_objectp)
695 value = selected_objectp->getID().asString();
696 else if("ParcelID" == var_name_string && agent_parcelp)
697 value = agent_parcelp->getID().asString();
698 else
699 value = "00000000-0000-0000-0000-000000000000";
700 break;
701 case MVT_BOOL:
702 value = "false";
703 break;
704 case MVT_VARIABLE:
705 value = "Hello, world!";
706 break;
707 case MVT_FIXED:
708 for(S32 si = 0; si < size; si++)
709 //value.append(std::string("0123456789abcdef").substr(si & 0xf, 1));
710 value.append("a");
711 break;
712 default:
713 value = "";
714 break;
715 }
716 text.append(llformat("%s\n", value.c_str()));
717 }
718 }
719 }
720 text = text.substr(0, text.length() - 1);
721 floaterp->childSetText("message_edit", text);
722}
723// static
724void LLFloaterMessageBuilder::onClickSend(void* user_data)
725{
726 LLFloaterMessageBuilder* floaterp = (LLFloaterMessageBuilder*)user_data;
727 std::vector<std::string> lines = split(floaterp->childGetText("message_edit"), "\n");
728 if(!lines.size())
729 {
730 LLFloaterChat::addChat(LLChat("Not enough information :O"));
731 return;
732 }
733 std::vector<std::string> tokens = split(lines[0], " ");
734 if(!tokens.size())
735 {
736 LLFloaterChat::addChat(LLChat("Not enough information :O"));
737 return;
738 }
739 std::string dir_str = tokens[0];
740 LLStringUtil::toLower(dir_str);
741 // Direction
742 BOOL outgoing;
743 if(dir_str == "out")
744 outgoing = TRUE;
745 else if(dir_str == "in")
746 outgoing = FALSE;
747 else
748 {
749 LLFloaterChat::addChat(LLChat("Expected direction 'in' or 'out'"));
750 return;
751 }
752 // Message
753 std::string message = "Invalid";
754 if(tokens.size() > 1)
755 {
756 if(tokens.size() > 2)
757 {
758 LLFloaterChat::addChat(LLChat("Unexpected extra stuff at the top"));
759 return;
760 }
761 message = tokens[1];
762 LLStringUtil::trim(message);
763 }
764 // Body
765 std::vector<parts_block> parts;
766 if(lines.size() > 1)
767 {
768 std::vector<std::string>::iterator line_end = lines.end();
769 std::vector<std::string>::iterator line_iter = lines.begin();
770 ++line_iter;
771 std::string current_block("");
772 int current_block_index = -1;
773 for( ; line_iter != line_end; ++line_iter)
774 {
775 std::string line = (*line_iter);
776 LLStringUtil::trim(line);
777 if(!line.length())
778 continue;
779 if(line.substr(0, 1) == "[" && line.substr(line.size() - 1, 1) == "]")
780 {
781 current_block = line.substr(1, line.length() - 2);
782 LLStringUtil::trim(current_block);
783 ++current_block_index;
784 parts_block pb;
785 pb.name = current_block;
786 parts.push_back(pb);
787 }
788 else
789 {
790 if(current_block.empty())
791 {
792 LLFloaterChat::addChat(LLChat("Unexpected field when no block yet"));
793 return;
794 }
795 int eqpos = line.find("=");
796 if(eqpos == line.npos)
797 {
798 LLFloaterChat::addChat(LLChat("Missing an equal sign"));
799 return;
800 }
801 std::string field = line.substr(0, eqpos);
802 LLStringUtil::trim(field);
803 if(!field.length())
804 {
805 LLFloaterChat::addChat(LLChat("Missing name of field"));
806 return;
807 }
808 std::string value = line.substr(eqpos + 1);
809 LLStringUtil::trim(value);
810 parts_var pv;
811 if(value.substr(0, 1) == "|")
812 {
813 pv.hex = TRUE;
814 value = value.substr(1);
815 LLStringUtil::trim(value);
816 }
817 else
818 pv.hex = FALSE;
819 pv.name = field;
820 pv.value = value;
821 parts[current_block_index].vars.push_back(pv);
822 }
823 }
824 }
825 // Verification
826 std::map<const char *, LLMessageTemplate*>::iterator template_iter;
827 template_iter = gMessageSystem->mMessageTemplates.find( LLMessageStringTable::getInstance()->getString(message.c_str()) );
828 if(template_iter == gMessageSystem->mMessageTemplates.end())
829 {
830 LLFloaterChat::addChat(LLChat(llformat("Don't know how to build a '%s' message", message.c_str())));
831 return;
832 }
833 LLMessageTemplate* temp = (*template_iter).second;
834 std::vector<parts_block>::iterator parts_end = parts.end();
835 std::vector<parts_block>::iterator parts_iter = parts.begin();
836 LLMessageTemplate::message_block_map_t::iterator blocks_end = temp->mMemberBlocks.end();
837 for (LLMessageTemplate::message_block_map_t::iterator blocks_iter = temp->mMemberBlocks.begin();
838 blocks_iter != blocks_end; )
839 {
840 LLMessageBlock* block = (*blocks_iter);
841 const char* block_name = block->mName;
842 if(parts_iter == parts_end)
843 {
844 if(block->mType != MBT_VARIABLE)
845 LLFloaterChat::addChat(LLChat(llformat("Expected '%s' block", block_name)));
846 else
847 {
848 ++blocks_iter;
849 continue;
850 }
851 return;
852 }
853 else if((*parts_iter).name != block_name)
854 {
855 if(block->mType != MBT_VARIABLE)
856 LLFloaterChat::addChat(LLChat(llformat("Expected '%s' block", block_name)));
857 else
858 {
859 ++blocks_iter;
860 continue;
861 }
862 return;
863 }
864 std::vector<parts_var>::iterator part_var_end = (*parts_iter).vars.end();
865 std::vector<parts_var>::iterator part_var_iter = (*parts_iter).vars.begin();
866 LLMessageBlock::message_variable_map_t::iterator var_end = block->mMemberVariables.end();
867 for (LLMessageBlock::message_variable_map_t::iterator var_iter = block->mMemberVariables.begin();
868 var_iter != var_end; ++var_iter)
869 {
870 LLMessageVariable* variable = (*var_iter);
871 const char* var_name = variable->getName();
872 if(part_var_iter == part_var_end)
873 {
874 LLFloaterChat::addChat(LLChat(llformat("Expected '%s' field under '%s' block", var_name, block_name)));
875 return;
876 }
877 else if((*part_var_iter).name != var_name)
878 {
879 LLFloaterChat::addChat(LLChat(llformat("Expected '%s' field under '%s' block", var_name, block_name)));
880 return;
881 }
882 (*part_var_iter).var_type = variable->getType();
883 ++part_var_iter;
884 }
885 if(part_var_iter != part_var_end)
886 {
887 LLFloaterChat::addChat(LLChat(llformat("Unexpected field(s) at end of '%s' block", block_name)));
888 return;
889 }
890 ++parts_iter;
891 // test
892 if((block->mType != MBT_SINGLE) && (parts_iter != parts_end) && ((*parts_iter).name == block_name))
893 {
894 // block will repeat
895 }
896 else ++blocks_iter;
897 }
898 if(parts_iter != parts_end)
899 {
900 LLFloaterChat::addChat(LLChat("Unexpected block(s) at end"));
901 return;
902 }
903 // Build and send
904 gMessageSystem->newMessage( message.c_str() );
905 for(parts_iter = parts.begin(); parts_iter != parts_end; ++parts_iter)
906 {
907 const char* block_name = (*parts_iter).name.c_str();
908 gMessageSystem->nextBlock(block_name);
909 std::vector<parts_var>::iterator part_var_end = (*parts_iter).vars.end();
910 for(std::vector<parts_var>::iterator part_var_iter = (*parts_iter).vars.begin();
911 part_var_iter != part_var_end; ++part_var_iter)
912 {
913 parts_var pv = (*part_var_iter);
914 if(!addField(pv.var_type, pv.name.c_str(), pv.value, pv.hex))
915 {
916 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)));
917 gMessageSystem->clearMessage();
918 return;
919 }
920 }
921 }
922
923 LLScrollListCtrl* scrollp = floaterp->getChild<LLScrollListCtrl>("net_list");
924 LLScrollListItem* selected_itemp = scrollp->getFirstSelected();
925
926 //if a specific circuit is selected, send it to that, otherwise send it to the current sim
927 if(selected_itemp)
928 {
929 LLNetListItem* itemp = findNetListItem(selected_itemp->getUUID());
930 LLScrollListText* textColumn = (LLScrollListText*)selected_itemp->getColumn(1);
931
932 //why would you send data through a dead circuit?
933 if(textColumn->getValue().asString() == "Dead")
934 {
935 LLFloaterChat::addChat(LLChat("No sending messages through dead circuits!"));
936 return;
937 }
938 if(outgoing)
939 {
940 gMessageSystem->sendMessage(itemp->mCircuitData->getHost());
941 } else {
942 U8 builtMessageBuffer[MAX_BUFFER_SIZE];
943
944 S32 message_size = gMessageSystem->mTemplateMessageBuilder->buildMessage(builtMessageBuffer, MAX_BUFFER_SIZE, 0);
945 gMessageSystem->clearMessage();
946 gMessageSystem->checkMessages(0, true, builtMessageBuffer, itemp->mCircuitData->getHost(), message_size);
947
948 }
949 } else {
950 if(outgoing)
951 {
952 gMessageSystem->sendMessage(gAgent.getRegionHost());
953 } else {
954 U8 builtMessageBuffer[MAX_BUFFER_SIZE];
955
956 S32 message_size = gMessageSystem->mTemplateMessageBuilder->buildMessage(builtMessageBuffer, MAX_BUFFER_SIZE, 0);
957 gMessageSystem->clearMessage();
958 gMessageSystem->checkMessages(0, true, builtMessageBuffer, gAgent.getRegionHost(), message_size);
959
960 }
961 }
962}
963
964BOOL LLFloaterMessageBuilder::handleKeyHere(KEY key, MASK mask)
965{
966 if(key == KEY_RETURN && (mask & MASK_CONTROL))
967 {
968 onClickSend(this);
969 return TRUE;
970 }
971 if(key == KEY_ESCAPE)
972 {
973 releaseFocus();
974 return TRUE;
975 }
976 return FALSE;
977}
978// </edit>