00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llviewermessage.h"
00035
00036 #include <deque>
00037
00038 #include "audioengine.h"
00039 #include "indra_constants.h"
00040 #include "lscript_byteformat.h"
00041 #include "mean_collision_data.h"
00042 #include "llfloaterbump.h"
00043 #include "llassetstorage.h"
00044 #include "llcachename.h"
00045 #include "llchat.h"
00046 #include "lldbstrings.h"
00047 #include "lleconomy.h"
00048 #include "llfilepicker.h"
00049 #include "llfocusmgr.h"
00050 #include "llfollowcamparams.h"
00051 #include "llfloaterreleasemsg.h"
00052 #include "llinstantmessage.h"
00053 #include "llquantize.h"
00054 #include "llregionflags.h"
00055 #include "llregionhandle.h"
00056 #include "llsdserialize.h"
00057 #include "llstring.h"
00058 #include "llteleportflags.h"
00059 #include "lltracker.h"
00060 #include "lltransactionflags.h"
00061 #include "llxfermanager.h"
00062 #include "message.h"
00063 #include "sound_ids.h"
00064 #include "lltimer.h"
00065 #include "llmd5.h"
00066
00067 #include "llagent.h"
00068 #include "llcallingcard.h"
00069 #include "llconsole.h"
00070 #include "llvieweraudio.h"
00071 #include "llviewercontrol.h"
00072 #include "lldrawpool.h"
00073 #include "llfirstuse.h"
00074 #include "llfloateractivespeakers.h"
00075 #include "llfloaterbuycurrency.h"
00076 #include "llfloaterbuyland.h"
00077 #include "llfloaterchat.h"
00078 #include "llfloatergroupinfo.h"
00079 #include "llfloaterimagepreview.h"
00080 #include "llfloaterland.h"
00081 #include "llfloaterregioninfo.h"
00082 #include "llfloaterlandholdings.h"
00083 #include "llfloatermap.h"
00084 #include "llurldispatcher.h"
00085 #include "llfloatermute.h"
00086 #include "llfloaterpostcard.h"
00087 #include "llfloaterpreference.h"
00088 #include "llfloaterreleasemsg.h"
00089 #include "llfollowcam.h"
00090 #include "llgroupnotify.h"
00091 #include "llhudeffect.h"
00092 #include "llhudeffecttrail.h"
00093 #include "llhudmanager.h"
00094 #include "llimpanel.h"
00095 #include "llinventorymodel.h"
00096 #include "llinventoryview.h"
00097 #include "llmenugl.h"
00098 #include "llmutelist.h"
00099 #include "llnetmap.h"
00100 #include "llnotify.h"
00101 #include "llpanelgrouplandmoney.h"
00102 #include "llselectmgr.h"
00103 #include "llstartup.h"
00104 #include "llsky.h"
00105 #include "llstatenums.h"
00106 #include "llstatusbar.h"
00107 #include "llimview.h"
00108 #include "lltool.h"
00109 #include "lltoolbar.h"
00110 #include "lltoolmgr.h"
00111 #include "llui.h"
00112 #include "lluploaddialog.h"
00113 #include "llviewercamera.h"
00114 #include "llviewergenericmessage.h"
00115 #include "llviewerinventory.h"
00116 #include "llviewermenu.h"
00117 #include "llviewerobject.h"
00118 #include "llviewerobjectlist.h"
00119 #include "llviewerparcelmgr.h"
00120 #include "llviewerpartsource.h"
00121 #include "llviewerregion.h"
00122 #include "llviewerstats.h"
00123 #include "llviewertexteditor.h"
00124 #include "llviewerthrottle.h"
00125 #include "llviewerwindow.h"
00126 #include "llvlmanager.h"
00127 #include "llvoavatar.h"
00128 #include "llvotextbubble.h"
00129 #include "llweb.h"
00130 #include "llworld.h"
00131 #include "pipeline.h"
00132 #include "llappviewer.h"
00133 #include "llfloaterworldmap.h"
00134 #include "llkeythrottle.h"
00135 #include "llviewerdisplay.h"
00136 #include "llkeythrottle.h"
00137
00138 #include <boost/tokenizer.hpp>
00139
00140 #if LL_WINDOWS // For Windows specific error handler
00141 #include "llwindebug.h"
00142 #endif
00143
00144
00145
00146
00147 const F32 BIRD_AUDIBLE_RADIUS = 32.0f;
00148 const F32 SIT_DISTANCE_FROM_TARGET = 0.25f;
00149 static const F32 LOGOUT_REPLY_TIME = 3.f;
00150
00151
00152
00153 static const U32 LLREQUEST_PERMISSION_THROTTLE_LIMIT = 5;
00154 static const F32 LLREQUEST_PERMISSION_THROTTLE_INTERVAL = 10.0f;
00155
00156 extern BOOL gDebugClicks;
00157
00158
00159 void open_offer(const std::vector<LLUUID>& items, const std::string& from_name);
00160 void friendship_offer_callback(S32 option, void* user_data);
00161 bool check_offer_throttle(const std::string& from_name, bool check_only);
00162
00163
00164 LLFrameTimer gThrottleTimer;
00165 const U32 OFFER_THROTTLE_MAX_COUNT=5;
00166 const F32 OFFER_THROTTLE_TIME=10.f;
00167
00168
00169 const LLString SCRIPT_QUESTIONS[SCRIPT_PERMISSION_EOF] =
00170 {
00171 "ScriptTakeMoney",
00172 "ActOnControlInputs",
00173 "RemapControlInputs",
00174 "AnimateYourAvatar",
00175 "AttachToYourAvatar",
00176 "ReleaseOwnership",
00177 "LinkAndDelink",
00178 "AddAndRemoveJoints",
00179 "ChangePermissions",
00180 "TrackYourCamera",
00181 "ControlYourCamera"
00182 };
00183
00184 struct LLFriendshipOffer
00185 {
00186 LLUUID mFromID;
00187 LLUUID mTransactionID;
00188 BOOL mOnline;
00189 LLHost mHost;
00190 };
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_group,
00201 S32 trx_type, const LLString& desc)
00202 {
00203 if(0 == amount) return;
00204 amount = abs(amount);
00205 LL_INFOS("Messaging") << "give_money(" << uuid << "," << amount << ")"<< LL_ENDL;
00206 if(can_afford_transaction(amount))
00207 {
00208
00209 LLMessageSystem* msg = gMessageSystem;
00210 msg->newMessageFast(_PREHASH_MoneyTransferRequest);
00211 msg->nextBlockFast(_PREHASH_AgentData);
00212 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00213 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00214 msg->nextBlockFast(_PREHASH_MoneyData);
00215 msg->addUUIDFast(_PREHASH_SourceID, gAgent.getID() );
00216 msg->addUUIDFast(_PREHASH_DestID, uuid);
00217 msg->addU8Fast(_PREHASH_Flags, pack_transaction_flags(FALSE, is_group));
00218 msg->addS32Fast(_PREHASH_Amount, amount);
00219 msg->addU8Fast(_PREHASH_AggregatePermNextOwner, (U8)LLAggregatePermissions::AP_EMPTY);
00220 msg->addU8Fast(_PREHASH_AggregatePermInventory, (U8)LLAggregatePermissions::AP_EMPTY);
00221 msg->addS32Fast(_PREHASH_TransactionType, trx_type );
00222 msg->addStringFast(_PREHASH_Description, desc.c_str());
00223 msg->sendReliable(region->getHost());
00224 }
00225 else
00226 {
00227 LLFloaterBuyCurrency::buyCurrency("Giving", amount);
00228 }
00229 }
00230
00231 void send_complete_agent_movement(const LLHost& sim_host)
00232 {
00233 LLMessageSystem* msg = gMessageSystem;
00234 msg->newMessageFast(_PREHASH_CompleteAgentMovement);
00235 msg->nextBlockFast(_PREHASH_AgentData);
00236 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00237 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00238 msg->addU32Fast(_PREHASH_CircuitCode, msg->mOurCircuitCode);
00239 msg->sendReliable(sim_host);
00240 }
00241
00242 void process_logout_reply(LLMessageSystem* msg, void**)
00243 {
00244
00245 LL_DEBUGS("Messaging") << "process_logout_reply" << LL_ENDL;
00246
00247 LLUUID agent_id;
00248 msg->getUUID("AgentData", "AgentID", agent_id);
00249 LLUUID session_id;
00250 msg->getUUID("AgentData", "SessionID", session_id);
00251 if((agent_id != gAgent.getID()) || (session_id != gAgent.getSessionID()))
00252 {
00253 LL_WARNS("Messaging") << "Bogus Logout Reply" << LL_ENDL;
00254 }
00255
00256 LLInventoryModel::update_map_t parents;
00257 S32 count = msg->getNumberOfBlocksFast( _PREHASH_InventoryData );
00258 for(S32 i = 0; i < count; ++i)
00259 {
00260 LLUUID item_id;
00261 msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_ItemID, item_id, i);
00262
00263 if( (1 == count) && item_id.isNull() )
00264 {
00265
00266 break;
00267 }
00268
00269
00270
00271 LL_INFOS("Messaging") << "process_logout_reply itemID=" << item_id << LL_ENDL;
00272 LLInventoryItem* item = gInventory.getItem( item_id );
00273 if( item )
00274 {
00275 parents[item->getParentUUID()] = 0;
00276 gInventory.addChangedMask(LLInventoryObserver::INTERNAL, item_id);
00277 }
00278 else
00279 {
00280 LL_INFOS("Messaging") << "process_logout_reply item not found: " << item_id << LL_ENDL;
00281 }
00282 }
00283 LLAppViewer::instance()->forceQuit();
00284 }
00285
00286 void process_layer_data(LLMessageSystem *mesgsys, void **user_data)
00287 {
00288 LLViewerRegion *regionp = LLWorld::getInstance()->getRegion(mesgsys->getSender());
00289
00290 if (!regionp || gNoRender)
00291 {
00292 return;
00293 }
00294
00295
00296 S32 size;
00297 S8 type;
00298
00299 mesgsys->getS8Fast(_PREHASH_LayerID, _PREHASH_Type, type);
00300 size = mesgsys->getSizeFast(_PREHASH_LayerData, _PREHASH_Data);
00301 if (0 == size)
00302 {
00303 LL_WARNS("Messaging") << "Layer data has zero size." << LL_ENDL;
00304 return;
00305 }
00306 if (size < 0)
00307 {
00308
00309 LL_WARNS("Messaging") << "getSizeFast() returned negative result: "
00310 << size
00311 << LL_ENDL;
00312 return;
00313 }
00314 U8 *datap = new U8[size];
00315 mesgsys->getBinaryDataFast(_PREHASH_LayerData, _PREHASH_Data, datap, size);
00316 LLVLData *vl_datap = new LLVLData(regionp, type, datap, size);
00317 if (mesgsys->getReceiveCompressedSize())
00318 {
00319 gVLManager.addLayerData(vl_datap, mesgsys->getReceiveCompressedSize());
00320 }
00321 else
00322 {
00323 gVLManager.addLayerData(vl_datap, mesgsys->getReceiveSize());
00324 }
00325 }
00326
00327 S32 exported_object_count = 0;
00328 S32 exported_image_count = 0;
00329 S32 current_object_count = 0;
00330 S32 current_image_count = 0;
00331
00332 extern LLNotifyBox *gExporterNotify;
00333 extern LLUUID gExporterRequestID;
00334 extern LLString gExportDirectory;
00335
00336 extern LLUploadDialog *gExportDialog;
00337
00338 LLString gExportedFile;
00339
00340 std::map<LLUUID, LLString> gImageChecksums;
00341
00342 void export_complete()
00343 {
00344 LLUploadDialog::modalUploadFinished();
00345 gExporterRequestID.setNull();
00346 gExportDirectory = "";
00347
00348 LLFILE* fXML = LLFile::fopen(gExportedFile.c_str(), "rb");
00349 fseek(fXML, 0, SEEK_END);
00350 long length = ftell(fXML);
00351 fseek(fXML, 0, SEEK_SET);
00352 U8 *buffer = new U8[length + 1];
00353 size_t nread = fread(buffer, 1, length, fXML);
00354 if (nread < (size_t) length)
00355 {
00356 LL_WARNS("Messaging") << "Short read" << LL_ENDL;
00357 }
00358 buffer[nread] = '\0';
00359 fclose(fXML);
00360
00361 char *pos = (char *)buffer;
00362 while ((pos = strstr(pos+1, "<sl:image ")) != 0)
00363 {
00364 char *pos_check = strstr(pos, "checksum=\"");
00365
00366 if (pos_check)
00367 {
00368 char *pos_uuid = strstr(pos_check, "\">");
00369
00370 if (pos_uuid)
00371 {
00372 char image_uuid_str[UUID_STR_SIZE];
00373 memcpy(image_uuid_str, pos_uuid+2, UUID_STR_SIZE-1);
00374 image_uuid_str[UUID_STR_SIZE-1] = 0;
00375
00376 LLUUID image_uuid(image_uuid_str);
00377
00378 LL_INFOS("Messaging") << "Found UUID: " << image_uuid << LL_ENDL;
00379
00380 std::map<LLUUID, LLString>::iterator itor = gImageChecksums.find(image_uuid);
00381 if (itor != gImageChecksums.end())
00382 {
00383 LL_INFOS("Messaging") << "Replacing with checksum: " << itor->second << LL_ENDL;
00384 if (itor->second.c_str() != NULL)
00385 {
00386 memcpy(&pos_check[10], itor->second.c_str(), 32);
00387 }
00388 }
00389 }
00390 }
00391 }
00392
00393 LLFILE* fXMLOut = LLFile::fopen(gExportedFile.c_str(), "wb");
00394 if (fwrite(buffer, 1, length, fXMLOut) != length)
00395 {
00396 LL_WARNS("Messaging") << "Short write" << LL_ENDL;
00397 }
00398 fclose(fXMLOut);
00399
00400 delete [] buffer;
00401 }
00402
00403
00404 void exported_item_complete(const LLTSCode status, void *user_data)
00405 {
00406
00407
00408 if (status < LLTS_OK)
00409 {
00410 LL_WARNS("Messaging") << "Export failed!" << LL_ENDL;
00411 }
00412 else
00413 {
00414 ++current_object_count;
00415 if (current_image_count == exported_image_count && current_object_count == exported_object_count)
00416 {
00417 LL_INFOS("Messaging") << "*** Export complete ***" << LL_ENDL;
00418
00419 export_complete();
00420 }
00421 else
00422 {
00423 gExportDialog->setMessage(llformat("Exported %d/%d object files, %d/%d textures.", current_object_count, exported_object_count, current_image_count, exported_image_count));
00424 }
00425 }
00426 }
00427
00428 struct exported_image_info
00429 {
00430 LLUUID image_id;
00431 LLString filename;
00432 U32 image_num;
00433 };
00434
00435 void exported_j2c_complete(const LLTSCode status, void *user_data)
00436 {
00437 exported_image_info *info = (exported_image_info *)user_data;
00438 LLUUID image_id = info->image_id;
00439 U32 image_num = info->image_num;
00440 LLString filename = info->filename;
00441 delete info;
00442
00443 if (status < LLTS_OK)
00444 {
00445 LL_WARNS("Messaging") << "Image download failed!" << LL_ENDL;
00446 }
00447 else
00448 {
00449 LLFILE* fIn = LLFile::fopen(filename.c_str(), "rb");
00450 if (fIn)
00451 {
00452 LLPointer<LLImageJ2C> ImageUtility = new LLImageJ2C;
00453 LLPointer<LLImageTGA> TargaUtility = new LLImageTGA;
00454
00455 fseek(fIn, 0, SEEK_END);
00456 S32 length = ftell(fIn);
00457 fseek(fIn, 0, SEEK_SET);
00458 U8 *buffer = ImageUtility->allocateData(length);
00459 if (fread(buffer, 1, length, fIn) != length)
00460 {
00461 LL_WARNS("Messaging") << "Short read" << LL_ENDL;
00462 }
00463 fclose(fIn);
00464 LLFile::remove(filename.c_str());
00465
00466
00467 LLPointer<LLImageRaw> image = new LLImageRaw();
00468
00469 ImageUtility->updateData();
00470 ImageUtility->decode(image, 100000.0f);
00471
00472 TargaUtility->encode(image);
00473 U8 *data = TargaUtility->getData();
00474 S32 data_size = TargaUtility->getDataSize();
00475
00476 char *file_path = new char[filename.size()+1];
00477 strcpy(file_path, filename.c_str());
00478 char *end = strrchr(file_path, gDirUtilp->getDirDelimiter()[0]);
00479 end[0] = 0;
00480 LLString output_file = llformat("%s/image-%03d.tga", file_path, image_num);
00481 delete [] file_path;
00482
00483
00484 LLFILE* fOut = LLFile::fopen(output_file.c_str(), "wb");
00485 char md5_hash_string[33];
00486 strcpy(md5_hash_string, "00000000000000000000000000000000");
00487 if (fOut)
00488 {
00489 if (fwrite(data, 1, data_size, fOut) != data_size)
00490 {
00491 LL_WARNS("Messaging") << "Short write" << LL_ENDL;
00492 }
00493 fseek(fOut, 0, SEEK_SET);
00494 fclose(fOut);
00495 fOut = LLFile::fopen(output_file.c_str(), "rb");
00496 LLMD5 my_md5_hash(fOut);
00497 my_md5_hash.hex_digest(md5_hash_string);
00498 }
00499
00500 gImageChecksums.insert(std::pair<LLUUID, LLString>(image_id, md5_hash_string));
00501 }
00502 }
00503
00504 ++current_image_count;
00505 if (current_image_count == exported_image_count && current_object_count == exported_object_count)
00506 {
00507 LL_INFOS("Messaging") << "*** Export textures complete ***" << LL_ENDL;
00508 export_complete();
00509 }
00510 else
00511 {
00512 gExportDialog->setMessage(llformat("Exported %d/%d object files, %d/%d textures.", current_object_count, exported_object_count, current_image_count, exported_image_count));
00513 }
00514 }
00515
00516 void process_derez_ack(LLMessageSystem*, void**)
00517 {
00518 if(gViewerWindow) gViewerWindow->getWindow()->decBusyCount();
00519 }
00520
00521 void process_places_reply(LLMessageSystem* msg, void** data)
00522 {
00523 LLUUID query_id;
00524
00525 msg->getUUID("AgentData", "QueryID", query_id);
00526 if (query_id.isNull())
00527 {
00528 LLFloaterLandHoldings::processPlacesReply(msg, data);
00529 }
00530 else if(gAgent.isInGroup(query_id))
00531 {
00532 LLPanelGroupLandMoney::processPlacesReply(msg, data);
00533 }
00534 else
00535 {
00536 LL_WARNS("Messaging") << "Got invalid PlacesReply message" << LL_ENDL;
00537 }
00538 }
00539
00540 void send_sound_trigger(const LLUUID& sound_id, F32 gain)
00541 {
00542 if (sound_id.isNull())
00543 {
00544
00545 return;
00546 }
00547
00548 LLMessageSystem* msg = gMessageSystem;
00549 msg->newMessageFast(_PREHASH_SoundTrigger);
00550 msg->nextBlockFast(_PREHASH_SoundData);
00551 msg->addUUIDFast(_PREHASH_SoundID, sound_id);
00552
00553 msg->addUUIDFast(_PREHASH_OwnerID, LLUUID::null );
00554 msg->addUUIDFast(_PREHASH_ObjectID, LLUUID::null );
00555 msg->addUUIDFast(_PREHASH_ParentID, LLUUID::null );
00556
00557 msg->addU64Fast(_PREHASH_Handle, gAgent.getRegion()->getHandle());
00558
00559 LLVector3 position = gAgent.getPositionAgent();
00560 msg->addVector3Fast(_PREHASH_Position, position);
00561 msg->addF32Fast(_PREHASH_Gain, gain);
00562
00563 gAgent.sendMessage();
00564 }
00565
00566 struct LLJoinGroupData
00567 {
00568 LLUUID mGroupID;
00569 LLUUID mTransactionID;
00570 std::string mName;
00571 std::string mMessage;
00572 S32 mFee;
00573 };
00574
00575 void join_group_callback(S32 option, void* user_data)
00576 {
00577 LLJoinGroupData* data = (LLJoinGroupData*)user_data;
00578 BOOL delete_context_data = TRUE;
00579 bool accept_invite = false;
00580
00581 if (option == 2 && data && !data->mGroupID.isNull())
00582 {
00583 LLFloaterGroupInfo::showFromUUID(data->mGroupID);
00584 LLString::format_map_t args;
00585 args["[MESSAGE]"] = data->mMessage;
00586 LLNotifyBox::showXml("JoinGroup", args, &join_group_callback, data);
00587 return;
00588 }
00589 if(option == 0 && data && !data->mGroupID.isNull())
00590 {
00591
00592 S32 max_groups = MAX_AGENT_GROUPS;
00593 if(gAgent.isInGroup(data->mGroupID)) ++max_groups;
00594
00595 if(gAgent.mGroups.count() < max_groups)
00596 {
00597 accept_invite = true;
00598 }
00599 else
00600 {
00601 delete_context_data = FALSE;
00602 LLString::format_map_t args;
00603 args["[NAME]"] = data->mName;
00604 args["[INVITE]"] = data->mMessage;
00605 LLAlertDialog::showXml("JoinedTooManyGroupsMember", args, join_group_callback, (void*)data);
00606 }
00607 }
00608
00609 if (accept_invite)
00610 {
00611
00612
00613 if (data->mFee > 0)
00614 {
00615 delete_context_data = FALSE;
00616 LLString::format_map_t args;
00617 args["[COST]"] = llformat("%d", data->mFee);
00618
00619
00620 data->mFee = 0;
00621 gViewerWindow->alertXml("JoinGroupCanAfford",
00622 args,
00623 join_group_callback,
00624 (void*)data);
00625 }
00626 else
00627 {
00628 send_improved_im(data->mGroupID,
00629 "name",
00630 "message",
00631 IM_ONLINE,
00632 IM_GROUP_INVITATION_ACCEPT,
00633 data->mTransactionID);
00634 }
00635 }
00636 else if (data)
00637 {
00638 send_improved_im(data->mGroupID,
00639 "name",
00640 "message",
00641 IM_ONLINE,
00642 IM_GROUP_INVITATION_DECLINE,
00643 data->mTransactionID);
00644 }
00645
00646 if(delete_context_data)
00647 {
00648 delete data;
00649 data = NULL;
00650 }
00651 }
00652
00653
00654
00655
00656
00657 class LLOpenAgentOffer : public LLInventoryFetchObserver
00658 {
00659 public:
00660 LLOpenAgentOffer(const std::string& from_name) : mFromName(from_name) {}
00661 void done()
00662 {
00663 open_offer(mComplete, mFromName);
00664 gInventory.removeObserver(this);
00665 delete this;
00666 }
00667 private:
00668 std::string mFromName;
00669 };
00670
00671
00672
00673
00674
00675
00676 class LLOpenTaskOffer : public LLInventoryAddedObserver
00677 {
00678 protected:
00679 void done()
00680 {
00681 open_offer(mAdded, "");
00682 mAdded.clear();
00683 }
00684 };
00685
00686
00687 LLOpenTaskOffer* gNewInventoryObserver=NULL;
00688
00689 void start_new_inventory_observer()
00690 {
00691 if (!gNewInventoryObserver)
00692 {
00693
00694 gNewInventoryObserver = new LLOpenTaskOffer;
00695 gInventory.addObserver(gNewInventoryObserver);
00696 }
00697 }
00698
00699 class LLDiscardAgentOffer : public LLInventoryFetchComboObserver
00700 {
00701 public:
00702 LLDiscardAgentOffer(const LLUUID& folder_id, const LLUUID& object_id) :
00703 mFolderID(folder_id),
00704 mObjectID(object_id) {}
00705 virtual ~LLDiscardAgentOffer() {}
00706 virtual void done()
00707 {
00708 LL_DEBUGS("Messaging") << "LLDiscardAgentOffer::done()" << LL_ENDL;
00709 LLUUID trash_id;
00710 trash_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH);
00711 bool notify = false;
00712 if(trash_id.notNull() && mObjectID.notNull())
00713 {
00714 LLInventoryModel::update_list_t update;
00715 LLInventoryModel::LLCategoryUpdate old_folder(mFolderID, -1);
00716 update.push_back(old_folder);
00717 LLInventoryModel::LLCategoryUpdate new_folder(trash_id, 1);
00718 update.push_back(new_folder);
00719 gInventory.accountForUpdate(update);
00720 gInventory.moveObject(mObjectID, trash_id);
00721 LLInventoryObject* obj = gInventory.getObject(mObjectID);
00722 if(obj)
00723 {
00724
00725
00726 obj->updateParentOnServer(FALSE);
00727 notify = true;
00728 }
00729 }
00730 else
00731 {
00732 LL_WARNS("Messaging") << "DiscardAgentOffer unable to find: "
00733 << (trash_id.isNull() ? "trash " : "")
00734 << (mObjectID.isNull() ? "object" : "") << LL_ENDL;
00735 }
00736 gInventory.removeObserver(this);
00737 if(notify)
00738 {
00739 gInventory.notifyObservers();
00740 }
00741 delete this;
00742 }
00743 protected:
00744 LLUUID mFolderID;
00745 LLUUID mObjectID;
00746 };
00747
00748
00749
00750
00751
00752 bool check_offer_throttle(const std::string& from_name, bool check_only)
00753 {
00754 static U32 throttle_count;
00755 static bool throttle_logged;
00756 LLChat chat;
00757 LLString log_message;
00758
00759 if (!gSavedSettings.getBOOL("ShowNewInventory"))
00760 return false;
00761
00762 if (check_only)
00763 {
00764 return gThrottleTimer.hasExpired();
00765 }
00766
00767 if(gThrottleTimer.checkExpirationAndReset(OFFER_THROTTLE_TIME))
00768 {
00769 LL_DEBUGS("Messaging") << "Throttle Expired" << LL_ENDL;
00770 throttle_count=1;
00771 throttle_logged=false;
00772 return true;
00773 }
00774 else
00775 {
00776 LL_DEBUGS("Messaging") << "Throttle Not Expired, Count: " << throttle_count << LL_ENDL;
00777
00778
00779 if (LLStartUp::getStartupState() >= STATE_STARTED
00780 && throttle_count >= OFFER_THROTTLE_MAX_COUNT)
00781 {
00782 if (!throttle_logged)
00783 {
00784
00785
00786 std::ostringstream message;
00787 message << LLAppViewer::instance()->getSecondLifeTitle();
00788 if (!from_name.empty())
00789 {
00790 message << ": Items coming in too fast from " << from_name;
00791 }
00792 else
00793 {
00794 message << ": Items coming in too fast";
00795 }
00796 message << ", automatic preview disabled for "
00797 << OFFER_THROTTLE_TIME << " seconds.";
00798 chat.mText = message.str();
00799
00800 LLFloaterChat::addChat(chat, FALSE, FALSE);
00801 throttle_logged=true;
00802 }
00803 return false;
00804 }
00805 else
00806 {
00807 throttle_count++;
00808 return true;
00809 }
00810 }
00811 }
00812
00813 void open_offer(const std::vector<LLUUID>& items, const std::string& from_name)
00814 {
00815 std::vector<LLUUID>::const_iterator it = items.begin();
00816 std::vector<LLUUID>::const_iterator end = items.end();
00817 LLUUID trash_id(gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH));
00818 LLInventoryItem* item;
00819 for(; it != end; ++it)
00820 {
00821 item = gInventory.getItem(*it);
00822 if(!item)
00823 {
00824 LL_WARNS("Messaging") << "Unable to show inventory item: " << *it << LL_ENDL;
00825 continue;
00826 }
00827 if(gInventory.isObjectDescendentOf(*it, trash_id))
00828 {
00829 continue;
00830 }
00831
00832 if (check_offer_throttle(from_name, false))
00833 {
00834
00835 bool show_keep_discard = item->getPermissions().getCreator() != gAgent.getID();
00836
00837 switch(item->getType())
00838 {
00839 case LLAssetType::AT_NOTECARD:
00840 open_notecard((LLViewerInventoryItem*)item, LLString("Note: ") + item->getName(), LLUUID::null, show_keep_discard, LLUUID::null, FALSE);
00841 break;
00842 case LLAssetType::AT_LANDMARK:
00843 open_landmark((LLViewerInventoryItem*)item, LLString("Landmark: ") + item->getName(), show_keep_discard, LLUUID::null, FALSE);
00844 break;
00845 case LLAssetType::AT_TEXTURE:
00846 open_texture(*it, LLString("Texture: ") + item->getName(), show_keep_discard, LLUUID::null, FALSE);
00847 break;
00848 default:
00849 break;
00850 }
00851 }
00852
00853
00854
00855 LLInventoryView* view = LLInventoryView::getActiveInventory();
00856 if(!view)
00857 {
00858 return;
00859 }
00860
00861
00862 LLUUID trash_id;
00863 trash_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH);
00864 if(gInventory.isObjectDescendentOf(item->getUUID(), trash_id))
00865 {
00866 return;
00867 }
00868 LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND);
00869
00870 BOOL user_is_away = gAwayTimer.getStarted();
00871
00872
00873 if (gInventory.isObjectDescendentOf(item->getUUID(), lost_and_found_id)
00874 && !user_is_away)
00875 {
00876 return;
00877 }
00878
00879
00880
00881
00882
00883 LL_DEBUGS("Messaging") << "Highlighting" << item->getUUID() << LL_ENDL;
00884
00885
00886 LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
00887 view->getPanel()->setSelection(item->getUUID(), TAKE_FOCUS_NO);
00888 gFocusMgr.setKeyboardFocus(focus_ctrl);
00889 }
00890 }
00891
00892 void inventory_offer_mute_callback(const LLUUID& blocked_id,
00893 const char* first_name,
00894 const char* last_name,
00895 BOOL is_group,
00896 void* user_data)
00897 {
00898 LLString from_name;
00899 LLMute::EType type;
00900
00901 if (is_group)
00902 {
00903 type = LLMute::GROUP;
00904 from_name = first_name;
00905 }
00906 else
00907 {
00908 type = LLMute::AGENT;
00909 from_name += first_name;
00910 from_name += " ";
00911 from_name += last_name;
00912 }
00913
00914 LLMute mute(blocked_id, from_name, type);
00915 if (LLMuteList::getInstance()->add(mute))
00916 {
00917 LLFloaterMute::showInstance();
00918 LLFloaterMute::getInstance()->selectMute(blocked_id);
00919 }
00920
00921
00922 class OfferMatcher : public LLNotifyBoxView::Matcher
00923 {
00924 public:
00925 OfferMatcher(const LLUUID& to_block) : blocked_id(to_block) {}
00926 BOOL matches(LLNotifyBox::notify_callback_t callback, void* cb_data) const
00927 {
00928 return callback == inventory_offer_callback && ((LLOfferInfo*)cb_data)->mFromID == blocked_id;
00929 }
00930 private:
00931 const LLUUID& blocked_id;
00932 };
00933 gNotifyBoxView->purgeMessagesMatching(OfferMatcher(blocked_id));
00934 }
00935
00936 void inventory_offer_callback(S32 button, void* user_data)
00937 {
00938 LLChat chat;
00939 LLString log_message;
00940 LLOfferInfo* info = (LLOfferInfo*)user_data;
00941 if(!info) return;
00942
00943
00944
00945
00946
00947
00948 if (2 == button)
00949 {
00950 gCacheName->get(info->mFromID, info->mFromGroup, inventory_offer_mute_callback, user_data);
00951 }
00952
00953 LLMessageSystem* msg = gMessageSystem;
00954 msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
00955 msg->nextBlockFast(_PREHASH_AgentData);
00956 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00957 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00958 msg->nextBlockFast(_PREHASH_MessageBlock);
00959 msg->addBOOLFast(_PREHASH_FromGroup, FALSE);
00960 msg->addUUIDFast(_PREHASH_ToAgentID, info->mFromID);
00961 msg->addU8Fast(_PREHASH_Offline, IM_ONLINE);
00962 msg->addUUIDFast(_PREHASH_ID, info->mTransactionID);
00963 msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP);
00964 std::string name;
00965 gAgent.buildFullname(name);
00966 msg->addStringFast(_PREHASH_FromAgentName, name);
00967 msg->addStringFast(_PREHASH_Message, "");
00968 msg->addU32Fast(_PREHASH_ParentEstateID, 0);
00969 msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null);
00970 msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
00971 LLInventoryObserver* opener = NULL;
00972 LLViewerInventoryCategory* catp = NULL;
00973 catp = (LLViewerInventoryCategory*)gInventory.getCategory(info->mObjectID);
00974 LLViewerInventoryItem* itemp = NULL;
00975 if(!catp)
00976 {
00977 itemp = (LLViewerInventoryItem*)gInventory.getItem(info->mObjectID);
00978 }
00979
00980
00981 LLString from_string;
00982 LLString chatHistory_string;
00983 if (info->mFromObject == TRUE)
00984 {
00985 if (info->mFromGroup)
00986 {
00987 std::string group_name;
00988 if (gCacheName->getGroupName(info->mFromID, group_name))
00989 {
00990 from_string = LLString("An object named '") + info->mFromName + "' owned by the group '" + group_name + "'";
00991 chatHistory_string = info->mFromName + " owned by the group '" + group_name + "'";
00992 }
00993 else
00994 {
00995 from_string = LLString("An object named '") + info->mFromName + "' owned by an unknown group";
00996 chatHistory_string = info->mFromName + " owned by an unknown group";
00997 }
00998 }
00999 else
01000 {
01001 std::string first_name, last_name;
01002 if (gCacheName->getName(info->mFromID, first_name, last_name))
01003 {
01004 from_string = LLString("An object named '") + info->mFromName + "' owned by " + first_name + " " + last_name;
01005 chatHistory_string = info->mFromName + " owned by " + first_name + " " + last_name;
01006 }
01007 else
01008 {
01009 from_string = LLString("An object named '") + info->mFromName + "' owned by an unknown user";
01010 chatHistory_string = info->mFromName + " owned by an unknown user";
01011 }
01012 }
01013 }
01014 else
01015 {
01016 from_string = chatHistory_string = info->mFromName;
01017 }
01018
01019 bool busy=FALSE;
01020
01021 switch(button)
01022 {
01023 case IOR_ACCEPT:
01024
01025
01026
01027
01028
01029 msg->addU8Fast(_PREHASH_Dialog, (U8)(info->mIM + 1));
01030 msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(info->mFolderID.mData),
01031 sizeof(info->mFolderID.mData));
01032
01033 msg->sendReliable(info->mHost);
01034
01035
01036 if (check_offer_throttle(info->mFromName, true))
01037 {
01038 log_message = chatHistory_string + " gave you " + info->mDesc + ".";
01039 chat.mText = log_message;
01040 LLFloaterChat::addChatHistory(chat);
01041 }
01042
01043
01044 LL_DEBUGS("Messaging") << "Initializing an opener for tid: " << info->mTransactionID
01045 << LL_ENDL;
01046 switch (info->mIM)
01047 {
01048 case IM_INVENTORY_OFFERED:
01049 {
01050
01051
01052
01053 LLInventoryFetchObserver::item_ref_t items;
01054 items.push_back(info->mObjectID);
01055 LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(from_string);
01056 open_agent_offer->fetchItems(items);
01057 if(catp || (itemp && itemp->isComplete()))
01058 {
01059 open_agent_offer->done();
01060 }
01061 else
01062 {
01063 opener = open_agent_offer;
01064 }
01065 }
01066 break;
01067 case IM_TASK_INVENTORY_OFFERED:
01068 case IM_GROUP_NOTICE:
01069 case IM_GROUP_NOTICE_REQUESTED:
01070 {
01071
01072
01073
01074
01075 }
01076 break;
01077 default:
01078 LL_WARNS("Messaging") << "inventory_offer_callback: unknown offer type" << LL_ENDL;
01079 break;
01080 }
01081 break;
01082
01083 case IOR_BUSY:
01084
01085 busy=TRUE;
01086 case IOR_MUTE:
01087
01088 case IOR_DECLINE:
01089
01090
01091
01092
01093
01094 default:
01095
01096 msg->addU8Fast(_PREHASH_Dialog, (U8)(info->mIM + 2));
01097 msg->addBinaryDataFast(_PREHASH_BinaryBucket, EMPTY_BINARY_BUCKET, EMPTY_BINARY_BUCKET_SIZE);
01098
01099 msg->sendReliable(info->mHost);
01100
01101 log_message = "You decline " + info->mDesc + " from " + info->mFromName + ".";
01102 chat.mText = log_message;
01103 if( LLMuteList::getInstance()->isMuted(info->mFromID ) && ! LLMuteList::getInstance()->isLinden(info->mFromName) )
01104 {
01105 chat.mMuted = TRUE;
01106 }
01107 LLFloaterChat::addChatHistory(chat);
01108
01109
01110
01111
01112 if(IM_INVENTORY_OFFERED == info->mIM)
01113 {
01114 LLInventoryFetchComboObserver::folder_ref_t folders;
01115 LLInventoryFetchComboObserver::item_ref_t items;
01116 items.push_back(info->mObjectID);
01117 LLDiscardAgentOffer* discard_agent_offer;
01118 discard_agent_offer = new LLDiscardAgentOffer(info->mFolderID, info->mObjectID);
01119 discard_agent_offer->fetch(folders, items);
01120 if(catp || (itemp && itemp->isComplete()))
01121 {
01122 discard_agent_offer->done();
01123 }
01124 else
01125 {
01126 opener = discard_agent_offer;
01127 }
01128
01129 }
01130 if (busy && (!info->mFromGroup && !info->mFromObject))
01131 {
01132 busy_message(msg,info->mFromID);
01133 }
01134 break;
01135 }
01136
01137 if(opener)
01138 {
01139 gInventory.addObserver(opener);
01140 }
01141
01142 delete info;
01143 info = NULL;
01144
01145
01146
01147 gFloaterView->resetStartingFloaterPosition();
01148 }
01149
01150
01151 void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
01152 {
01153
01154
01155 if (gAgent.getBusy())
01156 {
01157 inventory_offer_callback(IOR_BUSY, info);
01158 return;
01159 }
01160
01161
01162 if (LLMuteList::getInstance()->isMuted(info->mFromID, info->mFromName))
01163 {
01164 inventory_offer_callback(IOR_MUTE, info);
01165 return;
01166 }
01167
01168
01169 if (gSavedSettings.getBOOL("AutoAcceptNewInventory")
01170 && (info->mType == LLAssetType::AT_NOTECARD
01171 || info->mType == LLAssetType::AT_LANDMARK
01172 || info->mType == LLAssetType::AT_TEXTURE))
01173 {
01174
01175
01176 inventory_offer_callback(IOR_ACCEPT, info);
01177 return;
01178 }
01179
01180 LLString::format_map_t args;
01181 args["[OBJECTNAME]"] = info->mDesc;
01182
01183 std::string typestr = ll_safe_string(LLAssetType::lookupHumanReadable(info->mType));
01184 if (!typestr.empty())
01185 {
01186 args["[OBJECTTYPE]"] = typestr;
01187 }
01188 else
01189 {
01190 LL_WARNS("Messaging") << "LLAssetType::lookupHumanReadable() returned NULL - probably bad asset type: " << info->mType << LL_ENDL;
01191 args["[OBJECTTYPE]"] = "";
01192
01193
01194 LL_WARNS("Messaging") << "Forcing an inventory-decline for probably-bad asset type." << LL_ENDL;
01195 inventory_offer_callback(IOR_DECLINE, info);
01196 return;
01197 }
01198
01199
01200
01201 BOOL name_found = FALSE;
01202 if (info->mFromGroup)
01203 {
01204 std::string group_name;
01205 if (gCacheName->getGroupName(info->mFromID, group_name))
01206 {
01207 args["[FIRST]"] = group_name;
01208 args["[LAST]"] = "";
01209 name_found = TRUE;
01210 }
01211 }
01212 else
01213 {
01214 std::string first_name, last_name;
01215 if (gCacheName->getName(info->mFromID, first_name, last_name))
01216 {
01217 args["[FIRST]"] = first_name;
01218 args["[LAST]"] = last_name;
01219 name_found = TRUE;
01220 }
01221 }
01222 if (from_task)
01223 {
01224 args["[OBJECTFROMNAME]"] = info->mFromName;
01225 LLNotifyBox::showXml(name_found ? "ObjectGiveItem" : "ObjectGiveItemUnknownUser",
01226 args, &inventory_offer_callback, (void*)info);
01227 }
01228 else
01229 {
01230
01231 args["[NAME]"] = info->mFromName;
01232 LLNotifyBox::showXml("UserGiveItem", args,
01233 &inventory_offer_callback, (void*)info);
01234 }
01235 }
01236
01237
01238 void group_vote_callback(S32 option, void *userdata)
01239 {
01240 LLUUID *group_id = (LLUUID *)userdata;
01241 if (!group_id) return;
01242
01243 switch(option)
01244 {
01245 case 0:
01246
01247
01248 LLFloaterGroupInfo::showFromUUID(*group_id, "voting_tab");
01249 break;
01250 default:
01251
01252
01253 break;
01254 }
01255 delete group_id;
01256 group_id = NULL;
01257 }
01258
01259 struct LLLureInfo
01260 {
01261 LLLureInfo(const LLUUID& from, const LLUUID& lure_id, BOOL godlike) :
01262 mFromID(from),
01263 mLureID(lure_id),
01264 mGodlike(godlike)
01265 {}
01266
01267 LLUUID mFromID;
01268 LLUUID mLureID;
01269 BOOL mGodlike;
01270 };
01271
01272 void lure_callback(S32 option, void* user_data)
01273 {
01274 LLLureInfo* info = (LLLureInfo*)user_data;
01275 if(!info) return;
01276 switch(option)
01277 {
01278 case 0:
01279 {
01280
01281 gAgent.teleportViaLure(info->mLureID, info->mGodlike);
01282 }
01283 break;
01284 case 1:
01285 default:
01286
01287 send_simple_im(info->mFromID,
01288 "",
01289 IM_LURE_DECLINED,
01290 info->mLureID);
01291 break;
01292 }
01293 delete info;
01294 info = NULL;
01295 }
01296
01297 void goto_url_callback(S32 option, void* user_data)
01298 {
01299 char* url = (char*)user_data;
01300 if(1 == option)
01301 {
01302 LLWeb::loadURL(url);
01303 }
01304 delete[] url;
01305 }
01306
01307 void process_improved_im(LLMessageSystem *msg, void **user_data)
01308 {
01309 if (gNoRender)
01310 {
01311 return;
01312 }
01313 LLUUID from_id;
01314 BOOL from_group;
01315 LLUUID to_id;
01316 U8 offline;
01317 U8 d = 0;
01318 LLUUID session_id;
01319 U32 t;
01320 char name[DB_FULL_NAME_BUF_SIZE];
01321 char message[DB_IM_MSG_BUF_SIZE];
01322 U32 parent_estate_id = 0;
01323 LLUUID region_id;
01324 LLVector3 position;
01325 char buffer[DB_IM_MSG_BUF_SIZE * 2];
01326 U8 binary_bucket[MTUBYTES];
01327 S32 binary_bucket_size;
01328 LLChat chat;
01329
01330
01331 msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, from_id);
01332 msg->getBOOLFast(_PREHASH_MessageBlock, _PREHASH_FromGroup, from_group);
01333 msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ToAgentID, to_id);
01334 msg->getU8Fast( _PREHASH_MessageBlock, _PREHASH_Offline, offline);
01335 msg->getU8Fast( _PREHASH_MessageBlock, _PREHASH_Dialog, d);
01336 msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ID, session_id);
01337 msg->getU32Fast( _PREHASH_MessageBlock, _PREHASH_Timestamp, t);
01338
01339 msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, DB_FULL_NAME_BUF_SIZE, name);
01340 msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_Message, DB_IM_MSG_BUF_SIZE, message);
01341 msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_ParentEstateID, parent_estate_id);
01342 msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_RegionID, region_id);
01343 msg->getVector3Fast(_PREHASH_MessageBlock, _PREHASH_Position, position);
01344 msg->getBinaryDataFast( _PREHASH_MessageBlock, _PREHASH_BinaryBucket, binary_bucket, 0, 0, MTUBYTES);
01345 binary_bucket_size = msg->getSizeFast(_PREHASH_MessageBlock, _PREHASH_BinaryBucket);
01346 EInstantMessage dialog = (EInstantMessage)d;
01347 time_t timestamp = (time_t)t;
01348
01349 BOOL is_busy = gAgent.getBusy();
01350 BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat);
01351 BOOL is_linden = LLMuteList::getInstance()->isLinden(name);
01352 BOOL is_owned_by_me = FALSE;
01353
01354 chat.mMuted = is_muted && !is_linden;
01355 chat.mFromID = from_id;
01356 chat.mFromName = name;
01357 chat.mSourceType = (from_id.isNull() || !strcmp(name, SYSTEM_FROM)) ? CHAT_SOURCE_SYSTEM : CHAT_SOURCE_AGENT;
01358
01359 LLViewerObject *source = gObjectList.findObject(session_id);
01360 if (source)
01361 {
01362 is_owned_by_me = source->permYouOwner();
01363 }
01364
01365 char separator_string[3]=": ";
01366 int message_offset=0;
01367
01368
01369 if (!strncmp(message, "/me ", 4) || !strncmp(message, "/me'", 4))
01370 {
01371 strcpy(separator_string,"");
01372 message_offset=3;
01373 }
01374
01375 LLString::format_map_t args;
01376 switch(dialog)
01377 {
01378 case IM_CONSOLE_AND_CHAT_HISTORY:
01379
01380
01381
01382 args["[MESSAGE]"] = message;
01383
01384
01385
01386 LLNotifyBox::showXml("SystemMessageTip",args);
01387 break;
01388
01389 case IM_NOTHING_SPECIAL:
01390
01391 if (!gAgent.isGodlike()
01392 && gAgent.getRegion()->isPrelude()
01393 && to_id.isNull() )
01394 {
01395
01396
01397 }
01398 else if (offline == IM_ONLINE && !is_linden && is_busy && strcmp(name, SYSTEM_FROM))
01399 {
01400
01401
01402 if (!gIMMgr->hasSession(session_id))
01403 {
01404
01405
01406 std::string my_name;
01407 gAgent.buildFullname(my_name);
01408 LLString response = gSavedPerAccountSettings.getText("BusyModeResponse");
01409 pack_instant_message(
01410 gMessageSystem,
01411 gAgent.getID(),
01412 FALSE,
01413 gAgent.getSessionID(),
01414 from_id,
01415 my_name.c_str(),
01416 response.c_str(),
01417 IM_ONLINE,
01418 IM_BUSY_AUTO_RESPONSE,
01419 session_id);
01420 gAgent.sendReliableMessage();
01421 }
01422
01423
01424
01425 snprintf(buffer, sizeof(buffer), "%s%s", separator_string, (message+message_offset));
01426
01427 LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
01428
01429
01430 gIMMgr->addMessage(
01431 session_id,
01432 from_id,
01433 name,
01434 buffer,
01435 NULL,
01436 dialog,
01437 parent_estate_id,
01438 region_id,
01439 position,
01440 true);
01441
01442
01443 snprintf(buffer, sizeof(buffer), "IM: %s%s%s", name, separator_string, (message+message_offset));
01444 chat.mText = buffer;
01445 LLFloaterChat::addChat( chat, TRUE, TRUE );
01446 }
01447 else if (from_id.isNull())
01448 {
01449
01450
01451 snprintf(buffer, sizeof(buffer), "%s: %s", name, message);
01452 chat.mText = buffer;
01453 LLFloaterChat::addChat(chat, FALSE, FALSE);
01454 }
01455 else if (to_id.isNull())
01456 {
01457
01458 args["[NAME]"] = name;
01459 args["[MESSAGE]"] = message;
01460 LLNotifyBox::showXml("GodMessage", args);
01461
01462
01463
01464
01465 snprintf(buffer, sizeof(buffer), "%s%s%s", name, separator_string, (message+message_offset));
01466 chat.mText = buffer;
01467 BOOL local_agent = TRUE;
01468 LLFloaterChat::addChat(chat, FALSE, local_agent);
01469 }
01470 else
01471 {
01472
01473 char saved[MAX_STRING];
01474 saved[0] = '\0';
01475 if(offline == IM_OFFLINE)
01476 {
01477 char time_buf[TIME_STR_LENGTH];
01478 snprintf(saved, MAX_STRING, "(Saved %s) ",
01479 formatted_time(timestamp, time_buf));
01480 }
01481 snprintf(buffer, sizeof(buffer), "%s%s%s", separator_string, saved,(message+message_offset));
01482
01483 LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
01484
01485 if (!is_muted || is_linden)
01486 {
01487 gIMMgr->addMessage(
01488 session_id,
01489 from_id,
01490 name,
01491 buffer,
01492 NULL,
01493 dialog,
01494 parent_estate_id,
01495 region_id,
01496 position,
01497 true);
01498 snprintf(buffer, sizeof(buffer), "IM: %s%s%s%s", name, separator_string, saved, (message+message_offset));
01499
01500 chat.mText = buffer;
01501 BOOL local_agent = FALSE;
01502 LLFloaterChat::addChat( chat, TRUE, local_agent );
01503 }
01504 else
01505 {
01506
01507
01508
01509 chat.mText = buffer;
01510 BOOL local_agent = TRUE;
01511 LLFloaterChat::addChat( chat, TRUE, local_agent );
01512 }
01513 }
01514 break;
01515
01516 case IM_TYPING_START:
01517 {
01518 LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
01519 gIMMgr->processIMTypingStart(im_info);
01520 }
01521 break;
01522
01523 case IM_TYPING_STOP:
01524 {
01525 LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
01526 gIMMgr->processIMTypingStop(im_info);
01527 }
01528 break;
01529
01530 case IM_MESSAGEBOX:
01531 {
01532
01533
01534 args["[MESSAGE]"] = message;
01535 LLNotifyBox::showXml("SystemMessage", args);
01536 }
01537 break;
01538 case IM_GROUP_NOTICE:
01539 case IM_GROUP_NOTICE_REQUESTED:
01540 {
01541 LL_INFOS("Messaging") << "Received IM_GROUP_NOTICE message." << LL_ENDL;
01542
01543 struct notice_bucket_header_t
01544 {
01545 U8 has_inventory;
01546 U8 asset_type;
01547 LLUUID group_id;
01548 };
01549 struct notice_bucket_full_t
01550 {
01551 struct notice_bucket_header_t header;
01552 U8 item_name[DB_INV_ITEM_NAME_BUF_SIZE];
01553 }* notice_bin_bucket;
01554
01555
01556
01557 if ( (binary_bucket_size < (S32)((sizeof(notice_bucket_header_t) + sizeof(U8))))
01558 || (binary_bucket[binary_bucket_size - 1] != '\0') )
01559 {
01560 LL_WARNS("Messaging") << "Malformed group notice binary bucket" << LL_ENDL;
01561 break;
01562 }
01563
01564 notice_bin_bucket = (struct notice_bucket_full_t*) &binary_bucket[0];
01565 U8 has_inventory = notice_bin_bucket->header.has_inventory;
01566 U8 asset_type = notice_bin_bucket->header.asset_type;
01567 LLUUID group_id = notice_bin_bucket->header.group_id;
01568 const char* item_name = (const char*) notice_bin_bucket->item_name;
01569
01570
01571 LLOfferInfo* info = NULL;
01572 if (has_inventory)
01573 {
01574 info = new LLOfferInfo;
01575 info->mIM = IM_GROUP_NOTICE;
01576 info->mFromID = from_id;
01577 info->mFromGroup = from_group;
01578 info->mTransactionID = session_id;
01579 info->mType = (LLAssetType::EType) asset_type;
01580 info->mFolderID = gInventory.findCategoryUUIDForType(info->mType);
01581 std::string from_name;
01582
01583 from_name += "A group member named ";
01584 from_name += name;
01585
01586 info->mFromName = from_name;
01587 info->mDesc = item_name;
01588 info->mHost = msg->getSender();
01589 }
01590
01591 std::string str(message);
01592
01593
01594
01595 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
01596 boost::char_separator<char> sep("|","",boost::keep_empty_tokens);
01597 tokenizer tokens(str, sep);
01598 tokenizer::iterator iter = tokens.begin();
01599
01600 LLString subj(*iter++);
01601 LLString mes(*iter++);
01602
01603 if (IM_GROUP_NOTICE == dialog)
01604 {
01605 subj += "\n";
01606 mes = "\n\n" + mes;
01607 LLGroupNotifyBox::show(subj.c_str(),mes.c_str(),name,group_id,t,has_inventory,item_name,info);
01608 }
01609 else if (IM_GROUP_NOTICE_REQUESTED == dialog)
01610 {
01611 LLFloaterGroupInfo::showNotice(subj.c_str(),mes.c_str(),group_id,has_inventory,item_name,info);
01612 }
01613 }
01614 break;
01615 case IM_GROUP_INVITATION:
01616 {
01617
01618 if ((is_busy || is_muted))
01619 {
01620 LLMessageSystem *msg = gMessageSystem;
01621 join_group_callback(1, NULL);
01622 busy_message(msg,from_id);
01623 }
01624 else
01625 {
01626 LL_INFOS("Messaging") << "Received IM_GROUP_INVITATION message." << LL_ENDL;
01627
01628 struct invite_bucket_t
01629 {
01630 S32 membership_fee;
01631 LLUUID role_id;
01632 }* invite_bucket;
01633
01634
01635 if (binary_bucket_size != sizeof(invite_bucket_t))
01636 {
01637 LL_WARNS("Messaging") << "Malformed group invite binary bucket" << LL_ENDL;
01638 break;
01639 }
01640
01641 invite_bucket = (struct invite_bucket_t*) &binary_bucket[0];
01642 S32 membership_fee = ntohl(invite_bucket->membership_fee);
01643
01644 LLJoinGroupData* userdata = new LLJoinGroupData;
01645 userdata->mTransactionID = session_id;
01646 userdata->mGroupID = from_id;
01647 userdata->mName.assign(name);
01648 userdata->mMessage.assign(message);
01649 userdata->mFee = membership_fee;
01650
01651 LLString::format_map_t args;
01652 args["[MESSAGE]"] = message;
01653 LLNotifyBox::showXml("JoinGroup", args,
01654 &join_group_callback,
01655 (void*)userdata);
01656 }
01657 }
01658 break;
01659
01660 case IM_INVENTORY_OFFERED:
01661 case IM_TASK_INVENTORY_OFFERED:
01662
01663 {
01664 LLOfferInfo* info = new LLOfferInfo;
01665
01666 if (IM_INVENTORY_OFFERED == dialog)
01667 {
01668 struct offer_agent_bucket_t
01669 {
01670 S8 asset_type;
01671 LLUUID object_id;
01672 }* bucketp;
01673
01674 if (sizeof(offer_agent_bucket_t) != binary_bucket_size)
01675 {
01676 LL_WARNS("Messaging") << "Malformed inventory offer from agent" << LL_ENDL;
01677 break;
01678 }
01679 bucketp = (struct offer_agent_bucket_t*) &binary_bucket[0];
01680 info->mType = (LLAssetType::EType) bucketp->asset_type;
01681 info->mObjectID = bucketp->object_id;
01682 }
01683 else
01684 {
01685 if (sizeof(S8) != binary_bucket_size)
01686 {
01687 LL_WARNS("Messaging") << "Malformed inventory offer from object" << LL_ENDL;
01688 break;
01689 }
01690 info->mType = (LLAssetType::EType) binary_bucket[0];
01691 info->mObjectID = LLUUID::null;
01692 }
01693
01694 info->mIM = dialog;
01695 info->mFromID = from_id;
01696 info->mFromGroup = from_group;
01697 info->mTransactionID = session_id;
01698 info->mFolderID = gInventory.findCategoryUUIDForType(info->mType);
01699
01700 if (dialog == IM_TASK_INVENTORY_OFFERED)
01701 {
01702 info->mFromObject = TRUE;
01703 }
01704 else
01705 {
01706 info->mFromObject = FALSE;
01707 }
01708 info->mFromName = name;
01709 info->mDesc = message;
01710 info->mHost = msg->getSender();
01711
01712 if ( is_muted )
01713 {
01714
01715 inventory_offer_callback(-1, info);
01716 }
01717 else
01718 {
01719 inventory_offer_handler(info, dialog == IM_TASK_INVENTORY_OFFERED);
01720 }
01721 }
01722 break;
01723
01724 case IM_INVENTORY_ACCEPTED:
01725 {
01726 args["[NAME]"] = name;
01727 LLNotifyBox::showXml("InventoryAccepted", args);
01728 break;
01729 }
01730 case IM_INVENTORY_DECLINED:
01731 {
01732 args["[NAME]"] = name;
01733 LLNotifyBox::showXml("InventoryDeclined", args);
01734 break;
01735 }
01736 case IM_GROUP_VOTE:
01737 {
01738 LLUUID *userdata = new LLUUID(session_id);
01739 args["[NAME]"] = name;
01740 args["[MESSAGE]"] = message;
01741 LLNotifyBox::showXml("GroupVote", args,
01742 &group_vote_callback, userdata);
01743 }
01744 break;
01745
01746 case IM_GROUP_ELECTION_DEPRECATED:
01747 {
01748 LL_WARNS("Messaging") << "Received IM: IM_GROUP_ELECTION_DEPRECATED" << LL_ENDL;
01749 }
01750 break;
01751
01752 case IM_SESSION_SEND:
01753 {
01754 if (!is_linden && is_busy)
01755 {
01756 return;
01757 }
01758
01759
01760
01761 if ( !gIMMgr->hasSession(session_id) )
01762 {
01763 return;
01764 }
01765
01766
01767 char saved[MAX_STRING];
01768 saved[0] = '\0';
01769 if(offline == IM_OFFLINE)
01770 {
01771 char time_buf[TIME_STR_LENGTH];
01772 snprintf(saved,
01773 MAX_STRING,
01774 "(Saved %s) ",
01775 formatted_time(timestamp, time_buf));
01776 }
01777 snprintf(buffer, sizeof(buffer), "%s%s%s", separator_string, saved, (message+message_offset));
01778 BOOL is_this_agent = FALSE;
01779 if(from_id == gAgentID)
01780 {
01781 is_this_agent = TRUE;
01782 }
01783 gIMMgr->addMessage(
01784 session_id,
01785 from_id,
01786 name,
01787 buffer,
01788 (char*)binary_bucket,
01789 IM_SESSION_INVITE,
01790 parent_estate_id,
01791 region_id,
01792 position,
01793 true);
01794
01795 snprintf(buffer, sizeof(buffer), "IM: %s%s%s%s", name, separator_string, saved, (message+message_offset));
01796 chat.mText = buffer;
01797 LLFloaterChat::addChat(chat, TRUE, is_this_agent);
01798 }
01799 break;
01800
01801 case IM_FROM_TASK:
01802 if (is_busy && !is_owned_by_me)
01803 {
01804 return;
01805 }
01806 snprintf(buffer, sizeof(buffer), "%s%s%s", name, separator_string, (message+message_offset));
01807
01808
01809 chat.mText = buffer;
01810 chat.mSourceType = CHAT_SOURCE_OBJECT;
01811 LLFloaterChat::addChat(chat, FALSE, FALSE);
01812 break;
01813 case IM_FROM_TASK_AS_ALERT:
01814 if (is_busy && !is_owned_by_me)
01815 {
01816 return;
01817 }
01818 {
01819
01820 args["[NAME]"] = name;
01821 args["[MESSAGE]"] = message;
01822 LLNotifyBox::showXml("ObjectMessage", args);
01823 }
01824 break;
01825 case IM_BUSY_AUTO_RESPONSE:
01826 if (is_muted)
01827 {
01828 LL_DEBUGS("Messaging") << "Ignoring busy response from " << from_id << LL_ENDL;
01829 return;
01830 }
01831 else
01832 {
01833
01834 snprintf(buffer, sizeof(buffer), "%s (%s): %s", name, "busy response", (message+message_offset));
01835 gIMMgr->addMessage(session_id, from_id, name, buffer);
01836 }
01837 break;
01838
01839 case IM_LURE_USER:
01840 {
01841 if (is_muted)
01842 {
01843 return;
01844 }
01845 else if (is_busy)
01846 {
01847 busy_message(msg,from_id);
01848 }
01849 else
01850 {
01851
01852 LLLureInfo* info = new LLLureInfo(from_id, session_id, FALSE);
01853 args["[NAME]"] = name;
01854 args["[MESSAGE]"] = message;
01855 LLNotifyBox::showXml("OfferTeleport", args,
01856 lure_callback, (void*)info);
01857 }
01858 }
01859 break;
01860
01861 case IM_GODLIKE_LURE_USER:
01862 {
01863 LLLureInfo* info = new LLLureInfo(from_id, session_id, TRUE);
01864
01865
01866 lure_callback(0, (void *)info);
01867 }
01868 break;
01869
01870 case IM_GOTO_URL:
01871 {
01872
01873
01874 if (binary_bucket_size <= 0)
01875 {
01876 LL_WARNS("Messaging") << "bad binary_bucket_size: "
01877 << binary_bucket_size
01878 << " - aborting function." << LL_ENDL;
01879 return;
01880 }
01881
01882 char* url = new char[binary_bucket_size];
01883 if (url == NULL)
01884 {
01885 LL_ERRS("Messaging") << "Memory Allocation failed" << LL_ENDL;
01886 return;
01887 }
01888
01889 strncpy(url, (char*)binary_bucket, binary_bucket_size-1);
01890 url[binary_bucket_size-1] = '\0';
01891 args["[MESSAGE]"] = message;
01892 args["[URL]"] = url;
01893 LLNotifyBox::showXml("GotoURL", args,
01894 goto_url_callback, (void*)url);
01895 }
01896 break;
01897
01898 case IM_FRIENDSHIP_OFFERED:
01899 {
01900 LLFriendshipOffer* offer = new LLFriendshipOffer;
01901 offer->mFromID = from_id;
01902 offer->mTransactionID = session_id;
01903 offer->mOnline = (offline == IM_ONLINE);
01904 offer->mHost = msg->getSender();
01905
01906 if (is_busy)
01907 {
01908 busy_message(msg, from_id);
01909 friendship_offer_callback(1, (void*)offer);
01910 }
01911 else if (is_muted)
01912 {
01913 friendship_offer_callback(1, (void*)offer);
01914 }
01915 else
01916 {
01917 args["[NAME]"] = name;
01918 LLNotifyBox::showXml("OfferFriendship", args,
01919 &friendship_offer_callback, (void*)offer);
01920 }
01921 }
01922 break;
01923
01924 case IM_FRIENDSHIP_ACCEPTED:
01925 {
01926
01927
01928
01929 LLAvatarTracker::formFriendship(from_id);
01930
01931 std::vector<std::string> strings;
01932 strings.push_back(from_id.asString());
01933 send_generic_message("requestonlinenotification", strings);
01934
01935 args["[NAME]"] = name;
01936 LLNotifyBox::showXml("FriendshipAccepted", args);
01937 }
01938 break;
01939
01940 case IM_FRIENDSHIP_DECLINED:
01941 args["[NAME]"] = name;
01942 LLNotifyBox::showXml("FriendshipDeclined", args);
01943 break;
01944
01945 default:
01946 LL_WARNS("Messaging") << "Instant message calling for unknown dialog "
01947 << (S32)dialog << LL_ENDL;
01948 break;
01949 }
01950
01951 LLWindow* viewer_window = gViewerWindow->getWindow();
01952 if (viewer_window && viewer_window->getMinimized())
01953 {
01954 viewer_window->flashIcon(5.f);
01955 }
01956 }
01957
01958 void busy_message (LLMessageSystem* msg, LLUUID from_id)
01959 {
01960 if (gAgent.getBusy())
01961 {
01962 std::string my_name;
01963 gAgent.buildFullname(my_name);
01964 LLString response = gSavedPerAccountSettings.getText("BusyModeResponse");
01965 pack_instant_message(
01966 gMessageSystem,
01967 gAgent.getID(),
01968 FALSE,
01969 gAgent.getSessionID(),
01970 from_id,
01971 my_name.c_str(),
01972 response.c_str(),
01973 IM_ONLINE,
01974 IM_BUSY_AUTO_RESPONSE);
01975 gAgent.sendReliableMessage();
01976 }
01977 }
01978
01979 void friendship_offer_callback(S32 option, void* user_data)
01980 {
01981 LLFriendshipOffer* offer = (LLFriendshipOffer*)user_data;
01982 if(!offer) return;
01983 LLUUID fid;
01984 LLMessageSystem* msg = gMessageSystem;
01985 switch(option)
01986 {
01987 case 0:
01988
01989 LLAvatarTracker::formFriendship(offer->mFromID);
01990
01991 fid = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
01992
01993
01994 msg->newMessageFast(_PREHASH_AcceptFriendship);
01995 msg->nextBlockFast(_PREHASH_AgentData);
01996 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
01997 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
01998 msg->nextBlockFast(_PREHASH_TransactionBlock);
01999 msg->addUUIDFast(_PREHASH_TransactionID, offer->mTransactionID);
02000 msg->nextBlockFast(_PREHASH_FolderData);
02001 msg->addUUIDFast(_PREHASH_FolderID, fid);
02002 msg->sendReliable(offer->mHost);
02003 break;
02004 case 1:
02005
02006 msg->newMessageFast(_PREHASH_DeclineFriendship);
02007 msg->nextBlockFast(_PREHASH_AgentData);
02008 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
02009 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
02010 msg->nextBlockFast(_PREHASH_TransactionBlock);
02011 msg->addUUIDFast(_PREHASH_TransactionID, offer->mTransactionID);
02012 msg->sendReliable(offer->mHost);
02013 break;
02014 default:
02015
02016 break;
02017 }
02018
02019 delete offer;
02020 offer = NULL;
02021 }
02022
02023 struct LLCallingCardOfferData
02024 {
02025 LLUUID mTransactionID;
02026 LLUUID mSourceID;
02027 LLHost mHost;
02028 };
02029
02030 void callingcard_offer_callback(S32 option, void* user_data)
02031 {
02032 LLCallingCardOfferData* offerdata = (LLCallingCardOfferData*)user_data;
02033 if(!offerdata) return;
02034 LLUUID fid;
02035 LLUUID from_id;
02036 LLMessageSystem* msg = gMessageSystem;
02037 switch(option)
02038 {
02039 case 0:
02040
02041 msg->newMessageFast(_PREHASH_AcceptCallingCard);
02042 msg->nextBlockFast(_PREHASH_AgentData);
02043 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
02044 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
02045 msg->nextBlockFast(_PREHASH_TransactionBlock);
02046 msg->addUUIDFast(_PREHASH_TransactionID, offerdata->mTransactionID);
02047 fid = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
02048 msg->nextBlockFast(_PREHASH_FolderData);
02049 msg->addUUIDFast(_PREHASH_FolderID, fid);
02050 msg->sendReliable(offerdata->mHost);
02051 break;
02052 case 1:
02053
02054 msg->newMessageFast(_PREHASH_DeclineCallingCard);
02055 msg->nextBlockFast(_PREHASH_AgentData);
02056 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
02057 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
02058 msg->nextBlockFast(_PREHASH_TransactionBlock);
02059 msg->addUUIDFast(_PREHASH_TransactionID, offerdata->mTransactionID);
02060 msg->sendReliable(offerdata->mHost);
02061 busy_message(msg, offerdata->mSourceID);
02062 break;
02063 default:
02064
02065 break;
02066 }
02067
02068 delete offerdata;
02069 offerdata = NULL;
02070 }
02071
02072 void process_offer_callingcard(LLMessageSystem* msg, void**)
02073 {
02074
02075 LL_DEBUGS("Messaging") << "callingcard offer" << LL_ENDL;
02076
02077 LLUUID source_id;
02078 msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, source_id);
02079 LLUUID tid;
02080 msg->getUUIDFast(_PREHASH_AgentBlock, _PREHASH_TransactionID, tid);
02081
02082 LLCallingCardOfferData* offerdata = new LLCallingCardOfferData;
02083 offerdata->mTransactionID = tid;
02084 offerdata->mSourceID = source_id;
02085 offerdata->mHost = msg->getSender();
02086
02087 LLViewerObject* source = gObjectList.findObject(source_id);
02088 LLString::format_map_t args;
02089 std::string source_name;
02090 if(source && source->isAvatar())
02091 {
02092 LLNameValue* nvfirst = source->getNVPair("FirstName");
02093 LLNameValue* nvlast = source->getNVPair("LastName");
02094 if (nvfirst && nvlast)
02095 {
02096 args["[FIRST]"] = nvfirst->getString();
02097 args["[LAST]"] = nvlast->getString();
02098 source_name = std::string(nvfirst->getString()) + " " + nvlast->getString();
02099 }
02100 }
02101
02102 if(!source_name.empty())
02103 {
02104 if (gAgent.getBusy()
02105 || LLMuteList::getInstance()->isMuted(source_id, source_name, LLMute::flagTextChat))
02106 {
02107
02108 callingcard_offer_callback(1, (void*)offerdata);
02109 offerdata = NULL;
02110 }
02111 else
02112 {
02113 LLNotifyBox::showXml("OfferCallingCard", args,
02114 &callingcard_offer_callback, (void*)offerdata);
02115 offerdata = NULL;
02116 }
02117 }
02118 else
02119 {
02120 LL_WARNS("Messaging") << "Calling card offer from an unknown source." << LL_ENDL;
02121 }
02122
02123 delete offerdata;
02124 offerdata = NULL;
02125 }
02126
02127 void process_accept_callingcard(LLMessageSystem* msg, void**)
02128 {
02129 LLNotifyBox::showXml("CallingCardAccepted");
02130 }
02131
02132 void process_decline_callingcard(LLMessageSystem* msg, void**)
02133 {
02134 LLNotifyBox::showXml("CallingCardDeclined");
02135 }
02136
02137
02138 void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
02139 {
02140 LLChat chat;
02141 char mesg[DB_CHAT_MSG_BUF_SIZE];
02142 char from_name[DB_FULL_NAME_BUF_SIZE];
02143 U8 source_temp;
02144 U8 type_temp;
02145 U8 audible_temp;
02146 LLColor4 color(1.0f, 1.0f, 1.0f, 1.0f);
02147 LLUUID from_id;
02148 LLUUID owner_id;
02149 BOOL is_owned_by_me = FALSE;
02150 LLViewerObject* chatter;
02151
02152 msg->getString("ChatData", "FromName", DB_FULL_NAME_BUF_SIZE, from_name);
02153 chat.mFromName = from_name;
02154
02155 msg->getUUID("ChatData", "SourceID", from_id);
02156 chat.mFromID = from_id;
02157
02158
02159 msg->getUUID("ChatData", "OwnerID", owner_id);
02160
02161 msg->getU8Fast(_PREHASH_ChatData, _PREHASH_SourceType, source_temp);
02162 chat.mSourceType = (EChatSourceType)source_temp;
02163
02164 msg->getU8("ChatData", "ChatType", type_temp);
02165 chat.mChatType = (EChatType)type_temp;
02166
02167 msg->getU8Fast(_PREHASH_ChatData, _PREHASH_Audible, audible_temp);
02168 chat.mAudible = (EChatAudible)audible_temp;
02169
02170 chat.mTime = LLFrameTimer::getElapsedSeconds();
02171
02172 BOOL is_self = (from_id == gAgent.getID());
02173 BOOL is_busy = gAgent.getBusy();
02174
02175 BOOL is_muted = FALSE;
02176 BOOL is_linden = FALSE;
02177 is_muted = LLMuteList::getInstance()->isMuted(
02178 from_id,
02179 from_name,
02180 LLMute::flagTextChat)
02181 || LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagTextChat);
02182 is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT &&
02183 LLMuteList::getInstance()->isLinden(from_name);
02184
02185 BOOL is_audible = (CHAT_AUDIBLE_FULLY == chat.mAudible);
02186 chatter = gObjectList.findObject(from_id);
02187 if (chatter)
02188 {
02189 chat.mPosAgent = chatter->getPositionAgent();
02190
02191
02192 if (chat.mSourceType == CHAT_SOURCE_OBJECT
02193 && chat.mChatType != CHAT_TYPE_DEBUG_MSG)
02194 {
02195 LLPointer<LLViewerPartSourceChat> psc = new LLViewerPartSourceChat(chatter->getPositionAgent());
02196 psc->setSourceObject(chatter);
02197 psc->setColor(color);
02198
02199
02200 psc->setOwnerUUID(owner_id);
02201 LLViewerPartSim::getInstance()->addPartSource(psc);
02202 }
02203
02204
02205 if (is_audible
02206 && (is_linden || (!is_muted && !is_busy)))
02207 {
02208 if (chat.mChatType != CHAT_TYPE_START
02209 && chat.mChatType != CHAT_TYPE_STOP)
02210 {
02211 gAgent.heardChat(chat.mFromID);
02212 }
02213 }
02214
02215 is_owned_by_me = chatter->permYouOwner();
02216 }
02217
02218 if (is_audible)
02219 {
02220 BOOL visible_in_chat_bubble = FALSE;
02221 std::string verb;
02222
02223 color.setVec(1.f,1.f,1.f,1.f);
02224 msg->getStringFast(_PREHASH_ChatData, _PREHASH_Message, DB_CHAT_MSG_BUF_SIZE, mesg);
02225
02226 BOOL ircstyle = FALSE;
02227
02228
02229 if (!strncmp(mesg, "/me ", 4) || !strncmp(mesg, "/me'", 4))
02230 {
02231 chat.mText = from_name;
02232 chat.mText += (mesg + 3);
02233 ircstyle = TRUE;
02234 }
02235 else
02236 {
02237 chat.mText = mesg;
02238 }
02239
02240
02241 if (CHAT_TYPE_START == chat.mChatType)
02242 {
02243 LLLocalSpeakerMgr::getInstance()->setSpeakerTyping(from_id, TRUE);
02244
02245
02246 if (chatter && chatter->isAvatar())
02247 {
02248 ((LLVOAvatar*)chatter)->startTyping();
02249 }
02250 return;
02251 }
02252 else if (CHAT_TYPE_STOP == chat.mChatType)
02253 {
02254 LLLocalSpeakerMgr::getInstance()->setSpeakerTyping(from_id, FALSE);
02255
02256
02257 if (chatter && chatter->isAvatar())
02258 {
02259 ((LLVOAvatar*)chatter)->stopTyping();
02260 }
02261 return;
02262 }
02263
02264
02265 if (chatter && chatter->isAvatar())
02266 {
02267 LLLocalSpeakerMgr::getInstance()->setSpeakerTyping(from_id, FALSE);
02268 ((LLVOAvatar*)chatter)->stopTyping();
02269
02270 if (!is_muted && !is_busy)
02271 {
02272 visible_in_chat_bubble = gSavedSettings.getBOOL("UseChatBubbles");
02273 ((LLVOAvatar*)chatter)->addChat(chat);
02274 }
02275 }
02276
02277
02278 if (ircstyle)
02279 {
02280
02281 }
02282 else
02283 {
02284 switch(chat.mChatType)
02285 {
02286 case CHAT_TYPE_WHISPER:
02287 if (is_self)
02288 {
02289 verb = " whisper: ";
02290 }
02291 else
02292 {
02293 verb = " whispers: ";
02294 }
02295 break;
02296 case CHAT_TYPE_DEBUG_MSG:
02297 case CHAT_TYPE_OWNER:
02298 case CHAT_TYPE_NORMAL:
02299 verb = ": ";
02300 break;
02301 case CHAT_TYPE_SHOUT:
02302 if (is_self)
02303 {
02304 verb = " shout: ";
02305 }
02306 else
02307 {
02308 verb = " shouts: ";
02309 }
02310 break;
02311 case CHAT_TYPE_START:
02312 case CHAT_TYPE_STOP:
02313 LL_WARNS("Messaging") << "Got chat type start/stop in main chat processing." << LL_ENDL;
02314 break;
02315 default:
02316 LL_WARNS("Messaging") << "Unknown type " << chat.mChatType << " in chat!" << LL_ENDL;
02317 verb = " say, ";
02318 break;
02319 }
02320
02321 if (is_self)
02322 {
02323 chat.mText = "You";
02324 }
02325 else
02326 {
02327 chat.mText = from_name;
02328 }
02329 chat.mText += verb;
02330 chat.mText += mesg;
02331 }
02332
02333 if (chatter)
02334 {
02335 chat.mPosAgent = chatter->getPositionAgent();
02336 }
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350 chat.mMuted = is_muted && !is_linden;
02351
02352
02353 if (!visible_in_chat_bubble
02354 && (is_linden || !is_busy || is_owned_by_me))
02355 {
02356
02357 LLFloaterChat::addChat(chat, FALSE, FALSE);
02358 }
02359 else
02360 {
02361
02362 LLFloaterChat::addChatHistory(chat);
02363 }
02364 }
02365 }
02366
02367
02368
02369
02370
02371
02372
02373
02374 void process_teleport_start(LLMessageSystem *msg, void**)
02375 {
02376 U32 teleport_flags = 0x0;
02377 msg->getU32("Info", "TeleportFlags", teleport_flags);
02378
02379 if (teleport_flags & TELEPORT_FLAGS_DISABLE_CANCEL)
02380 {
02381 gViewerWindow->setProgressCancelButtonVisible(FALSE, "");
02382 }
02383 else
02384 {
02385 gViewerWindow->setProgressCancelButtonVisible(TRUE, "Cancel");
02386 }
02387
02388
02389
02390
02391 if( gAgent.getTeleportState() == LLAgent::TELEPORT_NONE )
02392 {
02393 gTeleportDisplay = TRUE;
02394 gAgent.setTeleportState( LLAgent::TELEPORT_START );
02395 make_ui_sound("UISndTeleportOut");
02396
02397
02398
02399 }
02400 }
02401
02402 void process_teleport_progress(LLMessageSystem* msg, void**)
02403 {
02404 LLUUID agent_id;
02405 msg->getUUID("AgentData", "AgentID", agent_id);
02406 if((gAgent.getID() != agent_id)
02407 || (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE))
02408 {
02409 LL_WARNS("Messaging") << "Unexpected teleport progress message." << LL_ENDL;
02410 return;
02411 }
02412 U32 teleport_flags = 0x0;
02413 msg->getU32("Info", "TeleportFlags", teleport_flags);
02414 if (teleport_flags & TELEPORT_FLAGS_DISABLE_CANCEL)
02415 {
02416 gViewerWindow->setProgressCancelButtonVisible(FALSE, "");
02417 }
02418 else
02419 {
02420 gViewerWindow->setProgressCancelButtonVisible(TRUE, "Cancel");
02421 }
02422 char buffer[MAX_STRING];
02423 msg->getString("Info", "Message", MAX_STRING, buffer);
02424 LL_DEBUGS("Messaging") << "teleport progress: " << buffer << LL_ENDL;
02425
02426
02427
02428 LLString message = buffer;
02429
02430 if (LLAgent::sTeleportProgressMessages.find(buffer) !=
02431 LLAgent::sTeleportProgressMessages.end() )
02432 {
02433 message = LLAgent::sTeleportProgressMessages[buffer];
02434 }
02435
02436 gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages[message]);
02437 }
02438
02439 class LLFetchInWelcomeArea : public LLInventoryFetchDescendentsObserver
02440 {
02441 public:
02442 LLFetchInWelcomeArea() {}
02443 virtual void done()
02444 {
02445 LLIsType is_landmark(LLAssetType::AT_LANDMARK);
02446 LLIsType is_card(LLAssetType::AT_CALLINGCARD);
02447
02448 LLInventoryModel::cat_array_t card_cats;
02449 LLInventoryModel::item_array_t card_items;
02450 LLInventoryModel::cat_array_t land_cats;
02451 LLInventoryModel::item_array_t land_items;
02452
02453 folder_ref_t::iterator it = mCompleteFolders.begin();
02454 folder_ref_t::iterator end = mCompleteFolders.end();
02455 for(; it != end; ++it)
02456 {
02457 gInventory.collectDescendentsIf(
02458 (*it),
02459 land_cats,
02460 land_items,
02461 LLInventoryModel::EXCLUDE_TRASH,
02462 is_landmark);
02463 gInventory.collectDescendentsIf(
02464 (*it),
02465 card_cats,
02466 card_items,
02467 LLInventoryModel::EXCLUDE_TRASH,
02468 is_card);
02469 }
02470 LLString::format_map_t args;
02471 if ( land_items.count() > 0 )
02472 {
02473 S32 random_land = ll_rand( land_items.count() - 1 );
02474 args["[NAME]"] = land_items[random_land]->getName();
02475 LLNotifyBox::showXml("TeleportToLandmark",args);
02476 }
02477 if ( card_items.count() > 0 )
02478 {
02479 S32 random_card = ll_rand( card_items.count() - 1 );
02480 args["[NAME]"] = card_items[random_card]->getName();
02481 LLNotifyBox::showXml("TeleportToPerson",args);
02482 }
02483
02484 gInventory.removeObserver(this);
02485 delete this;
02486 }
02487 };
02488
02489
02490
02491 class LLPostTeleportNotifiers : public LLEventTimer
02492 {
02493 public:
02494 LLPostTeleportNotifiers();
02495 virtual ~LLPostTeleportNotifiers();
02496
02497
02498 virtual BOOL tick();
02499 };
02500
02501 LLPostTeleportNotifiers::LLPostTeleportNotifiers() : LLEventTimer( 2.0 )
02502 {
02503 };
02504
02505 LLPostTeleportNotifiers::~LLPostTeleportNotifiers()
02506 {
02507 }
02508
02509 BOOL LLPostTeleportNotifiers::tick()
02510 {
02511 BOOL all_done = FALSE;
02512 if ( gAgent.getTeleportState() == LLAgent::TELEPORT_NONE )
02513 {
02514
02515 LLInventoryFetchDescendentsObserver::folder_ref_t folders;
02516 LLUUID folder_id;
02517 folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
02518 if(folder_id.notNull())
02519 folders.push_back(folder_id);
02520 folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK);
02521 if(folder_id.notNull())
02522 folders.push_back(folder_id);
02523 if(!folders.empty())
02524 {
02525 LLFetchInWelcomeArea* fetcher = new LLFetchInWelcomeArea;
02526 fetcher->fetchDescendents(folders);
02527 if(fetcher->isEverythingComplete())
02528 {
02529 fetcher->done();
02530 }
02531 else
02532 {
02533 gInventory.addObserver(fetcher);
02534 }
02535 }
02536 all_done = TRUE;
02537 }
02538
02539 return all_done;
02540 }
02541
02542
02543
02544
02545
02546 void process_teleport_finish(LLMessageSystem* msg, void**)
02547 {
02548 LL_DEBUGS("Messaging") << "Got teleport location message" << LL_ENDL;
02549 LLUUID agent_id;
02550 msg->getUUIDFast(_PREHASH_Info, _PREHASH_AgentID, agent_id);
02551 if (agent_id != gAgent.getID())
02552 {
02553 LL_WARNS("Messaging") << "Got teleport notification for wrong agent!" << LL_ENDL;
02554 return;
02555 }
02556
02557
02558
02559 LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
02560 effectp->setPositionGlobal(gAgent.getPositionGlobal());
02561 effectp->setColor(LLColor4U(gAgent.getEffectColor()));
02562 LLHUDManager::getInstance()->sendEffects();
02563
02564 U32 location_id;
02565 U32 sim_ip;
02566 U16 sim_port;
02567 LLVector3 pos, look_at;
02568 U64 region_handle;
02569 msg->getU32Fast(_PREHASH_Info, _PREHASH_LocationID, location_id);
02570 msg->getIPAddrFast(_PREHASH_Info, _PREHASH_SimIP, sim_ip);
02571 msg->getIPPortFast(_PREHASH_Info, _PREHASH_SimPort, sim_port);
02572
02573
02574 msg->getU64Fast(_PREHASH_Info, _PREHASH_RegionHandle, region_handle);
02575 U32 teleport_flags;
02576 msg->getU32Fast(_PREHASH_Info, _PREHASH_TeleportFlags, teleport_flags);
02577
02578
02579 char seedCap[STD_STRING_BUF_SIZE];
02580 msg->getStringFast(_PREHASH_Info, _PREHASH_SeedCapability,
02581 STD_STRING_BUF_SIZE, seedCap);
02582
02583
02584 if((teleport_flags & TELEPORT_FLAGS_SET_HOME_TO_TARGET)
02585 && (!gAgent.isGodlike()))
02586 {
02587 gAgent.setHomePosRegion(region_handle, pos);
02588
02589
02590
02591 new LLPostTeleportNotifiers();
02592 }
02593
02594 LLHost sim_host(sim_ip, sim_port);
02595
02596
02597 gMessageSystem->enableCircuit(sim_host, TRUE);
02598 LLViewerRegion* regionp = LLWorld::getInstance()->addRegion(region_handle, sim_host);
02599
02600
02601
02602
02603
02604
02605
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616
02617
02618
02619
02620
02621 LL_INFOS("Messaging") << "process_teleport_finish() Enabling "
02622 << sim_host << " with code " << msg->mOurCircuitCode << LL_ENDL;
02623 msg->newMessageFast(_PREHASH_UseCircuitCode);
02624 msg->nextBlockFast(_PREHASH_CircuitCode);
02625 msg->addU32Fast(_PREHASH_Code, msg->getOurCircuitCode());
02626 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
02627 msg->addUUIDFast(_PREHASH_ID, gAgent.getID());
02628 msg->sendReliable(sim_host);
02629
02630 send_complete_agent_movement(sim_host);
02631 gAgent.setTeleportState( LLAgent::TELEPORT_MOVING );
02632 gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages["contacting"]);
02633
02634 regionp->setSeedCapability(std::string(seedCap));
02635
02636
02637
02638
02639
02640
02641
02642 effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
02643 effectp->setPositionGlobal(gAgent.getPositionGlobal());
02644
02645 effectp->setColor(LLColor4U(gAgent.getEffectColor()));
02646 LLHUDManager::getInstance()->sendEffects();
02647
02648
02649
02650
02651
02652
02653 LLFirstUse::useTeleport();
02654 }
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666 static void display_release_message(S32, void* data)
02667 {
02668 std::string* msg = (std::string*)data;
02669 LLFloaterReleaseMsg::displayMessage(msg->c_str());
02670 delete msg;
02671 }
02672
02673 void process_agent_movement_complete(LLMessageSystem* msg, void**)
02674 {
02675 gAgentMovementCompleted = TRUE;
02676
02677 LLUUID agent_id;
02678 msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
02679 LLUUID session_id;
02680 msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_SessionID, session_id);
02681 if((gAgent.getID() != agent_id) || (gAgent.getSessionID() != session_id))
02682 {
02683 LL_WARNS("Messaging") << "Incorrect id in process_agent_movement_complete()"
02684 << LL_ENDL;
02685 return;
02686 }
02687
02688 LL_DEBUGS("Messaging") << "process_agent_movement_complete()" << LL_ENDL;
02689
02690
02691
02692 LLVector3 agent_pos;
02693 msg->getVector3Fast(_PREHASH_Data, _PREHASH_Position, agent_pos);
02694 LLVector3 look_at;
02695 msg->getVector3Fast(_PREHASH_Data, _PREHASH_LookAt, look_at);
02696 U64 region_handle;
02697 msg->getU64Fast(_PREHASH_Data, _PREHASH_RegionHandle, region_handle);
02698
02699 char version_channel_char[MAX_STRING];
02700 msg->getString("SimData", "ChannelVersion", MAX_STRING, version_channel_char);
02701
02702 LLVOAvatar* avatarp = gAgent.getAvatarObject();
02703 if (!avatarp)
02704 {
02705
02706
02707 LL_WARNS("Messaging") << "agent_movement_complete() with NULL avatarp." << LL_ENDL;
02708 }
02709
02710 F32 x, y;
02711 from_region_handle(region_handle, &x, &y);
02712 LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle);
02713 if (!regionp)
02714 {
02715 if (gAgent.getRegion())
02716 {
02717 LL_WARNS("Messaging") << "current region " << gAgent.getRegion()->getOriginGlobal() << LL_ENDL;
02718 }
02719
02720 LL_WARNS("Messaging") << "Agent being sent to invalid home region: "
02721 << x << ":" << y
02722 << " current pos " << gAgent.getPositionGlobal()
02723 << LL_ENDL;
02724 LLAppViewer::instance()->forceDisconnect("You were sent to an invalid region.");
02725 return;
02726
02727 }
02728
02729 LL_INFOS("Messaging") << "Changing home region to " << x << ":" << y << LL_ENDL;
02730
02731
02732
02733 LLVector3 shift_vector = regionp->getPosRegionFromGlobal(
02734 gAgent.getRegion()->getOriginGlobal());
02735 gAgent.setRegion(regionp);
02736 gObjectList.shiftObjects(shift_vector);
02737 gAssetStorage->setUpstream(msg->getSender());
02738 gCacheName->setUpstream(msg->getSender());
02739 gViewerThrottle.sendToSim();
02740 gViewerWindow->sendShapeToSim();
02741
02742 bool is_teleport = gAgent.getTeleportState() == LLAgent::TELEPORT_MOVING;
02743
02744 if( is_teleport )
02745 {
02746
02747 gAgent.setFocusOnAvatar(TRUE, FALSE);
02748 gAgent.slamLookAt(look_at);
02749 gAgent.updateCamera();
02750
02751 gAgent.setTeleportState( LLAgent::TELEPORT_START_ARRIVAL );
02752
02753
02754
02755 gAgent.sendAgentSetAppearance();
02756
02757 if (avatarp)
02758 {
02759
02760 LLChat chat("Teleport completed from " + gAgent.getTeleportSourceSLURL());
02761 chat.mSourceType = CHAT_SOURCE_SYSTEM;
02762 LLFloaterChat::addChatHistory(chat);
02763
02764
02765 avatarp->setPositionAgent(agent_pos);
02766 avatarp->clearChat();
02767 avatarp->slamPosition();
02768 }
02769 }
02770 else
02771 {
02772
02773 gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
02774 }
02775
02776 if ( LLTracker::isTracking(NULL) )
02777 {
02778
02779 LLVector3d beacon_pos = LLTracker::getTrackedPositionGlobal();
02780 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);
02781 if (beacon_dir.magVecSquared() < 25.f)
02782 {
02783 LLTracker::stopTracking(NULL);
02784 }
02785 else if ( is_teleport )
02786 {
02787
02788 LLVector3 global_agent_pos = agent_pos;
02789 global_agent_pos[0] += x;
02790 global_agent_pos[1] += y;
02791 look_at = (LLVector3)beacon_pos - global_agent_pos;
02792 look_at.normVec();
02793 gAgent.slamLookAt(look_at);
02794 }
02795 }
02796
02797
02798
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809
02810 send_agent_update(TRUE, TRUE);
02811
02812 if (gAgent.getRegion()->getBlockFly())
02813 {
02814 gAgent.setFlying(gAgent.canFly());
02815 }
02816
02817
02818 if (gAgent.getBusy())
02819 {
02820 gAgent.setBusy();
02821 }
02822 else
02823 {
02824 gAgent.clearBusy();
02825 }
02826
02827 if (avatarp)
02828 {
02829 avatarp->mFootPlane.clearVec();
02830 }
02831
02832
02833 gAgent.sendWalkRun(gAgent.getRunning() || gAgent.getAlwaysRun());
02834
02835 if (LLFloaterReleaseMsg::checkVersion(version_channel_char))
02836 {
02837 LLNotifyBox::showXml("ServerVersionChanged", display_release_message, new std::string(version_channel_char) );
02838 }
02839 }
02840
02841 void process_crossed_region(LLMessageSystem* msg, void**)
02842 {
02843 LLUUID agent_id;
02844 msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
02845 LLUUID session_id;
02846 msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_SessionID, session_id);
02847 if((gAgent.getID() != agent_id) || (gAgent.getSessionID() != session_id))
02848 {
02849 LL_WARNS("Messaging") << "Incorrect id in process_crossed_region()"
02850 << LL_ENDL;
02851 return;
02852 }
02853 LL_INFOS("Messaging") << "process_crossed_region()" << LL_ENDL;
02854
02855 U32 sim_ip;
02856 msg->getIPAddrFast(_PREHASH_RegionData, _PREHASH_SimIP, sim_ip);
02857 U16 sim_port;
02858 msg->getIPPortFast(_PREHASH_RegionData, _PREHASH_SimPort, sim_port);
02859 LLHost sim_host(sim_ip, sim_port);
02860 U64 region_handle;
02861 msg->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);
02862
02863 char seedCap[STD_STRING_BUF_SIZE];
02864 msg->getStringFast(_PREHASH_RegionData, _PREHASH_SeedCapability, STD_STRING_BUF_SIZE, seedCap);
02865
02866 send_complete_agent_movement(sim_host);
02867
02868 LLViewerRegion* regionp = LLWorld::getInstance()->addRegion(region_handle, sim_host);
02869 regionp->setSeedCapability(std::string(seedCap));
02870 }
02871
02872
02873
02874
02875
02876
02877 const F32 THRESHOLD_HEAD_ROT_QDOT = 0.9997f;
02878 const F32 MAX_HEAD_ROT_QDOT = 0.99999f;
02879
02880
02881
02882 void send_agent_update(BOOL force_send, BOOL send_reliable)
02883 {
02884 if (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
02885 {
02886
02887
02888 return;
02889 }
02890
02891
02892 if(LLAppViewer::instance()->logoutRequestSent())
02893 {
02894 return;
02895 }
02896
02897
02898 if(gAgent.getRegion() == NULL)
02899 {
02900 return;
02901 }
02902
02903 const F32 TRANSLATE_THRESHOLD = 0.01f;
02904
02905
02906
02907
02908 const F32 ROTATION_THRESHOLD = 0.1f * 2.f*F_PI/360.f;
02909
02910 const U8 DUP_MSGS = 1;
02911
02912
02913 static LLVector3 last_camera_pos_agent,
02914 last_camera_at,
02915 last_camera_left,
02916 last_camera_up;
02917
02918 static LLVector3 cam_center_chg,
02919 cam_rot_chg;
02920
02921 static LLQuaternion last_head_rot;
02922 static U32 last_control_flags = 0;
02923 static U8 last_render_state;
02924 static U8 duplicate_count = 0;
02925 static F32 head_rot_chg = 1.0;
02926 static U8 last_flags;
02927
02928 LLMessageSystem *msg = gMessageSystem;
02929 LLVector3 camera_pos_agent;
02930 U8 render_state;
02931
02932 LLQuaternion body_rotation = gAgent.getFrameAgent().getQuaternion();
02933 LLQuaternion head_rotation = gAgent.getHeadRotation();
02934
02935 camera_pos_agent = gAgent.getCameraPositionAgent();
02936
02937 render_state = gAgent.getRenderState();
02938
02939 U32 control_flag_change = 0;
02940 U8 flag_change = 0;
02941
02942 cam_center_chg = last_camera_pos_agent - camera_pos_agent;
02943 cam_rot_chg = last_camera_at - LLViewerCamera::getInstance()->getAtAxis();
02944
02945
02946
02947
02948 U32 control_flags = gAgent.getControlFlags();
02949 MASK key_mask = gKeyboard->currentMask(TRUE);
02950 if (key_mask & MASK_ALT || key_mask & MASK_CONTROL)
02951 {
02952 control_flags &= ~( AGENT_CONTROL_LBUTTON_DOWN |
02953 AGENT_CONTROL_ML_LBUTTON_DOWN );
02954 control_flags |= AGENT_CONTROL_LBUTTON_UP |
02955 AGENT_CONTROL_ML_LBUTTON_UP ;
02956 }
02957
02958 control_flag_change = last_control_flags ^ control_flags;
02959
02960 U8 flags = AU_FLAGS_NONE;
02961 if (gAgent.isGroupTitleHidden())
02962 {
02963 flags |= AU_FLAGS_HIDETITLE;
02964 }
02965
02966 flag_change = last_flags ^ flags;
02967
02968 head_rot_chg = dot(last_head_rot, head_rotation);
02969
02970 if (force_send ||
02971 (cam_center_chg.magVec() > TRANSLATE_THRESHOLD) ||
02972 (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT) ||
02973 (last_render_state != render_state) ||
02974 (cam_rot_chg.magVec() > ROTATION_THRESHOLD) ||
02975 control_flag_change != 0 ||
02976 flag_change != 0)
02977 {
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000
03001
03002 duplicate_count = 0;
03003 }
03004 else
03005 {
03006 duplicate_count++;
03007
03008 if (head_rot_chg < MAX_HEAD_ROT_QDOT && duplicate_count < AGENT_UPDATES_PER_SECOND)
03009 {
03010
03011
03012
03013
03014
03015
03016
03017
03018 if (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT + (MAX_HEAD_ROT_QDOT - THRESHOLD_HEAD_ROT_QDOT) * duplicate_count / AGENT_UPDATES_PER_SECOND)
03019 {
03020 duplicate_count = 0;
03021 }
03022 else
03023 {
03024 return;
03025 }
03026 }
03027 else
03028 {
03029 return;
03030 }
03031 }
03032
03033 if (duplicate_count < DUP_MSGS && !gDisconnected)
03034 {
03035
03036 msg->newMessageFast(_PREHASH_AgentUpdate);
03037 msg->nextBlockFast(_PREHASH_AgentData);
03038 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
03039 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
03040 msg->addQuatFast(_PREHASH_BodyRotation, body_rotation);
03041 msg->addQuatFast(_PREHASH_HeadRotation, head_rotation);
03042 msg->addU8Fast(_PREHASH_State, render_state);
03043 msg->addU8Fast(_PREHASH_Flags, flags);
03044
03045
03046
03047
03048
03049
03050 msg->addVector3Fast(_PREHASH_CameraCenter, camera_pos_agent);
03051 msg->addVector3Fast(_PREHASH_CameraAtAxis, LLViewerCamera::getInstance()->getAtAxis());
03052 msg->addVector3Fast(_PREHASH_CameraLeftAxis, LLViewerCamera::getInstance()->getLeftAxis());
03053 msg->addVector3Fast(_PREHASH_CameraUpAxis, LLViewerCamera::getInstance()->getUpAxis());
03054 msg->addF32Fast(_PREHASH_Far, gAgent.mDrawDistance);
03055
03056 msg->addU32Fast(_PREHASH_ControlFlags, control_flags);
03057
03058 if (gDebugClicks)
03059 {
03060 if (control_flags & AGENT_CONTROL_LBUTTON_DOWN)
03061 {
03062 LL_INFOS("Messaging") << "AgentUpdate left button down" << LL_ENDL;
03063 }
03064
03065 if (control_flags & AGENT_CONTROL_LBUTTON_UP)
03066 {
03067 LL_INFOS("Messaging") << "AgentUpdate left button up" << LL_ENDL;
03068 }
03069 }
03070
03071 gAgent.enableControlFlagReset();
03072
03073 if (!send_reliable)
03074 {
03075 gAgent.sendMessage();
03076 }
03077 else
03078 {
03079 gAgent.sendReliableMessage();
03080 }
03081
03082
03083
03084
03085 last_head_rot = head_rotation;
03086 last_render_state = render_state;
03087 last_camera_pos_agent = camera_pos_agent;
03088 last_camera_at = LLViewerCamera::getInstance()->getAtAxis();
03089 last_camera_left = LLViewerCamera::getInstance()->getLeftAxis();
03090 last_camera_up = LLViewerCamera::getInstance()->getUpAxis();
03091 last_control_flags = control_flags;
03092 last_flags = flags;
03093 }
03094 }
03095
03096
03097
03098
03099
03100 extern U32 gObjectBits;
03101
03102 void process_object_update(LLMessageSystem *mesgsys, void **user_data)
03103 {
03104 LLMemType mt(LLMemType::MTYPE_OBJECT);
03105
03106 if (mesgsys->getReceiveCompressedSize())
03107 {
03108 gObjectBits += mesgsys->getReceiveCompressedSize() * 8;
03109 }
03110 else
03111 {
03112 gObjectBits += mesgsys->getReceiveSize() * 8;
03113 }
03114
03115
03116 gObjectList.processObjectUpdate(mesgsys, user_data, OUT_FULL);
03117 stop_glerror();
03118 }
03119
03120 void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data)
03121 {
03122 LLMemType mt(LLMemType::MTYPE_OBJECT);
03123
03124 if (mesgsys->getReceiveCompressedSize())
03125 {
03126 gObjectBits += mesgsys->getReceiveCompressedSize() * 8;
03127 }
03128 else
03129 {
03130 gObjectBits += mesgsys->getReceiveSize() * 8;
03131 }
03132
03133
03134 gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_FULL_COMPRESSED);
03135 stop_glerror();
03136 }
03137
03138 void process_cached_object_update(LLMessageSystem *mesgsys, void **user_data)
03139 {
03140 LLMemType mt(LLMemType::MTYPE_OBJECT);
03141
03142 if (mesgsys->getReceiveCompressedSize())
03143 {
03144 gObjectBits += mesgsys->getReceiveCompressedSize() * 8;
03145 }
03146 else
03147 {
03148 gObjectBits += mesgsys->getReceiveSize() * 8;
03149 }
03150
03151
03152 gObjectList.processCachedObjectUpdate(mesgsys, user_data, OUT_FULL_CACHED);
03153 stop_glerror();
03154 }
03155
03156
03157 void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_data)
03158 {
03159 LLMemType mt(LLMemType::MTYPE_OBJECT);
03160 if (mesgsys->getReceiveCompressedSize())
03161 {
03162 gObjectBits += mesgsys->getReceiveCompressedSize() * 8;
03163 }
03164 else
03165 {
03166 gObjectBits += mesgsys->getReceiveSize() * 8;
03167 }
03168
03169 gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_TERSE_IMPROVED);
03170 }
03171
03172
03173
03174 void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
03175 {
03176 LLFastTimer t(LLFastTimer::FTM_PROCESS_OBJECTS);
03177
03178 LLUUID id;
03179 U32 local_id;
03180 S32 i;
03181 S32 num_objects;
03182
03183 num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData);
03184
03185 for (i = 0; i < num_objects; i++)
03186 {
03187 mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);
03188
03189 LLViewerObjectList::getUUIDFromLocal(id,
03190 local_id,
03191 gMessageSystem->getSenderIP(),
03192 gMessageSystem->getSenderPort());
03193 if (id == LLUUID::null)
03194 {
03195 LL_DEBUGS("Messaging") << "Unknown kill for local " << local_id << LL_ENDL;
03196 gObjectList.mNumUnknownKills++;
03197 continue;
03198 }
03199 else
03200 {
03201 LL_DEBUGS("Messaging") << "Kill message for local " << local_id << LL_ENDL;
03202 }
03203
03204 LLSelectMgr::getInstance()->removeObjectFromSelections(id);
03205
03206
03207 if (!(id == gAgentID))
03208 {
03209 LLViewerObject *objectp = gObjectList.findObject(id);
03210 if (objectp)
03211 {
03212
03213 if ( gShowObjectUpdates )
03214 {
03215 LLViewerObject* newobject;
03216 newobject = gObjectList.createObjectViewer(LL_PCODE_LEGACY_TEXT_BUBBLE, objectp->getRegion());
03217
03218 LLVOTextBubble* bubble = (LLVOTextBubble*) newobject;
03219
03220 bubble->mColor.setVec(0.f, 1.f, 0.f, 1.f);
03221 bubble->setScale( 2.0f * bubble->getScale() );
03222 bubble->setPositionGlobal(objectp->getPositionGlobal());
03223 gPipeline.addObject(bubble);
03224 }
03225
03226
03227 gObjectList.killObject(objectp);
03228 }
03229 else
03230 {
03231 LL_WARNS("Messaging") << "Object in UUID lookup, but not on object list in kill!" << LL_ENDL;
03232 gObjectList.mNumUnknownKills++;
03233 }
03234 }
03235 }
03236 }
03237
03238 void process_time_synch(LLMessageSystem *mesgsys, void **user_data)
03239 {
03240 LLVector3 sun_direction;
03241 LLVector3 sun_ang_velocity;
03242 F32 phase;
03243 U64 space_time_usec;
03244
03245 U32 seconds_per_day;
03246 U32 seconds_per_year;
03247
03248
03249 mesgsys->getU64Fast(_PREHASH_TimeInfo, _PREHASH_UsecSinceStart, space_time_usec);
03250 mesgsys->getU32Fast(_PREHASH_TimeInfo, _PREHASH_SecPerDay, seconds_per_day);
03251 mesgsys->getU32Fast(_PREHASH_TimeInfo, _PREHASH_SecPerYear, seconds_per_year);
03252
03253
03254 mesgsys->getF32Fast(_PREHASH_TimeInfo, _PREHASH_SunPhase, phase);
03255 mesgsys->getVector3Fast(_PREHASH_TimeInfo, _PREHASH_SunDirection, sun_direction);
03256 mesgsys->getVector3Fast(_PREHASH_TimeInfo, _PREHASH_SunAngVelocity, sun_ang_velocity);
03257
03258 LLWorld::getInstance()->setSpaceTimeUSec(space_time_usec);
03259
03260
03261
03262
03263 gSky.setSunPhase(phase);
03264 gSky.setSunTargetDirection(sun_direction, sun_ang_velocity);
03265 if (!gNoRender && !(gSavedSettings.getBOOL("SkyOverrideSimSunPosition") || gSky.getOverrideSun()))
03266 {
03267 gSky.setSunDirection(sun_direction, sun_ang_velocity);
03268 }
03269 }
03270
03271 void process_sound_trigger(LLMessageSystem *msg, void **)
03272 {
03273 if (!gAudiop) return;
03274
03275 U64 region_handle = 0;
03276 F32 gain = 0;
03277 LLUUID sound_id;
03278 LLUUID owner_id;
03279 LLUUID object_id;
03280 LLUUID parent_id;
03281 LLVector3 pos_local;
03282
03283 msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_SoundID, sound_id);
03284 msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_OwnerID, owner_id);
03285 msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_ObjectID, object_id);
03286 msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_ParentID, parent_id);
03287 msg->getU64Fast(_PREHASH_SoundData, _PREHASH_Handle, region_handle);
03288 msg->getVector3Fast(_PREHASH_SoundData, _PREHASH_Position, pos_local);
03289 msg->getF32Fast(_PREHASH_SoundData, _PREHASH_Gain, gain);
03290
03291
03292 LLVector3d pos_global = from_region_handle(region_handle);
03293 pos_global.mdV[VX] += pos_local.mV[VX];
03294 pos_global.mdV[VY] += pos_local.mV[VY];
03295 pos_global.mdV[VZ] += pos_local.mV[VZ];
03296
03297
03298
03299 if (!LLViewerParcelMgr::getInstance()->canHearSound(pos_global)) return;
03300
03301
03302 if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return;
03303
03304
03305 if (LLMuteList::getInstance()->isMuted(object_id)) return;
03306
03307
03308 if (parent_id.notNull()
03309 && LLMuteList::getInstance()->isMuted(parent_id))
03310 {
03311 return;
03312 }
03313
03314 F32 volume = gSavedSettings.getBOOL("MuteSounds") ? 0.f : (gain * gSavedSettings.getF32("AudioLevelSFX"));
03315 gAudiop->triggerSound(sound_id, owner_id, volume, pos_global);
03316 }
03317
03318 void process_preload_sound(LLMessageSystem *msg, void **user_data)
03319 {
03320 if (!gAudiop)
03321 {
03322 return;
03323 }
03324
03325 LLUUID sound_id;
03326 LLUUID object_id;
03327 LLUUID owner_id;
03328
03329 msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_SoundID, sound_id);
03330 msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_ObjectID, object_id);
03331 msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_OwnerID, owner_id);
03332
03333 LLViewerObject *objectp = gObjectList.findObject(object_id);
03334 if (!objectp) return;
03335
03336 if (LLMuteList::getInstance()->isMuted(object_id)) return;
03337 if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return;
03338
03339 LLAudioSource *sourcep = objectp->getAudioSource(owner_id);
03340 if (!sourcep) return;
03341
03342 LLAudioData *datap = gAudiop->getAudioData(sound_id);
03343
03344
03345
03346
03347
03348
03349 sourcep->addAudioData(datap, FALSE);
03350 }
03351
03352 void process_attached_sound(LLMessageSystem *msg, void **user_data)
03353 {
03354 F32 gain = 0;
03355 LLUUID sound_id;
03356 LLUUID object_id;
03357 LLUUID owner_id;
03358 U8 flags;
03359
03360 msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_SoundID, sound_id);
03361 msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_ObjectID, object_id);
03362 msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_OwnerID, owner_id);
03363 msg->getF32Fast(_PREHASH_DataBlock, _PREHASH_Gain, gain);
03364 msg->getU8Fast(_PREHASH_DataBlock, _PREHASH_Flags, flags);
03365
03366 LLViewerObject *objectp = gObjectList.findObject(object_id);
03367 if (!objectp)
03368 {
03369
03370 return;
03371 }
03372
03373 if (LLMuteList::getInstance()->isMuted(object_id)) return;
03374
03375 if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return;
03376
03377 objectp->setAttachedSound(sound_id, owner_id, gain, flags);
03378 }
03379
03380
03381 void process_attached_sound_gain_change(LLMessageSystem *mesgsys, void **user_data)
03382 {
03383 F32 gain = 0;
03384 LLUUID object_guid;
03385 LLViewerObject *objectp = NULL;
03386
03387 mesgsys->getUUIDFast(_PREHASH_DataBlock, _PREHASH_ObjectID, object_guid);
03388
03389 if (!((objectp = gObjectList.findObject(object_guid))))
03390 {
03391
03392 return;
03393 }
03394
03395 mesgsys->getF32Fast(_PREHASH_DataBlock, _PREHASH_Gain, gain);
03396
03397 objectp->adjustAudioGain(gain);
03398 }
03399
03400
03401 void process_health_message(LLMessageSystem *mesgsys, void **user_data)
03402 {
03403 F32 health;
03404
03405 mesgsys->getF32Fast(_PREHASH_HealthData, _PREHASH_Health, health);
03406
03407 if (gStatusBar)
03408 {
03409 gStatusBar->setHealth((S32)health);
03410 }
03411 }
03412
03413
03414 void process_sim_stats(LLMessageSystem *msg, void **user_data)
03415 {
03416 S32 count = msg->getNumberOfBlocks("Stat");
03417 for (S32 i = 0; i < count; ++i)
03418 {
03419 U32 stat_id;
03420 F32 stat_value;
03421 msg->getU32("Stat", "StatID", stat_id, i);
03422 msg->getF32("Stat", "StatValue", stat_value, i);
03423 switch (stat_id)
03424 {
03425 case LL_SIM_STAT_TIME_DILATION:
03426 LLViewerStats::getInstance()->mSimTimeDilation.addValue(stat_value);
03427 break;
03428 case LL_SIM_STAT_FPS:
03429 LLViewerStats::getInstance()->mSimFPS.addValue(stat_value);
03430 break;
03431 case LL_SIM_STAT_PHYSFPS:
03432 LLViewerStats::getInstance()->mSimPhysicsFPS.addValue(stat_value);
03433 break;
03434 case LL_SIM_STAT_AGENTUPS:
03435 LLViewerStats::getInstance()->mSimAgentUPS.addValue(stat_value);
03436 break;
03437 case LL_SIM_STAT_FRAMEMS:
03438 LLViewerStats::getInstance()->mSimFrameMsec.addValue(stat_value);
03439 break;
03440 case LL_SIM_STAT_NETMS:
03441 LLViewerStats::getInstance()->mSimNetMsec.addValue(stat_value);
03442 break;
03443 case LL_SIM_STAT_SIMOTHERMS:
03444 LLViewerStats::getInstance()->mSimSimOtherMsec.addValue(stat_value);
03445 break;
03446 case LL_SIM_STAT_SIMPHYSICSMS:
03447 LLViewerStats::getInstance()->mSimSimPhysicsMsec.addValue(stat_value);
03448 break;
03449 case LL_SIM_STAT_AGENTMS:
03450 LLViewerStats::getInstance()->mSimAgentMsec.addValue(stat_value);
03451 break;
03452 case LL_SIM_STAT_IMAGESMS:
03453 LLViewerStats::getInstance()->mSimImagesMsec.addValue(stat_value);
03454 break;
03455 case LL_SIM_STAT_SCRIPTMS:
03456 LLViewerStats::getInstance()->mSimScriptMsec.addValue(stat_value);
03457 break;
03458 case LL_SIM_STAT_NUMTASKS:
03459 LLViewerStats::getInstance()->mSimObjects.addValue(stat_value);
03460 break;
03461 case LL_SIM_STAT_NUMTASKSACTIVE:
03462 LLViewerStats::getInstance()->mSimActiveObjects.addValue(stat_value);
03463 break;
03464 case LL_SIM_STAT_NUMAGENTMAIN:
03465 LLViewerStats::getInstance()->mSimMainAgents.addValue(stat_value);
03466 break;
03467 case LL_SIM_STAT_NUMAGENTCHILD:
03468 LLViewerStats::getInstance()->mSimChildAgents.addValue(stat_value);
03469 break;
03470 case LL_SIM_STAT_NUMSCRIPTSACTIVE:
03471 LLViewerStats::getInstance()->mSimActiveScripts.addValue(stat_value);
03472 break;
03473 case LL_SIM_STAT_LSLIPS:
03474 LLViewerStats::getInstance()->mSimLSLIPS.addValue(stat_value);
03475 break;
03476 case LL_SIM_STAT_INPPS:
03477 LLViewerStats::getInstance()->mSimInPPS.addValue(stat_value);
03478 break;
03479 case LL_SIM_STAT_OUTPPS:
03480 LLViewerStats::getInstance()->mSimOutPPS.addValue(stat_value);
03481 break;
03482 case LL_SIM_STAT_PENDING_DOWNLOADS:
03483 LLViewerStats::getInstance()->mSimPendingDownloads.addValue(stat_value);
03484 break;
03485 case LL_SIM_STAT_PENDING_UPLOADS:
03486 LLViewerStats::getInstance()->mSimPendingUploads.addValue(stat_value);
03487 break;
03488 case LL_SIM_STAT_PENDING_LOCAL_UPLOADS:
03489 LLViewerStats::getInstance()->mSimPendingLocalUploads.addValue(stat_value);
03490 break;
03491 case LL_SIM_STAT_TOTAL_UNACKED_BYTES:
03492 LLViewerStats::getInstance()->mSimTotalUnackedBytes.addValue(stat_value / 1024.f);
03493 break;
03494 case LL_SIM_STAT_PHYSICS_PINNED_TASKS:
03495 LLViewerStats::getInstance()->mPhysicsPinnedTasks.addValue(stat_value);
03496 break;
03497 case LL_SIM_STAT_PHYSICS_LOD_TASKS:
03498 LLViewerStats::getInstance()->mPhysicsLODTasks.addValue(stat_value);
03499 break;
03500 case LL_SIM_STAT_SIMPHYSICSSTEPMS:
03501 LLViewerStats::getInstance()->mSimSimPhysicsStepMsec.addValue(stat_value);
03502 break;
03503 case LL_SIM_STAT_SIMPHYSICSSHAPEMS:
03504 LLViewerStats::getInstance()->mSimSimPhysicsShapeUpdateMsec.addValue(stat_value);
03505 break;
03506 case LL_SIM_STAT_SIMPHYSICSOTHERMS:
03507 LLViewerStats::getInstance()->mSimSimPhysicsOtherMsec.addValue(stat_value);
03508 break;
03509 case LL_SIM_STAT_SIMPHYSICSMEMORY:
03510 LLViewerStats::getInstance()->mPhysicsMemoryAllocated.addValue(stat_value);
03511 break;
03512 default:
03513
03514 LL_DEBUGS("Messaging") << "Unknown stat id" << stat_id << LL_ENDL;
03515 break;
03516 }
03517 }
03518
03519
03520
03521
03522
03523
03524
03525
03526
03527
03528
03529
03530
03531
03532
03533
03534
03535
03536
03537
03538
03539
03540
03541
03542
03543
03544 U32 max_tasks_per_region;
03545 U32 region_flags;
03546 msg->getU32("Region", "ObjectCapacity", max_tasks_per_region);
03547 msg->getU32("Region", "RegionFlags", region_flags);
03548
03549 LLViewerRegion* regionp = gAgent.getRegion();
03550 if (regionp)
03551 {
03552 BOOL was_flying = gAgent.getFlying();
03553 regionp->setRegionFlags(region_flags);
03554 regionp->setMaxTasks(max_tasks_per_region);
03555
03556
03557 if (was_flying && regionp->getBlockFly())
03558 {
03559 gAgent.setFlying(gAgent.canFly());
03560 }
03561 }
03562 }
03563
03564
03565
03566 void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
03567 {
03568 LLUUID animation_id;
03569 LLUUID uuid;
03570 S32 anim_sequence_id;
03571 LLVOAvatar *avatarp;
03572
03573 mesgsys->getUUIDFast(_PREHASH_Sender, _PREHASH_ID, uuid);
03574
03575
03576 avatarp = (LLVOAvatar *)gObjectList.findObject(uuid);
03577
03578 if (!avatarp)
03579 {
03580
03581 LL_WARNS("Messaging") << "Received animation state for unknown avatar" << uuid << LL_ENDL;
03582 return;
03583 }
03584
03585 S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationList);
03586 S32 num_source_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationSourceList);
03587
03588 avatarp->mSignaledAnimations.clear();
03589
03590 if (avatarp->mIsSelf)
03591 {
03592 LLUUID object_id;
03593
03594 for( S32 i = 0; i < num_blocks; i++ )
03595 {
03596 mesgsys->getUUIDFast(_PREHASH_AnimationList, _PREHASH_AnimID, animation_id, i);
03597 mesgsys->getS32Fast(_PREHASH_AnimationList, _PREHASH_AnimSequenceID, anim_sequence_id, i);
03598
03599 LL_DEBUGS("Messaging") << "Anim sequence ID: " << anim_sequence_id << LL_ENDL;
03600
03601 avatarp->mSignaledAnimations[animation_id] = anim_sequence_id;
03602
03603 if (i < num_source_blocks)
03604 {
03605 mesgsys->getUUIDFast(_PREHASH_AnimationSourceList, _PREHASH_ObjectID, object_id, i);
03606
03607 LLViewerObject* object = gObjectList.findObject(object_id);
03608 if (object)
03609 {
03610 object->mFlags |= FLAGS_ANIM_SOURCE;
03611
03612 BOOL anim_found = FALSE;
03613 LLVOAvatar::AnimSourceIterator anim_it = avatarp->mAnimationSources.find(object_id);
03614 for (;anim_it != avatarp->mAnimationSources.end(); ++anim_it)
03615 {
03616 if (anim_it->second == animation_id)
03617 {
03618 anim_found = TRUE;
03619 break;
03620 }
03621 }
03622
03623 if (!anim_found)
03624 {
03625 avatarp->mAnimationSources.insert(LLVOAvatar::AnimationSourceMap::value_type(object_id, animation_id));
03626 }
03627 }
03628 }
03629 }
03630 }
03631 else
03632 {
03633 for( S32 i = 0; i < num_blocks; i++ )
03634 {
03635 mesgsys->getUUIDFast(_PREHASH_AnimationList, _PREHASH_AnimID, animation_id, i);
03636 mesgsys->getS32Fast(_PREHASH_AnimationList, _PREHASH_AnimSequenceID, anim_sequence_id, i);
03637 avatarp->mSignaledAnimations[animation_id] = anim_sequence_id;
03638 }
03639 }
03640
03641 if (num_blocks)
03642 {
03643 avatarp->processAnimationStateChanges();
03644 }
03645 }
03646
03647 void process_avatar_appearance(LLMessageSystem *mesgsys, void **user_data)
03648 {
03649 LLUUID uuid;
03650 mesgsys->getUUIDFast(_PREHASH_Sender, _PREHASH_ID, uuid);
03651
03652 LLVOAvatar* avatarp = (LLVOAvatar *)gObjectList.findObject(uuid);
03653 if( avatarp )
03654 {
03655 avatarp->processAvatarAppearance( mesgsys );
03656 }
03657 else
03658 {
03659 LL_WARNS("Messaging") << "avatar_appearance sent for unknown avatar " << uuid << LL_ENDL;
03660 }
03661 }
03662
03663 void process_camera_constraint(LLMessageSystem *mesgsys, void **user_data)
03664 {
03665 LLVector4 cameraCollidePlane;
03666 mesgsys->getVector4Fast(_PREHASH_CameraCollidePlane, _PREHASH_Plane, cameraCollidePlane);
03667
03668 gAgent.setCameraCollidePlane(cameraCollidePlane);
03669 }
03670
03671 void near_sit_object(BOOL success, void *data)
03672 {
03673 if (success)
03674 {
03675
03676 gMessageSystem->newMessageFast(_PREHASH_AgentSit);
03677 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
03678 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
03679 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
03680 gAgent.sendReliableMessage();
03681 }
03682 }
03683
03684 void process_avatar_sit_response(LLMessageSystem *mesgsys, void **user_data)
03685 {
03686 LLVector3 sitPosition;
03687 LLQuaternion sitRotation;
03688 LLUUID sitObjectID;
03689 BOOL use_autopilot;
03690 mesgsys->getUUIDFast(_PREHASH_SitObject, _PREHASH_ID, sitObjectID);
03691 mesgsys->getBOOLFast(_PREHASH_SitTransform, _PREHASH_AutoPilot, use_autopilot);
03692 mesgsys->getVector3Fast(_PREHASH_SitTransform, _PREHASH_SitPosition, sitPosition);
03693 mesgsys->getQuatFast(_PREHASH_SitTransform, _PREHASH_SitRotation, sitRotation);
03694 LLVector3 camera_eye;
03695 mesgsys->getVector3Fast(_PREHASH_SitTransform, _PREHASH_CameraEyeOffset, camera_eye);
03696 LLVector3 camera_at;
03697 mesgsys->getVector3Fast(_PREHASH_SitTransform, _PREHASH_CameraAtOffset, camera_at);
03698 BOOL force_mouselook;
03699 mesgsys->getBOOLFast(_PREHASH_SitTransform, _PREHASH_ForceMouselook, force_mouselook);
03700
03701 LLVOAvatar* avatar = gAgent.getAvatarObject();
03702
03703 if (avatar && dist_vec_squared(camera_eye, camera_at) > 0.0001f)
03704 {
03705 gAgent.setSitCamera(sitObjectID, camera_eye, camera_at);
03706 }
03707
03708 gAgent.mForceMouselook = force_mouselook;
03709
03710 LLViewerObject* object = gObjectList.findObject(sitObjectID);
03711 if (object)
03712 {
03713 LLVector3 sit_spot = object->getPositionAgent() + (sitPosition * object->getRotation());
03714 if (!use_autopilot || (avatar && avatar->mIsSitting && avatar->getRoot() == object->getRoot()))
03715 {
03716
03717 }
03718 else
03719 {
03720 gAgent.startAutoPilotGlobal(gAgent.getPosGlobalFromAgent(sit_spot), "Sit", &sitRotation, near_sit_object, NULL, 0.5f);
03721 }
03722 }
03723 else
03724 {
03725 LL_WARNS("Messaging") << "Received sit approval for unknown object " << sitObjectID << LL_ENDL;
03726 }
03727 }
03728
03729 void process_clear_follow_cam_properties(LLMessageSystem *mesgsys, void **user_data)
03730 {
03731 LLUUID source_id;
03732
03733 mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, source_id);
03734
03735 LLFollowCamMgr::removeFollowCamParams(source_id);
03736 }
03737
03738 void process_set_follow_cam_properties(LLMessageSystem *mesgsys, void **user_data)
03739 {
03740 S32 type;
03741 F32 value;
03742 bool settingPosition = false;
03743 bool settingFocus = false;
03744 bool settingFocusOffset = false;
03745 LLVector3 position;
03746 LLVector3 focus;
03747 LLVector3 focus_offset;
03748
03749 LLUUID source_id;
03750
03751 mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, source_id);
03752
03753 LLViewerObject* objectp = gObjectList.findObject(source_id);
03754 if (objectp)
03755 {
03756 objectp->mFlags |= FLAGS_CAMERA_SOURCE;
03757 }
03758
03759 S32 num_objects = mesgsys->getNumberOfBlocks("CameraProperty");
03760 for (S32 block_index = 0; block_index < num_objects; block_index++)
03761 {
03762 mesgsys->getS32("CameraProperty", "Type", type, block_index);
03763 mesgsys->getF32("CameraProperty", "Value", value, block_index);
03764 switch(type)
03765 {
03766 case FOLLOWCAM_PITCH:
03767 LLFollowCamMgr::setPitch(source_id, value);
03768 break;
03769 case FOLLOWCAM_FOCUS_OFFSET_X:
03770 focus_offset.mV[VX] = value;
03771 settingFocusOffset = true;
03772 break;
03773 case FOLLOWCAM_FOCUS_OFFSET_Y:
03774 focus_offset.mV[VY] = value;
03775 settingFocusOffset = true;
03776 break;
03777 case FOLLOWCAM_FOCUS_OFFSET_Z:
03778 focus_offset.mV[VZ] = value;
03779 settingFocusOffset = true;
03780 break;
03781 case FOLLOWCAM_POSITION_LAG:
03782 LLFollowCamMgr::setPositionLag(source_id, value);
03783 break;
03784 case FOLLOWCAM_FOCUS_LAG:
03785 LLFollowCamMgr::setFocusLag(source_id, value);
03786 break;
03787 case FOLLOWCAM_DISTANCE:
03788 LLFollowCamMgr::setDistance(source_id, value);
03789 break;
03790 case FOLLOWCAM_BEHINDNESS_ANGLE:
03791 LLFollowCamMgr::setBehindnessAngle(source_id, value);
03792 break;
03793 case FOLLOWCAM_BEHINDNESS_LAG:
03794 LLFollowCamMgr::setBehindnessLag(source_id, value);
03795 break;
03796 case FOLLOWCAM_POSITION_THRESHOLD:
03797 LLFollowCamMgr::setPositionThreshold(source_id, value);
03798 break;
03799 case FOLLOWCAM_FOCUS_THRESHOLD:
03800 LLFollowCamMgr::setFocusThreshold(source_id, value);
03801 break;
03802 case FOLLOWCAM_ACTIVE:
03803
03804 LLFollowCamMgr::setCameraActive(source_id, value != 0.f);
03805 break;
03806 case FOLLOWCAM_POSITION_X:
03807 settingPosition = true;
03808 position.mV[ 0 ] = value;
03809 break;
03810 case FOLLOWCAM_POSITION_Y:
03811 settingPosition = true;
03812 position.mV[ 1 ] = value;
03813 break;
03814 case FOLLOWCAM_POSITION_Z:
03815 settingPosition = true;
03816 position.mV[ 2 ] = value;
03817 break;
03818 case FOLLOWCAM_FOCUS_X:
03819 settingFocus = true;
03820 focus.mV[ 0 ] = value;
03821 break;
03822 case FOLLOWCAM_FOCUS_Y:
03823 settingFocus = true;
03824 focus.mV[ 1 ] = value;
03825 break;
03826 case FOLLOWCAM_FOCUS_Z:
03827 settingFocus = true;
03828 focus.mV[ 2 ] = value;
03829 break;
03830 case FOLLOWCAM_POSITION_LOCKED:
03831 LLFollowCamMgr::setPositionLocked(source_id, value != 0.f);
03832 break;
03833 case FOLLOWCAM_FOCUS_LOCKED:
03834 LLFollowCamMgr::setFocusLocked(source_id, value != 0.f);
03835 break;
03836
03837 default:
03838 break;
03839 }
03840 }
03841
03842 if ( settingPosition )
03843 {
03844 LLFollowCamMgr::setPosition(source_id, position);
03845 }
03846 if ( settingFocus )
03847 {
03848 LLFollowCamMgr::setFocus(source_id, focus);
03849 }
03850 if ( settingFocusOffset )
03851 {
03852 LLFollowCamMgr::setFocusOffset(source_id, focus_offset);
03853 }
03854 }
03855
03856
03857
03858
03859 void process_name_value(LLMessageSystem *mesgsys, void **user_data)
03860 {
03861 char temp_str[NAME_VALUE_BUF_SIZE];
03862 LLUUID id;
03863 S32 i, num_blocks;
03864
03865 mesgsys->getUUIDFast(_PREHASH_TaskData, _PREHASH_ID, id);
03866
03867 LLViewerObject* object = gObjectList.findObject(id);
03868
03869 if (object)
03870 {
03871 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_NameValueData);
03872 for (i = 0; i < num_blocks; i++)
03873 {
03874 mesgsys->getStringFast(_PREHASH_NameValueData, _PREHASH_NVPair, NAME_VALUE_BUF_SIZE, temp_str, i);
03875 LL_INFOS("Messaging") << "Added to object Name Value: " << temp_str << LL_ENDL;
03876 object->addNVPair(temp_str);
03877 }
03878 }
03879 else
03880 {
03881 LL_INFOS("Messaging") << "Can't find object " << id << " to add name value pair" << LL_ENDL;
03882 }
03883 }
03884
03885 void process_remove_name_value(LLMessageSystem *mesgsys, void **user_data)
03886 {
03887 char temp_str[NAME_VALUE_BUF_SIZE];
03888 LLUUID id;
03889 S32 i, num_blocks;
03890
03891 mesgsys->getUUIDFast(_PREHASH_TaskData, _PREHASH_ID, id);
03892
03893 LLViewerObject* object = gObjectList.findObject(id);
03894
03895 if (object)
03896 {
03897 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_NameValueData);
03898 for (i = 0; i < num_blocks; i++)
03899 {
03900 mesgsys->getStringFast(_PREHASH_NameValueData, _PREHASH_NVPair, NAME_VALUE_BUF_SIZE, temp_str, i);
03901 LL_INFOS("Messaging") << "Removed from object Name Value: " << temp_str << LL_ENDL;
03902 object->removeNVPair(temp_str);
03903 }
03904 }
03905 else
03906 {
03907 LL_INFOS("Messaging") << "Can't find object " << id << " to remove name value pair" << LL_ENDL;
03908 }
03909 }
03910
03911 void process_kick_user(LLMessageSystem *msg, void** )
03912 {
03913 char message[2048];
03914 message[0] = '\0';
03915
03916 msg->getStringFast(_PREHASH_UserInfo, _PREHASH_Reason, 2048, message);
03917
03918 LLAppViewer::instance()->forceDisconnect(message);
03919 }
03920
03921
03922
03923
03924
03925
03926
03927
03928
03929
03930
03931
03932
03933
03934
03935
03936
03937
03938
03939
03940
03941
03942
03943
03944
03945
03946
03947
03948
03949
03950
03951
03952
03953
03954
03955
03956
03957
03958
03959
03960
03961
03962
03963
03964
03965
03966
03967
03968
03969
03970
03971
03972
03973
03974
03975
03976 void process_money_balance_reply( LLMessageSystem* msg, void** )
03977 {
03978 S32 balance = 0;
03979 S32 credit = 0;
03980 S32 committed = 0;
03981 char desc[STD_STRING_BUF_SIZE] = "";
03982
03983 msg->getS32("MoneyData", "MoneyBalance", balance);
03984 msg->getS32("MoneyData", "SquareMetersCredit", credit);
03985 msg->getS32("MoneyData", "SquareMetersCommitted", committed);
03986 msg->getStringFast(_PREHASH_MoneyData, _PREHASH_Description, STD_STRING_BUF_SIZE, desc);
03987 LL_INFOS("Messaging") << "L$, credit, committed: " << balance << " " << credit << " "
03988 << committed << LL_ENDL;
03989
03990 if (gStatusBar)
03991 {
03992 S32 old_balance = gStatusBar->getBalance();
03993
03994
03995 if (old_balance != 0)
03996 {
03997
03998 if (balance > old_balance)
03999 {
04000 LLFirstUse::useBalanceIncrease(balance - old_balance);
04001 }
04002 else if (balance < old_balance)
04003 {
04004 LLFirstUse::useBalanceDecrease(balance - old_balance);
04005 }
04006 }
04007
04008 gStatusBar->setBalance(balance);
04009 gStatusBar->setLandCredit(credit);
04010 gStatusBar->setLandCommitted(committed);
04011 }
04012
04013 LLUUID tid;
04014 msg->getUUID("MoneyData", "TransactionID", tid);
04015 static std::deque<LLUUID> recent;
04016 if(desc[0] && gSavedSettings.getBOOL("NotifyMoneyChange")
04017 && (std::find(recent.rbegin(), recent.rend(), tid) == recent.rend()))
04018 {
04019
04020
04021
04022 LLString::format_map_t args;
04023 args["[MESSAGE]"] = desc;
04024 LLNotifyBox::showXml("SystemMessage", args);
04025
04026
04027
04028 const U32 MAX_LOOKBACK = 30;
04029 const S32 POP_FRONT_SIZE = 12;
04030 if(recent.size() > MAX_LOOKBACK)
04031 {
04032 LL_DEBUGS("Messaging") << "Removing oldest transaction records" << LL_ENDL;
04033 recent.erase(recent.begin(), recent.begin() + POP_FRONT_SIZE);
04034 }
04035
04036 recent.push_back(tid);
04037 }
04038 }
04039
04040 void process_agent_alert_message(LLMessageSystem* msgsystem, void** user_data)
04041 {
04042 char buffer[MAX_STRING];
04043 msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, MAX_STRING, buffer);
04044 BOOL modal = FALSE;
04045 msgsystem->getBOOL("AlertData", "Modal", modal);
04046 process_alert_core(buffer, modal);
04047 }
04048
04049 void process_alert_message(LLMessageSystem *msgsystem, void **user_data)
04050 {
04051 char buffer[MAX_STRING];
04052 msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, MAX_STRING, buffer);
04053 BOOL modal = FALSE;
04054 process_alert_core(buffer, modal);
04055 }
04056
04057 void process_alert_core(const std::string& message, BOOL modal)
04058 {
04059
04060
04061 gViewerWindow->getWindow()->resetBusyCount();
04062
04063
04064 if ( message == "You died and have been teleported to your home location")
04065 {
04066 LLViewerStats::getInstance()->incStat(LLViewerStats::ST_KILLED_COUNT);
04067 }
04068 else if( message == "Home position set." )
04069 {
04070
04071 LLString snap_filename = gDirUtilp->getLindenUserDir();
04072 snap_filename += gDirUtilp->getDirDelimiter();
04073 snap_filename += SCREEN_HOME_FILENAME;
04074 gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight(), FALSE, FALSE);
04075 }
04076
04077 const std::string ALERT_PREFIX("ALERT: ");
04078 const std::string NOTIFY_PREFIX("NOTIFY: ");
04079 if (message.find(ALERT_PREFIX) == 0)
04080 {
04081
04082
04083 std::string alert_name(message.substr(ALERT_PREFIX.length()));
04084 LLAlertDialog::showXml(alert_name);
04085 }
04086 else if (message.find(NOTIFY_PREFIX) == 0)
04087 {
04088
04089
04090 std::string notify_name(message.substr(NOTIFY_PREFIX.length()));
04091 LLNotifyBox::showXml(notify_name);
04092 }
04093 else if (message[0] == '/')
04094 {
04095
04096 LLString text(message.substr(1));
04097 LLString::format_map_t args;
04098 if (text.substr(0,17) == "RESTART_X_MINUTES")
04099 {
04100 S32 mins = 0;
04101 LLString::convertToS32(text.substr(18), mins);
04102 args["[MINUTES]"] = llformat("%d",mins);
04103 LLNotifyBox::showXml("RegionRestartMinutes", args);
04104 }
04105 else if (text.substr(0,17) == "RESTART_X_SECONDS")
04106 {
04107 S32 secs = 0;
04108 LLString::convertToS32(text.substr(18), secs);
04109 args["[SECONDS]"] = llformat("%d",secs);
04110 LLNotifyBox::showXml("RegionRestartSeconds", args);
04111 }
04112 else
04113 {
04114
04115 args["[MESSAGE]"] = text;
04116 LLNotifyBox::showXml("SystemMessage", args);
04117 }
04118 }
04119 else if (modal)
04120 {
04121
04122 LLString::format_map_t args;
04123 args["[ERROR_MESSAGE]"] = message;
04124 gViewerWindow->alertXml("ErrorMessage", args);
04125 }
04126 else
04127 {
04128
04129 LLString::format_map_t args;
04130 args["[MESSAGE]"] = message;
04131 LLNotifyBox::showXml("SystemMessageTip", args);
04132 }
04133 }
04134
04135 mean_collision_list_t gMeanCollisionList;
04136 time_t gLastDisplayedTime = 0;
04137
04138 void handle_show_mean_events(void *)
04139 {
04140 if (gNoRender)
04141 {
04142 return;
04143 }
04144
04145 LLFloaterBump::show(NULL);
04146 }
04147
04148 void mean_name_callback(const LLUUID &id, const char *first, const char *last, BOOL always_false, void* data)
04149 {
04150 if (gNoRender)
04151 {
04152 return;
04153 }
04154
04155 static const int max_collision_list_size = 20;
04156 if (gMeanCollisionList.size() > max_collision_list_size)
04157 {
04158 mean_collision_list_t::iterator iter = gMeanCollisionList.begin();
04159 for (S32 i=0; i<max_collision_list_size; i++) iter++;
04160 for_each(iter, gMeanCollisionList.end(), DeletePointer());
04161 gMeanCollisionList.erase(iter, gMeanCollisionList.end());
04162 }
04163
04164 for (mean_collision_list_t::iterator iter = gMeanCollisionList.begin();
04165 iter != gMeanCollisionList.end(); ++iter)
04166 {
04167 LLMeanCollisionData *mcd = *iter;
04168 if (mcd->mPerp == id)
04169 {
04170 strncpy(mcd->mFirstName, first, DB_FIRST_NAME_BUF_SIZE -1);
04171 mcd->mFirstName[DB_FIRST_NAME_BUF_SIZE -1] = '\0';
04172 strncpy(mcd->mLastName, last, DB_LAST_NAME_BUF_SIZE -1);
04173 mcd->mLastName[DB_LAST_NAME_BUF_SIZE -1] = '\0';
04174 }
04175 }
04176 }
04177
04178 void process_mean_collision_alert_message(LLMessageSystem *msgsystem, void **user_data)
04179 {
04180 if (gAgent.inPrelude())
04181 {
04182
04183
04184 return;
04185 }
04186
04187
04188
04189 gViewerWindow->getWindow()->resetBusyCount();
04190
04191 LLUUID perp;
04192 U32 time;
04193 U8 u8type;
04194 EMeanCollisionType type;
04195 F32 mag;
04196
04197 S32 i, num = msgsystem->getNumberOfBlocks(_PREHASH_MeanCollision);
04198
04199 for (i = 0; i < num; i++)
04200 {
04201 msgsystem->getUUIDFast(_PREHASH_MeanCollision, _PREHASH_Perp, perp);
04202 msgsystem->getU32Fast(_PREHASH_MeanCollision, _PREHASH_Time, time);
04203 msgsystem->getF32Fast(_PREHASH_MeanCollision, _PREHASH_Mag, mag);
04204 msgsystem->getU8Fast(_PREHASH_MeanCollision, _PREHASH_Type, u8type);
04205
04206 type = (EMeanCollisionType)u8type;
04207
04208 BOOL b_found = FALSE;
04209
04210 for (mean_collision_list_t::iterator iter = gMeanCollisionList.begin();
04211 iter != gMeanCollisionList.end(); ++iter)
04212 {
04213 LLMeanCollisionData *mcd = *iter;
04214 if ((mcd->mPerp == perp) && (mcd->mType == type))
04215 {
04216 mcd->mTime = time;
04217 mcd->mMag = mag;
04218 b_found = TRUE;
04219 break;
04220 }
04221 }
04222
04223 if (!b_found)
04224 {
04225 LLMeanCollisionData *mcd = new LLMeanCollisionData(gAgentID, perp, time, type, mag);
04226 gMeanCollisionList.push_front(mcd);
04227 const BOOL is_group = FALSE;
04228 gCacheName->get(perp, is_group, mean_name_callback);
04229 }
04230 }
04231 }
04232
04233 void process_frozen_message(LLMessageSystem *msgsystem, void **user_data)
04234 {
04235
04236
04237 gViewerWindow->getWindow()->resetBusyCount();
04238 BOOL b_frozen;
04239
04240 msgsystem->getBOOL("FrozenData", "Data", b_frozen);
04241
04242
04243 if (b_frozen)
04244 {
04245 }
04246 else
04247 {
04248 }
04249 }
04250
04251
04252 void process_economy_data(LLMessageSystem *msg, void** )
04253 {
04254 LLGlobalEconomy::processEconomyData(msg, LLGlobalEconomy::Singleton::getInstance());
04255
04256 S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
04257 LLFloaterImagePreview::setUploadAmount(upload_cost);
04258
04259 gMenuHolder->childSetLabelArg("Upload Image", "[COST]", llformat("%d", upload_cost));
04260 gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", llformat("%d", upload_cost));
04261 gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", llformat("%d", upload_cost));
04262 gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", llformat("%d", upload_cost));
04263 }
04264
04265 class LLScriptQuestionCBData
04266 {
04267 public:
04268 LLScriptQuestionCBData(const LLUUID &taskid, const LLUUID &itemid, const LLHost &sender, S32 questions, const char *object_name, const char *owner_name)
04269 : mTaskID(taskid), mItemID(itemid), mSender(sender), mQuestions(questions), mObjectName(object_name), mOwnerName(owner_name)
04270 {
04271 }
04272
04273 LLUUID mTaskID;
04274 LLUUID mItemID;
04275 LLHost mSender;
04276 S32 mQuestions;
04277 LLString mObjectName;
04278 LLString mOwnerName;
04279 };
04280
04281 void notify_cautioned_script_question(LLScriptQuestionCBData* cbdata, S32 orig_questions, BOOL granted)
04282 {
04283
04284 if (orig_questions)
04285 {
04286
04287
04288
04289
04290
04291
04292 LLUIString notice(LLNotifyBox::getTemplateMessage(granted ? "ScriptQuestionCautionChatGranted" : "ScriptQuestionCautionChatDenied"));
04293
04294
04295 notice.setArg("[OBJECTNAME]", cbdata->mObjectName);
04296 notice.setArg("[OWNERNAME]", cbdata->mOwnerName);
04297
04298
04299
04300 BOOL foundpos = FALSE;
04301 LLViewerObject* viewobj = gObjectList.findObject(cbdata->mTaskID);
04302 if (viewobj)
04303 {
04304
04305 LLVector3 objpos(viewobj->getPosition());
04306
04307
04308 LLViewerRegion* viewregion = viewobj->getRegion();
04309 if (viewregion)
04310 {
04311
04312 notice.setArg("[REGIONNAME]", viewregion->getName());
04313 LLString formatpos = llformat("%.1f, %.1f,%.1f", objpos[VX], objpos[VY], objpos[VZ]);
04314 notice.setArg("[REGIONPOS]", formatpos);
04315
04316 foundpos = TRUE;
04317 }
04318 }
04319
04320 if (!foundpos)
04321 {
04322
04323 notice.setArg("[REGIONNAME]", "(unknown region)");
04324 notice.setArg("[REGIONPOS]", "(unknown position)");
04325 }
04326
04327
04328
04329 BOOL caution = FALSE;
04330 S32 count = 0;
04331 LLString perms;
04332 for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++)
04333 {
04334 if ((orig_questions & LSCRIPTRunTimePermissionBits[i]) && LLNotifyBox::getTemplateIsCaution(SCRIPT_QUESTIONS[i]))
04335 {
04336 count++;
04337 caution = TRUE;
04338
04339
04340
04341 if ((count > 1) && (i < SCRIPT_PERMISSION_EOF))
04342 {
04343 perms.append(", ");
04344 }
04345
04346 perms.append(LLNotifyBox::getTemplateMessage(SCRIPT_QUESTIONS[i]));
04347 }
04348 }
04349
04350 notice.setArg("[PERMISSIONS]", perms);
04351
04352
04353
04354 if (caution)
04355 {
04356 LLChat chat(notice.getString());
04357 LLFloaterChat::addChat(chat, FALSE, FALSE);
04358 }
04359 }
04360 }
04361
04362 void script_question_decline_cb(S32 option, void* user_data)
04363 {
04364 LLMessageSystem *msg = gMessageSystem;
04365 LLScriptQuestionCBData *cbdata = (LLScriptQuestionCBData *)user_data;
04366
04367
04368
04369 S32 orig = cbdata->mQuestions;
04370
04371
04372
04373
04374
04375 cbdata->mQuestions = 0;
04376
04377
04378 msg->newMessageFast(_PREHASH_ScriptAnswerYes);
04379 msg->nextBlockFast(_PREHASH_AgentData);
04380 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
04381 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
04382 msg->nextBlockFast(_PREHASH_Data);
04383 msg->addUUIDFast(_PREHASH_TaskID, cbdata->mTaskID);
04384 msg->addUUIDFast(_PREHASH_ItemID, cbdata->mItemID);
04385 msg->addS32Fast(_PREHASH_Questions, cbdata->mQuestions);
04386 msg->sendReliable(cbdata->mSender);
04387
04388
04389 notify_cautioned_script_question(cbdata, orig, FALSE);
04390
04391 delete cbdata;
04392 }
04393
04394 void script_question_cb(S32 option, void* user_data)
04395 {
04396 LLMessageSystem *msg = gMessageSystem;
04397 LLScriptQuestionCBData *cbdata = (LLScriptQuestionCBData *)user_data;
04398 S32 orig = cbdata->mQuestions;
04399
04400
04401 BOOL allowed = TRUE;
04402
04403
04404 if (option != 0)
04405 {
04406 cbdata->mQuestions = 0;
04407 allowed = FALSE;
04408 }
04409
04410
04411 msg->newMessageFast(_PREHASH_ScriptAnswerYes);
04412 msg->nextBlockFast(_PREHASH_AgentData);
04413 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
04414 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
04415 msg->nextBlockFast(_PREHASH_Data);
04416 msg->addUUIDFast(_PREHASH_TaskID, cbdata->mTaskID);
04417 msg->addUUIDFast(_PREHASH_ItemID, cbdata->mItemID);
04418 msg->addS32Fast(_PREHASH_Questions, cbdata->mQuestions);
04419 msg->sendReliable(cbdata->mSender);
04420
04421
04422 if (gSavedSettings.getBOOL("PermissionsCautionEnabled"))
04423 {
04424
04425 notify_cautioned_script_question(cbdata, orig, allowed);
04426 }
04427
04428 if ( option == 2 )
04429 {
04430 LLMuteList::getInstance()->add(LLMute(cbdata->mItemID, cbdata->mObjectName, LLMute::OBJECT));
04431
04432
04433 class OfferMatcher : public LLNotifyBoxView::Matcher
04434 {
04435 public:
04436 OfferMatcher(const LLUUID& to_block) : blocked_id(to_block) {}
04437 BOOL matches(LLNotifyBox::notify_callback_t callback, void* cb_data) const
04438 {
04439 return callback == script_question_cb && ((LLScriptQuestionCBData*)cb_data)->mItemID == blocked_id;
04440 }
04441 private:
04442 const LLUUID& blocked_id;
04443 };
04444 gNotifyBoxView->purgeMessagesMatching(OfferMatcher(cbdata->mItemID));
04445 }
04446 delete cbdata;
04447 }
04448
04449 void process_script_question(LLMessageSystem *msg, void **user_data)
04450 {
04451
04452
04453 LLHost sender = msg->getSender();
04454
04455 LLUUID taskid;
04456 LLUUID itemid;
04457 S32 questions;
04458 char object_name[255];
04459 char owner_name[DB_FULL_NAME_BUF_SIZE];
04460
04461
04462 msg->getUUIDFast(_PREHASH_Data, _PREHASH_TaskID, taskid );
04463
04464 msg->getUUIDFast(_PREHASH_Data, _PREHASH_ItemID, itemid );
04465 msg->getStringFast(_PREHASH_Data, _PREHASH_ObjectName, 255, object_name);
04466 msg->getStringFast(_PREHASH_Data, _PREHASH_ObjectOwner, DB_FULL_NAME_BUF_SIZE, owner_name);
04467 msg->getS32Fast(_PREHASH_Data, _PREHASH_Questions, questions );
04468
04469
04470 if (LLMuteList::getInstance()->isMuted(taskid)) return;
04471
04472
04473 LLString throttle_owner_name = owner_name;
04474 typedef LLKeyThrottle<LLString> LLStringThrottle;
04475 static LLStringThrottle question_throttle( LLREQUEST_PERMISSION_THROTTLE_LIMIT, LLREQUEST_PERMISSION_THROTTLE_INTERVAL );
04476
04477 switch (question_throttle.noteAction(throttle_owner_name))
04478 {
04479 case LLStringThrottle::THROTTLE_NEWLY_BLOCKED:
04480 LL_INFOS("Messaging") << "process_script_question throttled"
04481 << " owner_name:" << owner_name
04482 << LL_ENDL;
04483
04484
04485 case LLStringThrottle::THROTTLE_BLOCKED:
04486
04487 return;
04488
04489 case LLStringThrottle::THROTTLE_OK:
04490 break;
04491 }
04492
04493 LLString script_question;
04494 if (questions)
04495 {
04496 BOOL caution = FALSE;
04497 S32 count = 0;
04498 LLString::format_map_t args;
04499 args["[OBJECTNAME]"] = object_name;
04500 args["[NAME]"] = owner_name;
04501
04502
04503 for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++)
04504 {
04505 if (questions & LSCRIPTRunTimePermissionBits[i])
04506 {
04507 count++;
04508 script_question += " " + LLNotifyBox::getTemplateMessage(SCRIPT_QUESTIONS[i]) + "\n";
04509
04510
04511 caution |= LLNotifyBox::getTemplateIsCaution(SCRIPT_QUESTIONS[i]);
04512 }
04513 }
04514 args["[QUESTIONS]"] = script_question;
04515
04516 LLScriptQuestionCBData *cbdata = new LLScriptQuestionCBData(taskid, itemid, sender, questions, object_name, owner_name);
04517
04518
04519 if (gSavedSettings.getBOOL("PermissionsCautionEnabled"))
04520 {
04521 if (caution)
04522 {
04523
04524 LLNotifyBox::showXml("ScriptQuestionCaution", args, TRUE, script_question_cb, cbdata);
04525 }
04526 else
04527 {
04528
04529 LLNotifyBox::showXml("ScriptQuestion", args, FALSE, script_question_cb, cbdata);
04530 }
04531 }
04532 else
04533 {
04534
04535 LLNotifyBox::showXml("ScriptQuestion", args, FALSE, script_question_cb, cbdata);
04536 }
04537
04538 }
04539 }
04540
04541
04542 void process_derez_container(LLMessageSystem *msg, void**)
04543 {
04544 LL_WARNS("Messaging") << "call to deprecated process_derez_container" << LL_ENDL;
04545 }
04546
04547 void container_inventory_arrived(LLViewerObject* object,
04548 InventoryObjectList* inventory,
04549 S32 serial_num,
04550 void* data)
04551 {
04552 LL_DEBUGS("Messaging") << "container_inventory_arrived()" << LL_ENDL;
04553 if( gAgent.cameraMouselook() )
04554 {
04555 gAgent.changeCameraToDefault();
04556 }
04557
04558 LLInventoryView* view = LLInventoryView::getActiveInventory();
04559
04560 if (inventory->size() > 2)
04561 {
04562
04563 LLUUID cat_id;
04564 cat_id = gInventory.createNewCategory(gAgent.getInventoryRootID(),
04565 LLAssetType::AT_NONE,
04566 "Acquired Items");
04567
04568 InventoryObjectList::const_iterator it = inventory->begin();
04569 InventoryObjectList::const_iterator end = inventory->end();
04570 for ( ; it != end; ++it)
04571 {
04572 if ((*it)->getType() != LLAssetType::AT_CATEGORY &&
04573 (*it)->getType() != LLAssetType::AT_ROOT_CATEGORY)
04574 {
04575 LLInventoryObject* obj = (LLInventoryObject*)(*it);
04576 LLInventoryItem* item = (LLInventoryItem*)(obj);
04577 LLUUID item_id;
04578 item_id.generate();
04579 S32 creation_date_utc = time_corrected();
04580 LLPointer<LLViewerInventoryItem> new_item
04581 = new LLViewerInventoryItem(item_id,
04582 cat_id,
04583 item->getPermissions(),
04584 item->getAssetUUID(),
04585 item->getType(),
04586 item->getInventoryType(),
04587 item->getName(),
04588 item->getDescription(),
04589 LLSaleInfo::DEFAULT,
04590 item->getFlags(),
04591 creation_date_utc);
04592 new_item->updateServer(TRUE);
04593 gInventory.updateItem(new_item);
04594 }
04595 }
04596 gInventory.notifyObservers();
04597 if(view)
04598 {
04599 view->getPanel()->setSelection(cat_id, TAKE_FOCUS_NO);
04600 }
04601 }
04602 else if (inventory->size() == 2)
04603 {
04604
04605
04606 InventoryObjectList::iterator it = inventory->begin();
04607
04608 if ((*it)->getType() == LLAssetType::AT_CATEGORY ||
04609 (*it)->getType() == LLAssetType::AT_ROOT_CATEGORY)
04610 {
04611 ++it;
04612 }
04613
04614 LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
04615 LLUUID category = gInventory.findCategoryUUIDForType(item->getType());
04616
04617 LLUUID item_id;
04618 item_id.generate();
04619 S32 creation_date_utc = time_corrected();
04620 LLPointer<LLViewerInventoryItem> new_item
04621 = new LLViewerInventoryItem(item_id, category,
04622 item->getPermissions(),
04623 item->getAssetUUID(),
04624 item->getType(),
04625 item->getInventoryType(),
04626 item->getName(),
04627 item->getDescription(),
04628 LLSaleInfo::DEFAULT,
04629 item->getFlags(),
04630 creation_date_utc);
04631 new_item->updateServer(TRUE);
04632 gInventory.updateItem(new_item);
04633 gInventory.notifyObservers();
04634 if(view)
04635 {
04636 view->getPanel()->setSelection(item_id, TAKE_FOCUS_NO);
04637 }
04638 }
04639
04640
04641 BOOL delete_object = (BOOL)(intptr_t)data;
04642 LLViewerRegion *region = gAgent.getRegion();
04643 if (delete_object && region)
04644 {
04645 gMessageSystem->newMessageFast(_PREHASH_ObjectDelete);
04646 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
04647 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
04648 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
04649 const U8 NO_FORCE = 0;
04650 gMessageSystem->addU8Fast(_PREHASH_Force, NO_FORCE);
04651 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
04652 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID());
04653 gMessageSystem->sendReliable(region->getHost());
04654 }
04655 }
04656
04657
04658
04659
04660 char* formatted_time(const time_t& the_time, char* buffer)
04661 {
04662 LLString::copy(buffer, ctime(&the_time), TIME_STR_LENGTH);
04663 buffer[24] = '\0';
04664 return buffer;
04665 }
04666
04667
04668 void process_teleport_failed(LLMessageSystem *msg, void**)
04669 {
04670 char reason[STD_STRING_BUF_SIZE];
04671 msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, STD_STRING_BUF_SIZE, reason);
04672
04673 LLStringBase<char>::format_map_t args;
04674 LLString big_reason = LLAgent::sTeleportErrorMessages[reason];
04675 if ( big_reason.size() > 0 )
04676 {
04677 args["[REASON]"] = big_reason;
04678 }
04679 else
04680 {
04681 args["[REASON]"] = reason;
04682 }
04683
04684 gViewerWindow->alertXml("CouldNotTeleportReason", args);
04685
04686 if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
04687 {
04688 gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
04689 }
04690 }
04691
04692 void process_teleport_local(LLMessageSystem *msg,void**)
04693 {
04694 LLUUID agent_id;
04695 msg->getUUIDFast(_PREHASH_Info, _PREHASH_AgentID, agent_id);
04696 if (agent_id != gAgent.getID())
04697 {
04698 LL_WARNS("Messaging") << "Got teleport notification for wrong agent!" << LL_ENDL;
04699 return;
04700 }
04701
04702 U32 location_id;
04703 LLVector3 pos, look_at;
04704 U32 teleport_flags;
04705 msg->getU32Fast(_PREHASH_Info, _PREHASH_LocationID, location_id);
04706 msg->getVector3Fast(_PREHASH_Info, _PREHASH_Position, pos);
04707 msg->getVector3Fast(_PREHASH_Info, _PREHASH_LookAt, look_at);
04708 msg->getU32Fast(_PREHASH_Info, _PREHASH_TeleportFlags, teleport_flags);
04709
04710 if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
04711 {
04712 gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
04713 }
04714
04715
04716 if (teleport_flags & TELEPORT_FLAGS_IS_FLYING)
04717 {
04718 gAgent.setFlying(TRUE);
04719 }
04720 else
04721 {
04722 gAgent.setFlying(FALSE);
04723 }
04724
04725 gAgent.setPositionAgent(pos);
04726 gAgent.slamLookAt(look_at);
04727
04728
04729 gAgent.resetView(TRUE);
04730
04731
04732 gAgent.updateCamera();
04733
04734 send_agent_update(TRUE, TRUE);
04735 }
04736
04737 void send_simple_im(const LLUUID& to_id,
04738 const char* message,
04739 EInstantMessage dialog,
04740 const LLUUID& id)
04741 {
04742 std::string my_name;
04743 gAgent.buildFullname(my_name);
04744 send_improved_im(to_id,
04745 my_name.c_str(),
04746 message,
04747 IM_ONLINE,
04748 dialog,
04749 id,
04750 NO_TIMESTAMP,
04751 (U8*)EMPTY_BINARY_BUCKET,
04752 EMPTY_BINARY_BUCKET_SIZE);
04753 }
04754
04755 void send_group_notice(const LLUUID& group_id,
04756 const char* subject,
04757 const char* message,
04758 const LLInventoryItem* item)
04759 {
04760
04761
04762
04763 std::string my_name;
04764 gAgent.buildFullname(my_name);
04765
04766
04767 std::ostringstream subject_and_message;
04768
04769 subject_and_message << subject << "|" << message;
04770
04771
04772 U8 bin_bucket[MAX_INVENTORY_BUFFER_SIZE];
04773 U8* bucket_to_send = bin_bucket;
04774 bin_bucket[0] = '\0';
04775 S32 bin_bucket_size = EMPTY_BINARY_BUCKET_SIZE;
04776
04777 if (item)
04778 {
04779 LLSD item_def;
04780 item_def["item_id"] = item->getUUID();
04781 item_def["owner_id"] = item->getPermissions().getOwner();
04782 std::ostringstream ostr;
04783 LLSDSerialize::serialize(item_def, ostr, LLSDSerialize::LLSD_XML);
04784 bin_bucket_size = ostr.str().copy(
04785 (char*)bin_bucket, ostr.str().size());
04786 bin_bucket[bin_bucket_size] = '\0';
04787 }
04788 else
04789 {
04790 bucket_to_send = (U8*) EMPTY_BINARY_BUCKET;
04791 }
04792
04793
04794 send_improved_im(
04795 group_id,
04796 my_name.c_str(),
04797 subject_and_message.str().c_str(),
04798 IM_ONLINE,
04799 IM_GROUP_NOTICE,
04800 LLUUID::null,
04801 NO_TIMESTAMP,
04802 bucket_to_send,
04803 bin_bucket_size);
04804 }
04805
04806 void handle_lure_callback(S32 option, const LLString& text, void* userdata)
04807 {
04808 LLDynamicArray<LLUUID>* invitees = (LLDynamicArray<LLUUID>*)userdata;
04809
04810 if(0 == option)
04811 {
04812 LLMessageSystem* msg = gMessageSystem;
04813 msg->newMessageFast(_PREHASH_StartLure);
04814 msg->nextBlockFast(_PREHASH_AgentData);
04815 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
04816 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
04817 msg->nextBlockFast(_PREHASH_Info);
04818 msg->addU8Fast(_PREHASH_LureType, (U8)0);
04819 msg->addStringFast(_PREHASH_Message, text.c_str());
04820 for(LLDynamicArray<LLUUID>::iterator itr = invitees->begin(); itr != invitees->end(); ++itr)
04821 {
04822 msg->nextBlockFast(_PREHASH_TargetData);
04823 msg->addUUIDFast(_PREHASH_TargetID, *itr);
04824 }
04825 gAgent.sendReliableMessage();
04826 }
04827
04828 delete invitees;
04829 invitees = NULL;
04830 }
04831
04832 void handle_lure_callback_godlike(S32 option, void* userdata)
04833 {
04834 handle_lure_callback(option, LLString::null, userdata);
04835 }
04836
04837 void handle_lure(const LLUUID& invitee)
04838 {
04839 LLDynamicArray<LLUUID> ids;
04840 ids.push_back(invitee);
04841 handle_lure(ids);
04842 }
04843
04844
04845 void handle_lure(LLDynamicArray<LLUUID>& ids)
04846 {
04847 LLDynamicArray<LLUUID>* userdata = new LLDynamicArray<LLUUID>(ids);
04848
04849 LLString::format_map_t edit_args;
04850 edit_args["[REGION]"] = gAgent.getRegion()->getName();
04851 if (gAgent.isGodlike())
04852 {
04853 gViewerWindow->alertXmlEditText("OfferTeleportFromGod", edit_args,
04854 &handle_lure_callback_godlike, userdata,
04855 NULL, NULL, edit_args);
04856 }
04857 else
04858 {
04859 gViewerWindow->alertXmlEditText("OfferTeleport", edit_args,
04860 NULL, NULL,
04861 handle_lure_callback, userdata, edit_args);
04862 }
04863 }
04864
04865
04866 void send_improved_im(const LLUUID& to_id,
04867 const char* name,
04868 const char* message,
04869 U8 offline,
04870 EInstantMessage dialog,
04871 const LLUUID& id,
04872 U32 timestamp,
04873 const U8* binary_bucket,
04874 S32 binary_bucket_size)
04875 {
04876 pack_instant_message(
04877 gMessageSystem,
04878 gAgent.getID(),
04879 FALSE,
04880 gAgent.getSessionID(),
04881 to_id,
04882 name,
04883 message,
04884 offline,
04885 dialog,
04886 id,
04887 0,
04888 LLUUID::null,
04889 gAgent.getPositionAgent(),
04890 timestamp,
04891 binary_bucket,
04892 binary_bucket_size);
04893 gAgent.sendReliableMessage();
04894 }
04895
04896
04897 void send_places_query(const LLUUID& query_id,
04898 const LLUUID& trans_id,
04899 const char* query_text,
04900 U32 query_flags,
04901 S32 category,
04902 const char* sim_name)
04903 {
04904 LLMessageSystem* msg = gMessageSystem;
04905
04906 msg->newMessage("PlacesQuery");
04907 msg->nextBlock("AgentData");
04908 msg->addUUID("AgentID", gAgent.getID());
04909 msg->addUUID("SessionID", gAgent.getSessionID());
04910 msg->addUUID("QueryID", query_id);
04911 msg->nextBlock("TransactionData");
04912 msg->addUUID("TransactionID", trans_id);
04913 msg->nextBlock("QueryData");
04914 msg->addString("QueryText", query_text);
04915 msg->addU32("QueryFlags", query_flags);
04916 msg->addS8("Category", (S8)category);
04917 msg->addString("SimName", sim_name);
04918 gAgent.sendReliableMessage();
04919 }
04920
04921
04922 void process_user_info_reply(LLMessageSystem* msg, void**)
04923 {
04924 LLUUID agent_id;
04925 msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
04926 if(agent_id != gAgent.getID())
04927 {
04928 LL_WARNS("Messaging") << "process_user_info_reply - "
04929 << "wrong agent id." << LL_ENDL;
04930 }
04931
04932 BOOL im_via_email;
04933 msg->getBOOLFast(_PREHASH_UserData, _PREHASH_IMViaEMail, im_via_email);
04934 char email[DB_USER_EMAIL_ADDR_BUF_SIZE];
04935 msg->getStringFast(_PREHASH_UserData, _PREHASH_EMail, DB_USER_EMAIL_ADDR_BUF_SIZE,
04936 email);
04937 char dir_visibility[MAX_STRING];
04938 msg->getString(
04939 "UserData", "DirectoryVisibility", MAX_STRING, dir_visibility);
04940
04941 LLFloaterPreference::updateUserInfo(dir_visibility, im_via_email, email);
04942 LLFloaterPostcard::updateUserInfo(email);
04943 }
04944
04945
04946
04947
04948
04949
04950 const S32 SCRIPT_DIALOG_MAX_BUTTONS = 12;
04951 const S32 SCRIPT_DIALOG_BUTTON_STR_SIZE = 24;
04952 const S32 SCRIPT_DIALOG_MAX_MESSAGE_SIZE = 512;
04953 const char* SCRIPT_DIALOG_HEADER = "Script Dialog:\n";
04954
04955 struct ScriptDialogInfo
04956 {
04957 LLHost mSender;
04958 LLUUID mObjectID;
04959 S32 mChatChannel;
04960 std::vector<LLString> mButtons;
04961 };
04962
04963 void callback_script_dialog(S32 option, void* data)
04964 {
04965 ScriptDialogInfo* info = (ScriptDialogInfo*)data;
04966 if (!info) return;
04967
04968
04969 if (0 != option)
04970 {
04971 LLMessageSystem* msg = gMessageSystem;
04972 msg->newMessage("ScriptDialogReply");
04973 msg->nextBlock("AgentData");
04974 msg->addUUID("AgentID", gAgent.getID());
04975 msg->addUUID("SessionID", gAgent.getSessionID());
04976 msg->nextBlock("Data");
04977 msg->addUUID("ObjectID", info->mObjectID);
04978 msg->addS32("ChatChannel", info->mChatChannel);
04979 msg->addS32("ButtonIndex", option);
04980 msg->addString("ButtonLabel", info->mButtons[option-1]);
04981 msg->sendReliable(info->mSender);
04982 }
04983
04984 delete info;
04985 }
04986
04987 void process_script_dialog(LLMessageSystem* msg, void**)
04988 {
04989 S32 i;
04990
04991 ScriptDialogInfo* info = new ScriptDialogInfo;
04992
04993 const S32 messageLength = SCRIPT_DIALOG_MAX_MESSAGE_SIZE + sizeof(SCRIPT_DIALOG_HEADER);
04994 char message[messageLength];
04995
04996 char first_name[DB_FIRST_NAME_BUF_SIZE];
04997 char last_name[DB_GROUP_NAME_BUF_SIZE];
04998 char title[DB_INV_ITEM_NAME_BUF_SIZE];
04999 info->mSender = msg->getSender();
05000
05001 msg->getUUID("Data", "ObjectID", info->mObjectID);
05002 msg->getString("Data", "FirstName", DB_FIRST_NAME_BUF_SIZE, first_name);
05003 msg->getString("Data", "LastName", DB_LAST_NAME_BUF_SIZE, last_name);
05004 msg->getString("Data", "ObjectName", DB_INV_ITEM_NAME_BUF_SIZE, title);
05005 msg->getString("Data", "Message", SCRIPT_DIALOG_MAX_MESSAGE_SIZE, message);
05006 msg->getS32("Data", "ChatChannel", info->mChatChannel);
05007
05008
05009 LLUUID image_id;
05010 msg->getUUID("Data", "ImageID", image_id);
05011
05012 S32 button_count = msg->getNumberOfBlocks("Buttons");
05013 if (button_count > SCRIPT_DIALOG_MAX_BUTTONS)
05014 {
05015 button_count = SCRIPT_DIALOG_MAX_BUTTONS;
05016 }
05017
05018 for (i = 0; i < button_count; i++)
05019 {
05020 char tdesc[SCRIPT_DIALOG_BUTTON_STR_SIZE+1];
05021 msg->getString("Buttons", "ButtonLabel", SCRIPT_DIALOG_BUTTON_STR_SIZE + 1, tdesc, i);
05022 info->mButtons.push_back(LLString(tdesc));
05023 }
05024
05025 LLStringBase<char>::format_map_t args;
05026 args["[TITLE]"] = title;
05027 args["[MESSAGE]"] = message;
05028 if (strlen(first_name) > 0)
05029 {
05030 args["[FIRST]"] = first_name;
05031 args["[LAST]"] = last_name;
05032 LLNotifyBox::showXml("ScriptDialog", args,
05033 callback_script_dialog, info,
05034 info->mButtons,
05035 TRUE);
05036 }
05037 else
05038 {
05039 args["[GROUPNAME]"] = last_name;
05040 LLNotifyBox::showXml("ScriptDialogGroup", args,
05041 callback_script_dialog, info,
05042 info->mButtons,
05043 TRUE);
05044 }
05045 }
05046
05047
05048
05049 struct LoadUrlInfo
05050 {
05051 LLUUID mObjectID;
05052 LLUUID mOwnerID;
05053 BOOL mOwnerIsGroup;
05054 char mObjectName[256];
05055 char mMessage[256];
05056 char mUrl[256];
05057 };
05058
05059 std::vector<LoadUrlInfo*> gLoadUrlList;
05060
05061 void callback_load_url(S32 option, void* data)
05062 {
05063 LoadUrlInfo* infop = (LoadUrlInfo*)data;
05064 if (!infop) return;
05065
05066 if (0 == option)
05067 {
05068 LLWeb::loadURLExternal(infop->mUrl);
05069 }
05070
05071 delete infop;
05072 infop = NULL;
05073 }
05074
05075
05076
05077
05078 void callback_load_url_name(const LLUUID& id, const char* first, const char* last, BOOL is_group, void* data)
05079 {
05080 std::vector<LoadUrlInfo*>::iterator it;
05081 for (it = gLoadUrlList.begin(); it != gLoadUrlList.end(); )
05082 {
05083 LoadUrlInfo* infop = *it;
05084 if (infop->mOwnerID == id)
05085 {
05086 it = gLoadUrlList.erase(it);
05087
05088 std::string owner_name(first);
05089 if (is_group)
05090 {
05091 owner_name += " (group)";
05092 }
05093 else
05094 {
05095 owner_name += " ";
05096 owner_name += last;
05097 }
05098
05099
05100 if (LLMuteList::getInstance()->isMuted(LLUUID::null, owner_name))
05101 {
05102 delete infop;
05103 infop = NULL;
05104 continue;
05105 }
05106 LLString::format_map_t args;
05107 args["[URL]"] = infop->mUrl;
05108 args["[MESSAGE]"] = infop->mMessage;
05109 args["[OBJECTNAME]"] = infop->mObjectName;
05110 args["[NAME]"] = owner_name;
05111 LLNotifyBox::showXml("LoadWebPage", args, callback_load_url, infop);
05112 }
05113 else
05114 {
05115 ++it;
05116 }
05117 }
05118 }
05119
05120 void process_load_url(LLMessageSystem* msg, void**)
05121 {
05122 LoadUrlInfo* infop = new LoadUrlInfo;
05123
05124 msg->getString("Data", "ObjectName", 256, infop->mObjectName);
05125 msg->getUUID( "Data", "ObjectID", infop->mObjectID);
05126 msg->getUUID( "Data", "OwnerID", infop->mOwnerID);
05127 msg->getBOOL( "Data", "OwnerIsGroup", infop->mOwnerIsGroup);
05128 msg->getString("Data", "Message", 256, infop->mMessage);
05129 msg->getString("Data", "URL", 256, infop->mUrl);
05130
05131
05132
05133
05134 if (LLMuteList::getInstance()->isMuted(infop->mObjectID, infop->mObjectName) ||
05135 LLMuteList::getInstance()->isMuted(infop->mOwnerID))
05136 {
05137 LL_INFOS("Messaging")<<"Ignoring load_url from muted object/owner."<<LL_ENDL;
05138 delete infop;
05139 infop = NULL;
05140 return;
05141 }
05142
05143
05144 gLoadUrlList.push_back(infop);
05145
05146 gCacheName->get(infop->mOwnerID, infop->mOwnerIsGroup, callback_load_url_name);
05147 }
05148
05149
05150 void callback_download_complete(void** data, S32 result, LLExtStat ext_status)
05151 {
05152 LLString* filepath = (LLString*)data;
05153 LLString::format_map_t args;
05154 args["[DOWNLOAD_PATH]"] = *filepath;
05155 gViewerWindow->alertXml("FinishedRawDownload", args);
05156 delete filepath;
05157 }
05158
05159
05160 void process_initiate_download(LLMessageSystem* msg, void**)
05161 {
05162 LLUUID agent_id;
05163 msg->getUUID("AgentData", "AgentID", agent_id);
05164 if (agent_id != gAgent.getID())
05165 {
05166 LL_WARNS("Messaging") << "Initiate download for wrong agent" << LL_ENDL;
05167 return;
05168 }
05169
05170 char sim_filename[MAX_PATH];
05171 char viewer_filename[MAX_PATH];
05172 msg->getString("FileData", "SimFilename", MAX_PATH, sim_filename);
05173 msg->getString("FileData", "ViewerFilename", MAX_PATH, viewer_filename);
05174
05175 gXferManager->requestFile(viewer_filename,
05176 sim_filename,
05177 LL_PATH_NONE,
05178 msg->getSender(),
05179 FALSE,
05180 callback_download_complete,
05181 (void**)new LLString(viewer_filename));
05182 }
05183
05184
05185 void process_script_teleport_request(LLMessageSystem* msg, void**)
05186 {
05187 char object_name[256];
05188 char sim_name[256];
05189 LLVector3 pos;
05190 LLVector3 look_at;
05191
05192 msg->getString("Data", "ObjectName", 255, object_name);
05193 msg->getString( "Data", "SimName", 255, sim_name);
05194 msg->getVector3("Data", "SimPosition", pos);
05195 msg->getVector3("Data", "LookAt", look_at);
05196
05197
05198
05199
05200 LLURLDispatcher::dispatch(LLURLDispatcher::buildSLURL(sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]), FALSE);
05201
05202 }
05203
05204 void process_covenant_reply(LLMessageSystem* msg, void**)
05205 {
05206 LLUUID covenant_id, estate_owner_id;
05207 char estate_name[MAX_STRING];
05208 U32 covenant_timestamp;
05209 msg->getUUID("Data", "CovenantID", covenant_id);
05210 msg->getU32("Data", "CovenantTimestamp", covenant_timestamp);
05211 msg->getString("Data", "EstateName", MAX_STRING, estate_name);
05212 msg->getUUID("Data", "EstateOwnerID", estate_owner_id);
05213
05214 LLPanelEstateCovenant::updateEstateName(estate_name);
05215 LLPanelLandCovenant::updateEstateName(estate_name);
05216 LLFloaterBuyLand::updateEstateName(estate_name);
05217
05218
05219 char last_modified[MAX_STRING];
05220 last_modified[0] = '\0';
05221 char time_buf[TIME_STR_LENGTH];
05222 snprintf(last_modified, MAX_STRING, "Last Modified %s",
05223 formatted_time((time_t)covenant_timestamp, time_buf));
05224
05225 LLPanelEstateCovenant::updateLastModified(last_modified);
05226 LLPanelLandCovenant::updateLastModified(last_modified);
05227 LLFloaterBuyLand::updateLastModified(last_modified);
05228
05229 gCacheName->getName(estate_owner_id, callbackCacheEstateOwnerName);
05230
05231
05232 const BOOL high_priority = TRUE;
05233 if (covenant_id.notNull())
05234 {
05235 gAssetStorage->getEstateAsset(gAgent.getRegionHost(),
05236 gAgent.getID(),
05237 gAgent.getSessionID(),
05238 covenant_id,
05239 LLAssetType::AT_NOTECARD,
05240 ET_Covenant,
05241 onCovenantLoadComplete,
05242 NULL,
05243 high_priority);
05244 }
05245 else
05246 {
05247 std::string covenant_text;
05248 if (estate_owner_id.isNull())
05249 {
05250
05251 covenant_text = "There is no Covenant provided for this Estate.";
05252 }
05253 else
05254 {
05255 covenant_text = "There is no Covenant provided for this Estate. The land on this estate is being sold by the Estate owner, not Linden Lab. Please contact the Estate Owner for sales details.";
05256 }
05257 LLPanelEstateCovenant::updateCovenantText(covenant_text, covenant_id);
05258 LLPanelLandCovenant::updateCovenantText(covenant_text);
05259 LLFloaterBuyLand::updateCovenantText(covenant_text, covenant_id);
05260 }
05261 }
05262
05263 void callbackCacheEstateOwnerName(
05264 const LLUUID& id,
05265 const char* first,
05266 const char* last,
05267 BOOL is_group,
05268 void*)
05269 {
05270 std::string name;
05271
05272 if (id.isNull())
05273 {
05274 name = "(none)";
05275 }
05276 else
05277 {
05278 name = first;
05279 name += " ";
05280 name += last;
05281 }
05282 LLPanelEstateCovenant::updateEstateOwnerName(name);
05283 LLPanelLandCovenant::updateEstateOwnerName(name);
05284 LLFloaterBuyLand::updateEstateOwnerName(name);
05285 }
05286
05287 void onCovenantLoadComplete(LLVFS *vfs,
05288 const LLUUID& asset_uuid,
05289 LLAssetType::EType type,
05290 void* user_data, S32 status, LLExtStat ext_status)
05291 {
05292 LL_DEBUGS("Messaging") << "onCovenantLoadComplete()" << LL_ENDL;
05293 std::string covenant_text;
05294 if(0 == status)
05295 {
05296 LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
05297
05298 S32 file_length = file.getSize();
05299
05300 char* buffer = new char[file_length+1];
05301 if (buffer == NULL)
05302 {
05303 LL_ERRS("Messaging") << "Memory Allocation failed" << LL_ENDL;
05304 return;
05305 }
05306
05307 file.read((U8*)buffer, file_length);
05308
05309
05310 buffer[file_length] = 0;
05311
05312 if( (file_length > 19) && !strncmp( buffer, "Linden text version", 19 ) )
05313 {
05314 LLViewerTextEditor* editor =
05315 new LLViewerTextEditor("temp",
05316 LLRect(0,0,0,0),
05317 file_length+1);
05318 if( !editor->importBuffer( buffer ) )
05319 {
05320 LL_WARNS("Messaging") << "Problem importing estate covenant." << LL_ENDL;
05321 covenant_text = "Problem importing estate covenant.";
05322 }
05323 else
05324 {
05325
05326 covenant_text = editor->getText();
05327 }
05328 delete[] buffer;
05329 delete editor;
05330 }
05331 else
05332 {
05333 LL_WARNS("Messaging") << "Problem importing estate covenant: Covenant file format error." << LL_ENDL;
05334 covenant_text = "Problem importing estate covenant: Covenant file format error.";
05335 }
05336 }
05337 else
05338 {
05339 LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
05340
05341 if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
05342 LL_ERR_FILE_EMPTY == status)
05343 {
05344 covenant_text = "Estate covenant notecard is missing from database.";
05345 }
05346 else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
05347 {
05348 covenant_text = "Insufficient permissions to view estate covenant.";
05349 }
05350 else
05351 {
05352 covenant_text = "Unable to load estate covenant at this time.";
05353 }
05354
05355 LL_WARNS("Messaging") << "Problem loading notecard: " << status << LL_ENDL;
05356 }
05357 LLPanelEstateCovenant::updateCovenantText(covenant_text, asset_uuid);
05358 LLPanelLandCovenant::updateCovenantText(covenant_text);
05359 LLFloaterBuyLand::updateCovenantText(covenant_text, asset_uuid);
05360 }
05361
05362
05363 void process_feature_disabled_message(LLMessageSystem* msg, void**)
05364 {
05365
05366 LLUUID agentID;
05367 LLUUID transactionID;
05368 char messageText[MAX_STRING];
05369 msg->getStringFast(_PREHASH_FailureInfo,_PREHASH_ErrorMessage,MAX_STRING,&messageText[0],0);
05370 msg->getUUIDFast(_PREHASH_FailureInfo,_PREHASH_AgentID,agentID);
05371 msg->getUUIDFast(_PREHASH_FailureInfo,_PREHASH_TransactionID,transactionID);
05372
05373 LL_WARNS("Messaging") << "Blacklisted Feature Response:" << &messageText[0] << LL_ENDL;
05374 }
05375
05376
05377
05378
05379
05380 void invalid_message_callback(LLMessageSystem* msg,
05381 void*,
05382 EMessageException exception)
05383 {
05384 LLAppViewer::instance()->badNetworkHandler();
05385 }
05386
05387
05388