summaryrefslogtreecommitdiff
path: root/indra/newview/llstartup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llstartup.cpp')
-rw-r--r--indra/newview/llstartup.cpp918
1 files changed, 482 insertions, 436 deletions
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 7ad7799515..c56cacd12b 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2,31 +2,25 @@
* @file llstartup.cpp
* @brief startup routines.
*
- * $LicenseInfo:firstyear=2004&license=viewergpl$
- *
- * Copyright (c) 2004-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -118,7 +112,6 @@
#include "llinventorybridge.h"
#include "llinventorymodel.h"
#include "llinventorymodelbackgroundfetch.h"
-#include "llfriendcard.h"
#include "llkeyboard.h"
#include "llloginhandler.h" // gLoginHandler, SLURL support
#include "lllogininstance.h" // Host the login module.
@@ -128,7 +121,6 @@
#include "llfloaterevent.h"
#include "llpanelclassified.h"
#include "llpanelpick.h"
-#include "llpanelplace.h"
#include "llpanelgrouplandmoney.h"
#include "llpanelgroupnotices.h"
#include "llpreview.h"
@@ -147,7 +139,7 @@
#include "lltrans.h"
#include "llui.h"
#include "llurldispatcher.h"
-#include "llurlsimstring.h"
+#include "llslurl.h"
#include "llurlhistory.h"
#include "llurlwhitelist.h"
#include "llvieweraudio.h"
@@ -192,13 +184,13 @@
#include "llinventorybridge.h"
#include "llappearancemgr.h"
#include "llavatariconctrl.h"
+#include "llvoicechannel.h"
#include "lllogin.h"
#include "llevents.h"
#include "llstartuplistener.h"
#if LL_WINDOWS
-#include "llwindebug.h"
#include "lldxhardware.h"
#endif
@@ -224,15 +216,16 @@ extern S32 gStartImageHeight;
static bool gGotUseCircuitCodeAck = false;
static std::string sInitialOutfit;
static std::string sInitialOutfitGender; // "male" or "female"
+static boost::signals2::connection sWearablesLoadedCon;
static bool gUseCircuitCallbackCalled = false;
EStartupState LLStartUp::gStartupState = STATE_FIRST;
+LLSLURL LLStartUp::sStartSLURL;
-// *NOTE:Mani - to reconcile with giab changes...
-static std::string gFirstname;
-static std::string gLastname;
-static std::string gPassword;
+static LLPointer<LLCredential> gUserCredential;
+static std::string gDisplayName;
+static BOOL gRememberPassword = TRUE;
static U64 gFirstSimHandle = 0;
static LLHost gFirstSim;
@@ -249,7 +242,6 @@ boost::scoped_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener(
void login_show();
void login_callback(S32 option, void* userdata);
-bool is_hex_string(U8* str, S32 len);
void show_first_run_dialog();
bool first_run_dialog_callback(const LLSD& notification, const LLSD& response);
void set_startup_status(const F32 frac, const std::string& string, const std::string& msg);
@@ -262,6 +254,9 @@ bool callback_choose_gender(const LLSD& notification, const LLSD& response);
void init_start_screen(S32 location_id);
void release_start_screen();
void reset_login();
+LLSD transform_cert_args(LLPointer<LLCertificate> cert);
+void general_cert_done(const LLSD& notification, const LLSD& response);
+void trust_cert_done(const LLSD& notification, const LLSD& response);
void apply_udp_blacklist(const std::string& csv);
bool process_login_success_response();
void transition_back_to_login_panel(const std::string& emsg);
@@ -364,7 +359,7 @@ bool idle_startup()
if ( STATE_FIRST == LLStartUp::getStartupState() )
{
- gViewerWindow->showCursor();
+ gViewerWindow->showCursor();
gViewerWindow->getWindow()->setCursor(UI_CURSOR_WAIT);
/////////////////////////////////////////////////
@@ -381,13 +376,22 @@ bool idle_startup()
{
LLNotificationsUtil::add("DisplaySetToRecommended");
}
+ else if ((gSavedSettings.getS32("LastGPUClass") != LLFeatureManager::getInstance()->getGPUClass()) &&
+ (gSavedSettings.getS32("LastGPUClass") != -1))
+ {
+ LLNotificationsUtil::add("DisplaySetToRecommended");
+ }
else if (!gViewerWindow->getInitAlert().empty())
{
LLNotificationsUtil::add(gViewerWindow->getInitAlert());
}
gSavedSettings.setS32("LastFeatureVersion", LLFeatureManager::getInstance()->getVersion());
+ gSavedSettings.setS32("LastGPUClass", LLFeatureManager::getInstance()->getGPUClass());
+ // load dynamic GPU/feature tables from website (S3)
+ LLFeatureManager::getInstance()->fetchHTTPTables();
+
std::string xml_file = LLUI::locateSkin("xui_version.xml");
LLXMLNodePtr root;
bool xml_ok = false;
@@ -662,69 +666,25 @@ bool idle_startup()
//
// Log on to system
//
- if (!LLStartUp::sSLURLCommand.empty())
- {
- // this might be a secondlife:///app/login URL
- gLoginHandler.parseDirectLogin(LLStartUp::sSLURLCommand);
- }
- if (!gLoginHandler.getFirstName().empty()
- || !gLoginHandler.getLastName().empty()
- /*|| !gLoginHandler.getWebLoginKey().isNull()*/ )
- {
- // We have at least some login information on a SLURL
- gFirstname = gLoginHandler.getFirstName();
- gLastname = gLoginHandler.getLastName();
- LL_DEBUGS("LLStartup") << "STATE_FIRST: setting gFirstname, gLastname from gLoginHandler: '" << gFirstname << "' '" << gLastname << "'" << LL_ENDL;
-
- // Show the login screen if we don't have everything
- show_connect_box =
- gFirstname.empty() || gLastname.empty();
- }
- else if(gSavedSettings.getLLSD("UserLoginInfo").size() == 3)
- {
- LLSD cmd_line_login = gSavedSettings.getLLSD("UserLoginInfo");
- gFirstname = cmd_line_login[0].asString();
- gLastname = cmd_line_login[1].asString();
- LL_DEBUGS("LLStartup") << "Setting gFirstname, gLastname from gSavedSettings(\"UserLoginInfo\"): '" << gFirstname << "' '" << gLastname << "'" << LL_ENDL;
-
- LLMD5 pass((unsigned char*)cmd_line_login[2].asString().c_str());
- char md5pass[33]; /* Flawfinder: ignore */
- pass.hex_digest(md5pass);
- gPassword = md5pass;
-
-#ifdef USE_VIEWER_AUTH
- show_connect_box = true;
-#else
- show_connect_box = false;
-#endif
- gSavedSettings.setBOOL("AutoLogin", TRUE);
- }
- else if (gSavedSettings.getBOOL("AutoLogin"))
- {
- gFirstname = gSavedSettings.getString("FirstName");
- gLastname = gSavedSettings.getString("LastName");
- LL_DEBUGS("LLStartup") << "AutoLogin: setting gFirstname, gLastname from gSavedSettings(\"First|LastName\"): '" << gFirstname << "' '" << gLastname << "'" << LL_ENDL;
- gPassword = LLStartUp::loadPasswordFromDisk();
- gSavedSettings.setBOOL("RememberPassword", TRUE);
-
-#ifdef USE_VIEWER_AUTH
- show_connect_box = true;
-#else
- show_connect_box = false;
-#endif
+ if (gUserCredential.isNull())
+ {
+ gUserCredential = gLoginHandler.initializeLoginInfo();
}
- else
+ if (gUserCredential.isNull())
{
- // if not automatically logging in, display login dialog
- // a valid grid is selected
- gFirstname = gSavedSettings.getString("FirstName");
- gLastname = gSavedSettings.getString("LastName");
- LL_DEBUGS("LLStartup") << "normal login: setting gFirstname, gLastname from gSavedSettings(\"First|LastName\"): '" << gFirstname << "' '" << gLastname << "'" << LL_ENDL;
- gPassword = LLStartUp::loadPasswordFromDisk();
- show_connect_box = true;
+ show_connect_box = TRUE;
+ }
+ else if (gSavedSettings.getBOOL("AutoLogin"))
+ {
+ gRememberPassword = TRUE;
+ gSavedSettings.setBOOL("RememberPassword", TRUE);
+ show_connect_box = false;
+ }
+ else
+ {
+ gRememberPassword = gSavedSettings.getBOOL("RememberPassword");
+ show_connect_box = TRUE;
}
-
-
// Go to the next startup state
LLStartUp::setStartupState( STATE_BROWSER_INIT );
return FALSE;
@@ -756,8 +716,10 @@ bool idle_startup()
// Load all the name information out of the login view
// NOTE: Hits "Attempted getFields with no login view shown" warning, since we don't
// show the login view until login_show() is called below.
- // LLPanelLogin::getFields(gFirstname, gLastname, gPassword);
-
+ if (gUserCredential.isNull())
+ {
+ gUserCredential = gLoginHandler.initializeLoginInfo();
+ }
if (gNoRender)
{
LL_ERRS("AppInit") << "Need to autologin or use command line with norender!" << LL_ENDL;
@@ -765,11 +727,15 @@ bool idle_startup()
// Make sure the process dialog doesn't hide things
gViewerWindow->setShowProgress(FALSE);
+ initialize_edit_menu();
+
// Show the login dialog
login_show();
// connect dialog is already shown, so fill in the names
- LLPanelLogin::setFields( gFirstname, gLastname, gPassword);
-
+ if (gUserCredential.notNull())
+ {
+ LLPanelLogin::setFields( gUserCredential, gRememberPassword);
+ }
LLPanelLogin::giveFocus();
gSavedSettings.setBOOL("FirstRunThisInstall", FALSE);
@@ -806,9 +772,6 @@ bool idle_startup()
gViewerWindow->getWindow()->show();
display_startup();
- //DEV-10530. do cleanup. remove at some later date. jan-2009
- LLFloaterPreference::cleanupBadSetting();
-
// DEV-16927. The following code removes errant keystrokes that happen while the window is being
// first made visible.
#ifdef _WIN32
@@ -831,47 +794,40 @@ bool idle_startup()
if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState())
{
- // Move the progress view in front of the UI immediately when login is performed
- // this allows not to see main menu after Alt+Tab was pressed while login. EXT-744.
- gViewerWindow->moveProgressViewToFront();
-
//reset the values that could have come in from a slurl
- // DEV-42215: Make sure they're not empty -- gFirstname and gLastname
+ // 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.
- if (! gLoginHandler.getFirstName().empty() && ! gLoginHandler.getLastName().empty())
- {
- gFirstname = gLoginHandler.getFirstName();
- gLastname = gLoginHandler.getLastName();
- LL_DEBUGS("LLStartup") << "STATE_LOGIN_CLEANUP: setting gFirstname, gLastname from gLoginHandler: '" << gFirstname << "' '" << gLastname << "'" << LL_ENDL;
- }
if (show_connect_box)
{
// TODO if not use viewer auth
// Load all the name information out of the login view
- LLPanelLogin::getFields(&gFirstname, &gLastname, &gPassword);
+ LLPanelLogin::getFields(gUserCredential, gRememberPassword);
// end TODO
// HACK: Try to make not jump on login
gKeyboard->resetKeys();
}
- if (!gFirstname.empty() && !gLastname.empty())
- {
- gSavedSettings.setString("FirstName", gFirstname);
- gSavedSettings.setString("LastName", gLastname);
-
- LL_INFOS("AppInit") << "Attempting login as: " << gFirstname << " " << gLastname << LL_ENDL;
- gDebugInfo["LoginName"] = gFirstname + " " + gLastname;
+ // save the credentials
+ std::string userid = "unknown";
+ if(gUserCredential.notNull())
+ {
+ userid = gUserCredential->userID();
+ gSecAPIHandler->saveCredential(gUserCredential, gRememberPassword);
}
-
+ gSavedSettings.setBOOL("RememberPassword", gRememberPassword);
+ LL_INFOS("AppInit") << "Attempting login as: " << userid << LL_ENDL;
+ gDebugInfo["LoginName"] = userid;
+
// create necessary directories
// *FIX: these mkdir's should error check
- gDirUtilp->setLindenUserDir(gFirstname, gLastname);
+ gDirUtilp->setLindenUserDir(userid);
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")));
@@ -900,9 +856,8 @@ bool idle_startup()
{
gDirUtilp->setChatLogsDir(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
}
+ gDirUtilp->setPerAccountChatLogsDir(userid);
- gDirUtilp->setPerAccountChatLogsDir(gFirstname, gLastname);
-
LLFile::mkdir(gDirUtilp->getChatLogsDir());
LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir());
@@ -923,11 +878,7 @@ bool idle_startup()
if (show_connect_box)
{
- std::string location;
- LLPanelLogin::getLocation( location );
- LLURLSimString::setString( location );
-
- // END TODO
+ LLSLURL slurl;
LLPanelLogin::closePanel();
}
@@ -951,26 +902,21 @@ bool idle_startup()
// their last location, or some URL "-url //sim/x/y[/z]"
// All accounts have both a home and a last location, and we don't support
// more locations than that. Choose the appropriate one. JC
- if (LLURLSimString::parse())
- {
- // a startup URL was specified
- agent_location_id = START_LOCATION_ID_URL;
-
- // doesn't really matter what location_which is, since
- // gAgentStartLookAt will be overwritten when the
- // UserLoginLocationReply arrives
- location_which = START_LOCATION_ID_LAST;
- }
- else if (gSavedSettings.getString("LoginLocation") == "last" )
- {
- agent_location_id = START_LOCATION_ID_LAST; // last location
- location_which = START_LOCATION_ID_LAST;
- }
- else
- {
- agent_location_id = START_LOCATION_ID_HOME; // home
- location_which = START_LOCATION_ID_HOME;
- }
+ switch (LLStartUp::getStartSLURL().getType())
+ {
+ case LLSLURL::LOCATION:
+ agent_location_id = START_LOCATION_ID_URL;
+ location_which = START_LOCATION_ID_LAST;
+ break;
+ case LLSLURL::LAST_LOCATION:
+ agent_location_id = START_LOCATION_ID_LAST;
+ location_which = START_LOCATION_ID_LAST;
+ break;
+ default:
+ agent_location_id = START_LOCATION_ID_HOME;
+ location_which = START_LOCATION_ID_HOME;
+ break;
+ }
gViewerWindow->getWindow()->setCursor(UI_CURSOR_WAIT);
@@ -997,7 +943,7 @@ bool idle_startup()
if(STATE_LOGIN_AUTH_INIT == LLStartUp::getStartupState())
{
- gDebugInfo["GridName"] = LLViewerLogin::getInstance()->getGridLabel();
+ gDebugInfo["GridName"] = LLGridManager::getInstance()->getGridLabel();
// Update progress status and the display loop.
auth_desc = LLTrans::getString("LoginInProgress");
@@ -1021,11 +967,7 @@ bool idle_startup()
// This call to LLLoginInstance::connect() starts the
// authentication process.
- LLSD credentials;
- credentials["first"] = gFirstname;
- credentials["last"] = gLastname;
- credentials["passwd"] = gPassword;
- login->connect(credentials);
+ login->connect(gUserCredential);
LLStartUp::setStartupState( STATE_LOGIN_CURL_UNSTUCK );
return FALSE;
@@ -1050,10 +992,11 @@ bool idle_startup()
{
LL_INFOS("LLStartup") << "Login failed, LLLoginInstance::getResponse(): "
<< LLLoginInstance::getInstance()->getResponse() << LL_ENDL;
+ LLSD response = LLLoginInstance::getInstance()->getResponse();
// Still have error conditions that may need some
// sort of handling.
- std::string reason_response = LLLoginInstance::getInstance()->getResponse("reason");
- std::string message_response = LLLoginInstance::getInstance()->getResponse("message");
+ std::string reason_response = response["reason"];
+ std::string message_response = response["message"];
if(!message_response.empty())
{
@@ -1073,8 +1016,8 @@ bool idle_startup()
if(reason_response == "key")
{
// Couldn't login because user/password is wrong
- // Clear the password
- gPassword = "";
+ // Clear the credential
+ gUserCredential->clearAuthenticator();
}
if(reason_response == "update"
@@ -1087,18 +1030,65 @@ bool idle_startup()
LLLoginInstance::getInstance()->disconnect();
LLAppViewer::instance()->forceQuit();
}
- else
+ else
{
- // Don't pop up a notification in the TOS case because
- // LLFloaterTOS::onCancel() already scolded the user.
- if (reason_response != "tos")
+ if (reason_response != "tos")
{
- LLSD args;
- args["ERROR_MESSAGE"] = emsg.str();
- LL_INFOS("LLStartup") << "Notification: " << args << LL_ENDL;
- LLNotificationsUtil::add("ErrorMessage", args, LLSD(), login_alert_done);
+ // Don't pop up a notification in the TOS case because
+ // LLFloaterTOS::onCancel() already scolded the user.
+ std::string error_code;
+ if(response.has("errorcode"))
+ {
+ error_code = response["errorcode"].asString();
+ }
+ if ((reason_response == "CURLError") &&
+ (error_code == "SSL_CACERT" || error_code == "SSL_PEER_CERTIFICATE") &&
+ response.has("certificate"))
+ {
+ // This was a certificate error, so grab the certificate
+ // and throw up the appropriate dialog.
+ LLPointer<LLCertificate> certificate = gSecAPIHandler->getCertificate(response["certificate"]);
+ if(certificate)
+ {
+ LLSD args = transform_cert_args(certificate);
+
+ if(error_code == "SSL_CACERT")
+ {
+ // if we are handling an untrusted CA, throw up the dialog
+ // with the 'trust this CA' button.
+ LLNotificationsUtil::add("TrustCertificateError", args, response,
+ trust_cert_done);
+
+ show_connect_box = true;
+ }
+ else
+ {
+ // the certificate exception returns a unique string for each type of exception.
+ // we grab this string via the LLUserAuth object, and use that to grab the localized
+ // string.
+ args["REASON"] = LLTrans::getString(message_response);
+
+ LLNotificationsUtil::add("GeneralCertificateError", args, response,
+ general_cert_done);
+
+ reset_login();
+ gSavedSettings.setBOOL("AutoLogin", FALSE);
+ show_connect_box = true;
+
+ }
+
+ }
+ }
+ else
+ {
+ // This wasn't a certificate error, so throw up the normal
+ // notificatioin message.
+ LLSD args;
+ args["ERROR_MESSAGE"] = emsg.str();
+ LL_INFOS("LLStartup") << "Notification: " << args << LL_ENDL;
+ LLNotificationsUtil::add("ErrorMessage", args, LLSD(), login_alert_done);
+ }
}
-
//setup map of datetime strings to codes and slt & local time offset from utc
// *TODO: Does this need to be here?
LLStringOps::setupDatetimeInfo (false);
@@ -1111,7 +1101,10 @@ bool idle_startup()
if(process_login_success_response())
{
// Pass the user information to the voice chat server interface.
- gVoiceClient->userAuthorized(gFirstname, gLastname, gAgentID);
+ LLVoiceClient::getInstance()->userAuthorized(gUserCredential->userID(), gAgentID);
+ // create the default proximal channel
+ LLVoiceChannel::initClass();
+ LLGridManager::getInstance()->setFavorite();
LLStartUp::setStartupState( STATE_WORLD_INIT);
}
else
@@ -1122,6 +1115,7 @@ bool idle_startup()
LLNotificationsUtil::add("ErrorMessage", args, LLSD(), login_alert_done);
transition_back_to_login_panel(emsg.str());
show_connect_box = true;
+ return FALSE;
}
}
return FALSE;
@@ -1253,9 +1247,6 @@ bool idle_startup()
if (!gNoRender)
{
- // Move the progress view in front of the UI
- gViewerWindow->moveProgressViewToFront();
-
// direct logging to the debug console's line buffer
LLError::logToFixedBuffer(gDebugView->mDebugConsolep);
@@ -1292,6 +1283,10 @@ bool idle_startup()
LLAppViewer::instance()->loadNameCache();
}
+ // update the voice settings *after* gCacheName initialization
+ // so that we can construct voice UI that relies on the name cache
+ LLVoiceClient::getInstance()->updateSettings();
+
//gCacheName is required for nearby chat history loading
//so I just moved nearby history loading a few states further
if (!gNoRender && gSavedPerAccountSettings.getBOOL("LogShowHistory"))
@@ -1636,12 +1631,6 @@ bool idle_startup()
//all categories loaded. lets create "My Favorites" category
gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE,true);
- // Checks whether "Friends" and "Friends/All" folders exist in "Calling Cards" folder,
- // fetches their contents if needed and synchronizes it with buddies list.
- // If the folders are not found they are created.
- LLFriendCardsManager::instance().syncFriendCardsFolders();
-
-
// set up callbacks
llinfos << "Registering Callbacks" << llendl;
LLMessageSystem* msg = gMessageSystem;
@@ -1807,9 +1796,12 @@ bool idle_startup()
// thus, do not show this alert.
if (!gAgent.isFirstLogin())
{
- bool url_ok = LLURLSimString::sInstance.parse();
- if ((url_ok && gAgentStartLocation == "url") ||
- (!url_ok && ((gAgentStartLocation == gSavedSettings.getString("LoginLocation")))))
+ llinfos << "gAgentStartLocation : " << gAgentStartLocation << llendl;
+ LLSLURL start_slurl = LLStartUp::getStartSLURL();
+
+ if (((start_slurl.getType() == LLSLURL::LOCATION) && (gAgentStartLocation == "url")) ||
+ ((start_slurl.getType() == LLSLURL::LAST_LOCATION) && (gAgentStartLocation == "last")) ||
+ ((start_slurl.getType() == LLSLURL::HOME_LOCATION) && (gAgentStartLocation == "home")))
{
// Start location is OK
// Disabled code to restore camera location and focus if logging in to default location
@@ -1831,17 +1823,23 @@ bool idle_startup()
else
{
std::string msg;
- if (url_ok)
+ switch(start_slurl.getType())
{
- msg = "AvatarMovedDesired";
- }
- else if (gSavedSettings.getString("LoginLocation") == "home")
- {
- msg = "AvatarMovedHome";
- }
- else
- {
- msg = "AvatarMovedLast";
+ case LLSLURL::LOCATION:
+ {
+
+ msg = "AvatarMovedDesired";
+ break;
+ }
+ case LLSLURL::HOME_LOCATION:
+ {
+ msg = "AvatarMovedHome";
+ break;
+ }
+ default:
+ {
+ msg = "AvatarMovedLast";
+ }
}
LLNotificationsUtil::add(msg);
}
@@ -2057,20 +2055,9 @@ void login_show()
#endif
LLPanelLogin::show( gViewerWindow->getWindowRectScaled(),
- bUseDebugLogin,
+ bUseDebugLogin || gSavedSettings.getBOOL("SecondLifeEnterprise"),
login_callback, NULL );
- // UI textures have been previously loaded in doPreloadImages()
-
- LL_DEBUGS("AppInit") << "Setting Servers" << LL_ENDL;
-
- LLPanelLogin::addServer(LLViewerLogin::getInstance()->getGridLabel(), LLViewerLogin::getInstance()->getGridChoice());
-
- LLViewerLogin* vl = LLViewerLogin::getInstance();
- for(int grid_index = GRID_INFO_ADITI; grid_index < GRID_INFO_OTHER; ++grid_index)
- {
- LLPanelLogin::addServer(vl->getKnownGridLabel((EGridInfo)grid_index), grid_index);
- }
}
// Callback for when login screen is closed. Option 0 = connect, option 1 = quit.
@@ -2086,9 +2073,6 @@ void login_callback(S32 option, void *userdata)
}
else if (QUIT_OPTION == option) // *TODO: THIS CODE SEEMS TO BE UNREACHABLE!!!!! login_callback is never called with option equal to QUIT_OPTION
{
- // Make sure we don't save the password if the user is trying to clear it.
- std::string first, last, password;
- LLPanelLogin::getFields(&first, &last, &password);
if (!gSavedSettings.getBOOL("RememberPassword"))
{
// turn off the setting and write out to disk
@@ -2111,142 +2095,6 @@ void login_callback(S32 option, void *userdata)
}
}
-
-// static
-std::string LLStartUp::loadPasswordFromDisk()
-{
- // Only load password if we also intend to save it (otherwise the user
- // wonders what we're doing behind his back). JC
- BOOL remember_password = gSavedSettings.getBOOL("RememberPassword");
- if (!remember_password)
- {
- return std::string("");
- }
-
- std::string hashed_password("");
-
- // Look for legacy "marker" password from settings.ini
- hashed_password = gSavedSettings.getString("Marker");
- if (!hashed_password.empty())
- {
- // Stomp the Marker entry.
- gSavedSettings.setString("Marker", "");
-
- // Return that password.
- return hashed_password;
- }
-
- std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
- "password.dat");
- LLFILE* fp = LLFile::fopen(filepath, "rb"); /* Flawfinder: ignore */
- if (!fp)
- {
- return hashed_password;
- }
-
- // UUID is 16 bytes, written into ASCII is 32 characters
- // without trailing \0
- const S32 HASHED_LENGTH = 32;
- U8 buffer[HASHED_LENGTH+1];
-
- if (1 != fread(buffer, HASHED_LENGTH, 1, fp))
- {
- return hashed_password;
- }
-
- fclose(fp);
-
- // Decipher with MAC address
- LLXORCipher cipher(gMACAddress, 6);
- cipher.decrypt(buffer, HASHED_LENGTH);
-
- buffer[HASHED_LENGTH] = '\0';
-
- // Check to see if the mac address generated a bad hashed
- // password. It should be a hex-string or else the mac adress has
- // changed. This is a security feature to make sure that if you
- // get someone's password.dat file, you cannot hack their account.
- if(is_hex_string(buffer, HASHED_LENGTH))
- {
- hashed_password.assign((char*)buffer);
- }
-
- return hashed_password;
-}
-
-
-// static
-void LLStartUp::savePasswordToDisk(const std::string& hashed_password)
-{
- std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
- "password.dat");
- LLFILE* fp = LLFile::fopen(filepath, "wb"); /* Flawfinder: ignore */
- if (!fp)
- {
- return;
- }
-
- // Encipher with MAC address
- const S32 HASHED_LENGTH = 32;
- U8 buffer[HASHED_LENGTH+1];
-
- LLStringUtil::copy((char*)buffer, hashed_password.c_str(), HASHED_LENGTH+1);
-
- LLXORCipher cipher(gMACAddress, 6);
- cipher.encrypt(buffer, HASHED_LENGTH);
-
- if (fwrite(buffer, HASHED_LENGTH, 1, fp) != 1)
- {
- LL_WARNS("AppInit") << "Short write" << LL_ENDL;
- }
-
- fclose(fp);
-}
-
-
-// static
-void LLStartUp::deletePasswordFromDisk()
-{
- std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
- "password.dat");
- LLFile::remove(filepath);
-}
-
-
-bool is_hex_string(U8* str, S32 len)
-{
- bool rv = true;
- U8* c = str;
- while(rv && len--)
- {
- switch(*c)
- {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case 'a':
- case 'b':
- case 'c':
- case 'd':
- case 'e':
- case 'f':
- ++c;
- break;
- default:
- rv = false;
- break;
- }
- }
- return rv;
-}
-
void show_first_run_dialog()
{
LLNotificationsUtil::add("FirstRun", LLSD(), LLSD(), first_run_dialog_callback);
@@ -2288,7 +2136,7 @@ bool login_alert_status(const LLSD& notification, const LLSD& response)
// break;
case 2: // Teleport
// Restart the login process, starting at our home locaton
- LLURLSimString::setString("home");
+ LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME));
LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
break;
default:
@@ -2505,33 +2353,95 @@ void asset_callback_nothing(LLVFS*, const LLUUID&, LLAssetType::EType, void*, S3
}
// *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 MALE_OUTFIT_FOLDER = "Male Shape & Outfit";
-const std::string FEMALE_OUTFIT_FOLDER = "Female Shape & Outfit";
+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;
-
+const S32 OPT_TRUST_CERT = 0;
+const S32 OPT_CANCEL_TRUST = 1;
+
bool callback_choose_gender(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+{
+
+ // These defaults are returned from the server on login. They are set in login.xml.
+ // If no default is returned from the server, they are retrieved from settings.xml.
+
+ S32 option = LLNotification::getSelectedOption(notification, response);
switch(option)
{
- case OPT_MALE:
- LLStartUp::loadInitialOutfit( MALE_OUTFIT_FOLDER, "male" );
- break;
-
- case OPT_FEMALE:
- case OPT_CLOSED_WINDOW:
- default:
- LLStartUp::loadInitialOutfit( FEMALE_OUTFIT_FOLDER, "female" );
- break;
+ case OPT_MALE:
+ LLStartUp::loadInitialOutfit( gSavedSettings.getString("DefaultMaleAvatar"), "male" );
+ break;
+
+ case OPT_FEMALE:
+ case OPT_CLOSED_WINDOW:
+ default:
+ LLStartUp::loadInitialOutfit( gSavedSettings.getString("DefaultFemaleAvatar"), "female" );
+ break;
}
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 )
{
@@ -2543,16 +2453,16 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
S32 gender = 0;
- std::string gestures;
+ std::string same_gender_gestures;
if (gender_name == "male")
{
gender = OPT_MALE;
- gestures = MALE_GESTURES_FOLDER;
+ same_gender_gestures = MALE_GESTURES_FOLDER;
}
else
{
gender = OPT_FEMALE;
- gestures = FEMALE_GESTURES_FOLDER;
+ same_gender_gestures = FEMALE_GESTURES_FOLDER;
}
// try to find the outfit - if not there, create some default
@@ -2566,6 +2476,8 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
}
else
{
+ sWearablesLoadedCon = gAgentWearables.addLoadedCallback(LLStartUp::saveInitialOutfit);
+
bool do_copy = true;
bool do_append = false;
LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
@@ -2573,42 +2485,29 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
}
// Copy gestures
- LLUUID dst_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE);
- LLPointer<LLInventoryCallback> cb(NULL);
- LLAppearanceMgr *app_mgr = &(LLAppearanceMgr::instance());
+ 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);
- // - Copy gender-specific gestures.
- LLUUID gestures_cat_id = findDescendentCategoryIDByName(
- gInventory.getLibraryRootFolderID(),
- gestures);
- if (gestures_cat_id.notNull())
- {
- callAfterCategoryFetch(gestures_cat_id,
- boost::bind(&LLAppearanceMgr::shallowCopyCategory,
- app_mgr,
- gestures_cat_id,
- dst_id,
- cb));
- }
+}
- // - Copy common gestures.
- LLUUID common_gestures_cat_id = findDescendentCategoryIDByName(
- gInventory.getLibraryRootFolderID(),
- COMMON_GESTURES_FOLDER);
- if (common_gestures_cat_id.notNull())
+//static
+void LLStartUp::saveInitialOutfit()
+{
+ if (sInitialOutfit.empty()) return;
+
+ if (sWearablesLoadedCon.connected())
{
- callAfterCategoryFetch(common_gestures_cat_id,
- boost::bind(&LLAppearanceMgr::shallowCopyCategory,
- app_mgr,
- common_gestures_cat_id,
- dst_id,
- cb));
+ sWearablesLoadedCon.disconnect();
}
+ LLAppearanceMgr::getInstance()->makeNewOutfitLinks(sInitialOutfit,false);
+}
- // 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);
-
+std::string& LLStartUp::getInitialOutfitName()
+{
+ return sInitialOutfit;
}
// Loads a bitmap to display during load
@@ -2746,13 +2645,6 @@ void reset_login()
//---------------------------------------------------------------------------
-std::string LLStartUp::sSLURLCommand;
-
-bool LLStartUp::canGoFullscreen()
-{
- return gStartupState >= STATE_WORLD_INIT;
-}
-
// Initialize all plug-ins except the web browser (which was initialized
// early, before the login screen). JC
void LLStartUp::multimediaInit()
@@ -2779,41 +2671,146 @@ void LLStartUp::fontInit()
bool LLStartUp::dispatchURL()
{
// ok, if we've gotten this far and have a startup URL
- if (!sSLURLCommand.empty())
+ if (!getStartSLURL().isValid())
{
- LLMediaCtrl* web = NULL;
- const bool trusted_browser = false;
- LLURLDispatcher::dispatch(sSLURLCommand, web, trusted_browser);
+ return false;
}
- else if (LLURLSimString::parse())
- {
+ if(getStartSLURL().getType() != LLSLURL::APP)
+ {
+
// If we started with a location, but we're already
// at that location, don't pop dialogs open.
LLVector3 pos = gAgent.getPositionAgent();
- F32 dx = pos.mV[VX] - (F32)LLURLSimString::sInstance.mX;
- F32 dy = pos.mV[VY] - (F32)LLURLSimString::sInstance.mY;
+ LLVector3 slurlpos = getStartSLURL().getPosition();
+ F32 dx = pos.mV[VX] - slurlpos.mV[VX];
+ F32 dy = pos.mV[VY] - slurlpos.mV[VY];
const F32 SLOP = 2.f; // meters
- if( LLURLSimString::sInstance.mSimName != gAgent.getRegion()->getName()
+ if( getStartSLURL().getRegion() != gAgent.getRegion()->getName()
|| (dx*dx > SLOP*SLOP)
|| (dy*dy > SLOP*SLOP) )
{
- std::string url = LLURLSimString::getURL();
- LLMediaCtrl* web = NULL;
- const bool trusted_browser = false;
- LLURLDispatcher::dispatch(url, web, trusted_browser);
+ LLURLDispatcher::dispatch(getStartSLURL().getSLURLString(),
+ NULL, false);
}
return true;
}
return false;
}
+void LLStartUp::setStartSLURL(const LLSLURL& slurl)
+{
+ sStartSLURL = slurl;
+ switch(slurl.getType())
+ {
+ case LLSLURL::HOME_LOCATION:
+ {
+ gSavedSettings.setString("LoginLocation", LLSLURL::SIM_LOCATION_HOME);
+ break;
+ }
+ case LLSLURL::LAST_LOCATION:
+ {
+ gSavedSettings.setString("LoginLocation", LLSLURL::SIM_LOCATION_LAST);
+ break;
+ }
+ default:
+ LLGridManager::getInstance()->setGridChoice(slurl.getGrid());
+ break;
+ }
+}
+
bool login_alert_done(const LLSD& notification, const LLSD& response)
{
LLPanelLogin::giveFocus();
return false;
}
+// parse the certificate information into args for the
+// certificate notifications
+LLSD transform_cert_args(LLPointer<LLCertificate> cert)
+{
+ LLSD args = LLSD::emptyMap();
+ std::string value;
+ LLSD cert_info;
+ cert->getLLSD(cert_info);
+ // convert all of the elements in the cert into
+ // args for the xml dialog, so we have flexability to
+ // display various parts of the cert by only modifying
+ // the cert alert dialog xml.
+ for(LLSD::map_iterator iter = cert_info.beginMap();
+ iter != cert_info.endMap();
+ iter++)
+ {
+ // key usage and extended key usage
+ // are actually arrays, and we want to format them as comma separated
+ // strings, so special case those.
+ LLSDSerialize::toXML(cert_info[iter->first], std::cout);
+ if((iter->first== std::string(CERT_KEY_USAGE)) |
+ (iter->first == std::string(CERT_EXTENDED_KEY_USAGE)))
+ {
+ value = "";
+ LLSD usage = cert_info[iter->first];
+ for (LLSD::array_iterator usage_iter = usage.beginArray();
+ usage_iter != usage.endArray();
+ usage_iter++)
+ {
+
+ if(usage_iter != usage.beginArray())
+ {
+ value += ", ";
+ }
+
+ value += (*usage_iter).asString();
+ }
+
+ }
+ else
+ {
+ value = iter->second.asString();
+ }
+
+ std::string name = iter->first;
+ std::transform(name.begin(), name.end(), name.begin(),
+ (int(*)(int))toupper);
+ args[name.c_str()] = value;
+ }
+ return args;
+}
+
+
+// when we handle a cert error, give focus back to the login panel
+void general_cert_done(const LLSD& notification, const LLSD& response)
+{
+ LLStartUp::setStartupState( STATE_LOGIN_SHOW );
+ LLPanelLogin::giveFocus();
+}
+
+// check to see if the user wants to trust the cert.
+// if they do, add it to the cert store and
+void trust_cert_done(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ switch(option)
+ {
+ case OPT_TRUST_CERT:
+ {
+ LLPointer<LLCertificate> cert = gSecAPIHandler->getCertificate(notification["payload"]["certificate"]);
+ LLPointer<LLCertificateStore> store = gSecAPIHandler->getCertificateStore(gSavedSettings.getString("CertStore"));
+ store->add(cert);
+ store->save();
+ LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
+ break;
+ }
+ case OPT_CANCEL_TRUST:
+ reset_login();
+ gSavedSettings.setBOOL("AutoLogin", FALSE);
+ LLStartUp::setStartupState( STATE_LOGIN_SHOW );
+ default:
+ LLPanelLogin::giveFocus();
+ break;
+ }
+
+}
void apply_udp_blacklist(const std::string& csv)
{
@@ -2861,33 +2858,45 @@ bool process_login_success_response()
text = response["secure_session_id"].asString();
if(!text.empty()) gAgent.mSecureSessionID.set(text);
- text = response["first_name"].asString();
- if(!text.empty())
- {
- // Remove quotes from string. Login.cgi sends these to force
- // names that look like numbers into strings.
- gFirstname.assign(text);
- LLStringUtil::replaceChar(gFirstname, '"', ' ');
- LLStringUtil::trim(gFirstname);
- }
- text = response["last_name"].asString();
- if(!text.empty())
+ // if the response contains a display name, use that,
+ // otherwise if the response contains a first and/or last name,
+ // use those. Otherwise use the credential identifier
+
+ gDisplayName = "";
+ if (response.has("display_name"))
{
- gLastname.assign(text);
+ gDisplayName.assign(response["display_name"].asString());
+ if(!gDisplayName.empty())
+ {
+ // Remove quotes from string. Login.cgi sends these to force
+ // names that look like numbers into strings.
+ LLStringUtil::replaceChar(gDisplayName, '"', ' ');
+ LLStringUtil::trim(gDisplayName);
+ }
}
- gSavedSettings.setString("FirstName", gFirstname);
- gSavedSettings.setString("LastName", gLastname);
-
- if (gSavedSettings.getBOOL("RememberPassword"))
+ if(gDisplayName.empty())
{
- // Successful login means the password is valid, so save it.
- LLStartUp::savePasswordToDisk(gPassword);
+ if(response.has("first_name"))
+ {
+ gDisplayName.assign(response["first_name"].asString());
+ LLStringUtil::replaceChar(gDisplayName, '"', ' ');
+ LLStringUtil::trim(gDisplayName);
+ }
+ if(response.has("last_name"))
+ {
+ text.assign(response["last_name"].asString());
+ LLStringUtil::replaceChar(text, '"', ' ');
+ LLStringUtil::trim(text);
+ if(!gDisplayName.empty())
+ {
+ gDisplayName += " ";
+ }
+ gDisplayName += text;
+ }
}
- else
+ if(gDisplayName.empty())
{
- // Don't leave password from previous session sitting around
- // during this login session.
- LLStartUp::deletePasswordFromDisk();
+ gDisplayName.assign(gUserCredential->asString());
}
// this is their actual ability to access content
@@ -2903,9 +2912,8 @@ bool process_login_success_response()
text = response["agent_region_access"].asString();
if (!text.empty())
{
- U32 preferredMaturity =
- llmin((U32)LLAgent::convertTextToMaturity(text[0]),
- gSavedSettings.getU32("PreferredMaturity"));
+ U32 preferredMaturity = (U32)LLAgent::convertTextToMaturity(text[0]);
+
gSavedSettings.setU32("PreferredMaturity", preferredMaturity);
}
// During the AO transition, this flag will be true. Then the flag will
@@ -2981,7 +2989,7 @@ bool process_login_success_response()
// replace the default help URL format
gSavedSettings.setString("HelpURLFormat",text);
- // don't fall back to Nebraska's pre-connection static help
+ // don't fall back to Standalone's pre-connection static help
gSavedSettings.setBOOL("HelpUseLocal", false);
}
@@ -3044,6 +3052,37 @@ bool process_login_success_response()
LLStringOps::setupDatetimeInfo(pacific_daylight_time);
}
+ // set up the voice configuration. Ultimately, we should pass this up as part of each voice
+ // channel if we need to move to multiple voice servers per grid.
+ LLSD voice_config_info = response["voice-config"];
+ if(voice_config_info.has("VoiceServerType"))
+ {
+ gSavedSettings.setString("VoiceServerType", voice_config_info["VoiceServerType"].asString());
+ }
+
+ // Request the map server url
+ std::string map_server_url = response["map-server-url"];
+ if(!map_server_url.empty())
+ {
+ gSavedSettings.setString("MapServerURL", map_server_url);
+ }
+
+ // Default male and female avatars allowing the user to choose their avatar on first login.
+ // These may be passed up by SLE to allow choice of enterprise avatars instead of the standard
+ // "new ruth." Not to be confused with 'initial-outfit' below
+ LLSD newuser_config = response["newuser-config"][0];
+ if(newuser_config.has("DefaultFemaleAvatar"))
+ {
+ gSavedSettings.setString("DefaultFemaleAvatar", newuser_config["DefaultFemaleAvatar"].asString());
+ }
+ if(newuser_config.has("DefaultMaleAvatar"))
+ {
+ gSavedSettings.setString("DefaultMaleAvatar", newuser_config["DefaultMaleAvatar"].asString());
+ }
+
+ // 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())
{
@@ -3087,6 +3126,13 @@ bool process_login_success_response()
}
}
+ // Set the location of the snapshot sharing config endpoint
+ std::string snapshot_config_url = response["snapshot_config_url"];
+ if(!snapshot_config_url.empty())
+ {
+ gSavedSettings.setString("SnapshotConfigURL", snapshot_config_url);
+ }
+
// Start the process of fetching the OpenID session cookie for this user login
std::string openid_url = response["openid_url"];
if(!openid_url.empty())
@@ -3097,7 +3143,7 @@ bool process_login_success_response()
bool success = false;
// JC: gesture loading done below, when we have an asset system
- // in place. Don't delete/clear user_credentials until then.
+ // in place. Don't delete/clear gUserCredentials until then.
if(gAgentID.notNull()
&& gAgentSessionID.notNull()
&& gMessageSystem->mOurCircuitCode