diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llmessage/llcircuit.cpp | 11 | ||||
-rw-r--r-- | linden/indra/llmessage/llcircuit.h | 3 | ||||
-rw-r--r-- | linden/indra/llmessage/llmessagelog.cpp | 54 | ||||
-rw-r--r-- | linden/indra/llmessage/llmessagelog.h | 41 | ||||
-rw-r--r-- | linden/indra/llmessage/llpacketring.cpp | 5 | ||||
-rw-r--r-- | linden/indra/llmessage/lltemplatemessagereader.cpp | 50 | ||||
-rw-r--r-- | linden/indra/llmessage/lltemplatemessagereader.h | 16 | ||||
-rw-r--r-- | linden/indra/llmessage/message.cpp | 18 | ||||
-rw-r--r-- | linden/indra/llmessage/message.h | 18 | ||||
-rw-r--r-- | linden/indra/llui/llscrolllistctrl.cpp | 17 | ||||
-rw-r--r-- | linden/indra/llui/llscrolllistctrl.h | 11 | ||||
-rw-r--r-- | linden/indra/newview/llfloatermessagebuilder.cpp | 978 | ||||
-rw-r--r-- | linden/indra/newview/llfloatermessagebuilder.h | 55 | ||||
-rw-r--r-- | linden/indra/newview/llfloatermessagelog.cpp | 962 | ||||
-rw-r--r-- | linden/indra/newview/llfloatermessagelog.h | 84 | ||||
-rw-r--r-- | linden/indra/newview/llviewermenu.cpp | 45 | ||||
-rw-r--r-- | linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml | 9 |
17 files changed, 2358 insertions, 19 deletions
diff --git a/linden/indra/llmessage/llcircuit.cpp b/linden/indra/llmessage/llcircuit.cpp index 725425c..0ff5093 100644 --- a/linden/indra/llmessage/llcircuit.cpp +++ b/linden/indra/llmessage/llcircuit.cpp | |||
@@ -1231,6 +1231,17 @@ void LLCircuit::getCircuitRange( | |||
1231 | first = mCircuitData.upper_bound(key); | 1231 | first = mCircuitData.upper_bound(key); |
1232 | } | 1232 | } |
1233 | 1233 | ||
1234 | // <edit> | ||
1235 | std::vector<LLCircuitData*> LLCircuit::getCircuitDataList() | ||
1236 | { | ||
1237 | std::vector<LLCircuitData*> list; | ||
1238 | circuit_data_map::iterator end = mCircuitData.end(); | ||
1239 | for(circuit_data_map::iterator iter = mCircuitData.begin(); iter != end; ++iter) | ||
1240 | list.push_back((*iter).second); | ||
1241 | return list; | ||
1242 | } | ||
1243 | // </edit> | ||
1244 | |||
1234 | TPACKETID LLCircuitData::nextPacketOutID() | 1245 | TPACKETID LLCircuitData::nextPacketOutID() |
1235 | { | 1246 | { |
1236 | mPacketsOut++; | 1247 | mPacketsOut++; |
diff --git a/linden/indra/llmessage/llcircuit.h b/linden/indra/llmessage/llcircuit.h index e373cb1..379453e 100644 --- a/linden/indra/llmessage/llcircuit.h +++ b/linden/indra/llmessage/llcircuit.h | |||
@@ -336,6 +336,9 @@ public: | |||
336 | // HACK - this should become protected eventually, but stupid !@$@# message system/circuit classes are jumbling things up. | 336 | // HACK - this should become protected eventually, but stupid !@$@# message system/circuit classes are jumbling things up. |
337 | circuit_data_map mUnackedCircuitMap; // Map of circuits with unacked data | 337 | circuit_data_map mUnackedCircuitMap; // Map of circuits with unacked data |
338 | circuit_data_map mSendAckMap; // Map of circuits which need to send acks | 338 | circuit_data_map mSendAckMap; // Map of circuits which need to send acks |
339 | |||
340 | std::vector<LLCircuitData*> getCircuitDataList(); | ||
341 | |||
339 | protected: | 342 | protected: |
340 | circuit_data_map mCircuitData; | 343 | circuit_data_map mCircuitData; |
341 | 344 | ||
diff --git a/linden/indra/llmessage/llmessagelog.cpp b/linden/indra/llmessage/llmessagelog.cpp new file mode 100644 index 0000000..965b8c0 --- /dev/null +++ b/linden/indra/llmessage/llmessagelog.cpp | |||
@@ -0,0 +1,54 @@ | |||
1 | // <edit> | ||
2 | #include "llmessagelog.h" | ||
3 | |||
4 | LLMessageLogEntry::LLMessageLogEntry(EType type, LLHost from_host, LLHost to_host, U8* data, S32 data_size) | ||
5 | : mType(type), | ||
6 | mFromHost(from_host), | ||
7 | mToHost(to_host), | ||
8 | mDataSize(data_size) | ||
9 | { | ||
10 | if(data) | ||
11 | { | ||
12 | mData.resize(data_size); | ||
13 | memcpy(&(mData[0]), data, data_size); | ||
14 | } | ||
15 | } | ||
16 | LLMessageLogEntry::LLMessageLogEntry(EType type, LLHost from_host, LLHost to_host, std::vector<U8> data, S32 data_size) | ||
17 | : mType(type), | ||
18 | mFromHost(from_host), | ||
19 | mToHost(to_host), | ||
20 | mDataSize(data_size), | ||
21 | mData(data) | ||
22 | { | ||
23 | } | ||
24 | LLMessageLogEntry::~LLMessageLogEntry() | ||
25 | { | ||
26 | } | ||
27 | U32 LLMessageLog::sMaxSize = 4096; // testzone fixme todo boom | ||
28 | std::deque<LLMessageLogEntry> LLMessageLog::sDeque; | ||
29 | void (*(LLMessageLog::sCallback))(LLMessageLogEntry); | ||
30 | void LLMessageLog::setMaxSize(U32 size) | ||
31 | { | ||
32 | sMaxSize = size; | ||
33 | while(sDeque.size() > sMaxSize) | ||
34 | sDeque.pop_front(); | ||
35 | } | ||
36 | void LLMessageLog::setCallback(void (*callback)(LLMessageLogEntry)) | ||
37 | { | ||
38 | sCallback = callback; | ||
39 | } | ||
40 | void LLMessageLog::log(LLHost from_host, LLHost to_host, U8* data, S32 data_size) | ||
41 | { | ||
42 | LLMessageLogEntry entry = LLMessageLogEntry(LLMessageLogEntry::TEMPLATE, from_host, to_host, data, data_size); | ||
43 | if(!entry.mDataSize || !entry.mData.size()) return; | ||
44 | if(sCallback) sCallback(entry); | ||
45 | if(!sMaxSize) return; | ||
46 | sDeque.push_back(entry); | ||
47 | if(sDeque.size() > sMaxSize) | ||
48 | sDeque.pop_front(); | ||
49 | } | ||
50 | std::deque<LLMessageLogEntry> LLMessageLog::getDeque() | ||
51 | { | ||
52 | return sDeque; | ||
53 | } | ||
54 | // </edit> | ||
diff --git a/linden/indra/llmessage/llmessagelog.h b/linden/indra/llmessage/llmessagelog.h new file mode 100644 index 0000000..5046d80 --- /dev/null +++ b/linden/indra/llmessage/llmessagelog.h | |||
@@ -0,0 +1,41 @@ | |||
1 | // <edit> | ||
2 | #ifndef LL_LLMESSAGELOG_H | ||
3 | #define LL_LLMESSAGELOG_H | ||
4 | #include "stdtypes.h" | ||
5 | #include "llhost.h" | ||
6 | #include <queue> | ||
7 | #include <string.h> | ||
8 | |||
9 | class LLMessageSystem; | ||
10 | class LLMessageLogEntry | ||
11 | { | ||
12 | public: | ||
13 | enum EType | ||
14 | { | ||
15 | TEMPLATE, | ||
16 | HTTP_REQUEST, | ||
17 | HTTP_RESPONSE | ||
18 | }; | ||
19 | LLMessageLogEntry(EType type, LLHost from_host, LLHost to_host, U8* data, S32 data_size); | ||
20 | LLMessageLogEntry(EType type, LLHost from_host, LLHost to_host, std::vector<U8> data, S32 data_size); | ||
21 | ~LLMessageLogEntry(); | ||
22 | EType mType; | ||
23 | LLHost mFromHost; | ||
24 | LLHost mToHost; | ||
25 | S32 mDataSize; | ||
26 | std::vector<U8> mData; | ||
27 | }; | ||
28 | class LLMessageLog | ||
29 | { | ||
30 | public: | ||
31 | static void setMaxSize(U32 size); | ||
32 | static void setCallback(void (*callback)(LLMessageLogEntry)); | ||
33 | static void log(LLHost from_host, LLHost to_host, U8* data, S32 data_size); | ||
34 | static std::deque<LLMessageLogEntry> getDeque(); | ||
35 | private: | ||
36 | static U32 sMaxSize; | ||
37 | static void (*sCallback)(LLMessageLogEntry); | ||
38 | static std::deque<LLMessageLogEntry> sDeque; | ||
39 | }; | ||
40 | #endif | ||
41 | // </edit> | ||
diff --git a/linden/indra/llmessage/llpacketring.cpp b/linden/indra/llmessage/llpacketring.cpp index 35d5aac..7dcb606 100644 --- a/linden/indra/llmessage/llpacketring.cpp +++ b/linden/indra/llmessage/llpacketring.cpp | |||
@@ -40,6 +40,8 @@ | |||
40 | #include "timing.h" | 40 | #include "timing.h" |
41 | #include "llrand.h" | 41 | #include "llrand.h" |
42 | #include "u64.h" | 42 | #include "u64.h" |
43 | #include "llmessagelog.h" | ||
44 | #include "message.h" | ||
43 | 45 | ||
44 | /////////////////////////////////////////////////////////// | 46 | /////////////////////////////////////////////////////////// |
45 | LLPacketRing::LLPacketRing () : | 47 | LLPacketRing::LLPacketRing () : |
@@ -246,6 +248,9 @@ S32 LLPacketRing::receivePacket (S32 socket, char *datap) | |||
246 | 248 | ||
247 | BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LLHost host) | 249 | BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LLHost host) |
248 | { | 250 | { |
251 | //<edit> | ||
252 | LLMessageLog::log(LLHost(16777343, gMessageSystem->getListenPort()), host, (U8*)send_buffer, buf_size); | ||
253 | //</edit> | ||
249 | BOOL status = TRUE; | 254 | BOOL status = TRUE; |
250 | if (!mUseOutThrottle) | 255 | if (!mUseOutThrottle) |
251 | { | 256 | { |
diff --git a/linden/indra/llmessage/lltemplatemessagereader.cpp b/linden/indra/llmessage/lltemplatemessagereader.cpp index d8904a9..9f68fe9 100644 --- a/linden/indra/llmessage/lltemplatemessagereader.cpp +++ b/linden/indra/llmessage/lltemplatemessagereader.cpp | |||
@@ -449,7 +449,10 @@ S32 LLTemplateMessageReader::getMessageSize() const | |||
449 | // Returns template for the message contained in buffer | 449 | // Returns template for the message contained in buffer |
450 | BOOL LLTemplateMessageReader::decodeTemplate( | 450 | BOOL LLTemplateMessageReader::decodeTemplate( |
451 | const U8* buffer, S32 buffer_size, // inputs | 451 | const U8* buffer, S32 buffer_size, // inputs |
452 | LLMessageTemplate** msg_template ) // outputs | 452 | // <edit> |
453 | //LLMessageTemplate** msg_template ) // outputs | ||
454 | LLMessageTemplate** msg_template, BOOL custom) | ||
455 | // </edit> | ||
453 | { | 456 | { |
454 | const U8* header = buffer + LL_PACKET_ID_SIZE; | 457 | const U8* header = buffer + LL_PACKET_ID_SIZE; |
455 | 458 | ||
@@ -491,6 +494,9 @@ BOOL LLTemplateMessageReader::decodeTemplate( | |||
491 | } | 494 | } |
492 | else // bogus packet received (too short) | 495 | else // bogus packet received (too short) |
493 | { | 496 | { |
497 | // <edit> | ||
498 | if(!custom) | ||
499 | // </edit> | ||
494 | llwarns << "Packet with unusable length received (too short): " | 500 | llwarns << "Packet with unusable length received (too short): " |
495 | << buffer_size << llendl; | 501 | << buffer_size << llendl; |
496 | return(FALSE); | 502 | return(FALSE); |
@@ -503,9 +509,16 @@ BOOL LLTemplateMessageReader::decodeTemplate( | |||
503 | } | 509 | } |
504 | else | 510 | else |
505 | { | 511 | { |
512 | // <edit> | ||
513 | if(!custom) | ||
514 | { | ||
515 | // </edit> | ||
506 | llwarns << "Message #" << std::hex << num << std::dec | 516 | llwarns << "Message #" << std::hex << num << std::dec |
507 | << " received but not registered!" << llendl; | 517 | << " received but not registered!" << llendl; |
508 | gMessageSystem->callExceptionFunc(MX_UNREGISTERED_MESSAGE); | 518 | gMessageSystem->callExceptionFunc(MX_UNREGISTERED_MESSAGE); |
519 | // <edit> | ||
520 | } | ||
521 | // </edit> | ||
509 | return(FALSE); | 522 | return(FALSE); |
510 | } | 523 | } |
511 | 524 | ||
@@ -532,7 +545,8 @@ void LLTemplateMessageReader::logRanOffEndOfPacket( const LLHost& host, const S3 | |||
532 | } | 545 | } |
533 | 546 | ||
534 | // decode a given message | 547 | // decode a given message |
535 | BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender ) | 548 | BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender, BOOL custom) |
549 | // </edit> | ||
536 | { | 550 | { |
537 | llassert( mReceiveSize >= 0 ); | 551 | llassert( mReceiveSize >= 0 ); |
538 | llassert( mCurrentRMessageTemplate); | 552 | llassert( mCurrentRMessageTemplate); |
@@ -594,6 +608,9 @@ BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender | |||
594 | } | 608 | } |
595 | else | 609 | else |
596 | { | 610 | { |
611 | // <edit> | ||
612 | if(!custom) | ||
613 | // </edit> | ||
597 | llerrs << "Unknown block type" << llendl; | 614 | llerrs << "Unknown block type" << llendl; |
598 | return FALSE; | 615 | return FALSE; |
599 | } | 616 | } |
@@ -640,6 +657,9 @@ BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender | |||
640 | 657 | ||
641 | if ((decode_pos + data_size) > mReceiveSize) | 658 | if ((decode_pos + data_size) > mReceiveSize) |
642 | { | 659 | { |
660 | // <edit> | ||
661 | if(!custom) | ||
662 | // </edit> | ||
643 | logRanOffEndOfPacket(sender, decode_pos, data_size); | 663 | logRanOffEndOfPacket(sender, decode_pos, data_size); |
644 | 664 | ||
645 | // default to 0 length variable blocks | 665 | // default to 0 length variable blocks |
@@ -676,6 +696,9 @@ BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender | |||
676 | // so, copy data pointer and set data size to fixed size | 696 | // so, copy data pointer and set data size to fixed size |
677 | if ((decode_pos + mvci.getSize()) > mReceiveSize) | 697 | if ((decode_pos + mvci.getSize()) > mReceiveSize) |
678 | { | 698 | { |
699 | // <edit> | ||
700 | if(!custom) | ||
701 | // </edit> | ||
679 | logRanOffEndOfPacket(sender, decode_pos, mvci.getSize()); | 702 | logRanOffEndOfPacket(sender, decode_pos, mvci.getSize()); |
680 | 703 | ||
681 | // default to 0s. | 704 | // default to 0s. |
@@ -703,7 +726,10 @@ BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender | |||
703 | lldebugs << "Empty message '" << mCurrentRMessageTemplate->mName << "' (no blocks)" << llendl; | 726 | lldebugs << "Empty message '" << mCurrentRMessageTemplate->mName << "' (no blocks)" << llendl; |
704 | return FALSE; | 727 | return FALSE; |
705 | } | 728 | } |
706 | 729 | ||
730 | // <edit> | ||
731 | if(!custom) | ||
732 | // </edit> | ||
707 | { | 733 | { |
708 | static LLTimer decode_timer; | 734 | static LLTimer decode_timer; |
709 | 735 | ||
@@ -756,14 +782,26 @@ BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender | |||
756 | return TRUE; | 782 | return TRUE; |
757 | } | 783 | } |
758 | 784 | ||
785 | // <edit> | ||
786 | LLMessageTemplate* LLTemplateMessageReader::getTemplate() | ||
787 | { | ||
788 | return mCurrentRMessageTemplate; | ||
789 | } | ||
790 | // </edit> | ||
791 | |||
759 | BOOL LLTemplateMessageReader::validateMessage(const U8* buffer, | 792 | BOOL LLTemplateMessageReader::validateMessage(const U8* buffer, |
760 | S32 buffer_size, | 793 | S32 buffer_size, |
761 | const LLHost& sender, | 794 | const LLHost& sender, |
762 | bool trusted) | 795 | bool trusted, |
796 | BOOL custom) | ||
763 | { | 797 | { |
764 | mReceiveSize = buffer_size; | 798 | mReceiveSize = buffer_size; |
765 | BOOL valid = decodeTemplate(buffer, buffer_size, &mCurrentRMessageTemplate ); | 799 | // <edit> |
766 | if(valid) | 800 | //BOOL valid = decodeTemplate(buffer, buffer_size, &mCurrentRMessageTemplate ); |
801 | BOOL valid = decodeTemplate(buffer, buffer_size, &mCurrentRMessageTemplate, custom ); | ||
802 | //if(result) | ||
803 | if(valid && !custom) | ||
804 | // </edit> | ||
767 | { | 805 | { |
768 | mCurrentRMessageTemplate->mReceiveCount++; | 806 | mCurrentRMessageTemplate->mReceiveCount++; |
769 | //lldebugs << "MessageRecvd:" | 807 | //lldebugs << "MessageRecvd:" |
diff --git a/linden/indra/llmessage/lltemplatemessagereader.h b/linden/indra/llmessage/lltemplatemessagereader.h index ab06ab4..0eef93a 100644 --- a/linden/indra/llmessage/lltemplatemessagereader.h +++ b/linden/indra/llmessage/lltemplatemessagereader.h | |||
@@ -102,28 +102,32 @@ public: | |||
102 | virtual const char* getMessageName() const; | 102 | virtual const char* getMessageName() const; |
103 | virtual S32 getMessageSize() const; | 103 | virtual S32 getMessageSize() const; |
104 | 104 | ||
105 | // <edit> | ||
106 | LLMessageTemplate* getTemplate(); | ||
107 | // </edit> | ||
108 | |||
105 | virtual void copyToBuilder(LLMessageBuilder&) const; | 109 | virtual void copyToBuilder(LLMessageBuilder&) const; |
106 | 110 | ||
107 | BOOL validateMessage(const U8* buffer, S32 buffer_size, | 111 | BOOL validateMessage(const U8* buffer, S32 buffer_size, |
108 | const LLHost& sender, bool trusted = false); | 112 | const LLHost& sender, bool trusted = false, BOOL custom = FALSE); |
109 | BOOL readMessage(const U8* buffer, const LLHost& sender); | 113 | BOOL readMessage(const U8* buffer, const LLHost& sender); |
110 | 114 | ||
111 | bool isTrusted() const; | 115 | bool isTrusted() const; |
112 | bool isBanned(bool trusted_source) const; | 116 | bool isBanned(bool trusted_source) const; |
113 | bool isUdpBanned() const; | 117 | bool isUdpBanned() const; |
118 | |||
119 | BOOL decodeData(const U8* buffer, const LLHost& sender, BOOL custom = FALSE); | ||
120 | |||
121 | BOOL decodeTemplate(const U8* buffer, S32 buffer_size, // inputs | ||
122 | LLMessageTemplate** msg_template, BOOL custom = FALSE); // outputs | ||
114 | 123 | ||
115 | private: | 124 | private: |
116 | 125 | ||
117 | void getData(const char *blockname, const char *varname, void *datap, | 126 | void getData(const char *blockname, const char *varname, void *datap, |
118 | S32 size = 0, S32 blocknum = 0, S32 max_size = S32_MAX); | 127 | S32 size = 0, S32 blocknum = 0, S32 max_size = S32_MAX); |
119 | 128 | ||
120 | BOOL decodeTemplate(const U8* buffer, S32 buffer_size, // inputs | ||
121 | LLMessageTemplate** msg_template ); // outputs | ||
122 | |||
123 | void logRanOffEndOfPacket( const LLHost& host, const S32 where, const S32 wanted ); | 129 | void logRanOffEndOfPacket( const LLHost& host, const S32 where, const S32 wanted ); |
124 | 130 | ||
125 | BOOL decodeData(const U8* buffer, const LLHost& sender ); | ||
126 | |||
127 | S32 mReceiveSize; | 131 | S32 mReceiveSize; |
128 | LLMessageTemplate* mCurrentRMessageTemplate; | 132 | LLMessageTemplate* mCurrentRMessageTemplate; |
129 | LLMsgData* mCurrentRMessageData; | 133 | LLMsgData* mCurrentRMessageData; |
diff --git a/linden/indra/llmessage/message.cpp b/linden/indra/llmessage/message.cpp index 78af35b..7e8aff1 100644 --- a/linden/indra/llmessage/message.cpp +++ b/linden/indra/llmessage/message.cpp | |||
@@ -86,6 +86,7 @@ | |||
86 | #include "v3math.h" | 86 | #include "v3math.h" |
87 | #include "v4math.h" | 87 | #include "v4math.h" |
88 | #include "lltransfertargetvfile.h" | 88 | #include "lltransfertargetvfile.h" |
89 | #include "llmessagelog.h" | ||
89 | 90 | ||
90 | // Constants | 91 | // Constants |
91 | //const char* MESSAGE_LOG_FILENAME = "message.log"; | 92 | //const char* MESSAGE_LOG_FILENAME = "message.log"; |
@@ -524,10 +525,10 @@ LLCircuitData* LLMessageSystem::findCircuit(const LLHost& host, | |||
524 | } | 525 | } |
525 | 526 | ||
526 | // Returns TRUE if a valid, on-circuit message has been received. | 527 | // Returns TRUE if a valid, on-circuit message has been received. |
527 | BOOL LLMessageSystem::checkMessages( S64 frame_count ) | 528 | BOOL LLMessageSystem::checkMessages( S64 frame_count, bool faked_message, U8 fake_buffer[MAX_BUFFER_SIZE], LLHost fake_host, S32 fake_size ) |
528 | { | 529 | { |
529 | // Pump | 530 | // Pump |
530 | BOOL valid_packet = FALSE; | 531 | BOOL valid_packet = FALSE; |
531 | mMessageReader = mTemplateMessageReader; | 532 | mMessageReader = mTemplateMessageReader; |
532 | 533 | ||
533 | LLTransferTargetVFile::updateQueue(); | 534 | LLTransferTargetVFile::updateQueue(); |
@@ -557,6 +558,13 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count ) | |||
557 | mTrueReceiveSize = mPacketRing.receivePacket(mSocket, (char *)mTrueReceiveBuffer); | 558 | mTrueReceiveSize = mPacketRing.receivePacket(mSocket, (char *)mTrueReceiveBuffer); |
558 | // If you want to dump all received packets into SecondLife.log, uncomment this | 559 | // If you want to dump all received packets into SecondLife.log, uncomment this |
559 | //dumpPacketToLog(); | 560 | //dumpPacketToLog(); |
561 | // <edit> | ||
562 | if(mTrueReceiveSize && receive_size > (S32) LL_MINIMUM_VALID_PACKET_SIZE) | ||
563 | { | ||
564 | LLMessageLog::log(mLastSender, LLHost(16777343, mPort), buffer, mTrueReceiveSize); | ||
565 | } | ||
566 | // </edit> | ||
567 | |||
560 | 568 | ||
561 | receive_size = mTrueReceiveSize; | 569 | receive_size = mTrueReceiveSize; |
562 | mLastSender = mPacketRing.getLastSender(); | 570 | mLastSender = mPacketRing.getLastSender(); |
@@ -1549,6 +1557,12 @@ U32 LLMessageSystem::getOurCircuitCode() | |||
1549 | return mOurCircuitCode; | 1557 | return mOurCircuitCode; |
1550 | } | 1558 | } |
1551 | 1559 | ||
1560 | // <edit> | ||
1561 | LLCircuit* LLMessageSystem::getCircuit() | ||
1562 | { | ||
1563 | return &mCircuitInfo; | ||
1564 | } | ||
1565 | |||
1552 | void LLMessageSystem::getCircuitInfo(LLSD& info) const | 1566 | void LLMessageSystem::getCircuitInfo(LLSD& info) const |
1553 | { | 1567 | { |
1554 | mCircuitInfo.getInfo(info); | 1568 | mCircuitInfo.getInfo(info); |
diff --git a/linden/indra/llmessage/message.h b/linden/indra/llmessage/message.h index b25b27e..e6391d9 100644 --- a/linden/indra/llmessage/message.h +++ b/linden/indra/llmessage/message.h | |||
@@ -230,11 +230,14 @@ class LLMessageSystem : public LLMessageSenderInterface | |||
230 | typedef std::map<const char *, LLMessageTemplate*> message_template_name_map_t; | 230 | typedef std::map<const char *, LLMessageTemplate*> message_template_name_map_t; |
231 | typedef std::map<U32, LLMessageTemplate*> message_template_number_map_t; | 231 | typedef std::map<U32, LLMessageTemplate*> message_template_number_map_t; |
232 | 232 | ||
233 | private: | 233 | // <edit> |
234 | //private: | ||
235 | // </edit> | ||
234 | message_template_name_map_t mMessageTemplates; | 236 | message_template_name_map_t mMessageTemplates; |
235 | message_template_number_map_t mMessageNumbers; | 237 | message_template_number_map_t mMessageNumbers; |
236 | 238 | // <edit> | |
237 | public: | 239 | //public: |
240 | // </edit> | ||
238 | S32 mSystemVersionMajor; | 241 | S32 mSystemVersionMajor; |
239 | S32 mSystemVersionMinor; | 242 | S32 mSystemVersionMinor; |
240 | S32 mSystemVersionPatch; | 243 | S32 mSystemVersionPatch; |
@@ -341,7 +344,7 @@ public: | |||
341 | bool addCircuitCode(U32 code, const LLUUID& session_id); | 344 | bool addCircuitCode(U32 code, const LLUUID& session_id); |
342 | 345 | ||
343 | BOOL poll(F32 seconds); // Number of seconds that we want to block waiting for data, returns if data was received | 346 | BOOL poll(F32 seconds); // Number of seconds that we want to block waiting for data, returns if data was received |
344 | BOOL checkMessages( S64 frame_count = 0 ); | 347 | BOOL checkMessages( S64 frame_count = 0, bool faked_message = false, U8 fake_buffer[MAX_BUFFER_SIZE] = NULL, LLHost fake_host = LLHost(), S32 fake_size = 0 ); |
345 | void processAcks(); | 348 | void processAcks(); |
346 | 349 | ||
347 | BOOL isMessageFast(const char *msg); | 350 | BOOL isMessageFast(const char *msg); |
@@ -569,6 +572,10 @@ public: | |||
569 | void showCircuitInfo(); | 572 | void showCircuitInfo(); |
570 | void getCircuitInfo(LLSD& info) const; | 573 | void getCircuitInfo(LLSD& info) const; |
571 | 574 | ||
575 | // <edit> | ||
576 | LLCircuit* getCircuit(); | ||
577 | // </edit> | ||
578 | |||
572 | U32 getOurCircuitCode(); | 579 | U32 getOurCircuitCode(); |
573 | 580 | ||
574 | void enableCircuit(const LLHost &host, BOOL trusted); | 581 | void enableCircuit(const LLHost &host, BOOL trusted); |
@@ -733,6 +740,8 @@ public: | |||
733 | // This will cause all trust queries to return true until the next message | 740 | // This will cause all trust queries to return true until the next message |
734 | // is read: use with caution! | 741 | // is read: use with caution! |
735 | void receivedMessageFromTrustedSender(); | 742 | void receivedMessageFromTrustedSender(); |
743 | |||
744 | LLTemplateMessageBuilder* mTemplateMessageBuilder; | ||
736 | 745 | ||
737 | private: | 746 | private: |
738 | 747 | ||
@@ -807,7 +816,6 @@ private: | |||
807 | TPACKETID mCurrentRecvPacketID; // packet ID of current receive packet (for reporting) | 816 | TPACKETID mCurrentRecvPacketID; // packet ID of current receive packet (for reporting) |
808 | 817 | ||
809 | LLMessageBuilder* mMessageBuilder; | 818 | LLMessageBuilder* mMessageBuilder; |
810 | LLTemplateMessageBuilder* mTemplateMessageBuilder; | ||
811 | LLSDMessageBuilder* mLLSDMessageBuilder; | 819 | LLSDMessageBuilder* mLLSDMessageBuilder; |
812 | LLMessageReader* mMessageReader; | 820 | LLMessageReader* mMessageReader; |
813 | LLTemplateMessageReader* mTemplateMessageReader; | 821 | LLTemplateMessageReader* mTemplateMessageReader; |
diff --git a/linden/indra/llui/llscrolllistctrl.cpp b/linden/indra/llui/llscrolllistctrl.cpp index 3c2293f..9635f99 100644 --- a/linden/indra/llui/llscrolllistctrl.cpp +++ b/linden/indra/llui/llscrolllistctrl.cpp | |||
@@ -103,6 +103,10 @@ struct SortScrollListItem | |||
103 | LLScrollListIcon::LLScrollListIcon(LLUIImagePtr icon, S32 width) | 103 | LLScrollListIcon::LLScrollListIcon(LLUIImagePtr icon, S32 width) |
104 | : LLScrollListCell(width), | 104 | : LLScrollListCell(width), |
105 | mIcon(icon), | 105 | mIcon(icon), |
106 | // <edit> | ||
107 | mCallback(NULL), | ||
108 | mUserData(NULL), | ||
109 | // </edit> | ||
106 | mColor(LLColor4::white) | 110 | mColor(LLColor4::white) |
107 | { | 111 | { |
108 | } | 112 | } |
@@ -145,6 +149,19 @@ void LLScrollListIcon::setValue(const LLSD& value) | |||
145 | } | 149 | } |
146 | } | 150 | } |
147 | 151 | ||
152 | // <edit> | ||
153 | void LLScrollListIcon::setClickCallback(BOOL (*callback)(void*), void* user_data) | ||
154 | { | ||
155 | mCallback = callback; | ||
156 | mUserData = user_data; | ||
157 | } | ||
158 | |||
159 | BOOL LLScrollListIcon::handleClick() | ||
160 | { | ||
161 | if(mCallback) return mCallback(mUserData); | ||
162 | return FALSE; | ||
163 | } | ||
164 | // </edit> | ||
148 | 165 | ||
149 | void LLScrollListIcon::setColor(const LLColor4& color) | 166 | void LLScrollListIcon::setColor(const LLColor4& color) |
150 | { | 167 | { |
diff --git a/linden/indra/llui/llscrolllistctrl.h b/linden/indra/llui/llscrolllistctrl.h index 516e4f1..e875d7a 100644 --- a/linden/indra/llui/llscrolllistctrl.h +++ b/linden/indra/llui/llscrolllistctrl.h | |||
@@ -163,10 +163,18 @@ public: | |||
163 | virtual void setColor(const LLColor4&); | 163 | virtual void setColor(const LLColor4&); |
164 | virtual BOOL isText()const { return FALSE; } | 164 | virtual BOOL isText()const { return FALSE; } |
165 | virtual void setValue(const LLSD& value); | 165 | virtual void setValue(const LLSD& value); |
166 | // <edit> | ||
167 | void setClickCallback(BOOL (*callback)(void*), void* user_data); | ||
168 | virtual BOOL handleClick(); | ||
169 | // </edit> | ||
166 | 170 | ||
167 | private: | 171 | private: |
168 | LLUIImagePtr mIcon; | 172 | LLUIImagePtr mIcon; |
169 | LLColor4 mColor; | 173 | LLColor4 mColor; |
174 | // <edit> | ||
175 | BOOL (*mCallback)(void*); | ||
176 | void* mUserData; | ||
177 | // </edit> | ||
170 | }; | 178 | }; |
171 | 179 | ||
172 | /* | 180 | /* |
@@ -493,6 +501,9 @@ public: | |||
493 | 501 | ||
494 | virtual S32 getScrollPos() const; | 502 | virtual S32 getScrollPos() const; |
495 | virtual void setScrollPos( S32 pos ); | 503 | virtual void setScrollPos( S32 pos ); |
504 | // <edit> | ||
505 | S32 getPageLines() { return mPageLines; } | ||
506 | // </edit> | ||
496 | S32 getSearchColumn(); | 507 | S32 getSearchColumn(); |
497 | void setSearchColumn(S32 column) { mSearchColumn = column; } | 508 | void setSearchColumn(S32 column) { mSearchColumn = column; } |
498 | S32 getColumnIndexFromOffset(S32 x); | 509 | S32 getColumnIndexFromOffset(S32 x); |
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 | //////////////////////////////// | ||
21 | LLNetListItem::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 | //////////////////////////////// | ||
33 | std::list<LLNetListItem*> LLFloaterMessageBuilder::sNetListItems; | ||
34 | |||
35 | LLFloaterMessageBuilder::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 | } | ||
43 | LLFloaterMessageBuilder::~LLFloaterMessageBuilder() | ||
44 | { | ||
45 | } | ||
46 | void LLFloaterMessageBuilder::show(std::string initial_text) | ||
47 | { | ||
48 | (new LLFloaterMessageBuilder(initial_text))->open(); | ||
49 | } | ||
50 | BOOL LLFloaterMessageBuilder::tick() | ||
51 | { | ||
52 | refreshNetList(); | ||
53 | return FALSE; | ||
54 | } | ||
55 | LLNetListItem* 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 | } | ||
63 | LLNetListItem* 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 | } | ||
71 | void 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 | } | ||
163 | BOOL 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 | } | ||
194 | inline 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 | } | ||
210 | std::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 | ||
280 | BOOL 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 | ||
571 | void 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 | ||
724 | void 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 | |||
964 | BOOL 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> | ||
diff --git a/linden/indra/newview/llfloatermessagebuilder.h b/linden/indra/newview/llfloatermessagebuilder.h new file mode 100644 index 0000000..5dc9b42 --- /dev/null +++ b/linden/indra/newview/llfloatermessagebuilder.h | |||
@@ -0,0 +1,55 @@ | |||
1 | // <edit>] | ||
2 | #ifndef LL_LLFLOATERMESSAGEBUILDER_H | ||
3 | #define LL_LLFLOATERMESSAGEBUILDER_H | ||
4 | #include "llfloater.h" | ||
5 | #include "lltemplatemessagereader.h" | ||
6 | #include "llmessagelog.h" | ||
7 | |||
8 | class LLNetListItem | ||
9 | { | ||
10 | public: | ||
11 | LLNetListItem(LLUUID id); | ||
12 | LLUUID mID; | ||
13 | BOOL mAutoName; | ||
14 | std::string mName; | ||
15 | std::string mPreviousRegionName; | ||
16 | LLCircuitData* mCircuitData; | ||
17 | }; | ||
18 | |||
19 | class LLFloaterMessageBuilder : public LLFloater, public LLEventTimer | ||
20 | { | ||
21 | public: | ||
22 | LLFloaterMessageBuilder(std::string initial_text); | ||
23 | ~LLFloaterMessageBuilder(); | ||
24 | static void show(std::string initial_text); | ||
25 | static std::list<LLNetListItem*> sNetListItems; | ||
26 | BOOL postBuild(); | ||
27 | BOOL tick(); | ||
28 | static BOOL addField(e_message_variable_type var_type, const char* var_name, std::string input, BOOL hex); | ||
29 | static void onClickSend(void* user_data); | ||
30 | static void onCommitPacketCombo(LLUICtrl* ctrl, void* user_data); | ||
31 | static LLFloaterMessageBuilder* sInstance; | ||
32 | BOOL handleKeyHere(KEY key, MASK mask); | ||
33 | std::string mInitialText; | ||
34 | struct parts_var | ||
35 | { | ||
36 | std::string name; | ||
37 | std::string value; | ||
38 | BOOL hex; | ||
39 | e_message_variable_type var_type; | ||
40 | }; | ||
41 | struct parts_block | ||
42 | { | ||
43 | std::string name; | ||
44 | std::vector<parts_var> vars; | ||
45 | }; | ||
46 | static LLNetListItem* findNetListItem(LLHost host); | ||
47 | static LLNetListItem* findNetListItem(LLUUID id); | ||
48 | void refreshNetList(); | ||
49 | enum ENetInfoMode { NI_NET, NI_LOG }; | ||
50 | ENetInfoMode mNetInfoMode; | ||
51 | static void onCommitMessageLog(LLUICtrl* ctrl, void* user_data); | ||
52 | static void onCommitFilter(LLUICtrl* ctrl, void* user_data); | ||
53 | }; | ||
54 | #endif | ||
55 | // </edit> | ||
diff --git a/linden/indra/newview/llfloatermessagelog.cpp b/linden/indra/newview/llfloatermessagelog.cpp new file mode 100644 index 0000000..161779b --- /dev/null +++ b/linden/indra/newview/llfloatermessagelog.cpp | |||
@@ -0,0 +1,962 @@ | |||
1 | // <edit> | ||
2 | #include "llviewerprecompiledheaders.h" | ||
3 | #include "llfloatermessagelog.h" | ||
4 | #include "lluictrlfactory.h" | ||
5 | #include "llworld.h" | ||
6 | #include "llviewerregion.h" | ||
7 | #include "llscrolllistctrl.h" | ||
8 | #include "lltexteditor.h" | ||
9 | #include "llviewerwindow.h" // alertXml | ||
10 | #include "llmessagetemplate.h" | ||
11 | #include <boost/tokenizer.hpp> | ||
12 | #include "llmenugl.h" | ||
13 | #include "llfloatermessagebuilder.h" | ||
14 | #include "llagent.h" | ||
15 | //////////////////////////////// | ||
16 | // LLFloaterMessageLogItem | ||
17 | //////////////////////////////// | ||
18 | #define MAX_PACKET_LEN (0x2000) | ||
19 | LLTemplateMessageReader* LLFloaterMessageLogItem::sTemplateMessageReader = NULL; | ||
20 | LLFloaterMessageLogItem::LLFloaterMessageLogItem(LLMessageLogEntry entry) | ||
21 | : LLMessageLogEntry(entry.mType, entry.mFromHost, entry.mToHost, entry.mData, entry.mDataSize) | ||
22 | { | ||
23 | if(!sTemplateMessageReader) | ||
24 | { | ||
25 | sTemplateMessageReader = new LLTemplateMessageReader(gMessageSystem->mMessageNumbers); | ||
26 | } | ||
27 | mID.generate(); | ||
28 | mSequenceID = 0; | ||
29 | if(mType == TEMPLATE) | ||
30 | { | ||
31 | BOOL decode_invalid = FALSE; | ||
32 | S32 decode_len = mDataSize; | ||
33 | std::vector<U8> DecodeBuffer(MAX_PACKET_LEN,0); | ||
34 | memcpy(&(DecodeBuffer[0]),&(mData[0]),decode_len); | ||
35 | U8* decodep = &(DecodeBuffer[0]); | ||
36 | mFlags = DecodeBuffer[0]; | ||
37 | gMessageSystem->zeroCodeExpand(&decodep, &decode_len); | ||
38 | if(decode_len < 7) | ||
39 | decode_invalid = TRUE; | ||
40 | else | ||
41 | { | ||
42 | mSequenceID = ntohl(*((U32*)(&decodep[1]))); | ||
43 | sTemplateMessageReader->clearMessage(); | ||
44 | if(!sTemplateMessageReader->validateMessage(decodep, decode_len, mFromHost, TRUE)) | ||
45 | decode_invalid = TRUE; | ||
46 | else | ||
47 | { | ||
48 | if(!sTemplateMessageReader->decodeData(decodep, mFromHost, TRUE)) | ||
49 | decode_invalid = TRUE; | ||
50 | else | ||
51 | { | ||
52 | LLMessageTemplate* temp = sTemplateMessageReader->getTemplate(); | ||
53 | mName = temp->mName; | ||
54 | mSummary = ""; | ||
55 | |||
56 | if(mFlags) | ||
57 | { | ||
58 | mSummary.append(" [ "); | ||
59 | if(mFlags & LL_ZERO_CODE_FLAG) | ||
60 | mSummary.append(" Zer "); | ||
61 | if(mFlags & LL_RELIABLE_FLAG) | ||
62 | mSummary.append(" Rel "); | ||
63 | if(mFlags & LL_RESENT_FLAG) | ||
64 | mSummary.append(" Rsd "); | ||
65 | if(mFlags & LL_ACK_FLAG) | ||
66 | mSummary.append(" Ack "); | ||
67 | mSummary.append(" ] "); | ||
68 | } | ||
69 | |||
70 | LLMessageTemplate::message_block_map_t::iterator blocks_end = temp->mMemberBlocks.end(); | ||
71 | for (LLMessageTemplate::message_block_map_t::iterator blocks_iter = temp->mMemberBlocks.begin(); | ||
72 | blocks_iter != blocks_end; ++blocks_iter) | ||
73 | { | ||
74 | LLMessageBlock* block = (*blocks_iter); | ||
75 | const char* block_name = block->mName; | ||
76 | S32 num_blocks = sTemplateMessageReader->getNumberOfBlocks(block_name); | ||
77 | if(!num_blocks) | ||
78 | mSummary.append(" { } "); | ||
79 | else if(num_blocks > 1) | ||
80 | mSummary.append(llformat(" %s [ %d ] { ... } ", block_name, num_blocks)); | ||
81 | else for(S32 i = 0; i < 1; i++) | ||
82 | { | ||
83 | mSummary.append(" { "); | ||
84 | LLMessageBlock::message_variable_map_t::iterator var_end = block->mMemberVariables.end(); | ||
85 | for (LLMessageBlock::message_variable_map_t::iterator var_iter = block->mMemberVariables.begin(); | ||
86 | var_iter != var_end; ++var_iter) | ||
87 | { | ||
88 | LLMessageVariable* variable = (*var_iter); | ||
89 | const char* var_name = variable->getName(); | ||
90 | BOOL returned_hex; | ||
91 | std::string value = getString(sTemplateMessageReader, block_name, i, var_name, variable->getType(), returned_hex, TRUE); | ||
92 | mSummary.append(llformat(" %s=%s ", var_name, value.c_str())); | ||
93 | } | ||
94 | mSummary.append(" } "); | ||
95 | if(mSummary.length() > 255) break; | ||
96 | } | ||
97 | if(mSummary.length() > 255) | ||
98 | { | ||
99 | mSummary.append(" ... "); | ||
100 | break; | ||
101 | } | ||
102 | } // blocks_iter | ||
103 | } // decode_valid | ||
104 | } | ||
105 | } | ||
106 | if(decode_invalid) | ||
107 | { | ||
108 | mName = "Invalid"; | ||
109 | mSummary = ""; | ||
110 | for(S32 i = 0; i < mDataSize; i++) | ||
111 | mSummary.append(llformat("%02X ", mData[i])); | ||
112 | } | ||
113 | } | ||
114 | else // not template | ||
115 | { | ||
116 | mName = "SOMETHING ELSE"; | ||
117 | mSummary = "TODO: SOMETHING ELSE"; | ||
118 | } | ||
119 | } | ||
120 | LLFloaterMessageLogItem::~LLFloaterMessageLogItem() | ||
121 | { | ||
122 | } | ||
123 | BOOL LLFloaterMessageLogItem::isOutgoing() | ||
124 | { | ||
125 | return mFromHost == LLHost(16777343, gMessageSystem->getListenPort()); | ||
126 | } | ||
127 | std::string LLFloaterMessageLogItem::getFull(BOOL show_header) | ||
128 | { | ||
129 | std::string full(""); | ||
130 | if(mType == TEMPLATE) | ||
131 | { | ||
132 | BOOL decode_invalid = FALSE; | ||
133 | S32 decode_len = mDataSize; | ||
134 | std::vector<U8> DecodeBuffer(MAX_PACKET_LEN,0); | ||
135 | memcpy(&(DecodeBuffer[0]),&(mData[0]),decode_len); | ||
136 | U8* decodep = &(DecodeBuffer[0]); | ||
137 | gMessageSystem->zeroCodeExpand(&decodep, &decode_len); | ||
138 | if(decode_len < 7) | ||
139 | decode_invalid = TRUE; | ||
140 | else | ||
141 | { | ||
142 | sTemplateMessageReader->clearMessage(); | ||
143 | if(!sTemplateMessageReader->validateMessage(decodep, decode_len, mFromHost, TRUE)) | ||
144 | decode_invalid = TRUE; | ||
145 | else | ||
146 | { | ||
147 | if(!sTemplateMessageReader->decodeData(decodep, mFromHost, TRUE)) | ||
148 | decode_invalid = TRUE; | ||
149 | else | ||
150 | { | ||
151 | LLMessageTemplate* temp = sTemplateMessageReader->getTemplate(); | ||
152 | full.append(isOutgoing() ? "out " : "in "); | ||
153 | full.append(llformat("%s\n", temp->mName)); | ||
154 | if(show_header) | ||
155 | { | ||
156 | full.append("[Header]\n"); | ||
157 | full.append(llformat("SequenceID = %u\n", mSequenceID)); | ||
158 | full.append(llformat("LL_ZERO_CODE_FLAG = %s\n", (mFlags & LL_ZERO_CODE_FLAG) ? "True" : "False")); | ||
159 | full.append(llformat("LL_RELIABLE_FLAG = %s\n", (mFlags & LL_RELIABLE_FLAG) ? "True" : "False")); | ||
160 | full.append(llformat("LL_RESENT_FLAG = %s\n", (mFlags & LL_RESENT_FLAG) ? "True" : "False")); | ||
161 | full.append(llformat("LL_ACK_FLAG = %s\n", (mFlags & LL_ACK_FLAG) ? "True" : "False")); | ||
162 | } | ||
163 | LLMessageTemplate::message_block_map_t::iterator blocks_end = temp->mMemberBlocks.end(); | ||
164 | for (LLMessageTemplate::message_block_map_t::iterator blocks_iter = temp->mMemberBlocks.begin(); | ||
165 | blocks_iter != blocks_end; ++blocks_iter) | ||
166 | { | ||
167 | LLMessageBlock* block = (*blocks_iter); | ||
168 | const char* block_name = block->mName; | ||
169 | S32 num_blocks = sTemplateMessageReader->getNumberOfBlocks(block_name); | ||
170 | for(S32 i = 0; i < num_blocks; i++) | ||
171 | { | ||
172 | full.append(llformat("[%s]\n", block->mName)); | ||
173 | LLMessageBlock::message_variable_map_t::iterator var_end = block->mMemberVariables.end(); | ||
174 | for (LLMessageBlock::message_variable_map_t::iterator var_iter = block->mMemberVariables.begin(); | ||
175 | var_iter != var_end; ++var_iter) | ||
176 | { | ||
177 | LLMessageVariable* variable = (*var_iter); | ||
178 | const char* var_name = variable->getName(); | ||
179 | BOOL returned_hex; | ||
180 | std::string value = getString(sTemplateMessageReader, block_name, i, var_name, variable->getType(), returned_hex); | ||
181 | if(returned_hex) | ||
182 | full.append(llformat("%s =| ", var_name)); | ||
183 | else | ||
184 | full.append(llformat("%s = ", var_name)); | ||
185 | // llformat has a 1024 char limit!? | ||
186 | full.append(value); | ||
187 | full.append("\n"); | ||
188 | } | ||
189 | } | ||
190 | } // blocks_iter | ||
191 | } // decode_valid | ||
192 | } | ||
193 | } | ||
194 | if(decode_invalid) | ||
195 | { | ||
196 | full = isOutgoing() ? "out" : "in"; | ||
197 | full.append("\n"); | ||
198 | for(S32 i = 0; i < mDataSize; i++) | ||
199 | full.append(llformat("%02X ", mData[i])); | ||
200 | } | ||
201 | } | ||
202 | else // not template | ||
203 | { | ||
204 | full = "FIXME"; | ||
205 | } | ||
206 | return full; | ||
207 | } | ||
208 | // static | ||
209 | std::string LLFloaterMessageLogItem::getString(LLTemplateMessageReader* readerp, const char* block_name, S32 block_num, const char* var_name, e_message_variable_type var_type, BOOL &returned_hex, BOOL summary_mode) | ||
210 | { | ||
211 | returned_hex = FALSE; | ||
212 | std::stringstream stream; | ||
213 | char* value; | ||
214 | U32 valueU32; | ||
215 | U16 valueU16; | ||
216 | LLVector3 valueVector3; | ||
217 | LLVector3d valueVector3d; | ||
218 | LLVector4 valueVector4; | ||
219 | LLQuaternion valueQuaternion; | ||
220 | LLUUID valueLLUUID; | ||
221 | switch(var_type) | ||
222 | { | ||
223 | case MVT_U8: | ||
224 | U8 valueU8; | ||
225 | readerp->getU8(block_name, var_name, valueU8, block_num); | ||
226 | stream << U32(valueU8); | ||
227 | break; | ||
228 | case MVT_U16: | ||
229 | readerp->getU16(block_name, var_name, valueU16, block_num); | ||
230 | stream << valueU16; | ||
231 | break; | ||
232 | case MVT_U32: | ||
233 | readerp->getU32(block_name, var_name, valueU32, block_num); | ||
234 | stream << valueU32; | ||
235 | break; | ||
236 | case MVT_U64: | ||
237 | U64 valueU64; | ||
238 | readerp->getU64(block_name, var_name, valueU64, block_num); | ||
239 | stream << valueU64; | ||
240 | break; | ||
241 | case MVT_S8: | ||
242 | S8 valueS8; | ||
243 | readerp->getS8(block_name, var_name, valueS8, block_num); | ||
244 | stream << S32(valueS8); | ||
245 | break; | ||
246 | case MVT_S16: | ||
247 | S16 valueS16; | ||
248 | readerp->getS16(block_name, var_name, valueS16, block_num); | ||
249 | stream << valueS16; | ||
250 | break; | ||
251 | case MVT_S32: | ||
252 | S32 valueS32; | ||
253 | readerp->getS32(block_name, var_name, valueS32, block_num); | ||
254 | stream << valueS32; | ||
255 | break; | ||
256 | /*case MVT_S64: | ||
257 | S64 valueS64; | ||
258 | readerp->getS64(block_name, var_name, valueS64, block_num); | ||
259 | stream << valueS64; | ||
260 | break;*/ | ||
261 | case MVT_F32: | ||
262 | F32 valueF32; | ||
263 | readerp->getF32(block_name, var_name, valueF32, block_num); | ||
264 | stream << valueF32; | ||
265 | break; | ||
266 | case MVT_F64: | ||
267 | F64 valueF64; | ||
268 | readerp->getF64(block_name, var_name, valueF64, block_num); | ||
269 | stream << valueF64; | ||
270 | break; | ||
271 | case MVT_LLVector3: | ||
272 | readerp->getVector3(block_name, var_name, valueVector3, block_num); | ||
273 | //stream << valueVector3; | ||
274 | stream << "<" << valueVector3.mV[0] << ", " << valueVector3.mV[1] << ", " << valueVector3.mV[2] << ">"; | ||
275 | break; | ||
276 | case MVT_LLVector3d: | ||
277 | readerp->getVector3d(block_name, var_name, valueVector3d, block_num); | ||
278 | //stream << valueVector3d; | ||
279 | stream << "<" << valueVector3d.mdV[0] << ", " << valueVector3d.mdV[1] << ", " << valueVector3d.mdV[2] << ">"; | ||
280 | break; | ||
281 | case MVT_LLVector4: | ||
282 | readerp->getVector4(block_name, var_name, valueVector4, block_num); | ||
283 | //stream << valueVector4; | ||
284 | stream << "<" << valueVector4.mV[0] << ", " << valueVector4.mV[1] << ", " << valueVector4.mV[2] << ", " << valueVector4.mV[3] << ">"; | ||
285 | break; | ||
286 | case MVT_LLQuaternion: | ||
287 | readerp->getQuat(block_name, var_name, valueQuaternion, block_num); | ||
288 | //stream << valueQuaternion; | ||
289 | stream << "<" << valueQuaternion.mQ[0] << ", " << valueQuaternion.mQ[1] << ", " << valueQuaternion.mQ[2] << ", " << valueQuaternion.mQ[3] << ">"; | ||
290 | break; | ||
291 | case MVT_LLUUID: | ||
292 | readerp->getUUID(block_name, var_name, valueLLUUID, block_num); | ||
293 | stream << valueLLUUID; | ||
294 | break; | ||
295 | case MVT_BOOL: | ||
296 | BOOL valueBOOL; | ||
297 | readerp->getBOOL(block_name, var_name, valueBOOL, block_num); | ||
298 | stream << valueBOOL; | ||
299 | break; | ||
300 | case MVT_IP_ADDR: | ||
301 | readerp->getIPAddr(block_name, var_name, valueU32, block_num); | ||
302 | stream << LLHost(valueU32, 0).getIPString(); | ||
303 | break; | ||
304 | case MVT_IP_PORT: | ||
305 | readerp->getIPPort(block_name, var_name, valueU16, block_num); | ||
306 | stream << valueU16; | ||
307 | case MVT_VARIABLE: | ||
308 | case MVT_FIXED: | ||
309 | default: | ||
310 | S32 size = readerp->getSize(block_name, block_num, var_name); | ||
311 | if(size) | ||
312 | { | ||
313 | value = new char[size + 1]; | ||
314 | readerp->getBinaryData(block_name, var_name, value, size, block_num); | ||
315 | value[size] = '\0'; | ||
316 | S32 readable = 0; | ||
317 | S32 unreadable = 0; | ||
318 | S32 end = (summary_mode && (size > 64)) ? 64 : size; | ||
319 | for(S32 i = 0; i < end; i++) | ||
320 | { | ||
321 | if(!value[i]) | ||
322 | { | ||
323 | if(i != (end - 1)) | ||
324 | { // don't want null terminator hiding data | ||
325 | unreadable = S32_MAX; | ||
326 | break; | ||
327 | } | ||
328 | } | ||
329 | else if(value[i] < 0x20 || value[i] >= 0x7F) | ||
330 | { | ||
331 | if(summary_mode) | ||
332 | unreadable++; | ||
333 | else | ||
334 | { // never want any wrong characters outside of summary mode | ||
335 | unreadable = S32_MAX; | ||
336 | break; | ||
337 | } | ||
338 | } | ||
339 | else readable++; | ||
340 | } | ||
341 | if(readable >= unreadable) | ||
342 | { | ||
343 | if(summary_mode && (size > 64)) | ||
344 | { | ||
345 | for(S32 i = 60; i < 63; i++) | ||
346 | value[i] = '.'; | ||
347 | value[63] = '\0'; | ||
348 | } | ||
349 | stream << value; | ||
350 | |||
351 | delete[] value; | ||
352 | } | ||
353 | else | ||
354 | { | ||
355 | returned_hex = TRUE; | ||
356 | S32 end = (summary_mode && (size > 8)) ? 8 : size; | ||
357 | for(S32 i = 0; i < end; i++) | ||
358 | //stream << std::uppercase << std::hex << U32(value[i]) << " "; | ||
359 | stream << llformat("%02X ", (U8)value[i]); | ||
360 | if(summary_mode && (size > 8)) | ||
361 | stream << " ... "; | ||
362 | } | ||
363 | } | ||
364 | break; | ||
365 | } | ||
366 | |||
367 | return stream.str(); | ||
368 | } | ||
369 | LLMessageLogFilter::LLMessageLogFilter() | ||
370 | { | ||
371 | } | ||
372 | LLMessageLogFilter::~LLMessageLogFilter() | ||
373 | { | ||
374 | } | ||
375 | BOOL LLMessageLogFilter::set(std::string filter) | ||
376 | { | ||
377 | mPositiveNames.clear(); | ||
378 | mNegativeNames.clear(); | ||
379 | typedef boost::tokenizer<boost::char_separator<char> > tokenizer; | ||
380 | boost::char_separator<char> sep(" ","",boost::keep_empty_tokens); | ||
381 | boost::tokenizer<boost::char_separator<char> > tokens(filter, sep); | ||
382 | boost::tokenizer<boost::char_separator<char> >::iterator end = tokens.end(); | ||
383 | for(boost::tokenizer<boost::char_separator<char> >::iterator iter = tokens.begin(); iter != end; ++iter) | ||
384 | { | ||
385 | std::string token = (*iter); | ||
386 | LLStringUtil::trim(token); | ||
387 | LLStringUtil::toLower(token); | ||
388 | BOOL negative = token.find("!") == 0; | ||
389 | if(negative) | ||
390 | { | ||
391 | token = token.substr(1); | ||
392 | mNegativeNames.push_back(token); | ||
393 | } | ||
394 | else | ||
395 | mPositiveNames.push_back(token); | ||
396 | } | ||
397 | return TRUE; | ||
398 | } | ||
399 | //////////////////////////////// | ||
400 | // LLMessageLogFilterApply | ||
401 | //////////////////////////////// | ||
402 | LLMessageLogFilterApply::LLMessageLogFilterApply() | ||
403 | : LLEventTimer(0.1f), | ||
404 | mFinished(FALSE), | ||
405 | mProgress(0) | ||
406 | { | ||
407 | mIter = LLFloaterMessageLog::sMessageLogEntries.begin(); | ||
408 | } | ||
409 | void LLMessageLogFilterApply::cancel() | ||
410 | { | ||
411 | mFinished = TRUE; | ||
412 | } | ||
413 | BOOL LLMessageLogFilterApply::tick() | ||
414 | { | ||
415 | std::deque<LLMessageLogEntry>::iterator end = LLFloaterMessageLog::sMessageLogEntries.end(); | ||
416 | if(mIter == end || !LLFloaterMessageLog::sInstance) | ||
417 | { | ||
418 | mFinished = TRUE; | ||
419 | if(LLFloaterMessageLog::sInstance) | ||
420 | { | ||
421 | if(LLFloaterMessageLog::sInstance->mMessageLogFilterApply == this) | ||
422 | { | ||
423 | LLFloaterMessageLog::sInstance->stopApplyingFilter(); | ||
424 | } | ||
425 | } | ||
426 | return TRUE; | ||
427 | } | ||
428 | for(S32 i = 0; i < 256; i++) | ||
429 | { | ||
430 | if(mIter == end) | ||
431 | { | ||
432 | mFinished = TRUE; | ||
433 | if(LLFloaterMessageLog::sInstance) | ||
434 | { | ||
435 | if(LLFloaterMessageLog::sInstance->mMessageLogFilterApply == this) | ||
436 | { | ||
437 | LLFloaterMessageLog::sInstance->stopApplyingFilter(); | ||
438 | |||
439 | //we're done messing with the deque, push all queued items to the main deque | ||
440 | std::deque<LLMessageLogEntry>::iterator queueIter = mQueuedMessages.begin(); | ||
441 | std::deque<LLMessageLogEntry>::iterator queueEnd = mQueuedMessages.end(); | ||
442 | |||
443 | while(queueIter != queueEnd) | ||
444 | { | ||
445 | LLFloaterMessageLog::sInstance->conditionalLog(LLFloaterMessageLogItem((*queueIter))); | ||
446 | ++queueIter; | ||
447 | } | ||
448 | |||
449 | mQueuedMessages.clear(); | ||
450 | } | ||
451 | } | ||
452 | |||
453 | return TRUE; | ||
454 | } | ||
455 | |||
456 | LLFloaterMessageLog::sInstance->conditionalLog(LLFloaterMessageLogItem((*mIter))); | ||
457 | |||
458 | mIter++; | ||
459 | mProgress++; | ||
460 | } | ||
461 | LLFloaterMessageLog::sInstance->updateFilterStatus(); | ||
462 | return FALSE; | ||
463 | } | ||
464 | //////////////////////////////// | ||
465 | // LLFloaterMessageLog | ||
466 | //////////////////////////////// | ||
467 | LLFloaterMessageLog* LLFloaterMessageLog::sInstance; | ||
468 | std::list<LLNetListItem*> LLFloaterMessageLog::sNetListItems; | ||
469 | std::deque<LLMessageLogEntry> LLFloaterMessageLog::sMessageLogEntries; | ||
470 | std::vector<LLFloaterMessageLogItem> LLFloaterMessageLog::sFloaterMessageLogItems; | ||
471 | LLMessageLogFilter LLFloaterMessageLog::sMessageLogFilter = LLMessageLogFilter(); | ||
472 | std::string LLFloaterMessageLog::sMessageLogFilterString("!StartPingCheck !CompletePingCheck !PacketAck !SimulatorViewerTimeMessage !SimStats !AgentUpdate !AgentAnimation !AvatarAnimation !ViewerEffect !CoarseLocationUpdate !LayerData !CameraConstraint !ObjectUpdateCached !RequestMultipleObjects !ObjectUpdate !ObjectUpdateCompressed !ImprovedTerseObjectUpdate !KillObject !ImagePacket !SendXferPacket !ConfirmXferPacket !TransferPacket !SoundTrigger !AttachedSound !PreloadSound"); | ||
473 | BOOL LLFloaterMessageLog::sBusyApplyingFilter = FALSE; | ||
474 | LLFloaterMessageLog::LLFloaterMessageLog() | ||
475 | : LLFloater(), | ||
476 | LLEventTimer(1.0f), | ||
477 | mNetInfoMode(NI_NET), | ||
478 | mMessageLogFilterApply(NULL) | ||
479 | { | ||
480 | sInstance = this; | ||
481 | LLMessageLog::setCallback(onLog); | ||
482 | sMessageLogEntries = LLMessageLog::getDeque(); | ||
483 | LLUICtrlFactory::getInstance()->buildFloater(this, "floater_message_log.xml"); | ||
484 | } | ||
485 | LLFloaterMessageLog::~LLFloaterMessageLog() | ||
486 | { | ||
487 | LLMessageLog::setCallback(NULL); | ||
488 | stopApplyingFilter(); | ||
489 | sInstance = NULL; | ||
490 | sNetListItems.clear(); | ||
491 | sMessageLogEntries.clear(); | ||
492 | sFloaterMessageLogItems.clear(); | ||
493 | } | ||
494 | // static | ||
495 | void LLFloaterMessageLog::show() | ||
496 | { | ||
497 | if(!sInstance) sInstance = new LLFloaterMessageLog(); | ||
498 | sInstance->open(); | ||
499 | } | ||
500 | BOOL LLFloaterMessageLog::postBuild() | ||
501 | { | ||
502 | childSetCommitCallback("net_list", onCommitNetList, this); | ||
503 | childSetCommitCallback("message_log", onCommitMessageLog, this); | ||
504 | childSetAction("filter_choice_btn", onClickFilterChoice, this); | ||
505 | childSetAction("filter_apply_btn", onClickFilterApply, this); | ||
506 | childSetCommitCallback("filter_edit", onCommitFilter, this); | ||
507 | childSetAction("clear_log_btn", onClickClearLog, this); | ||
508 | childSetAction("send_to_message_builder_btn", onClickSendToMessageBuilder, this); | ||
509 | childSetText("filter_edit", sMessageLogFilterString); | ||
510 | refreshNetList(); | ||
511 | refreshNetInfo(TRUE); | ||
512 | startApplyingFilter(sMessageLogFilterString, TRUE); | ||
513 | return TRUE; | ||
514 | } | ||
515 | BOOL LLFloaterMessageLog::tick() | ||
516 | { | ||
517 | refreshNetList(); | ||
518 | refreshNetInfo(FALSE); | ||
519 | return FALSE; | ||
520 | } | ||
521 | LLNetListItem* LLFloaterMessageLog::findNetListItem(LLHost host) | ||
522 | { | ||
523 | std::list<LLNetListItem*>::iterator end = sNetListItems.end(); | ||
524 | for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != end; ++iter) | ||
525 | if((*iter)->mCircuitData && (*iter)->mCircuitData->getHost() == host) | ||
526 | return (*iter); | ||
527 | return NULL; | ||
528 | } | ||
529 | LLNetListItem* LLFloaterMessageLog::findNetListItem(LLUUID id) | ||
530 | { | ||
531 | std::list<LLNetListItem*>::iterator end = sNetListItems.end(); | ||
532 | for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != end; ++iter) | ||
533 | if((*iter)->mID == id) | ||
534 | return (*iter); | ||
535 | return NULL; | ||
536 | } | ||
537 | void LLFloaterMessageLog::refreshNetList() | ||
538 | { | ||
539 | LLScrollListCtrl* scrollp = getChild<LLScrollListCtrl>("net_list"); | ||
540 | // Update circuit data of net list items | ||
541 | std::vector<LLCircuitData*> circuits = gMessageSystem->getCircuit()->getCircuitDataList(); | ||
542 | std::vector<LLCircuitData*>::iterator circuits_end = circuits.end(); | ||
543 | for(std::vector<LLCircuitData*>::iterator iter = circuits.begin(); iter != circuits_end; ++iter) | ||
544 | { | ||
545 | LLNetListItem* itemp = findNetListItem((*iter)->getHost()); | ||
546 | if(!itemp) | ||
547 | { | ||
548 | LLUUID id; id.generate(); | ||
549 | itemp = new LLNetListItem(id); | ||
550 | sNetListItems.push_back(itemp); | ||
551 | } | ||
552 | itemp->mCircuitData = (*iter); | ||
553 | } | ||
554 | // Clear circuit data of items whose circuits are gone | ||
555 | std::list<LLNetListItem*>::iterator items_end = sNetListItems.end(); | ||
556 | for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != items_end; ++iter) | ||
557 | { | ||
558 | if(std::find(circuits.begin(), circuits.end(), (*iter)->mCircuitData) == circuits.end()) | ||
559 | (*iter)->mCircuitData = NULL; | ||
560 | } | ||
561 | // Remove net list items that are totally useless now | ||
562 | for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != sNetListItems.end();) | ||
563 | { | ||
564 | if((*iter)->mCircuitData == NULL) | ||
565 | iter = sNetListItems.erase(iter); | ||
566 | else ++iter; | ||
567 | } | ||
568 | // Update names of net list items | ||
569 | items_end = sNetListItems.end(); | ||
570 | for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != items_end; ++iter) | ||
571 | { | ||
572 | LLNetListItem* itemp = (*iter); | ||
573 | if(itemp->mAutoName) | ||
574 | { | ||
575 | if(itemp->mCircuitData) | ||
576 | { | ||
577 | LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(itemp->mCircuitData->getHost()); | ||
578 | if(regionp) | ||
579 | { | ||
580 | std::string name = regionp->getName(); | ||
581 | if(name == "") name = llformat("%s (awaiting region name)", itemp->mCircuitData->getHost().getString().c_str()); | ||
582 | itemp->mName = name; | ||
583 | itemp->mPreviousRegionName = name; | ||
584 | } | ||
585 | else | ||
586 | { | ||
587 | itemp->mName = itemp->mCircuitData->getHost().getString(); | ||
588 | if(itemp->mPreviousRegionName != "") | ||
589 | itemp->mName.append(llformat(" (was %s)", itemp->mPreviousRegionName.c_str())); | ||
590 | } | ||
591 | } | ||
592 | else | ||
593 | { | ||
594 | // an item just for an event queue, not handled yet | ||
595 | itemp->mName = "Something else"; | ||
596 | } | ||
597 | } | ||
598 | } | ||
599 | // Rebuild scroll list from scratch | ||
600 | LLUUID selected_id = scrollp->getFirstSelected() ? scrollp->getFirstSelected()->getUUID() : LLUUID::null; | ||
601 | S32 scroll_pos = scrollp->getScrollPos(); | ||
602 | scrollp->clearRows(); | ||
603 | for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != items_end; ++iter) | ||
604 | { | ||
605 | LLNetListItem* itemp = (*iter); | ||
606 | LLSD element; | ||
607 | element["id"] = itemp->mID; | ||
608 | LLSD& text_column = element["columns"][0]; | ||
609 | text_column["column"] = "text"; | ||
610 | text_column["value"] = itemp->mName + (itemp->mCircuitData->getHost() == gAgent.getRegionHost() ? " (main)" : ""); | ||
611 | for(int i = 0; i < 2; i++) | ||
612 | { | ||
613 | LLSD& icon_column = element["columns"][i + 1]; | ||
614 | icon_column["column"] = llformat("icon%d", i); | ||
615 | icon_column["type"] = "icon"; | ||
616 | icon_column["value"] = ""; | ||
617 | } | ||
618 | LLScrollListItem* scroll_itemp = scrollp->addElement(element); | ||
619 | BOOL has_live_circuit = itemp->mCircuitData && itemp->mCircuitData->isAlive(); | ||
620 | if(has_live_circuit) | ||
621 | { | ||
622 | LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(1); | ||
623 | icon->setValue("icon_net_close_circuit.tga"); | ||
624 | icon->setClickCallback(onClickCloseCircuit, itemp); | ||
625 | } | ||
626 | else | ||
627 | { | ||
628 | LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(1); | ||
629 | icon->setValue("icon_net_close_circuit_gray.tga"); | ||
630 | icon->setClickCallback(NULL, NULL); | ||
631 | } | ||
632 | // Event queue isn't even supported yet... FIXME | ||
633 | LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(2); | ||
634 | icon->setValue("icon_net_close_eventpoll_gray.tga"); | ||
635 | icon->setClickCallback(NULL, NULL); | ||
636 | } | ||
637 | if(selected_id.notNull()) scrollp->selectByID(selected_id); | ||
638 | if(scroll_pos < scrollp->getItemCount()) scrollp->setScrollPos(scroll_pos); | ||
639 | } | ||
640 | void LLFloaterMessageLog::refreshNetInfo(BOOL force) | ||
641 | { | ||
642 | if(mNetInfoMode != NI_NET) return; | ||
643 | LLScrollListCtrl* scrollp = getChild<LLScrollListCtrl>("net_list"); | ||
644 | LLScrollListItem* selected_itemp = scrollp->getFirstSelected(); | ||
645 | if(selected_itemp) | ||
646 | { | ||
647 | if(!force) if(getChild<LLTextEditor>("net_info")->hasSelection()) return; | ||
648 | LLNetListItem* itemp = findNetListItem(selected_itemp->getUUID()); | ||
649 | if(itemp) | ||
650 | { | ||
651 | std::string info(llformat("%s\n--------------------------------\n\n", itemp->mName.c_str())); | ||
652 | if(itemp->mCircuitData) | ||
653 | { | ||
654 | LLCircuitData* cdp = itemp->mCircuitData; | ||
655 | info.append("Circuit\n--------------------------------\n"); | ||
656 | info.append(llformat(" * Host: %s\n", cdp->getHost().getString().c_str())); | ||
657 | S32 seconds = (S32)cdp->getAgeInSeconds(); | ||
658 | S32 minutes = seconds / 60; | ||
659 | seconds = seconds % 60; | ||
660 | S32 hours = minutes / 60; | ||
661 | minutes = minutes % 60; | ||
662 | info.append(llformat(" * Age: %dh %dm %ds\n", hours, minutes, seconds)); | ||
663 | info.append(llformat(" * Alive: %s\n", cdp->isAlive() ? "yes" : "no")); | ||
664 | info.append(llformat(" * Blocked: %s\n", cdp->isBlocked() ? "yes" : "no")); | ||
665 | info.append(llformat(" * Allow timeout: %s\n", cdp->getAllowTimeout() ? "yes" : "no")); | ||
666 | info.append(llformat(" * Trusted: %s\n", cdp->getTrusted() ? "yes" : "no")); | ||
667 | info.append(llformat(" * Ping delay: %d\n", cdp->getPingDelay())); | ||
668 | info.append(llformat(" * Packets out: %d\n", cdp->getPacketsOut())); | ||
669 | info.append(llformat(" * Bytes out: %d\n", cdp->getBytesOut())); | ||
670 | info.append(llformat(" * Packets in: %d\n", cdp->getPacketsIn())); | ||
671 | info.append(llformat(" * Bytes in: %d\n", cdp->getBytesIn())); | ||
672 | info.append(llformat(" * Endpoint ID: %s\n", cdp->getLocalEndPointID().asString().c_str())); | ||
673 | info.append(llformat(" * Remote ID: %s\n", cdp->getRemoteID().asString().c_str())); | ||
674 | info.append(llformat(" * Remote session ID: %s\n", cdp->getRemoteSessionID().asString().c_str())); | ||
675 | } | ||
676 | childSetText("net_info", info); | ||
677 | } | ||
678 | else childSetText("net_info", std::string("")); | ||
679 | } | ||
680 | else childSetText("net_info", std::string("")); | ||
681 | } | ||
682 | void LLFloaterMessageLog::setNetInfoMode(ENetInfoMode mode) | ||
683 | { | ||
684 | mNetInfoMode = mode; | ||
685 | if(mNetInfoMode == NI_NET) | ||
686 | refreshNetInfo(TRUE); | ||
687 | childSetEnabled("send_to_message_builder_btn", mNetInfoMode == NI_LOG); | ||
688 | } | ||
689 | // static | ||
690 | void LLFloaterMessageLog::onLog(LLMessageLogEntry entry) | ||
691 | { | ||
692 | //don't mess with the queue while a filter's being applied, or face invalid iterators | ||
693 | if(!sBusyApplyingFilter) | ||
694 | { | ||
695 | sMessageLogEntries.push_back(entry); | ||
696 | conditionalLog(LLFloaterMessageLogItem(entry)); | ||
697 | } | ||
698 | } | ||
699 | // static | ||
700 | void LLFloaterMessageLog::conditionalLog(LLFloaterMessageLogItem item) | ||
701 | { | ||
702 | if(!sBusyApplyingFilter) | ||
703 | sInstance->childSetText("log_status_text", llformat("Showing %d messages from %d", sFloaterMessageLogItems.size(), sMessageLogEntries.size())); | ||
704 | std::string find_name = item.mName; | ||
705 | LLStringUtil::toLower(find_name); | ||
706 | if(sMessageLogFilter.mPositiveNames.size()) | ||
707 | if(std::find(sMessageLogFilter.mPositiveNames.begin(), sMessageLogFilter.mPositiveNames.end(), find_name) == sMessageLogFilter.mPositiveNames.end()) | ||
708 | return; | ||
709 | if(std::find(sMessageLogFilter.mNegativeNames.begin(), sMessageLogFilter.mNegativeNames.end(), find_name) != sMessageLogFilter.mNegativeNames.end()) | ||
710 | return; | ||
711 | sFloaterMessageLogItems.push_back(item); // moved from beginning... | ||
712 | BOOL outgoing = item.isOutgoing(); | ||
713 | std::string net_name("\?\?\?"); | ||
714 | if(item.mType == LLFloaterMessageLogItem::TEMPLATE) | ||
715 | { | ||
716 | LLHost find_host = outgoing ? item.mToHost : item.mFromHost; | ||
717 | net_name = find_host.getIPandPort(); | ||
718 | std::list<LLNetListItem*>::iterator end = sNetListItems.end(); | ||
719 | for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != end; ++iter) | ||
720 | { | ||
721 | if((*iter)->mCircuitData->getHost() == find_host) | ||
722 | { | ||
723 | net_name = (*iter)->mName; | ||
724 | break; | ||
725 | } | ||
726 | } | ||
727 | } | ||
728 | LLSD element; | ||
729 | element["id"] = item.mID; | ||
730 | LLSD& sequence_column = element["columns"][0]; | ||
731 | sequence_column["column"] = "sequence"; | ||
732 | sequence_column["value"] = llformat("%u", item.mSequenceID); | ||
733 | LLSD& type_column = element["columns"][1]; | ||
734 | type_column["column"] = "type"; | ||
735 | type_column["value"] = item.mType == LLFloaterMessageLogItem::TEMPLATE ? "UDP" : "\?\?\?"; | ||
736 | LLSD& direction_column = element["columns"][2]; | ||
737 | direction_column["column"] = "direction"; | ||
738 | direction_column["value"] = outgoing ? "to" : "from"; | ||
739 | LLSD& net_column = element["columns"][3]; | ||
740 | net_column["column"] = "net"; | ||
741 | net_column["value"] = net_name; | ||
742 | LLSD& name_column = element["columns"][4]; | ||
743 | name_column["column"] = "name"; | ||
744 | name_column["value"] = item.mName; | ||
745 | /* | ||
746 | LLSD& zer_column = element["columns"][5]; | ||
747 | zer_column["column"] = "flag_zer"; | ||
748 | zer_column["type"] = "icon"; | ||
749 | zer_column["value"] = (item.mFlags & LL_ZERO_CODE_FLAG) ? "flag_zer.tga" : ""; | ||
750 | LLSD& rel_column = element["columns"][6]; | ||
751 | rel_column["column"] = "flag_rel"; | ||
752 | rel_column["type"] = "icon"; | ||
753 | rel_column["value"] = (item.mFlags & LL_RELIABLE_FLAG) ? "flag_rel.tga" : ""; | ||
754 | LLSD& rsd_column = element["columns"][7]; | ||
755 | rsd_column["column"] = "flag_rsd"; | ||
756 | rsd_column["type"] = "icon"; | ||
757 | rsd_column["value"] = (item.mFlags & LL_RESENT_FLAG) ? "flag_rsd.tga" : ""; | ||
758 | LLSD& ack_column = element["columns"][8]; | ||
759 | ack_column["column"] = "flag_ack"; | ||
760 | ack_column["type"] = "icon"; | ||
761 | ack_column["value"] = (item.mFlags & LL_ACK_FLAG) ? "flag_ack.tga" : ""; | ||
762 | */ | ||
763 | LLSD& summary_column = element["columns"][5]; | ||
764 | summary_column["column"] = "summary"; | ||
765 | summary_column["value"] = item.mSummary; | ||
766 | LLScrollListCtrl* scrollp = sInstance->getChild<LLScrollListCtrl>("message_log"); | ||
767 | S32 scroll_pos = scrollp->getScrollPos(); | ||
768 | scrollp->addElement(element); | ||
769 | if(scroll_pos > scrollp->getItemCount() - scrollp->getPageLines() - 4) | ||
770 | scrollp->setScrollPos(scrollp->getItemCount()); | ||
771 | } | ||
772 | // static | ||
773 | void LLFloaterMessageLog::onCommitNetList(LLUICtrl* ctrl, void* user_data) | ||
774 | { | ||
775 | LLFloaterMessageLog* floaterp = (LLFloaterMessageLog*)user_data; | ||
776 | floaterp->setNetInfoMode(NI_NET); | ||
777 | floaterp->refreshNetInfo(TRUE); | ||
778 | } | ||
779 | // static | ||
780 | void LLFloaterMessageLog::onCommitMessageLog(LLUICtrl* ctrl, void* user_data) | ||
781 | { | ||
782 | LLFloaterMessageLog* floaterp = (LLFloaterMessageLog*)user_data; | ||
783 | LLScrollListCtrl* scrollp = floaterp->getChild<LLScrollListCtrl>("message_log"); | ||
784 | LLScrollListItem* selected_itemp = scrollp->getFirstSelected(); | ||
785 | if(!selected_itemp) return; | ||
786 | LLUUID id = selected_itemp->getUUID(); | ||
787 | std::vector<LLFloaterMessageLogItem>::iterator end = sFloaterMessageLogItems.end(); | ||
788 | for(std::vector<LLFloaterMessageLogItem>::iterator iter = sFloaterMessageLogItems.begin(); iter != end; ++iter) | ||
789 | { | ||
790 | if(iter->mID == id) | ||
791 | { | ||
792 | floaterp->setNetInfoMode(NI_LOG); | ||
793 | floaterp->childSetText("net_info", iter->getFull(FALSE)); | ||
794 | break; | ||
795 | } | ||
796 | } | ||
797 | } | ||
798 | // static | ||
799 | BOOL LLFloaterMessageLog::onClickCloseCircuit(void* user_data) | ||
800 | { | ||
801 | LLNetListItem* itemp = (LLNetListItem*)user_data; | ||
802 | LLCircuitData* cdp = (LLCircuitData*)itemp->mCircuitData; | ||
803 | if(!cdp) return FALSE; | ||
804 | LLHost myhost = cdp->getHost(); | ||
805 | LLSD args; | ||
806 | args["MESSAGE"] = "This will delete local circuit data.\nDo you want to tell the remote host to close the circuit too?"; | ||
807 | LLSD payload; | ||
808 | payload["circuittoclose"] = myhost.getString(); | ||
809 | LLNotifications::instance().add("GenericAlertYesCancel", args, payload, onConfirmCloseCircuit); | ||
810 | return TRUE; | ||
811 | } | ||
812 | // static | ||
813 | bool LLFloaterMessageLog::onConfirmCloseCircuit(const LLSD& notification, const LLSD& response ) | ||
814 | { | ||
815 | S32 option = LLNotification::getSelectedOption(notification, response); | ||
816 | LLCircuitData* cdp = gMessageSystem->mCircuitInfo.findCircuit(LLHost(notification["payload"]["circuittoclose"].asString())); | ||
817 | if(!cdp) return false; | ||
818 | LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(cdp->getHost()); | ||
819 | switch(option) | ||
820 | { | ||
821 | case 0: // yes | ||
822 | gMessageSystem->newMessageFast(_PREHASH_CloseCircuit); | ||
823 | gMessageSystem->sendReliable(cdp->getHost()); | ||
824 | break; | ||
825 | case 2: // cancel | ||
826 | return false; | ||
827 | break; | ||
828 | case 1: // no | ||
829 | default: | ||
830 | break; | ||
831 | } | ||
832 | if(gMessageSystem->findCircuitCode(cdp->getHost())) | ||
833 | gMessageSystem->disableCircuit(cdp->getHost()); | ||
834 | else | ||
835 | gMessageSystem->getCircuit()->removeCircuitData(cdp->getHost()); | ||
836 | if(regionp) | ||
837 | { | ||
838 | LLHost myhost = regionp->getHost(); | ||
839 | LLSD args; | ||
840 | args["MESSAGE"] = "That host had a region associated with it.\nDo you want to clean that up?"; | ||
841 | LLSD payload; | ||
842 | payload["regionhost"] = myhost.getString(); | ||
843 | LLNotifications::instance().add("GenericAlertYesCancel", args, payload, onConfirmRemoveRegion); | ||
844 | } | ||
845 | return false; | ||
846 | } | ||
847 | // static | ||
848 | bool LLFloaterMessageLog::onConfirmRemoveRegion(const LLSD& notification, const LLSD& response ) | ||
849 | { | ||
850 | S32 option = LLNotification::getSelectedOption(notification, response); | ||
851 | if(option == 0) // yes | ||
852 | LLWorld::getInstance()->removeRegion(LLHost(notification["payload"]["regionhost"].asString())); | ||
853 | return false; | ||
854 | } | ||
855 | // static | ||
856 | void LLFloaterMessageLog::onClickFilterApply(void* user_data) | ||
857 | { | ||
858 | LLFloaterMessageLog* floaterp = (LLFloaterMessageLog*)user_data; | ||
859 | floaterp->startApplyingFilter(floaterp->childGetValue("filter_edit"), FALSE); | ||
860 | } | ||
861 | void LLFloaterMessageLog::startApplyingFilter(std::string filter, BOOL force) | ||
862 | { | ||
863 | LLMessageLogFilter new_filter = LLMessageLogFilter(); | ||
864 | sMessageLogFilterString = filter; | ||
865 | new_filter.set(sMessageLogFilterString); | ||
866 | if(!filter.length() || filter.at(filter.length()-1) != ' ') | ||
867 | childSetText("filter_edit", filter + " "); | ||
868 | if(force | ||
869 | || (new_filter.mNegativeNames != sMessageLogFilter.mNegativeNames) | ||
870 | || (new_filter.mPositiveNames != sMessageLogFilter.mPositiveNames)) | ||
871 | { | ||
872 | stopApplyingFilter(); | ||
873 | sMessageLogFilter = new_filter; | ||
874 | sFloaterMessageLogItems.clear(); | ||
875 | getChild<LLScrollListCtrl>("message_log")->clearRows(); | ||
876 | sBusyApplyingFilter = TRUE; | ||
877 | childSetVisible("message_log", false); | ||
878 | //childSetVisible("log_status_text", true); | ||
879 | mMessageLogFilterApply = new LLMessageLogFilterApply(); | ||
880 | } | ||
881 | } | ||
882 | void LLFloaterMessageLog::stopApplyingFilter() | ||
883 | { | ||
884 | if(mMessageLogFilterApply) | ||
885 | { | ||
886 | if(!(mMessageLogFilterApply->mFinished)) | ||
887 | mMessageLogFilterApply->cancel(); | ||
888 | //delete mMessageLogFilterApply; | ||
889 | sBusyApplyingFilter = FALSE; | ||
890 | //childSetVisible("log_status_text", false); | ||
891 | childSetVisible("message_log", true); | ||
892 | childSetText("log_status_text", llformat("Showing %d messages from %d", sFloaterMessageLogItems.size(), sMessageLogEntries.size())); | ||
893 | } | ||
894 | } | ||
895 | void LLFloaterMessageLog::updateFilterStatus() | ||
896 | { | ||
897 | if(!mMessageLogFilterApply || !sBusyApplyingFilter) return; | ||
898 | S32 progress = mMessageLogFilterApply->mProgress; | ||
899 | S32 packets = sMessageLogEntries.size(); | ||
900 | S32 matches = sFloaterMessageLogItems.size(); | ||
901 | std::string text = llformat("Applying filter ( %d / %d ), %d matches ...", progress, packets, matches); | ||
902 | childSetText("log_status_text", text); | ||
903 | } | ||
904 | // static | ||
905 | void LLFloaterMessageLog::onCommitFilter(LLUICtrl* ctrl, void* user_data) | ||
906 | { | ||
907 | LLFloaterMessageLog* floaterp = (LLFloaterMessageLog*)user_data; | ||
908 | floaterp->startApplyingFilter(floaterp->childGetValue("filter_edit"), FALSE); | ||
909 | } | ||
910 | // static | ||
911 | void LLFloaterMessageLog::onClickClearLog(void* user_data) | ||
912 | { | ||
913 | LLFloaterMessageLog* floaterp = (LLFloaterMessageLog*)user_data; | ||
914 | floaterp->stopApplyingFilter(); | ||
915 | floaterp->getChild<LLScrollListCtrl>("message_log")->clearRows(); | ||
916 | floaterp->setNetInfoMode(NI_NET); | ||
917 | sMessageLogEntries.clear(); | ||
918 | sFloaterMessageLogItems.clear(); | ||
919 | } | ||
920 | // static | ||
921 | void LLFloaterMessageLog::onClickFilterChoice(void* user_data) | ||
922 | { | ||
923 | LLMenuGL* menu = new LLMenuGL(LLStringUtil::null); | ||
924 | menu->append(new LLMenuItemCallGL("No filter", onClickFilterMenu, NULL, (void*)"")); | ||
925 | menu->append(new LLMenuItemCallGL("Fewer spammy messages", onClickFilterMenu, NULL, (void*)"!StartPingCheck !CompletePingCheck !PacketAck !SimulatorViewerTimeMessage !SimStats !AgentUpdate !AgentAnimation !AvatarAnimation !ViewerEffect !CoarseLocationUpdate !LayerData !CameraConstraint !ObjectUpdateCached !RequestMultipleObjects !ObjectUpdate !ObjectUpdateCompressed !ImprovedTerseObjectUpdate !KillObject !ImagePacket !SendXferPacket !ConfirmXferPacket !TransferPacket")); | ||
926 | menu->append(new LLMenuItemCallGL("Fewer spammy messages (minus sound crap)", onClickFilterMenu, NULL, (void*)"!StartPingCheck !CompletePingCheck !PacketAck !SimulatorViewerTimeMessage !SimStats !AgentUpdate !AgentAnimation !AvatarAnimation !ViewerEffect !CoarseLocationUpdate !LayerData !CameraConstraint !ObjectUpdateCached !RequestMultipleObjects !ObjectUpdate !ObjectUpdateCompressed !ImprovedTerseObjectUpdate !KillObject !ImagePacket !SendXferPacket !ConfirmXferPacket !TransferPacket !SoundTrigger !AttachedSound !PreloadSound")); | ||
927 | menu->append(new LLMenuItemCallGL("Object updates", onClickFilterMenu, NULL, (void*)"ObjectUpdateCached ObjectUpdate ObjectUpdateCompressed ImprovedTerseObjectUpdate KillObject RequestMultipleObjects")); | ||
928 | menu->append(new LLMenuItemCallGL("Abnormal", onClickFilterMenu, NULL, (void*)"Invalid TestMessage AddCircuitCode NeighborList AvatarTextureUpdate SimulatorMapUpdate SimulatorSetMap SubscribeLoad UnsubscribeLoad SimulatorReady SimulatorPresentAtLocation SimulatorLoad SimulatorShutdownRequest RegionPresenceRequestByRegionID RegionPresenceRequestByHandle RegionPresenceResponse UpdateSimulator LogDwellTime FeatureDisabled LogFailedMoneyTransaction UserReportInternal SetSimStatusInDatabase SetSimPresenceInDatabase OpenCircuit CloseCircuit DirFindQueryBackend DirPlacesQueryBackend DirClassifiedQueryBackend DirLandQueryBackend DirPopularQueryBackend GroupNoticeAdd DataHomeLocationRequest DataHomeLocationReply DerezContainer ObjectCategory ObjectExportSelected StateSave ReportAutosaveCrash AgentAlertMessage NearestLandingRegionRequest NearestLandingRegionReply NearestLandingRegionUpdated TeleportLandingStatusChanged ConfirmEnableSimulator KickUserAck SystemKickUser AvatarPropertiesRequestBackend UpdateParcel RemoveParcel MergeParcel LogParcelChanges CheckParcelSales ParcelSales StartAuction ConfirmAuctionStart CompleteAuction CancelAuction CheckParcelAuctions ParcelAuctions ChatPass EdgeDataPacket SimStatus ChildAgentUpdate ChildAgentAlive ChildAgentPositionUpdate ChildAgentDying ChildAgentUnknown AtomicPassObject KillChildAgents ScriptSensorRequest ScriptSensorReply DataServerLogout RequestInventoryAsset InventoryAssetResponse TransferInventory TransferInventoryAck EventLocationRequest EventLocationReply MoneyTransferBackend RoutedMoneyBalanceReply SetStartLocation NetTest SetCPURatio SimCrashed NameValuePair RemoveNameValuePair UpdateAttachment RemoveAttachment EmailMessageRequest EmailMessageReply InternalScriptMail ScriptDataRequest ScriptDataReply InviteGroupResponse TallyVotes LiveHelpGroupRequest LiveHelpGroupReply GroupDataUpdate LogTextMessage CreateTrustedCircuit ParcelRename SystemMessage RpcChannelRequest RpcChannelReply RpcScriptRequestInbound RpcScriptRequestInboundForward RpcScriptReplyInbound ScriptMailRegistration Error")); | ||
929 | menu->updateParent(LLMenuGL::sMenuContainer); | ||
930 | menu->setCanTearOff(FALSE); | ||
931 | LLView* buttonp = sInstance->getChild<LLView>("filter_choice_btn"); | ||
932 | S32 x = buttonp->getRect().mLeft; | ||
933 | S32 y = buttonp->getRect().mBottom; | ||
934 | LLMenuGL::showPopup(sInstance, menu, x, y); | ||
935 | } | ||
936 | // static | ||
937 | void LLFloaterMessageLog::onClickFilterMenu(void* user_data) | ||
938 | { | ||
939 | std::string filter = std::string((char*)user_data); | ||
940 | sInstance->childSetText("filter_edit", filter); | ||
941 | sInstance->startApplyingFilter(filter, FALSE); | ||
942 | } | ||
943 | // static | ||
944 | void LLFloaterMessageLog::onClickSendToMessageBuilder(void* user_data) | ||
945 | { | ||
946 | LLFloaterMessageLog* floaterp = (LLFloaterMessageLog*)user_data; | ||
947 | LLScrollListCtrl* scrollp = floaterp->getChild<LLScrollListCtrl>("message_log"); | ||
948 | LLScrollListItem* selected_itemp = scrollp->getFirstSelected(); | ||
949 | if(!selected_itemp) return; | ||
950 | LLUUID id = selected_itemp->getUUID(); | ||
951 | std::vector<LLFloaterMessageLogItem>::iterator end = sFloaterMessageLogItems.end(); | ||
952 | for(std::vector<LLFloaterMessageLogItem>::iterator iter = sFloaterMessageLogItems.begin(); iter != end; ++iter) | ||
953 | { | ||
954 | if(iter->mID == id) | ||
955 | { | ||
956 | std::string message_text = iter->getFull(FALSE); | ||
957 | LLFloaterMessageBuilder::show(message_text); | ||
958 | break; | ||
959 | } | ||
960 | } | ||
961 | } | ||
962 | // </edit> | ||
diff --git a/linden/indra/newview/llfloatermessagelog.h b/linden/indra/newview/llfloatermessagelog.h new file mode 100644 index 0000000..ebc4f2a --- /dev/null +++ b/linden/indra/newview/llfloatermessagelog.h | |||
@@ -0,0 +1,84 @@ | |||
1 | // <edit> | ||
2 | #include "llfloater.h" | ||
3 | #include "llmessagelog.h" | ||
4 | #include "lltemplatemessagereader.h" | ||
5 | #include "llfloatermessagebuilder.h" | ||
6 | |||
7 | class LLFloaterMessageLogItem : public LLMessageLogEntry | ||
8 | { | ||
9 | public: | ||
10 | LLFloaterMessageLogItem(LLMessageLogEntry entry); | ||
11 | ~LLFloaterMessageLogItem(); | ||
12 | LLUUID mID; | ||
13 | U32 mSequenceID; | ||
14 | std::string mName; | ||
15 | std::string mSummary; | ||
16 | U32 mFlags; | ||
17 | std::string getFull(BOOL show_header = TRUE); | ||
18 | BOOL isOutgoing(); | ||
19 | private: | ||
20 | static LLTemplateMessageReader* sTemplateMessageReader; | ||
21 | static std::string getString(LLTemplateMessageReader* readerp, const char* block_name, S32 block_num, const char* var_name, e_message_variable_type var_type, BOOL &returned_hex, BOOL summary_mode = FALSE); | ||
22 | }; | ||
23 | class LLMessageLogFilter | ||
24 | { | ||
25 | public: | ||
26 | LLMessageLogFilter(); | ||
27 | ~LLMessageLogFilter(); | ||
28 | BOOL set(std::string filter); | ||
29 | std::list<std::string> mPositiveNames; | ||
30 | std::list<std::string> mNegativeNames; | ||
31 | }; | ||
32 | class LLMessageLogFilterApply : public LLEventTimer | ||
33 | { | ||
34 | public: | ||
35 | LLMessageLogFilterApply(); | ||
36 | void cancel(); | ||
37 | BOOL tick(); | ||
38 | S32 mProgress; | ||
39 | BOOL mFinished; | ||
40 | private: | ||
41 | std::deque<LLMessageLogEntry> mQueuedMessages; | ||
42 | std::deque<LLMessageLogEntry>::iterator mIter; | ||
43 | }; | ||
44 | class LLFloaterMessageLog : public LLFloater, public LLEventTimer | ||
45 | { | ||
46 | public: | ||
47 | LLFloaterMessageLog(); | ||
48 | ~LLFloaterMessageLog(); | ||
49 | static void show(); | ||
50 | BOOL postBuild(); | ||
51 | BOOL tick(); | ||
52 | LLNetListItem* findNetListItem(LLHost host); | ||
53 | LLNetListItem* findNetListItem(LLUUID id); | ||
54 | void refreshNetList(); | ||
55 | void refreshNetInfo(BOOL force); | ||
56 | enum ENetInfoMode { NI_NET, NI_LOG }; | ||
57 | void setNetInfoMode(ENetInfoMode mode); | ||
58 | static void onLog(LLMessageLogEntry entry); | ||
59 | static void conditionalLog(LLFloaterMessageLogItem item); | ||
60 | static void onCommitNetList(LLUICtrl* ctrl, void* user_data); | ||
61 | static void onCommitMessageLog(LLUICtrl* ctrl, void* user_data); | ||
62 | static void onCommitFilter(LLUICtrl* ctrl, void* user_data); | ||
63 | static BOOL onClickCloseCircuit(void* user_data); | ||
64 | static bool onConfirmCloseCircuit(const LLSD& notification, const LLSD& response ); | ||
65 | static bool onConfirmRemoveRegion(const LLSD& notification, const LLSD& response ); | ||
66 | static void onClickFilterApply(void* user_data); | ||
67 | void startApplyingFilter(std::string filter, BOOL force); | ||
68 | void stopApplyingFilter(); | ||
69 | void updateFilterStatus(); | ||
70 | static BOOL sBusyApplyingFilter; | ||
71 | LLMessageLogFilterApply* mMessageLogFilterApply; | ||
72 | static void onClickClearLog(void* user_data); | ||
73 | static LLFloaterMessageLog* sInstance; | ||
74 | static std::list<LLNetListItem*> sNetListItems; | ||
75 | static std::deque<LLMessageLogEntry> sMessageLogEntries; | ||
76 | static std::vector<LLFloaterMessageLogItem> sFloaterMessageLogItems; | ||
77 | static LLMessageLogFilter sMessageLogFilter; | ||
78 | static std::string sMessageLogFilterString; | ||
79 | ENetInfoMode mNetInfoMode; | ||
80 | static void onClickFilterChoice(void* user_data); | ||
81 | static void onClickFilterMenu(void* user_data); | ||
82 | static void onClickSendToMessageBuilder(void* user_data); | ||
83 | }; | ||
84 | // </edit> | ||
diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp index 524654a..3e502c0 100644 --- a/linden/indra/newview/llviewermenu.cpp +++ b/linden/indra/newview/llviewermenu.cpp | |||
@@ -121,6 +121,8 @@ | |||
121 | #include "llfloaterland.h" | 121 | #include "llfloaterland.h" |
122 | #include "llfloaterlandholdings.h" | 122 | #include "llfloaterlandholdings.h" |
123 | #include "llfloatermap.h" | 123 | #include "llfloatermap.h" |
124 | #include "llfloatermessagebuilder.h" | ||
125 | #include "llfloatermessagelog.h" | ||
124 | #include "llfloatermute.h" | 126 | #include "llfloatermute.h" |
125 | #include "llfloateropenobject.h" | 127 | #include "llfloateropenobject.h" |
126 | #include "llfloaterpermissionsmgr.h" | 128 | #include "llfloaterpermissionsmgr.h" |
@@ -394,6 +396,8 @@ void handle_god_mode(void*); | |||
394 | // God menu | 396 | // God menu |
395 | void handle_leave_god_mode(void*); | 397 | void handle_leave_god_mode(void*); |
396 | 398 | ||
399 | void handle_open_message_log(void*); | ||
400 | void handle_open_message_builder(void*); | ||
397 | BOOL is_inventory_visible( void* user_data ); | 401 | BOOL is_inventory_visible( void* user_data ); |
398 | void handle_reset_view(); | 402 | void handle_reset_view(); |
399 | 403 | ||
@@ -778,6 +782,11 @@ void init_client_menu(LLMenuGL* menu) | |||
778 | 782 | ||
779 | sub->appendSeparator(); | 783 | sub->appendSeparator(); |
780 | 784 | ||
785 | sub->append(new LLMenuItemCallGL( "Message Log", &handle_open_message_log, NULL)); | ||
786 | sub->append(new LLMenuItemCallGL( "Message Builder", &handle_open_message_builder, NULL)); | ||
787 | |||
788 | sub->appendSeparator(); | ||
789 | |||
781 | sub->append(new LLMenuItemCallGL("Region Info to Debug Console", | 790 | sub->append(new LLMenuItemCallGL("Region Info to Debug Console", |
782 | &handle_region_dump_settings, NULL)); | 791 | &handle_region_dump_settings, NULL)); |
783 | sub->append(new LLMenuItemCallGL("Group Info to Debug Console", | 792 | sub->append(new LLMenuItemCallGL("Group Info to Debug Console", |
@@ -3280,6 +3289,16 @@ void process_grant_godlike_powers(LLMessageSystem* msg, void**) | |||
3280 | } | 3289 | } |
3281 | } | 3290 | } |
3282 | 3291 | ||
3292 | |||
3293 | void handle_open_message_log(void*) | ||
3294 | { | ||
3295 | LLFloaterMessageLog::show(); | ||
3296 | } | ||
3297 | |||
3298 | void handle_open_message_builder(void*) | ||
3299 | { | ||
3300 | LLFloaterMessageBuilder::show(""); | ||
3301 | } | ||
3283 | /* | 3302 | /* |
3284 | class LLHaveCallingcard : public LLInventoryCollectFunctor | 3303 | class LLHaveCallingcard : public LLInventoryCollectFunctor |
3285 | { | 3304 | { |
@@ -8672,6 +8691,30 @@ class LLAdvancedDumpInfoToConsole : public view_listener_t | |||
8672 | 8691 | ||
8673 | 8692 | ||
8674 | 8693 | ||
8694 | ///////////////////////// | ||
8695 | // MESSAGE LOG/BUILDER // | ||
8696 | ///////////////////////// | ||
8697 | |||
8698 | |||
8699 | class LLMessageLogBuilder : public view_listener_t | ||
8700 | { | ||
8701 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | ||
8702 | { | ||
8703 | std::string info_type = userdata.asString(); | ||
8704 | if ("MessageLog" == info_type) | ||
8705 | { | ||
8706 | handle_open_message_log(NULL); | ||
8707 | } | ||
8708 | else if ("MessageBuilder" == info_type) | ||
8709 | { | ||
8710 | handle_open_message_builder(NULL); | ||
8711 | } | ||
8712 | return true; | ||
8713 | } | ||
8714 | }; | ||
8715 | |||
8716 | |||
8717 | |||
8675 | /////////////////////////////// | 8718 | /////////////////////////////// |
8676 | // RELOAD SETTINGS OVERRIDES // | 8719 | // RELOAD SETTINGS OVERRIDES // |
8677 | /////////////////////////////// | 8720 | /////////////////////////////// |
@@ -11260,6 +11303,8 @@ void initialize_menus() | |||
11260 | addMenu(new LLAdvancedToggleConsole(), "Advanced.ToggleConsole"); | 11303 | addMenu(new LLAdvancedToggleConsole(), "Advanced.ToggleConsole"); |
11261 | addMenu(new LLAdvancedCheckConsole(), "Advanced.CheckConsole"); | 11304 | addMenu(new LLAdvancedCheckConsole(), "Advanced.CheckConsole"); |
11262 | addMenu(new LLAdvancedDumpInfoToConsole(), "Advanced.DumpInfoToConsole"); | 11305 | addMenu(new LLAdvancedDumpInfoToConsole(), "Advanced.DumpInfoToConsole"); |
11306 | addMenu(new LLMessageLogBuilder(), "Advanced.MessageLog"); | ||
11307 | addMenu(new LLMessageLogBuilder(), "Advanced.MessageBuilder"); | ||
11263 | addMenu(new LLAdvancedReloadSettingsOverrides(), "Advanced.ReloadSettingsOverrides"); | 11308 | addMenu(new LLAdvancedReloadSettingsOverrides(), "Advanced.ReloadSettingsOverrides"); |
11264 | addMenu(new LLAdvancedToggleSit(), "Advanced.ToggleSit"); | 11309 | addMenu(new LLAdvancedToggleSit(), "Advanced.ToggleSit"); |
11265 | addMenu(new LLAdvancedCheckSit(), "Advanced.CheckSit"); | 11310 | addMenu(new LLAdvancedCheckSit(), "Advanced.CheckSit"); |
diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml b/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml index c85dd47..53e9e2d 100644 --- a/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml +++ b/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml | |||
@@ -908,6 +908,15 @@ | |||
908 | userdata="notifications" /> | 908 | userdata="notifications" /> |
909 | </menu_item_call> | 909 | </menu_item_call> |
910 | <menu_item_separator /> | 910 | <menu_item_separator /> |
911 | <menu_item_call name="Message Log" label="Message Log"> | ||
912 | <on_click function="Advanced.MessageLog" | ||
913 | userdata="MessageLog" /> | ||
914 | </menu_item_call> | ||
915 | <menu_item_call name="Message Builder" label="Message Builder"> | ||
916 | <on_click function="Advanced.MessageBuilder" | ||
917 | userdata="MessageBuilder" /> | ||
918 | </menu_item_call> | ||
919 | <menu_item_separator /> | ||
911 | <menu_item_call name="Region Info to Debug Console" | 920 | <menu_item_call name="Region Info to Debug Console" |
912 | label="Region Info to Debug Console"> | 921 | label="Region Info to Debug Console"> |
913 | <on_click function="Advanced.DumpInfoToConsole" | 922 | <on_click function="Advanced.DumpInfoToConsole" |