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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llstartup.cpp
  3.  * @brief startup routines.
  4.  *
  5.  * $LicenseInfo:firstyear=2004&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2004-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llstartup.h"
  34. #if LL_WINDOWS
  35. # include <process.h> // _spawnl()
  36. #else
  37. # include <sys/stat.h> // mkdir()
  38. #endif
  39. #include "llviewermedia_streamingaudio.h"
  40. #include "llaudioengine.h"
  41. #ifdef LL_FMOD
  42. # include "llaudioengine_fmod.h"
  43. #endif
  44. #ifdef LL_OPENAL
  45. #include "llaudioengine_openal.h"
  46. #endif
  47. #include "llares.h"
  48. #include "lllandmark.h"
  49. #include "llcachename.h"
  50. #include "lldir.h"
  51. #include "llerrorcontrol.h"
  52. #include "llfloaterreg.h"
  53. #include "llfocusmgr.h"
  54. #include "llhttpsender.h"
  55. #include "llimfloater.h"
  56. #include "lllocationhistory.h"
  57. #include "llimageworker.h"
  58. #include "llloginflags.h"
  59. #include "llmd5.h"
  60. #include "llmemorystream.h"
  61. #include "llmessageconfig.h"
  62. #include "llmoveview.h"
  63. #include "llnearbychat.h"
  64. #include "llnotifications.h"
  65. #include "llnotificationsutil.h"
  66. #include "llteleporthistory.h"
  67. #include "llregionhandle.h"
  68. #include "llsd.h"
  69. #include "llsdserialize.h"
  70. #include "llsdutil_math.h"
  71. #include "llsecondlifeurls.h"
  72. #include "llstring.h"
  73. #include "lluserrelations.h"
  74. #include "llversioninfo.h"
  75. #include "llviewercontrol.h"
  76. #include "llvfs.h"
  77. #include "llxorcipher.h" // saved password, MAC address
  78. #include "llwindow.h"
  79. #include "imageids.h"
  80. #include "message.h"
  81. #include "v3math.h"
  82. #include "llagent.h"
  83. #include "llagentpicksinfo.h"
  84. #include "llagentwearables.h"
  85. #include "llagentpilot.h"
  86. #include "llfloateravatarpicker.h"
  87. #include "llcallbacklist.h"
  88. #include "llcallingcard.h"
  89. #include "llconsole.h"
  90. #include "llcontainerview.h"
  91. #include "lldebugview.h"
  92. #include "lldrawable.h"
  93. #include "lleventnotifier.h"
  94. #include "llface.h"
  95. #include "llfeaturemanager.h"
  96. //#include "llfirstuse.h"
  97. #include "llfloaterhud.h"
  98. #include "llfloaterland.h"
  99. #include "llfloaterpreference.h"
  100. #include "llfloatertopobjects.h"
  101. #include "llfloaterworldmap.h"
  102. #include "llgesturemgr.h"
  103. #include "llgroupmgr.h"
  104. #include "llhudeffecttrail.h"
  105. #include "llhudmanager.h"
  106. #include "llhttpclient.h"
  107. #include "llimagebmp.h"
  108. #include "llinventorybridge.h"
  109. #include "llinventorymodel.h"
  110. #include "llfriendcard.h"
  111. #include "llkeyboard.h"
  112. #include "llloginhandler.h" // gLoginHandler, SLURL support
  113. #include "lllogininstance.h" // Host the login module.
  114. #include "llpanellogin.h"
  115. #include "llmutelist.h"
  116. #include "llpanelavatar.h"
  117. #include "llavatarpropertiesprocessor.h"
  118. #include "llfloaterevent.h"
  119. #include "llpanelclassified.h"
  120. #include "llpanelpick.h"
  121. #include "llpanelplace.h"
  122. #include "llpanelgrouplandmoney.h"
  123. #include "llpanelgroupnotices.h"
  124. #include "llpreview.h"
  125. #include "llpreviewscript.h"
  126. #include "llproductinforequest.h"
  127. #include "llsecondlifeurls.h"
  128. #include "llselectmgr.h"
  129. #include "llsky.h"
  130. #include "llsidetray.h"
  131. #include "llstatview.h"
  132. #include "llstatusbar.h" // sendMoneyBalanceRequest(), owns L$ balance
  133. #include "llsurface.h"
  134. #include "lltexturecache.h"
  135. #include "lltexturefetch.h"
  136. #include "lltoolmgr.h"
  137. #include "lltrans.h"
  138. #include "llui.h"
  139. #include "llurldispatcher.h"
  140. #include "llurlsimstring.h"
  141. #include "llurlhistory.h"
  142. #include "llurlwhitelist.h"
  143. #include "llvieweraudio.h"
  144. #include "llviewerassetstorage.h"
  145. #include "llviewercamera.h"
  146. #include "llviewerdisplay.h"
  147. #include "llviewergenericmessage.h"
  148. #include "llviewergesture.h"
  149. #include "llviewertexturelist.h"
  150. #include "llviewermedia.h"
  151. #include "llviewermenu.h"
  152. #include "llviewermessage.h"
  153. #include "llviewernetwork.h"
  154. #include "llviewerobjectlist.h"
  155. #include "llviewerparcelmedia.h"
  156. #include "llviewerparcelmgr.h"
  157. #include "llviewerregion.h"
  158. #include "llviewerstats.h"
  159. #include "llviewerthrottle.h"
  160. #include "llviewerwindow.h"
  161. #include "llvoavatar.h"
  162. #include "llvoavatarself.h"
  163. #include "llvoclouds.h"
  164. #include "llweb.h"
  165. #include "llworld.h"
  166. #include "llworldmapmessage.h"
  167. #include "llxfermanager.h"
  168. #include "pipeline.h"
  169. #include "llappviewer.h"
  170. #include "llfasttimerview.h"
  171. #include "llfloatermap.h"
  172. #include "llweb.h"
  173. #include "llvoiceclient.h"
  174. #include "llnamelistctrl.h"
  175. #include "llnamebox.h"
  176. #include "llnameeditor.h"
  177. #include "llpostprocess.h"
  178. #include "llwlparammanager.h"
  179. #include "llwaterparammanager.h"
  180. #include "llagentlanguage.h"
  181. #include "llwearable.h"
  182. #include "llinventorybridge.h"
  183. #include "llappearancemgr.h"
  184. #include "llavatariconctrl.h"
  185. #include "lllogin.h"
  186. #include "llevents.h"
  187. #include "llstartuplistener.h"
  188. #if LL_WINDOWS
  189. #include "llwindebug.h"
  190. #include "lldxhardware.h"
  191. #endif
  192. #if (LL_LINUX || LL_SOLARIS) && LL_GTK
  193. #include <glib/gspawn.h>
  194. #endif
  195. //
  196. // exported globals
  197. //
  198. bool gAgentMovementCompleted = false;
  199. std::string SCREEN_HOME_FILENAME = "screen_home.bmp";
  200. std::string SCREEN_LAST_FILENAME = "screen_last.bmp";
  201. LLPointer<LLViewerTexture> gStartTexture;
  202. //
  203. // Imported globals
  204. //
  205. extern S32 gStartImageWidth;
  206. extern S32 gStartImageHeight;
  207. //
  208. // local globals
  209. //
  210. static bool gGotUseCircuitCodeAck = false;
  211. static std::string sInitialOutfit;
  212. static std::string sInitialOutfitGender; // "male" or "female"
  213. static bool gUseCircuitCallbackCalled = false;
  214. EStartupState LLStartUp::gStartupState = STATE_FIRST;
  215. // *NOTE:Mani - to reconcile with giab changes...
  216. static std::string gFirstname;
  217. static std::string gLastname;
  218. static std::string gPassword;
  219. static U64 gFirstSimHandle = 0;
  220. static LLHost gFirstSim;
  221. static std::string gFirstSimSeedCap;
  222. static LLVector3 gAgentStartLookAt(1.0f, 0.f, 0.f);
  223. static std::string gAgentStartLocation = "safe";
  224. boost::scoped_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState"));
  225. boost::scoped_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener());
  226. //
  227. // local function declaration
  228. //
  229. void login_show();
  230. void login_callback(S32 option, void* userdata);
  231. bool is_hex_string(U8* str, S32 len);
  232. void show_first_run_dialog();
  233. bool first_run_dialog_callback(const LLSD& notification, const LLSD& response);
  234. void set_startup_status(const F32 frac, const std::string& string, const std::string& msg);
  235. bool login_alert_status(const LLSD& notification, const LLSD& response);
  236. void login_packet_failed(void**, S32 result);
  237. void use_circuit_callback(void**, S32 result);
  238. void register_viewer_callbacks(LLMessageSystem* msg);
  239. void asset_callback_nothing(LLVFS*, const LLUUID&, LLAssetType::EType, void*, S32);
  240. bool callback_choose_gender(const LLSD& notification, const LLSD& response);
  241. void init_start_screen(S32 location_id);
  242. void release_start_screen();
  243. void reset_login();
  244. void apply_udp_blacklist(const std::string& csv);
  245. bool process_login_success_response();
  246. void transition_back_to_login_panel(const std::string& emsg);
  247. void callback_cache_name(const LLUUID& id, const std::string& firstname, const std::string& lastname, BOOL is_group)
  248. {
  249. LLNameListCtrl::refreshAll(id, firstname, lastname, is_group);
  250. LLNameBox::refreshAll(id, firstname, lastname, is_group);
  251. LLNameEditor::refreshAll(id, firstname, lastname, is_group);
  252. // TODO: Actually be intelligent about the refresh.
  253. // For now, just brute force refresh the dialogs.
  254. dialog_refresh_all();
  255. }
  256. //
  257. // exported functionality
  258. //
  259. //
  260. // local classes
  261. //
  262. namespace
  263. {
  264. class LLNullHTTPSender : public LLHTTPSender
  265. {
  266. virtual void send(const LLHost& host, 
  267.   const std::string& message, const LLSD& body, 
  268.   LLHTTPClient::ResponderPtr response) const
  269. {
  270. LL_WARNS("AppInit") << " attemped to send " << message << " to " << host
  271. << " with null sender" << LL_ENDL;
  272. }
  273. };
  274. }
  275. void update_texture_fetch()
  276. {
  277. LLAppViewer::getTextureCache()->update(1); // unpauses the texture cache thread
  278. LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread
  279. LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread
  280. gTextureList.updateImages(0.10f);
  281. }
  282. // Returns false to skip other idle processing. Should only return
  283. // true when all initialization done.
  284. bool idle_startup()
  285. {
  286. LLMemType mt1(LLMemType::MTYPE_STARTUP);
  287. const F32 PRECACHING_DELAY = gSavedSettings.getF32("PrecachingDelay");
  288. static LLTimer timeout;
  289. static S32 timeout_count = 0;
  290. static LLTimer login_time;
  291. // until this is encapsulated, this little hack for the
  292. // auth/transform loop will do.
  293. static F32 progress = 0.10f;
  294. static std::string auth_desc;
  295. static std::string auth_message;
  296. static LLVector3 initial_sun_direction(1.f, 0.f, 0.f);
  297. static LLVector3 agent_start_position_region(10.f, 10.f, 10.f); // default for when no space server
  298. // last location by default
  299. static S32  agent_location_id = START_LOCATION_ID_LAST;
  300. static S32  location_which = START_LOCATION_ID_LAST;
  301. static bool show_connect_box = true;
  302. //static bool stipend_since_login = false;
  303. // HACK: These are things from the main loop that usually aren't done
  304. // until initialization is complete, but need to be done here for things
  305. // to work.
  306. gIdleCallbacks.callFunctions();
  307. gViewerWindow->updateUI();
  308. LLMortician::updateClass();
  309. const std::string delims (" ");
  310. std::string system;
  311. int begIdx, endIdx;
  312. std::string osString = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
  313. begIdx = osString.find_first_not_of (delims);
  314. endIdx = osString.find_first_of (delims, begIdx);
  315. system = osString.substr (begIdx, endIdx - begIdx);
  316. system += "Locale";
  317. LLStringUtil::setLocale (LLTrans::getString(system));
  318. if (!gNoRender)
  319. {
  320. //note: Removing this line will cause incorrect button size in the login screen. -- bao.
  321. gTextureList.updateImages(0.01f) ;
  322. }
  323. if ( STATE_FIRST == LLStartUp::getStartupState() )
  324. {
  325. gViewerWindow->showCursor();
  326. gViewerWindow->getWindow()->setCursor(UI_CURSOR_WAIT);
  327. /////////////////////////////////////////////////
  328. //
  329. // Initialize stuff that doesn't need data from simulators
  330. //
  331. if (LLFeatureManager::getInstance()->isSafe())
  332. {
  333. LLNotificationsUtil::add("DisplaySetToSafe");
  334. }
  335. else if ((gSavedSettings.getS32("LastFeatureVersion") < LLFeatureManager::getInstance()->getVersion()) &&
  336.  (gSavedSettings.getS32("LastFeatureVersion") != 0))
  337. {
  338. LLNotificationsUtil::add("DisplaySetToRecommended");
  339. }
  340. else if (!gViewerWindow->getInitAlert().empty())
  341. {
  342. LLNotificationsUtil::add(gViewerWindow->getInitAlert());
  343. }
  344. gSavedSettings.setS32("LastFeatureVersion", LLFeatureManager::getInstance()->getVersion());
  345. std::string xml_file = LLUI::locateSkin("xui_version.xml");
  346. LLXMLNodePtr root;
  347. bool xml_ok = false;
  348. if (LLXMLNode::parseFile(xml_file, root, NULL))
  349. {
  350. if( (root->hasName("xui_version") ) )
  351. {
  352. std::string value = root->getValue();
  353. F32 version = 0.0f;
  354. LLStringUtil::convertToF32(value, version);
  355. if (version >= 1.0f)
  356. {
  357. xml_ok = true;
  358. }
  359. }
  360. }
  361. if (!xml_ok)
  362. {
  363. // If XML is bad, there's a good possibility that notifications.xml is ALSO bad.
  364. // If that's so, then we'll get a fatal error on attempting to load it, 
  365. // which will display a nontranslatable error message that says so.
  366. // Otherwise, we'll display a reasonable error message that IS translatable.
  367. LLAppViewer::instance()->earlyExit("BadInstallation");
  368. }
  369. //
  370. // Statistics stuff
  371. //
  372. // Load autopilot and stats stuff
  373. gAgentPilot.load(gSavedSettings.getString("StatsPilotFile"));
  374. //gErrorStream.setTime(gSavedSettings.getBOOL("LogTimestamps"));
  375. // Load the throttle settings
  376. gViewerThrottle.load();
  377. if (ll_init_ares() == NULL || !gAres->isInitialized())
  378. {
  379. std::string diagnostic = "Could not start address resolution system";
  380. LL_WARNS("AppInit") << diagnostic << LL_ENDL;
  381. LLAppViewer::instance()->earlyExit("LoginFailedNoNetwork", LLSD().with("DIAGNOSTIC", diagnostic));
  382. }
  383. //
  384. // Initialize messaging system
  385. //
  386. LL_DEBUGS("AppInit") << "Initializing messaging system..." << LL_ENDL;
  387. std::string message_template_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"message_template.msg");
  388. LLFILE* found_template = NULL;
  389. found_template = LLFile::fopen(message_template_path, "r"); /* Flawfinder: ignore */
  390. #if LL_WINDOWS
  391. // On the windows dev builds, unpackaged, the message_template.msg 
  392. // file will be located in:
  393. // build-vc**/newview/<config>/app_settings
  394. if (!found_template)
  395. {
  396. message_template_path = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "app_settings", "message_template.msg");
  397. found_template = LLFile::fopen(message_template_path.c_str(), "r"); /* Flawfinder: ignore */
  398. }
  399. #elif LL_DARWIN
  400. // On Mac dev builds, message_template.msg lives in:
  401. // indra/build-*/newview/<config>/Second Life/Contents/Resources/app_settings
  402. if (!found_template)
  403. {
  404. message_template_path =
  405. gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE,
  406.    "../Resources/app_settings",
  407.    "message_template.msg");
  408. found_template = LLFile::fopen(message_template_path.c_str(), "r"); /* Flawfinder: ignore */
  409. }
  410. #endif
  411. if (found_template)
  412. {
  413. fclose(found_template);
  414. U32 port = gSavedSettings.getU32("UserConnectionPort");
  415. if ((NET_USE_OS_ASSIGNED_PORT == port) &&   // if nothing specified on command line (-port)
  416.     (gSavedSettings.getBOOL("ConnectionPortEnabled")))
  417.   {
  418.     port = gSavedSettings.getU32("ConnectionPort");
  419.   }
  420. LLHTTPSender::setDefaultSender(new LLNullHTTPSender());
  421. // TODO parameterize 
  422. const F32 circuit_heartbeat_interval = 5;
  423. const F32 circuit_timeout = 100;
  424. const LLUseCircuitCodeResponder* responder = NULL;
  425. bool failure_is_fatal = true;
  426. if(!start_messaging_system(
  427.    message_template_path,
  428.    port,
  429.    LLVersionInfo::getMajor(),
  430.    LLVersionInfo::getMinor(),
  431.    LLVersionInfo::getPatch(),
  432.    FALSE,
  433.    std::string(),
  434.    responder,
  435.    failure_is_fatal,
  436.    circuit_heartbeat_interval,
  437.    circuit_timeout))
  438. {
  439. std::string diagnostic = llformat(" Error: %d", gMessageSystem->getErrorCode());
  440. LL_WARNS("AppInit") << diagnostic << LL_ENDL;
  441. LLAppViewer::instance()->earlyExit("LoginFailedNoNetwork", LLSD().with("DIAGNOSTIC", diagnostic));
  442. }
  443. #if LL_WINDOWS
  444. // On the windows dev builds, unpackaged, the message.xml file will 
  445. // be located in indra/build-vc**/newview/<config>/app_settings.
  446. std::string message_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"message.xml");
  447. if (!LLFile::isfile(message_path.c_str())) 
  448. {
  449. LLMessageConfig::initClass("viewer", gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "app_settings", ""));
  450. }
  451. else
  452. {
  453. LLMessageConfig::initClass("viewer", gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
  454. }
  455. #else
  456. LLMessageConfig::initClass("viewer", gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
  457. #endif
  458. }
  459. else
  460. {
  461. LLAppViewer::instance()->earlyExit("MessageTemplateNotFound", LLSD().with("PATH", message_template_path));
  462. }
  463. if(gMessageSystem && gMessageSystem->isOK())
  464. {
  465. // Initialize all of the callbacks in case of bad message
  466. // system data
  467. LLMessageSystem* msg = gMessageSystem;
  468. msg->setExceptionFunc(MX_UNREGISTERED_MESSAGE,
  469.   invalid_message_callback,
  470.   NULL);
  471. msg->setExceptionFunc(MX_PACKET_TOO_SHORT,
  472.   invalid_message_callback,
  473.   NULL);
  474. // running off end of a packet is now valid in the case
  475. // when a reader has a newer message template than
  476. // the sender
  477. /*msg->setExceptionFunc(MX_RAN_OFF_END_OF_PACKET,
  478.   invalid_message_callback,
  479.   NULL);*/
  480. msg->setExceptionFunc(MX_WROTE_PAST_BUFFER_SIZE,
  481.   invalid_message_callback,
  482.   NULL);
  483. if (gSavedSettings.getBOOL("LogMessages"))
  484. {
  485. LL_DEBUGS("AppInit") << "Message logging activated!" << LL_ENDL;
  486. msg->startLogging();
  487. }
  488. // start the xfer system. by default, choke the downloads
  489. // a lot...
  490. const S32 VIEWER_MAX_XFER = 3;
  491. start_xfer_manager(gVFS);
  492. gXferManager->setMaxIncomingXfers(VIEWER_MAX_XFER);
  493. F32 xfer_throttle_bps = gSavedSettings.getF32("XferThrottle");
  494. if (xfer_throttle_bps > 1.f)
  495. {
  496. gXferManager->setUseAckThrottling(TRUE);
  497. gXferManager->setAckThrottleBPS(xfer_throttle_bps);
  498. }
  499. gAssetStorage = new LLViewerAssetStorage(msg, gXferManager, gVFS);
  500. F32 dropPercent = gSavedSettings.getF32("PacketDropPercentage");
  501. msg->mPacketRing.setDropPercentage(dropPercent);
  502.             F32 inBandwidth = gSavedSettings.getF32("InBandwidth"); 
  503.             F32 outBandwidth = gSavedSettings.getF32("OutBandwidth"); 
  504. if (inBandwidth != 0.f)
  505. {
  506. LL_DEBUGS("AppInit") << "Setting packetring incoming bandwidth to " << inBandwidth << LL_ENDL;
  507. msg->mPacketRing.setUseInThrottle(TRUE);
  508. msg->mPacketRing.setInBandwidth(inBandwidth);
  509. }
  510. if (outBandwidth != 0.f)
  511. {
  512. LL_DEBUGS("AppInit") << "Setting packetring outgoing bandwidth to " << outBandwidth << LL_ENDL;
  513. msg->mPacketRing.setUseOutThrottle(TRUE);
  514. msg->mPacketRing.setOutBandwidth(outBandwidth);
  515. }
  516. }
  517. LL_INFOS("AppInit") << "Message System Initialized." << LL_ENDL;
  518. //-------------------------------------------------
  519. // Init audio, which may be needed for prefs dialog
  520. // or audio cues in connection UI.
  521. //-------------------------------------------------
  522. if (FALSE == gSavedSettings.getBOOL("NoAudio"))
  523. {
  524. gAudiop = NULL;
  525. #ifdef LL_OPENAL
  526. if (!gAudiop
  527. #if !LL_WINDOWS
  528.     && NULL == getenv("LL_BAD_OPENAL_DRIVER")
  529. #endif // !LL_WINDOWS
  530.     )
  531. {
  532. gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL();
  533. }
  534. #endif
  535. #ifdef LL_FMOD
  536. if (!gAudiop
  537. #if !LL_WINDOWS
  538.     && NULL == getenv("LL_BAD_FMOD_DRIVER")
  539. #endif // !LL_WINDOWS
  540.     )
  541. {
  542. gAudiop = (LLAudioEngine *) new LLAudioEngine_FMOD();
  543. }
  544. #endif
  545. if (gAudiop)
  546. {
  547. #if LL_WINDOWS
  548. // FMOD on Windows needs the window handle to stop playing audio
  549. // when window is minimized. JC
  550. void* window_handle = (HWND)gViewerWindow->getPlatformWindow();
  551. #else
  552. void* window_handle = NULL;
  553. #endif
  554. bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle);
  555. if(init)
  556. {
  557. gAudiop->setMuted(TRUE);
  558. }
  559. else
  560. {
  561. LL_WARNS("AppInit") << "Unable to initialize audio engine" << LL_ENDL;
  562. delete gAudiop;
  563. gAudiop = NULL;
  564. }
  565. if (gAudiop)
  566. {
  567. // if the audio engine hasn't set up its own preferred handler for streaming audio then set up the generic streaming audio implementation which uses media plugins
  568. if (NULL == gAudiop->getStreamingAudioImpl())
  569. {
  570. LL_INFOS("AppInit") << "Using media plugins to render streaming audio" << LL_ENDL;
  571. gAudiop->setStreamingAudioImpl(new LLStreamingAudio_MediaPlugins());
  572. }
  573. }
  574. }
  575. }
  576. LL_INFOS("AppInit") << "Audio Engine Initialized." << LL_ENDL;
  577. if (LLTimer::knownBadTimer())
  578. {
  579. LL_WARNS("AppInit") << "Unreliable timers detected (may be bad PCI chipset)!!" << LL_ENDL;
  580. }
  581. //
  582. // Log on to system
  583. //
  584. if (!LLStartUp::sSLURLCommand.empty())
  585. {
  586. // this might be a secondlife:///app/login URL
  587. gLoginHandler.parseDirectLogin(LLStartUp::sSLURLCommand);
  588. }
  589. if (!gLoginHandler.getFirstName().empty()
  590. || !gLoginHandler.getLastName().empty()
  591. /*|| !gLoginHandler.getWebLoginKey().isNull()*/ )
  592. {
  593. // We have at least some login information on a SLURL
  594. gFirstname = gLoginHandler.getFirstName();
  595. gLastname = gLoginHandler.getLastName();
  596. LL_DEBUGS("LLStartup") << "STATE_FIRST: setting gFirstname, gLastname from gLoginHandler: '" << gFirstname << "' '" << gLastname << "'" << LL_ENDL;
  597. // Show the login screen if we don't have everything
  598. show_connect_box = 
  599. gFirstname.empty() || gLastname.empty();
  600. }
  601.         else if(gSavedSettings.getLLSD("UserLoginInfo").size() == 3)
  602.         {
  603.             LLSD cmd_line_login = gSavedSettings.getLLSD("UserLoginInfo");
  604. gFirstname = cmd_line_login[0].asString();
  605. gLastname = cmd_line_login[1].asString();
  606. LL_DEBUGS("LLStartup") << "Setting gFirstname, gLastname from gSavedSettings("UserLoginInfo"): '" << gFirstname << "' '" << gLastname << "'" << LL_ENDL;
  607. LLMD5 pass((unsigned char*)cmd_line_login[2].asString().c_str());
  608. char md5pass[33];               /* Flawfinder: ignore */
  609. pass.hex_digest(md5pass);
  610. gPassword = md5pass;
  611. #ifdef USE_VIEWER_AUTH
  612. show_connect_box = true;
  613. #else
  614. show_connect_box = false;
  615. #endif
  616. gSavedSettings.setBOOL("AutoLogin", TRUE);
  617.         }
  618. else if (gSavedSettings.getBOOL("AutoLogin"))
  619. {
  620. gFirstname = gSavedSettings.getString("FirstName");
  621. gLastname = gSavedSettings.getString("LastName");
  622. LL_DEBUGS("LLStartup") << "AutoLogin: setting gFirstname, gLastname from gSavedSettings("First|LastName"): '" << gFirstname << "' '" << gLastname << "'" << LL_ENDL;
  623. gPassword = LLStartUp::loadPasswordFromDisk();
  624. gSavedSettings.setBOOL("RememberPassword", TRUE);
  625. #ifdef USE_VIEWER_AUTH
  626. show_connect_box = true;
  627. #else
  628. show_connect_box = false;
  629. #endif
  630. }
  631. else
  632. {
  633. // if not automatically logging in, display login dialog
  634. // a valid grid is selected
  635. gFirstname = gSavedSettings.getString("FirstName");
  636. gLastname = gSavedSettings.getString("LastName");
  637. LL_DEBUGS("LLStartup") << "normal login: setting gFirstname, gLastname from gSavedSettings("First|LastName"): '" << gFirstname << "' '" << gLastname << "'" << LL_ENDL;
  638. gPassword = LLStartUp::loadPasswordFromDisk();
  639. show_connect_box = true;
  640. }
  641. // Go to the next startup state
  642. LLStartUp::setStartupState( STATE_BROWSER_INIT );
  643. return FALSE;
  644. }
  645. if (STATE_BROWSER_INIT == LLStartUp::getStartupState())
  646. {
  647. LL_DEBUGS("AppInit") << "STATE_BROWSER_INIT" << LL_ENDL;
  648. std::string msg = LLTrans::getString("LoginInitializingBrowser");
  649. set_startup_status(0.03f, msg.c_str(), gAgent.mMOTD.c_str());
  650. display_startup();
  651. // LLViewerMedia::initBrowser();
  652. LLStartUp::setStartupState( STATE_LOGIN_SHOW );
  653. return FALSE;
  654. }
  655. if (STATE_LOGIN_SHOW == LLStartUp::getStartupState())
  656. {
  657. LL_DEBUGS("AppInit") << "Initializing Window" << LL_ENDL;
  658. gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
  659. timeout_count = 0;
  660. if (show_connect_box)
  661. {
  662. // Load all the name information out of the login view
  663. // NOTE: Hits "Attempted getFields with no login view shown" warning, since we don't
  664. // show the login view until login_show() is called below.  
  665. // LLPanelLogin::getFields(gFirstname, gLastname, gPassword);
  666. if (gNoRender)
  667. {
  668. LL_ERRS("AppInit") << "Need to autologin or use command line with norender!" << LL_ENDL;
  669. }
  670. // Make sure the process dialog doesn't hide things
  671. gViewerWindow->setShowProgress(FALSE);
  672. // Show the login dialog
  673. login_show();
  674. // connect dialog is already shown, so fill in the names
  675. LLPanelLogin::setFields( gFirstname, gLastname, gPassword);
  676. LLPanelLogin::giveFocus();
  677. gSavedSettings.setBOOL("FirstRunThisInstall", FALSE);
  678. LLStartUp::setStartupState( STATE_LOGIN_WAIT ); // Wait for user input
  679. }
  680. else
  681. {
  682. // skip directly to message template verification
  683. LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
  684. }
  685. // *NOTE: This is where LLViewerParcelMgr::getInstance() used to get allocated before becoming LLViewerParcelMgr::getInstance().
  686. // *NOTE: This is where gHUDManager used to bet allocated before becoming LLHUDManager::getInstance().
  687. // *NOTE: This is where gMuteList used to get allocated before becoming LLMuteList::getInstance().
  688. // Login screen needs menus for preferences, but we can enter
  689. // this startup phase more than once.
  690. if (gLoginMenuBarView == NULL)
  691. {
  692. init_menus();
  693. }
  694. gViewerWindow->setNormalControlsVisible( FALSE );
  695. gLoginMenuBarView->setVisible( TRUE );
  696. gLoginMenuBarView->setEnabled( TRUE );
  697. // Hide the splash screen
  698. LLSplashScreen::hide();
  699. // Push our window frontmost
  700. gViewerWindow->getWindow()->show();
  701. display_startup();
  702. //DEV-10530.  do cleanup.  remove at some later date.  jan-2009
  703. LLFloaterPreference::cleanupBadSetting();
  704. // DEV-16927.  The following code removes errant keystrokes that happen while the window is being 
  705. // first made visible.
  706. #ifdef _WIN32
  707. MSG msg;
  708. while( PeekMessage( &msg, /*All hWnds owned by this thread */ NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE ) );
  709. #endif
  710. timeout.reset();
  711. return FALSE;
  712. }
  713. if (STATE_LOGIN_WAIT == LLStartUp::getStartupState())
  714. {
  715. // Don't do anything.  Wait for the login view to call the login_callback,
  716. // which will push us to the next state.
  717. // Sleep so we don't spin the CPU
  718. ms_sleep(1);
  719. return FALSE;
  720. }
  721. if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState())
  722. {
  723. // Move the progress view in front of the UI immediately when login is performed
  724. // this allows not to see main menu after Alt+Tab was pressed while login. EXT-744.
  725. gViewerWindow->moveProgressViewToFront();
  726. //reset the values that could have come in from a slurl
  727. // DEV-42215: Make sure they're not empty -- gFirstname and gLastname
  728. // might already have been set from gSavedSettings, and it's too bad
  729. // to overwrite valid values with empty strings.
  730. if (! gLoginHandler.getFirstName().empty() && ! gLoginHandler.getLastName().empty())
  731. {
  732. gFirstname = gLoginHandler.getFirstName();
  733. gLastname = gLoginHandler.getLastName();
  734. LL_DEBUGS("LLStartup") << "STATE_LOGIN_CLEANUP: setting gFirstname, gLastname from gLoginHandler: '" << gFirstname << "' '" << gLastname << "'" << LL_ENDL;
  735. }
  736. if (show_connect_box)
  737. {
  738. // TODO if not use viewer auth
  739. // Load all the name information out of the login view
  740. LLPanelLogin::getFields(&gFirstname, &gLastname, &gPassword);
  741. // end TODO
  742.  
  743. // HACK: Try to make not jump on login
  744. gKeyboard->resetKeys();
  745. }
  746. if (!gFirstname.empty() && !gLastname.empty())
  747. {
  748. gSavedSettings.setString("FirstName", gFirstname);
  749. gSavedSettings.setString("LastName", gLastname);
  750. LL_INFOS("AppInit") << "Attempting login as: " << gFirstname << " " << gLastname << LL_ENDL;
  751. gDebugInfo["LoginName"] = gFirstname + " " + gLastname;
  752. }
  753. // create necessary directories
  754. // *FIX: these mkdir's should error check
  755. gDirUtilp->setLindenUserDir(gFirstname, gLastname);
  756. LLFile::mkdir(gDirUtilp->getLindenUserDir());
  757. // Set PerAccountSettingsFile to the default value.
  758. gSavedSettings.setString("PerAccountSettingsFile",
  759. gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, 
  760. LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount")));
  761. // Note: can't store warnings files per account because some come up before login
  762. // Overwrite default user settings with user settings  
  763. LLAppViewer::instance()->loadSettingsFromDirectory("Account");
  764. // Need to set the LastLogoff time here if we don't have one.  LastLogoff is used for "Recent Items" calculation
  765. // and startup time is close enough if we don't have a real value.
  766. if (gSavedPerAccountSettings.getU32("LastLogoff") == 0)
  767. {
  768. gSavedPerAccountSettings.setU32("LastLogoff", time_corrected());
  769. }
  770. //Default the path if one isn't set.
  771. if (gSavedPerAccountSettings.getString("InstantMessageLogFolder").empty())
  772. {
  773. gDirUtilp->setChatLogsDir(gDirUtilp->getOSUserAppDir());
  774. std::string chat_log_dir = gDirUtilp->getChatLogsDir();
  775. std::string chat_log_top_folder=gDirUtilp->getBaseFileName(chat_log_dir);
  776. gSavedPerAccountSettings.setString("InstantMessageLogPath",chat_log_dir);
  777. gSavedPerAccountSettings.setString("InstantMessageLogFolder",chat_log_top_folder);
  778. }
  779. else
  780. {
  781. gDirUtilp->setChatLogsDir(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
  782. }
  783. gDirUtilp->setPerAccountChatLogsDir(gFirstname, gLastname);
  784. LLFile::mkdir(gDirUtilp->getChatLogsDir());
  785. LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir());
  786. //good a place as any to create user windlight directories
  787. std::string user_windlight_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight", ""));
  788. LLFile::mkdir(user_windlight_path_name.c_str());
  789. std::string user_windlight_skies_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", ""));
  790. LLFile::mkdir(user_windlight_skies_path_name.c_str());
  791. std::string user_windlight_water_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/water", ""));
  792. LLFile::mkdir(user_windlight_water_path_name.c_str());
  793. std::string user_windlight_days_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/days", ""));
  794. LLFile::mkdir(user_windlight_days_path_name.c_str());
  795. if (show_connect_box)
  796. {
  797. std::string location;
  798. LLPanelLogin::getLocation( location );
  799. LLURLSimString::setString( location );
  800. // END TODO
  801. LLPanelLogin::closePanel();
  802. }
  803. // Load URL History File
  804. LLURLHistory::loadFile("url_history.xml");
  805. // Load location history 
  806. LLLocationHistory::getInstance()->load();
  807. // Load Avatars icons cache
  808. LLAvatarIconIDCache::getInstance()->load();
  809. //-------------------------------------------------
  810. // Handle startup progress screen
  811. //-------------------------------------------------
  812. // on startup the user can request to go to their home,
  813. // their last location, or some URL "-url //sim/x/y[/z]"
  814. // All accounts have both a home and a last location, and we don't support
  815. // more locations than that.  Choose the appropriate one.  JC
  816. if (LLURLSimString::parse())
  817. {
  818. // a startup URL was specified
  819. agent_location_id = START_LOCATION_ID_URL;
  820. // doesn't really matter what location_which is, since
  821. // gAgentStartLookAt will be overwritten when the
  822. // UserLoginLocationReply arrives
  823. location_which = START_LOCATION_ID_LAST;
  824. }
  825. else if (gSavedSettings.getString("LoginLocation") == "last" )
  826. {
  827. agent_location_id = START_LOCATION_ID_LAST; // last location
  828. location_which = START_LOCATION_ID_LAST;
  829. }
  830. else
  831. {
  832. agent_location_id = START_LOCATION_ID_HOME; // home
  833. location_which = START_LOCATION_ID_HOME;
  834. }
  835. gViewerWindow->getWindow()->setCursor(UI_CURSOR_WAIT);
  836. if (!gNoRender)
  837. {
  838. init_start_screen(agent_location_id);
  839. }
  840. // Display the startup progress bar.
  841. gViewerWindow->setShowProgress(TRUE);
  842. gViewerWindow->setProgressCancelButtonVisible(TRUE, LLTrans::getString("Quit"));
  843. // Poke the VFS, which could potentially block for a while if
  844. // Windows XP is acting up
  845. set_startup_status(0.07f, LLTrans::getString("LoginVerifyingCache"), LLStringUtil::null);
  846. display_startup();
  847. gVFS->pokeFiles();
  848. LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT );
  849. return FALSE;
  850. }
  851. if(STATE_LOGIN_AUTH_INIT == LLStartUp::getStartupState())
  852. {
  853. gDebugInfo["GridName"] = LLViewerLogin::getInstance()->getGridLabel();
  854. // Update progress status and the display loop.
  855. auth_desc = LLTrans::getString("LoginInProgress");
  856. set_startup_status(progress, auth_desc, auth_message);
  857. progress += 0.02f;
  858. display_startup();
  859. // Setting initial values...
  860. LLLoginInstance* login = LLLoginInstance::getInstance();
  861. login->setNotificationsInterface(LLNotifications::getInstance());
  862. if(gNoRender)
  863. {
  864. // HACK, skip optional updates if you're running drones
  865. login->setSkipOptionalUpdate(true);
  866. }
  867. login->setUserInteraction(show_connect_box);
  868. login->setSerialNumber(LLAppViewer::instance()->getSerialNumber());
  869. login->setLastExecEvent(gLastExecEvent);
  870. login->setUpdaterLauncher(boost::bind(&LLAppViewer::launchUpdater, LLAppViewer::instance()));
  871. // This call to LLLoginInstance::connect() starts the 
  872. // authentication process.
  873. LLSD credentials;
  874. credentials["first"] = gFirstname;
  875. credentials["last"] = gLastname;
  876. credentials["passwd"] = gPassword;
  877. login->connect(credentials);
  878. LLStartUp::setStartupState( STATE_LOGIN_CURL_UNSTUCK );
  879. return FALSE;
  880. }
  881. if(STATE_LOGIN_CURL_UNSTUCK == LLStartUp::getStartupState())
  882. {
  883. // If we get here we have gotten past the potential stall
  884. // in curl, so take "may appear frozen" out of progress bar. JC
  885. auth_desc = LLTrans::getString("LoginInProgressNoFrozen");
  886. set_startup_status(progress, auth_desc, auth_message);
  887. LLStartUp::setStartupState( STATE_LOGIN_PROCESS_RESPONSE );
  888. return FALSE;
  889. }
  890. if(STATE_LOGIN_PROCESS_RESPONSE == LLStartUp::getStartupState()) 
  891. {
  892. std::ostringstream emsg;
  893. emsg << "Login failed.n";
  894. if(LLLoginInstance::getInstance()->authFailure())
  895. {
  896. LL_INFOS("LLStartup") << "Login failed, LLLoginInstance::getResponse(): "
  897.                       << LLLoginInstance::getInstance()->getResponse() << LL_ENDL;
  898. // Still have error conditions that may need some 
  899. // sort of handling.
  900. std::string reason_response = LLLoginInstance::getInstance()->getResponse("reason");
  901. std::string message_response = LLLoginInstance::getInstance()->getResponse("message");
  902. if(!message_response.empty())
  903. {
  904. // XUI: fix translation for strings returned during login
  905. // We need a generic table for translations
  906. std::string big_reason = LLAgent::sTeleportErrorMessages[ message_response ];
  907. if ( big_reason.size() == 0 )
  908. {
  909. emsg << message_response;
  910. }
  911. else
  912. {
  913. emsg << big_reason;
  914. }
  915. }
  916. if(reason_response == "key")
  917. {
  918. // Couldn't login because user/password is wrong
  919. // Clear the password
  920. gPassword = "";
  921. }
  922. if(reason_response == "update" 
  923. || reason_response == "optional")
  924. {
  925. // In the case of a needed update, quit.
  926. // Its either downloading or declined.
  927. // If optional was skipped this case shouldn't 
  928. // be reached.
  929. LLLoginInstance::getInstance()->disconnect();
  930. LLAppViewer::instance()->forceQuit();
  931. }
  932. else
  933. {
  934. // Don't pop up a notification in the TOS case because
  935. // LLFloaterTOS::onCancel() already scolded the user.
  936. if (reason_response != "tos")
  937. {
  938. LLSD args;
  939. args["ERROR_MESSAGE"] = emsg.str();
  940. LL_INFOS("LLStartup") << "Notification: " << args << LL_ENDL;
  941. LLNotificationsUtil::add("ErrorMessage", args, LLSD(), login_alert_done);
  942. }
  943. //setup map of datetime strings to codes and slt & local time offset from utc
  944. // *TODO: Does this need to be here?
  945. LLStringOps::setupDatetimeInfo (false);
  946. transition_back_to_login_panel(emsg.str());
  947. show_connect_box = true;
  948. }
  949. }
  950. else if(LLLoginInstance::getInstance()->authSuccess())
  951. {
  952. if(process_login_success_response())
  953. {
  954. // Pass the user information to the voice chat server interface.
  955. gVoiceClient->userAuthorized(gFirstname, gLastname, gAgentID);
  956. LLStartUp::setStartupState( STATE_WORLD_INIT);
  957. }
  958. else
  959. {
  960. LLSD args;
  961. args["ERROR_MESSAGE"] = emsg.str();
  962. LL_INFOS("LLStartup") << "Notification: " << args << LL_ENDL;
  963. LLNotificationsUtil::add("ErrorMessage", args, LLSD(), login_alert_done);
  964. transition_back_to_login_panel(emsg.str());
  965. show_connect_box = true;
  966. }
  967. }
  968. return FALSE;
  969. }
  970. //---------------------------------------------------------------------
  971. // World Init
  972. //---------------------------------------------------------------------
  973. if (STATE_WORLD_INIT == LLStartUp::getStartupState())
  974. {
  975. set_startup_status(0.30f, LLTrans::getString("LoginInitializingWorld"), gAgent.mMOTD);
  976. display_startup();
  977. // We should have an agent id by this point.
  978. llassert(!(gAgentID == LLUUID::null));
  979. // Finish agent initialization.  (Requires gSavedSettings, builds camera)
  980. gAgent.init();
  981. set_underclothes_menu_options();
  982. // Since we connected, save off the settings so the user doesn't have to
  983. // type the name/password again if we crash.
  984. gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);
  985. LLUIColorTable::instance().saveUserSettings();
  986. //
  987. // Initialize classes w/graphics stuff.
  988. //
  989. gTextureList.doPrefetchImages();
  990. LLSurface::initClasses();
  991. LLFace::initClass();
  992. LLDrawable::initClass();
  993. // init the shader managers
  994. LLPostProcess::initClass();
  995. LLWLParamManager::initClass();
  996. LLWaterParamManager::initClass();
  997. LLViewerObject::initVOClasses();
  998. // Initialize all our tools.  Must be done after saved settings loaded.
  999. // NOTE: This also is where gToolMgr used to be instantiated before being turned into a singleton.
  1000. LLToolMgr::getInstance()->initTools();
  1001. // Pre-load floaters, like the world map, that are slow to spawn
  1002. // due to XML complexity.
  1003. gViewerWindow->initWorldUI();
  1004. display_startup();
  1005. // This is where we used to initialize gWorldp. Original comment said:
  1006. // World initialization must be done after above window init
  1007. // User might have overridden far clip
  1008. LLWorld::getInstance()->setLandFarClip( gAgent.mDrawDistance );
  1009. // Before we create the first region, we need to set the agent's mOriginGlobal
  1010. // This is necessary because creating objects before this is set will result in a
  1011. // bad mPositionAgent cache.
  1012. gAgent.initOriginGlobal(from_region_handle(gFirstSimHandle));
  1013. LLWorld::getInstance()->addRegion(gFirstSimHandle, gFirstSim);
  1014. LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(gFirstSimHandle);
  1015. LL_INFOS("AppInit") << "Adding initial simulator " << regionp->getOriginGlobal() << LL_ENDL;
  1016. regionp->setSeedCapability(gFirstSimSeedCap);
  1017. LL_DEBUGS("AppInit") << "Waiting for seed grant ...." << LL_ENDL;
  1018. // Set agent's initial region to be the one we just created.
  1019. gAgent.setRegion(regionp);
  1020. // Set agent's initial position, which will be read by LLVOAvatar when the avatar
  1021. // object is created.  I think this must be done after setting the region.  JC
  1022. gAgent.setPositionAgent(agent_start_position_region);
  1023. display_startup();
  1024. LLStartUp::setStartupState( STATE_MULTIMEDIA_INIT );
  1025. return FALSE;
  1026. }
  1027. //---------------------------------------------------------------------
  1028. // Load QuickTime/GStreamer and other multimedia engines, can be slow.
  1029. // Do it while we're waiting on the network for our seed capability. JC
  1030. //---------------------------------------------------------------------
  1031. if (STATE_MULTIMEDIA_INIT == LLStartUp::getStartupState())
  1032. {
  1033. LLStartUp::multimediaInit();
  1034. LLStartUp::setStartupState( STATE_FONT_INIT );
  1035. return FALSE;
  1036. }
  1037. // Loading fonts takes several seconds
  1038. if (STATE_FONT_INIT == LLStartUp::getStartupState())
  1039. {
  1040. LLStartUp::fontInit();
  1041. LLStartUp::setStartupState( STATE_SEED_GRANTED_WAIT );
  1042. return FALSE;
  1043. }
  1044. //---------------------------------------------------------------------
  1045. // Wait for Seed Cap Grant
  1046. //---------------------------------------------------------------------
  1047. if(STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
  1048. {
  1049. return FALSE;
  1050. }
  1051. //---------------------------------------------------------------------
  1052. // Seed Capability Granted
  1053. // no newMessage calls should happen before this point
  1054. //---------------------------------------------------------------------
  1055. if (STATE_SEED_CAP_GRANTED == LLStartUp::getStartupState())
  1056. {
  1057. update_texture_fetch();
  1058. if ( gViewerWindow != NULL)
  1059. { // This isn't the first logon attempt, so show the UI
  1060. gViewerWindow->setNormalControlsVisible( TRUE );
  1061. }
  1062. gLoginMenuBarView->setVisible( FALSE );
  1063. gLoginMenuBarView->setEnabled( FALSE );
  1064. if (!gNoRender)
  1065. {
  1066. // Move the progress view in front of the UI
  1067. gViewerWindow->moveProgressViewToFront();
  1068. // direct logging to the debug console's line buffer
  1069. LLError::logToFixedBuffer(gDebugView->mDebugConsolep);
  1070. // set initial visibility of debug console
  1071. gDebugView->mDebugConsolep->setVisible(gSavedSettings.getBOOL("ShowDebugConsole"));
  1072. }
  1073. //
  1074. // Set message handlers
  1075. //
  1076. LL_INFOS("AppInit") << "Initializing communications..." << LL_ENDL;
  1077. // register callbacks for messages. . . do this after initial handshake to make sure that we don't catch any unwanted
  1078. register_viewer_callbacks(gMessageSystem);
  1079. // Debugging info parameters
  1080. gMessageSystem->setMaxMessageTime( 0.5f ); // Spam if decoding all msgs takes more than 500 ms
  1081. #ifndef LL_RELEASE_FOR_DOWNLOAD
  1082. gMessageSystem->setTimeDecodes( TRUE ); // Time the decode of each msg
  1083. gMessageSystem->setTimeDecodesSpamThreshold( 0.05f );  // Spam if a single msg takes over 50ms to decode
  1084. #endif
  1085. gXferManager->registerCallbacks(gMessageSystem);
  1086. if ( gCacheName == NULL )
  1087. {
  1088. gCacheName = new LLCacheName(gMessageSystem);
  1089. gCacheName->addObserver(&callback_cache_name);
  1090. gCacheName->LocalizeCacheName("waiting", LLTrans::getString("AvatarNameWaiting"));
  1091. gCacheName->LocalizeCacheName("nobody", LLTrans::getString("AvatarNameNobody"));
  1092. gCacheName->LocalizeCacheName("none", LLTrans::getString("GroupNameNone"));
  1093. // Load stored cache if possible
  1094.             LLAppViewer::instance()->loadNameCache();
  1095. }
  1096. //gCacheName is required for nearby chat history loading
  1097. //so I just moved nearby history loading a few states further
  1098. if (!gNoRender && gSavedPerAccountSettings.getBOOL("LogShowHistory"))
  1099. {
  1100. LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
  1101. if (nearby_chat) nearby_chat->loadHistory();
  1102. }
  1103. // *Note: this is where gWorldMap used to be initialized.
  1104. // register null callbacks for audio until the audio system is initialized
  1105. gMessageSystem->setHandlerFuncFast(_PREHASH_SoundTrigger, null_message_callback, NULL);
  1106. gMessageSystem->setHandlerFuncFast(_PREHASH_AttachedSound, null_message_callback, NULL);
  1107. //reset statistics
  1108. LLViewerStats::getInstance()->resetStats();
  1109. display_startup();
  1110. //
  1111. // Set up region and surface defaults
  1112. //
  1113. // Sets up the parameters for the first simulator
  1114. LL_DEBUGS("AppInit") << "Initializing camera..." << LL_ENDL;
  1115. gFrameTime    = totalTime();
  1116. F32 last_time = gFrameTimeSeconds;
  1117. gFrameTimeSeconds = (S64)(gFrameTime - gStartTime)/SEC_TO_MICROSEC;
  1118. gFrameIntervalSeconds = gFrameTimeSeconds - last_time;
  1119. if (gFrameIntervalSeconds < 0.f)
  1120. {
  1121. gFrameIntervalSeconds = 0.f;
  1122. }
  1123. // Make sure agent knows correct aspect ratio
  1124. // FOV limits depend upon aspect ratio so this needs to happen before initializing the FOV below
  1125. LLViewerCamera::getInstance()->setViewHeightInPixels(gViewerWindow->getWorldViewHeightRaw());
  1126. LLViewerCamera::getInstance()->setAspect(gViewerWindow->getWorldViewAspectRatio());
  1127. // Initialize FOV
  1128. LLViewerCamera::getInstance()->setDefaultFOV(gSavedSettings.getF32("CameraAngle")); 
  1129. // Move agent to starting location. The position handed to us by
  1130. // the space server is in global coordinates, but the agent frame
  1131. // is in region local coordinates. Therefore, we need to adjust
  1132. // the coordinates handed to us to fit in the local region.
  1133. gAgent.setPositionAgent(agent_start_position_region);
  1134. gAgent.resetAxes(gAgentStartLookAt);
  1135. gAgent.stopCameraAnimation();
  1136. gAgent.resetCamera();
  1137. // Initialize global class data needed for surfaces (i.e. textures)
  1138. if (!gNoRender)
  1139. {
  1140. LL_DEBUGS("AppInit") << "Initializing sky..." << LL_ENDL;
  1141. // Initialize all of the viewer object classes for the first time (doing things like texture fetches.
  1142. LLGLState::checkStates();
  1143. LLGLState::checkTextureChannels();
  1144. gSky.init(initial_sun_direction);
  1145. LLGLState::checkStates();
  1146. LLGLState::checkTextureChannels();
  1147. }
  1148. LL_DEBUGS("AppInit") << "Decoding images..." << LL_ENDL;
  1149. // For all images pre-loaded into viewer cache, decode them.
  1150. // Need to do this AFTER we init the sky
  1151. const S32 DECODE_TIME_SEC = 2;
  1152. for (int i = 0; i < DECODE_TIME_SEC; i++)
  1153. {
  1154. F32 frac = (F32)i / (F32)DECODE_TIME_SEC;
  1155. set_startup_status(0.45f + frac*0.1f, LLTrans::getString("LoginDecodingImages"), gAgent.mMOTD);
  1156. display_startup();
  1157. gTextureList.decodeAllImages(1.f);
  1158. }
  1159. LLStartUp::setStartupState( STATE_WORLD_WAIT );
  1160. // JC - Do this as late as possible to increase likelihood Purify
  1161. // will run.
  1162. LLMessageSystem* msg = gMessageSystem;
  1163. if (!msg->mOurCircuitCode)
  1164. {
  1165. LL_WARNS("AppInit") << "Attempting to connect to simulator with a zero circuit code!" << LL_ENDL;
  1166. }
  1167. gUseCircuitCallbackCalled = false;
  1168. msg->enableCircuit(gFirstSim, TRUE);
  1169. // now, use the circuit info to tell simulator about us!
  1170. LL_INFOS("AppInit") << "viewer: UserLoginLocationReply() Enabling " << gFirstSim << " with code " << msg->mOurCircuitCode << LL_ENDL;
  1171. msg->newMessageFast(_PREHASH_UseCircuitCode);
  1172. msg->nextBlockFast(_PREHASH_CircuitCode);
  1173. msg->addU32Fast(_PREHASH_Code, msg->mOurCircuitCode);
  1174. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  1175. msg->addUUIDFast(_PREHASH_ID, gAgent.getID());
  1176. msg->sendReliable(
  1177. gFirstSim,
  1178. gSavedSettings.getS32("UseCircuitCodeMaxRetries"),
  1179. FALSE,
  1180. gSavedSettings.getF32("UseCircuitCodeTimeout"),
  1181. use_circuit_callback,
  1182. NULL);
  1183. timeout.reset();
  1184. return FALSE;
  1185. }
  1186. //---------------------------------------------------------------------
  1187. // Agent Send
  1188. //---------------------------------------------------------------------
  1189. if(STATE_WORLD_WAIT == LLStartUp::getStartupState())
  1190. {
  1191. LL_DEBUGS("AppInit") << "Waiting for simulator ack...." << LL_ENDL;
  1192. set_startup_status(0.59f, LLTrans::getString("LoginWaitingForRegionHandshake"), gAgent.mMOTD);
  1193. if(gGotUseCircuitCodeAck)
  1194. {
  1195. LLStartUp::setStartupState( STATE_AGENT_SEND );
  1196. }
  1197. LLMessageSystem* msg = gMessageSystem;
  1198. while (msg->checkAllMessages(gFrameCount, gServicePump))
  1199. {
  1200. }
  1201. msg->processAcks();
  1202. return FALSE;
  1203. }
  1204. //---------------------------------------------------------------------
  1205. // Agent Send
  1206. //---------------------------------------------------------------------
  1207. if (STATE_AGENT_SEND == LLStartUp::getStartupState())
  1208. {
  1209. LL_DEBUGS("AppInit") << "Connecting to region..." << LL_ENDL;
  1210. set_startup_status(0.60f, LLTrans::getString("LoginConnectingToRegion"), gAgent.mMOTD);
  1211. // register with the message system so it knows we're
  1212. // expecting this message
  1213. LLMessageSystem* msg = gMessageSystem;
  1214. msg->setHandlerFuncFast(
  1215. _PREHASH_AgentMovementComplete,
  1216. process_agent_movement_complete);
  1217. LLViewerRegion* regionp = gAgent.getRegion();
  1218. if(regionp)
  1219. {
  1220. send_complete_agent_movement(regionp->getHost());
  1221. gAssetStorage->setUpstream(regionp->getHost());
  1222. gCacheName->setUpstream(regionp->getHost());
  1223. msg->newMessageFast(_PREHASH_EconomyDataRequest);
  1224. gAgent.sendReliableMessage();
  1225. }
  1226. // Create login effect
  1227. // But not on first login, because you can't see your avatar then
  1228. if (!gAgent.isFirstLogin())
  1229. {
  1230. LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
  1231. effectp->setPositionGlobal(gAgent.getPositionGlobal());
  1232. effectp->setColor(LLColor4U(gAgent.getEffectColor()));
  1233. LLHUDManager::getInstance()->sendEffects();
  1234. }
  1235. LLStartUp::setStartupState( STATE_AGENT_WAIT ); // Go to STATE_AGENT_WAIT
  1236. timeout.reset();
  1237. return FALSE;
  1238. }
  1239. //---------------------------------------------------------------------
  1240. // Agent Wait
  1241. //---------------------------------------------------------------------
  1242. if (STATE_AGENT_WAIT == LLStartUp::getStartupState())
  1243. {
  1244. LLMessageSystem* msg = gMessageSystem;
  1245. while (msg->checkAllMessages(gFrameCount, gServicePump))
  1246. {
  1247. if (gAgentMovementCompleted)
  1248. {
  1249. // Sometimes we have more than one message in the
  1250. // queue. break out of this loop and continue
  1251. // processing. If we don't, then this could skip one
  1252. // or more login steps.
  1253. break;
  1254. }
  1255. else
  1256. {
  1257. LL_DEBUGS("AppInit") << "Awaiting AvatarInitComplete, got "
  1258. << msg->getMessageName() << LL_ENDL;
  1259. }
  1260. }
  1261. msg->processAcks();
  1262. if (gAgentMovementCompleted)
  1263. {
  1264. LLStartUp::setStartupState( STATE_INVENTORY_SEND );
  1265. }
  1266. return FALSE;
  1267. }
  1268. //---------------------------------------------------------------------
  1269. // Inventory Send
  1270. //---------------------------------------------------------------------
  1271. if (STATE_INVENTORY_SEND == LLStartUp::getStartupState())
  1272. {
  1273. // Inform simulator of our language preference
  1274. LLAgentLanguage::update();
  1275. // unpack thin inventory
  1276. LLSD response = LLLoginInstance::getInstance()->getResponse();
  1277. //bool dump_buffer = false;
  1278. LLSD inv_lib_root = response["inventory-lib-root"];
  1279. if(inv_lib_root.isDefined())
  1280. {
  1281. // should only be one
  1282. LLSD id = inv_lib_root[0]["folder_id"];
  1283. if(id.isDefined())
  1284. {
  1285. gInventory.setLibraryRootFolderID(id.asUUID());
  1286. }
  1287. }
  1288.  
  1289. LLSD inv_lib_owner = response["inventory-lib-owner"];
  1290. if(inv_lib_owner.isDefined())
  1291. {
  1292. // should only be one
  1293. LLSD id = inv_lib_owner[0]["agent_id"];
  1294. if(id.isDefined())
  1295. {
  1296. gInventory.setLibraryOwnerID( LLUUID(id.asUUID()));
  1297. }
  1298. }
  1299. LLSD inv_skel_lib = response["inventory-skel-lib"];
  1300.   if(inv_skel_lib.isDefined() && gInventory.getLibraryOwnerID().notNull())
  1301.   {
  1302.   if(!gInventory.loadSkeleton(inv_skel_lib, gInventory.getLibraryOwnerID()))
  1303.   {
  1304.   LL_WARNS("AppInit") << "Problem loading inventory-skel-lib" << LL_ENDL;
  1305.   }
  1306.   }
  1307. LLSD inv_skeleton = response["inventory-skeleton"];
  1308.   if(inv_skeleton.isDefined())
  1309.   {
  1310.   if(!gInventory.loadSkeleton(inv_skeleton, gAgent.getID()))
  1311.   {
  1312.   LL_WARNS("AppInit") << "Problem loading inventory-skel-targets" << LL_ENDL;
  1313.   }
  1314.   }
  1315. LLSD buddy_list = response["buddy-list"];
  1316.   if(buddy_list.isDefined())
  1317.   {
  1318. LLAvatarTracker::buddy_map_t list;
  1319. LLUUID agent_id;
  1320. S32 has_rights = 0, given_rights = 0;
  1321. for(LLSD::array_const_iterator it = buddy_list.beginArray(),
  1322. end = buddy_list.endArray(); it != end; ++it)
  1323. {
  1324. LLSD buddy_id = (*it)["buddy_id"];
  1325. if(buddy_id.isDefined())
  1326. {
  1327. agent_id = buddy_id.asUUID();
  1328. }
  1329. LLSD buddy_rights_has = (*it)["buddy_rights_has"];
  1330. if(buddy_rights_has.isDefined())
  1331. {
  1332. has_rights = buddy_rights_has.asInteger();
  1333. }
  1334. LLSD buddy_rights_given = (*it)["buddy_rights_given"];
  1335. if(buddy_rights_given.isDefined())
  1336. {
  1337. given_rights = buddy_rights_given.asInteger();
  1338. }
  1339. list[agent_id] = new LLRelationship(given_rights, has_rights, false);
  1340. }
  1341. LLAvatarTracker::instance().addBuddyList(list);
  1342.   }
  1343. bool show_hud = false;
  1344. LLSD tutorial_setting = response["tutorial_setting"];
  1345. if(tutorial_setting.isDefined())
  1346. {
  1347. for(LLSD::array_const_iterator it = tutorial_setting.beginArray(),
  1348. end = tutorial_setting.endArray(); it != end; ++it)
  1349. {
  1350. LLSD tutorial_url = (*it)["tutorial_url"];
  1351. if(tutorial_url.isDefined())
  1352. {
  1353. // Tutorial floater will append language code
  1354. gSavedSettings.setString("TutorialURL", tutorial_url.asString());
  1355. }
  1356. // For Viewer 2.0 we are not using the web-based tutorial
  1357. // If we reverse that decision, put this code back and use
  1358. // login.cgi to send a different URL with content that matches
  1359. // the Viewer 2.0 UI.
  1360. //LLSD use_tutorial = (*it)["use_tutorial"];
  1361. //if(use_tutorial.asString() == "true")
  1362. //{
  1363. // show_hud = true;
  1364. //}
  1365. }
  1366. }
  1367. // Either we want to show tutorial because this is the first login
  1368. // to a Linden Help Island or the user quit with the tutorial
  1369. // visible.  JC
  1370. if (show_hud || gSavedSettings.getBOOL("ShowTutorial"))
  1371. {
  1372. LLFloaterReg::showInstance("hud", LLSD(), FALSE);
  1373. }
  1374. LLSD event_categories = response["event_categories"];
  1375. if(event_categories.isDefined())
  1376. {
  1377. LLEventInfo::loadCategories(event_categories);
  1378. }
  1379. LLSD event_notifications = response["event_notifications"];
  1380. if(event_notifications.isDefined())
  1381. {
  1382. gEventNotifier.load(event_notifications);
  1383. }
  1384. LLSD classified_categories = response["classified_categories"];
  1385. if(classified_categories.isDefined())
  1386. {
  1387. LLClassifiedInfo::loadCategories(classified_categories);
  1388. }
  1389. // This method MUST be called before gInventory.findCategoryUUIDForType because of 
  1390. // gInventory.mIsAgentInvUsable is set to true in the gInventory.buildParentChildMap.
  1391. gInventory.buildParentChildMap();
  1392. //all categories loaded. lets create "My Favorites" category
  1393. gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE,true);
  1394. // Checks whether "Friends" and "Friends/All" folders exist in "Calling Cards" folder,
  1395. // fetches their contents if needed and synchronizes it with buddies list.
  1396. // If the folders are not found they are created.
  1397. LLFriendCardsManager::instance().syncFriendCardsFolders();
  1398. // set up callbacks
  1399. llinfos << "Registering Callbacks" << llendl;
  1400. LLMessageSystem* msg = gMessageSystem;
  1401. llinfos << " Inventory" << llendl;
  1402. LLInventoryModel::registerCallbacks(msg);
  1403. llinfos << " AvatarTracker" << llendl;
  1404. LLAvatarTracker::instance().registerCallbacks(msg);
  1405. llinfos << " Landmark" << llendl;
  1406. LLLandmark::registerCallbacks(msg);
  1407. // request mute list
  1408. llinfos << "Requesting Mute List" << llendl;
  1409. LLMuteList::getInstance()->requestFromServer(gAgent.getID());
  1410. // Get L$ and ownership credit information
  1411. llinfos << "Requesting Money Balance" << llendl;
  1412. LLStatusBar::sendMoneyBalanceRequest();
  1413. // request all group information
  1414. llinfos << "Requesting Agent Data" << llendl;
  1415. gAgent.sendAgentDataUpdateRequest();
  1416. // Create the inventory views
  1417. llinfos << "Creating Inventory Views" << llendl;
  1418. LLFloaterReg::getInstance("inventory");
  1419. LLStartUp::setStartupState( STATE_MISC );
  1420. return FALSE;
  1421. }
  1422. //---------------------------------------------------------------------
  1423. // Misc
  1424. //---------------------------------------------------------------------
  1425. if (STATE_MISC == LLStartUp::getStartupState())
  1426. {
  1427. // We have a region, and just did a big inventory download.
  1428. // We can estimate the user's connection speed, and set their
  1429. // max bandwidth accordingly.  JC
  1430. if (gSavedSettings.getBOOL("FirstLoginThisInstall"))
  1431. {
  1432. // This is actually a pessimistic computation, because TCP may not have enough
  1433. // time to ramp up on the (small) default inventory file to truly measure max
  1434. // bandwidth. JC
  1435. F64 rate_bps = LLLoginInstance::getInstance()->getLastTransferRateBPS();
  1436. const F32 FAST_RATE_BPS = 600.f * 1024.f;
  1437. const F32 FASTER_RATE_BPS = 750.f * 1024.f;
  1438. F32 max_bandwidth = gViewerThrottle.getMaxBandwidth();
  1439. if (rate_bps > FASTER_RATE_BPS
  1440. && rate_bps > max_bandwidth)
  1441. {
  1442. LL_DEBUGS("AppInit") << "Fast network connection, increasing max bandwidth to " 
  1443. << FASTER_RATE_BPS/1024.f 
  1444. << " kbps" << LL_ENDL;
  1445. gViewerThrottle.setMaxBandwidth(FASTER_RATE_BPS / 1024.f);
  1446. }
  1447. else if (rate_bps > FAST_RATE_BPS
  1448. && rate_bps > max_bandwidth)
  1449. {
  1450. LL_DEBUGS("AppInit") << "Fast network connection, increasing max bandwidth to " 
  1451. << FAST_RATE_BPS/1024.f 
  1452. << " kbps" << LL_ENDL;
  1453. gViewerThrottle.setMaxBandwidth(FAST_RATE_BPS / 1024.f);
  1454. }
  1455. // Set the show start location to true, now that the user has logged
  1456. // on with this install.
  1457. gSavedSettings.setBOOL("ShowStartLocation", TRUE);
  1458. LLSideTray::getInstance()->showPanel("panel_home", LLSD());
  1459. }
  1460. // We're successfully logged in.
  1461. gSavedSettings.setBOOL("FirstLoginThisInstall", FALSE);
  1462. LLFloaterReg::showInitialVisibleInstances();
  1463. // based on the comments, we've successfully logged in so we can delete the 'forced'
  1464. // URL that the updater set in settings.ini (in a mostly paranoid fashion)
  1465. std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" );
  1466. if ( nextLoginLocation.length() )
  1467. {
  1468. // clear it
  1469. gSavedSettings.setString( "NextLoginLocation", "" );
  1470. // and make sure it's saved
  1471. gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile") , TRUE );
  1472. LLUIColorTable::instance().saveUserSettings();
  1473. };
  1474. if (!gNoRender)
  1475. {
  1476. // JC: Initializing audio requests many sounds for download.
  1477. init_audio();
  1478. // JC: Initialize "active" gestures.  This may also trigger
  1479. // many gesture downloads, if this is the user's first
  1480. // time on this machine or -purge has been run.
  1481. LLSD gesture_options 
  1482. = LLLoginInstance::getInstance()->getResponse("gestures");
  1483. if (gesture_options.isDefined())
  1484. {
  1485. LL_DEBUGS("AppInit") << "Gesture Manager loading " << gesture_options.size()
  1486. << LL_ENDL;
  1487. std::vector<LLUUID> item_ids;
  1488. for(LLSD::array_const_iterator resp_it = gesture_options.beginArray(),
  1489. end = gesture_options.endArray(); resp_it != end; ++resp_it)
  1490. {
  1491. // If the id is not specifed in the LLSD,
  1492. // the LLSD operator[]() will return a null LLUUID. 
  1493. LLUUID item_id = (*resp_it)["item_id"];
  1494. LLUUID asset_id = (*resp_it)["asset_id"];
  1495. if (item_id.notNull() && asset_id.notNull())
  1496. {
  1497. // Could schedule and delay these for later.
  1498. const BOOL no_inform_server = FALSE;
  1499. const BOOL no_deactivate_similar = FALSE;
  1500. LLGestureManager::instance().activateGestureWithAsset(item_id, asset_id,
  1501.  no_inform_server,
  1502.  no_deactivate_similar);
  1503. // We need to fetch the inventory items for these gestures
  1504. // so we have the names to populate the UI.
  1505. item_ids.push_back(item_id);
  1506. }
  1507. }
  1508. // no need to add gesture to inventory observer, it's already made in constructor 
  1509. LLGestureManager::instance().fetchItems(item_ids);
  1510. }
  1511. }
  1512. gDisplaySwapBuffers = TRUE;
  1513. LLMessageSystem* msg = gMessageSystem;
  1514. msg->setHandlerFuncFast(_PREHASH_SoundTrigger, process_sound_trigger);
  1515. msg->setHandlerFuncFast(_PREHASH_PreloadSound, process_preload_sound);
  1516. msg->setHandlerFuncFast(_PREHASH_AttachedSound, process_attached_sound);
  1517. msg->setHandlerFuncFast(_PREHASH_AttachedSoundGainChange, process_attached_sound_gain_change);
  1518. LL_DEBUGS("AppInit") << "Initialization complete" << LL_ENDL;
  1519. gRenderStartTime.reset();
  1520. gForegroundTime.reset();
  1521. // HACK: Inform simulator of window size.
  1522. // Do this here so it's less likely to race with RegisterNewAgent.
  1523. // TODO: Put this into RegisterNewAgent
  1524. // JC - 7/20/2002
  1525. gViewerWindow->sendShapeToSim();
  1526. // Ignore stipend information for now.  Money history is on the web site.
  1527. // if needed, show the L$ history window
  1528. //if (stipend_since_login && !gNoRender)
  1529. //{
  1530. //}
  1531. // The reason we show the alert is because we want to
  1532. // reduce confusion for when you log in and your provided
  1533. // location is not your expected location. So, if this is
  1534. // your first login, then you do not have an expectation,
  1535. // thus, do not show this alert.
  1536. if (!gAgent.isFirstLogin())
  1537. {
  1538. bool url_ok = LLURLSimString::sInstance.parse();
  1539. if ((url_ok && gAgentStartLocation == "url") ||
  1540. (!url_ok && ((gAgentStartLocation == gSavedSettings.getString("LoginLocation")))))
  1541. {
  1542. // Start location is OK
  1543. // Disabled code to restore camera location and focus if logging in to default location
  1544. static bool samename = false;
  1545. if (samename)
  1546. {
  1547. // restore old camera pos
  1548. gAgent.setFocusOnAvatar(FALSE, FALSE);
  1549. gAgent.setCameraPosAndFocusGlobal(gSavedSettings.getVector3d("CameraPosOnLogout"), gSavedSettings.getVector3d("FocusPosOnLogout"), LLUUID::null);
  1550. BOOL limit_hit = FALSE;
  1551. gAgent.calcCameraPositionTargetGlobal(&limit_hit);
  1552. if (limit_hit)
  1553. {
  1554. gAgent.setFocusOnAvatar(TRUE, FALSE);
  1555. }
  1556. gAgent.stopCameraAnimation();
  1557. }
  1558. }
  1559. else
  1560. {
  1561. std::string msg;
  1562. if (url_ok)
  1563. {
  1564. msg = "AvatarMovedDesired";
  1565. }
  1566. else if (gSavedSettings.getString("LoginLocation") == "home")
  1567. {
  1568. msg = "AvatarMovedHome";
  1569. }
  1570. else
  1571. {
  1572. msg = "AvatarMovedLast";
  1573. }
  1574. LLNotificationsUtil::add(msg);
  1575. }
  1576. }
  1577.         //DEV-17797.  get null folder.  Any items found here moved to Lost and Found
  1578.         LLInventoryModel::findLostItems();
  1579. LLStartUp::setStartupState( STATE_PRECACHE );
  1580. timeout.reset();
  1581. return FALSE;
  1582. }
  1583. if (STATE_PRECACHE == LLStartUp::getStartupState())
  1584. {
  1585. F32 timeout_frac = timeout.getElapsedTimeF32()/PRECACHING_DELAY;
  1586. // We now have an inventory skeleton, so if this is a user's first
  1587. // login, we can start setting up their clothing and avatar 
  1588. // appearance.  This helps to avoid the generic "Ruth" avatar in
  1589. // the orientation island tutorial experience. JC
  1590. if (gAgent.isFirstLogin()
  1591. && !sInitialOutfit.empty()    // registration set up an outfit
  1592. && !sInitialOutfitGender.empty() // and a gender
  1593. && gAgent.getAvatarObject()   // can't wear clothes without object
  1594. && !gAgent.isGenderChosen() ) // nothing already loading
  1595. {
  1596. // Start loading the wearables, textures, gestures
  1597. LLStartUp::loadInitialOutfit( sInitialOutfit, sInitialOutfitGender );
  1598. }
  1599. // wait precache-delay and for agent's avatar or a lot longer.
  1600. if(((timeout_frac > 1.f) && gAgent.getAvatarObject())
  1601.    || (timeout_frac > 3.f))
  1602. {
  1603. LLStartUp::setStartupState( STATE_WEARABLES_WAIT );
  1604. }
  1605. else
  1606. {
  1607. update_texture_fetch();
  1608. set_startup_status(0.60f + 0.30f * timeout_frac,
  1609. LLTrans::getString("LoginPrecaching"),
  1610. gAgent.mMOTD);
  1611. display_startup();
  1612. if (!LLViewerShaderMgr::sInitialized)
  1613. {
  1614. LLViewerShaderMgr::sInitialized = TRUE;
  1615. LLViewerShaderMgr::instance()->setShaders();
  1616. }
  1617. }
  1618. return TRUE;
  1619. }
  1620. if (STATE_WEARABLES_WAIT == LLStartUp::getStartupState())
  1621. {
  1622. static LLFrameTimer wearables_timer;
  1623. const F32 wearables_time = wearables_timer.getElapsedTimeF32();
  1624. const F32 MAX_WEARABLES_TIME = 10.f;
  1625. if (!gAgent.isGenderChosen())
  1626. {
  1627. // No point in waiting for clothing, we don't even
  1628. // know what gender we are.  Pop a dialog to ask and
  1629. // proceed to draw the world. JC
  1630. //
  1631. // *NOTE: We might hit this case even if we have an
  1632. // initial outfit, but if the load hasn't started
  1633. // already then something is wrong so fall back
  1634. // to generic outfits. JC
  1635. LLNotificationsUtil::add("WelcomeChooseSex", LLSD(), LLSD(),
  1636. callback_choose_gender);
  1637. LLStartUp::setStartupState( STATE_CLEANUP );
  1638. return TRUE;
  1639. }
  1640. if (wearables_time > MAX_WEARABLES_TIME)
  1641. {
  1642. LLNotificationsUtil::add("ClothingLoading");
  1643. LLViewerStats::getInstance()->incStat(LLViewerStats::ST_WEARABLES_TOO_LONG);
  1644. LLStartUp::setStartupState( STATE_CLEANUP );
  1645. return TRUE;
  1646. }
  1647. if (gAgent.isFirstLogin())
  1648. {
  1649. // wait for avatar to be completely loaded
  1650. if (gAgent.getAvatarObject()
  1651. && gAgent.getAvatarObject()->isFullyLoaded())
  1652. {
  1653. //llinfos << "avatar fully loaded" << llendl;
  1654. LLStartUp::setStartupState( STATE_CLEANUP );
  1655. return TRUE;
  1656. }
  1657. }
  1658. else
  1659. {
  1660. // OK to just get the wearables
  1661. if ( gAgentWearables.areWearablesLoaded() )
  1662. {
  1663. // We have our clothing, proceed.
  1664. //llinfos << "wearables loaded" << llendl;
  1665. LLStartUp::setStartupState( STATE_CLEANUP );
  1666. return TRUE;
  1667. }
  1668. }
  1669. update_texture_fetch();
  1670. set_startup_status(0.9f + 0.1f * wearables_time / MAX_WEARABLES_TIME,
  1671.  LLTrans::getString("LoginDownloadingClothing").c_str(),
  1672.  gAgent.mMOTD.c_str());
  1673. return TRUE;
  1674. }
  1675. if (STATE_CLEANUP == LLStartUp::getStartupState())
  1676. {
  1677. set_startup_status(1.0, "", "");
  1678. // Let the map know about the inventory.
  1679. LLFloaterWorldMap* floater_world_map = LLFloaterWorldMap::getInstance();
  1680. if(floater_world_map)
  1681. {
  1682. floater_world_map->observeInventory(&gInventory);
  1683. floater_world_map->observeFriends();
  1684. }
  1685. gViewerWindow->showCursor();
  1686. gViewerWindow->getWindow()->resetBusyCount();
  1687. gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
  1688. LL_DEBUGS("AppInit") << "Done releasing bitmap" << LL_ENDL;
  1689. gViewerWindow->setShowProgress(FALSE);
  1690. gViewerWindow->setProgressCancelButtonVisible(FALSE);
  1691. // We're not away from keyboard, even though login might have taken
  1692. // a while. JC
  1693. gAgent.clearAFK();
  1694. // Have the agent start watching the friends list so we can update proxies
  1695. gAgent.observeFriends();
  1696. if (gSavedSettings.getBOOL("LoginAsGod"))
  1697. {
  1698. gAgent.requestEnterGodMode();
  1699. }
  1700. // Start automatic replay if the flag is set.
  1701. if (gSavedSettings.getBOOL("StatsAutoRun") || LLAgentPilot::sReplaySession)
  1702. {
  1703. LLUUID id;
  1704. LL_DEBUGS("AppInit") << "Starting automatic playback" << LL_ENDL;
  1705. gAgentPilot.startPlayback();
  1706. }
  1707. show_debug_menus(); // Debug menu visiblity and First Use trigger
  1708. // If we've got a startup URL, dispatch it
  1709. LLStartUp::dispatchURL();
  1710. // Retrieve information about the land data
  1711. // (just accessing this the first time will fetch it,
  1712. // then the data is cached for the viewer's lifetime)
  1713. LLProductInfoRequestManager::instance();
  1714. // *FIX:Mani - What do I do here?
  1715. // Need we really clear the Auth response data?
  1716. // Clean up the userauth stuff.
  1717. // LLUserAuth::getInstance()->reset();
  1718. LLStartUp::setStartupState( STATE_STARTED );
  1719. // Unmute audio if desired and setup volumes.
  1720. // Unmute audio if desired and setup volumes.
  1721. // This is a not-uncommon crash site, so surround it with
  1722. // llinfos output to aid diagnosis.
  1723. LL_INFOS("AppInit") << "Doing first audio_update_volume..." << LL_ENDL;
  1724. audio_update_volume();
  1725. LL_INFOS("AppInit") << "Done first audio_update_volume." << LL_ENDL;
  1726. // reset keyboard focus to sane state of pointing at world
  1727. gFocusMgr.setKeyboardFocus(NULL);
  1728. #if 0 // sjb: enable for auto-enabling timer display 
  1729. gDebugView->mFastTimerView->setVisible(TRUE);
  1730. #endif
  1731. LLAppViewer::instance()->handleLoginComplete();
  1732. // reset timers now that we are running "logged in" logic
  1733. LLFastTimer::reset();
  1734. LLAgentPicksInfo::getInstance()->requestNumberOfPicks();
  1735. LLIMFloater::initIMFloater();
  1736. return TRUE;
  1737. }
  1738. LL_WARNS("AppInit") << "Reached end of idle_startup for state " << LLStartUp::getStartupState() << LL_ENDL;
  1739. return TRUE;
  1740. }
  1741. //
  1742. // local function definition
  1743. //
  1744. void login_show()
  1745. {
  1746. LL_INFOS("AppInit") << "Initializing Login Screen" << LL_ENDL;
  1747. #ifdef LL_RELEASE_FOR_DOWNLOAD
  1748. BOOL bUseDebugLogin = gSavedSettings.getBOOL("UseDebugLogin");
  1749. #else
  1750. BOOL bUseDebugLogin = TRUE;
  1751. #endif
  1752. LLPanelLogin::show( gViewerWindow->getWindowRectScaled(),
  1753. bUseDebugLogin,
  1754. login_callback, NULL );
  1755. // UI textures have been previously loaded in doPreloadImages()
  1756. LL_DEBUGS("AppInit") << "Setting Servers" << LL_ENDL;
  1757. LLPanelLogin::addServer(LLViewerLogin::getInstance()->getGridLabel(), LLViewerLogin::getInstance()->getGridChoice());
  1758. LLViewerLogin* vl = LLViewerLogin::getInstance();
  1759. for(int grid_index = GRID_INFO_ADITI; grid_index < GRID_INFO_OTHER; ++grid_index)
  1760. {
  1761. LLPanelLogin::addServer(vl->getKnownGridLabel((EGridInfo)grid_index), grid_index);
  1762. }
  1763. }
  1764. // Callback for when login screen is closed.  Option 0 = connect, option 1 = quit.
  1765. void login_callback(S32 option, void *userdata)
  1766. {
  1767. const S32 CONNECT_OPTION = 0;
  1768. const S32 QUIT_OPTION = 1;
  1769. if (CONNECT_OPTION == option)
  1770. {
  1771. LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
  1772. return;
  1773. }
  1774. else if (QUIT_OPTION == option) // *TODO: THIS CODE SEEMS TO BE UNREACHABLE!!!!! login_callback is never called with option equal to QUIT_OPTION
  1775. {
  1776. // Make sure we don't save the password if the user is trying to clear it.
  1777. std::string first, last, password;
  1778. LLPanelLogin::getFields(&first, &last, &password);
  1779. if (!gSavedSettings.getBOOL("RememberPassword"))
  1780. {
  1781. // turn off the setting and write out to disk
  1782. gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile") , TRUE );
  1783. LLUIColorTable::instance().saveUserSettings();
  1784. }
  1785. // Next iteration through main loop should shut down the app cleanly.
  1786. LLAppViewer::instance()->userQuit();
  1787. if (LLAppViewer::instance()->quitRequested())
  1788. {
  1789. LLPanelLogin::closePanel();
  1790. }
  1791. return;
  1792. }
  1793. else
  1794. {
  1795. LL_WARNS("AppInit") << "Unknown login button clicked" << LL_ENDL;
  1796. }
  1797. }
  1798. // static
  1799. std::string LLStartUp::loadPasswordFromDisk()
  1800. {
  1801. // Only load password if we also intend to save it (otherwise the user
  1802. // wonders what we're doing behind his back).  JC
  1803. BOOL remember_password = gSavedSettings.getBOOL("RememberPassword");
  1804. if (!remember_password)
  1805. {
  1806. return std::string("");
  1807. }
  1808. std::string hashed_password("");
  1809. // Look for legacy "marker" password from settings.ini
  1810. hashed_password = gSavedSettings.getString("Marker");
  1811. if (!hashed_password.empty())
  1812. {
  1813. // Stomp the Marker entry.
  1814. gSavedSettings.setString("Marker", "");
  1815. // Return that password.
  1816. return hashed_password;
  1817. }
  1818. std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
  1819.    "password.dat");
  1820. LLFILE* fp = LLFile::fopen(filepath, "rb"); /* Flawfinder: ignore */
  1821. if (!fp)
  1822. {
  1823. return hashed_password;
  1824. }
  1825. // UUID is 16 bytes, written into ASCII is 32 characters
  1826. // without trailing 
  1827. const S32 HASHED_LENGTH = 32;
  1828. U8 buffer[HASHED_LENGTH+1];
  1829. if (1 != fread(buffer, HASHED_LENGTH, 1, fp))
  1830. {
  1831. return hashed_password;
  1832. }
  1833. fclose(fp);
  1834. // Decipher with MAC address
  1835. LLXORCipher cipher(gMACAddress, 6);
  1836. cipher.decrypt(buffer, HASHED_LENGTH);
  1837. buffer[HASHED_LENGTH] = '';
  1838. // Check to see if the mac address generated a bad hashed
  1839. // password. It should be a hex-string or else the mac adress has
  1840. // changed. This is a security feature to make sure that if you
  1841. // get someone's password.dat file, you cannot hack their account.
  1842. if(is_hex_string(buffer, HASHED_LENGTH))
  1843. {
  1844. hashed_password.assign((char*)buffer);
  1845. }
  1846. return hashed_password;
  1847. }
  1848. // static
  1849. void LLStartUp::savePasswordToDisk(const std::string& hashed_password)
  1850. {
  1851. std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
  1852.    "password.dat");
  1853. LLFILE* fp = LLFile::fopen(filepath, "wb"); /* Flawfinder: ignore */
  1854. if (!fp)
  1855. {
  1856. return;
  1857. }
  1858. // Encipher with MAC address
  1859. const S32 HASHED_LENGTH = 32;
  1860. U8 buffer[HASHED_LENGTH+1];
  1861. LLStringUtil::copy((char*)buffer, hashed_password.c_str(), HASHED_LENGTH+1);
  1862. LLXORCipher cipher(gMACAddress, 6);
  1863. cipher.encrypt(buffer, HASHED_LENGTH);
  1864. if (fwrite(buffer, HASHED_LENGTH, 1, fp) != 1)
  1865. {
  1866. LL_WARNS("AppInit") << "Short write" << LL_ENDL;
  1867. }
  1868. fclose(fp);
  1869. }
  1870. // static
  1871. void LLStartUp::deletePasswordFromDisk()
  1872. {
  1873. std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
  1874.   "password.dat");
  1875. LLFile::remove(filepath);
  1876. }
  1877. bool is_hex_string(U8* str, S32 len)
  1878. {
  1879. bool rv = true;
  1880. U8* c = str;
  1881. while(rv && len--)
  1882. {
  1883. switch(*c)
  1884. {
  1885. case '0':
  1886. case '1':
  1887. case '2':
  1888. case '3':
  1889. case '4':
  1890. case '5':
  1891. case '6':
  1892. case '7':
  1893. case '8':
  1894. case '9':
  1895. case 'a':
  1896. case 'b':
  1897. case 'c':
  1898. case 'd':
  1899. case 'e':
  1900. case 'f':
  1901. ++c;
  1902. break;
  1903. default:
  1904. rv = false;
  1905. break;
  1906. }
  1907. }
  1908. return rv;
  1909. }
  1910. void show_first_run_dialog()
  1911. {
  1912. LLNotificationsUtil::add("FirstRun", LLSD(), LLSD(), first_run_dialog_callback);
  1913. }
  1914. bool first_run_dialog_callback(const LLSD& notification, const LLSD& response)
  1915. {
  1916. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  1917. if (0 == option)
  1918. {
  1919. LL_DEBUGS("AppInit") << "First run dialog cancelling" << LL_ENDL;
  1920. LLWeb::loadURLExternal(LLTrans::getString("create_account_url") );
  1921. }
  1922. LLPanelLogin::giveFocus();
  1923. return false;
  1924. }
  1925. void set_startup_status(const F32 frac, const std::string& string, const std::string& msg)
  1926. {
  1927. gViewerWindow->setProgressPercent(frac*100);
  1928. gViewerWindow->setProgressString(string);
  1929. gViewerWindow->setProgressMessage(msg);
  1930. }
  1931. bool login_alert_status(const LLSD& notification, const LLSD& response)
  1932. {
  1933. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  1934.     // Buttons
  1935.     switch( option )
  1936.     {
  1937.         case 0:     // OK
  1938.             break;
  1939.       //  case 1:     // Help
  1940.       //      LLWeb::loadURL(LLNotifications::instance().getGlobalString("SUPPORT_URL") );
  1941.       //      break;
  1942.         case 2:     // Teleport
  1943.             // Restart the login process, starting at our home locaton
  1944.             LLURLSimString::setString("home");
  1945.             LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
  1946.             break;
  1947.         default:
  1948.             LL_WARNS("AppInit") << "Missing case in login_alert_status switch" << LL_ENDL;
  1949.     }
  1950. LLPanelLogin::giveFocus();
  1951. return false;
  1952. }
  1953. void use_circuit_callback(void**, S32 result)
  1954. {
  1955. // bail if we're quitting.
  1956. if(LLApp::isExiting()) return;
  1957. if( !gUseCircuitCallbackCalled )
  1958. {
  1959. gUseCircuitCallbackCalled = true;
  1960. if (result)
  1961. {
  1962. // Make sure user knows something bad happened. JC
  1963. LL_WARNS("AppInit") << "Backing up to login screen!" << LL_ENDL;
  1964. LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status);
  1965. reset_login();
  1966. }
  1967. else
  1968. {
  1969. gGotUseCircuitCodeAck = true;
  1970. }
  1971. }
  1972. }
  1973. void register_viewer_callbacks(LLMessageSystem* msg)
  1974. {
  1975. msg->setHandlerFuncFast(_PREHASH_LayerData, process_layer_data );
  1976. msg->setHandlerFuncFast(_PREHASH_ImageData, LLViewerTextureList::receiveImageHeader );
  1977. msg->setHandlerFuncFast(_PREHASH_ImagePacket, LLViewerTextureList::receiveImagePacket );
  1978. msg->setHandlerFuncFast(_PREHASH_ObjectUpdate, process_object_update );
  1979. msg->setHandlerFunc("ObjectUpdateCompressed", process_compressed_object_update );
  1980. msg->setHandlerFunc("ObjectUpdateCached", process_cached_object_update );
  1981. msg->setHandlerFuncFast(_PREHASH_ImprovedTerseObjectUpdate, process_terse_object_update_improved );
  1982. msg->setHandlerFunc("SimStats", process_sim_stats);
  1983. msg->setHandlerFuncFast(_PREHASH_HealthMessage, process_health_message );
  1984. msg->setHandlerFuncFast(_PREHASH_EconomyData, process_economy_data);
  1985. msg->setHandlerFunc("RegionInfo", LLViewerRegion::processRegionInfo);
  1986. msg->setHandlerFuncFast(_PREHASH_ChatFromSimulator, process_chat_from_simulator);
  1987. msg->setHandlerFuncFast(_PREHASH_KillObject, process_kill_object, NULL);
  1988. msg->setHandlerFuncFast(_PREHASH_SimulatorViewerTimeMessage, process_time_synch, NULL);
  1989. msg->setHandlerFuncFast(_PREHASH_EnableSimulator, process_enable_simulator);
  1990. msg->setHandlerFuncFast(_PREHASH_DisableSimulator, process_disable_simulator);
  1991. msg->setHandlerFuncFast(_PREHASH_KickUser, process_kick_user, NULL);
  1992. msg->setHandlerFunc("CrossedRegion", process_crossed_region);
  1993. msg->setHandlerFuncFast(_PREHASH_TeleportFinish, process_teleport_finish);
  1994. msg->setHandlerFuncFast(_PREHASH_AlertMessage,             process_alert_message);
  1995. msg->setHandlerFunc("AgentAlertMessage", process_agent_alert_message);
  1996. msg->setHandlerFuncFast(_PREHASH_MeanCollisionAlert,             process_mean_collision_alert_message,  NULL);
  1997. msg->setHandlerFunc("ViewerFrozenMessage",             process_frozen_message);
  1998. msg->setHandlerFuncFast(_PREHASH_NameValuePair, process_name_value);
  1999. msg->setHandlerFuncFast(_PREHASH_RemoveNameValuePair, process_remove_name_value);
  2000. msg->setHandlerFuncFast(_PREHASH_AvatarAnimation, process_avatar_animation);
  2001. msg->setHandlerFuncFast(_PREHASH_AvatarAppearance, process_avatar_appearance);
  2002. msg->setHandlerFunc("AgentCachedTextureResponse", LLAgent::processAgentCachedTextureResponse);
  2003. msg->setHandlerFunc("RebakeAvatarTextures", LLVOAvatarSelf::processRebakeAvatarTextures);
  2004. msg->setHandlerFuncFast(_PREHASH_CameraConstraint, process_camera_constraint);
  2005. msg->setHandlerFuncFast(_PREHASH_AvatarSitResponse, process_avatar_sit_response);
  2006. msg->setHandlerFunc("SetFollowCamProperties", process_set_follow_cam_properties);
  2007. msg->setHandlerFunc("ClearFollowCamProperties", process_clear_follow_cam_properties);
  2008. msg->setHandlerFuncFast(_PREHASH_ImprovedInstantMessage, process_improved_im);
  2009. msg->setHandlerFuncFast(_PREHASH_ScriptQuestion, process_script_question);
  2010. msg->setHandlerFuncFast(_PREHASH_ObjectProperties, LLSelectMgr::processObjectProperties, NULL);
  2011. msg->setHandlerFuncFast(_PREHASH_ObjectPropertiesFamily, LLSelectMgr::processObjectPropertiesFamily, NULL);
  2012. msg->setHandlerFunc("ForceObjectSelect", LLSelectMgr::processForceObjectSelect);
  2013. msg->setHandlerFuncFast(_PREHASH_MoneyBalanceReply, process_money_balance_reply, NULL);
  2014. msg->setHandlerFuncFast(_PREHASH_CoarseLocationUpdate, LLWorld::processCoarseUpdate, NULL);
  2015. msg->setHandlerFuncFast(_PREHASH_ReplyTaskInventory,  LLViewerObject::processTaskInv, NULL);
  2016. msg->setHandlerFuncFast(_PREHASH_DerezContainer, process_derez_container, NULL);
  2017. msg->setHandlerFuncFast(_PREHASH_ScriptRunningReply,
  2018. &LLLiveLSLEditor::processScriptRunningReply);
  2019. msg->setHandlerFuncFast(_PREHASH_DeRezAck, process_derez_ack);
  2020. msg->setHandlerFunc("LogoutReply", process_logout_reply);
  2021. //msg->setHandlerFuncFast(_PREHASH_AddModifyAbility,
  2022. // &LLAgent::processAddModifyAbility);
  2023. //msg->setHandlerFuncFast(_PREHASH_RemoveModifyAbility,
  2024. // &LLAgent::processRemoveModifyAbility);
  2025. msg->setHandlerFuncFast(_PREHASH_AgentDataUpdate,
  2026. &LLAgent::processAgentDataUpdate);
  2027. msg->setHandlerFuncFast(_PREHASH_AgentGroupDataUpdate,
  2028. &LLAgent::processAgentGroupDataUpdate);
  2029. msg->setHandlerFunc("AgentDropGroup",
  2030. &LLAgent::processAgentDropGroup);
  2031. // land ownership messages
  2032. msg->setHandlerFuncFast(_PREHASH_ParcelOverlay,
  2033. LLViewerParcelMgr::processParcelOverlay);
  2034. msg->setHandlerFuncFast(_PREHASH_ParcelProperties,
  2035. LLViewerParcelMgr::processParcelProperties);
  2036. msg->setHandlerFunc("ParcelAccessListReply",
  2037. LLViewerParcelMgr::processParcelAccessListReply);
  2038. msg->setHandlerFunc("ParcelDwellReply",
  2039. LLViewerParcelMgr::processParcelDwellReply);
  2040. msg->setHandlerFunc("AvatarPropertiesReply",
  2041. &LLAvatarPropertiesProcessor::processAvatarPropertiesReply);
  2042. msg->setHandlerFunc("AvatarInterestsReply",
  2043. &LLAvatarPropertiesProcessor::processAvatarInterestsReply);
  2044. msg->setHandlerFunc("AvatarGroupsReply",
  2045. &LLAvatarPropertiesProcessor::processAvatarGroupsReply);
  2046. // ratings deprecated
  2047. //msg->setHandlerFuncFast(_PREHASH_AvatarStatisticsReply,
  2048. // LLPanelAvatar::processAvatarStatisticsReply);
  2049. msg->setHandlerFunc("AvatarNotesReply",
  2050. &LLAvatarPropertiesProcessor::processAvatarNotesReply);
  2051. msg->setHandlerFunc("AvatarPicksReply",
  2052. &LLAvatarPropertiesProcessor::processAvatarPicksReply);
  2053.   msg->setHandlerFunc("AvatarClassifiedReply",
  2054.   &LLAvatarPropertiesProcessor::processAvatarClassifiedsReply);
  2055. msg->setHandlerFuncFast(_PREHASH_CreateGroupReply,
  2056. LLGroupMgr::processCreateGroupReply);
  2057. msg->setHandlerFuncFast(_PREHASH_JoinGroupReply,
  2058. LLGroupMgr::processJoinGroupReply);
  2059. msg->setHandlerFuncFast(_PREHASH_EjectGroupMemberReply,
  2060. LLGroupMgr::processEjectGroupMemberReply);
  2061. msg->setHandlerFuncFast(_PREHASH_LeaveGroupReply,
  2062. LLGroupMgr::processLeaveGroupReply);
  2063. msg->setHandlerFuncFast(_PREHASH_GroupProfileReply,
  2064. LLGroupMgr::processGroupPropertiesReply);
  2065. // ratings deprecated
  2066. // msg->setHandlerFuncFast(_PREHASH_ReputationIndividualReply,
  2067. // LLFloaterRate::processReputationIndividualReply);
  2068. msg->setHandlerFuncFast(_PREHASH_AgentWearablesUpdate,
  2069. LLAgentWearables::processAgentInitialWearablesUpdate );
  2070. msg->setHandlerFunc("ScriptControlChange",
  2071. LLAgent::processScriptControlChange );
  2072. msg->setHandlerFuncFast(_PREHASH_ViewerEffect, LLHUDManager::processViewerEffect);
  2073. msg->setHandlerFuncFast(_PREHASH_GrantGodlikePowers, process_grant_godlike_powers);
  2074. msg->setHandlerFuncFast(_PREHASH_GroupAccountSummaryReply,
  2075. LLPanelGroupLandMoney::processGroupAccountSummaryReply);
  2076. msg->setHandlerFuncFast(_PREHASH_GroupAccountDetailsReply,
  2077. LLPanelGroupLandMoney::processGroupAccountDetailsReply);
  2078. msg->setHandlerFuncFast(_PREHASH_GroupAccountTransactionsReply,
  2079. LLPanelGroupLandMoney::processGroupAccountTransactionsReply);
  2080. msg->setHandlerFuncFast(_PREHASH_UserInfoReply,
  2081. process_user_info_reply);
  2082. msg->setHandlerFunc("RegionHandshake", process_region_handshake, NULL);
  2083. msg->setHandlerFunc("TeleportStart", process_teleport_start );
  2084. msg->setHandlerFunc("TeleportProgress", process_teleport_progress);
  2085. msg->setHandlerFunc("TeleportFailed", process_teleport_failed, NULL);
  2086. msg->setHandlerFunc("TeleportLocal", process_teleport_local, NULL);
  2087. msg->setHandlerFunc("ImageNotInDatabase", LLViewerTextureList::processImageNotInDatabase, NULL);
  2088. msg->setHandlerFuncFast(_PREHASH_GroupMembersReply,
  2089. LLGroupMgr::processGroupMembersReply);
  2090. msg->setHandlerFunc("GroupRoleDataReply",
  2091. LLGroupMgr::processGroupRoleDataReply);
  2092. msg->setHandlerFunc("GroupRoleMembersReply",
  2093. LLGroupMgr::processGroupRoleMembersReply);
  2094. msg->setHandlerFunc("GroupTitlesReply",
  2095. LLGroupMgr::processGroupTitlesReply);
  2096. // Special handler as this message is sometimes used for group land.
  2097. msg->setHandlerFunc("PlacesReply", process_places_reply);
  2098. msg->setHandlerFunc("GroupNoticesListReply", LLPanelGroupNotices::processGroupNoticesListReply);
  2099. msg->setHandlerFunc("AvatarPickerReply", LLFloaterAvatarPicker::processAvatarPickerReply);
  2100. msg->setHandlerFunc("MapBlockReply", LLWorldMapMessage::processMapBlockReply);
  2101. msg->setHandlerFunc("MapItemReply", LLWorldMapMessage::processMapItemReply);
  2102. msg->setHandlerFunc("EventInfoReply", LLFloaterEvent::processEventInfoReply);
  2103. msg->setHandlerFunc("PickInfoReply", &LLAvatarPropertiesProcessor::processPickInfoReply);
  2104. // msg->setHandlerFunc("ClassifiedInfoReply", LLPanelClassified::processClassifiedInfoReply);
  2105. msg->setHandlerFunc("ClassifiedInfoReply", LLAvatarPropertiesProcessor::processClassifiedInfoReply);
  2106. msg->setHandlerFunc("ParcelInfoReply", LLRemoteParcelInfoProcessor::processParcelInfoReply);
  2107. msg->setHandlerFunc("ScriptDialog", process_script_dialog);
  2108. msg->setHandlerFunc("LoadURL", process_load_url);
  2109. msg->setHandlerFunc("ScriptTeleportRequest", process_script_teleport_request);
  2110. msg->setHandlerFunc("EstateCovenantReply", process_covenant_reply);
  2111. // calling cards
  2112. msg->setHandlerFunc("OfferCallingCard", process_offer_callingcard);
  2113. msg->setHandlerFunc("AcceptCallingCard", process_accept_callingcard);
  2114. msg->setHandlerFunc("DeclineCallingCard", process_decline_callingcard);
  2115. msg->setHandlerFunc("ParcelObjectOwnersReply", LLPanelLandObjects::processParcelObjectOwnersReply);
  2116. msg->setHandlerFunc("InitiateDownload", process_initiate_download);
  2117. msg->setHandlerFunc("LandStatReply", LLFloaterTopObjects::handle_land_reply);
  2118. msg->setHandlerFunc("GenericMessage", process_generic_message);
  2119. msg->setHandlerFuncFast(_PREHASH_FeatureDisabled, process_feature_disabled_message);
  2120. }
  2121. void asset_callback_nothing(LLVFS*, const LLUUID&, LLAssetType::EType, void*, S32)
  2122. {
  2123. // nothing
  2124. }
  2125. // *HACK: Must match name in Library or agent inventory
  2126. const std::string COMMON_GESTURES_FOLDER = "Common Gestures";
  2127. const std::string MALE_GESTURES_FOLDER = "Male Gestures";
  2128. const std::string FEMALE_GESTURES_FOLDER = "Female Gestures";
  2129. const std::string MALE_OUTFIT_FOLDER = "Male Shape & Outfit";
  2130. const std::string FEMALE_OUTFIT_FOLDER = "Female Shape & Outfit";
  2131. const S32 OPT_CLOSED_WINDOW = -1;
  2132. const S32 OPT_MALE = 0;
  2133. const S32 OPT_FEMALE = 1;
  2134. bool callback_choose_gender(const LLSD& notification, const LLSD& response)
  2135. {
  2136. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  2137. switch(option)
  2138. {
  2139. case OPT_MALE:
  2140. LLStartUp::loadInitialOutfit( MALE_OUTFIT_FOLDER, "male" );
  2141. break;
  2142. case OPT_FEMALE:
  2143. case OPT_CLOSED_WINDOW:
  2144. default:
  2145. LLStartUp::loadInitialOutfit( FEMALE_OUTFIT_FOLDER, "female" );
  2146. break;
  2147. }
  2148. return false;
  2149. }
  2150. void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
  2151.    const std::string& gender_name )
  2152. {
  2153. llinfos << "starting" << llendl;
  2154. // Not going through the processAgentInitialWearables path, so need to set this here.
  2155. LLAppearanceManager::instance().setAttachmentInvLinkEnable(true);
  2156. // Initiate creation of COF, since we're also bypassing that.
  2157. gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
  2158. S32 gender = 0;
  2159. std::string gestures;
  2160. if (gender_name == "male")
  2161. {
  2162. gender = OPT_MALE;
  2163. gestures = MALE_GESTURES_FOLDER;
  2164. }
  2165. else
  2166. {
  2167. gender = OPT_FEMALE;
  2168. gestures = FEMALE_GESTURES_FOLDER;
  2169. }
  2170. // try to find the outfit - if not there, create some default
  2171. // wearables.
  2172. LLUUID cat_id = findDescendentCategoryIDByName(
  2173. gInventory.getLibraryRootFolderID(),
  2174. outfit_folder_name);
  2175. if (cat_id.isNull())
  2176. {
  2177. gAgentWearables.createStandardWearables(gender);
  2178. }
  2179. else
  2180. {
  2181. bool do_copy = true;
  2182. bool do_append = false;
  2183. LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
  2184. LLAppearanceManager::instance().wearInventoryCategory(cat, do_copy, do_append);
  2185. }
  2186. // Copy gestures
  2187. LLUUID dst_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE);
  2188. LLPointer<LLInventoryCallback> cb(NULL);
  2189. LLAppearanceManager *app_mgr = &(LLAppearanceManager::instance());
  2190. // - Copy gender-specific gestures.
  2191. LLUUID gestures_cat_id = findDescendentCategoryIDByName( 
  2192. gInventory.getLibraryRootFolderID(),
  2193. gestures);
  2194. if (gestures_cat_id.notNull())
  2195. {
  2196. callAfterCategoryFetch(gestures_cat_id,
  2197.    boost::bind(&LLAppearanceManager::shallowCopyCategory,
  2198.    app_mgr,
  2199.    gestures_cat_id,
  2200.    dst_id,
  2201.    cb));
  2202. }
  2203. // - Copy common gestures.
  2204. LLUUID common_gestures_cat_id = findDescendentCategoryIDByName( 
  2205. gInventory.getLibraryRootFolderID(),
  2206. COMMON_GESTURES_FOLDER);
  2207. if (common_gestures_cat_id.notNull())
  2208. {
  2209. callAfterCategoryFetch(common_gestures_cat_id,
  2210.    boost::bind(&LLAppearanceManager::shallowCopyCategory,
  2211.    app_mgr,
  2212.    common_gestures_cat_id,
  2213.    dst_id,
  2214.    cb));
  2215. }
  2216. // This is really misnamed -- it means we have started loading
  2217. // an outfit/shape that will give the avatar a gender eventually. JC
  2218. gAgent.setGenderChosen(TRUE);
  2219. }
  2220. // Loads a bitmap to display during load
  2221. void init_start_screen(S32 location_id)
  2222. {
  2223. if (gStartTexture.notNull())
  2224. {
  2225. gStartTexture = NULL;
  2226. LL_INFOS("AppInit") << "re-initializing start screen" << LL_ENDL;
  2227. }
  2228. LL_DEBUGS("AppInit") << "Loading startup bitmap..." << LL_ENDL;
  2229. std::string temp_str = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter();
  2230. if ((S32)START_LOCATION_ID_LAST == location_id)
  2231. {
  2232. temp_str += SCREEN_LAST_FILENAME;
  2233. }
  2234. else
  2235. {
  2236. temp_str += SCREEN_HOME_FILENAME;
  2237. }
  2238. LLPointer<LLImageBMP> start_image_bmp = new LLImageBMP;
  2239. // Turn off start screen to get around the occasional readback 
  2240. // driver bug
  2241. if(!gSavedSettings.getBOOL("UseStartScreen"))
  2242. {
  2243. LL_INFOS("AppInit")  << "Bitmap load disabled" << LL_ENDL;
  2244. return;
  2245. }
  2246. else if(!start_image_bmp->load(temp_str) )
  2247. {
  2248. LL_WARNS("AppInit") << "Bitmap load failed" << LL_ENDL;
  2249. return;
  2250. }
  2251. gStartImageWidth = start_image_bmp->getWidth();
  2252. gStartImageHeight = start_image_bmp->getHeight();
  2253. LLPointer<LLImageRaw> raw = new LLImageRaw;
  2254. if (!start_image_bmp->decode(raw, 0.0f))
  2255. {
  2256. LL_WARNS("AppInit") << "Bitmap decode failed" << LL_ENDL;
  2257. gStartTexture = NULL;
  2258. return;
  2259. }
  2260. raw->expandToPowerOfTwo();
  2261. gStartTexture = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE) ;
  2262. }
  2263. // frees the bitmap
  2264. void release_start_screen()
  2265. {
  2266. LL_DEBUGS("AppInit") << "Releasing bitmap..." << LL_ENDL;
  2267. gStartTexture = NULL;
  2268. }
  2269. // static
  2270. std::string LLStartUp::startupStateToString(EStartupState state)
  2271. {
  2272. #define RTNENUM(E) case E: return #E
  2273. switch(state){
  2274. RTNENUM( STATE_FIRST );
  2275. RTNENUM( STATE_BROWSER_INIT );
  2276. RTNENUM( STATE_LOGIN_SHOW );
  2277. RTNENUM( STATE_LOGIN_WAIT );
  2278. RTNENUM( STATE_LOGIN_CLEANUP );
  2279. RTNENUM( STATE_LOGIN_AUTH_INIT );
  2280. RTNENUM( STATE_LOGIN_CURL_UNSTUCK );
  2281. RTNENUM( STATE_LOGIN_PROCESS_RESPONSE );
  2282. RTNENUM( STATE_WORLD_INIT );
  2283. RTNENUM( STATE_MULTIMEDIA_INIT );
  2284. RTNENUM( STATE_FONT_INIT );
  2285. RTNENUM( STATE_SEED_GRANTED_WAIT );
  2286. RTNENUM( STATE_SEED_CAP_GRANTED );
  2287. RTNENUM( STATE_WORLD_WAIT );
  2288. RTNENUM( STATE_AGENT_SEND );
  2289. RTNENUM( STATE_AGENT_WAIT );
  2290. RTNENUM( STATE_INVENTORY_SEND );
  2291. RTNENUM( STATE_MISC );
  2292. RTNENUM( STATE_PRECACHE );
  2293. RTNENUM( STATE_WEARABLES_WAIT );
  2294. RTNENUM( STATE_CLEANUP );
  2295. RTNENUM( STATE_STARTED );
  2296. default:
  2297. return llformat("(state #%d)", state);
  2298. }
  2299. #undef RTNENUM
  2300. }
  2301. // static
  2302. void LLStartUp::setStartupState( EStartupState state )
  2303. {
  2304. LL_INFOS("AppInit") << "Startup state changing from " <<  
  2305. getStartupStateString() << " to " <<  
  2306. startupStateToString(state) << LL_ENDL;
  2307. gStartupState = state;
  2308. postStartupState();
  2309. }
  2310. void LLStartUp::postStartupState()
  2311. {
  2312. LLSD stateInfo;
  2313. stateInfo["str"] = getStartupStateString();
  2314. stateInfo["enum"] = gStartupState;
  2315. sStateWatcher->post(stateInfo);
  2316. }
  2317. void reset_login()
  2318. {
  2319. gAgent.cleanup();
  2320. LLWorld::getInstance()->destroyClass();
  2321. LLStartUp::setStartupState( STATE_LOGIN_SHOW );
  2322. if ( gViewerWindow )
  2323. { // Hide menus and normal buttons
  2324. gViewerWindow->setNormalControlsVisible( FALSE );
  2325. gLoginMenuBarView->setVisible( TRUE );
  2326. gLoginMenuBarView->setEnabled( TRUE );
  2327. }
  2328. // Hide any other stuff
  2329. LLFloaterReg::hideVisibleInstances();
  2330. }
  2331. //---------------------------------------------------------------------------
  2332. std::string LLStartUp::sSLURLCommand;
  2333. bool LLStartUp::canGoFullscreen()
  2334. {
  2335. return gStartupState >= STATE_WORLD_INIT;
  2336. }
  2337. // Initialize all plug-ins except the web browser (which was initialized
  2338. // early, before the login screen). JC
  2339. void LLStartUp::multimediaInit()
  2340. {
  2341. LL_DEBUGS("AppInit") << "Initializing Multimedia...." << LL_ENDL;
  2342. std::string msg = LLTrans::getString("LoginInitializingMultimedia");
  2343. set_startup_status(0.42f, msg.c_str(), gAgent.mMOTD.c_str());
  2344. display_startup();
  2345. // LLViewerMedia::initClass();
  2346. LLViewerParcelMedia::initClass();
  2347. }
  2348. void LLStartUp::fontInit()
  2349. {
  2350. LL_DEBUGS("AppInit") << "Initializing fonts...." << LL_ENDL;
  2351. std::string msg = LLTrans::getString("LoginInitializingFonts");
  2352. set_startup_status(0.45f, msg.c_str(), gAgent.mMOTD.c_str());
  2353. display_startup();
  2354. LLFontGL::loadDefaultFonts();
  2355. }
  2356. bool LLStartUp::dispatchURL()
  2357. {
  2358. // ok, if we've gotten this far and have a startup URL
  2359. if (!sSLURLCommand.empty())
  2360. {
  2361. LLMediaCtrl* web = NULL;
  2362. const bool trusted_browser = false;
  2363. LLURLDispatcher::dispatch(sSLURLCommand, web, trusted_browser);
  2364. }
  2365. else if (LLURLSimString::parse())
  2366. {
  2367. // If we started with a location, but we're already
  2368. // at that location, don't pop dialogs open.
  2369. LLVector3 pos = gAgent.getPositionAgent();
  2370. F32 dx = pos.mV[VX] - (F32)LLURLSimString::sInstance.mX;
  2371. F32 dy = pos.mV[VY] - (F32)LLURLSimString::sInstance.mY;
  2372. const F32 SLOP = 2.f; // meters
  2373. if( LLURLSimString::sInstance.mSimName != gAgent.getRegion()->getName()
  2374. || (dx*dx > SLOP*SLOP)
  2375. || (dy*dy > SLOP*SLOP) )
  2376. {
  2377. std::string url = LLURLSimString::getURL();
  2378. LLMediaCtrl* web = NULL;
  2379. const bool trusted_browser = false;
  2380. LLURLDispatcher::dispatch(url, web, trusted_browser);
  2381. }
  2382. return true;
  2383. }
  2384. return false;
  2385. }
  2386. bool login_alert_done(const LLSD& notification, const LLSD& response)
  2387. {
  2388. LLPanelLogin::giveFocus();
  2389. return false;
  2390. }
  2391. void apply_udp_blacklist(const std::string& csv)
  2392. {
  2393. std::string::size_type start = 0;
  2394. std::string::size_type comma = 0;
  2395. do 
  2396. {
  2397. comma = csv.find(",", start);
  2398. if (comma == std::string::npos)
  2399. {
  2400. comma = csv.length();
  2401. }
  2402. std::string item(csv, start, comma-start);
  2403. lldebugs << "udp_blacklist " << item << llendl;
  2404. gMessageSystem->banUdpMessage(item);
  2405. start = comma + 1;
  2406. }
  2407. while(comma < csv.length());
  2408. }
  2409. bool process_login_success_response()
  2410. {
  2411. LLSD response = LLLoginInstance::getInstance()->getResponse();
  2412. std::string text(response["udp_blacklist"]);
  2413. if(!text.empty())
  2414. {
  2415. apply_udp_blacklist(text);
  2416. }
  2417. // unpack login data needed by the application
  2418. text = response["agent_id"].asString();
  2419. if(!text.empty()) gAgentID.set(text);
  2420. gDebugInfo["AgentID"] = text;
  2421. text = response["session_id"].asString();
  2422. if(!text.empty()) gAgentSessionID.set(text);
  2423. gDebugInfo["SessionID"] = text;
  2424. text = response["secure_session_id"].asString();
  2425. if(!text.empty()) gAgent.mSecureSessionID.set(text);
  2426. text = response["first_name"].asString();
  2427. if(!text.empty()) 
  2428. {
  2429. // Remove quotes from string.  Login.cgi sends these to force
  2430. // names that look like numbers into strings.
  2431. gFirstname.assign(text);
  2432. LLStringUtil::replaceChar(gFirstname, '"', ' ');
  2433. LLStringUtil::trim(gFirstname);
  2434. }
  2435. text = response["last_name"].asString();
  2436. if(!text.empty()) 
  2437. {
  2438. gLastname.assign(text);
  2439. }
  2440. gSavedSettings.setString("FirstName", gFirstname);
  2441. gSavedSettings.setString("LastName", gLastname);
  2442. if (gSavedSettings.getBOOL("RememberPassword"))
  2443. {
  2444. // Successful login means the password is valid, so save it.
  2445. LLStartUp::savePasswordToDisk(gPassword);
  2446. }
  2447. else
  2448. {
  2449. // Don't leave password from previous session sitting around
  2450. // during this login session.
  2451. LLStartUp::deletePasswordFromDisk();
  2452. }
  2453. // this is their actual ability to access content
  2454. text = response["agent_access_max"].asString();
  2455. if (!text.empty())
  2456. {
  2457. // agent_access can be 'A', 'M', and 'PG'.
  2458. gAgent.setMaturity(text[0]);
  2459. }
  2460. // this is the value of their preference setting for that content
  2461. // which will always be <= agent_access_max
  2462. text = response["agent_region_access"].asString();
  2463. if (!text.empty())
  2464. {
  2465. U32 preferredMaturity =
  2466. llmin((U32)LLAgent::convertTextToMaturity(text[0]),
  2467.       gSavedSettings.getU32("PreferredMaturity"));
  2468. gSavedSettings.setU32("PreferredMaturity", preferredMaturity);
  2469. }
  2470. // During the AO transition, this flag will be true. Then the flag will
  2471. // go away. After the AO transition, this code and all the code that
  2472. // uses it can be deleted.
  2473. text = response["ao_transition"].asString();
  2474. if (!text.empty())
  2475. {
  2476. if (text == "1")
  2477. {
  2478. gAgent.setAOTransition();
  2479. }
  2480. }
  2481. text = response["start_location"].asString();
  2482. if(!text.empty()) 
  2483. {
  2484. gAgentStartLocation.assign(text);
  2485. }
  2486. text = response["circuit_code"].asString();
  2487. if(!text.empty())
  2488. {
  2489. gMessageSystem->mOurCircuitCode = strtoul(text.c_str(), NULL, 10);
  2490. }
  2491. std::string sim_ip_str = response["sim_ip"];
  2492. std::string sim_port_str = response["sim_port"];
  2493. if(!sim_ip_str.empty() && !sim_port_str.empty())
  2494. {
  2495. U32 sim_port = strtoul(sim_port_str.c_str(), NULL, 10);
  2496. gFirstSim.set(sim_ip_str, sim_port);
  2497. if (gFirstSim.isOk())
  2498. {
  2499. gMessageSystem->enableCircuit(gFirstSim, TRUE);
  2500. }
  2501. }
  2502. std::string region_x_str = response["region_x"];
  2503. std::string region_y_str = response["region_y"];
  2504. if(!region_x_str.empty() && !region_y_str.empty())
  2505. {
  2506. U32 region_x = strtoul(region_x_str.c_str(), NULL, 10);
  2507. U32 region_y = strtoul(region_y_str.c_str(), NULL, 10);
  2508. gFirstSimHandle = to_region_handle(region_x, region_y);
  2509. }
  2510. const std::string look_at_str = response["look_at"];
  2511. if (!look_at_str.empty())
  2512. {
  2513. size_t len = look_at_str.size();
  2514. LLMemoryStream mstr((U8*)look_at_str.c_str(), len);
  2515. LLSD sd = LLSDSerialize::fromNotation(mstr, len);
  2516. gAgentStartLookAt = ll_vector3_from_sd(sd);
  2517. }
  2518. text = response["seed_capability"].asString();
  2519. if (!text.empty()) gFirstSimSeedCap = text;
  2520. text = response["seconds_since_epoch"].asString();
  2521. if(!text.empty())
  2522. {
  2523. U32 server_utc_time = strtoul(text.c_str(), NULL, 10);
  2524. if(server_utc_time)
  2525. {
  2526. time_t now = time(NULL);
  2527. gUTCOffset = (server_utc_time - now);
  2528. }
  2529. }
  2530. // this is the base used to construct help URLs
  2531. text = response["help_url_format"].asString();
  2532. if (!text.empty())
  2533. {
  2534. // replace the default help URL format
  2535. gSavedSettings.setString("HelpURLFormat",text);
  2536. // don't fall back to Nebraska's pre-connection static help
  2537. gSavedSettings.setBOOL("HelpUseLocal", false);
  2538. }
  2539. std::string home_location = response["home"];
  2540. if(!home_location.empty())
  2541. {
  2542. size_t len = home_location.size();
  2543. LLMemoryStream mstr((U8*)home_location.c_str(), len);
  2544. LLSD sd = LLSDSerialize::fromNotation(mstr, len);
  2545. S32 region_x = sd["region_handle"][0].asInteger();
  2546. S32 region_y = sd["region_handle"][1].asInteger();
  2547. U64 region_handle = to_region_handle(region_x, region_y);
  2548. LLVector3 position = ll_vector3_from_sd(sd["position"]);
  2549. gAgent.setHomePosRegion(region_handle, position);
  2550. }
  2551. gAgent.mMOTD.assign(response["message"]);
  2552. // Options...
  2553. // Each 'option' is an array of submaps. 
  2554. // It appears that we only ever use the first element of the array.
  2555. LLUUID inv_root_folder_id = response["inventory-root"][0]["folder_id"];
  2556. if(inv_root_folder_id.notNull())
  2557. {
  2558. gInventory.setRootFolderID(inv_root_folder_id);
  2559. //gInventory.mock(gAgent.getInventoryRootID());
  2560. }
  2561. LLSD login_flags = response["login-flags"][0];
  2562. if(login_flags.size())
  2563. {
  2564. std::string flag = login_flags["ever_logged_in"];
  2565. if(!flag.empty())
  2566. {
  2567. gAgent.setFirstLogin((flag == "N") ? TRUE : FALSE);
  2568. }
  2569. /*  Flag is currently ignored by the viewer.
  2570. flag = login_flags["stipend_since_login"];
  2571. if(flag == "Y") 
  2572. {
  2573. stipend_since_login = true;
  2574. }
  2575. */
  2576. flag = login_flags["gendered"].asString();
  2577. if(flag == "Y")
  2578. {
  2579. gAgent.setGenderChosen(TRUE);
  2580. }
  2581. bool pacific_daylight_time = false;
  2582. flag = login_flags["daylight_savings"].asString();
  2583. if(flag == "Y")
  2584. {
  2585. pacific_daylight_time = (flag == "Y");
  2586. }
  2587. //setup map of datetime strings to codes and slt & local time offset from utc
  2588. LLStringOps::setupDatetimeInfo(pacific_daylight_time);
  2589. }
  2590. LLSD initial_outfit = response["initial-outfit"][0];
  2591. if(initial_outfit.size())
  2592. {
  2593. std::string flag = initial_outfit["folder_name"];
  2594. if(!flag.empty())
  2595. {
  2596. // Initial outfit is a folder in your inventory,
  2597. // must be an exact folder-name match.
  2598. sInitialOutfit = flag;
  2599. }
  2600. flag = initial_outfit["gender"].asString();
  2601. if(!flag.empty())
  2602. {
  2603. sInitialOutfitGender = flag;
  2604. }
  2605. }
  2606. LLSD global_textures = response["global-textures"][0];
  2607. if(global_textures.size())
  2608. {
  2609. // Extract sun and moon texture IDs.  These are used
  2610. // in the LLVOSky constructor, but I can't figure out
  2611. // how to pass them in.  JC
  2612. LLUUID id = global_textures["sun_texture_id"];
  2613. if(id.notNull())
  2614. {
  2615. gSunTextureID = id;
  2616. }
  2617. id = global_textures["moon_texture_id"];
  2618. if(id.notNull())
  2619. {
  2620. gMoonTextureID = id;
  2621. }
  2622. id = global_textures["cloud_texture_id"];
  2623. if(id.notNull())
  2624. {
  2625. gCloudTextureID = id;
  2626. }
  2627. }
  2628. bool success = false;
  2629. // JC: gesture loading done below, when we have an asset system
  2630. // in place.  Don't delete/clear user_credentials until then.
  2631. if(gAgentID.notNull()
  2632.    && gAgentSessionID.notNull()
  2633.    && gMessageSystem->mOurCircuitCode
  2634.    && gFirstSim.isOk()
  2635.    && gInventory.getRootFolderID().notNull())
  2636. {
  2637. success = true;
  2638. }
  2639. return success;
  2640. }
  2641. void transition_back_to_login_panel(const std::string& emsg)
  2642. {
  2643. if (gNoRender)
  2644. {
  2645. LL_WARNS("AppInit") << "Failed to login!" << LL_ENDL;
  2646. LL_WARNS("AppInit") << emsg << LL_ENDL;
  2647. exit(0);
  2648. }
  2649. // Bounce back to the login screen.
  2650. reset_login(); // calls LLStartUp::setStartupState( STATE_LOGIN_SHOW );
  2651. gSavedSettings.setBOOL("AutoLogin", FALSE);
  2652. }