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