/indra/newview/llworldmapmessage.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 258 lines · 172 code · 35 blank · 51 comment · 12 complexity · e4c33778bffc46f0794032ef151188aa MD5 · raw file

  1. /**
  2. * @file llworldmapmessage.cpp
  3. * @brief Handling of the messages to the DB made by and for the world map.
  4. *
  5. * $LicenseInfo:firstyear=2003&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "llviewerprecompiledheaders.h"
  27. #include "llworldmapmessage.h"
  28. #include "message.h"
  29. #include "llworldmap.h"
  30. #include "llagent.h"
  31. #include "llfloaterworldmap.h"
  32. const U32 LAYER_FLAG = 2;
  33. //---------------------------------------------------------------------------
  34. // World Map Message Handling
  35. //---------------------------------------------------------------------------
  36. LLWorldMapMessage::LLWorldMapMessage() :
  37. mSLURLRegionName(),
  38. mSLURLRegionHandle(0),
  39. mSLURL(),
  40. mSLURLCallback(0),
  41. mSLURLTeleport(false)
  42. {
  43. }
  44. LLWorldMapMessage::~LLWorldMapMessage()
  45. {
  46. }
  47. void LLWorldMapMessage::sendItemRequest(U32 type, U64 handle)
  48. {
  49. //LL_INFOS("World Map") << "Send item request : type = " << type << LL_ENDL;
  50. LLMessageSystem* msg = gMessageSystem;
  51. msg->newMessageFast(_PREHASH_MapItemRequest);
  52. msg->nextBlockFast(_PREHASH_AgentData);
  53. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  54. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  55. msg->addU32Fast(_PREHASH_Flags, LAYER_FLAG);
  56. msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim
  57. msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim
  58. msg->nextBlockFast(_PREHASH_RequestData);
  59. msg->addU32Fast(_PREHASH_ItemType, type);
  60. msg->addU64Fast(_PREHASH_RegionHandle, handle); // If zero, filled in on sim
  61. gAgent.sendReliableMessage();
  62. }
  63. void LLWorldMapMessage::sendNamedRegionRequest(std::string region_name)
  64. {
  65. //LL_INFOS("World Map") << "LLWorldMap::sendNamedRegionRequest()" << LL_ENDL;
  66. LLMessageSystem* msg = gMessageSystem;
  67. // Request for region data
  68. msg->newMessageFast(_PREHASH_MapNameRequest);
  69. msg->nextBlockFast(_PREHASH_AgentData);
  70. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  71. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  72. msg->addU32Fast(_PREHASH_Flags, LAYER_FLAG);
  73. msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim
  74. msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim
  75. msg->nextBlockFast(_PREHASH_NameData);
  76. msg->addStringFast(_PREHASH_Name, region_name);
  77. gAgent.sendReliableMessage();
  78. }
  79. void LLWorldMapMessage::sendNamedRegionRequest(std::string region_name,
  80. url_callback_t callback,
  81. const std::string& callback_url,
  82. bool teleport) // immediately teleport when result returned
  83. {
  84. //LL_INFOS("World Map") << "LLWorldMap::sendNamedRegionRequest()" << LL_ENDL;
  85. mSLURLRegionName = region_name;
  86. mSLURLRegionHandle = 0;
  87. mSLURL = callback_url;
  88. mSLURLCallback = callback;
  89. mSLURLTeleport = teleport;
  90. sendNamedRegionRequest(region_name);
  91. }
  92. void LLWorldMapMessage::sendHandleRegionRequest(U64 region_handle,
  93. url_callback_t callback,
  94. const std::string& callback_url,
  95. bool teleport) // immediately teleport when result returned
  96. {
  97. //LL_INFOS("World Map") << "LLWorldMap::sendHandleRegionRequest()" << LL_ENDL;
  98. mSLURLRegionName.clear();
  99. mSLURLRegionHandle = region_handle;
  100. mSLURL = callback_url;
  101. mSLURLCallback = callback;
  102. mSLURLTeleport = teleport;
  103. U32 global_x;
  104. U32 global_y;
  105. from_region_handle(region_handle, &global_x, &global_y);
  106. U16 grid_x = (U16)(global_x / REGION_WIDTH_UNITS);
  107. U16 grid_y = (U16)(global_y / REGION_WIDTH_UNITS);
  108. sendMapBlockRequest(grid_x, grid_y, grid_x, grid_y, true);
  109. }
  110. void LLWorldMapMessage::sendMapBlockRequest(U16 min_x, U16 min_y, U16 max_x, U16 max_y, bool return_nonexistent)
  111. {
  112. //LL_INFOS("World Map") << "LLWorldMap::sendMapBlockRequest()" << ", min = (" << min_x << ", " << min_y << "), max = (" << max_x << ", " << max_y << "), nonexistent = " << return_nonexistent << LL_ENDL;
  113. LLMessageSystem* msg = gMessageSystem;
  114. msg->newMessageFast(_PREHASH_MapBlockRequest);
  115. msg->nextBlockFast(_PREHASH_AgentData);
  116. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  117. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  118. U32 flags = LAYER_FLAG;
  119. flags |= (return_nonexistent ? 0x10000 : 0);
  120. msg->addU32Fast(_PREHASH_Flags, flags);
  121. msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim
  122. msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim
  123. msg->nextBlockFast(_PREHASH_PositionData);
  124. msg->addU16Fast(_PREHASH_MinX, min_x);
  125. msg->addU16Fast(_PREHASH_MinY, min_y);
  126. msg->addU16Fast(_PREHASH_MaxX, max_x);
  127. msg->addU16Fast(_PREHASH_MaxY, max_y);
  128. gAgent.sendReliableMessage();
  129. }
  130. // public static
  131. void LLWorldMapMessage::processMapBlockReply(LLMessageSystem* msg, void**)
  132. {
  133. U32 agent_flags;
  134. msg->getU32Fast(_PREHASH_AgentData, _PREHASH_Flags, agent_flags);
  135. // There's only one flag that we ever use here
  136. if (agent_flags != LAYER_FLAG)
  137. {
  138. llwarns << "Invalid map image type returned! layer = " << agent_flags << llendl;
  139. return;
  140. }
  141. S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_Data);
  142. //LL_INFOS("World Map") << "LLWorldMap::processMapBlockReply(), num_blocks = " << num_blocks << LL_ENDL;
  143. bool found_null_sim = false;
  144. for (S32 block=0; block<num_blocks; ++block)
  145. {
  146. U16 x_regions;
  147. U16 y_regions;
  148. std::string name;
  149. U8 accesscode;
  150. U32 region_flags;
  151. // U8 water_height;
  152. // U8 agents;
  153. LLUUID image_id;
  154. msg->getU16Fast(_PREHASH_Data, _PREHASH_X, x_regions, block);
  155. msg->getU16Fast(_PREHASH_Data, _PREHASH_Y, y_regions, block);
  156. msg->getStringFast(_PREHASH_Data, _PREHASH_Name, name, block);
  157. msg->getU8Fast(_PREHASH_Data, _PREHASH_Access, accesscode, block);
  158. msg->getU32Fast(_PREHASH_Data, _PREHASH_RegionFlags, region_flags, block);
  159. // msg->getU8Fast(_PREHASH_Data, _PREHASH_WaterHeight, water_height, block);
  160. // msg->getU8Fast(_PREHASH_Data, _PREHASH_Agents, agents, block);
  161. msg->getUUIDFast(_PREHASH_Data, _PREHASH_MapImageID, image_id, block);
  162. U32 x_world = (U32)(x_regions) * REGION_WIDTH_UNITS;
  163. U32 y_world = (U32)(y_regions) * REGION_WIDTH_UNITS;
  164. // name shouldn't be empty, see EXT-4568
  165. llassert(!name.empty());
  166. // Insert that region in the world map, if failure, flag it as a "null_sim"
  167. if (!(LLWorldMap::getInstance()->insertRegion(x_world, y_world, name, image_id, (U32)accesscode, region_flags)))
  168. {
  169. found_null_sim = true;
  170. }
  171. // If we hit a valid tracking location, do what needs to be done app level wise
  172. if (LLWorldMap::getInstance()->isTrackingValidLocation())
  173. {
  174. LLVector3d pos_global = LLWorldMap::getInstance()->getTrackedPositionGlobal();
  175. if (LLWorldMap::getInstance()->isTrackingDoubleClick())
  176. {
  177. // Teleport if the user double clicked
  178. gAgent.teleportViaLocation(pos_global);
  179. }
  180. // Update the "real" tracker information
  181. gFloaterWorldMap->trackLocation(pos_global);
  182. }
  183. // Handle the SLURL callback if any
  184. url_callback_t callback = LLWorldMapMessage::getInstance()->mSLURLCallback;
  185. if(callback != NULL)
  186. {
  187. U64 handle = to_region_handle(x_world, y_world);
  188. // Check if we reached the requested region
  189. if ((LLStringUtil::compareInsensitive(LLWorldMapMessage::getInstance()->mSLURLRegionName, name)==0)
  190. || (LLWorldMapMessage::getInstance()->mSLURLRegionHandle == handle))
  191. {
  192. LLWorldMapMessage::getInstance()->mSLURLCallback = NULL;
  193. LLWorldMapMessage::getInstance()->mSLURLRegionName.clear();
  194. LLWorldMapMessage::getInstance()->mSLURLRegionHandle = 0;
  195. callback(handle, LLWorldMapMessage::getInstance()->mSLURL, image_id, LLWorldMapMessage::getInstance()->mSLURLTeleport);
  196. }
  197. }
  198. }
  199. // Tell the UI to update itself
  200. gFloaterWorldMap->updateSims(found_null_sim);
  201. }
  202. // public static
  203. void LLWorldMapMessage::processMapItemReply(LLMessageSystem* msg, void**)
  204. {
  205. //LL_INFOS("World Map") << "LLWorldMap::processMapItemReply()" << LL_ENDL;
  206. U32 type;
  207. msg->getU32Fast(_PREHASH_RequestData, _PREHASH_ItemType, type);
  208. S32 num_blocks = msg->getNumberOfBlocks("Data");
  209. for (S32 block=0; block<num_blocks; ++block)
  210. {
  211. U32 X, Y;
  212. std::string name;
  213. S32 extra, extra2;
  214. LLUUID uuid;
  215. msg->getU32Fast(_PREHASH_Data, _PREHASH_X, X, block);
  216. msg->getU32Fast(_PREHASH_Data, _PREHASH_Y, Y, block);
  217. msg->getStringFast(_PREHASH_Data, _PREHASH_Name, name, block);
  218. msg->getUUIDFast(_PREHASH_Data, _PREHASH_ID, uuid, block);
  219. msg->getS32Fast(_PREHASH_Data, _PREHASH_Extra, extra, block);
  220. msg->getS32Fast(_PREHASH_Data, _PREHASH_Extra2, extra2, block);
  221. LLWorldMap::getInstance()->insertItem(X, Y, name, uuid, type, extra, extra2);
  222. }
  223. }