lllandmarkactions.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:12k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2. * @file lllandmarkactions.cpp
  3. * @brief LLLandmarkActions class implementation
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewergpl$
  6. * Copyright (c) 2001-2010, Linden Research, Inc.
  7. * Second Life Viewer Source Code
  8. * The source code in this file ("Source Code") is provided by Linden Lab
  9. * to you under the terms of the GNU General Public License, version 2.0
  10. * ("GPL"), unless you have obtained a separate licensing agreement
  11. * ("Other License"), formally executed by you and Linden Lab.  Terms of
  12. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  13. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  14. * There are special exceptions to the terms and conditions of the GPL as
  15. * it is applied to this Source Code. View the full text of the exception
  16. * in the file doc/FLOSS-exception.txt in this software distribution, or
  17. * online at
  18. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  19. * By copying, modifying or distributing this software, you acknowledge
  20. * that you have read and understood your obligations described above,
  21. * and agree to abide by those obligations.
  22. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  23. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  24. * COMPLETENESS OR PERFORMANCE.
  25. * $/LicenseInfo$
  26. */
  27. #include "llviewerprecompiledheaders.h"
  28. #include "lllandmarkactions.h"
  29. #include "roles_constants.h"
  30. #include "llinventory.h"
  31. #include "lllandmark.h"
  32. #include "llparcel.h"
  33. #include "llregionhandle.h"
  34. #include "llnotificationsutil.h"
  35. #include "llagent.h"
  36. #include "llagentui.h"
  37. #include "llinventorymodel.h"
  38. #include "lllandmarklist.h"
  39. #include "llslurl.h"
  40. #include "llstring.h"
  41. #include "llviewerinventory.h"
  42. #include "llviewerparcelmgr.h"
  43. #include "llworldmapmessage.h"
  44. #include "llviewerwindow.h"
  45. #include "llwindow.h"
  46. #include "llworldmap.h"
  47. void copy_slurl_to_clipboard_callback(const std::string& slurl);
  48. class LLFetchlLandmarkByPos : public LLInventoryCollectFunctor
  49. {
  50. private:
  51. LLVector3d mPos;
  52. public:
  53. LLFetchlLandmarkByPos(const LLVector3d& pos) :
  54. mPos(pos)
  55. {}
  56. /*virtual*/ bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
  57. {
  58. if (!item || item->getType() != LLAssetType::AT_LANDMARK)
  59. return false;
  60. LLLandmark* landmark = gLandmarkList.getAsset(item->getAssetUUID());
  61. if (!landmark) // the landmark not been loaded yet
  62. return false;
  63. LLVector3d landmark_global_pos;
  64. if (!landmark->getGlobalPos(landmark_global_pos))
  65. return false;
  66. //we have to round off each coordinates to compare positions properly
  67. return llround(mPos.mdV[VX]) ==  llround(landmark_global_pos.mdV[VX])
  68. && llround(mPos.mdV[VY]) ==  llround(landmark_global_pos.mdV[VY])
  69. && llround(mPos.mdV[VZ]) ==  llround(landmark_global_pos.mdV[VZ]);
  70. }
  71. };
  72. class LLFetchLandmarksByName : public LLInventoryCollectFunctor
  73. {
  74. private:
  75. std::string name;
  76. BOOL use_substring;
  77. //this member will be contain copy of founded items to keep the result unique
  78. std::set<std::string> check_duplicate;
  79. public:
  80. LLFetchLandmarksByName(std::string &landmark_name, BOOL if_use_substring)
  81. :name(landmark_name),
  82. use_substring(if_use_substring)
  83. {
  84. LLStringUtil::toLower(name);
  85. }
  86. public:
  87. /*virtual*/ bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
  88. {
  89. if (!item || item->getType() != LLAssetType::AT_LANDMARK)
  90. return false;
  91. LLLandmark* landmark = gLandmarkList.getAsset(item->getAssetUUID());
  92. if (!landmark) // the landmark not been loaded yet
  93. return false;
  94. bool acceptable = false;
  95. std::string landmark_name = item->getName();
  96. LLStringUtil::toLower(landmark_name);
  97. if(use_substring)
  98. {
  99. acceptable =  landmark_name.find( name ) != std::string::npos;
  100. }
  101. else
  102. {
  103. acceptable = landmark_name == name;
  104. }
  105. if(acceptable){
  106. if(check_duplicate.find(landmark_name) != check_duplicate.end()){
  107. // we have duplicated items in landmarks
  108. acceptable = false;
  109. }else{
  110. check_duplicate.insert(landmark_name);
  111. }
  112. }
  113. return acceptable;
  114. }
  115. };
  116. // Returns true if the given inventory item is a landmark pointing to the current parcel.
  117. // Used to find out if there is at least one landmark from current parcel.
  118. class LLFirstAgentParcelLandmark : public LLInventoryCollectFunctor
  119. {
  120. private:
  121. bool mFounded;// to avoid unnecessary  check
  122. public:
  123. LLFirstAgentParcelLandmark(): mFounded(false){}
  124. /*virtual*/ bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
  125. {
  126. if (mFounded || !item || item->getType() != LLAssetType::AT_LANDMARK)
  127. return false;
  128. LLLandmark* landmark = gLandmarkList.getAsset(item->getAssetUUID());
  129. if (!landmark) // the landmark not been loaded yet
  130. return false;
  131. LLVector3d landmark_global_pos;
  132. if (!landmark->getGlobalPos(landmark_global_pos))
  133. return false;
  134. mFounded = LLViewerParcelMgr::getInstance()->inAgentParcel(landmark_global_pos);
  135. return mFounded;
  136. }
  137. };
  138. static void fetch_landmarks(LLInventoryModel::cat_array_t& cats,
  139. LLInventoryModel::item_array_t& items,
  140. LLInventoryCollectFunctor& add)
  141. {
  142. // Look in "My Favorites"
  143. const LLUUID favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
  144. gInventory.collectDescendentsIf(favorites_folder_id,
  145. cats,
  146. items,
  147. LLInventoryModel::EXCLUDE_TRASH,
  148. add);
  149. // Look in "Landmarks"
  150. const LLUUID landmarks_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
  151. gInventory.collectDescendentsIf(landmarks_folder_id,
  152. cats,
  153. items,
  154. LLInventoryModel::EXCLUDE_TRASH,
  155. add);
  156. }
  157. LLInventoryModel::item_array_t LLLandmarkActions::fetchLandmarksByName(std::string& name, BOOL use_substring)
  158. {
  159. LLInventoryModel::cat_array_t cats;
  160. LLInventoryModel::item_array_t items;
  161. LLFetchLandmarksByName by_name(name, use_substring);
  162. fetch_landmarks(cats, items, by_name);
  163. return items;
  164. }
  165. bool LLLandmarkActions::landmarkAlreadyExists()
  166. {
  167. // Determine whether there are landmarks pointing to the current global  agent position.
  168. return findLandmarkForAgentPos() != NULL;
  169. }
  170. //static
  171. bool LLLandmarkActions::hasParcelLandmark()
  172. {
  173. LLFirstAgentParcelLandmark get_first_agent_landmark;
  174. LLInventoryModel::cat_array_t cats;
  175. LLInventoryModel::item_array_t items;
  176. fetch_landmarks(cats, items, get_first_agent_landmark);
  177. return !items.empty();
  178. }
  179. // *TODO: This could be made more efficient by only fetching the FIRST
  180. // landmark that meets the criteria
  181. LLViewerInventoryItem* LLLandmarkActions::findLandmarkForGlobalPos(const LLVector3d &pos)
  182. {
  183. // Determine whether there are landmarks pointing to the current parcel.
  184. LLInventoryModel::cat_array_t cats;
  185. LLInventoryModel::item_array_t items;
  186. LLFetchlLandmarkByPos is_current_pos_landmark(pos);
  187. fetch_landmarks(cats, items, is_current_pos_landmark);
  188. if(items.empty())
  189. {
  190. return NULL;
  191. }
  192. return items[0];
  193. }
  194. LLViewerInventoryItem* LLLandmarkActions::findLandmarkForAgentPos()
  195. {
  196. return findLandmarkForGlobalPos(gAgent.getPositionGlobal());
  197. }
  198. bool LLLandmarkActions::canCreateLandmarkHere()
  199. {
  200. LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
  201. if(!agent_parcel)
  202. {
  203. llwarns << "No agent region" << llendl;
  204. return false;
  205. }
  206. if (agent_parcel->getAllowLandmark()
  207. || LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK))
  208. {
  209. return true;
  210. }
  211. return false;
  212. }
  213. void LLLandmarkActions::createLandmarkHere(
  214. const std::string& name, 
  215. const std::string& desc, 
  216. const LLUUID& folder_id)
  217. {
  218. if(!gAgent.getRegion())
  219. {
  220. llwarns << "No agent region" << llendl;
  221. return;
  222. }
  223. LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
  224. if (!agent_parcel)
  225. {
  226. llwarns << "No agent parcel" << llendl;
  227. return;
  228. }
  229. if (!canCreateLandmarkHere())
  230. {
  231. LLNotificationsUtil::add("CannotCreateLandmarkNotOwner");
  232. return;
  233. }
  234. create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
  235. folder_id, LLTransactionID::tnull,
  236. name, desc,
  237. LLAssetType::AT_LANDMARK,
  238. LLInventoryType::IT_LANDMARK,
  239. NOT_WEARABLE, PERM_ALL, 
  240. NULL);
  241. }
  242. void LLLandmarkActions::createLandmarkHere()
  243. {
  244. std::string landmark_name, landmark_desc;
  245. LLAgentUI::buildLocationString(landmark_name, LLAgentUI::LOCATION_FORMAT_LANDMARK);
  246. LLAgentUI::buildLocationString(landmark_desc, LLAgentUI::LOCATION_FORMAT_FULL);
  247. const LLUUID folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
  248. createLandmarkHere(landmark_name, landmark_desc, folder_id);
  249. }
  250. void LLLandmarkActions::getSLURLfromPosGlobal(const LLVector3d& global_pos, slurl_callback_t cb, bool escaped /* = true */)
  251. {
  252. std::string sim_name;
  253. bool gotSimName = LLWorldMap::getInstance()->simNameFromPosGlobal(global_pos, sim_name);
  254. if (gotSimName)
  255. {
  256. std::string slurl = LLSLURL::buildSLURLfromPosGlobal(sim_name, global_pos, escaped);
  257. cb(slurl);
  258. return;
  259. }
  260. else
  261. {
  262. U64 new_region_handle = to_region_handle(global_pos);
  263. LLWorldMapMessage::url_callback_t url_cb = boost::bind(&LLLandmarkActions::onRegionResponseSLURL,
  264. cb,
  265. global_pos,
  266. escaped,
  267. _2);
  268. LLWorldMapMessage::getInstance()->sendHandleRegionRequest(new_region_handle, url_cb, std::string("unused"), false);
  269. }
  270. }
  271. void LLLandmarkActions::getRegionNameAndCoordsFromPosGlobal(const LLVector3d& global_pos, region_name_and_coords_callback_t cb)
  272. {
  273. std::string sim_name;
  274. LLSimInfo* sim_infop = LLWorldMap::getInstance()->simInfoFromPosGlobal(global_pos);
  275. if (sim_infop)
  276. {
  277. LLVector3 pos = sim_infop->getLocalPos(global_pos);
  278. std::string name = sim_infop->getName() ;
  279. cb(name, llround(pos.mV[VX]), llround(pos.mV[VY]),llround(pos.mV[VZ]));
  280. }
  281. else
  282. {
  283. U64 new_region_handle = to_region_handle(global_pos);
  284. LLWorldMapMessage::url_callback_t url_cb = boost::bind(&LLLandmarkActions::onRegionResponseNameAndCoords,
  285. cb,
  286. global_pos,
  287. _1);
  288. LLWorldMapMessage::getInstance()->sendHandleRegionRequest(new_region_handle, url_cb, std::string("unused"), false);
  289. }
  290. }
  291. void LLLandmarkActions::onRegionResponseSLURL(slurl_callback_t cb,
  292.  const LLVector3d& global_pos,
  293.  bool escaped,
  294.  const std::string& url)
  295. {
  296. std::string sim_name;
  297. std::string slurl;
  298. bool gotSimName = LLWorldMap::getInstance()->simNameFromPosGlobal(global_pos, sim_name);
  299. if (gotSimName)
  300. {
  301. slurl = LLSLURL::buildSLURLfromPosGlobal(sim_name, global_pos, escaped);
  302. }
  303. else
  304. {
  305. slurl = "";
  306. }
  307. cb(slurl);
  308. }
  309. void LLLandmarkActions::onRegionResponseNameAndCoords(region_name_and_coords_callback_t cb,
  310.  const LLVector3d& global_pos,
  311.  U64 region_handle)
  312. {
  313. LLSimInfo* sim_infop = LLWorldMap::getInstance()->simInfoFromHandle(region_handle);
  314. if (sim_infop)
  315. {
  316. LLVector3 local_pos = sim_infop->getLocalPos(global_pos);
  317. std::string name = sim_infop->getName() ;
  318. cb(name, llround(local_pos.mV[VX]), llround(local_pos.mV[VY]), llround(local_pos.mV[VZ]));
  319. }
  320. }
  321. bool LLLandmarkActions::getLandmarkGlobalPos(const LLUUID& landmarkInventoryItemID, LLVector3d& posGlobal)
  322. {
  323. LLViewerInventoryItem* item = gInventory.getItem(landmarkInventoryItemID);
  324. if (NULL == item)
  325. return false;
  326. const LLUUID& asset_id = item->getAssetUUID();
  327. LLLandmark* landmark = gLandmarkList.getAsset(asset_id, NULL);
  328. if (NULL == landmark)
  329. return false;
  330. return landmark->getGlobalPos(posGlobal);
  331. }
  332. LLLandmark* LLLandmarkActions::getLandmark(const LLUUID& landmarkInventoryItemID, LLLandmarkList::loaded_callback_t cb)
  333. {
  334. LLViewerInventoryItem* item = gInventory.getItem(landmarkInventoryItemID);
  335. if (NULL == item)
  336. return NULL;
  337. const LLUUID& asset_id = item->getAssetUUID();
  338. LLLandmark* landmark = gLandmarkList.getAsset(asset_id, cb);
  339. if (landmark)
  340. {
  341. return landmark;
  342. }
  343. return NULL;
  344. }
  345. void LLLandmarkActions::copySLURLtoClipboard(const LLUUID& landmarkInventoryItemID)
  346. {
  347. LLLandmark* landmark = LLLandmarkActions::getLandmark(landmarkInventoryItemID);
  348. if(landmark)
  349. {
  350. LLVector3d global_pos;
  351. landmark->getGlobalPos(global_pos);
  352. LLLandmarkActions::getSLURLfromPosGlobal(global_pos,&copy_slurl_to_clipboard_callback,true);
  353. }
  354. }
  355. void copy_slurl_to_clipboard_callback(const std::string& slurl)
  356. {
  357. gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(slurl));
  358. LLSD args;
  359. args["SLURL"] = slurl;
  360. LLNotificationsUtil::add("CopySLURL", args);
  361. }