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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llfloaterauction.cpp
  3.  * @author James Cook, Ian Wilkes
  4.  * @brief Implementation of the auction floater.
  5.  *
  6.  * $LicenseInfo:firstyear=2004&license=viewergpl$
  7.  * 
  8.  * Copyright (c) 2004-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 "llfloaterauction.h"
  35. #include "llfloaterregioninfo.h"
  36. #include "llgl.h"
  37. #include "llimagej2c.h"
  38. #include "llimagetga.h"
  39. #include "llparcel.h"
  40. #include "llvfile.h"
  41. #include "llvfs.h"
  42. #include "llwindow.h"
  43. #include "message.h"
  44. #include "llagent.h"
  45. #include "llcombobox.h"
  46. #include "llnotifications.h"
  47. #include "llnotificationsutil.h"
  48. #include "llsavedsettingsglue.h"
  49. #include "llviewertexturelist.h"
  50. #include "llviewerparcelmgr.h"
  51. #include "llviewerregion.h"
  52. #include "lluictrlfactory.h"
  53. #include "llviewerwindow.h"
  54. #include "llviewerdisplay.h"
  55. #include "llviewercontrol.h"
  56. #include "llui.h"
  57. #include "llrender.h"
  58. #include "llsdutil.h"
  59. #include "llsdutil_math.h"
  60. ///----------------------------------------------------------------------------
  61. /// Local function declarations, constants, enums, and typedefs
  62. ///----------------------------------------------------------------------------
  63. void auction_j2c_upload_done(const LLUUID& asset_id,
  64.    void* user_data, S32 status, LLExtStat ext_status);
  65. void auction_tga_upload_done(const LLUUID& asset_id,
  66.    void* user_data, S32 status, LLExtStat ext_status);
  67. ///----------------------------------------------------------------------------
  68. /// Class llfloaterauction
  69. ///----------------------------------------------------------------------------
  70. // Default constructor
  71. LLFloaterAuction::LLFloaterAuction(const LLSD& key)
  72.   : LLFloater(key),
  73. mParcelID(-1)
  74. {
  75. // LLUICtrlFactory::getInstance()->buildFloater(this, "floater_auction.xml");
  76. mCommitCallbackRegistrar.add("ClickSnapshot", boost::bind(&LLFloaterAuction::onClickSnapshot, this));
  77. mCommitCallbackRegistrar.add("ClickSellToAnyone", boost::bind(&LLFloaterAuction::onClickSellToAnyone, this));
  78. mCommitCallbackRegistrar.add("ClickStartAuction", boost::bind(&LLFloaterAuction::onClickStartAuction, this));
  79. mCommitCallbackRegistrar.add("ClickResetParcel", boost::bind(&LLFloaterAuction::onClickResetParcel, this));
  80. }
  81. // Destroys the object
  82. LLFloaterAuction::~LLFloaterAuction()
  83. {
  84. }
  85. BOOL LLFloaterAuction::postBuild()
  86. {
  87. return TRUE;
  88. }
  89. void LLFloaterAuction::onOpen(const LLSD& key)
  90. {
  91. initialize();
  92. }
  93. void LLFloaterAuction::initialize()
  94. {
  95. mParcelUpdateCapUrl.clear();
  96. mParcelp = LLViewerParcelMgr::getInstance()->getParcelSelection();
  97. LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
  98. LLParcel* parcelp = mParcelp->getParcel();
  99. if(parcelp && region && !parcelp->getForSale())
  100. {
  101. mParcelHost = region->getHost();
  102. mParcelID = parcelp->getLocalID();
  103. mParcelUpdateCapUrl = region->getCapability("ParcelPropertiesUpdate");
  104. childSetText("parcel_text", parcelp->getName());
  105. childEnable("snapshot_btn");
  106. childEnable("reset_parcel_btn");
  107. childEnable("start_auction_btn");
  108. LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate();
  109. if (panel)
  110. { // Only enable "Sell to Anyone" on Teen grid or if we don't know the ID yet
  111. U32 estate_id = panel->getEstateID();
  112. childSetEnabled("sell_to_anyone_btn", (estate_id == ESTATE_TEEN || estate_id == 0));
  113. }
  114. else
  115. { // Don't have the panel up, so don't know if we're on the teen grid or not.  Default to enabling it
  116. childEnable("sell_to_anyone_btn");
  117. }
  118. }
  119. else
  120. {
  121. mParcelHost.invalidate();
  122. if(parcelp && parcelp->getForSale())
  123. {
  124. childSetText("parcel_text", getString("already for sale"));
  125. }
  126. else
  127. {
  128. childSetText("parcel_text", LLStringUtil::null);
  129. }
  130. mParcelID = -1;
  131. childSetEnabled("snapshot_btn", false);
  132. childSetEnabled("reset_parcel_btn", false);
  133. childSetEnabled("sell_to_anyone_btn", false);
  134. childSetEnabled("start_auction_btn", false);
  135. }
  136. mImageID.setNull();
  137. mImage = NULL;
  138. }
  139. void LLFloaterAuction::draw()
  140. {
  141. LLFloater::draw();
  142. if(!isMinimized() && mImage.notNull()) 
  143. {
  144. LLRect rect;
  145. if (childGetRect("snapshot_icon", rect))
  146. {
  147. {
  148. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  149. gl_rect_2d(rect, LLColor4(0.f, 0.f, 0.f, 1.f));
  150. rect.stretch(-1);
  151. }
  152. {
  153. LLGLSUIDefault gls_ui;
  154. gGL.color3f(1.f, 1.f, 1.f);
  155. gl_draw_scaled_image(rect.mLeft,
  156.  rect.mBottom,
  157.  rect.getWidth(),
  158.  rect.getHeight(),
  159.  mImage);
  160. }
  161. }
  162. }
  163. }
  164. // static
  165. void LLFloaterAuction::onClickSnapshot(void* data)
  166. {
  167. LLFloaterAuction* self = (LLFloaterAuction*)(data);
  168. LLPointer<LLImageRaw> raw = new LLImageRaw;
  169. gForceRenderLandFence = self->childGetValue("fence_check").asBoolean();
  170. BOOL success = gViewerWindow->rawSnapshot(raw,
  171.   gViewerWindow->getWindowWidthScaled(),
  172.   gViewerWindow->getWindowHeightScaled(),
  173.   TRUE, FALSE,
  174.   FALSE, FALSE);
  175. gForceRenderLandFence = FALSE;
  176. if (success)
  177. {
  178. self->mTransactionID.generate();
  179. self->mImageID = self->mTransactionID.makeAssetID(gAgent.getSecureSessionID());
  180. if(!gSavedSettings.getBOOL("QuietSnapshotsToDisk"))
  181. {
  182. gViewerWindow->playSnapshotAnimAndSound();
  183. }
  184. llinfos << "Writing TGA..." << llendl;
  185. LLPointer<LLImageTGA> tga = new LLImageTGA;
  186. tga->encode(raw);
  187. LLVFile::writeFile(tga->getData(), tga->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_IMAGE_TGA);
  188. raw->biasedScaleToPowerOfTwo(LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT);
  189. llinfos << "Writing J2C..." << llendl;
  190. LLPointer<LLImageJ2C> j2c = new LLImageJ2C;
  191. j2c->encode(raw, 0.0f);
  192. LLVFile::writeFile(j2c->getData(), j2c->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_TEXTURE);
  193. self->mImage = LLViewerTextureManager::getLocalTexture((LLImageRaw*)raw, FALSE);
  194. gGL.getTexUnit(0)->bind(self->mImage);
  195. self->mImage->setAddressMode(LLTexUnit::TAM_CLAMP);
  196. }
  197. else
  198. {
  199. llwarns << "Unable to take snapshot" << llendl;
  200. }
  201. }
  202. // static
  203. void LLFloaterAuction::onClickStartAuction(void* data)
  204. {
  205. LLFloaterAuction* self = (LLFloaterAuction*)(data);
  206. if(self->mImageID.notNull())
  207. {
  208. LLSD parcel_name = self->childGetValue("parcel_text");
  209. // create the asset
  210. std::string* name = new std::string(parcel_name.asString());
  211. gAssetStorage->storeAssetData(self->mTransactionID, LLAssetType::AT_IMAGE_TGA,
  212. &auction_tga_upload_done,
  213. (void*)name,
  214. FALSE);
  215. self->getWindow()->incBusyCount();
  216. std::string* j2c_name = new std::string(parcel_name.asString());
  217. gAssetStorage->storeAssetData(self->mTransactionID, LLAssetType::AT_TEXTURE,
  218.    &auction_j2c_upload_done,
  219.    (void*)j2c_name,
  220.    FALSE);
  221. self->getWindow()->incBusyCount();
  222. LLNotificationsUtil::add("UploadingAuctionSnapshot");
  223. }
  224. LLMessageSystem* msg = gMessageSystem;
  225. msg->newMessage("ViewerStartAuction");
  226. msg->nextBlock("AgentData");
  227. msg->addUUID("AgentID", gAgent.getID());
  228. msg->addUUID("SessionID", gAgent.getSessionID());
  229. msg->nextBlock("ParcelData");
  230. msg->addS32("LocalID", self->mParcelID);
  231. msg->addUUID("SnapshotID", self->mImageID);
  232. msg->sendReliable(self->mParcelHost);
  233. // clean up floater, and get out
  234. self->cleanupAndClose();
  235. }
  236. void LLFloaterAuction::cleanupAndClose()
  237. {
  238. mImageID.setNull();
  239. mImage = NULL;
  240. mParcelID = -1;
  241. mParcelHost.invalidate();
  242. closeFloater();
  243. }
  244. // static glue
  245. void LLFloaterAuction::onClickResetParcel(void* data)
  246. {
  247. LLFloaterAuction* self = (LLFloaterAuction*)(data);
  248. if (self)
  249. {
  250. self->doResetParcel();
  251. }
  252. }
  253. // Reset all the values for the parcel in preparation for a sale
  254. void LLFloaterAuction::doResetParcel()
  255. {
  256. LLParcel* parcelp = mParcelp->getParcel();
  257. LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
  258. if (parcelp
  259. && region
  260. && !mParcelUpdateCapUrl.empty())
  261. {
  262. LLSD body;
  263. std::string empty;
  264. // request new properties update from simulator
  265. U32 message_flags = 0x01;
  266. body["flags"] = ll_sd_from_U32(message_flags);
  267. // Set all the default parcel properties for auction
  268. body["local_id"] = parcelp->getLocalID();
  269. U32 parcel_flags = PF_ALLOW_LANDMARK |
  270.    PF_ALLOW_FLY |
  271.    PF_CREATE_GROUP_OBJECTS |
  272.    PF_ALLOW_ALL_OBJECT_ENTRY |
  273.    PF_ALLOW_GROUP_OBJECT_ENTRY |
  274.    PF_ALLOW_GROUP_SCRIPTS |
  275.    PF_RESTRICT_PUSHOBJECT |
  276.    PF_SOUND_LOCAL |
  277.    PF_ALLOW_VOICE_CHAT |
  278.    PF_USE_ESTATE_VOICE_CHAN;
  279. body["parcel_flags"] = ll_sd_from_U32(parcel_flags);
  280. // Build a parcel name like "Ahern (128,128) PG 4032m"
  281. std::ostringstream parcel_name;
  282. LLVector3 center_point( parcelp->getCenterpoint() );
  283. center_point.snap(0); // Get rid of fractions
  284. parcel_name << region->getName() 
  285. << " ("
  286. << (S32) center_point.mV[VX]
  287. << ","
  288. << (S32) center_point.mV[VY]
  289. << ") "
  290. << region->getSimAccessString()
  291. << " "
  292. << parcelp->getArea()
  293. << "m";
  294. std::string new_name(parcel_name.str().c_str());
  295. body["name"] = new_name;
  296. childSetText("parcel_text", new_name); // Set name in dialog as well, since it won't get updated otherwise
  297. body["sale_price"] = (S32) 0;
  298. body["description"] = empty;
  299. body["music_url"] = empty;
  300. body["media_url"] = empty;
  301. body["media_desc"] = empty;
  302. body["media_type"] = std::string("none/none");
  303. body["media_width"] = (S32) 0;
  304. body["media_height"] = (S32) 0;
  305. body["auto_scale"] = (S32) 0;
  306. body["media_loop"] = (S32) 0;
  307. body["obscure_media"] = (S32) 0;
  308. body["obscure_music"] = (S32) 0;
  309. body["media_id"] = LLUUID::null;
  310. body["group_id"] = MAINTENANCE_GROUP_ID; // Use maintenance group
  311. body["pass_price"] = (S32) 10; // Defaults to $10
  312. body["pass_hours"] = 0.0f;
  313. body["category"] = (U8) LLParcel::C_NONE;
  314. body["auth_buyer_id"] = LLUUID::null;
  315. body["snapshot_id"] = LLUUID::null;
  316. body["user_location"] = ll_sd_from_vector3( LLVector3::zero );
  317. body["user_look_at"] = ll_sd_from_vector3( LLVector3::zero );
  318. body["landing_type"] = (U8) LLParcel::L_DIRECT;
  319. llinfos << "Sending parcel update to reset for auction via capability to: "
  320. << mParcelUpdateCapUrl << llendl;
  321. LLHTTPClient::post(mParcelUpdateCapUrl, body, new LLHTTPClient::Responder());
  322. // Send a message to clear the object return time
  323. LLMessageSystem *msg = gMessageSystem;
  324. msg->newMessageFast(_PREHASH_ParcelSetOtherCleanTime);
  325. msg->nextBlockFast(_PREHASH_AgentData);
  326. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  327. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  328. msg->nextBlockFast(_PREHASH_ParcelData);
  329. msg->addS32Fast(_PREHASH_LocalID, parcelp->getLocalID());
  330. msg->addS32Fast(_PREHASH_OtherCleanTime, 5); // 5 minute object auto-return
  331. msg->sendReliable(region->getHost());
  332. // Clear the access lists
  333. clearParcelAccessLists(parcelp, region);
  334. }
  335. }
  336. void LLFloaterAuction::clearParcelAccessLists(LLParcel* parcel, LLViewerRegion* region)
  337. {
  338. if (!region || !parcel) return;
  339. LLUUID transactionUUID;
  340. transactionUUID.generate();
  341. LLMessageSystem* msg = gMessageSystem;
  342. // Clear access list
  343. // parcel->mAccessList.clear();
  344. msg->newMessageFast(_PREHASH_ParcelAccessListUpdate);
  345. msg->nextBlockFast(_PREHASH_AgentData);
  346. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
  347. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
  348. msg->nextBlockFast(_PREHASH_Data);
  349. msg->addU32Fast(_PREHASH_Flags, AL_ACCESS);
  350. msg->addS32(_PREHASH_LocalID, parcel->getLocalID() );
  351. msg->addUUIDFast(_PREHASH_TransactionID, transactionUUID);
  352. msg->addS32Fast(_PREHASH_SequenceID, 1); // sequence_id
  353. msg->addS32Fast(_PREHASH_Sections, 0); // num_sections
  354. // pack an empty block since there will be no data
  355. msg->nextBlockFast(_PREHASH_List);
  356. msg->addUUIDFast(_PREHASH_ID,  LLUUID::null );
  357. msg->addS32Fast(_PREHASH_Time, 0 );
  358. msg->addU32Fast(_PREHASH_Flags, 0 );
  359. msg->sendReliable( region->getHost() );
  360. // Send message for empty ban list
  361. //parcel->mBanList.clear();
  362. msg->newMessageFast(_PREHASH_ParcelAccessListUpdate);
  363. msg->nextBlockFast(_PREHASH_AgentData);
  364. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
  365. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
  366. msg->nextBlockFast(_PREHASH_Data);
  367. msg->addU32Fast(_PREHASH_Flags, AL_BAN);
  368. msg->addS32(_PREHASH_LocalID, parcel->getLocalID() );
  369. msg->addUUIDFast(_PREHASH_TransactionID, transactionUUID);
  370. msg->addS32Fast(_PREHASH_SequenceID, 1); // sequence_id
  371. msg->addS32Fast(_PREHASH_Sections, 0); // num_sections
  372. // pack an empty block since there will be no data
  373. msg->nextBlockFast(_PREHASH_List);
  374. msg->addUUIDFast(_PREHASH_ID,  LLUUID::null );
  375. msg->addS32Fast(_PREHASH_Time, 0 );
  376. msg->addU32Fast(_PREHASH_Flags, 0 );
  377. msg->sendReliable( region->getHost() );
  378. }
  379. // static - 'Sell to Anyone' clicked, throw up a confirmation dialog
  380. void LLFloaterAuction::onClickSellToAnyone(void* data)
  381. {
  382. LLFloaterAuction* self = (LLFloaterAuction*)(data);
  383. if (self)
  384. {
  385. LLParcel* parcelp = self->mParcelp->getParcel();
  386. // Do a confirmation
  387. S32 sale_price = parcelp->getArea(); // Selling for L$1 per meter
  388. S32 area = parcelp->getArea();
  389. LLSD args;
  390. args["LAND_SIZE"] = llformat("%d", area);
  391. args["SALE_PRICE"] = llformat("%d", sale_price);
  392. args["NAME"] = "Anyone";
  393. LLNotification::Params params("ConfirmLandSaleChange"); // Re-use existing dialog
  394. params.substitutions(args)
  395. .functor.function(boost::bind(&LLFloaterAuction::onSellToAnyoneConfirmed, self, _1, _2));
  396. params.name("ConfirmLandSaleToAnyoneChange");
  397. // ask away
  398. LLNotifications::instance().add(params);
  399. }
  400. }
  401. // Sell confirmation clicked
  402. bool LLFloaterAuction::onSellToAnyoneConfirmed(const LLSD& notification, const LLSD& response)
  403. {
  404. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  405. if (option == 0)
  406. {
  407. doSellToAnyone();
  408. }
  409. return false;
  410. }
  411. // Reset all the values for the parcel in preparation for a sale
  412. void LLFloaterAuction::doSellToAnyone()
  413. {
  414. LLParcel* parcelp = mParcelp->getParcel();
  415. LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
  416. if (parcelp
  417. && region
  418. && !mParcelUpdateCapUrl.empty())
  419. {
  420. LLSD body;
  421. std::string empty;
  422. // request new properties update from simulator
  423. U32 message_flags = 0x01;
  424. body["flags"] = ll_sd_from_U32(message_flags);
  425. // Set all the default parcel properties for auction
  426. body["local_id"] = parcelp->getLocalID();
  427. // Set 'for sale' flag
  428. U32 parcel_flags = parcelp->getParcelFlags() | PF_FOR_SALE;
  429. // Ensure objects not included
  430. parcel_flags &= ~PF_FOR_SALE_OBJECTS;
  431. body["parcel_flags"] = ll_sd_from_U32(parcel_flags);
  432. body["sale_price"] = parcelp->getArea(); // Sell for L$1 per square meter
  433. body["auth_buyer_id"] = LLUUID::null; // To anyone
  434. llinfos << "Sending parcel update to sell to anyone for L$1 via capability to: "
  435. << mParcelUpdateCapUrl << llendl;
  436. LLHTTPClient::post(mParcelUpdateCapUrl, body, new LLHTTPClient::Responder());
  437. // clean up floater, and get out
  438. cleanupAndClose();
  439. }
  440. }
  441. ///----------------------------------------------------------------------------
  442. /// Local function definitions
  443. ///----------------------------------------------------------------------------
  444. void auction_tga_upload_done(const LLUUID& asset_id, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
  445. {
  446. std::string* name = (std::string*)(user_data);
  447. llinfos << "Upload of asset '" << *name << "' " << asset_id
  448. << " returned " << status << llendl;
  449. delete name;
  450. gViewerWindow->getWindow()->decBusyCount();
  451. if (0 == status)
  452. {
  453. LLNotificationsUtil::add("UploadWebSnapshotDone");
  454. }
  455. else
  456. {
  457. LLSD args;
  458. args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
  459. LLNotificationsUtil::add("UploadAuctionSnapshotFail", args);
  460. }
  461. }
  462. void auction_j2c_upload_done(const LLUUID& asset_id, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
  463. {
  464. std::string* name = (std::string*)(user_data);
  465. llinfos << "Upload of asset '" << *name << "' " << asset_id
  466. << " returned " << status << llendl;
  467. delete name;
  468. gViewerWindow->getWindow()->decBusyCount();
  469. if (0 == status)
  470. {
  471. LLNotificationsUtil::add("UploadSnapshotDone");
  472. }
  473. else
  474. {
  475. LLSD args;
  476. args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
  477. LLNotificationsUtil::add("UploadAuctionSnapshotFail", args);
  478. }
  479. }