diff options
Diffstat (limited to 'indra/newview/llstartup.cpp')
-rw-r--r-- | indra/newview/llstartup.cpp | 548 |
1 files changed, 407 insertions, 141 deletions
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 4dfcb85295..0ac8c1fe39 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -126,11 +126,11 @@ #include "llpanelgroupnotices.h" #include "llpreview.h" #include "llpreviewscript.h" +#include "llproxy.h" #include "llproductinforequest.h" #include "llsecondlifeurls.h" #include "llselectmgr.h" #include "llsky.h" -#include "llsidetray.h" #include "llstatview.h" #include "llstatusbar.h" // sendMoneyBalanceRequest(), owns L$ balance #include "llsurface.h" @@ -190,6 +190,7 @@ #include "lllogin.h" #include "llevents.h" #include "llstartuplistener.h" +#include "lltoolbarview.h" #if LL_WINDOWS #include "lldxhardware.h" @@ -366,7 +367,9 @@ bool idle_startup() // // Initialize stuff that doesn't need data from simulators // - + std::string lastGPU = gSavedSettings.getString("LastGPUString"); + std::string thisGPU = LLFeatureManager::getInstance()->getGPUString(); + if (LLFeatureManager::getInstance()->isSafe()) { LLNotificationsUtil::add("DisplaySetToSafe"); @@ -374,20 +377,30 @@ bool idle_startup() else if ((gSavedSettings.getS32("LastFeatureVersion") < LLFeatureManager::getInstance()->getVersion()) && (gSavedSettings.getS32("LastFeatureVersion") != 0)) { - LLNotificationsUtil::add("DisplaySetToRecommended"); + LLNotificationsUtil::add("DisplaySetToRecommendedFeatureChange"); } - else if ((gSavedSettings.getS32("LastGPUClass") != LLFeatureManager::getInstance()->getGPUClass()) && - (gSavedSettings.getS32("LastGPUClass") != -1)) + else if ( ! lastGPU.empty() && (lastGPU != thisGPU)) { - LLNotificationsUtil::add("DisplaySetToRecommended"); + LLSD subs; + subs["LAST_GPU"] = lastGPU; + subs["THIS_GPU"] = thisGPU; + LLNotificationsUtil::add("DisplaySetToRecommendedGPUChange", subs); } else if (!gViewerWindow->getInitAlert().empty()) { LLNotificationsUtil::add(gViewerWindow->getInitAlert()); } + //------------------------------------------------- + // Init the SOCKS 5 proxy if the user has configured + // one. We need to do this early in case the user + // is using SOCKS for HTTP so we get the login + // screen and HTTP tables via SOCKS. + //------------------------------------------------- + LLStartUp::startLLProxy(); + gSavedSettings.setS32("LastFeatureVersion", LLFeatureManager::getInstance()->getVersion()); - gSavedSettings.setS32("LastGPUClass", LLFeatureManager::getInstance()->getGPUClass()); + gSavedSettings.setString("LastGPUString", thisGPU); // load dynamic GPU/feature tables from website (S3) LLFeatureManager::getInstance()->fetchHTTPTables(); @@ -591,7 +604,7 @@ bool idle_startup() } LL_INFOS("AppInit") << "Message System Initialized." << LL_ENDL; - + //------------------------------------------------- // Init audio, which may be needed for prefs dialog // or audio cues in connection UI. @@ -720,7 +733,16 @@ bool idle_startup() timeout_count = 0; - initialize_edit_menu(); + // Login screen needs menus for preferences, but we can enter + // this startup phase more than once. + if (gLoginMenuBarView == NULL) + { + display_startup(); + initialize_edit_menu(); + display_startup(); + init_menus(); + display_startup(); + } if (show_connect_box) { @@ -728,23 +750,28 @@ bool idle_startup() // NOTE: Hits "Attempted getFields with no login view shown" warning, since we don't // show the login view until login_show() is called below. if (gUserCredential.isNull()) - { + { + display_startup(); gUserCredential = gLoginHandler.initializeLoginInfo(); + display_startup(); } if (gHeadlessClient) { LL_WARNS("AppInit") << "Waiting at connection box in headless client. Did you mean to add autologin params?" << LL_ENDL; } // Make sure the process dialog doesn't hide things + display_startup(); gViewerWindow->setShowProgress(FALSE); - + display_startup(); // Show the login dialog login_show(); + display_startup(); // connect dialog is already shown, so fill in the names if (gUserCredential.notNull()) { LLPanelLogin::setFields( gUserCredential, gRememberPassword); } + display_startup(); LLPanelLogin::giveFocus(); LLStartUp::setStartupState( STATE_LOGIN_WAIT ); // Wait for user input @@ -755,27 +782,19 @@ bool idle_startup() LLStartUp::setStartupState( STATE_LOGIN_CLEANUP ); } - // *NOTE: This is where LLViewerParcelMgr::getInstance() used to get allocated before becoming LLViewerParcelMgr::getInstance(). - - // *NOTE: This is where gHUDManager used to bet allocated before becoming LLHUDManager::getInstance(). - - // *NOTE: This is where gMuteList used to get allocated before becoming LLMuteList::getInstance(). - - // Login screen needs menus for preferences, but we can enter - // this startup phase more than once. - if (gLoginMenuBarView == NULL) - { - init_menus(); - } - + display_startup(); gViewerWindow->setNormalControlsVisible( FALSE ); + display_startup(); gLoginMenuBarView->setVisible( TRUE ); + display_startup(); gLoginMenuBarView->setEnabled( TRUE ); + display_startup(); show_debug_menus(); + display_startup(); // Hide the splash screen LLSplashScreen::hide(); - + display_startup(); // Push our window frontmost gViewerWindow->getWindow()->show(); display_startup(); @@ -784,7 +803,9 @@ bool idle_startup() // first made visible. #ifdef _WIN32 MSG msg; - while( PeekMessage( &msg, /*All hWnds owned by this thread */ NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE ) ); + while( PeekMessage( &msg, /*All hWnds owned by this thread */ NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE ) ) + { } + display_startup(); #endif timeout.reset(); return FALSE; @@ -799,7 +820,7 @@ bool idle_startup() // Don't do anything. Wait for the login view to call the login_callback, // which will push us to the next state. - + display_startup(); // Sleep so we don't spin the CPU ms_sleep(1); return FALSE; @@ -807,7 +828,21 @@ bool idle_startup() if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState()) { - //reset the values that could have come in from a slurl + // Post login screen, we should see if any settings have changed that may + // require us to either start/stop or change the socks proxy. As various communications + // past this point may require the proxy to be up. + if (!LLStartUp::startLLProxy()) + { + // Proxy start up failed, we should now bail the state machine + // startLLProxy() will have reported an error to the user + // already, so we just go back to the login screen. The user + // could then change the preferences to fix the issue. + + LLStartUp::setStartupState(STATE_LOGIN_SHOW); + return FALSE; + } + + // reset the values that could have come in from a slurl // DEV-42215: Make sure they're not empty -- gUserCredential // might already have been set from gSavedSettings, and it's too bad // to overwrite valid values with empty strings. @@ -845,7 +880,6 @@ bool idle_startup() LLFile::mkdir(gDirUtilp->getLindenUserDir()); // Set PerAccountSettingsFile to the default value. - std::string per_account_settings_file = LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount"); gSavedSettings.setString("PerAccountSettingsFile", gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount"))); @@ -897,7 +931,7 @@ bool idle_startup() if (show_connect_box) { LLSLURL slurl; - LLPanelLogin::closePanel(); + //LLPanelLogin::closePanel(); } @@ -944,6 +978,8 @@ bool idle_startup() gViewerWindow->setShowProgress(TRUE); gViewerWindow->setProgressCancelButtonVisible(TRUE, LLTrans::getString("Quit")); + gViewerWindow->revealIntroPanel(); + // Poke the VFS, which could potentially block for a while if // Windows XP is acting up set_startup_status(0.07f, LLTrans::getString("LoginVerifyingCache"), LLStringUtil::null); @@ -1151,37 +1187,51 @@ bool idle_startup() // Finish agent initialization. (Requires gSavedSettings, builds camera) gAgent.init(); + display_startup(); gAgentCamera.init(); + display_startup(); set_underclothes_menu_options(); + display_startup(); // Since we connected, save off the settings so the user doesn't have to // type the name/password again if we crash. gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE); LLUIColorTable::instance().saveUserSettings(); + display_startup(); + // // Initialize classes w/graphics stuff. // gTextureList.doPrefetchImages(); + display_startup(); + LLSurface::initClasses(); + display_startup(); + LLFace::initClass(); + display_startup(); LLDrawable::initClass(); + display_startup(); // init the shader managers LLPostProcess::initClass(); + display_startup(); LLViewerObject::initVOClasses(); + display_startup(); // Initialize all our tools. Must be done after saved settings loaded. // NOTE: This also is where gToolMgr used to be instantiated before being turned into a singleton. LLToolMgr::getInstance()->initTools(); + display_startup(); // Pre-load floaters, like the world map, that are slow to spawn // due to XML complexity. gViewerWindow->initWorldUI(); - + display_startup(); // This is where we used to initialize gWorldp. Original comment said: @@ -1189,24 +1239,26 @@ bool idle_startup() // User might have overridden far clip LLWorld::getInstance()->setLandFarClip(gAgentCamera.mDrawDistance); - + display_startup(); // Before we create the first region, we need to set the agent's mOriginGlobal // This is necessary because creating objects before this is set will result in a // bad mPositionAgent cache. gAgent.initOriginGlobal(from_region_handle(gFirstSimHandle)); + display_startup(); LLWorld::getInstance()->addRegion(gFirstSimHandle, gFirstSim); + display_startup(); LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(gFirstSimHandle); LL_INFOS("AppInit") << "Adding initial simulator " << regionp->getOriginGlobal() << LL_ENDL; regionp->setSeedCapability(gFirstSimSeedCap); LL_DEBUGS("AppInit") << "Waiting for seed grant ...." << LL_ENDL; - + display_startup(); // Set agent's initial region to be the one we just created. gAgent.setRegion(regionp); - + display_startup(); // Set agent's initial position, which will be read by LLVOAvatar when the avatar // object is created. I think this must be done after setting the region. JC gAgent.setPositionAgent(agent_start_position_region); @@ -1226,6 +1278,7 @@ bool idle_startup() { LLStartUp::multimediaInit(); LLStartUp::setStartupState( STATE_FONT_INIT ); + display_startup(); return FALSE; } @@ -1234,6 +1287,7 @@ bool idle_startup() { LLStartUp::fontInit(); LLStartUp::setStartupState( STATE_SEED_GRANTED_WAIT ); + display_startup(); return FALSE; } @@ -1242,6 +1296,26 @@ bool idle_startup() //--------------------------------------------------------------------- if(STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState()) { + LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(gFirstSimHandle); + if (regionp->capabilitiesReceived()) + { + LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED ); + } + else + { + U32 num_retries = regionp->getNumSeedCapRetries(); + if (num_retries > 0) + { + LLStringUtil::format_map_t args; + args["[NUMBER]"] = llformat("%d", num_retries + 1); + set_startup_status(0.4f, LLTrans::getString("LoginRetrySeedCapGrant", args), gAgent.mMOTD); + } + else + { + set_startup_status(0.4f, LLTrans::getString("LoginRequestSeedCapGrant"), gAgent.mMOTD); + } + } + display_startup(); return FALSE; } @@ -1252,7 +1326,9 @@ bool idle_startup() //--------------------------------------------------------------------- if (STATE_SEED_CAP_GRANTED == LLStartUp::getStartupState()) { + display_startup(); update_texture_fetch(); + display_startup(); if ( gViewerWindow != NULL) { // This isn't the first logon attempt, so show the UI @@ -1260,12 +1336,15 @@ bool idle_startup() } gLoginMenuBarView->setVisible( FALSE ); gLoginMenuBarView->setEnabled( FALSE ); + display_startup(); // direct logging to the debug console's line buffer LLError::logToFixedBuffer(gDebugView->mDebugConsolep); + display_startup(); // set initial visibility of debug console gDebugView->mDebugConsolep->setVisible(gSavedSettings.getBOOL("ShowDebugConsole")); + display_startup(); // // Set message handlers @@ -1274,22 +1353,28 @@ bool idle_startup() // register callbacks for messages. . . do this after initial handshake to make sure that we don't catch any unwanted register_viewer_callbacks(gMessageSystem); + display_startup(); // Debugging info parameters gMessageSystem->setMaxMessageTime( 0.5f ); // Spam if decoding all msgs takes more than 500 ms + display_startup(); #ifndef LL_RELEASE_FOR_DOWNLOAD gMessageSystem->setTimeDecodes( TRUE ); // Time the decode of each msg gMessageSystem->setTimeDecodesSpamThreshold( 0.05f ); // Spam if a single msg takes over 50ms to decode #endif + display_startup(); gXferManager->registerCallbacks(gMessageSystem); + display_startup(); LLStartUp::initNameCache(); + display_startup(); // update the voice settings *after* gCacheName initialization // so that we can construct voice UI that relies on the name cache LLVoiceClient::getInstance()->updateSettings(); + display_startup(); //gCacheName is required for nearby chat history loading //so I just moved nearby history loading a few states further @@ -1298,12 +1383,14 @@ bool idle_startup() LLNearbyChat* nearby_chat = LLNearbyChat::getInstance(); if (nearby_chat) nearby_chat->loadHistory(); } + display_startup(); // *Note: this is where gWorldMap used to be initialized. // register null callbacks for audio until the audio system is initialized gMessageSystem->setHandlerFuncFast(_PREHASH_SoundTrigger, null_message_callback, NULL); gMessageSystem->setHandlerFuncFast(_PREHASH_AttachedSound, null_message_callback, NULL); + display_startup(); //reset statistics LLViewerStats::getInstance()->resetStats(); @@ -1333,6 +1420,7 @@ bool idle_startup() LLViewerCamera::getInstance()->setAspect(gViewerWindow->getWorldViewAspectRatio()); // Initialize FOV LLViewerCamera::getInstance()->setDefaultFOV(gSavedSettings.getF32("CameraAngle")); + display_startup(); // Move agent to starting location. The position handed to us by // the space server is in global coordinates, but the agent frame @@ -1343,6 +1431,7 @@ bool idle_startup() gAgent.resetAxes(gAgentStartLookAt); gAgentCamera.stopCameraAnimation(); gAgentCamera.resetCamera(); + display_startup(); // Initialize global class data needed for surfaces (i.e. textures) LL_DEBUGS("AppInit") << "Initializing sky..." << LL_ENDL; @@ -1355,6 +1444,8 @@ bool idle_startup() LLGLState::checkStates(); LLGLState::checkTextureChannels(); + display_startup(); + LL_DEBUGS("AppInit") << "Decoding images..." << LL_ENDL; // For all images pre-loaded into viewer cache, decode them. // Need to do this AFTER we init the sky @@ -1368,6 +1459,8 @@ bool idle_startup() } LLStartUp::setStartupState( STATE_WORLD_WAIT ); + display_startup(); + // JC - Do this as late as possible to increase likelihood Purify // will run. LLMessageSystem* msg = gMessageSystem; @@ -1395,6 +1488,7 @@ bool idle_startup() NULL); timeout.reset(); + display_startup(); return FALSE; } @@ -1413,8 +1507,10 @@ bool idle_startup() LLMessageSystem* msg = gMessageSystem; while (msg->checkAllMessages(gFrameCount, gServicePump)) { + display_startup(); } msg->processAcks(); + display_startup(); return FALSE; } @@ -1425,6 +1521,7 @@ bool idle_startup() { LL_DEBUGS("AppInit") << "Connecting to region..." << LL_ENDL; set_startup_status(0.60f, LLTrans::getString("LoginConnectingToRegion"), gAgent.mMOTD); + display_startup(); // register with the message system so it knows we're // expecting this message LLMessageSystem* msg = gMessageSystem; @@ -1440,6 +1537,7 @@ bool idle_startup() msg->newMessageFast(_PREHASH_EconomyDataRequest); gAgent.sendReliableMessage(); } + display_startup(); // Create login effect // But not on first login, because you can't see your avatar then @@ -1454,6 +1552,7 @@ bool idle_startup() LLStartUp::setStartupState( STATE_AGENT_WAIT ); // Go to STATE_AGENT_WAIT timeout.reset(); + display_startup(); return FALSE; } @@ -1478,14 +1577,17 @@ bool idle_startup() LL_DEBUGS("AppInit") << "Awaiting AvatarInitComplete, got " << msg->getMessageName() << LL_ENDL; } + display_startup(); } msg->processAcks(); + display_startup(); + if (gAgentMovementCompleted) { LLStartUp::setStartupState( STATE_INVENTORY_SEND ); } - + display_startup(); return FALSE; } @@ -1494,9 +1596,10 @@ bool idle_startup() //--------------------------------------------------------------------- if (STATE_INVENTORY_SEND == LLStartUp::getStartupState()) { + display_startup(); // Inform simulator of our language preference LLAgentLanguage::update(); - + display_startup(); // unpack thin inventory LLSD response = LLLoginInstance::getInstance()->getResponse(); //bool dump_buffer = false; @@ -1511,6 +1614,7 @@ bool idle_startup() gInventory.setLibraryRootFolderID(id.asUUID()); } } + display_startup(); LLSD inv_lib_owner = response["inventory-lib-owner"]; if(inv_lib_owner.isDefined()) @@ -1522,6 +1626,7 @@ bool idle_startup() gInventory.setLibraryOwnerID( LLUUID(id.asUUID())); } } + display_startup(); LLSD inv_skel_lib = response["inventory-skel-lib"]; if(inv_skel_lib.isDefined() && gInventory.getLibraryOwnerID().notNull()) @@ -1531,6 +1636,7 @@ bool idle_startup() LL_WARNS("AppInit") << "Problem loading inventory-skel-lib" << LL_ENDL; } } + display_startup(); LLSD inv_skeleton = response["inventory-skeleton"]; if(inv_skeleton.isDefined()) @@ -1540,6 +1646,13 @@ bool idle_startup() LL_WARNS("AppInit") << "Problem loading inventory-skel-targets" << LL_ENDL; } } + display_startup(); + + LLSD inv_basic = response["inventory-basic"]; + if(inv_basic.isDefined()) + { + llinfos << "Basic inventory root folder id is " << inv_basic["folder_id"] << llendl; + } LLSD buddy_list = response["buddy-list"]; if(buddy_list.isDefined()) @@ -1571,6 +1684,7 @@ bool idle_startup() list[agent_id] = new LLRelationship(given_rights, has_rights, false); } LLAvatarTracker::instance().addBuddyList(list); + display_startup(); } bool show_hud = false; @@ -1598,6 +1712,8 @@ bool idle_startup() //} } } + display_startup(); + // Either we want to show tutorial because this is the first login // to a Linden Help Island or the user quit with the tutorial // visible. JC @@ -1605,22 +1721,26 @@ bool idle_startup() { LLFloaterReg::showInstance("hud", LLSD(), FALSE); } + display_startup(); LLSD event_notifications = response["event_notifications"]; if(event_notifications.isDefined()) { gEventNotifier.load(event_notifications); } + display_startup(); LLSD classified_categories = response["classified_categories"]; if(classified_categories.isDefined()) { LLClassifiedInfo::loadCategories(classified_categories); } + display_startup(); // This method MUST be called before gInventory.findCategoryUUIDForType because of // gInventory.mIsAgentInvUsable is set to true in the gInventory.buildParentChildMap. gInventory.buildParentChildMap(); + display_startup(); //all categories loaded. lets create "My Favorites" category gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE,true); @@ -1634,24 +1754,26 @@ bool idle_startup() LLAvatarTracker::instance().registerCallbacks(msg); llinfos << " Landmark" << llendl; LLLandmark::registerCallbacks(msg); + display_startup(); // request mute list llinfos << "Requesting Mute List" << llendl; LLMuteList::getInstance()->requestFromServer(gAgent.getID()); - + display_startup(); // Get L$ and ownership credit information llinfos << "Requesting Money Balance" << llendl; LLStatusBar::sendMoneyBalanceRequest(); - + display_startup(); // request all group information llinfos << "Requesting Agent Data" << llendl; gAgent.sendAgentDataUpdateRequest(); - + display_startup(); // Create the inventory views llinfos << "Creating Inventory Views" << llendl; LLFloaterReg::getInstance("inventory"); - + display_startup(); LLStartUp::setStartupState( STATE_MISC ); + display_startup(); return FALSE; } @@ -1700,17 +1822,23 @@ bool idle_startup() gSavedSettings.setBOOL("ShowStartLocation", TRUE); } + display_startup(); + if (gSavedSettings.getBOOL("HelpFloaterOpen")) { // show default topic LLViewerHelp::instance().showTopic(""); } + display_startup(); + // We're successfully logged in. gSavedSettings.setBOOL("FirstLoginThisInstall", FALSE); LLFloaterReg::showInitialVisibleInstances(); + display_startup(); + // based on the comments, we've successfully logged in so we can delete the 'forced' // URL that the updater set in settings.ini (in a mostly paranoid fashion) std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" ); @@ -1724,8 +1852,10 @@ bool idle_startup() LLUIColorTable::instance().saveUserSettings(); }; + display_startup(); // JC: Initializing audio requests many sounds for download. init_audio(); + display_startup(); // JC: Initialize "active" gestures. This may also trigger // many gesture downloads, if this is the user's first @@ -1763,6 +1893,7 @@ bool idle_startup() LLGestureMgr::instance().startFetch(); } gDisplaySwapBuffers = TRUE; + display_startup(); LLMessageSystem* msg = gMessageSystem; msg->setHandlerFuncFast(_PREHASH_SoundTrigger, process_sound_trigger); @@ -1837,8 +1968,10 @@ bool idle_startup() } } + display_startup(); //DEV-17797. get null folder. Any items found here moved to Lost and Found LLInventoryModelBackgroundFetch::instance().findLostItems(); + display_startup(); LLStartUp::setStartupState( STATE_PRECACHE ); timeout.reset(); @@ -1847,6 +1980,7 @@ bool idle_startup() if (STATE_PRECACHE == LLStartUp::getStartupState()) { + display_startup(); F32 timeout_frac = timeout.getElapsedTimeF32()/PRECACHING_DELAY; // We now have an inventory skeleton, so if this is a user's first @@ -1863,6 +1997,8 @@ bool idle_startup() LLStartUp::loadInitialOutfit( sInitialOutfit, sInitialOutfitGender ); } + display_startup(); + // wait precache-delay and for agent's avatar or a lot longer. if(((timeout_frac > 1.f) && isAgentAvatarValid()) || (timeout_frac > 3.f)) @@ -1876,11 +2012,6 @@ bool idle_startup() LLTrans::getString("LoginPrecaching"), gAgent.mMOTD); display_startup(); - if (!LLViewerShaderMgr::sInitialized) - { - LLViewerShaderMgr::sInitialized = TRUE; - LLViewerShaderMgr::instance()->setShaders(); - } } return TRUE; @@ -1893,7 +2024,7 @@ bool idle_startup() const F32 wearables_time = wearables_timer.getElapsedTimeF32(); const F32 MAX_WEARABLES_TIME = 10.f; - if (!gAgent.isGenderChosen()) + if (!gAgent.isGenderChosen() && isAgentAvatarValid()) { // No point in waiting for clothing, we don't even // know what gender we are. Pop a dialog to ask and @@ -1909,6 +2040,8 @@ bool idle_startup() return TRUE; } + display_startup(); + if (wearables_time > MAX_WEARABLES_TIME) { LLNotificationsUtil::add("ClothingLoading"); @@ -1940,16 +2073,20 @@ bool idle_startup() } } + display_startup(); update_texture_fetch(); + display_startup(); set_startup_status(0.9f + 0.1f * wearables_time / MAX_WEARABLES_TIME, LLTrans::getString("LoginDownloadingClothing").c_str(), gAgent.mMOTD.c_str()); + display_startup(); return TRUE; } if (STATE_CLEANUP == LLStartUp::getStartupState()) { set_startup_status(1.0, "", ""); + display_startup(); // Let the map know about the inventory. LLFloaterWorldMap* floater_world_map = LLFloaterWorldMap::getInstance(); @@ -1962,9 +2099,10 @@ bool idle_startup() gViewerWindow->getWindow()->resetBusyCount(); gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW); LL_DEBUGS("AppInit") << "Done releasing bitmap" << LL_ENDL; - gViewerWindow->revealIntroPanel(); - //gViewerWindow->setShowProgress(FALSE); // reveal intro video now handles this + //gViewerWindow->revealIntroPanel(); + gViewerWindow->setStartupComplete(); gViewerWindow->setProgressCancelButtonVisible(FALSE); + display_startup(); // We're not away from keyboard, even though login might have taken // a while. JC @@ -1987,7 +2125,7 @@ bool idle_startup() show_debug_menus(); // Debug menu visiblity and First Use trigger // If we've got a startup URL, dispatch it - LLStartUp::dispatchURL(); + //LLStartUp::dispatchURL(); // Retrieve information about the land data // (just accessing this the first time will fetch it, @@ -2000,6 +2138,7 @@ bool idle_startup() // LLUserAuth::getInstance()->reset(); LLStartUp::setStartupState( STATE_STARTED ); + display_startup(); // Unmute audio if desired and setup volumes. // Unmute audio if desired and setup volumes. @@ -2024,6 +2163,7 @@ bool idle_startup() LLAgentPicksInfo::getInstance()->requestNumberOfPicks(); LLIMFloater::initIMFloater(); + display_startup(); return TRUE; } @@ -2045,7 +2185,12 @@ void login_show() #else BOOL bUseDebugLogin = TRUE; #endif - + // Hide the toolbars: may happen to come back here if login fails after login agent but before login in region + if (gToolBarView) + { + gToolBarView->setVisible(FALSE); + } + LLPanelLogin::show( gViewerWindow->getWindowRectScaled(), bUseDebugLogin || gSavedSettings.getBOOL("SecondLifeEnterprise"), login_callback, NULL ); @@ -2344,13 +2489,6 @@ void asset_callback_nothing(LLVFS*, const LLUUID&, LLAssetType::EType, void*, S3 // nothing } -// *HACK: Must match name in Library or agent inventory -const std::string ROOT_GESTURES_FOLDER = "Gestures"; -const std::string COMMON_GESTURES_FOLDER = "Common Gestures"; -const std::string MALE_GESTURES_FOLDER = "Male Gestures"; -const std::string FEMALE_GESTURES_FOLDER = "Female Gestures"; -const std::string SPEECH_GESTURES_FOLDER = "Speech Gestures"; -const std::string OTHER_GESTURES_FOLDER = "Other Gestures"; const S32 OPT_CLOSED_WINDOW = -1; const S32 OPT_MALE = 0; const S32 OPT_FEMALE = 1; @@ -2379,84 +2517,36 @@ bool callback_choose_gender(const LLSD& notification, const LLSD& response) return false; } -void LLStartUp::copyLibraryGestures(const std::string& same_gender_gestures) -{ - llinfos << "Copying library gestures" << llendl; - - // Copy gestures - LLUUID lib_gesture_cat_id = - gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE,false,true); - if (lib_gesture_cat_id.isNull()) - { - llwarns << "Unable to copy gestures, source category not found" << llendl; - } - LLUUID dst_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE); - - std::vector<std::string> gesture_folders_to_copy; - gesture_folders_to_copy.push_back(MALE_GESTURES_FOLDER); - gesture_folders_to_copy.push_back(FEMALE_GESTURES_FOLDER); - gesture_folders_to_copy.push_back(COMMON_GESTURES_FOLDER); - gesture_folders_to_copy.push_back(SPEECH_GESTURES_FOLDER); - gesture_folders_to_copy.push_back(OTHER_GESTURES_FOLDER); - - for(std::vector<std::string>::iterator it = gesture_folders_to_copy.begin(); - it != gesture_folders_to_copy.end(); - ++it) - { - std::string& folder_name = *it; - - LLPointer<LLInventoryCallback> cb(NULL); - - if (folder_name == same_gender_gestures || - folder_name == COMMON_GESTURES_FOLDER || - folder_name == OTHER_GESTURES_FOLDER) - { - cb = new ActivateGestureCallback; - } - - - LLUUID cat_id = findDescendentCategoryIDByName(lib_gesture_cat_id,folder_name); - if (cat_id.isNull()) - { - llwarns << "failed to find gesture folder for " << folder_name << llendl; - } - else - { - llinfos << "initiating fetch and copy for " << folder_name << " cat_id " << cat_id << llendl; - LLAppearanceMgr* app_mgr = LLAppearanceMgr::getInstance(); - callAfterCategoryFetch(cat_id, - boost::bind(&LLAppearanceMgr::shallowCopyCategory, - app_mgr, - cat_id, - dst_id, - cb)); - } - } -} - void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name, const std::string& gender_name ) { - llinfos << "starting" << llendl; + lldebugs << "starting" << llendl; // Not going through the processAgentInitialWearables path, so need to set this here. LLAppearanceMgr::instance().setAttachmentInvLinkEnable(true); // Initiate creation of COF, since we're also bypassing that. gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); - S32 gender = 0; - std::string same_gender_gestures; + ESex gender; if (gender_name == "male") { - gender = OPT_MALE; - same_gender_gestures = MALE_GESTURES_FOLDER; + lldebugs << "male" << llendl; + gender = SEX_MALE; } else { - gender = OPT_FEMALE; - same_gender_gestures = FEMALE_GESTURES_FOLDER; + lldebugs << "female" << llendl; + gender = SEX_FEMALE; } + if (!isAgentAvatarValid()) + { + llwarns << "Trying to load an initial outfit for an invalid agent avatar" << llendl; + return; + } + + gAgentAvatarp->setSex(gender); + // try to find the outfit - if not there, create some default // wearables. LLUUID cat_id = findDescendentCategoryIDByName( @@ -2464,7 +2554,8 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name, outfit_folder_name); if (cat_id.isNull()) { - gAgentWearables.createStandardWearables(gender); + lldebugs << "standard wearables" << llendl; + gAgentWearables.createStandardWearables(); } else { @@ -2474,26 +2565,28 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name, bool do_append = false; LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id); LLAppearanceMgr::instance().wearInventoryCategory(cat, do_copy, do_append); + lldebugs << "initial outfit category id: " << cat_id << llendl; } - // Copy gestures - copyLibraryGestures(same_gender_gestures); - // This is really misnamed -- it means we have started loading // an outfit/shape that will give the avatar a gender eventually. JC gAgent.setGenderChosen(TRUE); - } //static void LLStartUp::saveInitialOutfit() { - if (sInitialOutfit.empty()) return; + if (sInitialOutfit.empty()) { + lldebugs << "sInitialOutfit is empty" << llendl; + return; + } if (sWearablesLoadedCon.connected()) { + lldebugs << "sWearablesLoadedCon is connected, disconnecting" << llendl; sWearablesLoadedCon.disconnect(); } + lldebugs << "calling makeNewOutfitLinks( \"" << sInitialOutfit << "\" )" << llendl; LLAppearanceMgr::getInstance()->makeNewOutfitLinks(sInitialOutfit,false); } @@ -2536,22 +2629,32 @@ void init_start_screen(S32 location_id) else if(!start_image_bmp->load(temp_str) ) { LL_WARNS("AppInit") << "Bitmap load failed" << LL_ENDL; - return; + gStartTexture = NULL; } + else + { + gStartImageWidth = start_image_bmp->getWidth(); + gStartImageHeight = start_image_bmp->getHeight(); - gStartImageWidth = start_image_bmp->getWidth(); - gStartImageHeight = start_image_bmp->getHeight(); + LLPointer<LLImageRaw> raw = new LLImageRaw; + if (!start_image_bmp->decode(raw, 0.0f)) + { + LL_WARNS("AppInit") << "Bitmap decode failed" << LL_ENDL; + gStartTexture = NULL; + } + else + { + raw->expandToPowerOfTwo(); + gStartTexture = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE) ; + } + } - LLPointer<LLImageRaw> raw = new LLImageRaw; - if (!start_image_bmp->decode(raw, 0.0f)) + if(gStartTexture.isNull()) { - LL_WARNS("AppInit") << "Bitmap decode failed" << LL_ENDL; - gStartTexture = NULL; - return; + gStartTexture = LLViewerTexture::sBlackImagep ; + gStartImageWidth = gStartTexture->getWidth() ; + gStartImageHeight = gStartTexture->getHeight() ; } - - raw->expandToPowerOfTwo(); - gStartTexture = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE) ; } @@ -2690,12 +2793,12 @@ void LLStartUp::cleanupNameCache() bool LLStartUp::dispatchURL() { // ok, if we've gotten this far and have a startup URL - if (!getStartSLURL().isValid()) + if (!getStartSLURL().isValid()) { return false; } - if(getStartSLURL().getType() != LLSLURL::APP) - { + if(getStartSLURL().getType() != LLSLURL::APP) + { // If we started with a location, but we're already // at that location, don't pop dialogs open. @@ -2738,6 +2841,171 @@ void LLStartUp::setStartSLURL(const LLSLURL& slurl) } } +/** + * Read all proxy configuration settings and set up both the HTTP proxy and + * SOCKS proxy as needed. + * + * Any errors that are encountered will result in showing the user a notification. + * When an error is encountered, + * + * @return Returns true if setup was successful, false if an error was encountered. + */ +bool LLStartUp::startLLProxy() +{ + bool proxy_ok = true; + std::string httpProxyType = gSavedSettings.getString("HttpProxyType"); + + // Set up SOCKS proxy (if needed) + if (gSavedSettings.getBOOL("Socks5ProxyEnabled")) + { + // Determine and update LLProxy with the saved authentication system + std::string auth_type = gSavedSettings.getString("Socks5AuthType"); + + if (auth_type.compare("UserPass") == 0) + { + LLPointer<LLCredential> socks_cred = gSecAPIHandler->loadCredential("SOCKS5"); + std::string socks_user = socks_cred->getIdentifier()["username"].asString(); + std::string socks_password = socks_cred->getAuthenticator()["creds"].asString(); + + bool ok = LLProxy::getInstance()->setAuthPassword(socks_user, socks_password); + + if (!ok) + { + LLNotificationsUtil::add("SOCKS_BAD_CREDS"); + proxy_ok = false; + } + } + else if (auth_type.compare("None") == 0) + { + LLProxy::getInstance()->setAuthNone(); + } + else + { + LL_WARNS("Proxy") << "Invalid SOCKS 5 authentication type."<< LL_ENDL; + + // Unknown or missing setting. + gSavedSettings.setString("Socks5AuthType", "None"); + + // Clear the SOCKS credentials. + LLPointer<LLCredential> socks_cred = new LLCredential("SOCKS5"); + gSecAPIHandler->deleteCredential(socks_cred); + + LLProxy::getInstance()->setAuthNone(); + } + + if (proxy_ok) + { + // Start the proxy and check for errors + // If status != SOCKS_OK, stopSOCKSProxy() will already have been called when startSOCKSProxy() returns. + LLHost socks_host; + socks_host.setHostByName(gSavedSettings.getString("Socks5ProxyHost")); + socks_host.setPort(gSavedSettings.getU32("Socks5ProxyPort")); + int status = LLProxy::getInstance()->startSOCKSProxy(socks_host); + + if (status != SOCKS_OK) + { + LLSD subs; + subs["HOST"] = gSavedSettings.getString("Socks5ProxyHost"); + subs["PORT"] = (S32)gSavedSettings.getU32("Socks5ProxyPort"); + + std::string error_string; + + switch(status) + { + case SOCKS_CONNECT_ERROR: // TCP Fail + error_string = "SOCKS_CONNECT_ERROR"; + break; + + case SOCKS_NOT_PERMITTED: // SOCKS 5 server rule set refused connection + error_string = "SOCKS_NOT_PERMITTED"; + break; + + case SOCKS_NOT_ACCEPTABLE: // Selected authentication is not acceptable to server + error_string = "SOCKS_NOT_ACCEPTABLE"; + break; + + case SOCKS_AUTH_FAIL: // Authentication failed + error_string = "SOCKS_AUTH_FAIL"; + break; + + case SOCKS_UDP_FWD_NOT_GRANTED: // UDP forward request failed + error_string = "SOCKS_UDP_FWD_NOT_GRANTED"; + break; + + case SOCKS_HOST_CONNECT_FAILED: // Failed to open a TCP channel to the socks server + error_string = "SOCKS_HOST_CONNECT_FAILED"; + break; + + case SOCKS_INVALID_HOST: // Improperly formatted host address or port. + error_string = "SOCKS_INVALID_HOST"; + break; + + default: + error_string = "SOCKS_UNKNOWN_STATUS"; // Something strange happened, + LL_WARNS("Proxy") << "Unknown return from LLProxy::startProxy(): " << status << LL_ENDL; + break; + } + + LLNotificationsUtil::add(error_string, subs); + proxy_ok = false; + } + } + } + else + { + LLProxy::getInstance()->stopSOCKSProxy(); // ensure no UDP proxy is running and it's all cleaned up + } + + if (proxy_ok) + { + // Determine the HTTP proxy type (if any) + if ((httpProxyType.compare("Web") == 0) && gSavedSettings.getBOOL("BrowserProxyEnabled")) + { + LLHost http_host; + http_host.setHostByName(gSavedSettings.getString("BrowserProxyAddress")); + http_host.setPort(gSavedSettings.getS32("BrowserProxyPort")); + if (!LLProxy::getInstance()->enableHTTPProxy(http_host, LLPROXY_HTTP)) + { + LLSD subs; + subs["HOST"] = http_host.getIPString(); + subs["PORT"] = (S32)http_host.getPort(); + LLNotificationsUtil::add("PROXY_INVALID_HTTP_HOST", subs); + proxy_ok = false; + } + } + else if ((httpProxyType.compare("Socks") == 0) && gSavedSettings.getBOOL("Socks5ProxyEnabled")) + { + LLHost socks_host; + socks_host.setHostByName(gSavedSettings.getString("Socks5ProxyHost")); + socks_host.setPort(gSavedSettings.getU32("Socks5ProxyPort")); + if (!LLProxy::getInstance()->enableHTTPProxy(socks_host, LLPROXY_SOCKS)) + { + LLSD subs; + subs["HOST"] = socks_host.getIPString(); + subs["PORT"] = (S32)socks_host.getPort(); + LLNotificationsUtil::add("PROXY_INVALID_SOCKS_HOST", subs); + proxy_ok = false; + } + } + else if (httpProxyType.compare("None") == 0) + { + LLProxy::getInstance()->disableHTTPProxy(); + } + else + { + LL_WARNS("Proxy") << "Invalid other HTTP proxy configuration."<< LL_ENDL; + + // Set the missing or wrong configuration back to something valid. + gSavedSettings.setString("HttpProxyType", "None"); + LLProxy::getInstance()->disableHTTPProxy(); + + // Leave proxy_ok alone, since this isn't necessarily fatal. + } + } + + return proxy_ok; +} + bool login_alert_done(const LLSD& notification, const LLSD& response) { LLPanelLogin::giveFocus(); @@ -3122,8 +3390,6 @@ bool process_login_success_response() } // Initial outfit for the user. - // QUESTION: Why can't we simply simply set the users outfit directly - // from a web page into the user info on the server? - Roxie LLSD initial_outfit = response["initial-outfit"][0]; if(initial_outfit.size()) { |