llstartup.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "llstartup.h"
00035 
00036 #if LL_WINDOWS
00037 #       include <process.h>             // _spawnl()
00038 #else
00039 #       include <sys/stat.h>            // mkdir()
00040 #endif
00041 
00042 #include "audioengine.h"
00043 
00044 #if LL_FMOD
00045 #include "audioengine_fmod.h"
00046 #endif
00047 
00048 #include "audiosettings.h"
00049 #include "llcachename.h"
00050 #include "llviewercontrol.h"
00051 #include "lldir.h"
00052 #include "lleconomy.h"
00053 #include "llerrorcontrol.h"
00054 #include "llfiltersd2xmlrpc.h"
00055 #include "llfocusmgr.h"
00056 #include "llhttpsender.h"
00057 #include "imageids.h"
00058 #include "lllandmark.h"
00059 #include "llloginflags.h"
00060 #include "llmd5.h"
00061 #include "llmemorystream.h"
00062 #include "llmessageconfig.h"
00063 #include "llregionhandle.h"
00064 #include "llregionnamecache.h"
00065 #include "llsd.h"
00066 #include "llsdserialize.h"
00067 #include "llsdutil.h"
00068 #include "llsecondlifeurls.h"
00069 #include "llstring.h"
00070 #include "lluserrelations.h"
00071 #include "llversionviewer.h"
00072 #include "llvfs.h"
00073 #include "llwindow.h"           // for shell_open
00074 #include "llxorcipher.h"        // saved password, MAC address
00075 #include "message.h"
00076 #include "v3math.h"
00077 
00078 #include "llagent.h"
00079 #include "llagentpilot.h"
00080 #include "llasynchostbyname.h"
00081 #include "llfloateravatarpicker.h"
00082 #include "llcallbacklist.h"
00083 #include "llcallingcard.h"
00084 #include "llcolorscheme.h"
00085 #include "llconsole.h"
00086 #include "llcontainerview.h"
00087 #include "lldebugview.h"
00088 #include "lldrawable.h"
00089 #include "lleventnotifier.h"
00090 #include "llface.h"
00091 #include "llfeaturemanager.h"
00092 #include "llfirstuse.h"
00093 #include "llfloateractivespeakers.h"
00094 #include "llfloaterchat.h"
00095 #include "llfloatergesture.h"
00096 #include "llfloaterland.h"
00097 #include "llfloatertopobjects.h"
00098 #include "llfloatertos.h"
00099 #include "llfloaterworldmap.h"
00100 #include "llframestats.h"
00101 #include "llframestatview.h"
00102 #include "llgesturemgr.h"
00103 #include "llgroupmgr.h"
00104 #include "llhudeffecttrail.h"
00105 #include "llhudmanager.h"
00106 #include "llhttpclient.h"
00107 #include "llimagebmp.h"
00108 #include "llinventorymodel.h"
00109 #include "llinventoryview.h"
00110 #include "llkeyboard.h"
00111 #include "llpanellogin.h"
00112 #include "llmutelist.h"
00113 #include "llnotify.h"
00114 #include "llpanelavatar.h"
00115 #include "llpaneldirbrowser.h"
00116 #include "llpaneldirland.h"
00117 #include "llpanelevent.h"
00118 #include "llpanelclassified.h"
00119 #include "llpanelpick.h"
00120 #include "llpanelplace.h"
00121 #include "llpanelgrouplandmoney.h"
00122 #include "llpanelgroupnotices.h"
00123 #include "llpreview.h"
00124 #include "llpreviewscript.h"
00125 #include "lltrustnet.h"
00126 #include "llselectmgr.h"
00127 #include "llsky.h"
00128 #include "llsrv.h"
00129 #include "llstatview.h"
00130 #include "llsurface.h"
00131 #include "lltexturecache.h"
00132 #include "lltexturefetch.h"
00133 #include "lltoolmgr.h"
00134 #include "llui.h"
00135 #include "llurldispatcher.h"
00136 #include "llurlsimstring.h"
00137 #include "llurlwhitelist.h"
00138 #include "lluserauth.h"
00139 #include "llviewerassetstorage.h"
00140 #include "llviewercamera.h"
00141 #include "llviewercommunication.h"
00142 #include "llviewerdisplay.h"
00143 #include "llviewergenericmessage.h"
00144 #include "llviewergesture.h"
00145 #include "llviewerimagelist.h"
00146 #include "llviewermenu.h"
00147 #include "llviewermessage.h"
00148 #include "llviewernetwork.h"
00149 #include "llviewerobjectlist.h"
00150 #include "llviewerparcelmgr.h"
00151 #include "llviewerregion.h"
00152 #include "llviewerstats.h"
00153 #include "llviewerthrottle.h"
00154 #include "llviewerwindow.h"
00155 #include "llvoavatar.h"
00156 #include "llvoclouds.h"
00157 #include "llworld.h"
00158 #include "llworldmap.h"
00159 #include "llxfermanager.h"
00160 #include "pipeline.h"
00161 #include "viewer.h"
00162 #include "llmediaengine.h"
00163 #include "llfasttimerview.h"
00164 #include "llfloatermap.h"
00165 #include "llweb.h"
00166 #include "llvoiceclient.h"
00167 
00168 #if LL_LIBXUL_ENABLED
00169 #include "llmozlib.h"
00170 #endif // LL_LIBXUL_ENABLED
00171 
00172 #if LL_WINDOWS
00173 #include "llwindebug.h"
00174 #include "lldxhardware.h"
00175 #endif
00176 
00177 #if LL_QUICKTIME_ENABLED
00178 #if LL_DARWIN
00179 #include <QuickTime/QuickTime.h>
00180 #else
00181 // quicktime specific includes
00182 #include "MacTypes.h"
00183 #include "QTML.h"
00184 #include "Movies.h"
00185 #include "FixMath.h"
00186 #endif
00187 #endif
00188 
00189 //
00190 // exported globals
00191 //
00192 
00193 // HACK: Allow server to change sun and moon IDs.
00194 // I can't figure out how to pass the appropriate
00195 // information into the LLVOSky constructor.  JC
00196 LLUUID gSunTextureID = IMG_SUN;
00197 LLUUID gMoonTextureID = IMG_MOON;
00198 LLUUID gCloudTextureID = IMG_CLOUD_POOF;
00199 
00200 const char* SCREEN_HOME_FILENAME = "screen_home.bmp";
00201 const char* SCREEN_LAST_FILENAME = "screen_last.bmp";
00202 
00203 const LLString HTTP_UPDATE_URL = "http://sl.daleglass.net/viewer_update_check";
00204 //
00205 // Imported globals
00206 //
00207 extern S32 gStartImageWidth;
00208 extern S32 gStartImageHeight;
00209 extern std::string gSerialNumber;
00210 
00211 //
00212 // local globals
00213 //
00214 
00215 LLPointer<LLImageGL> gStartImageGL;
00216 
00217 static LLHost gAgentSimHost;
00218 static BOOL gSkipOptionalUpdate = FALSE;
00219 
00220 bool gUseQuickTime = true;
00221 bool gQuickTimeInitialized = false;
00222 static bool gGotUseCircuitCodeAck = false;
00223 LLString gInitialOutfit;
00224 LLString gInitialOutfitGender;  // "male" or "female"
00225 
00226 static bool gUseCircuitCallbackCalled = false;
00227 
00228 S32 LLStartUp::gStartupState = STATE_FIRST;
00229 
00230 
00231 //
00232 // local function declaration
00233 //
00234 
00235 void login_show();
00236 void login_callback(S32 option, void* userdata);
00237 LLString load_password_from_disk();
00238 void save_password_to_disk(const char* hashed_password);
00239 BOOL is_hex_string(U8* str, S32 len);
00240 void show_first_run_dialog();
00241 void first_run_dialog_callback(S32 option, void* userdata);
00242 void set_startup_status(const F32 frac, const char* string, const char* msg);
00243 void login_alert_status(S32 option, void* user_data);
00244 void update_app(BOOL mandatory, const std::string& message);
00245 void update_dialog_callback(S32 option, void *userdata);
00246 void update_check_failure_dialog_callback(S32 option, void *userdata);
00247 void login_packet_failed(void**, S32 result);
00248 void use_circuit_callback(void**, S32 result);
00249 void register_viewer_callbacks(LLMessageSystem* msg);
00250 void init_stat_view();
00251 void asset_callback_nothing(LLVFS*, const LLUUID&, LLAssetType::EType, void*, S32);
00252 void dialog_choose_gender_first_start();
00253 void callback_choose_gender(S32 option, void* userdata);
00254 void init_start_screen(S32 location_id);
00255 void release_start_screen();
00256 void reset_login();
00257 
00258 //
00259 // exported functionality
00260 //
00261 
00262 //
00263 // local classes
00264 //
00265 
00266 namespace
00267 {
00268         class LLNullHTTPSender : public LLHTTPSender
00269         {
00270                 virtual void send(const LLHost& host, 
00271                                                   const char* message, const LLSD& body, 
00272                                                   LLHTTPClient::ResponderPtr response) const
00273                 {
00274                         llwarns << " attemped to send " << message << " to " << host
00275                                         << " with null sender" << llendl;
00276                 }
00277         };
00278 }
00279 
00280 class LLGestureInventoryFetchObserver : public LLInventoryFetchObserver
00281 {
00282 public:
00283         LLGestureInventoryFetchObserver() {}
00284         virtual void done()
00285         {
00286                 // we've downloaded all the items, so repaint the dialog
00287                 LLFloaterGesture::refreshAll();
00288 
00289                 gInventory.removeObserver(this);
00290                 delete this;
00291         }
00292 };
00293 
00294 // This only runs in STATE_UPDATE_CHECK
00295 class LLHTTPUpdateResponder : public LLHTTPClient::Responder
00296 {
00297 public:
00298         virtual void error(U32 status, const std::string& reason)
00299         {
00300                 llwarns << "Update check failed: " << reason << llendl;
00301 
00302                 std::ostringstream o;
00303                 o << "Error " << status << ": " << reason;
00304 
00305                 LLStringBase<char>::format_map_t args;
00306                 args["[MESSAGE]"] = o.str();
00307 
00308                 gViewerWindow->alertXml("WebUpdateCheckFailed", args,
00309                                                                 update_check_failure_dialog_callback,
00310                                                                 NULL);
00311         }
00312         virtual void result(const LLSD& content)
00313         { 
00314                 llinfos << "Update check completed" << llendl;
00315                 if ( content["update_available"].asBoolean() )
00316                 {
00317                         llinfos << "Available new version: " << content["last_version"].asString() << llendl;
00318                         
00319                         if ( content["update_required"].asBoolean() )
00320                         {
00321                                 llinfos << "This version is required" << llendl;
00322                         }
00323 
00324                         llinfos << "Message:" << content["message"].asString() << llendl;
00325 
00326                         update_app(content["update_required"].asBoolean(), content["message"].asString());
00327                 }
00328                 else
00329                 {
00330                         llinfos << "No update required" << llendl;
00331                         LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT );
00332                 }
00333         }
00334 };
00335 
00336 void update_texture_fetch()
00337 {
00338         gTextureCache->update(1); // unpauses the texture cache thread
00339         gImageDecodeThread->update(1); // unpauses the image thread
00340         gTextureFetch->update(1); // unpauses the texture fetch thread
00341         gImageList.updateImages(0.10f);
00342 }
00343 
00344 // Returns FALSE to skip other idle processing. Should only return
00345 // TRUE when all initialization done.
00346 BOOL idle_startup()
00347 {
00348         LLMemType mt1(LLMemType::MTYPE_STARTUP);
00349         
00350         const F32 PRECACHING_DELAY = gSavedSettings.getF32("PrecachingDelay");
00351         const F32 TIMEOUT_SECONDS = 5.f;
00352         const S32 MAX_TIMEOUT_COUNT = 3;
00353         static LLTimer timeout;
00354         static S32 timeout_count = 0;
00355 
00356         static LLTimer login_time;
00357 
00358         // until this is encapsulated, this little hack for the
00359         // auth/transform loop will do.
00360         static F32 progress = 0.10f;
00361         static std::vector<std::string> auth_uris;
00362         static int auth_uri_num = -1;
00363 
00364         static std::string auth_method;
00365         static std::string auth_desc;
00366         static std::string auth_message;
00367         static LLString firstname;
00368         static LLString lastname;
00369         static LLString password;
00370         static std::vector<const char*> requested_options;
00371 
00372         static U32 region_size = 256;
00373         static F32 region_scale = 1.f;
00374         static U64 first_sim_handle = 0;
00375         static LLHost first_sim;
00376         static std::string first_sim_seed_cap;
00377 
00378         static LLVector3 initial_sun_direction(1.f, 0.f, 0.f);
00379         static LLVector3 agent_start_position_region(10.f, 10.f, 10.f);         // default for when no space server
00380         static LLVector3 agent_start_look_at(1.0f, 0.f, 0.f);
00381         static std::string agent_start_location = "safe";
00382 
00383         // last location by default
00384         static S32  agent_location_id = START_LOCATION_ID_LAST;
00385         static S32  location_which = START_LOCATION_ID_LAST;
00386 
00387         static BOOL show_connect_box = TRUE;
00388         static BOOL remember_password = TRUE;
00389 
00390         static BOOL stipend_since_login = FALSE;
00391 
00392         static BOOL samename = FALSE;
00393 
00394         BOOL do_normal_idle = FALSE;
00395 
00396         // HACK: These are things from the main loop that usually aren't done
00397         // until initialization is complete, but need to be done here for things
00398         // to work.
00399         gIdleCallbacks.callFunctions();
00400         gViewerWindow->handlePerFrameHover();
00401         LLMortician::updateClass();
00402 
00403         if (gNoRender)
00404         {
00405                 // HACK, skip optional updates if you're running drones
00406                 gSkipOptionalUpdate = TRUE;
00407         }
00408         else
00409         {
00410                 // Update images?
00411                 gImageList.updateImages(0.01f);
00412         }
00413 
00414         if ( STATE_FIRST == LLStartUp::getStartupState() )
00415         {
00416                 gViewerWindow->showCursor();
00417                 gViewerWindow->getWindow()->setCursor(UI_CURSOR_WAIT);
00418 
00420                 //
00421                 // Initialize stuff that doesn't need data from userserver/simulators
00422                 //
00423 
00424                 if (gFeatureManagerp->isSafe())
00425                 {
00426                         gViewerWindow->alertXml("DisplaySetToSafe");
00427                 }
00428                 else if ((gSavedSettings.getS32("LastFeatureVersion") < gFeatureManagerp->getVersion()) &&
00429                                  (gSavedSettings.getS32("LastFeatureVersion") != 0))
00430                 {
00431                         gViewerWindow->alertXml("DisplaySetToRecommended");
00432                 }
00433                 else if (!gViewerWindow->getInitAlert().empty())
00434                 {
00435                         gViewerWindow->alertXml(gViewerWindow->getInitAlert());
00436                 }
00437                         
00438                 gSavedSettings.setS32("LastFeatureVersion", gFeatureManagerp->getVersion());
00439 
00440                 LLString xml_file = LLUI::locateSkin("xui_version.xml");
00441                 LLXMLNodePtr root;
00442                 bool xml_ok = false;
00443                 if (LLXMLNode::parseFile(xml_file, root, NULL))
00444                 {
00445                         if( (root->hasName("xui_version") ) )
00446                         {
00447                                 LLString value = root->getValue();
00448                                 F32 version = 0.0f;
00449                                 LLString::convertToF32(value, version);
00450                                 if (version >= 1.0f)
00451                                 {
00452                                         xml_ok = true;
00453                                 }
00454                         }
00455                 }
00456                 if (!xml_ok)
00457                 {
00458                         // *TODO:translate (maybe - very unlikely error message)
00459                         // Note: alerts.xml may be invalid - if this gets translated it will need to be in the code
00460                         LLString bad_xui_msg = "An error occured while updating Second Life. Please download the latest version from www.secondlife.com.";
00461                         app_early_exit(bad_xui_msg);
00462                 }
00463                 //
00464                 // Statistics stuff
00465                 //
00466 
00467                 // Load autopilot and stats stuff
00468                 gAgentPilot.load(gSavedSettings.getString("StatsPilotFile").c_str());
00469                 gFrameStats.setFilename(gSavedSettings.getString("StatsFile"));
00470                 gFrameStats.setSummaryFilename(gSavedSettings.getString("StatsSummaryFile"));
00471 
00472                 //gErrorStream.setTime(gSavedSettings.getBOOL("LogTimestamps"));
00473 
00474                 // Load the throttle settings
00475                 gViewerThrottle.load();
00476 
00477                 //
00478                 // Initialize messaging system
00479                 //
00480                 llinfos << "Initializing messaging system..." << llendl;
00481 
00482                 std::string message_template_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"message_template.msg");
00483 
00484                 FILE* found_template = NULL;
00485                 found_template = LLFile::fopen(message_template_path.c_str(), "r");             /* Flawfinder: ignore */
00486                 if (found_template)
00487                 {
00488                         fclose(found_template);
00489 
00490                         U32 port = gAgent.mViewerPort;
00491 
00492                         if ((NET_USE_OS_ASSIGNED_PORT == port) &&   // if nothing specified on command line (-port)
00493                             (gSavedSettings.getBOOL("ConnectionPortEnabled")))
00494                           {
00495                             port = gSavedSettings.getU32("ConnectionPort");
00496                           }
00497 
00498                         LLHTTPSender::setDefaultSender(new LLNullHTTPSender());
00499                         if(!start_messaging_system(
00500                                    message_template_path,
00501                                    port,
00502                                    LL_VERSION_MAJOR,
00503                                    LL_VERSION_MINOR,
00504                                    LL_VERSION_PATCH,
00505                                    FALSE,
00506                                    std::string()))
00507                         {
00508                                 std::string msg = llformat("Unable to start networking, error %d", gMessageSystem->getErrorCode());
00509                                 app_early_exit(msg);
00510                         }
00511                         LLMessageConfig::initClass("viewer", gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
00512                 }
00513                 else
00514                 {
00515                         app_early_exit("Unable to initialize communications.");
00516                 }
00517 
00518                 if(gMessageSystem && gMessageSystem->isOK())
00519                 {
00520                         // Initialize all of the callbacks in case of bad message
00521                         // system data
00522                         LLMessageSystem* msg = gMessageSystem;
00523                         msg->setExceptionFunc(MX_UNREGISTERED_MESSAGE,
00524                                                                   invalid_message_callback,
00525                                                                   NULL);
00526                         msg->setExceptionFunc(MX_PACKET_TOO_SHORT,
00527                                                                   invalid_message_callback,
00528                                                                   NULL);
00529 
00530                         // running off end of a packet is now valid in the case
00531                         // when a reader has a newer message template than
00532                         // the sender
00533                         /*msg->setExceptionFunc(MX_RAN_OFF_END_OF_PACKET,
00534                                                                   invalid_message_callback,
00535                                                                   NULL);*/
00536                         msg->setExceptionFunc(MX_WROTE_PAST_BUFFER_SIZE,
00537                                                                   invalid_message_callback,
00538                                                                   NULL);
00539 
00540                         if (gSavedSettings.getBOOL("LogMessages") || gLogMessages)
00541                         {
00542                                 llinfos << "Message logging activated!" << llendl;
00543                                 msg->startLogging();
00544                         }
00545 
00546                         // start the xfer system. by default, choke the downloads
00547                         // a lot...
00548                         const S32 VIEWER_MAX_XFER = 3;
00549                         start_xfer_manager(gVFS);
00550                         gXferManager->setMaxIncomingXfers(VIEWER_MAX_XFER);
00551                         F32 xfer_throttle_bps = gSavedSettings.getF32("XferThrottle");
00552                         if (xfer_throttle_bps > 1.f)
00553                         {
00554                                 gXferManager->setUseAckThrottling(TRUE);
00555                                 gXferManager->setAckThrottleBPS(xfer_throttle_bps);
00556                         }
00557                         gAssetStorage = new LLViewerAssetStorage(msg, gXferManager, gVFS);
00558 
00559                         msg->mPacketRing.setDropPercentage(gPacketDropPercentage);
00560                         if (gInBandwidth != 0.f)
00561                         {
00562                                 llinfos << "Setting packetring incoming bandwidth to " << gInBandwidth << llendl;
00563                                 msg->mPacketRing.setUseInThrottle(TRUE);
00564                                 msg->mPacketRing.setInBandwidth(gInBandwidth);
00565                         }
00566                         if (gOutBandwidth != 0.f)
00567                         {
00568                                 llinfos << "Setting packetring outgoing bandwidth to " << gOutBandwidth << llendl;
00569                                 msg->mPacketRing.setUseOutThrottle(TRUE);
00570                                 msg->mPacketRing.setOutBandwidth(gOutBandwidth);
00571                         }
00572                 }
00573 
00574                 // initialize the economy
00575                 gGlobalEconomy = new LLGlobalEconomy();
00576 
00577                 // Initialize viewer/object communication
00578                 gViewerCommunication = new LLViewerCommunication();
00579 
00580                 gTrustNet = new LLTrustNet();
00581 
00582                 //---------------------------------------------------------------------
00583                 // LibXUL (Mozilla) initialization
00584                 //---------------------------------------------------------------------
00585                 #if LL_LIBXUL_ENABLED
00586                 set_startup_status(0.58f, "Initializing embedded web browser...", gAgent.mMOTD.c_str());
00587                 display_startup();
00588                 llinfos << "Initializing embedded web browser..." << llendl;
00589 
00590                 #if LL_DARWIN
00591                         // For Mac OS, we store both the shared libraries and the runtime files (chrome/, plugins/, etc) in
00592                         // Second Life.app/Contents/MacOS/.  This matches the way Firefox is distributed on the Mac.
00593                         std::string componentDir(gDirUtilp->getExecutableDir());
00594                 #elif LL_WINDOWS
00595                         std::string componentDir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) );
00596                         componentDir += gDirUtilp->getDirDelimiter();
00597                         #ifdef LL_DEBUG
00598                                 componentDir += "mozilla_debug";
00599                         #else
00600                                 componentDir += "mozilla";
00601                         #endif
00602                 #elif LL_LINUX
00603                         std::string componentDir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) );
00604                         componentDir += gDirUtilp->getDirDelimiter();
00605                         componentDir += "mozilla-runtime-linux-i686";
00606                 #else
00607                         std::string componentDir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) );
00608                         componentDir += gDirUtilp->getDirDelimiter();
00609                         componentDir += "mozilla";
00610                 #endif
00611 
00612 #if LL_LINUX
00613                 // Yuck, Mozilla init plays with the locale - push/pop
00614                 // the locale to protect it, as exotic/non-C locales
00615                 // causes our code lots of general critical weirdness
00616                 // and crashness. (SL-35450)
00617                 std::string saved_locale = setlocale(LC_ALL, NULL);
00618 #endif // LL_LINUX
00619 
00620                 // initialize Mozilla - pass in executable dir, location of extra dirs (chrome/, greprefs/, plugins/ etc.) and path to profile dir)
00621                 LLMozLib::getInstance()->init( gDirUtilp->getExecutableDir(), componentDir, gDirUtilp->getExpandedFilename( LL_PATH_MOZILLA_PROFILE, "" ) );
00622 
00623 #if LL_LINUX
00624                 setlocale(LC_ALL, saved_locale.c_str() );
00625 #endif // LL_LINUX
00626 
00627                 std::ostringstream codec;
00628                 codec << "[Second Life ";
00629                 codec << "(" << gChannelName << ")";
00630                 codec << " - " << LL_VERSION_MAJOR << "." << LL_VERSION_MINOR << "." << LL_VERSION_PATCH << "." << LL_VERSION_BUILD << "." << LL_VERSION_REVISION;
00631                 codec << "]";
00632                 LLMozLib::getInstance()->setBrowserAgentId( codec.str() );
00633                 #endif
00634 
00635                 //-------------------------------------------------
00636                 // Init audio, which may be needed for prefs dialog
00637                 // or audio cues in connection UI.
00638                 //-------------------------------------------------
00639 
00640                 if (gUseAudio)
00641                 {
00642 #if LL_FMOD
00643                         gAudiop = (LLAudioEngine *) new LLAudioEngine_FMOD();
00644 #else
00645                         gAudiop = NULL;
00646 #endif
00647 
00648                         if (gAudiop)
00649                         {
00650 #if LL_WINDOWS
00651                                 // FMOD on Windows needs the window handle to stop playing audio
00652                                 // when window is minimized. JC
00653                                 void* window_handle = (HWND)gViewerWindow->getPlatformWindow();
00654 #else
00655                                 void* window_handle = NULL;
00656 #endif
00657                                 BOOL init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle);
00658                                 if(!init)
00659                                 {
00660                                         llwarns << "Unable to initialize audio engine" << llendl;
00661                                 }
00662                                 gAudiop->setMuted(TRUE);
00663                         }
00664                 }
00665 
00666                 if (LLTimer::knownBadTimer())
00667                 {
00668                         llwarns << "Unreliable timers detected (may be bad PCI chipset)!!" << llendl;
00669                 }
00670 
00671                 //
00672                 // Log on to system
00673                 //
00674                 if( !gCmdLineFirstName.empty() 
00675                         && !gCmdLineLastName.empty() 
00676                         && !gCmdLinePassword.empty())
00677                 {
00678                         firstname = gCmdLineFirstName;
00679                         lastname = gCmdLineLastName;
00680 
00681                         LLMD5 pass((unsigned char*)gCmdLinePassword.c_str());
00682                         char md5pass[33];               /* Flawfinder: ignore */
00683                         pass.hex_digest(md5pass);
00684                         password = md5pass;
00685 
00686                         remember_password = gSavedSettings.getBOOL("RememberPassword");
00687                         show_connect_box = FALSE;
00688                 }
00689                 else if (gAutoLogin || gSavedSettings.getBOOL("AutoLogin"))
00690                 {
00691                         firstname = gSavedSettings.getString("FirstName");
00692                         lastname = gSavedSettings.getString("LastName");
00693                         password = load_password_from_disk();
00694                         remember_password = TRUE;
00695                         show_connect_box = FALSE;
00696                 }
00697                 else
00698                 {
00699                         // if not automatically logging in, display login dialog
00700                         // until a valid userserver is selected
00701                         firstname = gSavedSettings.getString("FirstName");
00702                         lastname = gSavedSettings.getString("LastName");
00703                         password = load_password_from_disk();
00704                         remember_password = gSavedSettings.getBOOL("RememberPassword");
00705                         show_connect_box = TRUE;
00706                 }
00707 
00708                 // Go to the next startup state
00709                 LLStartUp::setStartupState( STATE_LOGIN_SHOW );
00710                 return do_normal_idle;
00711         }
00712 
00713         if (STATE_LOGIN_SHOW == LLStartUp::getStartupState())
00714         {
00715                 llinfos << "Initializing Window" << llendl;
00716                 
00717                 gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
00718                 // Push our window frontmost
00719                 gViewerWindow->getWindow()->show();
00720 
00721                 timeout_count = 0;
00722 
00723                 if (show_connect_box)
00724                 {
00725                         if (gNoRender)
00726                         {
00727                                 llerrs << "Need to autologin or use command line with norender!" << llendl;
00728                         }
00729                         // Make sure the process dialog doesn't hide things
00730                         gViewerWindow->setShowProgress(FALSE);
00731 
00732                         // Show the login dialog
00733                         login_show();
00734 
00735                         // connect dialog is already shown, so fill in the names
00736                         LLPanelLogin::setFields( firstname, lastname, password, remember_password );
00737                         LLPanelLogin::giveFocus();
00738 
00739                         gSavedSettings.setBOOL("FirstRunThisInstall", FALSE);
00740 
00741                         LLStartUp::setStartupState( STATE_LOGIN_WAIT );         // Wait for user input
00742                 }
00743                 else
00744                 {
00745                         // skip directly to message template verification
00746                         LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
00747                 }
00748 
00749                 timeout.reset();
00750                 return do_normal_idle;
00751         }
00752         
00753         if (STATE_WEB_UPDATE_START == LLStartUp::getStartupState())
00754         {
00755                 // HTTP based update code by Dale Glass
00756                 //
00757                 // Since we send our own channel name to the grid, it won't offer
00758                 // and wouldn't know about it for third party viewers anyway.
00759                 //
00760                 // This works by sending a request to an HTTP server. The reply is indicated
00761                 // by HTTP status, with text for the user being returned.
00762                 //
00763                 // Here we submit the full version number, plus the viewer digest.
00764                 // The digest allows telling viewers apart if needed, in the case
00765                 // different viewers are ever mistakenly uploaded with the same version
00766                 // number.
00767                 //
00768                 // See the class definition of LLHTTPUpdateResponder above for details.
00769                 llinfos << "Checking for updates at " << HTTP_UPDATE_URL << llendl;
00770                 set_startup_status(0.01f, "Checking for updates...", NULL);
00771 
00772                 std::ostringstream o;
00773                 o << HTTP_UPDATE_URL    << "?server=" << gUserServerName
00774                                         << "&major="  << LL_VERSION_MAJOR
00775                                         << "&minor="  << LL_VERSION_MINOR
00776                                         << "&patch="  << LL_VERSION_PATCH
00777                                         << "&build="  << LL_VERSION_BUILD
00778                                         << "&rev="    << LL_VERSION_REVISION
00779                                         << "&digest=" << gViewerDigest;
00780 
00781                 LLHTTPClient::get(o.str(), new LLHTTPUpdateResponder(), 30.0f);
00782 
00783                 LLStartUp::setStartupState( STATE_UPDATE_CHECK );
00784         }
00785 
00786         if (STATE_LOGIN_WAIT == LLStartUp::getStartupState())
00787         {
00788                 // Don't do anything.  Wait for the login view to call the login_callback,
00789                 // which will push us to the next state.
00790 
00791                 // Sleep so we don't spin the CPU
00792                 ms_sleep(1);
00793                 return do_normal_idle;
00794         }
00795 
00796         if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState())
00797         {
00798                 if (show_connect_box)
00799                 {
00800                         // Load all the name information out of the login view
00801                         LLPanelLogin::getFields(firstname, lastname, password, remember_password);
00802 
00803                         // HACK: Try to make not jump on login
00804                         gKeyboard->resetKeys();
00805                 }
00806 
00807                 if (!firstname.empty() && !lastname.empty())
00808                 {
00809                         gSavedSettings.setString("FirstName", firstname);
00810                         gSavedSettings.setString("LastName", lastname);
00811 
00812                         llinfos << "Attempting login as: " << firstname << " " << lastname << llendl;
00813                         write_debug("Attempting login as: ");
00814                         write_debug(firstname);
00815                         write_debug(" ");
00816                         write_debug(lastname);
00817                         write_debug("\n");
00818                 }
00819 
00820                 // create necessary directories
00821                 // *FIX: these mkdir's should error check
00822                 gDirUtilp->setLindenUserDir(firstname.c_str(), lastname.c_str());
00823 
00824 
00825                 LLFile::mkdir(gDirUtilp->getLindenUserDir().c_str());
00826 
00827                 // the mute list is loaded in the llmutelist class.
00828 
00829                 gSavedSettings.loadFromFile(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT,"overrides.xml"));
00830 
00831                 // handle the per account settings setup
00832                 gPerAccountSettingsFileName = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, DEFAULT_SETTINGS_FILE);
00833 
00834                 // per account settings.  Set defaults here if not found.  If we get a bunch of these, eventually move to a function.
00835                 gSavedPerAccountSettings.loadFromFile(gPerAccountSettingsFileName);
00836 
00837                 // Need to set the LastLogoff time here if we don't have one.  LastLogoff is used for "Recent Items" calculation
00838                 // and startup time is close enough if we don't have a real value.
00839                 if (gSavedPerAccountSettings.getU32("LastLogoff") == 0)
00840                 {
00841                         gSavedPerAccountSettings.setU32("LastLogoff", time_corrected());
00842                 }
00843 
00844                 //Default the path if one isn't set.
00845                 if (gSavedPerAccountSettings.getString("InstantMessageLogPath").empty())
00846                 {
00847                         gDirUtilp->setChatLogsDir(gDirUtilp->getOSUserAppDir());
00848                         gSavedPerAccountSettings.setString("InstantMessageLogPath",gDirUtilp->getChatLogsDir());
00849                 }
00850                 else
00851                 {
00852                         gDirUtilp->setChatLogsDir(gSavedPerAccountSettings.getString("InstantMessageLogPath"));         
00853                 }
00854                 
00855                 gDirUtilp->setPerAccountChatLogsDir(firstname.c_str(), lastname.c_str());
00856 
00857                 LLFile::mkdir(gDirUtilp->getChatLogsDir().c_str());
00858                 LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir().c_str());
00859 
00860                 if (show_connect_box)
00861                 {
00862                         LLString server_label;
00863                         S32 domain_name_index;
00864                         BOOL user_picked_server = LLPanelLogin::getServer( server_label, domain_name_index );
00865                         gUserServerChoice = (EUserServerDomain) domain_name_index;
00866                         gSavedSettings.setS32("ServerChoice", gUserServerChoice);
00867                         if (gUserServerChoice == USERSERVER_OTHER)
00868                         {
00869                                 snprintf(gUserServerName, MAX_STRING, "%s", server_label.c_str());                      /* Flawfinder: ignore */
00870                         }
00871 
00872                         if ( user_picked_server )
00873                         {       // User picked a grid from the popup, so clear the stored urls and they will be re-generated from gUserServerChoice
00874                                 auth_uris.clear();
00875                                 resetURIs();
00876                         }
00877 
00878                         LLString location;
00879                         LLPanelLogin::getLocation( location );
00880                         LLURLSimString::setString( location );
00881                         LLPanelLogin::close();
00882                 }
00883 
00884                 //For HTML parsing in text boxes.
00885                 LLTextEditor::setLinkColor( gSavedSettings.getColor4("HTMLLinkColor") );
00886                 LLTextEditor::setURLCallbacks ( &LLWeb::loadURL, &LLURLDispatcher::dispatch, &LLURLDispatcher::dispatch   );
00887 
00888                 //-------------------------------------------------
00889                 // Handle startup progress screen
00890                 //-------------------------------------------------
00891 
00892                 // on startup the user can request to go to their home,
00893                 // their last location, or some URL "-url //sim/x/y[/z]"
00894                 // All accounts have both a home and a last location, and we don't support
00895                 // more locations than that.  Choose the appropriate one.  JC
00896                 if (LLURLSimString::parse())
00897                 {
00898                         // a startup URL was specified
00899                         agent_location_id = START_LOCATION_ID_URL;
00900 
00901                         // doesn't really matter what location_which is, since
00902                         // agent_start_look_at will be overwritten when the
00903                         // UserLoginLocationReply arrives
00904                         location_which = START_LOCATION_ID_LAST;
00905                 }
00906                 else if (gSavedSettings.getBOOL("LoginLastLocation"))
00907                 {
00908                         agent_location_id = START_LOCATION_ID_LAST;     // last location
00909                         location_which = START_LOCATION_ID_LAST;
00910                 }
00911                 else
00912                 {
00913                         agent_location_id = START_LOCATION_ID_HOME;     // home
00914                         location_which = START_LOCATION_ID_HOME;
00915                 }
00916 
00917                 gViewerWindow->getWindow()->setCursor(UI_CURSOR_WAIT);
00918 
00919                 if (!gNoRender)
00920                 {
00921                         init_start_screen(agent_location_id);
00922                 }
00923 
00924                 // Display the startup progress bar.
00925                 gViewerWindow->setShowProgress(TRUE);
00926                 gViewerWindow->setProgressCancelButtonVisible(TRUE, "Quit");
00927 
00928                 // Poke the VFS, which could potentially block for a while if
00929                 // Windows XP is acting up
00930                 set_startup_status(0.05f, "Verifying cache files (can take 60-90 seconds)...", NULL);
00931                 display_startup();
00932 
00933                 gVFS->pokeFiles();
00934 
00935                 // color init must be after saved settings loaded
00936                 init_colors();
00937 
00938                 // skipping over STATE_UPDATE_CHECK because that just waits for input
00939                 LLStartUp::setStartupState( STATE_WEB_UPDATE_START );
00940 
00941                 return do_normal_idle;
00942         }
00943 
00944         if (STATE_UPDATE_CHECK == LLStartUp::getStartupState())
00945         {
00946                 // wait for user to give input via dialog box
00947                 return do_normal_idle;
00948         }
00949 
00950         if(STATE_LOGIN_AUTH_INIT == LLStartUp::getStartupState())
00951         {
00952 //#define LL_MINIMIAL_REQUESTED_OPTIONS
00953                 lldebugs << "STATE_LOGIN_AUTH_INIT" << llendl;
00954                 if (!gUserAuthp)
00955                 {
00956                         gUserAuthp = new LLUserAuth();
00957                 }
00958                 requested_options.clear();
00959                 requested_options.push_back("inventory-root");
00960                 requested_options.push_back("inventory-skeleton");
00961                 //requested_options.push_back("inventory-meat");
00962                 //requested_options.push_back("inventory-skel-targets");
00963 #if (!defined LL_MINIMIAL_REQUESTED_OPTIONS)
00964                 if(gRequestInventoryLibrary)
00965                 {
00966                         requested_options.push_back("inventory-lib-root");
00967                         requested_options.push_back("inventory-lib-owner");
00968                         requested_options.push_back("inventory-skel-lib");
00969                 //      requested_options.push_back("inventory-meat-lib");
00970                 }
00971 
00972                 requested_options.push_back("initial-outfit");
00973                 requested_options.push_back("gestures");
00974                 requested_options.push_back("event_categories");
00975                 requested_options.push_back("event_notifications");
00976                 requested_options.push_back("classified_categories");
00977                 //requested_options.push_back("inventory-targets");
00978                 requested_options.push_back("buddy-list");
00979                 requested_options.push_back("ui-config");
00980 #endif
00981                 requested_options.push_back("login-flags");
00982                 requested_options.push_back("global-textures");
00983                 if(gGodConnect)
00984                 {
00985                         gSavedSettings.setBOOL("UseDebugMenus", TRUE);
00986                         requested_options.push_back("god-connect");
00987                 }
00988                 if (auth_uris.empty())
00989                 {
00990                         auth_uris = getLoginURIs();
00991                 }
00992                 auth_uri_num = 0;
00993                 auth_method = "login_to_simulator";
00994                 auth_desc = "Logging in.  ";
00995                 auth_desc += gSecondLife;
00996                 auth_desc += " may appear frozen.  Please wait.";
00997                 LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE );
00998         }
00999 
01000         if (STATE_LOGIN_AUTHENTICATE == LLStartUp::getStartupState())
01001         {
01002                 lldebugs << "STATE_LOGIN_AUTHENTICATE" << llendl;
01003                 set_startup_status(progress, auth_desc.c_str(), auth_message.c_str());
01004                 progress += 0.02f;
01005                 display_startup();
01006                 
01007                 std::stringstream start;
01008                 if (LLURLSimString::parse())
01009                 {
01010                         // a startup URL was specified
01011                         std::stringstream unescaped_start;
01012                         unescaped_start << "uri:" 
01013                                 << LLURLSimString::sInstance.mSimName << "&" 
01014                                 << LLURLSimString::sInstance.mX << "&" 
01015                                 << LLURLSimString::sInstance.mY << "&" 
01016                                 << LLURLSimString::sInstance.mZ;
01017                         start << xml_escape_string(unescaped_start.str().c_str());
01018                 }
01019                 else if (gSavedSettings.getBOOL("LoginLastLocation"))
01020                 {
01021                         start << "last";
01022                 }
01023                 else
01024                 {
01025                         start << "home";
01026                 }
01027 
01028                 char hashed_mac_string[MD5HEX_STR_SIZE];                /* Flawfinder: ignore */
01029                 LLMD5 hashed_mac;
01030                 hashed_mac.update( gMACAddress, MAC_ADDRESS_BYTES );
01031                 hashed_mac.finalize();
01032                 hashed_mac.hex_digest(hashed_mac_string);
01033                 
01034                 gUserAuthp->authenticate(
01035                         auth_uris[auth_uri_num].c_str(),
01036                         auth_method.c_str(),
01037                         firstname.c_str(),
01038                         lastname.c_str(),
01039                         password.c_str(),
01040                         start.str().c_str(),
01041                         gSkipOptionalUpdate,
01042                         gAcceptTOS,
01043                         gAcceptCriticalMessage,
01044                         gViewerDigest,
01045                         gLastExecFroze,
01046                         requested_options,
01047                         hashed_mac_string,
01048                         gSerialNumber);
01049                 // reset globals
01050                 gAcceptTOS = FALSE;
01051                 gAcceptCriticalMessage = FALSE;
01052                 LLStartUp::setStartupState( STATE_LOGIN_NO_DATA_YET );
01053                 return do_normal_idle;
01054         }
01055 
01056         if(STATE_LOGIN_NO_DATA_YET == LLStartUp::getStartupState())
01057         {
01058                 //lldebugs << "STATE_LOGIN_NO_DATA_YET" << llendl;
01059                 if (!gUserAuthp)
01060                 {
01061                         llerrs << "No userauth in STATE_LOGIN_NO_DATA_YET!" << llendl;
01062                 }
01063                 // Process messages to keep from dropping circuit.
01064                 LLMessageSystem* msg = gMessageSystem;
01065                 while (msg->checkAllMessages(gFrameCount, gServicePump))
01066                 {
01067                 }
01068                 msg->processAcks();
01069                 LLUserAuth::UserAuthcode error = gUserAuthp->authResponse();
01070                 if(LLUserAuth::E_NO_RESPONSE_YET == error)
01071                 {
01072                         //llinfos << "waiting..." << llendl;
01073                         return do_normal_idle;
01074                 }
01075                 LLStartUp::setStartupState( STATE_LOGIN_DOWNLOADING );
01076                 progress += 0.01f;
01077                 set_startup_status(progress, auth_desc.c_str(), auth_message.c_str());
01078                 return do_normal_idle;
01079         }
01080 
01081         if(STATE_LOGIN_DOWNLOADING == LLStartUp::getStartupState())
01082         {
01083                 lldebugs << "STATE_LOGIN_DOWNLOADING" << llendl;
01084                 if (!gUserAuthp)
01085                 {
01086                         llerrs << "No userauth in STATE_LOGIN_DOWNLOADING!" << llendl;
01087                 }
01088                 // Process messages to keep from dropping circuit.
01089                 LLMessageSystem* msg = gMessageSystem;
01090                 while (msg->checkAllMessages(gFrameCount, gServicePump))
01091                 {
01092                 }
01093                 msg->processAcks();
01094                 LLUserAuth::UserAuthcode error = gUserAuthp->authResponse();
01095                 if(LLUserAuth::E_DOWNLOADING == error)
01096                 {
01097                         //llinfos << "downloading..." << llendl;
01098                         return do_normal_idle;
01099                 }
01100                 LLStartUp::setStartupState( STATE_LOGIN_PROCESS_RESPONSE );
01101                 progress += 0.01f;
01102                 set_startup_status(progress, "Processing Response...", auth_message.c_str());
01103                 return do_normal_idle;
01104         }
01105 
01106         if(STATE_LOGIN_PROCESS_RESPONSE == LLStartUp::getStartupState())
01107         {
01108                 lldebugs << "STATE_LOGIN_PROCESS_RESPONSE" << llendl;
01109                 std::ostringstream emsg;
01110                 BOOL quit = FALSE;
01111                 const char* login_response = NULL;
01112                 const char* reason_response = NULL;
01113                 const char* message_response = NULL;
01114                 BOOL successful_login = FALSE;
01115                 LLUserAuth::UserAuthcode error = gUserAuthp->authResponse();
01116                 // reset globals
01117                 gAcceptTOS = FALSE;
01118                 gAcceptCriticalMessage = FALSE;
01119                 switch(error)
01120                 {
01121                 case LLUserAuth::E_OK:
01122                         login_response = gUserAuthp->getResponse("login");
01123                         if(login_response && (0 == strcmp(login_response, "true")))
01124                         {
01125                                 // Yay, login!
01126                                 successful_login = TRUE;
01127                         }
01128                         else if(login_response && (0 == strcmp(login_response, "indeterminate")))
01129                         {
01130                                 llinfos << "Indeterminate login..." << llendl;
01131                                 auth_uris = LLSRV::rewriteURI(gUserAuthp->getResponse("next_url"));
01132                                 auth_uri_num = 0;
01133                                 auth_method = gUserAuthp->getResponse("next_method");
01134                                 auth_message = gUserAuthp->getResponse("message");
01135                                 if(auth_method.substr(0, 5) == "login")
01136                                 {
01137                                         auth_desc.assign("Authenticating...");
01138                                 }
01139                                 else
01140                                 {
01141                                         auth_desc.assign("Performing account maintenance...");
01142                                 }
01143                                 // ignoring the duration & options array for now.
01144                                 // Go back to authenticate.
01145                                 LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE );
01146                                 return do_normal_idle;
01147                         }
01148                         else
01149                         {
01150                                 emsg << "Login failed.\n";
01151                                 reason_response = gUserAuthp->getResponse("reason");
01152                                 message_response = gUserAuthp->getResponse("message");
01153 
01154                                 if (gHideLinks && reason_response && (0 == strcmp(reason_response, "disabled")))
01155                                 {
01156                                         emsg << gDisabledMessage;
01157                                 }
01158                                 else if (message_response)
01159                                 {
01160                                         // XUI: fix translation for strings returned during login
01161                                         // We need a generic table for translations
01162                                         LLString big_reason = LLAgent::sTeleportErrorMessages[ message_response ];
01163                                         if ( big_reason.size() == 0 )
01164                                         {
01165                                                 emsg << message_response;
01166                                         }
01167                                         else
01168                                         {
01169                                                 emsg << big_reason;
01170                                         }
01171                                 }
01172 
01173                                 if(reason_response && (0 == strcmp(reason_response, "tos")))
01174                                 {
01175                                         if (show_connect_box)
01176                                         {
01177                                                 llinfos << "Need tos agreement" << llendl;
01178                                                 LLStartUp::setStartupState( STATE_UPDATE_CHECK );
01179                                                 LLFloaterTOS* tos_dialog = LLFloaterTOS::show(LLFloaterTOS::TOS_TOS,
01180                                                                                                                                         message_response);
01181                                                 tos_dialog->startModal();
01182                                                 // LLFloaterTOS deletes itself.
01183                                                 return FALSE;
01184                                         }
01185                                         else
01186                                         {
01187                                                 quit = TRUE;
01188                                         }
01189                                 }
01190                                 if(reason_response && (0 == strcmp(reason_response, "critical")))
01191                                 {
01192                                         if (show_connect_box)
01193                                         {
01194                                                 llinfos << "Need critical message" << llendl;
01195                                                 LLStartUp::setStartupState( STATE_UPDATE_CHECK );
01196                                                 LLFloaterTOS* tos_dialog = LLFloaterTOS::show(LLFloaterTOS::TOS_CRITICAL_MESSAGE,
01197                                                                                                                                         message_response);
01198                                                 tos_dialog->startModal();
01199                                                 // LLFloaterTOS deletes itself.
01200                                                 return FALSE;
01201                                         }
01202                                         else
01203                                         {
01204                                                 quit = TRUE;
01205                                         }
01206                                 }
01207                                 if(reason_response && (0 == strcmp(reason_response, "key")))
01208                                 {
01209                                         // Couldn't login because user/password is wrong
01210                                         // Clear the password
01211                                         password = "";
01212                                 }
01213                                 if(reason_response && (0 == strcmp(reason_response, "update")))
01214                                 {
01215                                         auth_message = gUserAuthp->getResponse("message");
01216                                         if (show_connect_box)
01217                                         {
01218                                                 update_app(TRUE, auth_message);
01219                                                 LLStartUp::setStartupState( STATE_UPDATE_CHECK );
01220                                                 return FALSE;
01221                                         }
01222                                         else
01223                                         {
01224                                                 quit = TRUE;
01225                                         }
01226                                 }
01227                                 if(reason_response && (0 == strcmp(reason_response, "optional")))
01228                                 {
01229                                         llinfos << "Login got optional update" << llendl;
01230                                         auth_message = gUserAuthp->getResponse("message");
01231                                         if (show_connect_box)
01232                                         {
01233                                                 update_app(FALSE, auth_message);
01234                                                 LLStartUp::setStartupState( STATE_UPDATE_CHECK );
01235                                                 gSkipOptionalUpdate = TRUE;
01236                                                 return FALSE;
01237                                         }
01238                                 }
01239                         }
01240                         break;
01241                 case LLUserAuth::E_COULDNT_RESOLVE_HOST:
01242                 case LLUserAuth::E_SSL_PEER_CERTIFICATE:
01243                 case LLUserAuth::E_UNHANDLED_ERROR:
01244                 case LLUserAuth::E_SSL_CACERT:
01245                 case LLUserAuth::E_SSL_CONNECT_ERROR:
01246                 default:
01247                         if (auth_uri_num >= (int) auth_uris.size() - 1)
01248                         {
01249                                 emsg << "Unable to connect to " << gSecondLife << ".\n";
01250                                 emsg << gUserAuthp->errorMessage();
01251                         } else {
01252                                 auth_uri_num++;
01253                                 std::ostringstream s;
01254                                 s << "Previous login attempt failed. Logging in, attempt "
01255                                   << (auth_uri_num + 1) << ".  ";
01256                                 auth_desc = s.str();
01257                                 LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE );
01258                                 auth_uri_num++;
01259                                 return do_normal_idle;
01260                         }
01261                         break;
01262                 }
01263 
01264                 // Version update and we're not showing the dialog
01265                 if(quit)
01266                 {
01267                         delete gUserAuthp;
01268                         gUserAuthp = NULL;
01269                         app_force_quit(NULL);
01270                         return FALSE;
01271                 }
01272 
01273                 if(successful_login)
01274                 {
01275                     if (!gUserAuthp)
01276                     {
01277                             llerrs << "No userauth on successful login!" << llendl;
01278                     }
01279 
01280                         // unpack login data needed by the application
01281                         const char* text;
01282                         text = gUserAuthp->getResponse("agent_id");
01283                         if(text) gAgentID.set(text);
01284                         write_debug("AgentID: ");
01285                         write_debug(text);
01286                         write_debug("\n");
01287                         
01288                         text = gUserAuthp->getResponse("session_id");
01289                         if(text) gAgentSessionID.set(text);
01290                         write_debug("SessionID: ");
01291                         write_debug(text);
01292                         write_debug("\n");
01293                         
01294                         text = gUserAuthp->getResponse("secure_session_id");
01295                         if(text) gAgent.mSecureSessionID.set(text);
01296 
01297                         text = gUserAuthp->getResponse("first_name");
01298                         if(text) 
01299                         {
01300                                 // Remove quotes from string.  Login.cgi sends these to force
01301                                 // names that look like numbers into strings.
01302                                 firstname.assign(text);
01303                                 LLString::replaceChar(firstname, '"', ' ');
01304                                 LLString::trim(firstname);
01305                         }
01306                         text = gUserAuthp->getResponse("last_name");
01307                         if(text) lastname.assign(text);
01308                         gSavedSettings.setString("FirstName", firstname);
01309                         gSavedSettings.setString("LastName", lastname);
01310                         if (remember_password)
01311                         {
01312                                 save_password_to_disk(password.c_str());
01313                         }
01314                         else
01315                         {
01316                                 save_password_to_disk(NULL);
01317                         }
01318                         gSavedSettings.setBOOL("RememberPassword", remember_password);
01319                         gSavedSettings.setBOOL("LoginLastLocation", gSavedSettings.getBOOL("LoginLastLocation"));
01320                         gSavedSettings.setBOOL("LoggedIn", TRUE);
01321 
01322                         text = gUserAuthp->getResponse("agent_access");
01323                         if(text && (text[0] == 'M'))
01324                         {
01325                                 gAgent.setTeen(false);
01326                         }
01327                         else
01328                         {
01329                                 gAgent.setTeen(true);
01330                         }
01331 
01332                         text = gUserAuthp->getResponse("start_location");
01333                         if(text) agent_start_location.assign(text);
01334                         text = gUserAuthp->getResponse("circuit_code");
01335                         if(text)
01336                         {
01337                                 gMessageSystem->mOurCircuitCode = strtoul(text, NULL, 10);
01338                         }
01339                         const char* sim_ip_str = gUserAuthp->getResponse("sim_ip");
01340                         const char* sim_port_str = gUserAuthp->getResponse("sim_port");
01341                         if(sim_ip_str && sim_port_str)
01342                         {
01343                                 U32 sim_port = strtoul(sim_port_str, NULL, 10);
01344                                 first_sim.set(sim_ip_str, sim_port);
01345                                 if (first_sim.isOk())
01346                                 {
01347                                         gMessageSystem->enableCircuit(first_sim, TRUE);
01348                                 }
01349                         }
01350                         const char* region_x_str = gUserAuthp->getResponse("region_x");
01351                         const char* region_y_str = gUserAuthp->getResponse("region_y");
01352                         if(region_x_str && region_y_str)
01353                         {
01354                                 U32 region_x = strtoul(region_x_str, NULL, 10);
01355                                 U32 region_y = strtoul(region_y_str, NULL, 10);
01356                                 first_sim_handle = to_region_handle(region_x, region_y);
01357                         }
01358                         
01359                         const char* look_at_str = gUserAuthp->getResponse("look_at");
01360                         if (look_at_str)
01361                         {
01362                                 LLMemoryStream mstr((U8*)look_at_str, strlen(look_at_str));             /* Flawfinder: ignore */
01363                                 LLSD sd = LLSDNotationParser::parse(mstr);
01364                                 agent_start_look_at = ll_vector3_from_sd(sd);
01365                         }
01366 
01367                         text = gUserAuthp->getResponse("seed_capability");
01368                         if (text) first_sim_seed_cap = text;
01369                                                 
01370                         text = gUserAuthp->getResponse("seconds_since_epoch");
01371                         if(text)
01372                         {
01373                                 U32 server_utc_time = strtoul(text, NULL, 10);
01374                                 if(server_utc_time)
01375                                 {
01376                                         time_t now = time(NULL);
01377                                         gUTCOffset = (server_utc_time - now);
01378                                 }
01379                         }
01380 
01381                         const char* home_location = gUserAuthp->getResponse("home");
01382                         if(home_location)
01383                         {
01384                                 LLMemoryStream mstr((U8*)home_location, strlen(home_location));         /* Flawfinder: ignore */
01385                                 LLSD sd = LLSDNotationParser::parse(mstr);
01386                                 S32 region_x = sd["region_handle"][0].asInteger();
01387                                 S32 region_y = sd["region_handle"][1].asInteger();
01388                                 U64 region_handle = to_region_handle(region_x, region_y);
01389                                 LLVector3 position = ll_vector3_from_sd(sd["position"]);
01390                                 gAgent.setHomePosRegion(region_handle, position);
01391                         }
01392 
01393                         gAgent.mMOTD.assign(gUserAuthp->getResponse("message"));
01394                         LLUserAuth::options_t options;
01395                         if(gUserAuthp->getOptions("inventory-root", options))
01396                         {
01397                                 LLUserAuth::response_t::iterator it;
01398                                 it = options[0].find("folder_id");
01399                                 if(it != options[0].end())
01400                                 {
01401                                         gAgent.mInventoryRootID.set((*it).second.c_str());
01402                                         //gInventory.mock(gAgent.getInventoryRootID());
01403                                 }
01404                         }
01405 
01406                         options.clear();
01407                         if(gUserAuthp->getOptions("login-flags", options))
01408                         {
01409                                 LLUserAuth::response_t::iterator it;
01410                                 LLUserAuth::response_t::iterator no_flag = options[0].end();
01411                                 it = options[0].find("ever_logged_in");
01412                                 if(it != no_flag)
01413                                 {
01414                                         if((*it).second == "N") gAgent.setFirstLogin(TRUE);
01415                                         else gAgent.setFirstLogin(FALSE);
01416                                 }
01417                                 it = options[0].find("stipend_since_login");
01418                                 if(it != no_flag)
01419                                 {
01420                                         if((*it).second == "Y") stipend_since_login = TRUE;
01421                                 }
01422                                 it = options[0].find("gendered");
01423                                 if(it != no_flag)
01424                                 {
01425                                         if((*it).second == "Y") gAgent.setGenderChosen(TRUE);
01426                                 }
01427                                 it = options[0].find("daylight_savings");
01428                                 if(it != no_flag)
01429                                 {
01430                                         if((*it).second == "Y")  gPacificDaylightTime = TRUE;
01431                                         else gPacificDaylightTime = FALSE;
01432                                 }
01433                         }
01434                         options.clear();
01435                         if (gUserAuthp->getOptions("initial-outfit", options)
01436                                 && !options.empty())
01437                         {
01438                                 LLUserAuth::response_t::iterator it;
01439                                 LLUserAuth::response_t::iterator it_end = options[0].end();
01440                                 it = options[0].find("folder_name");
01441                                 if(it != it_end)
01442                                 {
01443                                         gInitialOutfit = (*it).second;
01444                                 }
01445                                 it = options[0].find("gender");
01446                                 if (it != it_end)
01447                                 {
01448                                         gInitialOutfitGender = (*it).second;
01449                                 }
01450                         }
01451 
01452                         options.clear();
01453                         if(gUserAuthp->getOptions("global-textures", options))
01454                         {
01455                                 // Extract sun and moon texture IDs.  These are used
01456                                 // in the LLVOSky constructor, but I can't figure out
01457                                 // how to pass them in.  JC
01458                                 LLUserAuth::response_t::iterator it;
01459                                 LLUserAuth::response_t::iterator no_texture = options[0].end();
01460                                 it = options[0].find("sun_texture_id");
01461                                 if(it != no_texture)
01462                                 {
01463                                         gSunTextureID.set((*it).second.c_str());
01464                                 }
01465                                 it = options[0].find("moon_texture_id");
01466                                 if(it != no_texture)
01467                                 {
01468                                         gMoonTextureID.set((*it).second.c_str());
01469                                 }
01470                                 it = options[0].find("cloud_texture_id");
01471                                 if(it != no_texture)
01472                                 {
01473                                         gCloudTextureID.set((*it).second.c_str());
01474                                 }
01475                         }
01476 
01477 
01478                         // JC: gesture loading done below, when we have an asset system
01479                         // in place.  Don't delete/clear user_credentials until then.
01480 
01481                         if(gAgentID.notNull()
01482                            && gAgentSessionID.notNull()
01483                            && gMessageSystem->mOurCircuitCode
01484                            && first_sim.isOk()
01485                            && gAgent.mInventoryRootID.notNull())
01486                         {
01487                                 LLStartUp::setStartupState( STATE_WORLD_INIT );
01488                         }
01489                         else
01490                         {
01491                                 if (gNoRender)
01492                                 {
01493                                         llinfos << "Bad login - missing return values" << llendl;
01494                                         llinfos << emsg << llendl;
01495                                         exit(0);
01496                                 }
01497                                 // Bounce back to the login screen.
01498                                 LLStringBase<char>::format_map_t args;
01499                                 args["[ERROR_MESSAGE]"] = emsg.str();
01500                                 gViewerWindow->alertXml("ErrorMessage", args, login_alert_done);
01501                                 reset_login();
01502                                 gAutoLogin = FALSE;
01503                                 show_connect_box = TRUE;
01504                         }
01505                         
01506                         // Pass the user information to the voice chat server interface.
01507                         gVoiceClient->userAuthorized(firstname, lastname, gAgentID);
01508                 }
01509                 else
01510                 {
01511                         if (gNoRender)
01512                         {
01513                                 llinfos << "Failed to login!" << llendl;
01514                                 llinfos << emsg << llendl;
01515                                 exit(0);
01516                         }
01517                         // Bounce back to the login screen.
01518                         LLStringBase<char>::format_map_t args;
01519                         args["[ERROR_MESSAGE]"] = emsg.str();
01520                         gViewerWindow->alertXml("ErrorMessage", args, login_alert_done);
01521                         reset_login();
01522                         gAutoLogin = FALSE;
01523                         show_connect_box = TRUE;
01524                 }
01525                 return do_normal_idle;
01526         }
01527 
01528         //---------------------------------------------------------------------
01529         // World Init
01530         //---------------------------------------------------------------------
01531         if (STATE_WORLD_INIT == LLStartUp::getStartupState())
01532         {
01533                 set_startup_status(0.40f, "Initializing World...", gAgent.mMOTD.c_str());
01534                 display_startup();
01535                 // We should have an agent id by this point.
01536                 llassert(!(gAgentID == LLUUID::null));
01537 
01538                 // Finish agent initialization.  (Requires gSavedSettings, builds camera)
01539                 gAgent.init();
01540 
01541                 // Since we connected, save off the settings so the user doesn't have to
01542                 // type the name/password again if we crash.
01543                 gSavedSettings.saveToFile(gSettingsFileName, TRUE);
01544 
01545                 // Create selection manager
01546                 // Must be done before menus created, because many enabled callbacks
01547                 // require its existance.
01548                 gSelectMgr = new LLSelectMgr();
01549                 gParcelMgr = new LLViewerParcelMgr();
01550                 gHUDManager = new LLHUDManager();
01551                 gMuteListp = new LLMuteList();
01552 
01553                 //
01554                 // Initialize classes w/graphics stuff.
01555                 //
01556                 gImageList.doPrefetchImages();          
01557                 LLSurface::initClasses();
01558 
01559                 LLFace::initClass();
01560 
01561                 LLDrawable::initClass();
01562 
01563                 // RN: don't initialize VO classes in drone mode, they are too closely tied to rendering
01564                 LLViewerObject::initVOClasses();
01565 
01566                 display_startup();
01567 
01568                 // World initialization must be done after above window init
01569                 gWorldp = new LLWorld(region_size, region_scale);
01570 
01571                 // User might have overridden far clip
01572                 gWorldp->setLandFarClip( gAgent.mDrawDistance );
01573 
01574                 // Before we create the first region, we need to set the agent's mOriginGlobal
01575                 // This is necessary because creating objects before this is set will result in a
01576                 // bad mPositionAgent cache.
01577 
01578                 gAgent.initOriginGlobal(from_region_handle(first_sim_handle));
01579 
01580                 gWorldp->addRegion(first_sim_handle, first_sim);
01581 
01582                 LLViewerRegion *regionp = gWorldp->getRegionFromHandle(first_sim_handle);
01583                 llinfos << "Adding initial simulator " << regionp->getOriginGlobal() << llendl;
01584                 
01585                 LLStartUp::setStartupState( STATE_SEED_GRANTED_WAIT );
01586                 regionp->setSeedCapability(first_sim_seed_cap);
01587                 llinfos << "Waiting for seed grant ...." << llendl;
01588                 
01589                 // Set agent's initial region to be the one we just created.
01590                 gAgent.setRegion(regionp);
01591 
01592                 // Set agent's initial position, which will be read by LLVOAvatar when the avatar
01593                 // object is created.  I think this must be done after setting the region.  JC
01594                 gAgent.setPositionAgent(agent_start_position_region);
01595 
01596                 display_startup();
01597                 return do_normal_idle;
01598         }
01599 
01600 
01601         //---------------------------------------------------------------------
01602         // Wait for Seed Cap Grant
01603         //---------------------------------------------------------------------
01604         if(STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
01605         {
01606                 return do_normal_idle;
01607         }
01608 
01609 
01610         //---------------------------------------------------------------------
01611         // Seed Capability Granted
01612         // no newMessage calls should happen before this point
01613         //---------------------------------------------------------------------
01614         if (STATE_SEED_CAP_GRANTED == LLStartUp::getStartupState())
01615         {
01616                 update_texture_fetch();
01617 
01618                 if ( gViewerWindow != NULL && gToolMgr != NULL )
01619                 {       // This isn't the first logon attempt, so show the UI
01620                         gViewerWindow->setNormalControlsVisible( TRUE );
01621                 }
01622 
01623                 //
01624                 // Set message handlers
01625                 //
01626                 llinfos << "Initializing communications..." << llendl;
01627 
01628                 // register callbacks for messages. . . do this after initial handshake to make sure that we don't catch any unwanted
01629                 register_viewer_callbacks(gMessageSystem);
01630 
01631                 // Initialize UI
01632                 if (!gNoRender)
01633                 {
01634                         // Initialize all our tools.  Must be done after saved settings loaded.
01635                         if ( gToolMgr == NULL )
01636                         {
01637                                 gToolMgr = new LLToolMgr();
01638                                 gToolMgr->initTools();
01639                         }
01640 
01641                         // Quickly get something onscreen to look at.
01642                         gViewerWindow->initWorldUI();
01643 
01644                         // Move the progress view in front of the UI
01645                         gViewerWindow->moveProgressViewToFront();
01646 
01647                         LLError::logToFixedBuffer(gDebugView->mDebugConsolep);
01648                         // set initial visibility of debug console
01649                         gDebugView->mDebugConsolep->setVisible(gSavedSettings.getBOOL("ShowDebugConsole"));
01650                         gDebugView->mStatViewp->setVisible(gSavedSettings.getBOOL("ShowDebugStats"));
01651                 }
01652 
01653                 // Debugging info parameters
01654                 gMessageSystem->setMaxMessageTime( 0.5f );                      // Spam if decoding all msgs takes more than 500 ms
01655 
01656                 #ifndef LL_RELEASE_FOR_DOWNLOAD
01657                         gMessageSystem->setTimeDecodes( TRUE );                         // Time the decode of each msg
01658                         gMessageSystem->setTimeDecodesSpamThreshold( 0.05f );  // Spam if a single msg takes over 50ms to decode
01659                 #endif
01660 
01661                 gXferManager->registerCallbacks(gMessageSystem);
01662 
01663                 if ( gCacheName == NULL )
01664                 {
01665                         gCacheName = new LLCacheName(gMessageSystem);
01666                         gCacheName->addObserver(callback_cache_name);
01667         
01668                         // Load stored cache if possible
01669                         load_name_cache();
01670                 }
01671 
01672                 // Data storage for map of world.
01673                 if ( gWorldMap == NULL )
01674                 {
01675                         gWorldMap = new LLWorldMap();
01676                 }
01677 
01678                 if ( gRegionNameCache == NULL )
01679                 {
01680                         gRegionNameCache = new LLRegionNameCache();
01681 
01682                         load_region_name_cache();
01683                 }
01684 
01685                 // register null callbacks for audio until the audio system is initialized
01686                 gMessageSystem->setHandlerFuncFast(_PREHASH_SoundTrigger, null_message_callback, NULL);
01687                 gMessageSystem->setHandlerFuncFast(_PREHASH_AttachedSound, null_message_callback, NULL);
01688 
01689                 //reset statistics
01690                 gViewerStats->resetStats();
01691 
01692                 if (!gNoRender)
01693                 {
01694                         //
01695                         // Set up all of our statistics UI stuff.
01696                         //
01697                         init_stat_view();
01698                 }
01699 
01700                 display_startup();
01701                 //
01702                 // Set up region and surface defaults
01703                 //
01704 
01705 
01706                 // Sets up the parameters for the first simulator
01707 
01708                 llinfos << "Initializing camera..." << llendl;
01709                 gFrameTime    = totalTime();
01710                 F32 last_time = gFrameTimeSeconds;
01711                 gFrameTimeSeconds = (S64)(gFrameTime - gStartTime)/SEC_TO_MICROSEC;
01712 
01713                 gFrameIntervalSeconds = gFrameTimeSeconds - last_time;
01714                 if (gFrameIntervalSeconds < 0.f)
01715                 {
01716                         gFrameIntervalSeconds = 0.f;
01717                 }
01718 
01719                 // Make sure agent knows correct aspect ratio
01720                 gCamera->setViewHeightInPixels(gViewerWindow->getWindowDisplayHeight());
01721                 if (gViewerWindow->mWindow->getFullscreen())
01722                 {
01723                         gCamera->setAspect(gViewerWindow->getDisplayAspectRatio());
01724                 }
01725                 else
01726                 {
01727                         gCamera->setAspect( (F32) gViewerWindow->getWindowWidth() / (F32) gViewerWindow->getWindowHeight());
01728                 }
01729 
01730                 // Move agent to starting location. The position handed to us by
01731                 // the space server is in global coordinates, but the agent frame
01732                 // is in region local coordinates. Therefore, we need to adjust
01733                 // the coordinates handed to us to fit in the local region.
01734 
01735                 gAgent.setPositionAgent(agent_start_position_region);
01736                 gAgent.resetAxes(agent_start_look_at);
01737                 gAgent.stopCameraAnimation();
01738                 gAgent.resetCamera();
01739 
01740                 // Initialize global class data needed for surfaces (i.e. textures)
01741                 if (!gNoRender)
01742                 {
01743                         llinfos << "Initializing sky..." << llendl;
01744                         // Initialize all of the viewer object classes for the first time (doing things like texture fetches.
01745                         gSky.init(initial_sun_direction);
01746                 }
01747 
01748                 llinfos << "Decoding images..." << llendl;
01749                 // For all images pre-loaded into viewer cache, decode them.
01750                 // Need to do this AFTER we init the sky
01751                 const S32 DECODE_TIME_SEC = 2;
01752                 for (int i = 0; i < DECODE_TIME_SEC; i++)
01753                 {
01754                         F32 frac = (F32)i / (F32)DECODE_TIME_SEC;
01755                         set_startup_status(0.45f + frac*0.1f, "Decoding images...", gAgent.mMOTD.c_str());
01756                         display_startup();
01757                         gImageList.decodeAllImages(1.f);
01758                 }
01759                 LLStartUp::setStartupState( STATE_QUICKTIME_INIT );
01760 
01761                 // JC - Do this as late as possible to increase likelihood Purify
01762                 // will run.
01763                 LLMessageSystem* msg = gMessageSystem;
01764                 if (!msg->mOurCircuitCode)
01765                 {
01766                         llwarns << "Attempting to connect to simulator with a zero circuit code!" << llendl;
01767                 }
01768 
01769                 gUseCircuitCallbackCalled = FALSE;
01770 
01771                 msg->enableCircuit(first_sim, TRUE);
01772                 // now, use the circuit info to tell simulator about us!
01773                 llinfos << "viewer: UserLoginLocationReply() Enabling " << first_sim << " with code " << msg->mOurCircuitCode << llendl;
01774                 msg->newMessageFast(_PREHASH_UseCircuitCode);
01775                 msg->nextBlockFast(_PREHASH_CircuitCode);
01776                 msg->addU32Fast(_PREHASH_Code, msg->mOurCircuitCode);
01777                 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
01778                 msg->addUUIDFast(_PREHASH_ID, gAgent.getID());
01779                 msg->sendReliable(
01780                         first_sim,
01781                         MAX_TIMEOUT_COUNT,
01782                         FALSE,
01783                         TIMEOUT_SECONDS,
01784                         use_circuit_callback,
01785                         NULL);
01786 
01787                 timeout.reset();
01788 
01789                 return do_normal_idle;
01790         }
01791 
01792         //---------------------------------------------------------------------
01793         // LLMediaEngine Init
01794         //---------------------------------------------------------------------
01795         if (STATE_QUICKTIME_INIT == LLStartUp::getStartupState())
01796         {
01797                 if (gViewerWindow)
01798                 {
01799                         audio_update_volume(true);
01800                 }
01801 
01802                 #if LL_QUICKTIME_ENABLED        // windows only right now but will be ported to mac 
01803                 if (gUseQuickTime)
01804                 {
01805                         if(!gQuickTimeInitialized)
01806                         {
01807                                 // initialize quicktime libraries (fails gracefully if quicktime not installed ($QUICKTIME)
01808                                 llinfos << "Initializing QuickTime...." << llendl;
01809                                 set_startup_status(0.57f, "Initializing QuickTime...", gAgent.mMOTD.c_str());
01810                                 display_startup();
01811                                 #if LL_WINDOWS
01812                                         // Only necessary/available on Windows.
01813                                         if ( InitializeQTML ( 0L ) != noErr )
01814                                         {
01815                                                 // quicktime init failed - turn off media engine support
01816                                                 LLMediaEngine::getInstance ()->setAvailable ( FALSE );
01817                                                 llinfos << "...not found - unable to initialize." << llendl;
01818                                                 set_startup_status(0.57f, "QuickTime not found - unable to initialize.", gAgent.mMOTD.c_str());
01819                                         }
01820                                         else
01821                                         {
01822                                                 llinfos << ".. initialized successfully." << llendl;
01823                                                 set_startup_status(0.57f, "QuickTime initialized successfully.", gAgent.mMOTD.c_str());
01824                                         };
01825                                 #endif
01826                                 EnterMovies ();
01827                                 gQuickTimeInitialized = true;
01828                         }
01829                 }
01830                 else
01831                 {
01832                         LLMediaEngine::getInstance()->setAvailable( FALSE );
01833                 }
01834                 #endif
01835 
01836                 LLStartUp::setStartupState( STATE_WORLD_WAIT );
01837                 return do_normal_idle;
01838         }
01839 
01840         //---------------------------------------------------------------------
01841         // Agent Send
01842         //---------------------------------------------------------------------
01843         if(STATE_WORLD_WAIT == LLStartUp::getStartupState())
01844         {
01845                 //llinfos << "Waiting for simulator ack...." << llendl;
01846                 set_startup_status(0.59f, "Waiting for region handshake...", gAgent.mMOTD.c_str());
01847                 if(gGotUseCircuitCodeAck)
01848                 {
01849                         LLStartUp::setStartupState( STATE_AGENT_SEND );
01850                 }
01851                 LLMessageSystem* msg = gMessageSystem;
01852                 while (msg->checkAllMessages(gFrameCount, gServicePump))
01853                 {
01854                 }
01855                 msg->processAcks();
01856                 return do_normal_idle;
01857         }
01858 
01859         //---------------------------------------------------------------------
01860         // Agent Send
01861         //---------------------------------------------------------------------
01862         if (STATE_AGENT_SEND == LLStartUp::getStartupState())
01863         {
01864                 llinfos << "Connecting to region..." << llendl;
01865                 set_startup_status(0.60f, "Connecting to region...", gAgent.mMOTD.c_str());
01866                 // register with the message system so it knows we're
01867                 // expecting this message
01868                 LLMessageSystem* msg = gMessageSystem;
01869                 msg->setHandlerFuncFast(
01870                         _PREHASH_AgentMovementComplete,
01871                         process_agent_movement_complete);
01872                 LLViewerRegion* regionp = gAgent.getRegion();
01873                 if(regionp)
01874                 {
01875                         send_complete_agent_movement(regionp->getHost());
01876                         gAssetStorage->setUpstream(regionp->getHost());
01877                         gCacheName->setUpstream(regionp->getHost());
01878                         msg->newMessageFast(_PREHASH_EconomyDataRequest);
01879                         gAgent.sendReliableMessage();
01880                 }
01881 
01882                 // Create login effect
01883                 // But not on first login, because you can't see your avatar then
01884                 if (!gAgent.isFirstLogin())
01885                 {
01886                         LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
01887                         effectp->setPositionGlobal(gAgent.getPositionGlobal());
01888                         effectp->setColor(LLColor4U(gAgent.getEffectColor()));
01889                         gHUDManager->sendEffects();
01890                 }
01891 
01892                 LLStartUp::setStartupState( STATE_AGENT_WAIT );         // Go to STATE_AGENT_WAIT
01893 
01894                 timeout.reset();
01895                 return do_normal_idle;
01896         }
01897 
01898         //---------------------------------------------------------------------
01899         // Agent Wait
01900         //---------------------------------------------------------------------
01901         if (STATE_AGENT_WAIT == LLStartUp::getStartupState())
01902         {
01903                 LLMessageSystem* msg = gMessageSystem;
01904                 while (msg->checkAllMessages(gFrameCount, gServicePump))
01905                 {
01906                         if (gAgentMovementCompleted)
01907                         {
01908                                 // Sometimes we have more than one message in the
01909                                 // queue. break out of this loop and continue
01910                                 // processing. If we don't, then this could skip one
01911                                 // or more login steps.
01912                                 break;
01913                         }
01914                         else
01915                         {
01916                                 //llinfos << "Awaiting AvatarInitComplete, got "
01917                                 //<< msg->getMessageName() << llendl;
01918                         }
01919                 }
01920                 msg->processAcks();
01921 
01922                 if (gAgentMovementCompleted)
01923                 {
01924                         LLStartUp::setStartupState( STATE_INVENTORY_SEND );
01925                 }
01926 
01927                 return do_normal_idle;
01928         }
01929 
01930         //---------------------------------------------------------------------
01931         // Inventory Send
01932         //---------------------------------------------------------------------
01933         if (STATE_INVENTORY_SEND == LLStartUp::getStartupState())
01934         {
01935                 if (!gUserAuthp)
01936                 {
01937                         llerrs << "No userauth in STATE_INVENTORY_SEND!" << llendl;
01938                 }
01939 
01940                 // unpack thin inventory
01941                 LLUserAuth::options_t options;
01942                 options.clear();
01943                 //bool dump_buffer = false;
01944                 
01945                 if(gUserAuthp->getOptions("inventory-lib-root", options)
01946                         && !options.empty())
01947                 {
01948                         // should only be one
01949                         LLUserAuth::response_t::iterator it;
01950                         it = options[0].find("folder_id");
01951                         if(it != options[0].end())
01952                         {
01953                                 gInventoryLibraryRoot.set((*it).second.c_str());
01954                         }
01955                 }
01956                 options.clear();
01957                 if(gUserAuthp->getOptions("inventory-lib-owner", options)
01958                         && !options.empty())
01959                 {
01960                         // should only be one
01961                         LLUserAuth::response_t::iterator it;
01962                         it = options[0].find("agent_id");
01963                         if(it != options[0].end())
01964                         {
01965                                 gInventoryLibraryOwner.set((*it).second.c_str());
01966                         }
01967                 }
01968                 options.clear();
01969                 if(gUserAuthp->getOptions("inventory-skel-lib", options)
01970                         && gInventoryLibraryOwner.notNull())
01971                 {
01972                         if(!gInventory.loadSkeleton(options, gInventoryLibraryOwner))
01973                         {
01974                                 llwarns << "Problem loading inventory-skel-lib" << llendl;
01975                         }
01976                 }
01977                 options.clear();
01978                 if(gUserAuthp->getOptions("inventory-skeleton", options))
01979                 {
01980                         if(!gInventory.loadSkeleton(options, gAgent.getID()))
01981                         {
01982                                 llwarns << "Problem loading inventory-skel-targets"
01983                                                 << llendl;
01984                         }
01985                 }
01986 
01987                 options.clear();
01988                 if(gUserAuthp->getOptions("buddy-list", options))
01989                 {
01990                         LLUserAuth::options_t::iterator it = options.begin();
01991                         LLUserAuth::options_t::iterator end = options.end();
01992                         LLAvatarTracker::buddy_map_t list;
01993                         LLUUID agent_id;
01994                         S32 has_rights = 0, given_rights = 0;
01995                         for (; it != end; ++it)
01996                         {
01997                                 LLUserAuth::response_t::const_iterator option_it;
01998                                 option_it = (*it).find("buddy_id");
01999                                 if(option_it != (*it).end())
02000                                 {
02001                                         agent_id.set((*option_it).second.c_str());
02002                                 }
02003                                 option_it = (*it).find("buddy_rights_has");
02004                                 if(option_it != (*it).end())
02005                                 {
02006                                         has_rights = atoi((*option_it).second.c_str());
02007                                 }
02008                                 option_it = (*it).find("buddy_rights_given");
02009                                 if(option_it != (*it).end())
02010                                 {
02011                                         given_rights = atoi((*option_it).second.c_str());
02012                                 }
02013                                 list[agent_id] = new LLRelationship(given_rights, has_rights, false);
02014                         }
02015                         LLAvatarTracker::instance().addBuddyList(list);
02016                 }
02017 
02018                 options.clear();
02019                 if(gUserAuthp->getOptions("ui-config", options))
02020                 {
02021                         LLUserAuth::options_t::iterator it = options.begin();
02022                         LLUserAuth::options_t::iterator end = options.end();
02023                         for (; it != end; ++it)
02024                         {
02025                                 LLUserAuth::response_t::const_iterator option_it;
02026                                 option_it = (*it).find("allow_first_life");
02027                                 if(option_it != (*it).end())
02028                                 {
02029                                         if (option_it->second == "Y")
02030                                         {
02031                                                 LLPanelAvatar::sAllowFirstLife = TRUE;
02032                                         }
02033                                 }
02034                         }
02035                 }
02036 
02037                 options.clear();
02038                 if(gUserAuthp->getOptions("event_categories", options))
02039                 {
02040                         LLEventInfo::loadCategories(options);
02041                 }
02042                 if(gUserAuthp->getOptions("event_notifications", options))
02043                 {
02044                         gEventNotifier.load(options);
02045                 }
02046                 options.clear();
02047                 if(gUserAuthp->getOptions("classified_categories", options))
02048                 {
02049                         LLClassifiedInfo::loadCategories(options);
02050                 }
02051                 gInventory.buildParentChildMap();
02052                 gInventory.addChangedMask(LLInventoryObserver::ALL, LLUUID::null);
02053                 gInventory.notifyObservers();
02054 
02055                 // set up callbacks
02056                 LLMessageSystem* msg = gMessageSystem;
02057                 LLInventoryModel::registerCallbacks(msg);
02058                 LLAvatarTracker::instance().registerCallbacks(msg);
02059                 LLLandmark::registerCallbacks(msg);
02060 
02061                 // request mute list
02062                 gMuteListp->requestFromServer(gAgent.getID());
02063 
02064                 // Get L$ and ownership credit information
02065                 msg->newMessageFast(_PREHASH_MoneyBalanceRequest);
02066                 msg->nextBlockFast(_PREHASH_AgentData);
02067                 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
02068                 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
02069                 msg->nextBlockFast(_PREHASH_MoneyData);
02070                 msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null );
02071                 gAgent.sendReliableMessage();
02072 
02073                 // request all group information
02074                 // *FIX: This will not do the right thing if the message
02075                 // gets there before the requestuserserverconnection
02076                 // circuit is completed.
02077                 gAgent.sendAgentDataUpdateRequest();
02078 
02079 
02080                 // NOTE: removed as part of user-privacy
02081                 // enhancements. this information should be available from
02082                 // login. 2006-10-16 Phoenix.
02083                 // get the users that have been granted modify powers
02084                 //msg->newMessageFast(_PREHASH_RequestGrantedProxies);
02085                 //msg->nextBlockFast(_PREHASH_AgentData);
02086                 //msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
02087                 //msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
02088                 //gAgent.sendReliableMessage();
02089 
02090                 BOOL shown_at_exit = gSavedSettings.getBOOL("ShowInventory");
02091 
02092                 // Create the inventory views
02093                 LLInventoryView::showAgentInventory();
02094 
02095                 // Hide the inventory if it wasn't shown at exit
02096                 if(!shown_at_exit)
02097                 {
02098                         LLInventoryView::toggleVisibility(NULL);
02099                 }
02100 
02101                 LLStartUp::setStartupState( STATE_MISC );
02102                 return do_normal_idle;
02103         }
02104 
02105 
02106         //---------------------------------------------------------------------
02107         // Misc
02108         //---------------------------------------------------------------------
02109         if (STATE_MISC == LLStartUp::getStartupState())
02110         {
02111                 // We have a region, and just did a big inventory download.
02112                 // We can estimate the user's connection speed, and set their
02113                 // max bandwidth accordingly.  JC
02114                 if (gSavedSettings.getBOOL("FirstLoginThisInstall")
02115                         && gUserAuthp)
02116                 {
02117                         // This is actually a pessimistic computation, because TCP may not have enough
02118                         // time to ramp up on the (small) default inventory file to truly measure max
02119                         // bandwidth. JC
02120                         F64 rate_bps = gUserAuthp->getLastTransferRateBPS();
02121                         const F32 FAST_RATE_BPS = 600.f * 1024.f;
02122                         const F32 FASTER_RATE_BPS = 750.f * 1024.f;
02123                         F32 max_bandwidth = gViewerThrottle.getMaxBandwidth();
02124                         if (rate_bps > FASTER_RATE_BPS
02125                                 && rate_bps > max_bandwidth)
02126                         {
02127                                 llinfos << "Fast network connection, increasing max bandwidth to " 
02128                                         << FASTER_RATE_BPS/1024.f 
02129                                         << " kbps" << llendl;
02130                                 gViewerThrottle.setMaxBandwidth(FASTER_RATE_BPS / 1024.f);
02131                         }
02132                         else if (rate_bps > FAST_RATE_BPS
02133                                 && rate_bps > max_bandwidth)
02134                         {
02135                                 llinfos << "Fast network connection, increasing max bandwidth to " 
02136                                         << FAST_RATE_BPS/1024.f 
02137                                         << " kbps" << llendl;
02138                                 gViewerThrottle.setMaxBandwidth(FAST_RATE_BPS / 1024.f);
02139                         }
02140                 }
02141 
02142                 // We're successfully logged in.
02143                 gSavedSettings.setBOOL("FirstLoginThisInstall", FALSE);
02144 
02145 
02146                 // based on the comments, we've successfully logged in so we can delete the 'forced'
02147                 // URL that the updater set in settings.ini (in a mostly paranoid fashion)
02148                 LLString nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" );
02149                 if ( nextLoginLocation.length() )
02150                 {
02151                         // clear it
02152                         gSavedSettings.setString( "NextLoginLocation", "" );
02153 
02154                         // and make sure it's saved
02155                         gSavedSettings.saveToFile( gSettingsFileName, TRUE );
02156                 };
02157 
02158                 if (!gNoRender)
02159                 {
02160                         // JC: Initializing audio requests many sounds for download.
02161                         init_audio();
02162 
02163                         // JC: Initialize "active" gestures.  This may also trigger
02164                         // many gesture downloads, if this is the user's first
02165                         // time on this machine or -purge has been run.
02166                         LLUserAuth::options_t gesture_options;
02167                         if (gUserAuthp->getOptions("gestures", gesture_options))
02168                         {
02169                                 llinfos << "Gesture Manager loading " << gesture_options.size()
02170                                         << llendl;
02171                                 std::vector<LLUUID> item_ids;
02172                                 LLUserAuth::options_t::iterator resp_it;
02173                                 for (resp_it = gesture_options.begin();
02174                                          resp_it != gesture_options.end();
02175                                          ++resp_it)
02176                                 {
02177                                         const LLUserAuth::response_t& response = *resp_it;
02178                                         LLUUID item_id;
02179                                         LLUUID asset_id;
02180                                         LLUserAuth::response_t::const_iterator option_it;
02181 
02182                                         option_it = response.find("item_id");
02183                                         if (option_it != response.end())
02184                                         {
02185                                                 const std::string& uuid_string = (*option_it).second;
02186                                                 item_id.set(uuid_string.c_str());
02187                                         }
02188                                         option_it = response.find("asset_id");
02189                                         if (option_it != response.end())
02190                                         {
02191                                                 const std::string& uuid_string = (*option_it).second;
02192                                                 asset_id.set(uuid_string.c_str());
02193                                         }
02194 
02195                                         if (item_id.notNull() && asset_id.notNull())
02196                                         {
02197                                                 // Could schedule and delay these for later.
02198                                                 const BOOL no_inform_server = FALSE;
02199                                                 const BOOL no_deactivate_similar = FALSE;
02200                                                 gGestureManager.activateGestureWithAsset(item_id, asset_id,
02201                                                                                                                                  no_inform_server,
02202                                                                                                                                  no_deactivate_similar);
02203                                                 // We need to fetch the inventory items for these gestures
02204                                                 // so we have the names to populate the UI.
02205                                                 item_ids.push_back(item_id);
02206                                         }
02207                                 }
02208 
02209                                 LLGestureInventoryFetchObserver* fetch = new LLGestureInventoryFetchObserver();
02210                                 fetch->fetchItems(item_ids);
02211                                 // deletes itself when done
02212                                 gInventory.addObserver(fetch);
02213                         }
02214                 }
02215                 gDisplaySwapBuffers = TRUE;
02216 
02217                 LLMessageSystem* msg = gMessageSystem;
02218                 msg->setHandlerFuncFast(_PREHASH_SoundTrigger,                          process_sound_trigger);
02219                 msg->setHandlerFuncFast(_PREHASH_PreloadSound,                          process_preload_sound);
02220                 msg->setHandlerFuncFast(_PREHASH_AttachedSound,                         process_attached_sound);
02221                 msg->setHandlerFuncFast(_PREHASH_AttachedSoundGainChange,       process_attached_sound_gain_change);
02222                 //msg->setHandlerFuncFast(_PREHASH_AttachedSoundCutoffRadius,   process_attached_sound_cutoff_radius);
02223 
02224                 llinfos << "Initialization complete" << llendl;
02225                 gInitializationComplete = TRUE;
02226 
02227                 gRenderStartTime.reset();
02228                 gForegroundTime.reset();
02229 
02230                 // HACK: Inform simulator of window size.
02231                 // Do this here so it's less likely to race with RegisterNewAgent.
02232                 // TODO: Put this into RegisterNewAgent
02233                 // JC - 7/20/2002
02234                 gViewerWindow->sendShapeToSim();
02235 
02236                 // Ignore stipend information for now.  Money history is on the web site.
02237                 // if needed, show the L$ history window
02238                 //if (stipend_since_login && !gNoRender)
02239                 //{
02240                 //}
02241 
02242                 if (!gAgent.isFirstLogin())
02243                 {
02244                         bool url_ok = LLURLSimString::sInstance.parse();
02245                         if (!((agent_start_location == "url" && url_ok) ||
02246                   (!url_ok && ((agent_start_location == "last" && gSavedSettings.getBOOL("LoginLastLocation")) ||
02247                                                            (agent_start_location == "home" && !gSavedSettings.getBOOL("LoginLastLocation"))))))
02248                         {
02249                                 // The reason we show the alert is because we want to
02250                                 // reduce confusion for when you log in and your provided
02251                                 // location is not your expected location. So, if this is
02252                                 // your first login, then you do not have an expectation,
02253                                 // thus, do not show this alert.
02254                                 LLString::format_map_t args;
02255                                 if (url_ok)
02256                                 {
02257                                         args["[TYPE]"] = "desired";
02258                                         args["[HELP]"] = " ";
02259                                 }
02260                                 else if (gSavedSettings.getBOOL("LoginLastLocation"))
02261                                 {
02262                                         args["[TYPE]"] = "last";
02263                                         args["[HELP]"] = " \n ";
02264                                 }
02265                                 else
02266                                 {
02267                                         args["[TYPE]"] = "home";
02268                                         args["[HELP]"] = " \nYou may want to set a new home location.\n ";
02269                                 }
02270                                 gViewerWindow->alertXml("AvatarMoved", args);
02271                         }
02272                         else
02273                         {
02274                                 if (samename)
02275                                 {
02276                                         // restore old camera pos
02277                                         gAgent.setFocusOnAvatar(FALSE, FALSE);
02278                                         gAgent.setCameraPosAndFocusGlobal(gSavedSettings.getVector3d("CameraPosOnLogout"), gSavedSettings.getVector3d("FocusPosOnLogout"), LLUUID::null);
02279                                         BOOL limit_hit = FALSE;
02280                                         gAgent.calcCameraPositionTargetGlobal(&limit_hit);
02281                                         if (limit_hit)
02282                                         {
02283                                                 gAgent.setFocusOnAvatar(TRUE, FALSE);
02284                                         }
02285                                         gAgent.stopCameraAnimation();
02286                                 }
02287                         }
02288                 }
02289 
02290                 LLStartUp::setStartupState( STATE_PRECACHE );
02291                 timeout.reset();
02292                 return do_normal_idle;
02293         }
02294 
02295         if (STATE_PRECACHE == LLStartUp::getStartupState())
02296         {
02297                 do_normal_idle = TRUE;
02298                 
02299                 F32 timeout_frac = timeout.getElapsedTimeF32()/PRECACHING_DELAY;
02300                 // wait precache-delay and for agent's avatar or a lot longer.
02301                 if(((timeout_frac > 1.f) && gAgent.getAvatarObject())
02302                    || (timeout_frac > 3.f))
02303                 {
02304                         LLStartUp::setStartupState( STATE_WEARABLES_WAIT );
02305                 }
02306                 else
02307                 {
02308                         update_texture_fetch();
02309                         set_startup_status(0.60f + 0.40f * timeout_frac, "Precaching...",
02310                                                            gAgent.mMOTD.c_str());
02311                 }
02312 
02313                 return do_normal_idle;
02314         }
02315 
02316         if (STATE_WEARABLES_WAIT == LLStartUp::getStartupState())
02317         {
02318                 do_normal_idle = TRUE;
02319 
02320                 static LLFrameTimer wearables_timer;
02321 
02322                 const F32 wearables_time = wearables_timer.getElapsedTimeF32();
02323                 const F32 MAX_WEARABLES_TIME = 10.f;
02324 
02325                 if(gAgent.getWearablesLoaded() || !gAgent.isGenderChosen())
02326                 {
02327                         LLStartUp::setStartupState( STATE_CLEANUP );
02328                 }
02329                 else if (wearables_time > MAX_WEARABLES_TIME)
02330                 {
02331                         gViewerWindow->alertXml("ClothingLoading");
02332                         gViewerStats->incStat(LLViewerStats::ST_WEARABLES_TOO_LONG);
02333                         LLStartUp::setStartupState( STATE_CLEANUP );
02334                 }
02335                 else
02336                 {
02337                         update_texture_fetch();
02338                         set_startup_status(0.f + 0.25f * wearables_time / MAX_WEARABLES_TIME,
02339                                                          "Downloading clothing...",
02340                                                          gAgent.mMOTD.c_str());
02341                 }
02342                 return do_normal_idle;
02343         }
02344 
02345         if (STATE_CLEANUP == LLStartUp::getStartupState())
02346         {
02347                 set_startup_status(1.0, "", NULL);
02348 
02349                 do_normal_idle = TRUE;
02350 
02351                 // Let the map know about the inventory.
02352                 if(gFloaterWorldMap)
02353                 {
02354                         gFloaterWorldMap->observeInventory(&gInventory);
02355                         gFloaterWorldMap->observeFriends();
02356                 }
02357 
02358                 gViewerWindow->showCursor();
02359                 gViewerWindow->getWindow()->resetBusyCount();
02360                 gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
02361                 //llinfos << "Done releasing bitmap" << llendl;
02362                 gViewerWindow->setShowProgress(FALSE);
02363                 gViewerWindow->setProgressCancelButtonVisible(FALSE, "");
02364 
02365                 // We're not away from keyboard, even though login might have taken
02366                 // a while. JC
02367                 gAgent.clearAFK();
02368 
02369                 // Have the agent start watching the friends list so we can update proxies
02370                 gAgent.observeFriends();
02371                 if (gSavedSettings.getBOOL("LoginAsGod"))
02372                 {
02373                         gAgent.requestEnterGodMode();
02374                 }
02375                 
02376                 // On first start, ask user for gender
02377                 dialog_choose_gender_first_start();
02378 
02379                 // setup voice
02380                 LLFirstUse::useVoice();
02381 
02382                 // Start automatic replay if the flag is set.
02383                 if (gSavedSettings.getBOOL("StatsAutoRun"))
02384                 {
02385                         LLUUID id;
02386                         llinfos << "Starting automatic playback" << llendl;
02387                         gAgentPilot.startPlayback();
02388                 }
02389 
02390                 // If we've got a startup URL, dispatch it
02391                 LLStartUp::dispatchURL();
02392                 
02393                 // Clean up the userauth stuff.
02394                 if (gUserAuthp)
02395                 {
02396                         delete gUserAuthp;
02397                         gUserAuthp = NULL;
02398                 }
02399 
02400                 LLStartUp::setStartupState( STATE_STARTED );
02401 
02402                 // Unmute audio if desired and setup volumes
02403                 audio_update_volume();
02404 
02405                 // reset keyboard focus to sane state of pointing at world
02406                 gFocusMgr.setKeyboardFocus(NULL, NULL);
02407 
02408 #if 0 // sjb: enable for auto-enabling timer display 
02409                 gDebugView->mFastTimerView->setVisible(TRUE);
02410 #endif
02411 
02412                 return do_normal_idle;
02413         }
02414 
02415         llwarns << "Reached end of idle_startup for state " << LLStartUp::getStartupState() << llendl;
02416         return do_normal_idle;
02417 }
02418 
02419 //
02420 // local function definition
02421 //
02422 
02423 void login_show()
02424 {
02425         llinfos << "Initializing Login Screen" << llendl;
02426 
02427 #ifdef LL_RELEASE_FOR_DOWNLOAD
02428         BOOL bUseDebugLogin = gSavedSettings.getBOOL("UseDebugLogin");
02429 #else
02430         BOOL bUseDebugLogin = TRUE;
02431 #endif
02432 
02433         LLPanelLogin::show(     gViewerWindow->getVirtualWindowRect(),
02434                                                 bUseDebugLogin,
02435                                                 login_callback, NULL );
02436 
02437         // UI textures have been previously loaded in doPreloadImages()
02438         
02439         llinfos << "Setting Servers" << llendl;
02440         
02441         if( USERSERVER_OTHER == gUserServerChoice )
02442         {
02443                 LLPanelLogin::addServer( gUserServerName, USERSERVER_OTHER );
02444         }
02445         else
02446         {
02447                 LLPanelLogin::addServer( gUserServerDomainName[gUserServerChoice].mLabel, gUserServerChoice );
02448         }
02449 
02450         // Arg!  We hate loops!
02451         LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_DMZ].mLabel,  USERSERVER_DMZ );
02452         LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_LOCAL].mLabel,        USERSERVER_LOCAL );
02453         LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_AGNI].mLabel, USERSERVER_AGNI );
02454         LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_ADITI].mLabel,        USERSERVER_ADITI );
02455         LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_SIVA].mLabel, USERSERVER_SIVA );
02456         LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_DURGA].mLabel,        USERSERVER_DURGA );
02457         LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_SHAKTI].mLabel,       USERSERVER_SHAKTI );
02458         LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_GANGA].mLabel,        USERSERVER_GANGA );
02459         LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_UMA].mLabel,  USERSERVER_UMA );
02460         LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_SOMA].mLabel, USERSERVER_SOMA );
02461         LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_VAAK].mLabel, USERSERVER_VAAK );
02462 }
02463 
02464 // Callback for when login screen is closed.  Option 0 = connect, option 1 = quit.
02465 void login_callback(S32 option, void *userdata)
02466 {
02467         const S32 CONNECT_OPTION = 0;
02468         const S32 QUIT_OPTION = 1;
02469 
02470         if (CONNECT_OPTION == option)
02471         {
02472                 LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
02473                 return;
02474         }
02475         else if (QUIT_OPTION == option)
02476         {
02477                 // Make sure we don't save the password if the user is trying to clear it.
02478                 LLString first, last, password;
02479                 BOOL remember = TRUE;
02480                 LLPanelLogin::getFields(first, last, password, remember);
02481                 if (!remember)
02482                 {
02483                         // turn off the setting and write out to disk
02484                         gSavedSettings.setBOOL("RememberPassword", FALSE);
02485                         gSavedSettings.saveToFile(gSettingsFileName, TRUE);
02486 
02487                         // stomp the saved password on disk
02488                         save_password_to_disk(NULL);
02489                 }
02490 
02491                 LLPanelLogin::close();
02492 
02493                 // Next iteration through main loop should shut down the app cleanly.
02494                 gQuit = TRUE;
02495 
02496                 return;
02497         }
02498         else
02499         {
02500                 llwarns << "Unknown login button clicked" << llendl;
02501         }
02502 }
02503 
02504 LLString load_password_from_disk()
02505 {
02506         LLString hashed_password("");
02507 
02508         // Look for legacy "marker" password from settings.ini
02509         hashed_password = gSavedSettings.getString("Marker");
02510         if (!hashed_password.empty())
02511         {
02512                 // Stomp the Marker entry.
02513                 gSavedSettings.setString("Marker", "");
02514 
02515                 // Return that password.
02516                 return hashed_password;
02517         }
02518 
02519         std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
02520                                                                                                            "password.dat");
02521         FILE* fp = LLFile::fopen(filepath.c_str(), "rb");               /* Flawfinder: ignore */
02522         if (!fp)
02523         {
02524                 return hashed_password;
02525         }
02526 
02527         // UUID is 16 bytes, written into ASCII is 32 characters
02528         // without trailing \0
02529         const S32 HASHED_LENGTH = 32;
02530         U8 buffer[HASHED_LENGTH+1];
02531 
02532         if (1 != fread(buffer, HASHED_LENGTH, 1, fp))
02533         {
02534                 return hashed_password;
02535         }
02536 
02537         fclose(fp);
02538 
02539         // Decipher with MAC address
02540         LLXORCipher cipher(gMACAddress, 6);
02541         cipher.decrypt(buffer, HASHED_LENGTH);
02542 
02543         buffer[HASHED_LENGTH] = '\0';
02544 
02545         // Check to see if the mac address generated a bad hashed
02546         // password. It should be a hex-string or else the mac adress has
02547         // changed. This is a security feature to make sure that if you
02548         // get someone's password.dat file, you cannot hack their account.
02549         if(is_hex_string(buffer, HASHED_LENGTH))
02550         {
02551                 hashed_password.assign((char*)buffer);
02552         }
02553 
02554         return hashed_password;
02555 }
02556 
02557 void save_password_to_disk(const char* hashed_password)
02558 {
02559         std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
02560                                                                                                            "password.dat");
02561         if (!hashed_password)
02562         {
02563                 // No password, remove the file.
02564                 LLFile::remove(filepath.c_str());
02565         }
02566         else
02567         {
02568                 FILE* fp = LLFile::fopen(filepath.c_str(), "wb");               /* Flawfinder: ignore */
02569                 if (!fp)
02570                 {
02571                         return;
02572                 }
02573 
02574                 // Encipher with MAC address
02575                 const S32 HASHED_LENGTH = 32;
02576                 U8 buffer[HASHED_LENGTH+1];
02577 
02578                 LLString::copy((char*)buffer, hashed_password, HASHED_LENGTH+1);
02579 
02580                 LLXORCipher cipher(gMACAddress, 6);
02581                 cipher.encrypt(buffer, HASHED_LENGTH);
02582 
02583                 if (fwrite(buffer, HASHED_LENGTH, 1, fp) != 1)
02584                 {
02585                         llwarns << "Short write" << llendl;
02586                 }
02587 
02588                 fclose(fp);
02589         }
02590 }
02591 
02592 BOOL is_hex_string(U8* str, S32 len)
02593 {
02594         BOOL rv = TRUE;
02595         U8* c = str;
02596         while(rv && len--)
02597         {
02598                 switch(*c)
02599                 {
02600                 case '0':
02601                 case '1':
02602                 case '2':
02603                 case '3':
02604                 case '4':
02605                 case '5':
02606                 case '6':
02607                 case '7':
02608                 case '8':
02609                 case '9':
02610                 case 'a':
02611                 case 'b':
02612                 case 'c':
02613                 case 'd':
02614                 case 'e':
02615                 case 'f':
02616                         ++c;
02617                         break;
02618                 default:
02619                         rv = FALSE;
02620                         break;
02621                 }
02622         }
02623         return rv;
02624 }
02625 
02626 void show_first_run_dialog()
02627 {
02628         gViewerWindow->alertXml("FirstRun", first_run_dialog_callback, NULL);
02629 }
02630 
02631 void first_run_dialog_callback(S32 option, void* userdata)
02632 {
02633         if (0 == option)
02634         {
02635                 llinfos << "First run dialog cancelling" << llendl;
02636                 LLWeb::loadURL( CREATE_ACCOUNT_URL );
02637         }
02638 
02639         LLPanelLogin::giveFocus();
02640 }
02641 
02642 
02643 
02644 void set_startup_status(const F32 frac, const char *string, const char* msg)
02645 {
02646         gViewerWindow->setProgressPercent(frac*100);
02647         gViewerWindow->setProgressString(string);
02648 
02649         gViewerWindow->setProgressMessage(msg);
02650 }
02651 
02652 void login_alert_status(S32 option, void* user_data)
02653 {
02654         if (0 == option)
02655         {
02656                 // OK button
02657         }
02658         else if (1 == option)
02659         {
02660                 // Help button
02661                 std::string help_path;
02662                 help_path = gDirUtilp->getExpandedFilename(LL_PATH_HELP, "unable_to_connect.html");
02663                 load_url_local_file(help_path.c_str() );
02664         }
02665 
02666         LLPanelLogin::giveFocus();
02667 }
02668 
02669 void update_app(BOOL mandatory, const std::string& auth_msg)
02670 {
02671         // store off config state, as we might quit soon
02672         gSavedSettings.saveToFile(gSettingsFileName, TRUE);
02673 
02674         std::ostringstream message;
02675 
02676         //*TODO:translate
02677         std::string msg;
02678         if (!auth_msg.empty())
02679         {
02680                 msg = "(" + auth_msg + ") \n";
02681         }
02682         LLStringBase<char>::format_map_t args;
02683         args["[MESSAGE]"] = msg;
02684         
02685         // represent a bool as a null/non-null pointer
02686         void *mandatoryp = mandatory ? &mandatory : NULL;
02687 
02688 #if LL_WINDOWS
02689         if (mandatory)
02690         {
02691                 gViewerWindow->alertXml("DownloadWindowsMandatory", args,
02692                                                                 update_dialog_callback,
02693                                                                 mandatoryp);
02694         }
02695         else
02696         {
02697 #if LL_RELEASE_FOR_DOWNLOAD
02698                 gViewerWindow->alertXml("DownloadWindowsReleaseForDownload", args,
02699                                                                 update_dialog_callback,
02700                                                                 mandatoryp);
02701 #else
02702                 gViewerWindow->alertXml("DownloadWindows", args,
02703                                                                 update_dialog_callback,
02704                                                                 mandatoryp);
02705 #endif
02706         }
02707 #else
02708         if (mandatory)
02709         {
02710                 gViewerWindow->alertXml("DownloadMacMandatory", args,
02711                                                                 update_dialog_callback,
02712                                                                 mandatoryp);
02713         }
02714         else
02715         {
02716 #if LL_RELEASE_FOR_DOWNLOAD
02717                 gViewerWindow->alertXml("DownloadMacReleaseForDownload", args,
02718                                                                 update_dialog_callback,
02719                                                                 mandatoryp);
02720 #else
02721                 gViewerWindow->alertXml("DownloadMac", args,
02722                                                                 update_dialog_callback,
02723                                                                 mandatoryp);
02724 #endif
02725         }
02726 #endif
02727 
02728 }
02729 
02730 
02731 void update_dialog_callback(S32 option, void *userdata)
02732 {
02733         std::string update_exe_path;
02734         BOOL mandatory = userdata != NULL;
02735 
02736 #if !LL_RELEASE_FOR_DOWNLOAD
02737         if (option == 2)
02738         {
02739                 LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT ); 
02740                 return;
02741         }
02742 #endif
02743         
02744         if (option == 1)
02745         {
02746                 // ...user doesn't want to do it
02747                 if (mandatory)
02748                 {
02749                         app_force_quit();
02750                         // Bump them back to the login screen.
02751                         //reset_login();
02752                 }
02753                 else
02754                 {
02755                         LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT );
02756                 }
02757                 return;
02758         }
02759         
02760         LLSD query_map = LLSD::emptyMap();
02761         // *TODO place os string in a global constant
02762 #if LL_WINDOWS  
02763         query_map["os"] = "win";
02764 #elif LL_DARWIN
02765         query_map["os"] = "mac";
02766 #elif LL_LINUX
02767         query_map["os"] = "lnx";
02768 #endif
02769         query_map["userserver"] = gUserServerName;
02770         query_map["channel"] = gChannelName;
02771         // *TODO constantize this guy
02772         LLURI update_url = LLURI::buildHTTP("sl.daleglass.net", 80, "download", query_map);
02773         
02774 #if LL_WINDOWS
02775         update_exe_path = gDirUtilp->getTempFilename();
02776         if (update_exe_path.empty())
02777         {
02778                 // We're hosed, bail
02779                 llwarns << "LLDir::getTempFilename() failed" << llendl;
02780                 app_force_quit(NULL);
02781                 return;
02782         }
02783 
02784         update_exe_path += ".exe";
02785 
02786         std::string updater_source = gDirUtilp->getAppRODataDir();
02787         updater_source += gDirUtilp->getDirDelimiter();
02788         updater_source += "updater.exe";
02789 
02790         llinfos << "Calling CopyFile source: " << updater_source.c_str()
02791                         << " dest: " << update_exe_path
02792                         << llendl;
02793 
02794 
02795         if (!CopyFileA(updater_source.c_str(), update_exe_path.c_str(), FALSE))
02796         {
02797                 llinfos << "Unable to copy the updater!" << llendl;
02798                 app_force_quit(NULL);
02799                 return;
02800         }
02801 
02802         // if a sim name was passed in via command line parameter (typically through a SLURL)
02803         if ( LLURLSimString::sInstance.mSimString.length() )
02804         {
02805                 // record the location to start at next time
02806                 gSavedSettings.setString( "NextLoginLocation", LLURLSimString::sInstance.mSimString ); 
02807         };
02808 
02809         std::ostringstream params;
02810         params << "-url \"" << update_url.asString() << "\"";
02811         if (gHideLinks)
02812         {
02813                 // Figure out the program name.
02814                 const char* data_dir = gDirUtilp->getAppRODataDir().c_str();
02815                 // Roll back from the end, stopping at the first '\'
02816                 const char* program_name = data_dir + strlen(data_dir);         /* Flawfinder: ignore */
02817                 while ( (data_dir != --program_name) &&
02818                                 *(program_name) != '\\');
02819                 
02820                 if ( *(program_name) == '\\')
02821                 {
02822                         // We found a '\'.
02823                         program_name++;
02824                 }
02825                 else
02826                 {
02827                         // Oops.
02828                         program_name = "SecondLife";
02829                 }
02830 
02831                 params << " -silent -name \"" << gSecondLife << "\"";
02832                 params << " -program \"" << program_name << "\"";
02833         }
02834 
02835         llinfos << "Calling updater: " << update_exe_path << " " << params.str() << llendl;
02836 
02837         remove_marker_file(); // In case updater fails
02838         
02839         // Use spawn() to run asynchronously
02840         int retval = _spawnl(_P_NOWAIT, update_exe_path.c_str(), update_exe_path.c_str(), params.str().c_str(), NULL);
02841         llinfos << "Spawn returned " << retval << llendl;
02842 
02843 #elif LL_DARWIN
02844         // if a sim name was passed in via command line parameter (typically through a SLURL)
02845         if ( LLURLSimString::sInstance.mSimString.length() )
02846         {
02847                 // record the location to start at next time
02848                 gSavedSettings.setString( "NextLoginLocation", LLURLSimString::sInstance.mSimString ); 
02849         };
02850         
02851         update_exe_path = "'";
02852         update_exe_path += gDirUtilp->getAppRODataDir();
02853         update_exe_path += "/AutoUpdater.app/Contents/MacOS/AutoUpdater' -url \"";
02854         update_exe_path += update_url.asString();
02855         update_exe_path += "\" -name \"";
02856         update_exe_path += gSecondLife;
02857         update_exe_path += "\" &";
02858 
02859         llinfos << "Calling updater: " << update_exe_path << llendl;
02860 
02861         remove_marker_file(); // In case updater fails
02862         
02863         // Run the auto-updater.
02864         system(update_exe_path.c_str());                /* Flawfinder: ignore */
02865         
02866 #elif LL_LINUX
02867         OSMessageBox("Automatic updating is not yet implemented for Linux.\n"
02868                 "Please download the latest version from www.secondlife.com.",
02869                 NULL, OSMB_OK);
02870         remove_marker_file();
02871         
02872 #endif
02873         app_force_quit(NULL);
02874 }
02875 
02876 void update_check_failure_dialog_callback(S32 option, void *userdata)
02877 {
02878         if (option == 0)
02879         {
02880                 llinfos << "Continuing" << llendl;
02881                 LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT );
02882                 return;
02883         }
02884         
02885         llinfos << "Quitting" << llendl;
02886         app_force_quit(NULL);
02887 }
02888 
02889 void use_circuit_callback(void**, S32 result)
02890 {
02891         // bail if we're quitting.
02892         if(gQuit) return;
02893         if( !gUseCircuitCallbackCalled )
02894         {
02895                 gUseCircuitCallbackCalled = true;
02896                 if (result)
02897                 {
02898                         // Make sure user knows something bad happened. JC
02899                         llinfos << "Backing up to login screen!" << llendl;
02900                         gViewerWindow->alertXml("LoginPacketNeverReceived",
02901                                 login_alert_status, NULL);
02902                         reset_login();
02903                 }
02904                 else
02905                 {
02906                         gGotUseCircuitCodeAck = true;
02907                 }
02908         }
02909 }
02910 
02911 void register_viewer_callbacks(LLMessageSystem* msg)
02912 {
02913         msg->setHandlerFuncFast(_PREHASH_LayerData,                             process_layer_data );
02914         msg->setHandlerFuncFast(_PREHASH_ImageData,                             LLViewerImageList::receiveImageHeader );
02915         msg->setHandlerFuncFast(_PREHASH_ImagePacket,                           LLViewerImageList::receiveImagePacket );
02916         msg->setHandlerFuncFast(_PREHASH_ObjectUpdate,                          process_object_update );
02917         msg->setHandlerFunc("ObjectUpdateCompressed",                           process_compressed_object_update );
02918         msg->setHandlerFunc("ObjectUpdateCached",                                       process_cached_object_update );
02919         msg->setHandlerFuncFast(_PREHASH_ImprovedTerseObjectUpdate, process_terse_object_update_improved );
02920         msg->setHandlerFunc("SimStats",                         process_sim_stats);
02921         msg->setHandlerFuncFast(_PREHASH_HealthMessage,                 process_health_message );
02922         msg->setHandlerFuncFast(_PREHASH_EconomyData,                           process_economy_data);
02923         msg->setHandlerFunc("RegionInfo", LLViewerRegion::processRegionInfo);
02924 
02925         msg->setHandlerFuncFast(_PREHASH_ChatFromSimulator,             process_chat_from_simulator);
02926         msg->setHandlerFuncFast(_PREHASH_KillObject,                            process_kill_object,    NULL);
02927         msg->setHandlerFuncFast(_PREHASH_SimulatorViewerTimeMessage,    process_time_synch,             NULL);
02928         msg->setHandlerFuncFast(_PREHASH_EnableSimulator,                       process_enable_simulator);
02929         msg->setHandlerFuncFast(_PREHASH_DisableSimulator,                      process_disable_simulator);
02930         msg->setHandlerFuncFast(_PREHASH_KickUser,                                      process_kick_user,              NULL);
02931 
02932         msg->setHandlerFunc("CrossedRegion", process_crossed_region);
02933         msg->setHandlerFuncFast(_PREHASH_TeleportFinish, process_teleport_finish);
02934 
02935         msg->setHandlerFuncFast(_PREHASH_AlertMessage,             process_alert_message);
02936         msg->setHandlerFunc("AgentAlertMessage", process_agent_alert_message);
02937         msg->setHandlerFuncFast(_PREHASH_MeanCollisionAlert,             process_mean_collision_alert_message,  NULL);
02938         msg->setHandlerFunc("ViewerFrozenMessage",             process_frozen_message);
02939 
02940         //msg->setHandlerFuncFast(_PREHASH_RequestAvatarInfo,           process_avatar_info_request);
02941         msg->setHandlerFuncFast(_PREHASH_NameValuePair,                 process_name_value);
02942         msg->setHandlerFuncFast(_PREHASH_RemoveNameValuePair,   process_remove_name_value);
02943         msg->setHandlerFuncFast(_PREHASH_AvatarAnimation,               process_avatar_animation);
02944         msg->setHandlerFuncFast(_PREHASH_AvatarAppearance,              process_avatar_appearance);
02945         msg->setHandlerFunc("AgentCachedTextureResponse",       LLAgent::processAgentCachedTextureResponse);
02946         msg->setHandlerFunc("RebakeAvatarTextures", LLVOAvatar::processRebakeAvatarTextures);
02947         msg->setHandlerFuncFast(_PREHASH_CameraConstraint,              process_camera_constraint);
02948         msg->setHandlerFuncFast(_PREHASH_AvatarSitResponse,             process_avatar_sit_response);
02949         msg->setHandlerFunc("SetFollowCamProperties",                   process_set_follow_cam_properties);
02950         msg->setHandlerFunc("ClearFollowCamProperties",                 process_clear_follow_cam_properties);
02951 
02952         msg->setHandlerFuncFast(_PREHASH_ImprovedInstantMessage,        process_improved_im);
02953         msg->setHandlerFuncFast(_PREHASH_ScriptQuestion,                        process_script_question);
02954         msg->setHandlerFuncFast(_PREHASH_ObjectProperties,                      LLSelectMgr::processObjectProperties, NULL);
02955         msg->setHandlerFuncFast(_PREHASH_ObjectPropertiesFamily,        LLSelectMgr::processObjectPropertiesFamily, NULL);
02956         msg->setHandlerFunc("ForceObjectSelect", LLSelectMgr::processForceObjectSelect);
02957 
02958         msg->setHandlerFuncFast(_PREHASH_MoneyBalanceReply,             process_money_balance_reply,    NULL);
02959         msg->setHandlerFuncFast(_PREHASH_CoarseLocationUpdate,          LLWorld::processCoarseUpdate, NULL);
02960         msg->setHandlerFuncFast(_PREHASH_ReplyTaskInventory,            LLViewerObject::processTaskInv, NULL);
02961         msg->setHandlerFuncFast(_PREHASH_DerezContainer,                        process_derez_container, NULL);
02962         msg->setHandlerFuncFast(_PREHASH_ScriptRunningReply,
02963                                                 &LLLiveLSLEditor::processScriptRunningReply);
02964 
02965         msg->setHandlerFuncFast(_PREHASH_DeRezAck, process_derez_ack);
02966 
02967         msg->setHandlerFunc("LogoutReply", process_logout_reply);
02968 
02969         //msg->setHandlerFuncFast(_PREHASH_AddModifyAbility,
02970         //                                      &LLAgent::processAddModifyAbility);
02971         //msg->setHandlerFuncFast(_PREHASH_RemoveModifyAbility,
02972         //                                      &LLAgent::processRemoveModifyAbility);
02973         msg->setHandlerFuncFast(_PREHASH_AgentDataUpdate,
02974                                                 &LLAgent::processAgentDataUpdate);
02975         msg->setHandlerFuncFast(_PREHASH_AgentGroupDataUpdate,
02976                                                 &LLAgent::processAgentGroupDataUpdate);
02977         msg->setHandlerFunc("AgentDropGroup",
02978                                                 &LLAgent::processAgentDropGroup);
02979         // land ownership messages
02980         msg->setHandlerFuncFast(_PREHASH_ParcelOverlay,
02981                                                 LLViewerParcelMgr::processParcelOverlay);
02982         msg->setHandlerFuncFast(_PREHASH_ParcelProperties,
02983                                                 LLViewerParcelMgr::processParcelProperties);
02984         msg->setHandlerFunc("ParcelAccessListReply",
02985                 LLViewerParcelMgr::processParcelAccessListReply);
02986         msg->setHandlerFunc("ParcelDwellReply",
02987                 LLViewerParcelMgr::processParcelDwellReply);
02988 
02989         msg->setHandlerFunc("AvatarPropertiesReply",
02990                                                 LLPanelAvatar::processAvatarPropertiesReply);
02991         msg->setHandlerFunc("AvatarInterestsReply",
02992                                                 LLPanelAvatar::processAvatarInterestsReply);
02993         msg->setHandlerFunc("AvatarGroupsReply",
02994                                                 LLPanelAvatar::processAvatarGroupsReply);
02995         // ratings deprecated
02996         //msg->setHandlerFuncFast(_PREHASH_AvatarStatisticsReply,
02997         //                                      LLPanelAvatar::processAvatarStatisticsReply);
02998         msg->setHandlerFunc("AvatarNotesReply",
02999                                                 LLPanelAvatar::processAvatarNotesReply);
03000         msg->setHandlerFunc("AvatarPicksReply",
03001                                                 LLPanelAvatar::processAvatarPicksReply);
03002         msg->setHandlerFunc("AvatarClassifiedReply",
03003                                                 LLPanelAvatar::processAvatarClassifiedReply);
03004 
03005         msg->setHandlerFuncFast(_PREHASH_CreateGroupReply,
03006                                                 LLGroupMgr::processCreateGroupReply);
03007         msg->setHandlerFuncFast(_PREHASH_JoinGroupReply,
03008                                                 LLGroupMgr::processJoinGroupReply);
03009         msg->setHandlerFuncFast(_PREHASH_EjectGroupMemberReply,
03010                                                 LLGroupMgr::processEjectGroupMemberReply);
03011         msg->setHandlerFuncFast(_PREHASH_LeaveGroupReply,
03012                                                 LLGroupMgr::processLeaveGroupReply);
03013         msg->setHandlerFuncFast(_PREHASH_GroupProfileReply,
03014                                                 LLGroupMgr::processGroupPropertiesReply);
03015 
03016         // ratings deprecated
03017         // msg->setHandlerFuncFast(_PREHASH_ReputationIndividualReply,
03018         //                                      LLFloaterRate::processReputationIndividualReply);
03019 
03020         msg->setHandlerFuncFast(_PREHASH_AgentWearablesUpdate,
03021                                                 LLAgent::processAgentInitialWearablesUpdate );
03022 
03023         msg->setHandlerFunc("ScriptControlChange",
03024                                                 LLAgent::processScriptControlChange );
03025 
03026         msg->setHandlerFuncFast(_PREHASH_ViewerEffect, LLHUDManager::processViewerEffect);
03027 
03028         msg->setHandlerFuncFast(_PREHASH_GrantGodlikePowers, process_grant_godlike_powers);
03029 
03030         msg->setHandlerFuncFast(_PREHASH_GroupAccountSummaryReply,
03031                                                         LLPanelGroupLandMoney::processGroupAccountSummaryReply);
03032         msg->setHandlerFuncFast(_PREHASH_GroupAccountDetailsReply,
03033                                                         LLPanelGroupLandMoney::processGroupAccountDetailsReply);
03034         msg->setHandlerFuncFast(_PREHASH_GroupAccountTransactionsReply,
03035                                                         LLPanelGroupLandMoney::processGroupAccountTransactionsReply);
03036 
03037         msg->setHandlerFuncFast(_PREHASH_UserInfoReply,
03038                 process_user_info_reply);
03039 
03040         msg->setHandlerFunc("RegionHandshake", process_region_handshake, NULL);
03041 
03042         msg->setHandlerFunc("TeleportStart", process_teleport_start );
03043         msg->setHandlerFunc("TeleportProgress", process_teleport_progress);
03044         msg->setHandlerFunc("TeleportFailed", process_teleport_failed, NULL);
03045         msg->setHandlerFunc("TeleportLocal", process_teleport_local, NULL);
03046 
03047         msg->setHandlerFunc("ImageNotInDatabase", LLViewerImageList::processImageNotInDatabase, NULL);
03048 
03049         msg->setHandlerFuncFast(_PREHASH_GroupMembersReply,
03050                                                 LLGroupMgr::processGroupMembersReply);
03051         msg->setHandlerFunc("GroupRoleDataReply",
03052                                                 LLGroupMgr::processGroupRoleDataReply);
03053         msg->setHandlerFunc("GroupRoleMembersReply",
03054                                                 LLGroupMgr::processGroupRoleMembersReply);
03055         msg->setHandlerFunc("GroupTitlesReply",
03056                                                 LLGroupMgr::processGroupTitlesReply);
03057         // Special handler as this message is sometimes used for group land.
03058         msg->setHandlerFunc("PlacesReply", process_places_reply);
03059         msg->setHandlerFunc("GroupNoticesListReply", LLPanelGroupNotices::processGroupNoticesListReply);
03060 
03061         msg->setHandlerFunc("DirPlacesReply", LLPanelDirBrowser::processDirPlacesReply);
03062         msg->setHandlerFunc("DirPeopleReply", LLPanelDirBrowser::processDirPeopleReply);
03063         msg->setHandlerFunc("DirEventsReply", LLPanelDirBrowser::processDirEventsReply);
03064         msg->setHandlerFunc("DirGroupsReply", LLPanelDirBrowser::processDirGroupsReply);
03065         //msg->setHandlerFunc("DirPicksReply",  LLPanelDirBrowser::processDirPicksReply);
03066         msg->setHandlerFunc("DirClassifiedReply",  LLPanelDirBrowser::processDirClassifiedReply);
03067         msg->setHandlerFunc("DirLandReply",   LLPanelDirBrowser::processDirLandReply);
03068         msg->setHandlerFunc("DirPopularReply",LLPanelDirBrowser::processDirPopularReply);
03069 
03070         msg->setHandlerFunc("AvatarPickerReply", LLFloaterAvatarPicker::processAvatarPickerReply);
03071 
03072         msg->setHandlerFunc("MapLayerReply", LLWorldMap::processMapLayerReply);
03073         msg->setHandlerFunc("MapBlockReply", LLWorldMap::processMapBlockReply);
03074         msg->setHandlerFunc("MapItemReply", LLWorldMap::processMapItemReply);
03075 
03076         msg->setHandlerFunc("EventInfoReply", LLPanelEvent::processEventInfoReply);
03077         msg->setHandlerFunc("PickInfoReply", LLPanelPick::processPickInfoReply);
03078         msg->setHandlerFunc("ClassifiedInfoReply", LLPanelClassified::processClassifiedInfoReply);
03079         msg->setHandlerFunc("ParcelInfoReply", LLPanelPlace::processParcelInfoReply);
03080         msg->setHandlerFunc("ScriptDialog", process_script_dialog);
03081         msg->setHandlerFunc("LoadURL", process_load_url);
03082         msg->setHandlerFunc("ScriptTeleportRequest", process_script_teleport_request);
03083         msg->setHandlerFunc("EstateCovenantReply", process_covenant_reply);
03084 
03085         // calling cards
03086         msg->setHandlerFunc("OfferCallingCard", process_offer_callingcard);
03087         msg->setHandlerFunc("AcceptCallingCard", process_accept_callingcard);
03088         msg->setHandlerFunc("DeclineCallingCard", process_decline_callingcard);
03089 
03090         msg->setHandlerFunc("ParcelObjectOwnersReply", LLPanelLandObjects::processParcelObjectOwnersReply);
03091 
03092         // Reponse to the "Refresh" button on land objects floater.
03093         if (gSavedSettings.getBOOL("AudioStreamingVideo"))
03094         {
03095                 msg->setHandlerFunc("ParcelMediaCommandMessage", LLMediaEngine::process_parcel_media);
03096                 msg->setHandlerFunc ( "ParcelMediaUpdate", LLMediaEngine::process_parcel_media_update );
03097         }
03098         else
03099         {
03100                 msg->setHandlerFunc("ParcelMediaCommandMessage", null_message_callback);
03101                 gMessageSystem->setHandlerFunc ( "ParcelMediaUpdate", null_message_callback );
03102         }
03103 
03104         msg->setHandlerFunc("InitiateDownload", process_initiate_download);
03105         msg->setHandlerFunc("LandStatReply", LLFloaterTopObjects::handle_land_reply);
03106         msg->setHandlerFunc("GenericMessage", process_generic_message);
03107 
03108         msg->setHandlerFuncFast(_PREHASH_FeatureDisabled, process_feature_disabled_message);
03109 }
03110 
03111 
03112 void init_stat_view()
03113 {
03114         LLFrameStatView *frameviewp = gDebugView->mFrameStatView;
03115         frameviewp->setup(gFrameStats);
03116         frameviewp->mShowPercent = FALSE;
03117 
03118         LLRect rect;
03119         LLStatBar *stat_barp;
03120         rect = gDebugView->mStatViewp->getRect();
03121 
03122         //
03123         // Viewer advanced stats
03124         //
03125         LLStatView *stat_viewp = NULL;
03126 
03127         //
03128         // Viewer Basic
03129         //
03130         stat_viewp = new LLStatView("basic stat view", "Basic", "OpenDebugStatBasic", rect);
03131         gDebugView->mStatViewp->addChildAtEnd(stat_viewp);
03132 
03133         stat_barp = stat_viewp->addStat("FPS", &(gViewerStats->mFPSStat));
03134         stat_barp->setUnitLabel(" fps");
03135         stat_barp->mMinBar = 0.f;
03136         stat_barp->mMaxBar = 45.f;
03137         stat_barp->mTickSpacing = 7.5f;
03138         stat_barp->mLabelSpacing = 15.f;
03139         stat_barp->mPrecision = 1;
03140         stat_barp->mDisplayBar = TRUE;
03141         stat_barp->mDisplayHistory = TRUE;
03142 
03143         stat_barp = stat_viewp->addStat("Bandwidth", &(gViewerStats->mKBitStat));
03144         stat_barp->setUnitLabel(" kbps");
03145         stat_barp->mMinBar = 0.f;
03146         stat_barp->mMaxBar = 900.f;
03147         stat_barp->mTickSpacing = 100.f;
03148         stat_barp->mLabelSpacing = 300.f;
03149         stat_barp->mDisplayBar = TRUE;
03150         stat_barp->mDisplayHistory = FALSE;
03151 
03152         stat_barp = stat_viewp->addStat("Packet Loss", &(gViewerStats->mPacketsLostPercentStat));
03153         stat_barp->setUnitLabel(" %");
03154         stat_barp->mMinBar = 0.f;
03155         stat_barp->mMaxBar = 5.f;
03156         stat_barp->mTickSpacing = 1.f;
03157         stat_barp->mLabelSpacing = 1.f;
03158         stat_barp->mDisplayBar = FALSE;
03159         stat_barp->mPerSec = FALSE;
03160         stat_barp->mDisplayMean = TRUE;
03161         stat_barp->mPrecision = 1;
03162 
03163         stat_barp = stat_viewp->addStat("Ping Sim", &(gViewerStats->mSimPingStat));
03164         stat_barp->setUnitLabel(" msec");
03165         stat_barp->mMinBar = 0.f;
03166         stat_barp->mMaxBar = 1000.f;
03167         stat_barp->mTickSpacing = 100.f;
03168         stat_barp->mLabelSpacing = 200.f;
03169         stat_barp->mDisplayBar = FALSE;
03170         stat_barp->mPerSec = FALSE;
03171         stat_barp->mDisplayMean = FALSE;
03172 
03173 
03174         stat_viewp = new LLStatView("advanced stat view", "Advanced", "OpenDebugStatAdvanced", rect);
03175         gDebugView->mStatViewp->addChildAtEnd(stat_viewp);
03176 
03177 
03178         LLStatView *render_statviewp;
03179         render_statviewp = new LLStatView("render stat view", "Render", "OpenDebugStatRender", rect);
03180         stat_viewp->addChildAtEnd(render_statviewp);
03181 
03182         stat_barp = render_statviewp->addStat("KTris Drawn", &(gPipeline.mTrianglesDrawnStat));
03183         stat_barp->setUnitLabel("/fr");
03184         stat_barp->mMinBar = 0.f;
03185         stat_barp->mMaxBar = 500.f;
03186         stat_barp->mTickSpacing = 100.f;
03187         stat_barp->mLabelSpacing = 500.f;
03188         stat_barp->mPrecision = 1;
03189         stat_barp->mPerSec = FALSE;
03190 
03191         stat_barp = render_statviewp->addStat("KTris Drawn", &(gPipeline.mTrianglesDrawnStat));
03192         stat_barp->setUnitLabel("/sec");
03193         stat_barp->mMinBar = 0.f;
03194         stat_barp->mMaxBar = 3000.f;
03195         stat_barp->mTickSpacing = 250.f;
03196         stat_barp->mLabelSpacing = 1000.f;
03197         stat_barp->mPrecision = 1;
03198 
03199         stat_barp = render_statviewp->addStat("Total Objs", &(gObjectList.mNumObjectsStat));
03200         stat_barp->mMinBar = 0.f;
03201         stat_barp->mMaxBar = 10000.f;
03202         stat_barp->mTickSpacing = 2500.f;
03203         stat_barp->mLabelSpacing = 5000.f;
03204         stat_barp->mPerSec = FALSE;
03205         stat_barp->mDisplayBar = FALSE;
03206 
03207         stat_barp = render_statviewp->addStat("New Objs", &(gObjectList.mNumNewObjectsStat));
03208         stat_barp->setLabel("New Objs");
03209         stat_barp->setUnitLabel("/sec");
03210         stat_barp->mMinBar = 0.f;
03211         stat_barp->mMaxBar = 1000.f;
03212         stat_barp->mTickSpacing = 100.f;
03213         stat_barp->mLabelSpacing = 500.f;
03214         stat_barp->mPerSec = TRUE;
03215         stat_barp->mDisplayBar = FALSE;
03216 
03217 
03218         // Texture statistics
03219         LLStatView *texture_statviewp;
03220         texture_statviewp = new LLStatView("texture stat view", "Texture", "", rect);
03221         render_statviewp->addChildAtEnd(texture_statviewp);
03222 
03223         stat_barp = texture_statviewp->addStat("Count", &(gImageList.sNumImagesStat));
03224         stat_barp->setUnitLabel("");
03225         stat_barp->mMinBar = 0.f;
03226         stat_barp->mMaxBar = 8000.f;
03227         stat_barp->mTickSpacing = 2000.f;
03228         stat_barp->mLabelSpacing = 4000.f;
03229         stat_barp->mPerSec = FALSE;
03230         stat_barp->mDisplayBar = FALSE;
03231 
03232         stat_barp = texture_statviewp->addStat("Raw Count", &(gImageList.sNumRawImagesStat));
03233         stat_barp->setUnitLabel("");
03234         stat_barp->mMinBar = 0.f;
03235         stat_barp->mMaxBar = 8000.f;
03236         stat_barp->mTickSpacing = 2000.f;
03237         stat_barp->mLabelSpacing = 4000.f;
03238         stat_barp->mPerSec = FALSE;
03239         stat_barp->mDisplayBar = FALSE;
03240 
03241         stat_barp = texture_statviewp->addStat("GL Mem", &(gImageList.sGLTexMemStat));
03242         stat_barp->setUnitLabel("");
03243         stat_barp->mMinBar = 0.f;
03244         stat_barp->mMaxBar = 400.f;
03245         stat_barp->mTickSpacing = 100.f;
03246         stat_barp->mLabelSpacing = 200.f;
03247         stat_barp->mPrecision = 1;
03248         stat_barp->mPerSec = FALSE;
03249 
03250         stat_barp = texture_statviewp->addStat("Formatted Mem", &(gImageList.sFormattedMemStat));
03251         stat_barp->setUnitLabel("");
03252         stat_barp->mMinBar = 0.f;
03253         stat_barp->mMaxBar = 400.f;
03254         stat_barp->mTickSpacing = 100.f;
03255         stat_barp->mLabelSpacing = 200.f;
03256         stat_barp->mPrecision = 1;
03257         stat_barp->mPerSec = FALSE;
03258 
03259         stat_barp = texture_statviewp->addStat("Raw Mem", &(gImageList.sRawMemStat));
03260         stat_barp->setUnitLabel("");
03261         stat_barp->mMinBar = 0.f;
03262         stat_barp->mMaxBar = 400.f;
03263         stat_barp->mTickSpacing = 100.f;
03264         stat_barp->mLabelSpacing = 200.f;
03265         stat_barp->mPrecision = 1;
03266         stat_barp->mPerSec = FALSE;
03267 
03268         stat_barp = texture_statviewp->addStat("Bound Mem", &(gImageList.sGLBoundMemStat));
03269         stat_barp->setUnitLabel("");
03270         stat_barp->mMinBar = 0.f;
03271         stat_barp->mMaxBar = 400.f;
03272         stat_barp->mTickSpacing = 100.f;
03273         stat_barp->mLabelSpacing = 200.f;
03274         stat_barp->mPrecision = 1;
03275         stat_barp->mPerSec = FALSE;
03276 
03277         
03278         // Network statistics
03279         LLStatView *net_statviewp;
03280         net_statviewp = new LLStatView("network stat view", "Network", "OpenDebugStatNet", rect);
03281         stat_viewp->addChildAtEnd(net_statviewp);
03282 
03283         stat_barp = net_statviewp->addStat("Packets In", &(gViewerStats->mPacketsInStat));
03284         stat_barp->setUnitLabel("/sec");
03285         stat_barp->mDisplayBar = FALSE;
03286 
03287         stat_barp = net_statviewp->addStat("Packets Out", &(gViewerStats->mPacketsOutStat));
03288         stat_barp->setUnitLabel("/sec");
03289         stat_barp->mDisplayBar = FALSE;
03290 
03291         stat_barp = net_statviewp->addStat("Objects", &(gViewerStats->mObjectKBitStat));
03292         stat_barp->setUnitLabel(" kbps");
03293         stat_barp->mDisplayBar = FALSE;
03294 
03295         stat_barp = net_statviewp->addStat("Texture", &(gViewerStats->mTextureKBitStat));
03296         stat_barp->setUnitLabel(" kbps");
03297         stat_barp->mDisplayBar = FALSE;
03298 
03299         stat_barp = net_statviewp->addStat("Asset", &(gViewerStats->mAssetKBitStat));
03300         stat_barp->setUnitLabel(" kbps");
03301         stat_barp->mDisplayBar = FALSE;
03302 
03303         stat_barp = net_statviewp->addStat("Layers", &(gViewerStats->mLayersKBitStat));
03304         stat_barp->setUnitLabel(" kbps");
03305         stat_barp->mDisplayBar = FALSE;
03306 
03307         stat_barp = net_statviewp->addStat("Actual In", &(gViewerStats->mActualInKBitStat));
03308         stat_barp->setUnitLabel(" kbps");
03309         stat_barp->mMinBar = 0.f;
03310         stat_barp->mMaxBar = 1024.f;
03311         stat_barp->mTickSpacing = 128.f;
03312         stat_barp->mLabelSpacing = 256.f;
03313         stat_barp->mDisplayBar = TRUE;
03314         stat_barp->mDisplayHistory = FALSE;
03315 
03316         stat_barp = net_statviewp->addStat("Actual Out", &(gViewerStats->mActualOutKBitStat));
03317         stat_barp->setUnitLabel(" kbps");
03318         stat_barp->mMinBar = 0.f;
03319         stat_barp->mMaxBar = 512.f;
03320         stat_barp->mTickSpacing = 128.f;
03321         stat_barp->mLabelSpacing = 256.f;
03322         stat_barp->mDisplayBar = TRUE;
03323         stat_barp->mDisplayHistory = FALSE;
03324 
03325         stat_barp = net_statviewp->addStat("VFS Pending Ops", &(gViewerStats->mVFSPendingOperations));
03326         stat_barp->setUnitLabel(" ");
03327         stat_barp->mPerSec = FALSE;
03328         stat_barp->mDisplayBar = FALSE;
03329 
03330 
03331         // Simulator stats
03332         LLStatView *sim_statviewp = new LLStatView("sim stat view", "Simulator", "OpenDebugStatSim", rect);
03333         gDebugView->mStatViewp->addChildAtEnd(sim_statviewp);
03334 
03335         stat_barp = sim_statviewp->addStat("Time Dilation", &(gViewerStats->mSimTimeDilation));
03336         stat_barp->mPrecision = 2;
03337         stat_barp->mMinBar = 0.f;
03338         stat_barp->mMaxBar = 1.f;
03339         stat_barp->mTickSpacing = 0.25f;
03340         stat_barp->mLabelSpacing = 0.5f;
03341         stat_barp->mPerSec = FALSE;
03342         stat_barp->mDisplayBar = FALSE;
03343         stat_barp->mDisplayMean = FALSE;
03344 
03345         stat_barp = sim_statviewp->addStat("Sim FPS", &(gViewerStats->mSimFPS));
03346         stat_barp->mMinBar = 0.f;
03347         stat_barp->mMaxBar = 200.f;
03348         stat_barp->mTickSpacing = 20.f;
03349         stat_barp->mLabelSpacing = 100.f;
03350         stat_barp->mPerSec = FALSE;
03351         stat_barp->mDisplayBar = FALSE;
03352         stat_barp->mDisplayMean = FALSE;
03353 
03354         stat_barp = sim_statviewp->addStat("Physics FPS", &(gViewerStats->mSimPhysicsFPS));
03355         stat_barp->mPrecision = 1;
03356         stat_barp->mMinBar = 0.f;
03357         stat_barp->mMaxBar = 66.f;
03358         stat_barp->mTickSpacing = 33.f;
03359         stat_barp->mLabelSpacing = 33.f;
03360         stat_barp->mPerSec = FALSE;
03361         stat_barp->mDisplayBar = FALSE;
03362         stat_barp->mDisplayMean = FALSE;
03363 
03364         stat_barp = sim_statviewp->addStat("Agent Updates/Sec", &(gViewerStats->mSimAgentUPS));
03365         stat_barp->mPrecision = 1;
03366         stat_barp->mMinBar = 0.f;
03367         stat_barp->mMaxBar = 100.f;
03368         stat_barp->mTickSpacing = 25.f;
03369         stat_barp->mLabelSpacing = 50.f;
03370         stat_barp->mPerSec = FALSE;
03371         stat_barp->mDisplayBar = FALSE;
03372         stat_barp->mDisplayMean = FALSE;
03373 
03374         stat_barp = sim_statviewp->addStat("Main Agents", &(gViewerStats->mSimMainAgents));
03375         stat_barp->mPrecision = 0;
03376         stat_barp->mMinBar = 0.f;
03377         stat_barp->mMaxBar = 80.f;
03378         stat_barp->mTickSpacing = 10.f;
03379         stat_barp->mLabelSpacing = 40.f;
03380         stat_barp->mPerSec = FALSE;
03381         stat_barp->mDisplayBar = FALSE;
03382         stat_barp->mDisplayMean = FALSE;
03383 
03384         stat_barp = sim_statviewp->addStat("Child Agents", &(gViewerStats->mSimChildAgents));
03385         stat_barp->mPrecision = 0;
03386         stat_barp->mMinBar = 0.f;
03387         stat_barp->mMaxBar = 40.f;
03388         stat_barp->mTickSpacing = 5.f;
03389         stat_barp->mLabelSpacing = 10.f;
03390         stat_barp->mPerSec = FALSE;
03391         stat_barp->mDisplayBar = FALSE;
03392         stat_barp->mDisplayMean = FALSE;
03393 
03394         stat_barp = sim_statviewp->addStat("Objects", &(gViewerStats->mSimObjects));
03395         stat_barp->mPrecision = 0;
03396         stat_barp->mMinBar = 0.f;
03397         stat_barp->mMaxBar = 30000.f;
03398         stat_barp->mTickSpacing = 5000.f;
03399         stat_barp->mLabelSpacing = 10000.f;
03400         stat_barp->mPerSec = FALSE;
03401         stat_barp->mDisplayBar = FALSE;
03402         stat_barp->mDisplayMean = FALSE;
03403 
03404         stat_barp = sim_statviewp->addStat("Active Objects", &(gViewerStats->mSimActiveObjects));
03405         stat_barp->mPrecision = 0;
03406         stat_barp->mMinBar = 0.f;
03407         stat_barp->mMaxBar = 800.f;
03408         stat_barp->mTickSpacing = 100.f;
03409         stat_barp->mLabelSpacing = 200.f;
03410         stat_barp->mPerSec = FALSE;
03411         stat_barp->mDisplayBar = FALSE;
03412         stat_barp->mDisplayMean = FALSE;
03413 
03414         stat_barp = sim_statviewp->addStat("Active Scripts", &(gViewerStats->mSimActiveScripts));
03415         stat_barp->mPrecision = 0;
03416         stat_barp->mMinBar = 0.f;
03417         stat_barp->mMaxBar = 800.f;
03418         stat_barp->mTickSpacing = 100.f;
03419         stat_barp->mLabelSpacing = 200.f;
03420         stat_barp->mPerSec = FALSE;
03421         stat_barp->mDisplayBar = FALSE;
03422         stat_barp->mDisplayMean = FALSE;
03423 
03424         stat_barp = sim_statviewp->addStat("Script Perf", &(gViewerStats->mSimLSLIPS));
03425         stat_barp->setUnitLabel(" ips");
03426         stat_barp->mPrecision = 0;
03427         stat_barp->mMinBar = 0.f;
03428         stat_barp->mMaxBar = 100000.f;
03429         stat_barp->mTickSpacing = 25000.f;
03430         stat_barp->mLabelSpacing = 50000.f;
03431         stat_barp->mPerSec = FALSE;
03432         stat_barp->mDisplayBar = FALSE;
03433         stat_barp->mDisplayMean = FALSE;
03434 
03435         stat_barp = sim_statviewp->addStat("Packets In", &(gViewerStats->mSimInPPS));
03436         stat_barp->setUnitLabel(" pps");
03437         stat_barp->mPrecision = 0;
03438         stat_barp->mMinBar = 0.f;
03439         stat_barp->mMaxBar = 2000.f;
03440         stat_barp->mTickSpacing = 250.f;
03441         stat_barp->mLabelSpacing = 1000.f;
03442         stat_barp->mPerSec = FALSE;
03443         stat_barp->mDisplayBar = FALSE;
03444         stat_barp->mDisplayMean = FALSE;
03445 
03446         stat_barp = sim_statviewp->addStat("Packets Out", &(gViewerStats->mSimOutPPS));
03447         stat_barp->setUnitLabel(" pps");
03448         stat_barp->mPrecision = 0;
03449         stat_barp->mMinBar = 0.f;
03450         stat_barp->mMaxBar = 2000.f;
03451         stat_barp->mTickSpacing = 250.f;
03452         stat_barp->mLabelSpacing = 1000.f;
03453         stat_barp->mPerSec = FALSE;
03454         stat_barp->mDisplayBar = FALSE;
03455         stat_barp->mDisplayMean = FALSE;
03456 
03457         stat_barp = sim_statviewp->addStat("Pending Downloads", &(gViewerStats->mSimPendingDownloads));
03458         stat_barp->mPrecision = 0;
03459         stat_barp->mMinBar = 0.f;
03460         stat_barp->mMaxBar = 800.f;
03461         stat_barp->mTickSpacing = 100.f;
03462         stat_barp->mLabelSpacing = 200.f;
03463         stat_barp->mPerSec = FALSE;
03464         stat_barp->mDisplayBar = FALSE;
03465         stat_barp->mDisplayMean = FALSE;
03466 
03467         stat_barp = sim_statviewp->addStat("Pending Uploads", &(gViewerStats->mSimPendingUploads));
03468         stat_barp->mPrecision = 0;
03469         stat_barp->mMinBar = 0.f;
03470         stat_barp->mMaxBar = 100.f;
03471         stat_barp->mTickSpacing = 25.f;
03472         stat_barp->mLabelSpacing = 50.f;
03473         stat_barp->mPerSec = FALSE;
03474         stat_barp->mDisplayBar = FALSE;
03475         stat_barp->mDisplayMean = FALSE;
03476 
03477         stat_barp = sim_statviewp->addStat("Total Unacked Bytes", &(gViewerStats->mSimTotalUnackedBytes));
03478         stat_barp->setUnitLabel(" kb");
03479         stat_barp->mPrecision = 0;
03480         stat_barp->mMinBar = 0.f;
03481         stat_barp->mMaxBar = 100000.f;
03482         stat_barp->mTickSpacing = 25000.f;
03483         stat_barp->mLabelSpacing = 50000.f;
03484         stat_barp->mPerSec = FALSE;
03485         stat_barp->mDisplayBar = FALSE;
03486         stat_barp->mDisplayMean = FALSE;
03487 
03488         LLStatView *sim_time_viewp;
03489         sim_time_viewp = new LLStatView("sim perf view", "Time (ms)", "", rect);
03490         sim_statviewp->addChildAtEnd(sim_time_viewp);
03491 
03492         stat_barp = sim_time_viewp->addStat("Total Frame Time", &(gViewerStats->mSimFrameMsec));
03493         stat_barp->setUnitLabel("ms");
03494         stat_barp->mPrecision = 1;
03495         stat_barp->mMinBar = 0.f;
03496         stat_barp->mMaxBar = 40.f;
03497         stat_barp->mTickSpacing = 10.f;
03498         stat_barp->mLabelSpacing = 20.f;
03499         stat_barp->mPerSec = FALSE;
03500         stat_barp->mDisplayBar = FALSE;
03501         stat_barp->mDisplayMean = FALSE;
03502 
03503         stat_barp = sim_time_viewp->addStat("Net Time", &(gViewerStats->mSimNetMsec));
03504         stat_barp->setUnitLabel("ms");
03505         stat_barp->mPrecision = 1;
03506         stat_barp->mMinBar = 0.f;
03507         stat_barp->mMaxBar = 40.f;
03508         stat_barp->mTickSpacing = 10.f;
03509         stat_barp->mLabelSpacing = 20.f;
03510         stat_barp->mPerSec = FALSE;
03511         stat_barp->mDisplayBar = FALSE;
03512         stat_barp->mDisplayMean = FALSE;
03513 
03514         stat_barp = sim_time_viewp->addStat("Sim Time (Physics)", &(gViewerStats->mSimSimPhysicsMsec));
03515         stat_barp->setUnitLabel("ms");
03516         stat_barp->mPrecision = 1;
03517         stat_barp->mMinBar = 0.f;
03518         stat_barp->mMaxBar = 40.f;
03519         stat_barp->mTickSpacing = 10.f;
03520         stat_barp->mLabelSpacing = 20.f;
03521         stat_barp->mPerSec = FALSE;
03522         stat_barp->mDisplayBar = FALSE;
03523         stat_barp->mDisplayMean = FALSE;
03524 
03525         stat_barp = sim_time_viewp->addStat("Sim Time (Other)", &(gViewerStats->mSimSimOtherMsec));
03526         stat_barp->setUnitLabel("ms");
03527         stat_barp->mPrecision = 1;
03528         stat_barp->mMinBar = 0.f;
03529         stat_barp->mMaxBar = 40.f;
03530         stat_barp->mTickSpacing = 10.f;
03531         stat_barp->mLabelSpacing = 20.f;
03532         stat_barp->mPerSec = FALSE;
03533         stat_barp->mDisplayBar = FALSE;
03534         stat_barp->mDisplayMean = FALSE;
03535 
03536         stat_barp = sim_time_viewp->addStat("Agent Time", &(gViewerStats->mSimAgentMsec));
03537         stat_barp->setUnitLabel("ms");
03538         stat_barp->mPrecision = 1;
03539         stat_barp->mMinBar = 0.f;
03540         stat_barp->mMaxBar = 40.f;
03541         stat_barp->mTickSpacing = 10.f;
03542         stat_barp->mLabelSpacing = 20.f;
03543         stat_barp->mPerSec = FALSE;
03544         stat_barp->mDisplayBar = FALSE;
03545         stat_barp->mDisplayMean = FALSE;
03546 
03547         stat_barp = sim_time_viewp->addStat("Images Time", &(gViewerStats->mSimImagesMsec));
03548         stat_barp->setUnitLabel("ms");
03549         stat_barp->mPrecision = 1;
03550         stat_barp->mMinBar = 0.f;
03551         stat_barp->mMaxBar = 40.f;
03552         stat_barp->mTickSpacing = 10.f;
03553         stat_barp->mLabelSpacing = 20.f;
03554         stat_barp->mPerSec = FALSE;
03555         stat_barp->mDisplayBar = FALSE;
03556         stat_barp->mDisplayMean = FALSE;
03557 
03558         stat_barp = sim_time_viewp->addStat("Script Time", &(gViewerStats->mSimScriptMsec));
03559         stat_barp->setUnitLabel("ms");
03560         stat_barp->mPrecision = 1;
03561         stat_barp->mMinBar = 0.f;
03562         stat_barp->mMaxBar = 40.f;
03563         stat_barp->mTickSpacing = 10.f;
03564         stat_barp->mLabelSpacing = 20.f;
03565         stat_barp->mPerSec = FALSE;
03566         stat_barp->mDisplayBar = FALSE;
03567         stat_barp->mDisplayMean = FALSE;
03568 
03569         LLRect r = gDebugView->mStatViewp->getRect();
03570 
03571         // Reshape based on the parameters we set.
03572         gDebugView->mStatViewp->reshape(r.getWidth(), r.getHeight());
03573 }
03574 
03575 void asset_callback_nothing(LLVFS*, const LLUUID&, LLAssetType::EType, void*, S32)
03576 {
03577         // nothing
03578 }
03579 
03580 // *HACK: Must match name in Library or agent inventory
03581 const char* COMMON_GESTURES_FOLDER = "Common Gestures";
03582 const char* MALE_GESTURES_FOLDER = "Male Gestures";
03583 const char* FEMALE_GESTURES_FOLDER = "Female Gestures";
03584 const char* MALE_OUTFIT_FOLDER = "Male Shape & Outfit";
03585 const char* FEMALE_OUTFIT_FOLDER = "Female Shape & Outfit";
03586 const S32 OPT_USE_INITIAL_OUTFIT = -2;
03587 const S32 OPT_CLOSED_WINDOW = -1;
03588 const S32 OPT_MALE = 0;
03589 const S32 OPT_FEMALE = 1;
03590 
03591 void callback_choose_gender(S32 option, void* userdata)
03592 {
03593         S32 gender = OPT_FEMALE;
03594         const char* outfit = FEMALE_OUTFIT_FOLDER;
03595         const char* gestures = FEMALE_GESTURES_FOLDER;
03596         const char* common_gestures = COMMON_GESTURES_FOLDER;
03597         if (!gInitialOutfit.empty())
03598         {
03599                 outfit = gInitialOutfit.c_str();
03600                 if (gInitialOutfitGender == "male")
03601                 {
03602                         gender = OPT_MALE;
03603                         gestures = MALE_GESTURES_FOLDER;
03604                 }
03605                 else
03606                 {
03607                         gender = OPT_FEMALE;
03608                         gestures = FEMALE_GESTURES_FOLDER;
03609                 }
03610         }
03611         else
03612         {
03613                 switch(option)
03614                 {
03615                 case OPT_MALE:
03616                         gender = OPT_MALE;
03617                         outfit = MALE_OUTFIT_FOLDER;
03618                         gestures = MALE_GESTURES_FOLDER;
03619                         break;
03620 
03621                 case OPT_FEMALE:
03622                 case OPT_CLOSED_WINDOW:
03623                 default:
03624                         gender = OPT_FEMALE;
03625                         outfit = FEMALE_OUTFIT_FOLDER;
03626                         gestures = FEMALE_GESTURES_FOLDER;
03627                         break;
03628                 }
03629         }
03630 
03631         // try to find the outfit - if not there, create some default
03632         // wearables.
03633         LLInventoryModel::cat_array_t cat_array;
03634         LLInventoryModel::item_array_t item_array;
03635         LLNameCategoryCollector has_name(outfit);
03636         gInventory.collectDescendentsIf(LLUUID::null,
03637                                                                         cat_array,
03638                                                                         item_array,
03639                                                                         LLInventoryModel::EXCLUDE_TRASH,
03640                                                                         has_name);
03641         if (0 == cat_array.count())
03642         {
03643                 gAgent.createStandardWearables(gender);
03644         }
03645         else
03646         {
03647                 wear_outfit_by_name(outfit);
03648         }
03649         wear_outfit_by_name(gestures);
03650         wear_outfit_by_name(common_gestures);
03651 
03652         typedef std::map<LLUUID, LLMultiGesture*> item_map_t;
03653         item_map_t::iterator gestureIterator;
03654 
03655         // Must be here so they aren't invisible if they close the window.
03656         gAgent.setGenderChosen(TRUE);
03657 }
03658 
03659 void dialog_choose_gender_first_start()
03660 {
03661         if (!gNoRender
03662                 && (!gAgent.isGenderChosen()))
03663         {
03664                 if (!gInitialOutfit.empty())
03665                 {
03666                         gViewerWindow->alertXml("WelcomeNoClothes",
03667                                 callback_choose_gender, NULL);
03668                 }
03669                 else
03670                 {       
03671                         gViewerWindow->alertXml("WelcomeChooseSex",
03672                                 callback_choose_gender, NULL);
03673                         
03674                 }
03675         }
03676 }
03677 
03678 // Loads a bitmap to display during load
03679 // location_id = 0 => last position
03680 // location_id = 1 => home position
03681 void init_start_screen(S32 location_id)
03682 {
03683         if (gStartImageGL.notNull())
03684         {
03685                 gStartImageGL = NULL;
03686                 llinfos << "re-initializing start screen" << llendl;
03687         }
03688 
03689         llinfos << "Loading startup bitmap..." << llendl;
03690 
03691         LLString temp_str = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter();
03692 
03693         if ((S32)START_LOCATION_ID_LAST == location_id)
03694         {
03695                 temp_str += SCREEN_LAST_FILENAME;
03696         }
03697         else
03698         {
03699                 temp_str += SCREEN_HOME_FILENAME;
03700         }
03701 
03702         LLPointer<LLImageBMP> start_image_bmp = new LLImageBMP;
03703         if( !start_image_bmp->load(temp_str) )
03704         {
03705                 llinfos << "Bitmap load failed" << llendl;
03706                 return;
03707         }
03708 
03709         gStartImageGL = new LLImageGL(FALSE);
03710         gStartImageWidth = start_image_bmp->getWidth();
03711         gStartImageHeight = start_image_bmp->getHeight();
03712         LLPointer<LLImageRaw> raw = new LLImageRaw;
03713         if (!start_image_bmp->decode(raw))
03714         {
03715                 llinfos << "Bitmap decode failed" << llendl;
03716                 gStartImageGL = NULL;
03717                 return;
03718         }
03719 
03720         raw->expandToPowerOfTwo();
03721         gStartImageGL->createGLTexture(0, raw);
03722 }
03723 
03724 
03725 // frees the bitmap
03726 void release_start_screen()
03727 {
03728         //llinfos << "Releasing bitmap..." << llendl;
03729         gStartImageGL = NULL;
03730 }
03731 
03732 
03733 // static
03734 void LLStartUp::setStartupState( S32 state )
03735 {
03736         llinfos << "Startup state changing from " << gStartupState << " to " << state << llendl;
03737         gStartupState = state;
03738 }
03739 
03740 
03741 void reset_login()
03742 {
03743         LLStartUp::setStartupState( STATE_LOGIN_SHOW );
03744 
03745         if ( gViewerWindow )
03746         {       // Hide menus and normal buttons
03747                 gViewerWindow->setNormalControlsVisible( FALSE );
03748         }
03749 
03750         // Hide any other stuff
03751         if ( gFloaterMap )
03752                 gFloaterMap->setVisible( FALSE );
03753 }
03754 
03755 //---------------------------------------------------------------------------
03756 
03757 std::string LLStartUp::sSLURLCommand;
03758 
03759 bool LLStartUp::canGoFullscreen()
03760 {
03761         return gStartupState >= STATE_WORLD_INIT;
03762 }
03763 
03764 bool LLStartUp::dispatchURL()
03765 {
03766         // ok, if we've gotten this far and have a startup URL
03767         if (!sSLURLCommand.empty())
03768         {
03769                 LLURLDispatcher::dispatch(sSLURLCommand);
03770         }
03771         else if (LLURLSimString::parse())
03772         {
03773                 // If we started with a location, but we're already
03774                 // at that location, don't pop dialogs open.
03775                 LLVector3 pos = gAgent.getPositionAgent();
03776                 F32 dx = pos.mV[VX] - (F32)LLURLSimString::sInstance.mX;
03777                 F32 dy = pos.mV[VY] - (F32)LLURLSimString::sInstance.mY;
03778                 const F32 SLOP = 2.f;   // meters
03779 
03780                 if( LLURLSimString::sInstance.mSimName != gAgent.getRegion()->getName()
03781                         || (dx*dx > SLOP*SLOP)
03782                         || (dy*dy > SLOP*SLOP) )
03783                 {
03784                         std::string url = LLURLSimString::getURL();
03785                         LLURLDispatcher::dispatch(url);
03786                 }
03787                 return true;
03788         }
03789         return false;
03790 }

Generated on Thu Jul 1 06:09:13 2010 for Second Life Viewer by  doxygen 1.4.7