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

游戏引擎

开发平台:

C++ Builder

  1. LLUUID agent_id;
  2. msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
  3. LLUUID session_id;
  4. msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_SessionID, session_id);
  5. if((gAgent.getID() != agent_id) || (gAgent.getSessionID() != session_id))
  6. {
  7. LL_WARNS("Messaging") << "Incorrect id in process_agent_movement_complete()"
  8. << LL_ENDL;
  9. return;
  10. }
  11. LL_DEBUGS("Messaging") << "process_agent_movement_complete()" << LL_ENDL;
  12. // *TODO: check timestamp to make sure the movement compleation
  13. // makes sense.
  14. LLVector3 agent_pos;
  15. msg->getVector3Fast(_PREHASH_Data, _PREHASH_Position, agent_pos);
  16. LLVector3 look_at;
  17. msg->getVector3Fast(_PREHASH_Data, _PREHASH_LookAt, look_at);
  18. U64 region_handle;
  19. msg->getU64Fast(_PREHASH_Data, _PREHASH_RegionHandle, region_handle);
  20. std::string version_channel;
  21. msg->getString("SimData", "ChannelVersion", version_channel);
  22. LLVOAvatar* avatarp = gAgent.getAvatarObject();
  23. if (!avatarp)
  24. {
  25. // Could happen if you were immediately god-teleported away on login,
  26. // maybe other cases.  Continue, but warn.
  27. LL_WARNS("Messaging") << "agent_movement_complete() with NULL avatarp." << LL_ENDL;
  28. }
  29. F32 x, y;
  30. from_region_handle(region_handle, &x, &y);
  31. LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle);
  32. if (!regionp)
  33. {
  34. if (gAgent.getRegion())
  35. {
  36. LL_WARNS("Messaging") << "current region " << gAgent.getRegion()->getOriginGlobal() << LL_ENDL;
  37. }
  38. LL_WARNS("Messaging") << "Agent being sent to invalid home region: " 
  39. << x << ":" << y 
  40. << " current pos " << gAgent.getPositionGlobal()
  41. << LL_ENDL;
  42. LLAppViewer::instance()->forceDisconnect("You were sent to an invalid region.");
  43. return;
  44. }
  45. LL_INFOS("Messaging") << "Changing home region to " << x << ":" << y << LL_ENDL;
  46. // set our upstream host the new simulator and shuffle things as
  47. // appropriate.
  48. LLVector3 shift_vector = regionp->getPosRegionFromGlobal(
  49. gAgent.getRegion()->getOriginGlobal());
  50. gAgent.setRegion(regionp);
  51. gObjectList.shiftObjects(shift_vector);
  52. gAssetStorage->setUpstream(msg->getSender());
  53. gCacheName->setUpstream(msg->getSender());
  54. gViewerThrottle.sendToSim();
  55. gViewerWindow->sendShapeToSim();
  56. bool is_teleport = gAgent.getTeleportState() == LLAgent::TELEPORT_MOVING;
  57. if( is_teleport )
  58. {
  59. // Force the camera back onto the agent, don't animate.
  60. gAgent.setFocusOnAvatar(TRUE, FALSE);
  61. gAgent.slamLookAt(look_at);
  62. gAgent.updateCamera();
  63. gAgent.setTeleportState( LLAgent::TELEPORT_START_ARRIVAL );
  64. // set the appearance on teleport since the new sim does not
  65. // know what you look like.
  66. gAgent.sendAgentSetAppearance();
  67. if (avatarp)
  68. {
  69. // Chat the "back" SLURL. (DEV-4907)
  70. LLSD args;
  71. args["MESSAGE"] = "Teleport completed from " + gAgent.getTeleportSourceSLURL();
  72. LLNotificationsUtil::add("SystemMessageTip", args);
  73. // Set the new position
  74. avatarp->setPositionAgent(agent_pos);
  75. avatarp->clearChat();
  76. avatarp->slamPosition();
  77. }
  78. }
  79. else
  80. {
  81. // This is likely just the initial logging in phase.
  82. gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
  83. }
  84. if ( LLTracker::isTracking(NULL) )
  85. {
  86. // Check distance to beacon, if < 5m, remove beacon
  87. LLVector3d beacon_pos = LLTracker::getTrackedPositionGlobal();
  88. LLVector3 beacon_dir(agent_pos.mV[VX] - (F32)fmod(beacon_pos.mdV[VX], 256.0), agent_pos.mV[VY] - (F32)fmod(beacon_pos.mdV[VY], 256.0), 0);
  89. if (beacon_dir.magVecSquared() < 25.f)
  90. {
  91. LLTracker::stopTracking(NULL);
  92. }
  93. else if ( is_teleport )
  94. {
  95. //look at the beacon
  96. LLVector3 global_agent_pos = agent_pos;
  97. global_agent_pos[0] += x;
  98. global_agent_pos[1] += y;
  99. look_at = (LLVector3)beacon_pos - global_agent_pos;
  100. look_at.normVec();
  101. gAgent.slamLookAt(look_at);
  102. }
  103. }
  104. // TODO: Put back a check for flying status! DK 12/19/05
  105. // Sim tells us whether the new position is off the ground
  106. /*
  107. if (teleport_flags & TELEPORT_FLAGS_IS_FLYING)
  108. {
  109. gAgent.setFlying(TRUE);
  110. }
  111. else
  112. {
  113. gAgent.setFlying(FALSE);
  114. }
  115. */
  116. send_agent_update(TRUE, TRUE);
  117. if (gAgent.getRegion()->getBlockFly())
  118. {
  119. gAgent.setFlying(gAgent.canFly());
  120. }
  121. // force simulator to recognize busy state
  122. if (gAgent.getBusy())
  123. {
  124. gAgent.setBusy();
  125. }
  126. else
  127. {
  128. gAgent.clearBusy();
  129. }
  130. if (avatarp)
  131. {
  132. avatarp->mFootPlane.clearVec();
  133. }
  134. // send walk-vs-run status
  135. gAgent.sendWalkRun(gAgent.getRunning() || gAgent.getAlwaysRun());
  136. // If the server version has changed, display an info box and offer
  137. // to display the release notes, unless this is the initial log in.
  138. if (gLastVersionChannel == version_channel)
  139. {
  140. return;
  141. }
  142. if (!gLastVersionChannel.empty())
  143. {
  144. // work out the URL for this server's Release Notes
  145. std::string url ="http://wiki.secondlife.com/wiki/Release_Notes/";
  146. std::string server_version = version_channel;
  147. std::vector<std::string> s_vect;
  148. boost::algorithm::split(s_vect, server_version, isspace);
  149. for(U32 i = 0; i < s_vect.size(); i++)
  150. {
  151. if (i != (s_vect.size() - 1))
  152. {
  153. if(i != (s_vect.size() - 2))
  154. {
  155.    url += s_vect[i] + "_";
  156. }
  157. else
  158. {
  159. url += s_vect[i] + "/";
  160. }
  161. }
  162. else
  163. {
  164. url += s_vect[i].substr(0,4);
  165. }
  166. }
  167. LLSD args;
  168. args["URL"] = url;
  169. LLNotificationsUtil::add("ServerVersionChanged", args);
  170. }
  171. gLastVersionChannel = version_channel;
  172. }
  173. void process_crossed_region(LLMessageSystem* msg, void**)
  174. {
  175. LLUUID agent_id;
  176. msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
  177. LLUUID session_id;
  178. msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_SessionID, session_id);
  179. if((gAgent.getID() != agent_id) || (gAgent.getSessionID() != session_id))
  180. {
  181. LL_WARNS("Messaging") << "Incorrect id in process_crossed_region()"
  182. << LL_ENDL;
  183. return;
  184. }
  185. LL_INFOS("Messaging") << "process_crossed_region()" << LL_ENDL;
  186. U32 sim_ip;
  187. msg->getIPAddrFast(_PREHASH_RegionData, _PREHASH_SimIP, sim_ip);
  188. U16 sim_port;
  189. msg->getIPPortFast(_PREHASH_RegionData, _PREHASH_SimPort, sim_port);
  190. LLHost sim_host(sim_ip, sim_port);
  191. U64 region_handle;
  192. msg->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);
  193. std::string seedCap;
  194. msg->getStringFast(_PREHASH_RegionData, _PREHASH_SeedCapability, seedCap);
  195. send_complete_agent_movement(sim_host);
  196. LLViewerRegion* regionp = LLWorld::getInstance()->addRegion(region_handle, sim_host);
  197. regionp->setSeedCapability(seedCap);
  198. }
  199. // Sends avatar and camera information to simulator.
  200. // Sent roughly once per frame, or 20 times per second, whichever is less often
  201. const F32 THRESHOLD_HEAD_ROT_QDOT = 0.9997f; // ~= 2.5 degrees -- if its less than this we need to update head_rot
  202. const F32 MAX_HEAD_ROT_QDOT = 0.99999f; // ~= 0.5 degrees -- if its greater than this then no need to update head_rot
  203. // between these values we delay the updates (but no more than one second)
  204. void send_agent_update(BOOL force_send, BOOL send_reliable)
  205. {
  206. if (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
  207. {
  208. // We don't care if they want to send an agent update, they're not allowed to until the simulator
  209. // that's the target is ready to receive them (after avatar_init_complete is received)
  210. return;
  211. }
  212. // We have already requested to log out.  Don't send agent updates.
  213. if(LLAppViewer::instance()->logoutRequestSent())
  214. {
  215. return;
  216. }
  217. // no region to send update to
  218. if(gAgent.getRegion() == NULL)
  219. {
  220. return;
  221. }
  222. const F32 TRANSLATE_THRESHOLD = 0.01f;
  223. // NOTA BENE: This is (intentionally?) using the small angle sine approximation to test for rotation
  224. //   Plus, there is an extra 0.5 in the mix since the perpendicular between last_camera_at and getAtAxis() bisects cam_rot_change
  225. //   Thus, we're actually testing against 0.2 degrees
  226. const F32 ROTATION_THRESHOLD = 0.1f * 2.f*F_PI/360.f; //  Rotation thresh 0.2 deg, see note above
  227. const U8 DUP_MSGS = 1; //  HACK!  number of times to repeat data on motionless agent
  228. //  Store data on last sent update so that if no changes, no send
  229. static LLVector3 last_camera_pos_agent, 
  230.  last_camera_at, 
  231.  last_camera_left,
  232.  last_camera_up;
  233. static LLVector3 cam_center_chg,
  234.  cam_rot_chg;
  235. static LLQuaternion last_head_rot;
  236. static U32 last_control_flags = 0;
  237. static U8 last_render_state;
  238. static U8 duplicate_count = 0;
  239. static F32 head_rot_chg = 1.0;
  240. static U8 last_flags;
  241. LLMessageSystem *msg = gMessageSystem;
  242. LLVector3 camera_pos_agent; // local to avatar's region
  243. U8 render_state;
  244. LLQuaternion body_rotation = gAgent.getFrameAgent().getQuaternion();
  245. LLQuaternion head_rotation = gAgent.getHeadRotation();
  246. camera_pos_agent = gAgent.getCameraPositionAgent();
  247. render_state = gAgent.getRenderState();
  248. U32 control_flag_change = 0;
  249. U8 flag_change = 0;
  250. cam_center_chg = last_camera_pos_agent - camera_pos_agent;
  251. cam_rot_chg = last_camera_at - LLViewerCamera::getInstance()->getAtAxis();
  252. // If a modifier key is held down, turn off
  253. // LBUTTON and ML_LBUTTON so that using the camera (alt-key) doesn't
  254. // trigger a control event.
  255. U32 control_flags = gAgent.getControlFlags();
  256. MASK key_mask = gKeyboard->currentMask(TRUE);
  257. if (key_mask & MASK_ALT || key_mask & MASK_CONTROL)
  258. {
  259. control_flags &= ~( AGENT_CONTROL_LBUTTON_DOWN |
  260. AGENT_CONTROL_ML_LBUTTON_DOWN );
  261. control_flags |=  AGENT_CONTROL_LBUTTON_UP |
  262. AGENT_CONTROL_ML_LBUTTON_UP ;
  263. }
  264. control_flag_change = last_control_flags ^ control_flags;
  265. U8 flags = AU_FLAGS_NONE;
  266. if (gAgent.isGroupTitleHidden())
  267. {
  268. flags |= AU_FLAGS_HIDETITLE;
  269. }
  270. if (gAgent.getAutoPilot())
  271. {
  272. flags |= AU_FLAGS_CLIENT_AUTOPILOT;
  273. }
  274. flag_change = last_flags ^ flags;
  275. head_rot_chg = dot(last_head_rot, head_rotation);
  276. if (force_send || 
  277. (cam_center_chg.magVec() > TRANSLATE_THRESHOLD) || 
  278. (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT) ||
  279. (last_render_state != render_state) ||
  280. (cam_rot_chg.magVec() > ROTATION_THRESHOLD) ||
  281. control_flag_change != 0 ||
  282. flag_change != 0)  
  283. {
  284. /*
  285. if (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT)
  286. {
  287. //LL_INFOS("Messaging") << "head rot " << head_rotation << LL_ENDL;
  288. LL_INFOS("Messaging") << "head_rot_chg = " << head_rot_chg << LL_ENDL;
  289. }
  290. if (cam_rot_chg.magVec() > ROTATION_THRESHOLD) 
  291. {
  292. LL_INFOS("Messaging") << "cam rot " <<  cam_rot_chg.magVec() << LL_ENDL;
  293. }
  294. if (cam_center_chg.magVec() > TRANSLATE_THRESHOLD)
  295. {
  296. LL_INFOS("Messaging") << "cam center " << cam_center_chg.magVec() << LL_ENDL;
  297. }
  298. // if (drag_delta_chg.magVec() > TRANSLATE_THRESHOLD)
  299. // {
  300. // LL_INFOS("Messaging") << "drag delta " << drag_delta_chg.magVec() << LL_ENDL;
  301. // }
  302. if (control_flag_change)
  303. {
  304. LL_INFOS("Messaging") << "dcf = " << control_flag_change << LL_ENDL;
  305. }
  306. */
  307. duplicate_count = 0;
  308. }
  309. else
  310. {
  311. duplicate_count++;
  312. if (head_rot_chg < MAX_HEAD_ROT_QDOT  &&  duplicate_count < AGENT_UPDATES_PER_SECOND)
  313. {
  314. // The head_rotation is sent for updating things like attached guns.
  315. // We only trigger a new update when head_rotation deviates beyond
  316. // some threshold from the last update, however this can break fine
  317. // adjustments when trying to aim an attached gun, so what we do here
  318. // (where we would normally skip sending an update when nothing has changed)
  319. // is gradually reduce the threshold to allow a better update to 
  320. // eventually get sent... should update to within 0.5 degrees in less 
  321. // than a second.
  322. if (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT + (MAX_HEAD_ROT_QDOT - THRESHOLD_HEAD_ROT_QDOT) * duplicate_count / AGENT_UPDATES_PER_SECOND)
  323. {
  324. duplicate_count = 0;
  325. }
  326. else
  327. {
  328. return;
  329. }
  330. }
  331. else
  332. {
  333. return;
  334. }
  335. }
  336. if (duplicate_count < DUP_MSGS && !gDisconnected)
  337. {
  338. // Build the message
  339. msg->newMessageFast(_PREHASH_AgentUpdate);
  340. msg->nextBlockFast(_PREHASH_AgentData);
  341. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  342. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  343. msg->addQuatFast(_PREHASH_BodyRotation, body_rotation);
  344. msg->addQuatFast(_PREHASH_HeadRotation, head_rotation);
  345. msg->addU8Fast(_PREHASH_State, render_state);
  346. msg->addU8Fast(_PREHASH_Flags, flags);
  347. // if (camera_pos_agent.mV[VY] > 255.f)
  348. // {
  349. // LL_INFOS("Messaging") << "Sending camera center " << camera_pos_agent << LL_ENDL;
  350. // }
  351. msg->addVector3Fast(_PREHASH_CameraCenter, camera_pos_agent);
  352. msg->addVector3Fast(_PREHASH_CameraAtAxis, LLViewerCamera::getInstance()->getAtAxis());
  353. msg->addVector3Fast(_PREHASH_CameraLeftAxis, LLViewerCamera::getInstance()->getLeftAxis());
  354. msg->addVector3Fast(_PREHASH_CameraUpAxis, LLViewerCamera::getInstance()->getUpAxis());
  355. msg->addF32Fast(_PREHASH_Far, gAgent.mDrawDistance);
  356. msg->addU32Fast(_PREHASH_ControlFlags, control_flags);
  357. if (gDebugClicks)
  358. {
  359. if (control_flags & AGENT_CONTROL_LBUTTON_DOWN)
  360. {
  361. LL_INFOS("Messaging") << "AgentUpdate left button down" << LL_ENDL;
  362. }
  363. if (control_flags & AGENT_CONTROL_LBUTTON_UP)
  364. {
  365. LL_INFOS("Messaging") << "AgentUpdate left button up" << LL_ENDL;
  366. }
  367. }
  368. gAgent.enableControlFlagReset();
  369. if (!send_reliable)
  370. {
  371. gAgent.sendMessage();
  372. }
  373. else
  374. {
  375. gAgent.sendReliableMessage();
  376. }
  377. // LL_DEBUGS("Messaging") << "agent " << avatar_pos_agent << " cam " << camera_pos_agent << LL_ENDL;
  378. // Copy the old data 
  379. last_head_rot = head_rotation;
  380. last_render_state = render_state;
  381. last_camera_pos_agent = camera_pos_agent;
  382. last_camera_at = LLViewerCamera::getInstance()->getAtAxis();
  383. last_camera_left = LLViewerCamera::getInstance()->getLeftAxis();
  384. last_camera_up = LLViewerCamera::getInstance()->getUpAxis();
  385. last_control_flags = control_flags;
  386. last_flags = flags;
  387. }
  388. }
  389. // *TODO: Remove this dependency, or figure out a better way to handle
  390. // this hack.
  391. extern U32 gObjectBits;
  392. void process_object_update(LLMessageSystem *mesgsys, void **user_data)
  393. {
  394. LLMemType mt(LLMemType::MTYPE_OBJECT);
  395. // Update the data counters
  396. if (mesgsys->getReceiveCompressedSize())
  397. {
  398. gObjectBits += mesgsys->getReceiveCompressedSize() * 8;
  399. }
  400. else
  401. {
  402. gObjectBits += mesgsys->getReceiveSize() * 8;
  403. }
  404. // Update the object...
  405. gObjectList.processObjectUpdate(mesgsys, user_data, OUT_FULL);
  406. }
  407. void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data)
  408. {
  409. LLMemType mt(LLMemType::MTYPE_OBJECT);
  410. // Update the data counters
  411. if (mesgsys->getReceiveCompressedSize())
  412. {
  413. gObjectBits += mesgsys->getReceiveCompressedSize() * 8;
  414. }
  415. else
  416. {
  417. gObjectBits += mesgsys->getReceiveSize() * 8;
  418. }
  419. // Update the object...
  420. gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_FULL_COMPRESSED);
  421. }
  422. void process_cached_object_update(LLMessageSystem *mesgsys, void **user_data)
  423. {
  424. LLMemType mt(LLMemType::MTYPE_OBJECT);
  425. // Update the data counters
  426. if (mesgsys->getReceiveCompressedSize())
  427. {
  428. gObjectBits += mesgsys->getReceiveCompressedSize() * 8;
  429. }
  430. else
  431. {
  432. gObjectBits += mesgsys->getReceiveSize() * 8;
  433. }
  434. // Update the object...
  435. gObjectList.processCachedObjectUpdate(mesgsys, user_data, OUT_FULL_CACHED);
  436. }
  437. void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_data)
  438. {
  439. LLMemType mt(LLMemType::MTYPE_OBJECT);
  440. if (mesgsys->getReceiveCompressedSize())
  441. {
  442. gObjectBits += mesgsys->getReceiveCompressedSize() * 8;
  443. }
  444. else
  445. {
  446. gObjectBits += mesgsys->getReceiveSize() * 8;
  447. }
  448. gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_TERSE_IMPROVED);
  449. }
  450. static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Objects");
  451. void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
  452. {
  453. LLFastTimer t(FTM_PROCESS_OBJECTS);
  454. LLUUID id;
  455. U32 local_id;
  456. S32 i;
  457. S32 num_objects;
  458. num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData);
  459. for (i = 0; i < num_objects; i++)
  460. {
  461. mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);
  462. LLViewerObjectList::getUUIDFromLocal(id,
  463. local_id,
  464. gMessageSystem->getSenderIP(),
  465. gMessageSystem->getSenderPort());
  466. if (id == LLUUID::null)
  467. {
  468. LL_DEBUGS("Messaging") << "Unknown kill for local " << local_id << LL_ENDL;
  469. gObjectList.mNumUnknownKills++;
  470. continue;
  471. }
  472. else
  473. {
  474. LL_DEBUGS("Messaging") << "Kill message for local " << local_id << LL_ENDL;
  475. }
  476. LLSelectMgr::getInstance()->removeObjectFromSelections(id);
  477. // ...don't kill the avatar
  478. if (!(id == gAgentID))
  479. {
  480. LLViewerObject *objectp = gObjectList.findObject(id);
  481. if (objectp)
  482. {
  483. // Display green bubble on kill
  484. if ( gShowObjectUpdates )
  485. {
  486. LLViewerObject* newobject;
  487. newobject = gObjectList.createObjectViewer(LL_PCODE_LEGACY_TEXT_BUBBLE, objectp->getRegion());
  488. LLVOTextBubble* bubble = (LLVOTextBubble*) newobject;
  489. bubble->mColor.setVec(0.f, 1.f, 0.f, 1.f);
  490. bubble->setScale( 2.0f * bubble->getScale() );
  491. bubble->setPositionGlobal(objectp->getPositionGlobal());
  492. gPipeline.addObject(bubble);
  493. }
  494. // Do the kill
  495. gObjectList.killObject(objectp);
  496. }
  497. else
  498. {
  499. LL_WARNS("Messaging") << "Object in UUID lookup, but not on object list in kill!" << LL_ENDL;
  500. gObjectList.mNumUnknownKills++;
  501. }
  502. }
  503. }
  504. }
  505. void process_time_synch(LLMessageSystem *mesgsys, void **user_data)
  506. {
  507. LLVector3 sun_direction;
  508. LLVector3 sun_ang_velocity;
  509. F32 phase;
  510. U64 space_time_usec;
  511.     U32 seconds_per_day;
  512.     U32 seconds_per_year;
  513. // "SimulatorViewerTimeMessage"
  514. mesgsys->getU64Fast(_PREHASH_TimeInfo, _PREHASH_UsecSinceStart, space_time_usec);
  515. mesgsys->getU32Fast(_PREHASH_TimeInfo, _PREHASH_SecPerDay, seconds_per_day);
  516. mesgsys->getU32Fast(_PREHASH_TimeInfo, _PREHASH_SecPerYear, seconds_per_year);
  517. // This should eventually be moved to an "UpdateHeavenlyBodies" message
  518. mesgsys->getF32Fast(_PREHASH_TimeInfo, _PREHASH_SunPhase, phase);
  519. mesgsys->getVector3Fast(_PREHASH_TimeInfo, _PREHASH_SunDirection, sun_direction);
  520. mesgsys->getVector3Fast(_PREHASH_TimeInfo, _PREHASH_SunAngVelocity, sun_ang_velocity);
  521. LLWorld::getInstance()->setSpaceTimeUSec(space_time_usec);
  522. //LL_DEBUGS("Messaging") << "time_synch() - " << sun_direction << ", " << sun_ang_velocity
  523. //  << ", " << phase << LL_ENDL;
  524. gSky.setSunPhase(phase);
  525. gSky.setSunTargetDirection(sun_direction, sun_ang_velocity);
  526. if (!gNoRender && !(gSavedSettings.getBOOL("SkyOverrideSimSunPosition") || gSky.getOverrideSun()))
  527. {
  528. gSky.setSunDirection(sun_direction, sun_ang_velocity);
  529. }
  530. }
  531. void process_sound_trigger(LLMessageSystem *msg, void **)
  532. {
  533. if (!gAudiop) return;
  534. U64 region_handle = 0;
  535. F32 gain = 0;
  536. LLUUID sound_id;
  537. LLUUID owner_id;
  538. LLUUID object_id;
  539. LLUUID parent_id;
  540. LLVector3 pos_local;
  541. msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_SoundID, sound_id);
  542. msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_OwnerID, owner_id);
  543. msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_ObjectID, object_id);
  544. msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_ParentID, parent_id);
  545. msg->getU64Fast(_PREHASH_SoundData, _PREHASH_Handle, region_handle);
  546. msg->getVector3Fast(_PREHASH_SoundData, _PREHASH_Position, pos_local);
  547. msg->getF32Fast(_PREHASH_SoundData, _PREHASH_Gain, gain);
  548. // adjust sound location to true global coords
  549. LLVector3d pos_global = from_region_handle(region_handle);
  550. pos_global.mdV[VX] += pos_local.mV[VX];
  551. pos_global.mdV[VY] += pos_local.mV[VY];
  552. pos_global.mdV[VZ] += pos_local.mV[VZ];
  553. // Don't play a trigger sound if you can't hear it due
  554. // to parcel "local audio only" settings.
  555. if (!LLViewerParcelMgr::getInstance()->canHearSound(pos_global)) return;
  556. // Don't play sounds triggered by someone you muted.
  557. if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return;
  558. // Don't play sounds from an object you muted
  559. if (LLMuteList::getInstance()->isMuted(object_id)) return;
  560. // Don't play sounds from an object whose parent you muted
  561. if (parent_id.notNull()
  562. && LLMuteList::getInstance()->isMuted(parent_id))
  563. {
  564. return;
  565. }
  566. // Don't play sounds from a region with maturity above current agent maturity
  567. if( !gAgent.canAccessMaturityInRegion( region_handle ) )
  568. {
  569. return;
  570. }
  571. gAudiop->triggerSound(sound_id, owner_id, gain, LLAudioEngine::AUDIO_TYPE_SFX, pos_global);
  572. }
  573. void process_preload_sound(LLMessageSystem *msg, void **user_data)
  574. {
  575. if (!gAudiop)
  576. {
  577. return;
  578. }
  579. LLUUID sound_id;
  580. LLUUID object_id;
  581. LLUUID owner_id;
  582. msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_SoundID, sound_id);
  583. msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_ObjectID, object_id);
  584. msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_OwnerID, owner_id);
  585. LLViewerObject *objectp = gObjectList.findObject(object_id);
  586. if (!objectp) return;
  587. if (LLMuteList::getInstance()->isMuted(object_id)) return;
  588. if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return;
  589. LLAudioSource *sourcep = objectp->getAudioSource(owner_id);
  590. if (!sourcep) return;
  591. LLAudioData *datap = gAudiop->getAudioData(sound_id);
  592. // Note that I don't actually do any loading of the
  593. // audio data into a buffer at this point, as it won't actually
  594. // help us out.
  595. // Don't play sounds from a region with maturity above current agent maturity
  596. LLVector3d pos_global = objectp->getPositionGlobal();
  597. if( !gAgent.canAccessMaturityAtGlobal( pos_global ) )
  598. {
  599. return;
  600. }
  601. // Add audioData starts a transfer internally.
  602. sourcep->addAudioData(datap, FALSE);
  603. }
  604. void process_attached_sound(LLMessageSystem *msg, void **user_data)
  605. {
  606. F32 gain = 0;
  607. LLUUID sound_id;
  608. LLUUID object_id;
  609. LLUUID owner_id;
  610. U8 flags;
  611. msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_SoundID, sound_id);
  612. msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_ObjectID, object_id);
  613. msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_OwnerID, owner_id);
  614. msg->getF32Fast(_PREHASH_DataBlock, _PREHASH_Gain, gain);
  615. msg->getU8Fast(_PREHASH_DataBlock, _PREHASH_Flags, flags);
  616. LLViewerObject *objectp = gObjectList.findObject(object_id);
  617. if (!objectp)
  618. {
  619. // we don't know about this object, just bail
  620. return;
  621. }
  622. if (LLMuteList::getInstance()->isMuted(object_id)) return;
  623. if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return;
  624. // Don't play sounds from a region with maturity above current agent maturity
  625. LLVector3d pos = objectp->getPositionGlobal();
  626. if( !gAgent.canAccessMaturityAtGlobal(pos) )
  627. {
  628. return;
  629. }
  630. objectp->setAttachedSound(sound_id, owner_id, gain, flags);
  631. }
  632. void process_attached_sound_gain_change(LLMessageSystem *mesgsys, void **user_data)
  633. {
  634. F32 gain = 0;
  635. LLUUID object_guid;
  636. LLViewerObject *objectp = NULL;
  637. mesgsys->getUUIDFast(_PREHASH_DataBlock, _PREHASH_ObjectID, object_guid);
  638. if (!((objectp = gObjectList.findObject(object_guid))))
  639. {
  640. // we don't know about this object, just bail
  641. return;
  642. }
  643.   mesgsys->getF32Fast(_PREHASH_DataBlock, _PREHASH_Gain, gain);
  644. objectp->adjustAudioGain(gain);
  645. }
  646. void process_health_message(LLMessageSystem *mesgsys, void **user_data)
  647. {
  648. F32 health;
  649. mesgsys->getF32Fast(_PREHASH_HealthData, _PREHASH_Health, health);
  650. if (gStatusBar)
  651. {
  652. gStatusBar->setHealth((S32)health);
  653. }
  654. }
  655. void process_sim_stats(LLMessageSystem *msg, void **user_data)
  656. {
  657. S32 count = msg->getNumberOfBlocks("Stat");
  658. for (S32 i = 0; i < count; ++i)
  659. {
  660. U32 stat_id;
  661. F32 stat_value;
  662. msg->getU32("Stat", "StatID", stat_id, i);
  663. msg->getF32("Stat", "StatValue", stat_value, i);
  664. switch (stat_id)
  665. {
  666. case LL_SIM_STAT_TIME_DILATION:
  667. LLViewerStats::getInstance()->mSimTimeDilation.addValue(stat_value);
  668. break;
  669. case LL_SIM_STAT_FPS:
  670. LLViewerStats::getInstance()->mSimFPS.addValue(stat_value);
  671. break;
  672. case LL_SIM_STAT_PHYSFPS:
  673. LLViewerStats::getInstance()->mSimPhysicsFPS.addValue(stat_value);
  674. break;
  675. case LL_SIM_STAT_AGENTUPS:
  676. LLViewerStats::getInstance()->mSimAgentUPS.addValue(stat_value);
  677. break;
  678. case LL_SIM_STAT_FRAMEMS:
  679. LLViewerStats::getInstance()->mSimFrameMsec.addValue(stat_value);
  680. break;
  681. case LL_SIM_STAT_NETMS:
  682. LLViewerStats::getInstance()->mSimNetMsec.addValue(stat_value);
  683. break;
  684. case LL_SIM_STAT_SIMOTHERMS:
  685. LLViewerStats::getInstance()->mSimSimOtherMsec.addValue(stat_value);
  686. break;
  687. case LL_SIM_STAT_SIMPHYSICSMS:
  688. LLViewerStats::getInstance()->mSimSimPhysicsMsec.addValue(stat_value);
  689. break;
  690. case LL_SIM_STAT_AGENTMS:
  691. LLViewerStats::getInstance()->mSimAgentMsec.addValue(stat_value);
  692. break;
  693. case LL_SIM_STAT_IMAGESMS:
  694. LLViewerStats::getInstance()->mSimImagesMsec.addValue(stat_value);
  695. break;
  696. case LL_SIM_STAT_SCRIPTMS:
  697. LLViewerStats::getInstance()->mSimScriptMsec.addValue(stat_value);
  698. break;
  699. case LL_SIM_STAT_NUMTASKS:
  700. LLViewerStats::getInstance()->mSimObjects.addValue(stat_value);
  701. break;
  702. case LL_SIM_STAT_NUMTASKSACTIVE:
  703. LLViewerStats::getInstance()->mSimActiveObjects.addValue(stat_value);
  704. break;
  705. case LL_SIM_STAT_NUMAGENTMAIN:
  706. LLViewerStats::getInstance()->mSimMainAgents.addValue(stat_value);
  707. break;
  708. case LL_SIM_STAT_NUMAGENTCHILD:
  709. LLViewerStats::getInstance()->mSimChildAgents.addValue(stat_value);
  710. break;
  711. case LL_SIM_STAT_NUMSCRIPTSACTIVE:
  712. LLViewerStats::getInstance()->mSimActiveScripts.addValue(stat_value);
  713. break;
  714. case LL_SIM_STAT_SCRIPT_EPS:
  715. LLViewerStats::getInstance()->mSimScriptEPS.addValue(stat_value);
  716. break;
  717. case LL_SIM_STAT_INPPS:
  718. LLViewerStats::getInstance()->mSimInPPS.addValue(stat_value);
  719. break;
  720. case LL_SIM_STAT_OUTPPS:
  721. LLViewerStats::getInstance()->mSimOutPPS.addValue(stat_value);
  722. break;
  723. case LL_SIM_STAT_PENDING_DOWNLOADS:
  724. LLViewerStats::getInstance()->mSimPendingDownloads.addValue(stat_value);
  725. break;
  726. case LL_SIM_STAT_PENDING_UPLOADS:
  727. LLViewerStats::getInstance()->mSimPendingUploads.addValue(stat_value);
  728. break;
  729. case LL_SIM_STAT_PENDING_LOCAL_UPLOADS:
  730. LLViewerStats::getInstance()->mSimPendingLocalUploads.addValue(stat_value);
  731. break;
  732. case LL_SIM_STAT_TOTAL_UNACKED_BYTES:
  733. LLViewerStats::getInstance()->mSimTotalUnackedBytes.addValue(stat_value / 1024.f);
  734. break;
  735. case LL_SIM_STAT_PHYSICS_PINNED_TASKS:
  736. LLViewerStats::getInstance()->mPhysicsPinnedTasks.addValue(stat_value);
  737. break;
  738. case LL_SIM_STAT_PHYSICS_LOD_TASKS:
  739. LLViewerStats::getInstance()->mPhysicsLODTasks.addValue(stat_value);
  740. break;
  741. case LL_SIM_STAT_SIMPHYSICSSTEPMS:
  742. LLViewerStats::getInstance()->mSimSimPhysicsStepMsec.addValue(stat_value);
  743. break;
  744. case LL_SIM_STAT_SIMPHYSICSSHAPEMS:
  745. LLViewerStats::getInstance()->mSimSimPhysicsShapeUpdateMsec.addValue(stat_value);
  746. break;
  747. case LL_SIM_STAT_SIMPHYSICSOTHERMS:
  748. LLViewerStats::getInstance()->mSimSimPhysicsOtherMsec.addValue(stat_value);
  749. break;
  750. case LL_SIM_STAT_SIMPHYSICSMEMORY:
  751. LLViewerStats::getInstance()->mPhysicsMemoryAllocated.addValue(stat_value);
  752. break;
  753. case LL_SIM_STAT_SIMSPARETIME:
  754. LLViewerStats::getInstance()->mSimSpareMsec.addValue(stat_value);
  755. break;
  756. case LL_SIM_STAT_SIMSLEEPTIME:
  757. LLViewerStats::getInstance()->mSimSleepMsec.addValue(stat_value);
  758. break;
  759. case LL_SIM_STAT_IOPUMPTIME:
  760. LLViewerStats::getInstance()->mSimPumpIOMsec.addValue(stat_value);
  761. break;
  762. default:
  763. // Used to be a commented out warning.
  764.   LL_DEBUGS("Messaging") << "Unknown stat id" << stat_id << LL_ENDL;
  765.   break;
  766. }
  767. }
  768. /*
  769. msg->getF32Fast(_PREHASH_Statistics, _PREHASH_PhysicsTimeDilation, time_dilation);
  770. LLViewerStats::getInstance()->mSimTDStat.addValue(time_dilation);
  771. // Process information
  772. // { CpuUsage F32 }
  773. // { SimMemTotal F32 }
  774. // { SimMemRSS F32 }
  775. // { ProcessUptime F32 }
  776. F32 cpu_usage;
  777. F32 sim_mem_total;
  778. F32 sim_mem_rss;
  779. F32 process_uptime;
  780. msg->getF32Fast(_PREHASH_Statistics, _PREHASH_CpuUsage, cpu_usage);
  781. msg->getF32Fast(_PREHASH_Statistics, _PREHASH_SimMemTotal, sim_mem_total);
  782. msg->getF32Fast(_PREHASH_Statistics, _PREHASH_SimMemRSS, sim_mem_rss);
  783. msg->getF32Fast(_PREHASH_Statistics, _PREHASH_ProcessUptime, process_uptime);
  784. LLViewerStats::getInstance()->mSimCPUUsageStat.addValue(cpu_usage);
  785. LLViewerStats::getInstance()->mSimMemTotalStat.addValue(sim_mem_total);
  786. LLViewerStats::getInstance()->mSimMemRSSStat.addValue(sim_mem_rss);
  787. */
  788. //
  789. // Various hacks that aren't statistics, but are being handled here.
  790. //
  791. U32 max_tasks_per_region;
  792. U32 region_flags;
  793. msg->getU32("Region", "ObjectCapacity", max_tasks_per_region);
  794. msg->getU32("Region", "RegionFlags", region_flags);
  795. LLViewerRegion* regionp = gAgent.getRegion();
  796. if (regionp)
  797. {
  798. BOOL was_flying = gAgent.getFlying();
  799. regionp->setRegionFlags(region_flags);
  800. regionp->setMaxTasks(max_tasks_per_region);
  801. // HACK: This makes agents drop from the sky if the region is 
  802. // set to no fly while people are still in the sim.
  803. if (was_flying && regionp->getBlockFly())
  804. {
  805. gAgent.setFlying(gAgent.canFly());
  806. }
  807. }
  808. }
  809. void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
  810. {
  811. LLUUID animation_id;
  812. LLUUID uuid;
  813. S32 anim_sequence_id;
  814. LLVOAvatar *avatarp;
  815. mesgsys->getUUIDFast(_PREHASH_Sender, _PREHASH_ID, uuid);
  816. //clear animation flags
  817. avatarp = (LLVOAvatar *)gObjectList.findObject(uuid);
  818. if (!avatarp)
  819. {
  820. // no agent by this ID...error?
  821. LL_WARNS("Messaging") << "Received animation state for unknown avatar" << uuid << LL_ENDL;
  822. return;
  823. }
  824. S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationList);
  825. S32 num_source_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationSourceList);
  826. avatarp->mSignaledAnimations.clear();
  827. if (avatarp->isSelf())
  828. {
  829. LLUUID object_id;
  830. for( S32 i = 0; i < num_blocks; i++ )
  831. {
  832. mesgsys->getUUIDFast(_PREHASH_AnimationList, _PREHASH_AnimID, animation_id, i);
  833. mesgsys->getS32Fast(_PREHASH_AnimationList, _PREHASH_AnimSequenceID, anim_sequence_id, i);
  834. LL_DEBUGS("Messaging") << "Anim sequence ID: " << anim_sequence_id << LL_ENDL;
  835. avatarp->mSignaledAnimations[animation_id] = anim_sequence_id;
  836. // *HACK: Disabling flying mode if it has been enabled shortly before the agent
  837. // stand up animation is signaled. In this case we don't get a signal to start
  838. // flying animation from server, the AGENT_CONTROL_FLY flag remains set but the
  839. // avatar does not play flying animation, so we switch flying mode off.
  840. // See LLAgent::setFlying(). This may cause "Stop Flying" button to blink.
  841. // See EXT-2781.
  842. if (animation_id == ANIM_AGENT_STANDUP && gAgent.getFlying())
  843. {
  844. gAgent.setFlying(FALSE);
  845. }
  846. if (i < num_source_blocks)
  847. {
  848. mesgsys->getUUIDFast(_PREHASH_AnimationSourceList, _PREHASH_ObjectID, object_id, i);
  849. LLViewerObject* object = gObjectList.findObject(object_id);
  850. if (object)
  851. {
  852. object->mFlags |= FLAGS_ANIM_SOURCE;
  853. BOOL anim_found = FALSE;
  854. LLVOAvatar::AnimSourceIterator anim_it = avatarp->mAnimationSources.find(object_id);
  855. for (;anim_it != avatarp->mAnimationSources.end(); ++anim_it)
  856. {
  857. if (anim_it->second == animation_id)
  858. {
  859. anim_found = TRUE;
  860. break;
  861. }
  862. }
  863. if (!anim_found)
  864. {
  865. avatarp->mAnimationSources.insert(LLVOAvatar::AnimationSourceMap::value_type(object_id, animation_id));
  866. }
  867. }
  868. }
  869. }
  870. }
  871. else
  872. {
  873. for( S32 i = 0; i < num_blocks; i++ )
  874. {
  875. mesgsys->getUUIDFast(_PREHASH_AnimationList, _PREHASH_AnimID, animation_id, i);
  876. mesgsys->getS32Fast(_PREHASH_AnimationList, _PREHASH_AnimSequenceID, anim_sequence_id, i);
  877. avatarp->mSignaledAnimations[animation_id] = anim_sequence_id;
  878. }
  879. }
  880. if (num_blocks)
  881. {
  882. avatarp->processAnimationStateChanges();
  883. }
  884. }
  885. void process_avatar_appearance(LLMessageSystem *mesgsys, void **user_data)
  886. {
  887. LLUUID uuid;
  888. mesgsys->getUUIDFast(_PREHASH_Sender, _PREHASH_ID, uuid);
  889. LLVOAvatar* avatarp = (LLVOAvatar *)gObjectList.findObject(uuid);
  890. if( avatarp )
  891. {
  892. avatarp->processAvatarAppearance( mesgsys );
  893. }
  894. else
  895. {
  896. LL_WARNS("Messaging") << "avatar_appearance sent for unknown avatar " << uuid << LL_ENDL;
  897. }
  898. }
  899. void process_camera_constraint(LLMessageSystem *mesgsys, void **user_data)
  900. {
  901. LLVector4 cameraCollidePlane;
  902. mesgsys->getVector4Fast(_PREHASH_CameraCollidePlane, _PREHASH_Plane, cameraCollidePlane);
  903. gAgent.setCameraCollidePlane(cameraCollidePlane);
  904. }
  905. void near_sit_object(BOOL success, void *data)
  906. {
  907. if (success)
  908. {
  909. // Send message to sit on object
  910. gMessageSystem->newMessageFast(_PREHASH_AgentSit);
  911. gMessageSystem->nextBlockFast(_PREHASH_AgentData);
  912. gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  913. gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  914. gAgent.sendReliableMessage();
  915. }
  916. }
  917. void process_avatar_sit_response(LLMessageSystem *mesgsys, void **user_data)
  918. {
  919. LLVector3 sitPosition;
  920. LLQuaternion sitRotation;
  921. LLUUID sitObjectID;
  922. BOOL use_autopilot;
  923. mesgsys->getUUIDFast(_PREHASH_SitObject, _PREHASH_ID, sitObjectID);
  924. mesgsys->getBOOLFast(_PREHASH_SitTransform, _PREHASH_AutoPilot, use_autopilot);
  925. mesgsys->getVector3Fast(_PREHASH_SitTransform, _PREHASH_SitPosition, sitPosition);
  926. mesgsys->getQuatFast(_PREHASH_SitTransform, _PREHASH_SitRotation, sitRotation);
  927. LLVector3 camera_eye;
  928. mesgsys->getVector3Fast(_PREHASH_SitTransform, _PREHASH_CameraEyeOffset, camera_eye);
  929. LLVector3 camera_at;
  930. mesgsys->getVector3Fast(_PREHASH_SitTransform, _PREHASH_CameraAtOffset, camera_at);
  931. BOOL force_mouselook;
  932. mesgsys->getBOOLFast(_PREHASH_SitTransform, _PREHASH_ForceMouselook, force_mouselook);
  933. LLVOAvatar* avatar = gAgent.getAvatarObject();
  934. if (avatar && dist_vec_squared(camera_eye, camera_at) > 0.0001f)
  935. {
  936. gAgent.setSitCamera(sitObjectID, camera_eye, camera_at);
  937. }
  938. gAgent.setForceMouselook(force_mouselook);
  939. LLViewerObject* object = gObjectList.findObject(sitObjectID);
  940. if (object)
  941. {
  942. LLVector3 sit_spot = object->getPositionAgent() + (sitPosition * object->getRotation());
  943. if (!use_autopilot || (avatar && avatar->isSitting() && avatar->getRoot() == object->getRoot()))
  944. {
  945. //we're already sitting on this object, so don't autopilot
  946. }
  947. else
  948. {
  949. gAgent.startAutoPilotGlobal(gAgent.getPosGlobalFromAgent(sit_spot), "Sit", &sitRotation, near_sit_object, NULL, 0.5f);
  950. }
  951. }
  952. else
  953. {
  954. LL_WARNS("Messaging") << "Received sit approval for unknown object " << sitObjectID << LL_ENDL;
  955. }
  956. }
  957. void process_clear_follow_cam_properties(LLMessageSystem *mesgsys, void **user_data)
  958. {
  959. LLUUID source_id;
  960. mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, source_id);
  961. LLFollowCamMgr::removeFollowCamParams(source_id);
  962. }
  963. void process_set_follow_cam_properties(LLMessageSystem *mesgsys, void **user_data)
  964. {
  965. S32 type;
  966. F32 value;
  967. bool settingPosition = false;
  968. bool settingFocus = false;
  969. bool settingFocusOffset = false;
  970. LLVector3 position;
  971. LLVector3 focus;
  972. LLVector3 focus_offset;
  973. LLUUID source_id;
  974. mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, source_id);
  975. LLViewerObject* objectp = gObjectList.findObject(source_id);
  976. if (objectp)
  977. {
  978. objectp->mFlags |= FLAGS_CAMERA_SOURCE;
  979. }
  980. S32 num_objects = mesgsys->getNumberOfBlocks("CameraProperty");
  981. for (S32 block_index = 0; block_index < num_objects; block_index++)
  982. {
  983. mesgsys->getS32("CameraProperty", "Type", type, block_index);
  984. mesgsys->getF32("CameraProperty", "Value", value, block_index);
  985. switch(type)
  986. {
  987. case FOLLOWCAM_PITCH:
  988. LLFollowCamMgr::setPitch(source_id, value);
  989. break;
  990. case FOLLOWCAM_FOCUS_OFFSET_X:
  991. focus_offset.mV[VX] = value;
  992. settingFocusOffset = true;
  993. break;
  994. case FOLLOWCAM_FOCUS_OFFSET_Y:
  995. focus_offset.mV[VY] = value;
  996. settingFocusOffset = true;
  997. break;
  998. case FOLLOWCAM_FOCUS_OFFSET_Z:
  999. focus_offset.mV[VZ] = value;
  1000. settingFocusOffset = true;
  1001. break;
  1002. case FOLLOWCAM_POSITION_LAG:
  1003. LLFollowCamMgr::setPositionLag(source_id, value);
  1004. break;
  1005. case FOLLOWCAM_FOCUS_LAG:
  1006. LLFollowCamMgr::setFocusLag(source_id, value);
  1007. break;
  1008. case FOLLOWCAM_DISTANCE:
  1009. LLFollowCamMgr::setDistance(source_id, value);
  1010. break;
  1011. case FOLLOWCAM_BEHINDNESS_ANGLE:
  1012. LLFollowCamMgr::setBehindnessAngle(source_id, value);
  1013. break;
  1014. case FOLLOWCAM_BEHINDNESS_LAG:
  1015. LLFollowCamMgr::setBehindnessLag(source_id, value);
  1016. break;
  1017. case FOLLOWCAM_POSITION_THRESHOLD:
  1018. LLFollowCamMgr::setPositionThreshold(source_id, value);
  1019. break;
  1020. case FOLLOWCAM_FOCUS_THRESHOLD:
  1021. LLFollowCamMgr::setFocusThreshold(source_id, value);
  1022. break;
  1023. case FOLLOWCAM_ACTIVE:
  1024. //if 1, set using followcam,. 
  1025. LLFollowCamMgr::setCameraActive(source_id, value != 0.f);
  1026. break;
  1027. case FOLLOWCAM_POSITION_X:
  1028. settingPosition = true;
  1029. position.mV[ 0 ] = value;
  1030. break;
  1031. case FOLLOWCAM_POSITION_Y:
  1032. settingPosition = true;
  1033. position.mV[ 1 ] = value;
  1034. break;
  1035. case FOLLOWCAM_POSITION_Z:
  1036. settingPosition = true;
  1037. position.mV[ 2 ] = value;
  1038. break;
  1039. case FOLLOWCAM_FOCUS_X:
  1040. settingFocus = true;
  1041. focus.mV[ 0 ] = value;
  1042. break;
  1043. case FOLLOWCAM_FOCUS_Y:
  1044. settingFocus = true;
  1045. focus.mV[ 1 ] = value;
  1046. break;
  1047. case FOLLOWCAM_FOCUS_Z:
  1048. settingFocus = true;
  1049. focus.mV[ 2 ] = value;
  1050. break;
  1051. case FOLLOWCAM_POSITION_LOCKED:
  1052. LLFollowCamMgr::setPositionLocked(source_id, value != 0.f);
  1053. break;
  1054. case FOLLOWCAM_FOCUS_LOCKED:
  1055. LLFollowCamMgr::setFocusLocked(source_id, value != 0.f);
  1056. break;
  1057. default:
  1058. break;
  1059. }
  1060. }
  1061. if ( settingPosition )
  1062. {
  1063. LLFollowCamMgr::setPosition(source_id, position);
  1064. }
  1065. if ( settingFocus )
  1066. {
  1067. LLFollowCamMgr::setFocus(source_id, focus);
  1068. }
  1069. if ( settingFocusOffset )
  1070. {
  1071. LLFollowCamMgr::setFocusOffset(source_id, focus_offset);
  1072. }
  1073. }
  1074. //end Ventrella 
  1075. // Culled from newsim lltask.cpp
  1076. void process_name_value(LLMessageSystem *mesgsys, void **user_data)
  1077. {
  1078. std::string temp_str;
  1079. LLUUID id;
  1080. S32 i, num_blocks;
  1081. mesgsys->getUUIDFast(_PREHASH_TaskData, _PREHASH_ID, id);
  1082. LLViewerObject* object = gObjectList.findObject(id);
  1083. if (object)
  1084. {
  1085. num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_NameValueData);
  1086. for (i = 0; i < num_blocks; i++)
  1087. {
  1088. mesgsys->getStringFast(_PREHASH_NameValueData, _PREHASH_NVPair, temp_str, i);
  1089. LL_INFOS("Messaging") << "Added to object Name Value: " << temp_str << LL_ENDL;
  1090. object->addNVPair(temp_str);
  1091. }
  1092. }
  1093. else
  1094. {
  1095. LL_INFOS("Messaging") << "Can't find object " << id << " to add name value pair" << LL_ENDL;
  1096. }
  1097. }
  1098. void process_remove_name_value(LLMessageSystem *mesgsys, void **user_data)
  1099. {
  1100. std::string temp_str;
  1101. LLUUID id;
  1102. S32 i, num_blocks;
  1103. mesgsys->getUUIDFast(_PREHASH_TaskData, _PREHASH_ID, id);
  1104. LLViewerObject* object = gObjectList.findObject(id);
  1105. if (object)
  1106. {
  1107. num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_NameValueData);
  1108. for (i = 0; i < num_blocks; i++)
  1109. {
  1110. mesgsys->getStringFast(_PREHASH_NameValueData, _PREHASH_NVPair, temp_str, i);
  1111. LL_INFOS("Messaging") << "Removed from object Name Value: " << temp_str << LL_ENDL;
  1112. object->removeNVPair(temp_str);
  1113. }
  1114. }
  1115. else
  1116. {
  1117. LL_INFOS("Messaging") << "Can't find object " << id << " to remove name value pair" << LL_ENDL;
  1118. }
  1119. }
  1120. void process_kick_user(LLMessageSystem *msg, void** /*user_data*/)
  1121. {
  1122. std::string message;
  1123. msg->getStringFast(_PREHASH_UserInfo, _PREHASH_Reason, message);
  1124. LLAppViewer::instance()->forceDisconnect(message);
  1125. }
  1126. /*
  1127. void process_user_list_reply(LLMessageSystem *msg, void **user_data)
  1128. {
  1129. LLUserList::processUserListReply(msg, user_data);
  1130. return;
  1131. char firstname[MAX_STRING+1];
  1132. char lastname[MAX_STRING+1];
  1133. U8 status;
  1134. S32 user_count;
  1135. user_count = msg->getNumberOfBlocks("UserBlock");
  1136. for (S32 i = 0; i < user_count; i++)
  1137. {
  1138. msg->getData("UserBlock", i, "FirstName", firstname);
  1139. msg->getData("UserBlock", i, "LastName", lastname);
  1140. msg->getData("UserBlock", i, "Status", &status);
  1141. if (status & 0x01)
  1142. {
  1143. dialog_friends_add_friend(buffer, TRUE);
  1144. }
  1145. else
  1146. {
  1147. dialog_friends_add_friend(buffer, FALSE);
  1148. }
  1149. }
  1150. dialog_friends_done_adding();
  1151. }
  1152. */
  1153. // this is not handled in processUpdateMessage
  1154. /*
  1155. void process_time_dilation(LLMessageSystem *msg, void **user_data)
  1156. {
  1157. // get the time_dilation
  1158. U16 foo;
  1159. msg->getData("TimeDilation", "TimeDilation", &foo);
  1160. F32 time_dilation = ((F32) foo) / 65535.f;
  1161. // get the pointer to the right region
  1162. U32 ip = msg->getSenderIP();
  1163. U32 port = msg->getSenderPort();
  1164. LLViewerRegion *regionp = LLWorld::getInstance()->getRegion(ip, port);
  1165. if (regionp)
  1166. {
  1167. regionp->setTimeDilation(time_dilation);
  1168. }
  1169. }
  1170. */
  1171. void process_money_balance_reply( LLMessageSystem* msg, void** )
  1172. {
  1173. S32 balance = 0;
  1174. S32 credit = 0;
  1175. S32 committed = 0;
  1176. std::string desc;
  1177. msg->getS32("MoneyData", "MoneyBalance", balance);
  1178. msg->getS32("MoneyData", "SquareMetersCredit", credit);
  1179. msg->getS32("MoneyData", "SquareMetersCommitted", committed);
  1180. msg->getStringFast(_PREHASH_MoneyData, _PREHASH_Description, desc);
  1181. LL_INFOS("Messaging") << "L$, credit, committed: " << balance << " " << credit << " "
  1182. << committed << LL_ENDL;
  1183. if (gStatusBar)
  1184. {
  1185. // S32 old_balance = gStatusBar->getBalance();
  1186. // This is an update, not the first transmission of balance
  1187. /* if (old_balance != 0)
  1188. {
  1189. // this is actually an update
  1190. if (balance > old_balance)
  1191. {
  1192. LLFirstUse::useBalanceIncrease(balance - old_balance);
  1193. }
  1194. else if (balance < old_balance)
  1195. {
  1196. LLFirstUse::useBalanceDecrease(balance - old_balance);
  1197. }
  1198. }
  1199.  */
  1200. gStatusBar->setBalance(balance);
  1201. gStatusBar->setLandCredit(credit);
  1202. gStatusBar->setLandCommitted(committed);
  1203. }
  1204. LLUUID tid;
  1205. msg->getUUID("MoneyData", "TransactionID", tid);
  1206. static std::deque<LLUUID> recent;
  1207. if(!desc.empty() && gSavedSettings.getBOOL("NotifyMoneyChange")
  1208.    && (std::find(recent.rbegin(), recent.rend(), tid) == recent.rend()))
  1209. {
  1210. // Make the user confirm the transaction, since they might
  1211. // have missed something during an event.
  1212. // *TODO: Translate
  1213. LLSD args;
  1214. args["MESSAGE"] = desc;
  1215. // this is a marker to retrieve avatar name from server message:
  1216. // "<avatar name> paid you L$"
  1217. const std::string marker = "paid you L$";
  1218. // extract avatar name from system message
  1219. std::string name = desc.substr(0, desc.find(marker, 0));
  1220. LLStringUtil::trim(name);
  1221. // if name extracted and name cache contains avatar id send loggable notification
  1222. LLUUID from_id;
  1223. if(name.size() > 0 && gCacheName->getUUID(name, from_id))
  1224. {
  1225. args["NAME"] = name;
  1226. LLSD payload;
  1227. payload["from_id"] = from_id;
  1228. LLNotificationsUtil::add("PaymentRecived", args, payload);
  1229. }
  1230. else
  1231. {
  1232. LLNotificationsUtil::add("SystemMessage", args);
  1233. }
  1234. // Once the 'recent' container gets large enough, chop some
  1235. // off the beginning.
  1236. const U32 MAX_LOOKBACK = 30;
  1237. const S32 POP_FRONT_SIZE = 12;
  1238. if(recent.size() > MAX_LOOKBACK)
  1239. {
  1240. LL_DEBUGS("Messaging") << "Removing oldest transaction records" << LL_ENDL;
  1241. recent.erase(recent.begin(), recent.begin() + POP_FRONT_SIZE);
  1242. }
  1243. //LL_DEBUGS("Messaging") << "Pushing back transaction " << tid << LL_ENDL;
  1244. recent.push_back(tid);
  1245. }
  1246. }
  1247. bool handle_special_notification_callback(const LLSD& notification, const LLSD& response)
  1248. {
  1249. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  1250. if (0 == option)
  1251. {
  1252. // set the preference to the maturity of the region we're calling
  1253. int preferredMaturity = notification["payload"]["_region_access"].asInteger();
  1254. gSavedSettings.setU32("PreferredMaturity", preferredMaturity);
  1255. gAgent.sendMaturityPreferenceToServer(preferredMaturity);
  1256. }
  1257. return false;
  1258. }
  1259. // some of the server notifications need special handling. This is where we do that.
  1260. bool handle_special_notification(std::string notificationID, LLSD& llsdBlock)
  1261. {
  1262. int regionAccess = llsdBlock["_region_access"].asInteger();
  1263. llsdBlock["REGIONMATURITY"] = LLViewerRegion::accessToString(regionAccess);
  1264. // we're going to throw the LLSD in there in case anyone ever wants to use it
  1265. LLNotificationsUtil::add(notificationID+"_Notify", llsdBlock);
  1266. if (regionAccess == SIM_ACCESS_MATURE)
  1267. {
  1268. if (gAgent.isTeen())
  1269. {
  1270. LLNotificationsUtil::add(notificationID+"_KB", llsdBlock);
  1271. return true;
  1272. }
  1273. else if (gAgent.prefersPG())
  1274. {
  1275. LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback);
  1276. return true;
  1277. }
  1278. }
  1279. else if (regionAccess == SIM_ACCESS_ADULT)
  1280. {
  1281. if (!gAgent.isAdult())
  1282. {
  1283. LLNotificationsUtil::add(notificationID+"_KB", llsdBlock);
  1284. return true;
  1285. }
  1286. else if (gAgent.prefersPG() || gAgent.prefersMature())
  1287. {
  1288. LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback);
  1289. return true;
  1290. }
  1291. }
  1292. return false;
  1293. }
  1294. bool attempt_standard_notification(LLMessageSystem* msgsystem)
  1295. {
  1296. // if we have additional alert data
  1297. if (msgsystem->has(_PREHASH_AlertInfo) && msgsystem->getNumberOfBlocksFast(_PREHASH_AlertInfo) > 0)
  1298. {
  1299. // notification was specified using the new mechanism, so we can just handle it here
  1300. std::string notificationID;
  1301. std::string llsdRaw;
  1302. LLSD llsdBlock;
  1303. msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, notificationID);
  1304. msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_ExtraParams, llsdRaw);
  1305. if (llsdRaw.length())
  1306. {
  1307. std::istringstream llsdData(llsdRaw);
  1308. if (!LLSDSerialize::deserialize(llsdBlock, llsdData, llsdRaw.length()))
  1309. {
  1310. llwarns << "attempt_standard_notification: Attempted to read notification parameter data into LLSD but failed:" << llsdRaw << llendl;
  1311. }
  1312. }
  1313. if (
  1314. (notificationID == "RegionEntryAccessBlocked") ||
  1315. (notificationID == "LandClaimAccessBlocked") ||
  1316. (notificationID == "LandBuyAccessBlocked")
  1317.    )
  1318. {
  1319. /*---------------------------------------------------------------------
  1320.  (Commented so a grep will find the notification strings, since
  1321.  we construct them on the fly; if you add additional notifications,
  1322.  please update the comment.)
  1323.  
  1324.  Could throw any of the following notifications:
  1325.  
  1326. RegionEntryAccessBlocked
  1327. RegionEntryAccessBlocked_Notify
  1328. RegionEntryAccessBlocked_Change
  1329. RegionEntryAccessBlocked_KB
  1330. LandClaimAccessBlocked 
  1331. LandClaimAccessBlocked_Notify 
  1332. LandClaimAccessBlocked_Change 
  1333. LandClaimAccessBlocked_KB 
  1334. LandBuyAccessBlocked
  1335. LandBuyAccessBlocked_Notify
  1336. LandBuyAccessBlocked_Change
  1337. LandBuyAccessBlocked_KB
  1338.  
  1339. -----------------------------------------------------------------------*/ 
  1340. if (handle_special_notification(notificationID, llsdBlock))
  1341. {
  1342. return true;
  1343. }
  1344. }
  1345. LLNotificationsUtil::add(notificationID, llsdBlock);
  1346. return true;
  1347. }
  1348. return false;
  1349. }
  1350. void process_agent_alert_message(LLMessageSystem* msgsystem, void** user_data)
  1351. {
  1352. // make sure the cursor is back to the usual default since the
  1353. // alert is probably due to some kind of error.
  1354. gViewerWindow->getWindow()->resetBusyCount();
  1355. if (!attempt_standard_notification(msgsystem))
  1356. {
  1357. BOOL modal = FALSE;
  1358. msgsystem->getBOOL("AlertData", "Modal", modal);
  1359. std::string buffer;
  1360. msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, buffer);
  1361. process_alert_core(buffer, modal);
  1362. }
  1363. }
  1364. // The only difference between this routine and the previous is the fact that
  1365. // for this routine, the modal parameter is always false. Sadly, for the message
  1366. // handled by this routine, there is no "Modal" parameter on the message, and
  1367. // there's no API to tell if a message has the given parameter or not.
  1368. // So we can't handle the messages with the same handler.
  1369. void process_alert_message(LLMessageSystem *msgsystem, void **user_data)
  1370. {
  1371. // make sure the cursor is back to the usual default since the
  1372. // alert is probably due to some kind of error.
  1373. gViewerWindow->getWindow()->resetBusyCount();
  1374. if (!attempt_standard_notification(msgsystem))
  1375. {
  1376. BOOL modal = FALSE;
  1377. std::string buffer;
  1378. msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, buffer);
  1379. process_alert_core(buffer, modal);
  1380. }
  1381. }
  1382. void process_alert_core(const std::string& message, BOOL modal)
  1383. {
  1384. // HACK -- handle callbacks for specific alerts
  1385. if ( message == "You died and have been teleported to your home location")
  1386. {
  1387. LLViewerStats::getInstance()->incStat(LLViewerStats::ST_KILLED_COUNT);
  1388. }
  1389. else if( message == "Home position set." )
  1390. {
  1391. // save the home location image to disk
  1392. std::string snap_filename = gDirUtilp->getLindenUserDir();
  1393. snap_filename += gDirUtilp->getDirDelimiter();
  1394. snap_filename += SCREEN_HOME_FILENAME;
  1395. gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw(), FALSE, FALSE);
  1396. }
  1397. const std::string ALERT_PREFIX("ALERT: ");
  1398. const std::string NOTIFY_PREFIX("NOTIFY: ");
  1399. if (message.find(ALERT_PREFIX) == 0)
  1400. {
  1401. // Allow the server to spawn a named alert so that server alerts can be
  1402. // translated out of English.
  1403. std::string alert_name(message.substr(ALERT_PREFIX.length()));
  1404. LLNotificationsUtil::add(alert_name);
  1405. }
  1406. else if (message.find(NOTIFY_PREFIX) == 0)
  1407. {
  1408. // Allow the server to spawn a named notification so that server notifications can be
  1409. // translated out of English.
  1410. std::string notify_name(message.substr(NOTIFY_PREFIX.length()));
  1411. LLNotificationsUtil::add(notify_name);
  1412. }
  1413. else if (message[0] == '/')
  1414. {
  1415. // System message is important, show in upper-right box not tip
  1416. std::string text(message.substr(1));
  1417. LLSD args;
  1418. if (text.substr(0,17) == "RESTART_X_MINUTES")
  1419. {
  1420. S32 mins = 0;
  1421. LLStringUtil::convertToS32(text.substr(18), mins);
  1422. args["MINUTES"] = llformat("%d",mins);
  1423. LLNotificationsUtil::add("RegionRestartMinutes", args);
  1424. }
  1425. else if (text.substr(0,17) == "RESTART_X_SECONDS")
  1426. {
  1427. S32 secs = 0;
  1428. LLStringUtil::convertToS32(text.substr(18), secs);
  1429. args["SECONDS"] = llformat("%d",secs);
  1430. LLNotificationsUtil::add("RegionRestartSeconds", args);
  1431. }
  1432. else
  1433. {
  1434. std::string new_msg =LLNotifications::instance().getGlobalString(text);
  1435. args["MESSAGE"] = new_msg;
  1436. LLNotificationsUtil::add("SystemMessage", args);
  1437. }
  1438. }
  1439. else if (modal)
  1440. {
  1441. LLSD args;
  1442. std::string new_msg =LLNotifications::instance().getGlobalString(message);
  1443. args["ERROR_MESSAGE"] = new_msg;
  1444. LLNotificationsUtil::add("ErrorMessage", args);
  1445. }
  1446. else
  1447. {
  1448. LLSD args;
  1449. std::string new_msg =LLNotifications::instance().getGlobalString(message);
  1450. args["MESSAGE"] = new_msg;
  1451. LLNotificationsUtil::add("SystemMessageTip", args);
  1452. }
  1453. }
  1454. mean_collision_list_t gMeanCollisionList;
  1455. time_t gLastDisplayedTime = 0;
  1456. void handle_show_mean_events(void *)
  1457. {
  1458. if (gNoRender)
  1459. {
  1460. return;
  1461. }
  1462. LLFloaterReg::showInstance("bumps");
  1463. //LLFloaterBump::showInstance();
  1464. }
  1465. void mean_name_callback(const LLUUID &id, const std::string& first, const std::string& last, BOOL always_false)
  1466. {
  1467. if (gNoRender)
  1468. {
  1469. return;
  1470. }
  1471. static const U32 max_collision_list_size = 20;
  1472. if (gMeanCollisionList.size() > max_collision_list_size)
  1473. {
  1474. mean_collision_list_t::iterator iter = gMeanCollisionList.begin();
  1475. for (U32 i=0; i<max_collision_list_size; i++) iter++;
  1476. for_each(iter, gMeanCollisionList.end(), DeletePointer());
  1477. gMeanCollisionList.erase(iter, gMeanCollisionList.end());
  1478. }
  1479. for (mean_collision_list_t::iterator iter = gMeanCollisionList.begin();
  1480.  iter != gMeanCollisionList.end(); ++iter)
  1481. {
  1482. LLMeanCollisionData *mcd = *iter;
  1483. if (mcd->mPerp == id)
  1484. {
  1485. mcd->mFirstName = first;
  1486. mcd->mLastName = last;
  1487. }
  1488. }
  1489. }
  1490. void process_mean_collision_alert_message(LLMessageSystem *msgsystem, void **user_data)
  1491. {
  1492. if (gAgent.inPrelude())
  1493. {
  1494. // In prelude, bumping is OK.  This dialog is rather confusing to 
  1495. // newbies, so we don't show it.  Drop the packet on the floor.
  1496. return;
  1497. }
  1498. // make sure the cursor is back to the usual default since the
  1499. // alert is probably due to some kind of error.
  1500. gViewerWindow->getWindow()->resetBusyCount();
  1501. LLUUID perp;
  1502. U32    time;
  1503. U8    u8type;
  1504. EMeanCollisionType    type;
  1505. F32    mag;
  1506. S32 i, num = msgsystem->getNumberOfBlocks(_PREHASH_MeanCollision);
  1507. for (i = 0; i < num; i++)
  1508. {
  1509. msgsystem->getUUIDFast(_PREHASH_MeanCollision, _PREHASH_Perp, perp);
  1510. msgsystem->getU32Fast(_PREHASH_MeanCollision, _PREHASH_Time, time);
  1511. msgsystem->getF32Fast(_PREHASH_MeanCollision, _PREHASH_Mag, mag);
  1512. msgsystem->getU8Fast(_PREHASH_MeanCollision, _PREHASH_Type, u8type);
  1513. type = (EMeanCollisionType)u8type;
  1514. BOOL b_found = FALSE;
  1515. for (mean_collision_list_t::iterator iter = gMeanCollisionList.begin();
  1516.  iter != gMeanCollisionList.end(); ++iter)
  1517. {
  1518. LLMeanCollisionData *mcd = *iter;
  1519. if ((mcd->mPerp == perp) && (mcd->mType == type))
  1520. {
  1521. mcd->mTime = time;
  1522. mcd->mMag = mag;
  1523. b_found = TRUE;
  1524. break;
  1525. }
  1526. }
  1527. if (!b_found)
  1528. {
  1529. LLMeanCollisionData *mcd = new LLMeanCollisionData(gAgentID, perp, time, type, mag);
  1530. gMeanCollisionList.push_front(mcd);
  1531. const BOOL is_group = FALSE;
  1532. gCacheName->get(perp, is_group, &mean_name_callback);
  1533. }
  1534. }
  1535. }
  1536. void process_frozen_message(LLMessageSystem *msgsystem, void **user_data)
  1537. {
  1538. // make sure the cursor is back to the usual default since the
  1539. // alert is probably due to some kind of error.
  1540. gViewerWindow->getWindow()->resetBusyCount();
  1541. BOOL b_frozen;
  1542. msgsystem->getBOOL("FrozenData", "Data", b_frozen);
  1543. // TODO: make being frozen change view
  1544. if (b_frozen)
  1545. {
  1546. }
  1547. else
  1548. {
  1549. }
  1550. }
  1551. // do some extra stuff once we get our economy data
  1552. void process_economy_data(LLMessageSystem *msg, void** /*user_data*/)
  1553. {
  1554. LLGlobalEconomy::processEconomyData(msg, LLGlobalEconomy::Singleton::getInstance());
  1555. S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
  1556. LL_INFOS_ONCE("Messaging") << "EconomyData message arrived; upload cost is L$" << upload_cost << LL_ENDL;
  1557. gMenuHolder->childSetLabelArg("Upload Image", "[COST]", llformat("%d", upload_cost));
  1558. gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", llformat("%d", upload_cost));
  1559. gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", llformat("%d", upload_cost));
  1560. gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", llformat("%d", upload_cost));
  1561. }
  1562. void notify_cautioned_script_question(const LLSD& notification, const LLSD& response, S32 orig_questions, BOOL granted)
  1563. {
  1564. // only continue if at least some permissions were requested
  1565. if (orig_questions)
  1566. {
  1567. // check to see if the person we are asking
  1568. // "'[OBJECTNAME]', an object owned by '[OWNERNAME]', 
  1569. // located in [REGIONNAME] at [REGIONPOS], 
  1570. // has been <granted|denied> permission to: [PERMISSIONS]."
  1571. LLUIString notice(LLTrans::getString(granted ? "ScriptQuestionCautionChatGranted" : "ScriptQuestionCautionChatDenied"));
  1572. // always include the object name and owner name 
  1573. notice.setArg("[OBJECTNAME]", notification["payload"]["object_name"].asString());
  1574. notice.setArg("[OWNERNAME]", notification["payload"]["owner_name"].asString());
  1575. // try to lookup viewerobject that corresponds to the object that
  1576. // requested permissions (here, taskid->requesting object id)
  1577. BOOL foundpos = FALSE;
  1578. LLViewerObject* viewobj = gObjectList.findObject(notification["payload"]["task_id"].asUUID());
  1579. if (viewobj)
  1580. {
  1581. // found the viewerobject, get it's position in its region
  1582. LLVector3 objpos(viewobj->getPosition());
  1583. // try to lookup the name of the region the object is in
  1584. LLViewerRegion* viewregion = viewobj->getRegion();
  1585. if (viewregion)
  1586. {
  1587. // got the region, so include the region and 3d coordinates of the object
  1588. notice.setArg("[REGIONNAME]", viewregion->getName());
  1589. std::string formatpos = llformat("%.1f, %.1f,%.1f", objpos[VX], objpos[VY], objpos[VZ]);
  1590. notice.setArg("[REGIONPOS]", formatpos);
  1591. foundpos = TRUE;
  1592. }
  1593. }
  1594. if (!foundpos)
  1595. {
  1596. // unable to determine location of the object
  1597. notice.setArg("[REGIONNAME]", "(unknown region)");
  1598. notice.setArg("[REGIONPOS]", "(unknown position)");
  1599. }
  1600. // check each permission that was requested, and list each 
  1601. // permission that has been flagged as a caution permission
  1602. BOOL caution = FALSE;
  1603. S32 count = 0;
  1604. std::string perms;
  1605. for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++)
  1606. {
  1607. if ((orig_questions & LSCRIPTRunTimePermissionBits[i]) && SCRIPT_QUESTION_IS_CAUTION[i])
  1608. {
  1609. count++;
  1610. caution = TRUE;
  1611. // add a comma before the permission description if it is not the first permission
  1612. // added to the list or the last permission to check
  1613. if ((count > 1) && (i < SCRIPT_PERMISSION_EOF))
  1614. {
  1615. perms.append(", ");
  1616. }
  1617. perms.append(LLTrans::getString(SCRIPT_QUESTIONS[i]));
  1618. }
  1619. }
  1620. notice.setArg("[PERMISSIONS]", perms);
  1621. // log a chat message as long as at least one requested permission
  1622. // is a caution permission
  1623. if (caution)
  1624. {
  1625. LLChat chat(notice.getString());
  1626. // LLFloaterChat::addChat(chat, FALSE, FALSE);
  1627. }
  1628. }
  1629. }
  1630. bool script_question_cb(const LLSD& notification, const LLSD& response)
  1631. {
  1632. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  1633. LLMessageSystem *msg = gMessageSystem;
  1634. S32 orig = notification["payload"]["questions"].asInteger();
  1635. S32 new_questions = orig;
  1636. // check whether permissions were granted or denied
  1637. BOOL allowed = TRUE;
  1638. // the "yes/accept" button is the first button in the template, making it button 0
  1639. // if any other button was clicked, the permissions were denied
  1640. if (option != 0)
  1641. {
  1642. new_questions = 0;
  1643. allowed = FALSE;
  1644. }
  1645. LLUUID task_id = notification["payload"]["task_id"].asUUID();
  1646. LLUUID item_id = notification["payload"]["item_id"].asUUID();
  1647. // reply with the permissions granted or denied
  1648. msg->newMessageFast(_PREHASH_ScriptAnswerYes);
  1649. msg->nextBlockFast(_PREHASH_AgentData);
  1650. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  1651. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  1652. msg->nextBlockFast(_PREHASH_Data);
  1653. msg->addUUIDFast(_PREHASH_TaskID, task_id);
  1654. msg->addUUIDFast(_PREHASH_ItemID, item_id);
  1655. msg->addS32Fast(_PREHASH_Questions, new_questions);
  1656. msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
  1657. // only log a chat message if caution prompts are enabled
  1658. if (gSavedSettings.getBOOL("PermissionsCautionEnabled"))
  1659. {
  1660. // log a chat message, if appropriate
  1661. notify_cautioned_script_question(notification, response, orig, allowed);
  1662. }
  1663. if ( response["Mute"] ) // mute
  1664. {
  1665. LLMuteList::getInstance()->add(LLMute(item_id, notification["payload"]["object_name"].asString(), LLMute::OBJECT));
  1666. // purge the message queue of any previously queued requests from the same source. DEV-4879
  1667. class OfferMatcher : public LLNotificationsUI::LLScreenChannel::Matcher
  1668. {
  1669. public:
  1670. OfferMatcher(const LLUUID& to_block) : blocked_id(to_block) {}
  1671. bool matches(const LLNotificationPtr notification) const
  1672. {
  1673. if (notification->getName() == "ScriptQuestionCaution"
  1674. || notification->getName() == "ScriptQuestion")
  1675. {
  1676. return (notification->getPayload()["item_id"].asUUID() == blocked_id);
  1677. }
  1678. return false;
  1679. }
  1680. private:
  1681. const LLUUID& blocked_id;
  1682. };
  1683. LLNotificationsUI::LLChannelManager::getInstance()->killToastsFromChannel(LLUUID(
  1684. gSavedSettings.getString("NotificationChannelUUID")), OfferMatcher(item_id));
  1685. }
  1686. if (response["Details"])
  1687. {
  1688. // respawn notification...
  1689. LLNotificationsUtil::add(notification["name"], notification["substitutions"], notification["payload"]);
  1690. // ...with description on top
  1691. LLNotificationsUtil::add("DebitPermissionDetails");
  1692. }
  1693. return false;
  1694. }
  1695. static LLNotificationFunctorRegistration script_question_cb_reg_1("ScriptQuestion", script_question_cb);
  1696. static LLNotificationFunctorRegistration script_question_cb_reg_2("ScriptQuestionCaution", script_question_cb);
  1697. void process_script_question(LLMessageSystem *msg, void **user_data)
  1698. {
  1699. // *TODO: Translate owner name -> [FIRST] [LAST]
  1700. LLHost sender = msg->getSender();
  1701. LLUUID taskid;
  1702. LLUUID itemid;
  1703. S32 questions;
  1704. std::string object_name;
  1705. std::string owner_name;
  1706. // taskid -> object key of object requesting permissions
  1707. msg->getUUIDFast(_PREHASH_Data, _PREHASH_TaskID, taskid );
  1708. // itemid -> script asset key of script requesting permissions
  1709. msg->getUUIDFast(_PREHASH_Data, _PREHASH_ItemID, itemid );
  1710. msg->getStringFast(_PREHASH_Data, _PREHASH_ObjectName, object_name);
  1711. msg->getStringFast(_PREHASH_Data, _PREHASH_ObjectOwner, owner_name);
  1712. msg->getS32Fast(_PREHASH_Data, _PREHASH_Questions, questions );
  1713. // Special case. If the objects are owned by this agent, throttle per-object instead
  1714. // of per-owner. It's common for residents to reset a ton of scripts that re-request
  1715. // permissions, as with tier boxes. UUIDs can't be valid agent names and vice-versa,
  1716. // so we'll reuse the same namespace for both throttle types.
  1717. std::string throttle_name = owner_name;
  1718. std::string self_name;
  1719. LLAgentUI::buildName( self_name );
  1720. if( owner_name == self_name )
  1721. {
  1722. throttle_name = taskid.getString();
  1723. }
  1724. // don't display permission requests if this object is muted
  1725. if (LLMuteList::getInstance()->isMuted(taskid)) return;
  1726. // throttle excessive requests from any specific user's scripts
  1727. typedef LLKeyThrottle<std::string> LLStringThrottle;
  1728. static LLStringThrottle question_throttle( LLREQUEST_PERMISSION_THROTTLE_LIMIT, LLREQUEST_PERMISSION_THROTTLE_INTERVAL );
  1729. switch (question_throttle.noteAction(throttle_name))
  1730. {
  1731. case LLStringThrottle::THROTTLE_NEWLY_BLOCKED:
  1732. LL_INFOS("Messaging") << "process_script_question throttled"
  1733. << " owner_name:" << owner_name
  1734. << LL_ENDL;
  1735. // Fall through
  1736. case LLStringThrottle::THROTTLE_BLOCKED:
  1737. // Escape altogether until we recover
  1738. return;
  1739. case LLStringThrottle::THROTTLE_OK:
  1740. break;
  1741. }
  1742. std::string script_question;
  1743. if (questions)
  1744. {
  1745. BOOL caution = FALSE;
  1746. S32 count = 0;
  1747. LLSD args;
  1748. args["OBJECTNAME"] = object_name;
  1749. args["NAME"] = owner_name;
  1750. // check the received permission flags against each permission
  1751. for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++)
  1752. {
  1753. if (questions & LSCRIPTRunTimePermissionBits[i])
  1754. {
  1755. count++;
  1756. script_question += "    " + LLTrans::getString(SCRIPT_QUESTIONS[i]) + "n";
  1757. // check whether permission question should cause special caution dialog
  1758. caution |= (SCRIPT_QUESTION_IS_CAUTION[i]);
  1759. }
  1760. }
  1761. args["QUESTIONS"] = script_question;
  1762. LLSD payload;
  1763. payload["task_id"] = taskid;
  1764. payload["item_id"] = itemid;
  1765. payload["sender"] = sender.getIPandPort();
  1766. payload["questions"] = questions;
  1767. payload["object_name"] = object_name;
  1768. payload["owner_name"] = owner_name;
  1769. // check whether cautions are even enabled or not
  1770. if (gSavedSettings.getBOOL("PermissionsCautionEnabled"))
  1771. {
  1772. // display the caution permissions prompt
  1773. LLNotificationsUtil::add(caution ? "ScriptQuestionCaution" : "ScriptQuestion", args, payload);
  1774. }
  1775. else
  1776. {
  1777. // fall back to default behavior if cautions are entirely disabled
  1778. LLNotificationsUtil::add("ScriptQuestion", args, payload);
  1779. }
  1780. }
  1781. }
  1782. void process_derez_container(LLMessageSystem *msg, void**)
  1783. {
  1784. LL_WARNS("Messaging") << "call to deprecated process_derez_container" << LL_ENDL;
  1785. }
  1786. void container_inventory_arrived(LLViewerObject* object,
  1787.  InventoryObjectList* inventory,
  1788.  S32 serial_num,
  1789.  void* data)
  1790. {
  1791. LL_DEBUGS("Messaging") << "container_inventory_arrived()" << LL_ENDL;
  1792. if( gAgent.cameraMouselook() )
  1793. {
  1794. gAgent.changeCameraToDefault();
  1795. }
  1796. LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel();
  1797. if (inventory->size() > 2)
  1798. {
  1799. // create a new inventory category to put this in
  1800. LLUUID cat_id;
  1801. cat_id = gInventory.createNewCategory(gInventory.getRootFolderID(),
  1802.   LLFolderType::FT_NONE,
  1803.   LLTrans::getString("AcquiredItems"));
  1804. InventoryObjectList::const_iterator it = inventory->begin();
  1805. InventoryObjectList::const_iterator end = inventory->end();
  1806. for ( ; it != end; ++it)
  1807. {
  1808. if ((*it)->getType() != LLAssetType::AT_CATEGORY)
  1809. {
  1810. LLInventoryObject* obj = (LLInventoryObject*)(*it);
  1811. LLInventoryItem* item = (LLInventoryItem*)(obj);
  1812. LLUUID item_id;
  1813. item_id.generate();
  1814. time_t creation_date_utc = time_corrected();
  1815. LLPointer<LLViewerInventoryItem> new_item
  1816. = new LLViewerInventoryItem(item_id,
  1817. cat_id,
  1818. item->getPermissions(),
  1819. item->getAssetUUID(),
  1820. item->getType(),
  1821. item->getInventoryType(),
  1822. item->getName(),
  1823. item->getDescription(),
  1824. LLSaleInfo::DEFAULT,
  1825. item->getFlags(),
  1826. creation_date_utc);
  1827. new_item->updateServer(TRUE);
  1828. gInventory.updateItem(new_item);
  1829. }
  1830. }
  1831. gInventory.notifyObservers();
  1832. if(active_panel)
  1833. {
  1834. active_panel->setSelection(cat_id, TAKE_FOCUS_NO);
  1835. }
  1836. }
  1837. else if (inventory->size() == 2)
  1838. {
  1839. // we're going to get one fake root category as well as the
  1840. // one actual object
  1841. InventoryObjectList::iterator it = inventory->begin();
  1842. if ((*it)->getType() == LLAssetType::AT_CATEGORY)
  1843. {
  1844. ++it;
  1845. }
  1846. LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
  1847. const LLUUID category = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(item->getType()));
  1848. LLUUID item_id;
  1849. item_id.generate();
  1850. time_t creation_date_utc = time_corrected();
  1851. LLPointer<LLViewerInventoryItem> new_item
  1852. = new LLViewerInventoryItem(item_id, category,
  1853. item->getPermissions(),
  1854. item->getAssetUUID(),
  1855. item->getType(),
  1856. item->getInventoryType(),
  1857. item->getName(),
  1858. item->getDescription(),
  1859. LLSaleInfo::DEFAULT,
  1860. item->getFlags(),
  1861. creation_date_utc);
  1862. new_item->updateServer(TRUE);
  1863. gInventory.updateItem(new_item);
  1864. gInventory.notifyObservers();
  1865. if(active_panel)
  1866. {
  1867. active_panel->setSelection(item_id, TAKE_FOCUS_NO);
  1868. }
  1869. }
  1870. // we've got the inventory, now delete this object if this was a take
  1871. BOOL delete_object = (BOOL)(intptr_t)data;
  1872. LLViewerRegion *region = gAgent.getRegion();
  1873. if (delete_object && region)
  1874. {
  1875. gMessageSystem->newMessageFast(_PREHASH_ObjectDelete);
  1876. gMessageSystem->nextBlockFast(_PREHASH_AgentData);
  1877. gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  1878. gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  1879. const U8 NO_FORCE = 0;
  1880. gMessageSystem->addU8Fast(_PREHASH_Force, NO_FORCE);
  1881. gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
  1882. gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID());
  1883. gMessageSystem->sendReliable(region->getHost());
  1884. }
  1885. }
  1886. // method to format the time.
  1887. std::string formatted_time(const time_t& the_time)
  1888. {
  1889. std::string dateStr = "["+LLTrans::getString("LTimeWeek")+"] ["
  1890. +LLTrans::getString("LTimeMonth")+"] ["
  1891. +LLTrans::getString("LTimeDay")+"] ["
  1892. +LLTrans::getString("LTimeHour")+"]:["
  1893. +LLTrans::getString("LTimeMin")+"]:["
  1894. +LLTrans::getString("LTimeSec")+"] ["
  1895. +LLTrans::getString("LTimeYear")+"]";
  1896. LLSD substitution;
  1897. substitution["datetime"] = (S32) the_time;
  1898. LLStringUtil::format (dateStr, substitution);
  1899. return dateStr;
  1900. }
  1901. void process_teleport_failed(LLMessageSystem *msg, void**)
  1902. {
  1903. std::string reason;
  1904. std::string big_reason;
  1905. LLSD args;
  1906. // if we have additional alert data
  1907. if (msg->has(_PREHASH_AlertInfo) && msg->getSizeFast(_PREHASH_AlertInfo, _PREHASH_Message) > 0)
  1908. {
  1909. // Get the message ID
  1910. msg->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, reason);
  1911. big_reason = LLAgent::sTeleportErrorMessages[reason];
  1912. if ( big_reason.size() > 0 )
  1913. { // Substitute verbose reason from the local map
  1914. args["REASON"] = big_reason;
  1915. }
  1916. else
  1917. { // Nothing found in the map - use what the server returned in the original message block
  1918. msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, reason);
  1919. args["REASON"] = reason;
  1920. }
  1921. LLSD llsd_block;
  1922. std::string llsd_raw;
  1923. msg->getStringFast(_PREHASH_AlertInfo, _PREHASH_ExtraParams, llsd_raw);
  1924. if (llsd_raw.length())
  1925. {
  1926. std::istringstream llsd_data(llsd_raw);
  1927. if (!LLSDSerialize::deserialize(llsd_block, llsd_data, llsd_raw.length()))
  1928. {
  1929. llwarns << "process_teleport_failed: Attempted to read alert parameter data into LLSD but failed:" << llsd_raw << llendl;
  1930. }
  1931. else
  1932. {
  1933. // change notification name in this special case
  1934. if (handle_special_notification("RegionEntryAccessBlocked", llsd_block))
  1935. {
  1936. if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
  1937. {
  1938. gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
  1939. }
  1940. return;
  1941. }
  1942. }
  1943. }
  1944. }
  1945. else
  1946. {
  1947. msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, reason);
  1948. big_reason = LLAgent::sTeleportErrorMessages[reason];
  1949. if ( big_reason.size() > 0 )
  1950. { // Substitute verbose reason from the local map
  1951. args["REASON"] = big_reason;
  1952. }
  1953. else
  1954. { // Nothing found in the map - use what the server returned
  1955. args["REASON"] = reason;
  1956. }
  1957. }
  1958. LLNotificationsUtil::add("CouldNotTeleportReason", args);
  1959. // Let the interested parties know that teleport failed.
  1960. LLViewerParcelMgr::getInstance()->onTeleportFailed();
  1961. if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
  1962. {
  1963. gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
  1964. }
  1965. }
  1966. void process_teleport_local(LLMessageSystem *msg,void**)
  1967. {
  1968. LLUUID agent_id;
  1969. msg->getUUIDFast(_PREHASH_Info, _PREHASH_AgentID, agent_id);
  1970. if (agent_id != gAgent.getID())
  1971. {
  1972. LL_WARNS("Messaging") << "Got teleport notification for wrong agent!" << LL_ENDL;
  1973. return;
  1974. }
  1975. U32 location_id;
  1976. LLVector3 pos, look_at;
  1977. U32 teleport_flags;
  1978. msg->getU32Fast(_PREHASH_Info, _PREHASH_LocationID, location_id);
  1979. msg->getVector3Fast(_PREHASH_Info, _PREHASH_Position, pos);
  1980. msg->getVector3Fast(_PREHASH_Info, _PREHASH_LookAt, look_at);
  1981. msg->getU32Fast(_PREHASH_Info, _PREHASH_TeleportFlags, teleport_flags);
  1982. if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
  1983. {
  1984. gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
  1985. }
  1986. // Sim tells us whether the new position is off the ground
  1987. if (teleport_flags & TELEPORT_FLAGS_IS_FLYING)
  1988. {
  1989. gAgent.setFlying(TRUE);
  1990. }
  1991. else
  1992. {
  1993. gAgent.setFlying(FALSE);
  1994. }
  1995. gAgent.setPositionAgent(pos);
  1996. gAgent.slamLookAt(look_at);
  1997. // likewise make sure the camera is behind the avatar
  1998. gAgent.resetView(TRUE, TRUE);
  1999. // send camera update to new region
  2000. gAgent.updateCamera();
  2001. send_agent_update(TRUE, TRUE);
  2002. // Let the interested parties know we've teleported.
  2003. // Vadim *HACK: Agent position seems to get reset (to render position?)
  2004. //              on each frame, so we have to pass the new position manually.
  2005. LLViewerParcelMgr::getInstance()->onTeleportFinished(true, gAgent.getPosGlobalFromAgent(pos));
  2006. }
  2007. void send_simple_im(const LLUUID& to_id,
  2008. const std::string& message,
  2009. EInstantMessage dialog,
  2010. const LLUUID& id)
  2011. {
  2012. std::string my_name;
  2013. LLAgentUI::buildFullname(my_name);
  2014. send_improved_im(to_id,
  2015.  my_name,
  2016.  message,
  2017.  IM_ONLINE,
  2018.  dialog,
  2019.  id,
  2020.  NO_TIMESTAMP,
  2021.  (U8*)EMPTY_BINARY_BUCKET,
  2022.  EMPTY_BINARY_BUCKET_SIZE);
  2023. }
  2024. void send_group_notice(const LLUUID& group_id,
  2025.    const std::string& subject,
  2026.    const std::string& message,
  2027.    const LLInventoryItem* item)
  2028. {
  2029. // Put this notice into an instant message form.
  2030. // This will mean converting the item to a binary bucket,
  2031. // and the subject/message into a single field.
  2032. std::string my_name;
  2033. LLAgentUI::buildFullname(my_name);
  2034. // Combine subject + message into a single string.
  2035. std::ostringstream subject_and_message;
  2036. // TODO: turn all existing |'s into ||'s in subject and message.
  2037. subject_and_message << subject << "|" << message;
  2038. // Create an empty binary bucket.
  2039. U8 bin_bucket[MAX_INVENTORY_BUFFER_SIZE];
  2040. U8* bucket_to_send = bin_bucket;
  2041. bin_bucket[0] = '';
  2042. S32 bin_bucket_size = EMPTY_BINARY_BUCKET_SIZE;
  2043. // If there is an item being sent, pack it into the binary bucket.
  2044. if (item)
  2045. {
  2046. LLSD item_def;
  2047. item_def["item_id"] = item->getUUID();
  2048. item_def["owner_id"] = item->getPermissions().getOwner();
  2049. std::ostringstream ostr;
  2050. LLSDSerialize::serialize(item_def, ostr, LLSDSerialize::LLSD_XML);
  2051. bin_bucket_size = ostr.str().copy(
  2052. (char*)bin_bucket, ostr.str().size());
  2053. bin_bucket[bin_bucket_size] = '';
  2054. }
  2055. else
  2056. {
  2057. bucket_to_send = (U8*) EMPTY_BINARY_BUCKET;
  2058. }
  2059.    
  2060. send_improved_im(
  2061. group_id,
  2062. my_name,
  2063. subject_and_message.str(),
  2064. IM_ONLINE,
  2065. IM_GROUP_NOTICE,
  2066. LLUUID::null,
  2067. NO_TIMESTAMP,
  2068. bucket_to_send,
  2069. bin_bucket_size);
  2070. }
  2071. bool handle_lure_callback(const LLSD& notification, const LLSD& response)
  2072. {
  2073. std::string text = response["message"].asString();
  2074. text.append("rn").append(LLAgentUI::buildSLURL());
  2075. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  2076. if(0 == option)
  2077. {
  2078. LLMessageSystem* msg = gMessageSystem;
  2079. msg->newMessageFast(_PREHASH_StartLure);
  2080. msg->nextBlockFast(_PREHASH_AgentData);
  2081. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  2082. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  2083. msg->nextBlockFast(_PREHASH_Info);
  2084. msg->addU8Fast(_PREHASH_LureType, (U8)0); // sim will fill this in.
  2085. msg->addStringFast(_PREHASH_Message, text);
  2086. for(LLSD::array_const_iterator it = notification["payload"]["ids"].beginArray();
  2087. it != notification["payload"]["ids"].endArray();
  2088. ++it)
  2089. {
  2090. LLUUID target_id = it->asUUID();
  2091. msg->nextBlockFast(_PREHASH_TargetData);
  2092. msg->addUUIDFast(_PREHASH_TargetID, target_id);
  2093. // Record the offer.
  2094. {
  2095. std::string target_name;
  2096. gCacheName->getFullName(target_id, target_name);
  2097. LLSD args;
  2098. args["TO_NAME"] = target_name;
  2099. LLSD payload;
  2100. payload["from_id"] = target_id;
  2101. payload["SESSION_NAME"] = target_name;
  2102. payload["SUPPRESS_TOAST"] = true;
  2103. LLNotificationsUtil::add("TeleportOfferSent", args, payload);
  2104. }
  2105. }
  2106. gAgent.sendReliableMessage();
  2107. }
  2108. return false;
  2109. }
  2110. void handle_lure(const LLUUID& invitee)
  2111. {
  2112. LLDynamicArray<LLUUID> ids;
  2113. ids.push_back(invitee);
  2114. handle_lure(ids);
  2115. }
  2116. // Prompt for a message to the invited user.
  2117. void handle_lure(const std::vector<LLUUID>& ids)
  2118. {
  2119. LLSD edit_args;
  2120. edit_args["REGION"] = gAgent.getRegion()->getName();
  2121. LLSD payload;
  2122. for (LLDynamicArray<LLUUID>::const_iterator it = ids.begin();
  2123. it != ids.end();
  2124. ++it)
  2125. {
  2126. payload["ids"].append(*it);
  2127. }
  2128. if (gAgent.isGodlike())
  2129. {
  2130. LLNotificationsUtil::add("OfferTeleportFromGod", edit_args, payload, handle_lure_callback);
  2131. }
  2132. else
  2133. {
  2134. LLNotificationsUtil::add("OfferTeleport", edit_args, payload, handle_lure_callback);
  2135. }
  2136. }
  2137. void send_improved_im(const LLUUID& to_id,
  2138. const std::string& name,
  2139. const std::string& message,
  2140. U8 offline,
  2141. EInstantMessage dialog,
  2142. const LLUUID& id,
  2143. U32 timestamp, 
  2144. const U8* binary_bucket,
  2145. S32 binary_bucket_size)
  2146. {
  2147. pack_instant_message(
  2148. gMessageSystem,
  2149. gAgent.getID(),
  2150. FALSE,
  2151. gAgent.getSessionID(),
  2152. to_id,
  2153. name,
  2154. message,
  2155. offline,
  2156. dialog,
  2157. id,
  2158. 0,
  2159. LLUUID::null,
  2160. gAgent.getPositionAgent(),
  2161. timestamp,
  2162. binary_bucket,
  2163. binary_bucket_size);
  2164. gAgent.sendReliableMessage();
  2165. }
  2166. void send_places_query(const LLUUID& query_id,
  2167.    const LLUUID& trans_id,
  2168.    const std::string& query_text,
  2169.    U32 query_flags,
  2170.    S32 category,
  2171.    const std::string& sim_name)
  2172. {
  2173. LLMessageSystem* msg = gMessageSystem;
  2174. msg->newMessage("PlacesQuery");
  2175. msg->nextBlock("AgentData");
  2176. msg->addUUID("AgentID", gAgent.getID());
  2177. msg->addUUID("SessionID", gAgent.getSessionID());
  2178. msg->addUUID("QueryID", query_id);
  2179. msg->nextBlock("TransactionData");
  2180. msg->addUUID("TransactionID", trans_id);
  2181. msg->nextBlock("QueryData");
  2182. msg->addString("QueryText", query_text);
  2183. msg->addU32("QueryFlags", query_flags);
  2184. msg->addS8("Category", (S8)category);
  2185. msg->addString("SimName", sim_name);
  2186. gAgent.sendReliableMessage();
  2187. }
  2188. void process_user_info_reply(LLMessageSystem* msg, void**)
  2189. {
  2190. LLUUID agent_id;
  2191. msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
  2192. if(agent_id != gAgent.getID())
  2193. {
  2194. LL_WARNS("Messaging") << "process_user_info_reply - "
  2195. << "wrong agent id." << LL_ENDL;
  2196. }
  2197. BOOL im_via_email;
  2198. msg->getBOOLFast(_PREHASH_UserData, _PREHASH_IMViaEMail, im_via_email);
  2199. std::string email;
  2200. msg->getStringFast(_PREHASH_UserData, _PREHASH_EMail, email);
  2201. std::string dir_visibility;
  2202. msg->getString( "UserData", "DirectoryVisibility", dir_visibility);
  2203. LLFloaterPreference::updateUserInfo(dir_visibility, im_via_email, email);
  2204. LLFloaterPostcard::updateUserInfo(email);
  2205. }
  2206. //---------------------------------------------------------------------------
  2207. // Script Dialog
  2208. //---------------------------------------------------------------------------
  2209. const S32 SCRIPT_DIALOG_MAX_BUTTONS = 12;
  2210. const S32 SCRIPT_DIALOG_BUTTON_STR_SIZE = 24;
  2211. const S32 SCRIPT_DIALOG_MAX_MESSAGE_SIZE = 512;
  2212. const char* SCRIPT_DIALOG_HEADER = "Script Dialog:n";
  2213. bool callback_script_dialog(const LLSD& notification, const LLSD& response)
  2214. {
  2215. LLNotificationForm form(notification["form"]);
  2216. std::string button = LLNotification::getSelectedOptionName(response);
  2217. S32 button_idx = LLNotification::getSelectedOption(notification, response);
  2218. // Didn't click "Ignore"
  2219. if (button_idx != -1)
  2220. {
  2221. LLMessageSystem* msg = gMessageSystem;
  2222. msg->newMessage("ScriptDialogReply");
  2223. msg->nextBlock("AgentData");
  2224. msg->addUUID("AgentID", gAgent.getID());
  2225. msg->addUUID("SessionID", gAgent.getSessionID());
  2226. msg->nextBlock("Data");
  2227. msg->addUUID("ObjectID", notification["payload"]["object_id"].asUUID());
  2228. msg->addS32("ChatChannel", notification["payload"]["chat_channel"].asInteger());
  2229. msg->addS32("ButtonIndex", button_idx);
  2230. msg->addString("ButtonLabel", button);
  2231. msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
  2232. }
  2233. return false;
  2234. }
  2235. static LLNotificationFunctorRegistration callback_script_dialog_reg_1("ScriptDialog", callback_script_dialog);
  2236. static LLNotificationFunctorRegistration callback_script_dialog_reg_2("ScriptDialogGroup", callback_script_dialog);
  2237. void process_script_dialog(LLMessageSystem* msg, void**)
  2238. {
  2239. S32 i;
  2240. LLSD payload;
  2241. LLUUID object_id;
  2242. msg->getUUID("Data", "ObjectID", object_id);
  2243. if (LLMuteList::getInstance()->isMuted(object_id))
  2244. {
  2245. return;
  2246. }
  2247. std::string message; 
  2248. std::string first_name;
  2249. std::string last_name;
  2250. std::string title;
  2251. S32 chat_channel;
  2252. msg->getString("Data", "FirstName", first_name);
  2253. msg->getString("Data", "LastName", last_name);
  2254. msg->getString("Data", "ObjectName", title);
  2255. msg->getString("Data", "Message", message);
  2256. msg->getS32("Data", "ChatChannel", chat_channel);
  2257. // unused for now
  2258. LLUUID image_id;
  2259. msg->getUUID("Data", "ImageID", image_id);
  2260. payload["sender"] = msg->getSender().getIPandPort();
  2261. payload["object_id"] = object_id;
  2262. payload["chat_channel"] = chat_channel;
  2263. // build up custom form
  2264. S32 button_count = msg->getNumberOfBlocks("Buttons");
  2265. if (button_count > SCRIPT_DIALOG_MAX_BUTTONS)
  2266. {
  2267. llwarns << "Too many script dialog buttons - omitting some" << llendl;
  2268. button_count = SCRIPT_DIALOG_MAX_BUTTONS;
  2269. }
  2270. LLNotificationForm form;
  2271. for (i = 0; i < button_count; i++)
  2272. {
  2273. std::string tdesc;
  2274. msg->getString("Buttons", "ButtonLabel", tdesc, i);
  2275. form.addElement("button", std::string(tdesc));
  2276. }
  2277. LLSD args;
  2278. args["TITLE"] = title;
  2279. args["MESSAGE"] = message;
  2280. LLNotificationPtr notification;
  2281. if (!first_name.empty())
  2282. {
  2283. args["FIRST"] = first_name;
  2284. args["LAST"] = last_name;
  2285. notification = LLNotifications::instance().add(
  2286. LLNotification::Params("ScriptDialog").substitutions(args).payload(payload).form_elements(form.asLLSD()));
  2287. }
  2288. else
  2289. {
  2290. args["GROUPNAME"] = last_name;
  2291. notification = LLNotifications::instance().add(
  2292. LLNotification::Params("ScriptDialogGroup").substitutions(args).payload(payload).form_elements(form.asLLSD()));
  2293. }
  2294. }
  2295. //---------------------------------------------------------------------------
  2296. std::vector<LLSD> gLoadUrlList;
  2297. bool callback_load_url(const LLSD& notification, const LLSD& response)
  2298. {
  2299. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  2300. if (0 == option)
  2301. {
  2302. LLWeb::loadURL(notification["payload"]["url"].asString());
  2303. }
  2304. return false;
  2305. }
  2306. static LLNotificationFunctorRegistration callback_load_url_reg("LoadWebPage", callback_load_url);
  2307. // We've got the name of the person who owns the object hurling the url.
  2308. // Display confirmation dialog.
  2309. void callback_load_url_name(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group)
  2310. {
  2311. std::vector<LLSD>::iterator it;
  2312. for (it = gLoadUrlList.begin(); it != gLoadUrlList.end(); )
  2313. {
  2314. LLSD load_url_info = *it;
  2315. if (load_url_info["owner_id"].asUUID() == id)
  2316. {
  2317. it = gLoadUrlList.erase(it);
  2318. std::string owner_name;
  2319. if (is_group)
  2320. {
  2321. owner_name = first + LLTrans::getString("Group");
  2322. }
  2323. else
  2324. {
  2325. owner_name = first + " " + last;
  2326. }
  2327. // For legacy name-only mutes.
  2328. if (LLMuteList::getInstance()->isMuted(LLUUID::null, owner_name))
  2329. {
  2330. continue;
  2331. }
  2332. LLSD args;
  2333. args["URL"] = load_url_info["url"].asString();
  2334. args["MESSAGE"] = load_url_info["message"].asString();;
  2335. args["OBJECTNAME"] = load_url_info["object_name"].asString();
  2336. args["NAME"] = owner_name;
  2337. LLNotificationsUtil::add("LoadWebPage", args, load_url_info);
  2338. }
  2339. else
  2340. {
  2341. ++it;
  2342. }
  2343. }
  2344. }
  2345. void process_load_url(LLMessageSystem* msg, void**)
  2346. {
  2347. LLUUID object_id;
  2348. LLUUID owner_id;
  2349. BOOL owner_is_group;
  2350. char object_name[256]; /* Flawfinder: ignore */
  2351. char message[256]; /* Flawfinder: ignore */
  2352. char url[256]; /* Flawfinder: ignore */
  2353. msg->getString("Data", "ObjectName", 256, object_name);
  2354. msg->getUUID(  "Data", "ObjectID", object_id);
  2355. msg->getUUID(  "Data", "OwnerID", owner_id);
  2356. msg->getBOOL(  "Data", "OwnerIsGroup", owner_is_group);
  2357. msg->getString("Data", "Message", 256, message);
  2358. msg->getString("Data", "URL", 256, url);
  2359. LLSD payload;
  2360. payload["object_id"] = object_id;
  2361. payload["owner_id"] = owner_id;
  2362. payload["owner_is_group"] = owner_is_group;
  2363. payload["object_name"] = object_name;
  2364. payload["message"] = message;
  2365. payload["url"] = url;
  2366. // URL is safety checked in load_url above
  2367. // Check if object or owner is muted
  2368. if (LLMuteList::getInstance()->isMuted(object_id, object_name) ||
  2369.     LLMuteList::getInstance()->isMuted(owner_id))
  2370. {
  2371. LL_INFOS("Messaging")<<"Ignoring load_url from muted object/owner."<<LL_ENDL;
  2372. return;
  2373. }
  2374. // Add to list of pending name lookups
  2375. gLoadUrlList.push_back(payload);
  2376. gCacheName->get(owner_id, owner_is_group, &callback_load_url_name);
  2377. }
  2378. void callback_download_complete(void** data, S32 result, LLExtStat ext_status)
  2379. {
  2380. std::string* filepath = (std::string*)data;
  2381. LLSD args;
  2382. args["DOWNLOAD_PATH"] = *filepath;
  2383. LLNotificationsUtil::add("FinishedRawDownload", args);
  2384. delete filepath;
  2385. }
  2386. void process_initiate_download(LLMessageSystem* msg, void**)
  2387. {
  2388. LLUUID agent_id;
  2389. msg->getUUID("AgentData", "AgentID", agent_id);
  2390. if (agent_id != gAgent.getID())
  2391. {
  2392. LL_WARNS("Messaging") << "Initiate download for wrong agent" << LL_ENDL;
  2393. return;
  2394. }
  2395. std::string sim_filename;
  2396. std::string viewer_filename;
  2397. msg->getString("FileData", "SimFilename", sim_filename);
  2398. msg->getString("FileData", "ViewerFilename", viewer_filename);
  2399. if (!gXferManager->validateFileForRequest(viewer_filename))
  2400. {
  2401. llwarns << "SECURITY: Unauthorized download to local file " << viewer_filename << llendl;
  2402. return;
  2403. }
  2404. gXferManager->requestFile(viewer_filename,
  2405. sim_filename,
  2406. LL_PATH_NONE,
  2407. msg->getSender(),
  2408. FALSE, // don't delete remote
  2409. callback_download_complete,
  2410. (void**)new std::string(viewer_filename));
  2411. }
  2412. void process_script_teleport_request(LLMessageSystem* msg, void**)
  2413. {
  2414. std::string object_name;
  2415. std::string sim_name;
  2416. LLVector3 pos;
  2417. LLVector3 look_at;
  2418. msg->getString("Data", "ObjectName", object_name);
  2419. msg->getString("Data", "SimName", sim_name);
  2420. msg->getVector3("Data", "SimPosition", pos);
  2421. msg->getVector3("Data", "LookAt", look_at);
  2422. LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance();
  2423. if(instance)
  2424. {
  2425. instance->trackURL(
  2426.    sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]);
  2427. LLFloaterReg::showInstance("world_map", "center");
  2428. }
  2429. // remove above two lines and replace with below line
  2430. // to re-enable parcel browser for llMapDestination()
  2431. // LLURLDispatcher::dispatch(LLSLURL::buildSLURL(sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]), FALSE);
  2432. }
  2433. void process_covenant_reply(LLMessageSystem* msg, void**)
  2434. {
  2435. LLUUID covenant_id, estate_owner_id;
  2436. std::string estate_name;
  2437. U32 covenant_timestamp;
  2438. msg->getUUID("Data", "CovenantID", covenant_id);
  2439. msg->getU32("Data", "CovenantTimestamp", covenant_timestamp);
  2440. msg->getString("Data", "EstateName", estate_name);
  2441. msg->getUUID("Data", "EstateOwnerID", estate_owner_id);
  2442. LLPanelEstateCovenant::updateEstateName(estate_name);
  2443. LLPanelLandCovenant::updateEstateName(estate_name);
  2444. LLFloaterBuyLand::updateEstateName(estate_name);
  2445. std::string owner_name =
  2446. LLSLURL::buildCommand("agent", estate_owner_id, "inspect");
  2447. LLPanelEstateCovenant::updateEstateOwnerName(owner_name);
  2448. LLPanelLandCovenant::updateEstateOwnerName(owner_name);
  2449. LLFloaterBuyLand::updateEstateOwnerName(owner_name);
  2450. LLPanelPlaceProfile* panel = LLSideTray::getInstance()->findChild<LLPanelPlaceProfile>("panel_place_profile");
  2451. if (panel)
  2452. {
  2453. panel->updateEstateName(estate_name);
  2454. panel->updateEstateOwnerName(owner_name);
  2455. }
  2456. // standard message, not from system
  2457. std::string last_modified;
  2458. if (covenant_timestamp == 0)
  2459. {
  2460. last_modified = LLTrans::getString("covenant_last_modified")+LLTrans::getString("never_text");
  2461. }
  2462. else
  2463. {
  2464. last_modified = LLTrans::getString("covenant_last_modified")+"["
  2465. +LLTrans::getString("LTimeWeek")+"] ["
  2466. +LLTrans::getString("LTimeMonth")+"] ["
  2467. +LLTrans::getString("LTimeDay")+"] ["
  2468. +LLTrans::getString("LTimeHour")+"]:["
  2469. +LLTrans::getString("LTimeMin")+"]:["
  2470. +LLTrans::getString("LTimeSec")+"] ["
  2471. +LLTrans::getString("LTimeYear")+"]";
  2472. LLSD substitution;
  2473. substitution["datetime"] = (S32) covenant_timestamp;
  2474. LLStringUtil::format (last_modified, substitution);
  2475. }
  2476. LLPanelEstateCovenant::updateLastModified(last_modified);
  2477. LLPanelLandCovenant::updateLastModified(last_modified);
  2478. LLFloaterBuyLand::updateLastModified(last_modified);
  2479. // load the actual covenant asset data
  2480. const BOOL high_priority = TRUE;
  2481. if (covenant_id.notNull())
  2482. {
  2483. gAssetStorage->getEstateAsset(gAgent.getRegionHost(),
  2484. gAgent.getID(),
  2485. gAgent.getSessionID(),
  2486. covenant_id,
  2487.                                     LLAssetType::AT_NOTECARD,
  2488. ET_Covenant,
  2489.                                     onCovenantLoadComplete,
  2490. NULL,
  2491. high_priority);
  2492. }
  2493. else
  2494. {
  2495. std::string covenant_text;
  2496. if (estate_owner_id.isNull())
  2497. {
  2498. // mainland
  2499. covenant_text = LLTrans::getString("RegionNoCovenant");
  2500. }
  2501. else
  2502. {
  2503. covenant_text = LLTrans::getString("RegionNoCovenantOtherOwner");
  2504. }
  2505. LLPanelEstateCovenant::updateCovenantText(covenant_text, covenant_id);
  2506. LLPanelLandCovenant::updateCovenantText(covenant_text);
  2507. LLFloaterBuyLand::updateCovenantText(covenant_text, covenant_id);
  2508. if (panel)
  2509. {
  2510. panel->updateCovenantText(covenant_text);
  2511. }
  2512. }
  2513. }
  2514. void onCovenantLoadComplete(LLVFS *vfs,
  2515. const LLUUID& asset_uuid,
  2516. LLAssetType::EType type,
  2517. void* user_data, S32 status, LLExtStat ext_status)
  2518. {
  2519. LL_DEBUGS("Messaging") << "onCovenantLoadComplete()" << LL_ENDL;
  2520. std::string covenant_text;
  2521. if(0 == status)
  2522. {
  2523. LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
  2524. S32 file_length = file.getSize();
  2525. std::vector<char> buffer(file_length+1);
  2526. file.read((U8*)&buffer[0], file_length);
  2527. // put a EOS at the end
  2528. buffer[file_length] = '';
  2529. if( (file_length > 19) && !strncmp( &buffer[0], "Linden text version", 19 ) )
  2530. {
  2531. LLViewerTextEditor::Params params;
  2532. params.name("temp");
  2533. params.max_text_length(file_length+1);
  2534. LLViewerTextEditor * editor = LLUICtrlFactory::create<LLViewerTextEditor> (params);
  2535. if( !editor->importBuffer( &buffer[0], file_length+1 ) )
  2536. {
  2537. LL_WARNS("Messaging") << "Problem importing estate covenant." << LL_ENDL;
  2538. covenant_text = "Problem importing estate covenant.";
  2539. }
  2540. else
  2541. {
  2542. // Version 0 (just text, doesn't include version number)
  2543. covenant_text = editor->getText();
  2544. }
  2545. delete editor;
  2546. }
  2547. else
  2548. {
  2549. LL_WARNS("Messaging") << "Problem importing estate covenant: Covenant file format error." << LL_ENDL;
  2550. covenant_text = "Problem importing estate covenant: Covenant file format error.";
  2551. }
  2552. }
  2553. else
  2554. {
  2555. LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
  2556. if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
  2557.     LL_ERR_FILE_EMPTY == status)
  2558. {
  2559. covenant_text = "Estate covenant notecard is missing from database.";
  2560. }
  2561. else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
  2562. {
  2563. covenant_text = "Insufficient permissions to view estate covenant.";
  2564. }
  2565. else
  2566. {
  2567. covenant_text = "Unable to load estate covenant at this time.";
  2568. }
  2569. LL_WARNS("Messaging") << "Problem loading notecard: " << status << LL_ENDL;
  2570. }
  2571. LLPanelEstateCovenant::updateCovenantText(covenant_text, asset_uuid);
  2572. LLPanelLandCovenant::updateCovenantText(covenant_text);
  2573. LLFloaterBuyLand::updateCovenantText(covenant_text, asset_uuid);
  2574. LLPanelPlaceProfile* panel = LLSideTray::getInstance()->findChild<LLPanelPlaceProfile>("panel_place_profile");
  2575. if (panel)
  2576. {
  2577. panel->updateCovenantText(covenant_text);
  2578. }
  2579. }
  2580. void process_feature_disabled_message(LLMessageSystem* msg, void**)
  2581. {
  2582. // Handle Blacklisted feature simulator response...
  2583. LLUUID agentID;
  2584. LLUUID transactionID;
  2585. std::string messageText;
  2586. msg->getStringFast(_PREHASH_FailureInfo,_PREHASH_ErrorMessage, messageText,0);
  2587. msg->getUUIDFast(_PREHASH_FailureInfo,_PREHASH_AgentID,agentID);
  2588. msg->getUUIDFast(_PREHASH_FailureInfo,_PREHASH_TransactionID,transactionID);
  2589. LL_WARNS("Messaging") << "Blacklisted Feature Response:" << messageText << LL_ENDL;
  2590. }
  2591. // ------------------------------------------------------------
  2592. // Message system exception callbacks
  2593. // ------------------------------------------------------------
  2594. void invalid_message_callback(LLMessageSystem* msg,
  2595.    void*,
  2596.    EMessageException exception)
  2597. {
  2598.     LLAppViewer::instance()->badNetworkHandler();
  2599. }
  2600. // Please do not add more message handlers here. This file is huge.
  2601. // Put them in a file related to the functionality you are implementing.
  2602. void LLOfferInfo::forceResponse(InventoryOfferResponse response)
  2603. {
  2604. LLNotification::Params params("UserGiveItem");
  2605. params.functor.function(boost::bind(&LLOfferInfo::inventory_offer_callback, this, _1, _2));
  2606. LLNotifications::instance().forceResponse(params, response);
  2607. }