diff options
Diffstat (limited to 'indra/newview/llstartup.cpp')
-rw-r--r-- | indra/newview/llstartup.cpp | 387 |
1 files changed, 274 insertions, 113 deletions
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 4dfcb85295..e62227fa3c 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" @@ -366,7 +366,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 +376,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 +603,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 +732,13 @@ bool idle_startup() timeout_count = 0; + // Login screen needs menus for preferences, but we can enter + // this startup phase more than once. + if (gLoginMenuBarView == NULL) + { initialize_edit_menu(); + init_menus(); + } if (show_connect_box) { @@ -755,19 +773,6 @@ 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(); - } - gViewerWindow->setNormalControlsVisible( FALSE ); gLoginMenuBarView->setVisible( TRUE ); gLoginMenuBarView->setEnabled( TRUE ); @@ -807,7 +812,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. @@ -897,7 +916,7 @@ bool idle_startup() if (show_connect_box) { LLSLURL slurl; - LLPanelLogin::closePanel(); + //LLPanelLogin::closePanel(); } @@ -944,6 +963,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); @@ -1242,6 +1263,25 @@ 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); + } + } return FALSE; } @@ -1541,6 +1581,12 @@ bool idle_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()) { @@ -1962,8 +2008,8 @@ 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); // We're not away from keyboard, even though login might have taken @@ -2344,13 +2390,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 +2418,30 @@ 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; } + gAgentAvatarp->setSex(gender); + // try to find the outfit - if not there, create some default // wearables. LLUUID cat_id = findDescendentCategoryIDByName( @@ -2464,7 +2449,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 +2460,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 +2524,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) ; } @@ -2738,6 +2736,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 +3285,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()) { |