Newer
Older
/**
* @file llstartup.cpp
* @brief startup routines.
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* 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.
* 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.
* 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
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
*/
#include "llviewerprecompiledheaders.h"
#include "llstartup.h"
#if LL_WINDOWS
# include <process.h> // _spawnl()
# include <sys/stat.h> // mkdir()
#include "llviewermedia_streamingaudio.h"
#include "llaudioengine.h"
Bryan O'Sullivan
committed
#ifdef LL_FMOD
Don Kjer
committed
#include "llares.h"
#include "lllandmark.h"
#include "llfloaterreg.h"
#include "llhttpsender.h"
Dmitry Zaporozhan
committed
#include "llimfloater.h"
#include "lllocationhistory.h"
#include "llimageworker.h"
Loren Shih
committed
#include "llloginflags.h"
#include "llmd5.h"
#include "llmemorystream.h"
Don Kjer
committed
#include "llmessageconfig.h"
Igor Borovkov
committed
#include "llnearbychat.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "llteleporthistory.h"
#include "llregionhandle.h"
#include "llsd.h"
#include "llsdserialize.h"
#include "llsecondlifeurls.h"
#include "llstring.h"
#include "lluserrelations.h"
#include "llviewercontrol.h"
#include "llxorcipher.h" // saved password, MAC address
Steven Bennetts
committed
#include "llwindow.h"
#include "imageids.h"
#include "message.h"
#include "v3math.h"
#include "llagent.h"
#include "llagentcamera.h"
#include "llagentwearables.h"
#include "llagentpilot.h"
#include "llfloateravatarpicker.h"
#include "llcallbacklist.h"
#include "llcallingcard.h"
#include "llconsole.h"
#include "llcontainerview.h"
#include "lldebugview.h"
#include "lldrawable.h"
#include "lleventnotifier.h"
#include "llface.h"
#include "llfeaturemanager.h"
//#include "llfirstuse.h"
#include "llfloaterpreference.h"
#include "llfloatertopobjects.h"
#include "llfloaterworldmap.h"
#include "llgesturemgr.h"
#include "llgroupmgr.h"
#include "llhudeffecttrail.h"
#include "llhudmanager.h"
#include "llhttpclient.h"
#include "llimagebmp.h"
#include "llinventorybridge.h"
Loren Shih
committed
#include "llinventorymodelbackgroundfetch.h"
Melinda Green
committed
#include "llloginhandler.h" // gLoginHandler, SLURL support
#include "lllogininstance.h" // Host the login module.
#include "llpanellogin.h"
#include "llmutelist.h"
#include "llavatarpropertiesprocessor.h"
#include "llfloaterevent.h"
#include "llpanelclassified.h"
#include "llpanelpick.h"
#include "llpanelgrouplandmoney.h"
#include "llpanelgroupnotices.h"
#include "llpreview.h"
#include "llpreviewscript.h"
#include "llproductinforequest.h"
Josh Bell
committed
#include "llsecondlifeurls.h"
#include "llsidetray.h"
#include "llstatusbar.h" // sendMoneyBalanceRequest(), owns L$ balance
#include "lltexturecache.h"
#include "lltexturefetch.h"
#include "lltrans.h"
Tess Chu
committed
#include "llurldispatcher.h"
Steven Bennetts
committed
#include "llvieweraudio.h"
#include "llviewerassetstorage.h"
#include "llviewercamera.h"
#include "llviewerdisplay.h"
Don Kjer
committed
#include "llviewergenericmessage.h"
#include "llviewermenu.h"
#include "llviewermessage.h"
#include "llviewernetwork.h"
#include "llviewerobjectlist.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
#include "llviewerstats.h"
#include "llviewerthrottle.h"
#include "llviewerwindow.h"
#include "llvoavatar.h"
#include "llvoavatarself.h"
Josh Bell
committed
#include "llweb.h"
#include "llworldmapmessage.h"
Steven Bennetts
committed
#include "llappviewer.h"
Josh Bell
committed
#include "llfloatermap.h"
Steven Bennetts
committed
#include "llnamelistctrl.h"
#include "llnamebox.h"
#include "llnameeditor.h"
#include "llpostprocess.h"
#include "llwlparammanager.h"
#include "llwaterparammanager.h"
#include "llwearable.h"
#include "llinventorybridge.h"
Bradley Payne
committed
#include "llappearancemgr.h"
Steven Bennetts
committed
#include "llavatariconctrl.h"
#include "llvoicechannel.h"
#include "llevents.h"
#include "llstartuplistener.h"
#if LL_WINDOWS
#include "lldxhardware.h"
#endif
//
// exported globals
//
bool gAgentMovementCompleted = false;
S32 gMaxAgentGroups;
std::string SCREEN_HOME_FILENAME = "screen_home.bmp";
std::string SCREEN_LAST_FILENAME = "screen_last.bmp";
brad kittenbrink
committed
LLPointer<LLViewerTexture> gStartTexture;
//
// Imported globals
//
extern S32 gStartImageWidth;
extern S32 gStartImageHeight;
//
// local globals
//
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;
static LLPointer<LLCredential> gUserCredential;
static std::string gDisplayName;
static BOOL gRememberPassword = TRUE;
static U64 gFirstSimHandle = 0;
static LLHost gFirstSim;
static std::string gFirstSimSeedCap;
static LLVector3 gAgentStartLookAt(1.0f, 0.f, 0.f);
static std::string gAgentStartLocation = "safe";
boost::scoped_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState"));
boost::scoped_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener());
//
// local function declaration
//
void login_show();
void login_callback(S32 option, void* userdata);
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);
bool login_alert_status(const LLSD& notification, const LLSD& response);
void login_packet_failed(void**, S32 result);
void use_circuit_callback(void**, S32 result);
void register_viewer_callbacks(LLMessageSystem* msg);
void asset_callback_nothing(LLVFS*, const LLUUID&, LLAssetType::EType, void*, S32);
bool callback_choose_gender(const LLSD& notification, const LLSD& response);
void init_start_screen(S32 location_id);
void release_start_screen();
Josh Bell
committed
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);
void callback_cache_name(const LLUUID& id, const std::string& firstname, const std::string& lastname, BOOL is_group)
Steven Bennetts
committed
{
LLNameListCtrl::refreshAll(id, firstname, lastname, is_group);
LLNameBox::refreshAll(id, firstname, lastname, is_group);
LLNameEditor::refreshAll(id, firstname, lastname, is_group);
// TODO: Actually be intelligent about the refresh.
// For now, just brute force refresh the dialogs.
dialog_refresh_all();
}
//
// exported functionality
//
//
// local classes
//
namespace
{
class LLNullHTTPSender : public LLHTTPSender
{
virtual void send(const LLHost& host,
const std::string& message, const LLSD& body,
LLHTTPClient::ResponderPtr response) const
{
LL_WARNS("AppInit") << " attemped to send " << message << " to " << host
<< " with null sender" << LL_ENDL;
}
};
}
void update_texture_fetch()
{
Steven Bennetts
committed
LLAppViewer::getTextureCache()->update(1); // unpauses the texture cache thread
LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread
LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread
// Returns false to skip other idle processing. Should only return
// true when all initialization done.
bool idle_startup()
{
LLMemType mt1(LLMemType::MTYPE_STARTUP);
const F32 PRECACHING_DELAY = gSavedSettings.getF32("PrecachingDelay");
static LLTimer timeout;
static S32 timeout_count = 0;
static LLTimer login_time;
// until this is encapsulated, this little hack for the
// auth/transform loop will do.
static F32 progress = 0.10f;
static std::string auth_desc;
static std::string auth_message;
static LLVector3 initial_sun_direction(1.f, 0.f, 0.f);
static LLVector3 agent_start_position_region(10.f, 10.f, 10.f); // default for when no space server
// last location by default
static S32 agent_location_id = START_LOCATION_ID_LAST;
static S32 location_which = START_LOCATION_ID_LAST;
static bool show_connect_box = true;
//static bool stipend_since_login = false;
// HACK: These are things from the main loop that usually aren't done
// until initialization is complete, but need to be done here for things
// to work.
gIdleCallbacks.callFunctions();
gViewerWindow->updateUI();
const std::string delims (" ");
std::string system;
int begIdx, endIdx;
std::string osString = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
begIdx = osString.find_first_not_of (delims);
endIdx = osString.find_first_of (delims, begIdx);
system = osString.substr (begIdx, endIdx - begIdx);
system += "Locale";
LLStringUtil::setLocale (LLTrans::getString(system));
//note: Removing this line will cause incorrect button size in the login screen. -- bao.
gTextureList.updateImages(0.01f) ;
if ( STATE_FIRST == LLStartUp::getStartupState() )
gViewerWindow->showCursor();
gViewerWindow->getWindow()->setCursor(UI_CURSOR_WAIT);
/////////////////////////////////////////////////
//
Steven Bennetts
committed
// Initialize stuff that doesn't need data from simulators
if (LLFeatureManager::getInstance()->isSafe())
LLNotificationsUtil::add("DisplaySetToSafe");
else if ((gSavedSettings.getS32("LastFeatureVersion") < LLFeatureManager::getInstance()->getVersion()) &&
Josh Bell
committed
(gSavedSettings.getS32("LastFeatureVersion") != 0))
LLNotificationsUtil::add("DisplaySetToRecommended");
Josh Bell
committed
}
else if ((gSavedSettings.getS32("LastGPUClass") != LLFeatureManager::getInstance()->getGPUClass()) &&
(gSavedSettings.getS32("LastGPUClass") != -1))
{
LLNotificationsUtil::add("DisplaySetToRecommended");
}
Josh Bell
committed
else if (!gViewerWindow->getInitAlert().empty())
{
LLNotificationsUtil::add(gViewerWindow->getInitAlert());
Josh Bell
committed
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;
if (LLXMLNode::parseFile(xml_file, root, NULL))
{
if( (root->hasName("xui_version") ) )
{
std::string value = root->getValue();
LLStringUtil::convertToF32(value, version);
if (version >= 1.0f)
{
xml_ok = true;
}
}
}
if (!xml_ok)
{
// If XML is bad, there's a good possibility that notifications.xml is ALSO bad.
// If that's so, then we'll get a fatal error on attempting to load it,
// which will display a nontranslatable error message that says so.
// Otherwise, we'll display a reasonable error message that IS translatable.
LLAppViewer::instance()->earlyExit("BadInstallation");
}
//
// Statistics stuff
//
// Load autopilot and stats stuff
gAgentPilot.load(gSavedSettings.getString("StatsPilotFile"));
//gErrorStream.setTime(gSavedSettings.getBOOL("LogTimestamps"));
// Load the throttle settings
gViewerThrottle.load();
if (ll_init_ares() == NULL || !gAres->isInitialized())
Don Kjer
committed
{
std::string diagnostic = "Could not start address resolution system";
LL_WARNS("AppInit") << diagnostic << LL_ENDL;
LLAppViewer::instance()->earlyExit("LoginFailedNoNetwork", LLSD().with("DIAGNOSTIC", diagnostic));
Don Kjer
committed
}
LL_DEBUGS("AppInit") << "Initializing messaging system..." << LL_ENDL;
std::string message_template_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"message_template.msg");
found_template = LLFile::fopen(message_template_path, "r"); /* Flawfinder: ignore */
#if LL_WINDOWS
// On the windows dev builds, unpackaged, the message_template.msg
James Cook
committed
// file will be located in:
// build-vc**/newview/<config>/app_settings
if (!found_template)
{
message_template_path = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "app_settings", "message_template.msg");
found_template = LLFile::fopen(message_template_path.c_str(), "r"); /* Flawfinder: ignore */
}
James Cook
committed
#elif LL_DARWIN
// On Mac dev builds, message_template.msg lives in:
// indra/build-*/newview/<config>/Second Life/Contents/Resources/app_settings
if (!found_template)
{
message_template_path =
gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE,
"../Resources/app_settings",
"message_template.msg");
found_template = LLFile::fopen(message_template_path.c_str(), "r"); /* Flawfinder: ignore */
}
if (found_template)
{
fclose(found_template);
U32 port = gSavedSettings.getU32("UserConnectionPort");
if ((NET_USE_OS_ASSIGNED_PORT == port) && // if nothing specified on command line (-port)
(gSavedSettings.getBOOL("ConnectionPortEnabled")))
{
port = gSavedSettings.getU32("ConnectionPort");
}
LLHTTPSender::setDefaultSender(new LLNullHTTPSender());
// TODO parameterize
const F32 circuit_heartbeat_interval = 5;
const F32 circuit_timeout = 100;
const LLUseCircuitCodeResponder* responder = NULL;
bool failure_is_fatal = true;
if(!start_messaging_system(
message_template_path,
LLVersionInfo::getMajor(),
LLVersionInfo::getMinor(),
LLVersionInfo::getPatch(),
std::string(),
responder,
failure_is_fatal,
circuit_heartbeat_interval,
circuit_timeout))
std::string diagnostic = llformat(" Error: %d", gMessageSystem->getErrorCode());
LL_WARNS("AppInit") << diagnostic << LL_ENDL;
LLAppViewer::instance()->earlyExit("LoginFailedNoNetwork", LLSD().with("DIAGNOSTIC", diagnostic));
#if LL_WINDOWS
// On the windows dev builds, unpackaged, the message.xml file will
// be located in indra/build-vc**/newview/<config>/app_settings.
std::string message_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"message.xml");
if (!LLFile::isfile(message_path.c_str()))
{
LLMessageConfig::initClass("viewer", gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "app_settings", ""));
}
else
{
LLMessageConfig::initClass("viewer", gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
}
#else
LLMessageConfig::initClass("viewer", gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
#endif
LLAppViewer::instance()->earlyExit("MessageTemplateNotFound", LLSD().with("PATH", message_template_path));
}
if(gMessageSystem && gMessageSystem->isOK())
{
// Initialize all of the callbacks in case of bad message
// system data
LLMessageSystem* msg = gMessageSystem;
msg->setExceptionFunc(MX_UNREGISTERED_MESSAGE,
invalid_message_callback,
NULL);
msg->setExceptionFunc(MX_PACKET_TOO_SHORT,
invalid_message_callback,
NULL);
// running off end of a packet is now valid in the case
// when a reader has a newer message template than
// the sender
/*msg->setExceptionFunc(MX_RAN_OFF_END_OF_PACKET,
NULL);*/
msg->setExceptionFunc(MX_WROTE_PAST_BUFFER_SIZE,
invalid_message_callback,
NULL);
if (gSavedSettings.getBOOL("LogMessages"))
LL_DEBUGS("AppInit") << "Message logging activated!" << LL_ENDL;
msg->startLogging();
}
// start the xfer system. by default, choke the downloads
// a lot...
const S32 VIEWER_MAX_XFER = 3;
start_xfer_manager(gVFS);
gXferManager->setMaxIncomingXfers(VIEWER_MAX_XFER);
F32 xfer_throttle_bps = gSavedSettings.getF32("XferThrottle");
if (xfer_throttle_bps > 1.f)
{
gXferManager->setUseAckThrottling(TRUE);
gXferManager->setAckThrottleBPS(xfer_throttle_bps);
}
gAssetStorage = new LLViewerAssetStorage(msg, gXferManager, gVFS, gStaticVFS);
F32 dropPercent = gSavedSettings.getF32("PacketDropPercentage");
msg->mPacketRing.setDropPercentage(dropPercent);
F32 inBandwidth = gSavedSettings.getF32("InBandwidth");
F32 outBandwidth = gSavedSettings.getF32("OutBandwidth");
if (inBandwidth != 0.f)
LL_DEBUGS("AppInit") << "Setting packetring incoming bandwidth to " << inBandwidth << LL_ENDL;
msg->mPacketRing.setInBandwidth(inBandwidth);
if (outBandwidth != 0.f)
LL_DEBUGS("AppInit") << "Setting packetring outgoing bandwidth to " << outBandwidth << LL_ENDL;
msg->mPacketRing.setOutBandwidth(outBandwidth);
LL_INFOS("AppInit") << "Message System Initialized." << LL_ENDL;
//-------------------------------------------------
// Init audio, which may be needed for prefs dialog
// or audio cues in connection UI.
//-------------------------------------------------
if (FALSE == gSavedSettings.getBOOL("NoAudio"))
#ifdef LL_OPENAL
if (!gAudiop
#if !LL_WINDOWS
&& NULL == getenv("LL_BAD_OPENAL_DRIVER")
#endif // !LL_WINDOWS
)
{
gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL();
}
#endif
#ifdef LL_FMOD
if (!gAudiop
#if !LL_WINDOWS
&& NULL == getenv("LL_BAD_FMOD_DRIVER")
#endif // !LL_WINDOWS
)
{
gAudiop = (LLAudioEngine *) new LLAudioEngine_FMOD();
}
#endif
if (gAudiop)
{
#if LL_WINDOWS
// FMOD on Windows needs the window handle to stop playing audio
// when window is minimized. JC
void* window_handle = (HWND)gViewerWindow->getPlatformWindow();
bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle);
if(init)
{
gAudiop->setMuted(TRUE);
}
else
LL_WARNS("AppInit") << "Unable to initialize audio engine" << LL_ENDL;
delete gAudiop;
gAudiop = NULL;
if (gAudiop)
{
// if the audio engine hasn't set up its own preferred handler for streaming audio then set up the generic streaming audio implementation which uses media plugins
if (NULL == gAudiop->getStreamingAudioImpl())
{
LL_INFOS("AppInit") << "Using media plugins to render streaming audio" << LL_ENDL;
gAudiop->setStreamingAudioImpl(new LLStreamingAudio_MediaPlugins());
}
}
LL_INFOS("AppInit") << "Audio Engine Initialized." << LL_ENDL;
LL_WARNS("AppInit") << "Unreliable timers detected (may be bad PCI chipset)!!" << LL_ENDL;
//
// Log on to system
//
if (gUserCredential.isNull())
{
gUserCredential = gLoginHandler.initializeLoginInfo();
if (gUserCredential.isNull())
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;
if (STATE_BROWSER_INIT == LLStartUp::getStartupState())
LL_DEBUGS("AppInit") << "STATE_BROWSER_INIT" << LL_ENDL;
std::string msg = LLTrans::getString("LoginInitializingBrowser");
set_startup_status(0.03f, msg.c_str(), gAgent.mMOTD.c_str());
LLStartUp::setStartupState( STATE_LOGIN_SHOW );
return FALSE;
if (STATE_LOGIN_SHOW == LLStartUp::getStartupState())
{
LL_DEBUGS("AppInit") << "Initializing Window" << LL_ENDL;
gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
timeout_count = 0;
Josh Bell
committed
// 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.
if (gUserCredential.isNull())
{
gUserCredential = gLoginHandler.initializeLoginInfo();
}
LL_ERRS("AppInit") << "Need to autologin or use command line with norender!" << LL_ENDL;
}
// Make sure the process dialog doesn't hide things
gViewerWindow->setShowProgress(FALSE);
initialize_edit_menu();
// Show the login dialog
login_show();
Josh Bell
committed
// connect dialog is already shown, so fill in the names
if (gUserCredential.notNull())
{
LLPanelLogin::setFields( gUserCredential, gRememberPassword);
}
LLPanelLogin::giveFocus();
gSavedSettings.setBOOL("FirstRunThisInstall", FALSE);
LLStartUp::setStartupState( STATE_LOGIN_WAIT ); // Wait for user input
// skip directly to message template verification
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)
}
gViewerWindow->setNormalControlsVisible( FALSE );
gLoginMenuBarView->setVisible( TRUE );
// Hide the splash screen
LLSplashScreen::hide();
// Push our window frontmost
gViewerWindow->getWindow()->show();
display_startup();
// DEV-16927. The following code removes errant keystrokes that happen while the window is being
// first made visible.
#ifdef _WIN32
MSG msg;
while( PeekMessage( &msg, /*All hWnds owned by this thread */ NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE ) );
#endif
return FALSE;
if (STATE_LOGIN_WAIT == LLStartUp::getStartupState())
{
// Don't do anything. Wait for the login view to call the login_callback,
// which will push us to the next state.
// Sleep so we don't spin the CPU
ms_sleep(1);
return FALSE;
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
Roxie Linden
committed
// 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.
Josh Bell
committed
// TODO if not use viewer auth
// Load all the name information out of the login view
LLPanelLogin::getFields(gUserCredential, gRememberPassword);
Josh Bell
committed
// end TODO
// HACK: Try to make not jump on login
gKeyboard->resetKeys();
}
// 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;
Aaron Brashears
committed
// *FIX: these mkdir's should error check
gDirUtilp->setLindenUserDir(userid);
Tofu Linden
committed
LLFile::mkdir(gDirUtilp->getLindenUserDir());
Tofu Linden
committed
// 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")));
// Note: can't store warnings files per account because some come up before login
// Overwrite default user settings with user settings
LLAppViewer::instance()->loadSettingsFromDirectory("Account");
// Need to set the LastLogoff time here if we don't have one. LastLogoff is used for "Recent Items" calculation
// and startup time is close enough if we don't have a real value.
if (gSavedPerAccountSettings.getU32("LastLogoff") == 0)
{
gSavedPerAccountSettings.setU32("LastLogoff", time_corrected());
}
//Default the path if one isn't set.
// *NOTE: unable to check variable differ from "InstantMessageLogPath" because it was
// provided in pre 2.0 viewer. See EXT-6661
if (gSavedPerAccountSettings.getString("InstantMessageLogPath").empty())
{
gDirUtilp->setChatLogsDir(gDirUtilp->getOSUserAppDir());
gSavedPerAccountSettings.setString("InstantMessageLogPath", gDirUtilp->getChatLogsDir());
}
else
{
gDirUtilp->setChatLogsDir(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
}
gDirUtilp->setPerAccountChatLogsDir(userid);
LLFile::mkdir(gDirUtilp->getChatLogsDir());
LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir());
Igor Borovkov
committed
//good a place as any to create user windlight directories
std::string user_windlight_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight", ""));
LLFile::mkdir(user_windlight_path_name.c_str());
std::string user_windlight_skies_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", ""));
LLFile::mkdir(user_windlight_skies_path_name.c_str());
std::string user_windlight_water_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/water", ""));
LLFile::mkdir(user_windlight_water_path_name.c_str());
std::string user_windlight_days_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/days", ""));
LLFile::mkdir(user_windlight_days_path_name.c_str());
LLPanelLogin::closePanel();
Kyle Machulis
committed
// Load URL History File
LLURLHistory::loadFile("url_history.xml");
// Load location history
LLLocationHistory::getInstance()->load();
Steven Bennetts
committed
// Load Avatars icons cache
LLAvatarIconIDCache::getInstance()->load();
// Load media plugin cookies
LLViewerMedia::loadCookieFile();
Steven Bennetts
committed
//-------------------------------------------------
// Handle startup progress screen
//-------------------------------------------------
// on startup the user can request to go to their home,
// 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
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);
if (!gNoRender)
{
init_start_screen(agent_location_id);
}
// Display the startup progress bar.
gViewerWindow->setShowProgress(TRUE);
gViewerWindow->setProgressCancelButtonVisible(TRUE, LLTrans::getString("Quit"));
// 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);
LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT );
return FALSE;
if(STATE_LOGIN_AUTH_INIT == LLStartUp::getStartupState())
gDebugInfo["GridName"] = LLGridManager::getInstance()->getGridLabel();
Kyle Machulis
committed
// Update progress status and the display loop.
auth_desc = LLTrans::getString("LoginInProgress");
set_startup_status(progress, auth_desc, auth_message);
// Setting initial values...
LLLoginInstance* login = LLLoginInstance::getInstance();
login->setNotificationsInterface(LLNotifications::getInstance());
// HACK, skip optional updates if you're running drones
login->setSkipOptionalUpdate(true);
login->setUserInteraction(show_connect_box);
login->setSerialNumber(LLAppViewer::instance()->getSerialNumber());
login->setLastExecEvent(gLastExecEvent);
login->setUpdaterLauncher(boost::bind(&LLAppViewer::launchUpdater, LLAppViewer::instance()));
// This call to LLLoginInstance::connect() starts the
// authentication process.
login->connect(gUserCredential);
LLStartUp::setStartupState( STATE_LOGIN_CURL_UNSTUCK );
return FALSE;
}
if(STATE_LOGIN_CURL_UNSTUCK == LLStartUp::getStartupState())
{
// If we get here we have gotten past the potential stall
// in curl, so take "may appear frozen" out of progress bar. JC
auth_desc = LLTrans::getString("LoginInProgressNoFrozen");
set_startup_status(progress, auth_desc, auth_message);
LLStartUp::setStartupState( STATE_LOGIN_PROCESS_RESPONSE );
return FALSE;
if(STATE_LOGIN_PROCESS_RESPONSE == LLStartUp::getStartupState())
emsg << LLTrans::getString("LoginFailed") << "\n";
if(LLLoginInstance::getInstance()->authFailure())
{
LL_INFOS("LLStartup") << "Login failed, LLLoginInstance::getResponse(): "
<< LLLoginInstance::getInstance()->getResponse() << LL_ENDL;
LLSD response = LLLoginInstance::getInstance()->getResponse();