llfloaterregiondebugconsole.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /**
  2. * @file llfloaterregiondebugconsole.h
  3. * @author Brad Kittenbrink <[email protected]>
  4. * @brief Quick and dirty console for region debug settings
  5. *
  6. * $LicenseInfo:firstyear=2010&license=viewergpl$
  7. *
  8. * Copyright (c) 2010-2010, Linden Research, Inc.
  9. *
  10. * Second Life Viewer Source Code
  11. * The source code in this file ("Source Code") is provided by Linden Lab
  12. * to you under the terms of the GNU General Public License, version 2.0
  13. * ("GPL"), unless you have obtained a separate licensing agreement
  14. * ("Other License"), formally executed by you and Linden Lab. Terms of
  15. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  16. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  17. *
  18. * There are special exceptions to the terms and conditions of the GPL as
  19. * it is applied to this Source Code. View the full text of the exception
  20. * in the file doc/FLOSS-exception.txt in this software distribution, or
  21. * online at
  22. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  23. *
  24. * By copying, modifying or distributing this software, you acknowledge
  25. * that you have read and understood your obligations described above,
  26. * and agree to abide by those obligations.
  27. *
  28. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  29. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  30. * COMPLETENESS OR PERFORMANCE.
  31. * $/LicenseInfo$
  32. */
  33. #include "llviewerprecompiledheaders.h"
  34. #include "llfloaterregiondebugconsole.h"
  35. #include "llcorehttputil.h"
  36. #include "llhttpnode.h"
  37. #include "lllineeditor.h"
  38. #include "lltexteditor.h"
  39. #include "lluictrlfactory.h"
  40. #include "llagent.h"
  41. // Two versions of the sim console API are supported.
  42. //
  43. // SimConsole capability (deprecated):
  44. // This is the initial implementation that is supported by some versions of the
  45. // simulator. It is simple and straight forward, just POST a command and the
  46. // body of the response has the result. This API is deprecated because it
  47. // doesn't allow the sim to use any asynchronous API.
  48. //
  49. // SimConsoleAsync capability:
  50. // This capability replaces the original SimConsole capability. It is similar
  51. // in that the command is POSTed to the SimConsoleAsync cap, but the response
  52. // comes in through the event poll, which gives the simulator more flexibility
  53. // and allows it to perform complex operations without blocking any frames.
  54. //
  55. // We will assume the SimConsoleAsync capability is available, and fall back to
  56. // the SimConsole cap if it is not. The simulator will only support one or the
  57. // other.
  58. const std::string PROMPT = "\n\n> ";
  59. const std::string UNABLE_TO_SEND_COMMAND = "\nERROR: The last command was not received by the server.";
  60. const std::string CONSOLE_UNAVAILABLE = "\nERROR: No console available for this region/simulator.";
  61. const std::string CONSOLE_NOT_SUPPORTED = "\nThis region does not support the simulator console.";
  62. // This handles responses for console commands sent via the asynchronous API.
  63. class ConsoleResponseNode final : public LLHTTPNode
  64. {
  65. protected:
  66. LOG_CLASS(ConsoleResponseNode);
  67. public:
  68. void post(LLHTTPNode::ResponsePtr reponse, const LLSD& context,
  69. const LLSD& input) const override
  70. {
  71. llinfos << "Received response from the debug console: " << input
  72. << llendl;
  73. LLFloaterRegionDebugConsole::onReplyReceived(input["body"].asString());
  74. }
  75. };
  76. LLFloaterRegionDebugConsole::LLFloaterRegionDebugConsole(const LLSD&)
  77. {
  78. LLUICtrlFactory::getInstance()->buildFloater(this,
  79. "floater_region_debug_console.xml");
  80. }
  81. bool LLFloaterRegionDebugConsole::postBuild()
  82. {
  83. LLLineEditor* input = getChild<LLLineEditor>("region_debug_console_input");
  84. input->setEnableLineHistory(true);
  85. input->setCommitCallback(onInput);
  86. input->setCallbackUserData(this);
  87. input->setFocus(true);
  88. input->setCommitOnFocusLost(false);
  89. mOutput = getChild<LLTextEditor>("region_debug_console_output");
  90. mUseNewCap = !gAgent.getRegionCapability("SimConsoleAsync").empty();
  91. if (!mUseNewCap && gAgent.getRegionCapability("SimConsole").empty())
  92. {
  93. mOutput->appendText(CONSOLE_NOT_SUPPORTED + PROMPT, false, false);
  94. }
  95. else
  96. {
  97. mOutput->appendText("Type \"help\" for the list of commands.\n\n> ",
  98. false, false);
  99. }
  100. return true;
  101. }
  102. //static
  103. void LLFloaterRegionDebugConsole::onInput(LLUICtrl* ctrl, void* userdata)
  104. {
  105. LLFloaterRegionDebugConsole* self = (LLFloaterRegionDebugConsole*)userdata;
  106. LLLineEditor* input = (LLLineEditor*)ctrl;
  107. if (!self || !input) return;
  108. std::string text = input->getText() + "\n";
  109. LLSD body = LLSD(input->getText());
  110. const std::string& url =
  111. self->mUseNewCap ? gAgent.getRegionCapability("SimConsoleAsync")
  112. : gAgent.getRegionCapability("SimConsole");
  113. if (url.empty())
  114. {
  115. text += CONSOLE_UNAVAILABLE + PROMPT;
  116. }
  117. else if (self->mUseNewCap)
  118. {
  119. // Using SimConsoleAsync
  120. LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, body,
  121. NULL,
  122. onConsoleError);
  123. }
  124. else
  125. {
  126. // Using SimConsole (deprecated)
  127. LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, body,
  128. onConsoleSuccess,
  129. onConsoleError);
  130. }
  131. self->mOutput->appendText(text, false, false);
  132. input->clear();
  133. }
  134. //static
  135. void LLFloaterRegionDebugConsole::onConsoleSuccess(const LLSD& result)
  136. {
  137. LLSD content = result;
  138. if (result.isMap() &&
  139. result.has(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT))
  140. {
  141. content = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT];
  142. }
  143. onReplyReceived(content.asString());
  144. }
  145. //static
  146. void LLFloaterRegionDebugConsole::onConsoleError(const LLSD& result)
  147. {
  148. llwarns << result << llendl;
  149. onReplyReceived(UNABLE_TO_SEND_COMMAND);
  150. }
  151. //static
  152. void LLFloaterRegionDebugConsole::onReplyReceived(const std::string& output)
  153. {
  154. LLFloaterRegionDebugConsole* self = findInstance();
  155. if (self)
  156. {
  157. self->mOutput->appendText(output + PROMPT, false, false);
  158. }
  159. }
  160. LLHTTPRegistration<ConsoleResponseNode>
  161. gHTTPRegistrationMessageDebugConsoleResponse("/message/SimConsoleResponse");