diff options
Diffstat (limited to 'indra')
23 files changed, 573 insertions, 658 deletions
diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py index 029b697e83..2408fab96f 100644 --- a/indra/lib/python/indra/util/llmanifest.py +++ b/indra/lib/python/indra/util/llmanifest.py @@ -38,6 +38,7 @@ import re import shutil import sys import tarfile +import errno def path_ancestors(path): path = os.path.normpath(path) @@ -463,6 +464,12 @@ class LLManifest(object): return # only copy if it's not excluded if(self.includes(src, dst)): + try: + os.unlink(dst) + except OSError, err: + if err.errno != errno.ENOENT: + raise + shutil.copy2(src, dst) def ccopytree(self, src, dst): diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp index df790433df..5e4dec7f82 100644 --- a/indra/llcommon/lluri.cpp +++ b/indra/llcommon/lluri.cpp @@ -40,6 +40,8 @@ #include "../llmath/lluuid.h" +// system includes +#include <boost/tokenizer.hpp> // static std::string LLURI::escape(const std::string& str, const std::string & allowed) @@ -130,7 +132,7 @@ LLURI::LLURI() LLURI::LLURI(const std::string& escaped_str) { - std::string::size_type delim_pos, delim_pos2; + std::string::size_type delim_pos; delim_pos = escaped_str.find(':'); std::string temp; if (delim_pos == std::string::npos) @@ -144,13 +146,39 @@ LLURI::LLURI(const std::string& escaped_str) mEscapedOpaque = escaped_str.substr(delim_pos+1); } - if (mScheme == "http" || mScheme == "https" || mScheme == "ftp") + parseAuthorityAndPathUsingOpaque(); + + delim_pos = mEscapedPath.find('?'); + if (delim_pos != std::string::npos) + { + mEscapedQuery = mEscapedPath.substr(delim_pos+1); + mEscapedPath = mEscapedPath.substr(0,delim_pos); + } +} + +static BOOL isDefault(const std::string& scheme, U16 port) +{ + if (scheme == "http") + return port == 80; + if (scheme == "https") + return port == 443; + if (scheme == "ftp") + return port == 21; + + return FALSE; +} + +void LLURI::parseAuthorityAndPathUsingOpaque() +{ + if (mScheme == "http" || mScheme == "https" || + mScheme == "ftp" || mScheme == "secondlife" ) { if (mEscapedOpaque.substr(0,2) != "//") { return; } - + + std::string::size_type delim_pos, delim_pos2; delim_pos = mEscapedOpaque.find('/', 2); delim_pos2 = mEscapedOpaque.find('?', 2); // no path, no query @@ -182,27 +210,12 @@ LLURI::LLURI(const std::string& escaped_str) mEscapedPath = mEscapedOpaque.substr(delim_pos); } } - - delim_pos = mEscapedPath.find('?'); - if (delim_pos != std::string::npos) + else if (mScheme == "about") { - mEscapedQuery = mEscapedPath.substr(delim_pos+1); - mEscapedPath = mEscapedPath.substr(0,delim_pos); + mEscapedPath = mEscapedOpaque; } } -static BOOL isDefault(const std::string& scheme, U16 port) -{ - if (scheme == "http") - return port == 80; - if (scheme == "https") - return port == 443; - if (scheme == "ftp") - return port == 21; - - return FALSE; -} - LLURI::LLURI(const std::string& scheme, const std::string& userName, const std::string& password, @@ -440,6 +453,22 @@ std::string LLURI::path() const return unescape(mEscapedPath); } +LLSD LLURI::pathArray() const +{ + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; + boost::char_separator<char> sep("/", "", boost::drop_empty_tokens); + tokenizer tokens(mEscapedPath, sep); + tokenizer::iterator it = tokens.begin(); + tokenizer::iterator end = tokens.end(); + + LLSD params; + for ( ; it != end; ++it) + { + params.append(*it); + } + return params; +} + std::string LLURI::query() const { return unescape(mEscapedQuery); diff --git a/indra/llcommon/lluri.h b/indra/llcommon/lluri.h index 3246dcd81f..bfe673c2f7 100644 --- a/indra/llcommon/lluri.h +++ b/indra/llcommon/lluri.h @@ -107,7 +107,7 @@ public: BOOL defaultPort() const; // true if port is default for scheme const std::string& escapedPath() const { return mEscapedPath; } std::string path() const; // ex.: "/abc/def", includes leading slash - // LLSD pathArray() const; // above decoded into an array of strings + LLSD pathArray() const; // above decoded into an array of strings std::string query() const; // ex.: "x=34", section after "?" const std::string& escapedQuery() const { return mEscapedQuery; } LLSD queryMap() const; // above decoded into a map @@ -135,6 +135,11 @@ public: //@} private: + // only "http", "https", "ftp", and "secondlife" schemes are parsed + // secondlife scheme parses authority as "" and includes it as part of + // the path. See lluri_tut.cpp + // i.e. secondlife://app/login has mAuthority = "" and mPath = "/app/login" + void parseAuthorityAndPathUsingOpaque(); std::string mScheme; std::string mEscapedOpaque; std::string mEscapedAuthority; diff --git a/indra/newview/linux_tools/handle_secondlifeprotocol.sh b/indra/newview/linux_tools/handle_secondlifeprotocol.sh new file mode 100755 index 0000000000..7ff86d1b93 --- /dev/null +++ b/indra/newview/linux_tools/handle_secondlifeprotocol.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# Send a URL of the form secondlife://... to Second Life. +# + +URL="$1" + +if [ -z "$URL" ]; then + echo Usage: $0 secondlife://... + exit +fi + +RUN_PATH=`dirname "$0" || echo .` +cd "${RUN_PATH}" + +exec ./secondlife -url \'"${URL}"\' + diff --git a/indra/newview/linux_tools/register_secondlifeprotocol.sh b/indra/newview/linux_tools/register_secondlifeprotocol.sh new file mode 100755 index 0000000000..4ab96f97d6 --- /dev/null +++ b/indra/newview/linux_tools/register_secondlifeprotocol.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# Register a protocol handler (default: handle_secondlifeprotocol.sh) for +# URLs of the form secondlife://... +# + +HANDLER="$1" + +RUN_PATH=`dirname "$0" || echo .` +cd "${RUN_PATH}" + +if [ -z "$HANDLER" ]; then + HANDLER=`pwd`/handle_secondlifeprotocol.sh +fi + +# Register handler for GNOME-aware apps +LLGCONFTOOL2=gconftool-2 +if which ${LLGCONFTOOL2} >/dev/null; then + (${LLGCONFTOOL2} -s -t string /desktop/gnome/url-handlers/secondlife/command "${HANDLER} \"%s\"" && ${LLGCONFTOOL2} -s -t bool /desktop/gnome/url-handlers/secondlife/enabled true) || echo Warning: Did not register secondlife:// handler with GNOME: ${LLGCONFTOOL2} failed. +else + echo Warning: Did not register secondlife:// handler with GNOME: ${LLGCONFTOOL2} not found. +fi + +# Register handler for KDE-aware apps +if [ -z "$KDEHOME" ]; then + KDEHOME=~/.kde +fi +LLKDEPROTDIR=${KDEHOME}/share/services +if [ -d "$LLKDEPROTDIR" ]; then + LLKDEPROTFILE=${LLKDEPROTDIR}/secondlife.protocol + cat > ${LLKDEPROTFILE} <<EOF || echo Warning: Did not register secondlife:// handler with KDE: Could not write ${LLKDEPROTFILE} +[Protocol] +exec=${HANDLER} '%u' +protocol=secondlife +input=none +output=none +helper=true +listing= +reading=false +writing=false +makedir=false +deleting=false +EOF +else + echo Warning: Did not register secondlife:// handler with KDE: Directory $LLKDEPROTDIR does not exist. +fi diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index 10041ee255..638a0f0b76 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -61,6 +61,10 @@ fi RUN_PATH=`dirname "$0" || echo .` cd "${RUN_PATH}" + +# Re-register the secondlife:// protocol handler every launch, for now. +./register_secondlifeprotocol.sh + if [ -n "$LL_TCMALLOC" ]; then tcmalloc_libs='/usr/lib/libtcmalloc.so.0 /usr/lib/libstacktrace.so.0 /lib/libpthread.so.0' all=1 diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index fc8d44e990..c0e9833829 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -58,6 +58,7 @@ #include "llviewerobjectlist.h" #include "llworldmap.h" #include "llmutelist.h" +#include "llurldispatcher.h" #include "llweb.h" #include "llsecondlifeurls.h" @@ -801,25 +802,22 @@ int parse_args(int argc, char **argv) } // some programs don't respect the command line options in protocol handlers (I'm looking at you, Opera) // so this allows us to parse the URL straight off the command line without a "-url" paramater - else if (!argument.compare(0, std::string( "secondlife://" ).length(), std::string("secondlife://"))) - { - // *NOTE: After setting the url, bail. What can happen is - // that someone can use IE (or potentially other browsers) - // and do the rough equivalent of command injection and - // steal passwords. Phoenix. SL-55321 - LLURLSimString::setString(argv[j]); - gArgs += argv[j]; - return 0; - } - else if (!strcmp(argv[j], "-url") && (++j < argc)) + else if (LLURLDispatcher::isSLURL(argv[j]) + || !strcmp(argv[j], "-url") && (++j < argc)) { + std::string slurl = argv[j]; + if (LLURLDispatcher::isSLURLCommand(slurl)) + { + LLStartUp::sSLURLCommand = slurl; + } + else + { + LLURLSimString::setString(slurl); + } // *NOTE: After setting the url, bail. What can happen is // that someone can use IE (or potentially other browsers) // and do the rough equivalent of command injection and // steal passwords. Phoenix. SL-55321 - LLURLSimString::setString(argv[j]); - gArgs += argv[j]; - return 0; } else if (!strcmp(argv[j], "-ignorepixeldepth")) { @@ -982,7 +980,8 @@ bool LLAppViewer::init() gSettingsFileName = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, DEFAULT_SETTINGS_FILE); gOldSettingsFileName = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, LEGACY_DEFAULT_SETTINGS_FILE); - initConfiguration(); + if (!initConfiguration()) + return false; ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -2071,7 +2070,7 @@ bool LLAppViewer::initConfiguration() if (send_url_to_other_instance(slurl)) { // successfully handed off URL to existing instance, exit - return 1; + return false; } } @@ -2089,7 +2088,7 @@ bool LLAppViewer::initConfiguration() msg.str().c_str(), NULL, OSMB_OK); - return 1; + return false; } initMarkerFile(); diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 63e7a6b129..e80491e786 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -42,6 +42,7 @@ #include "llmd5.h" #include "llurlsimstring.h" #include "llfloaterworldmap.h" +#include "llurldispatcher.h" #include <Carbon/Carbon.h> @@ -170,24 +171,8 @@ OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn) if(result == noErr) { - // Got the URL out of the event. - // secondlife:// - - // Parse it and stash in globals. - LLURLSimString::setString(buffer); - - if(gFloaterWorldMap != NULL) - { - // If the viewer's already logged in, pass it along directly. - if (LLURLSimString::parse()) - { - gFloaterWorldMap->trackURL(LLURLSimString::sInstance.mSimName, - LLURLSimString::sInstance.mX, - LLURLSimString::sInstance.mY, - LLURLSimString::sInstance.mZ); - LLFloaterWorldMap::show(NULL, TRUE); - } - } + std::string url = buffer; + LLURLDispatcher::dispatch(url); } return(result); diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp index fd3aef9afc..95a30e8903 100644 --- a/indra/newview/llcommandhandler.cpp +++ b/indra/newview/llcommandhandler.cpp @@ -46,7 +46,7 @@ class LLCommandHandlerRegistry public: static LLCommandHandlerRegistry& instance(); void add(const char* cmd, LLCommandHandler* handler); - bool dispatch(const std::string& cmd, const std::vector<std::string>& params); + bool dispatch(const std::string& cmd, const LLSD& params, const LLSD& queryMap); private: std::map<std::string, LLCommandHandler*> mMap; @@ -68,13 +68,14 @@ void LLCommandHandlerRegistry::add(const char* cmd, LLCommandHandler* handler) } bool LLCommandHandlerRegistry::dispatch(const std::string& cmd, - const std::vector<std::string>& params) + const LLSD& params, + const LLSD& queryMap) { std::map<std::string, LLCommandHandler*>::iterator it = mMap.find(cmd); if (it == mMap.end()) return false; LLCommandHandler* handler = it->second; if (!handler) return false; - return handler->handle(params); + return handler->handle(params, queryMap); } //--------------------------------------------------------------------------- @@ -97,7 +98,7 @@ LLCommandHandler::~LLCommandHandler() //--------------------------------------------------------------------------- // static -bool LLCommandDispatcher::dispatch(const std::string& cmd, const std::vector<std::string>& params) +bool LLCommandDispatcher::dispatch(const std::string& cmd, const LLSD& params, const LLSD& queryMap) { - return LLCommandHandlerRegistry::instance().dispatch(cmd, params); + return LLCommandHandlerRegistry::instance().dispatch(cmd, params, queryMap); } diff --git a/indra/newview/llcommandhandler.h b/indra/newview/llcommandhandler.h index 50928e210b..0cb9d123fa 100644 --- a/indra/newview/llcommandhandler.h +++ b/indra/newview/llcommandhandler.h @@ -44,7 +44,7 @@ public: LLFooHandler() : LLCommandHandler("foo") { } // Your code here - bool handle(const std::vector<std::string>& tokens) + bool handle(const LLSD& tokens, const LLSD& queryMap) { if (tokens.size() < 1) return false; LLUUID id( tokens[0] ); @@ -65,7 +65,8 @@ public: virtual ~LLCommandHandler(); - virtual bool handle(const std::vector<std::string>& params) = 0; + virtual bool handle(const LLSD& params, + const LLSD& queryMap) = 0; // Execute the command with a provided (possibly empty) // list of parameters. // Return true if you did something, false if the parameters @@ -76,7 +77,9 @@ public: class LLCommandDispatcher { public: - static bool dispatch(const std::string& cmd, const std::vector<std::string>& params); + static bool dispatch(const std::string& cmd, + const LLSD& params, + const LLSD& queryMap); // Execute a command registered via the above mechanism, // passing string parameters. // Returns true if command was found and executed correctly. diff --git a/indra/newview/llfloaterevent.cpp b/indra/newview/llfloaterevent.cpp index 2b9d011e90..89f738203c 100644 --- a/indra/newview/llfloaterevent.cpp +++ b/indra/newview/llfloaterevent.cpp @@ -34,14 +34,14 @@ class LLEventHandler : public LLCommandHandler { public: LLEventHandler() : LLCommandHandler("event") { } - bool handle(const std::vector<std::string>& tokens) + bool handle(const LLSD& tokens, const LLSD& queryMap) { if (tokens.size() < 2) { return false; } - U32 event_id = atoi(tokens[0].c_str()); - if (tokens[1] == "about") + U32 event_id = tokens[0].asInteger(); + if (tokens[1].asString() == "about") { LLFloaterEventInfo::show(event_id); return true; diff --git a/indra/newview/llfloaterparcel.cpp b/indra/newview/llfloaterparcel.cpp index 61b7176153..f737188b34 100644 --- a/indra/newview/llfloaterparcel.cpp +++ b/indra/newview/llfloaterparcel.cpp @@ -29,7 +29,7 @@ class LLParcelHandler : public LLCommandHandler { public: LLParcelHandler() : LLCommandHandler("parcel") { } - bool handle(const std::vector<std::string>& params) + bool handle(const LLSD& params, const LLSD& queryMap) { if (params.size() < 2) { @@ -40,7 +40,7 @@ public: { return false; } - if (params[1] == "about") + if (params[1].asString() == "about") { LLFloaterParcelInfo::show(parcel_id); return true; diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 100ae0cfae..25a88e6e7c 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -47,13 +47,16 @@ #include "llspinctrl.h" #include "message.h" +#include "llcommandhandler.h" #include "llfloaterabout.h" +#include "llfloaterpreference.h" #include "llpanelnetwork.h" #include "llpanelaudioprefs.h" #include "llpaneldisplay.h" #include "llpaneldebug.h" #include "llpanelgeneral.h" #include "llpanelinput.h" +#include "llpanellogin.h" #include "llpanelLCD.h" #include "llpanelmsgs.h" #include "llpanelweb.h" @@ -71,6 +74,13 @@ #include "llkeyboard.h" #include "llscrollcontainer.h" +#if LL_WINDOWS +// for Logitech LCD keyboards / speakers +#ifndef LL_LOGITECH_LCD_H +#include "lllogitechlcd.h" +#endif +extern llLCD *gLcdScreen; +#endif const S32 PREF_BORDER = 4; const S32 PREF_PAD = 5; @@ -81,13 +91,20 @@ const S32 PREF_FLOATER_MIN_HEIGHT = 2 * SCROLLBAR_SIZE + 2 * LLPANEL_BORDER_WIDT LLFloaterPreference* LLFloaterPreference::sInstance = NULL; -#if LL_WINDOWS -// for Logitech LCD keyboards / speakers -#ifndef LL_LOGITECH_LCD_H -#include "lllogitechlcd.h" -#endif -extern llLCD *gLcdScreen; -#endif + +class LLPreferencesHandler : public LLCommandHandler +{ +public: + LLPreferencesHandler() : LLCommandHandler("preferences") { } + bool handle(const LLSD& tokens, const LLSD& queryMap) + { + LLFloaterPreference::show(NULL); + return true; + } +}; + +LLPreferencesHandler gPreferencesHandler; + // Must be done at run time, not compile time. JC S32 pref_min_width() @@ -410,6 +427,8 @@ void LLFloaterPreference::show(void*) gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); gAgent.sendReliableMessage(); } + + LLPanelLogin::setAlwaysRefresh(true); } @@ -423,6 +442,9 @@ void LLFloaterPreference::onClickAbout(void*) // static void LLFloaterPreference::onBtnOK( void* userdata ) { + //refresh splash page if we're displaying it + LLPanelLogin::loadLoginPage(); + LLFloaterPreference *fp =(LLFloaterPreference *)userdata; // commit any outstanding text entry if (fp->hasFocus()) @@ -466,6 +488,16 @@ void LLFloaterPreference::onBtnApply( void* userdata ) } } fp->apply(); + + //refresh splash page if we're displaying it + LLPanelLogin::loadLoginPage(); +} + + +void LLFloaterPreference::onClose(bool app_quitting) +{ + LLPanelLogin::setAlwaysRefresh(false); + LLFloater::onClose(app_quitting); } diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index a4c43fc8d6..bf554766b7 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -117,6 +117,7 @@ protected: LLPreferenceCore *mPreferenceCore; /*virtual*/ void draw(); + /*virtual*/ void onClose(bool app_quitting); LLButton* mAboutBtn; LLButton *mOKBtn; diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index fe07175529..8ebdb14e15 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -44,13 +44,16 @@ #include "llbutton.h" #include "llcheckboxctrl.h" +#include "llcommandhandler.h" #include "llcombobox.h" +#include "llcurl.h" #include "llviewercontrol.h" #include "llfloaterabout.h" #include "llfloatertest.h" #include "llfloaterpreference.h" #include "llfocusmgr.h" #include "lllineeditor.h" +#include "llstartup.h" #include "lltextbox.h" #include "llui.h" #include "lluiconstants.h" @@ -74,11 +77,145 @@ #include "llglheaders.h" +LLString load_password_from_disk(void); +void save_password_to_disk(const char* hashed_password); + const S32 BLACK_BORDER_HEIGHT = 160; const S32 MAX_PASSWORD = 16; LLPanelLogin *LLPanelLogin::sInstance = NULL; -BOOL LLPanelLogin::sCapslockDidNotification = FALSE; + + +//parses the input url and returns true if afterwards +//a web-login-key, firstname and lastname is set +bool LLLoginHandler::parseDirectLogin(std::string url) +{ + LLURI uri(url); + parse(uri.queryMap()); + + if (mWebLoginKey.isNull() || + mFirstName.empty() || + mLastName.empty()) + { + return false; + } + else + { + return true; + } +} + + +void LLLoginHandler::parse(const LLSD& queryMap) +{ + mWebLoginKey = queryMap["web_login_key"].asUUID(); + mFirstName = queryMap["first_name"].asString(); + mLastName = queryMap["last_name"].asString(); + + if (queryMap["grid"].asString() == "aditi") + { + gGridChoice = GRID_INFO_ADITI; + } + else if (queryMap["grid"].asString() == "agni") + { + gGridChoice = GRID_INFO_AGNI; + } + else if (queryMap["grid"].asString() == "siva") + { + gGridChoice = GRID_INFO_SIVA; + } + else if (queryMap["grid"].asString() == "durga") + { + gGridChoice = GRID_INFO_DURGA; + } + else if (queryMap["grid"].asString() == "shakti") + { + gGridChoice = GRID_INFO_SHAKTI; + } + else if (queryMap["grid"].asString() == "soma") + { + gGridChoice = GRID_INFO_SOMA; + } + else if (queryMap["grid"].asString() == "ganga") + { + gGridChoice = GRID_INFO_GANGA; + } + else if (queryMap["grid"].asString() == "vaak") + { + gGridChoice = GRID_INFO_VAAK; + } + else if (queryMap["grid"].asString() == "uma") + { + gGridChoice = GRID_INFO_UMA; + } + + snprintf(gGridName, MAX_STRING, "%s", gGridInfo[gGridChoice].mName); /* Flawfinder: ignore */ + LLAppViewer::instance()->resetURIs(); + + LLString startLocation = queryMap["location"].asString(); + + if (startLocation == "specify") + { + LLURLSimString::setString(queryMap["region"].asString()); + } + else if (startLocation == "home") + { + gSavedSettings.setBOOL("LoginLastLocation", FALSE); + LLURLSimString::setString(""); + } + else if (startLocation == "last") + { + gSavedSettings.setBOOL("LoginLastLocation", TRUE); + LLURLSimString::setString(""); + } +} + +bool LLLoginHandler::handle(const LLSD& tokens, + const LLSD& queryMap) +{ + parse(queryMap); + + //if we haven't initialized stuff yet, this is + //coming in from the GURL handler, just parse + if (STATE_FIRST == LLStartUp::getStartupState()) + { + return true; + } + + LLString password = queryMap["password"].asString(); + + if (!password.empty()) + { + gSavedSettings.setBOOL("RememberPassword", TRUE); + + if (password.substr(0,3) != "$1$") + { + LLMD5 pass((unsigned char*)password.c_str()); + char md5pass[33]; /* Flawfinder: ignore */ + pass.hex_digest(md5pass); + password = md5pass; + save_password_to_disk(password.c_str()); + } + } + else + { + save_password_to_disk(NULL); + gSavedSettings.setBOOL("RememberPassword", FALSE); + } + + + if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) //on splash page + { + if (mWebLoginKey.isNull()) { + LLPanelLogin::loadLoginPage(); + } else { + LLStartUp::setStartupState( STATE_LOGIN_CLEANUP ); + } + } + return true; +} + +LLLoginHandler gLoginHandler; // helper class that trys to download a URL from a web site and calls a method // on parent class indicating if the web server is working or not @@ -157,92 +294,11 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, mLogoImage = gImageList.getImage("startup_logo.tga", LLUUID::null, MIPMAP_FALSE, TRUE); gUICtrlFactory->buildPanel(this, "panel_login.xml"); - //setRect(rect); + + //leave room for the login menu bar + setRect(LLRect(0, rect.getHeight()-18, rect.getWidth(), 0)); reshape(rect.getWidth(), rect.getHeight()); - - childSetPrevalidate("first_name_edit", LLLineEditor::prevalidatePrintableNoSpace); - childSetPrevalidate("last_name_edit", LLLineEditor::prevalidatePrintableNoSpace); - - childSetCommitCallback("password_edit", mungePassword); - childSetKeystrokeCallback("password_edit", onPassKey, this); - childSetUserData("password_edit", this); - - LLLineEditor* edit = LLUICtrlFactory::getLineEditorByName(this, "password_edit"); - if (edit) edit->setDrawAsterixes(TRUE); - - LLComboBox* combo = LLUICtrlFactory::getComboBoxByName(this, "start_location_combo"); - if (combo) - { - combo->setAllowTextEntry(TRUE, 128, FALSE); - - // The XML file loads the combo with the following labels: - // 0 - "My Home" - // 1 - "My Last Location" - // 2 - "<Type region name>" - - BOOL login_last = gSavedSettings.getBOOL("LoginLastLocation"); - LLString sim_string = LLURLSimString::sInstance.mSimString; - if (!sim_string.empty()) - { - // Replace "<Type region name>" with this region name - combo->remove(2); - combo->add( sim_string ); - combo->setTextEntry(sim_string); - combo->setCurrentByIndex( 2 ); - } - else if (login_last) - { - combo->setCurrentByIndex( 1 ); - } - else - { - combo->setCurrentByIndex( 0 ); - } - - combo->setCommitCallback( &LLPanelGeneral::set_start_location ); - } - // Specific servers added later. - childSetVisible("server_combo", show_server); - - childSetAction("new_account_btn", onClickNewAccount, this); - childSetVisible("new_account_btn", !gHideLinks); - - childSetAction("connect_btn", onClickConnect, this); - - setDefaultBtn("connect_btn"); - - childSetAction("preferences_btn", LLFloaterPreference::show, this); - - childSetAction("quit_btn", onClickQuit, this); - - LLTextBox* version_text = LLUICtrlFactory::getTextBoxByName(this, "version_text"); - if (version_text) - { - LLString version = llformat("%d.%d.%d (%d)", - LL_VERSION_MAJOR, - LL_VERSION_MINOR, - LL_VERSION_PATCH, - LL_VIEWER_BUILD ); - version_text->setText(version); - version_text->setClickedCallback(onClickVersion); - version_text->setCallbackUserData(this); - } - - LLTextBox* channel_text = LLUICtrlFactory::getTextBoxByName(this, "channel_text"); - if (channel_text) - { - channel_text->setText(gChannelName); - channel_text->setClickedCallback(onClickVersion); - channel_text->setCallbackUserData(this); - } - - LLTextBox* forgot_password_text = LLUICtrlFactory::getTextBoxByName(this, "forgot_password_text"); - if (forgot_password_text) - { - forgot_password_text->setClickedCallback(onClickForgotPassword); - } - // get the web browser control #if LL_LIBXUL_ENABLED LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(this, "login_html"); @@ -266,11 +322,11 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, // force the size to be correct (XML doesn't seem to be sufficient to do this) (with some padding so the other login screen doesn't show through) LLRect htmlRect = mRect; - htmlRect.setCenterAndSize( mRect.getCenterX() - 2, mRect.getCenterY() + 40, mRect.getWidth() + 6, mRect.getHeight() - 78 ); + htmlRect.setCenterAndSize( mRect.getCenterX() - 2, mRect.getCenterY(), mRect.getWidth() + 6, mRect.getHeight()); web_browser->setRect( htmlRect ); web_browser->reshape( htmlRect.getWidth(), htmlRect.getHeight(), TRUE ); - reshape( mRect.getWidth(), mRect.getHeight(), 1 ); - + reshape( mRect.getWidth(), mRect.getHeight(), 1 ); + // kick off a request to grab the url manually gResponsePtr = LLIamHereLogin::build( this ); LLHTTPClient::get( childGetValue( "real_url" ).asString(), gResponsePtr ); @@ -280,7 +336,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, #endif // Initialize visibility (and don't force visibility - use prefs) - refreshLocation( false ); } void LLPanelLogin::setSiteIsAlive( bool alive ) @@ -292,9 +347,8 @@ void LLPanelLogin::setSiteIsAlive( bool alive ) { if ( web_browser ) { - // navigate to the "real" page - web_browser->navigateTo( childGetValue( "real_url" ).asString() ); - + loadLoginPage(); + // mark as available mHtmlAvailable = TRUE; }; @@ -316,21 +370,6 @@ void LLPanelLogin::setSiteIsAlive( bool alive ) #endif } -void LLPanelLogin::mungePassword(LLUICtrl* caller, void* user_data) -{ - LLPanelLogin* self = (LLPanelLogin*)user_data; - LLLineEditor* editor = (LLLineEditor*)caller; - std::string password = editor->getText(); - - // Re-md5 if we've changed at all - if (password != self->mIncomingPassword) - { - LLMD5 pass((unsigned char *)password.c_str()); - char munged_password[MD5HEX_STR_SIZE]; - pass.hex_digest(munged_password); - self->mMungedPassword = munged_password; - } -} LLPanelLogin::~LLPanelLogin() { @@ -366,13 +405,6 @@ void LLPanelLogin::draw() glTranslatef(-0.5f * (image_aspect / view_aspect - 1.f) * mRect.getWidth(), 0.f, 0.f); glScalef(image_aspect / view_aspect, 1.f, 1.f); } - // Don't maintain aspect ratio if screen wider than image. This results in the - // hand being partially cut off. JC - //else - //{ - // glTranslatef(0.f, -0.5f * (view_aspect / image_aspect - 1.f) * (F32)BLACK_BORDER_HEIGHT, 0.f); - // glScalef(1.f, view_aspect / image_aspect, 1.f); - //} S32 width = mRect.getWidth(); S32 height = mRect.getHeight(); @@ -381,9 +413,6 @@ void LLPanelLogin::draw() { // draw a background box in black gl_rect_2d( 0, height - 264, width, 264, LLColor4( 0.0f, 0.0f, 0.0f, 1.f ) ); - - // draw the bottom part of the background image - just the blue background to the native client UI - gl_draw_scaled_image(0, -264, width + 8, mLogoImage->getHeight(), mLogoImage); } else { @@ -451,54 +480,14 @@ BOOL LLPanelLogin::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) return LLPanel::handleKeyHere(key, mask, called_from_parent); } - -// virtual -void LLPanelLogin::setFocus(BOOL b) -{ - if(b != hasFocus()) - { - if(b) - { - LLPanelLogin::giveFocus(); - } - else - { - LLPanel::setFocus(b); - } - } -} + // static void LLPanelLogin::giveFocus() { - if( sInstance ) - { - // Grab focus and move cursor to first blank input field - std::string first = sInstance->childGetText("first_name_edit"); - std::string pass = sInstance->childGetText("password_edit"); - - BOOL have_first = !first.empty(); - BOOL have_pass = !pass.empty(); - - LLLineEditor* edit = NULL; - if (have_first && !have_pass) - { - // User saved his name but not his password. Move - // focus to password field. - edit = LLUICtrlFactory::getLineEditorByName(sInstance, "password_edit"); - } - else - { - // User doesn't have a name, so start there. - edit = LLUICtrlFactory::getLineEditorByName(sInstance, "first_name_edit"); - } - if (edit) - { - edit->setFocus(TRUE); - edit->selectAll(); - } - } + if (sInstance) + sInstance->setFocus(TRUE); } @@ -510,266 +499,156 @@ void LLPanelLogin::show(const LLRect &rect, { new LLPanelLogin(rect, show_server, callback, callback_data); + LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(sInstance, "login_html"); + + if (!web_browser) return; + if( !gFocusMgr.getKeyboardFocus() ) { // Grab focus and move cursor to first enabled control - sInstance->setFocus(TRUE); + web_browser->setFocus(TRUE); } // Make sure that focus always goes here (and use the latest sInstance that was just created) - gFocusMgr.setDefaultKeyboardFocus(sInstance); + gFocusMgr.setDefaultKeyboardFocus(web_browser); } + // static -void LLPanelLogin::setFields(const std::string& firstname, const std::string& lastname, const std::string& password, - BOOL remember) +void LLPanelLogin::close() { - if (!sInstance) + if (sInstance) { - llwarns << "Attempted fillFields with no login view shown" << llendl; - return; - } - - sInstance->childSetText("first_name_edit", firstname); - sInstance->childSetText("last_name_edit", lastname); + gViewerWindow->getRootView()->removeChild( LLPanelLogin::sInstance ); + + gFocusMgr.setDefaultKeyboardFocus(NULL); - // Max "actual" password length is 16 characters. - // Hex digests are always 32 characters. - if (password.length() == 32) - { - // This is a MD5 hex digest of a password. - // We don't actually use the password input field, - // fill it with MAX_PASSWORD characters so we get a - // nice row of asterixes. - const std::string filler("123456789!123456"); - sInstance->childSetText("password_edit", filler); - sInstance->mIncomingPassword = filler; - sInstance->mMungedPassword = password; - } - else - { - // this is a normal text password - sInstance->childSetText("password_edit", password); - sInstance->mIncomingPassword = password; - LLMD5 pass((unsigned char *)password.c_str()); - char munged_password[MD5HEX_STR_SIZE]; - pass.hex_digest(munged_password); - sInstance->mMungedPassword = munged_password; + delete sInstance; + sInstance = NULL; } - - sInstance->childSetValue("remember_check", remember); } - // static -void LLPanelLogin::addServer(const char *server, S32 domain_name) +void LLPanelLogin::setAlwaysRefresh(bool refresh) { - if (!sInstance) - { - llwarns << "Attempted addServer with no login view shown" << llendl; - return; - } + if (LLStartUp::getStartupState() >= STATE_LOGIN_CLEANUP) return; - LLComboBox* combo = LLUICtrlFactory::getComboBoxByName(sInstance, "server_combo"); - if (combo) + LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(sInstance, "login_html"); + + if (web_browser) { - combo->add(server, LLSD(domain_name) ); - combo->setCurrentByIndex(0); + web_browser->setAlwaysRefresh(refresh); } } -// static -void LLPanelLogin::getFields(LLString &firstname, LLString &lastname, LLString &password, - BOOL &remember) -{ - if (!sInstance) - { - llwarns << "Attempted getFields with no login view shown" << llendl; - return; - } - firstname = sInstance->childGetText("first_name_edit"); - LLString::trim(firstname); - lastname = sInstance->childGetText("last_name_edit"); - LLString::trim(lastname); +void LLPanelLogin::loadLoginPage() +{ + if (!sInstance) return; - password = sInstance->mMungedPassword; - remember = sInstance->childGetValue("remember_check"); -} + LLURLSimString::sInstance.parse(); + LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(sInstance, "login_html"); -// static. Return TRUE if user made a choice from the popup -BOOL LLPanelLogin::getServer(LLString &server, S32 &domain_name) -{ - BOOL user_picked = FALSE; - if (!sInstance) + std::ostringstream oStr; + + LLString location; + LLString region; + LLString password; + + if (LLURLSimString::parse()) { - llwarns << "Attempted getServer with no login view shown" << llendl; + std::ostringstream oRegionStr; + location = "specify"; + oRegionStr << LLURLSimString::sInstance.mSimName << "/" << LLURLSimString::sInstance.mX << "/" + << LLURLSimString::sInstance.mY << "/" + << LLURLSimString::sInstance.mZ; + region = oRegionStr.str(); } else { - LLComboBox* combo = LLUICtrlFactory::getComboBoxByName(sInstance, "server_combo"); - if (combo) + if (gSavedSettings.getBOOL("LoginLastLocation")) { - LLSD combo_val = combo->getValue(); - if (LLSD::TypeInteger == combo_val.type()) - { - domain_name = combo->getValue().asInteger(); - - if ((S32)GRID_INFO_OTHER == domain_name) - { - server = gGridName; - } - } - else - { - // no valid selection, return other - domain_name = (S32)GRID_INFO_OTHER; - server = combo_val.asString(); - } - user_picked = combo->isDirty(); + location = "last"; + } + else + { + location = "home"; } } - - return user_picked; -} - -// static -void LLPanelLogin::getLocation(LLString &location) -{ - if (!sInstance) + + LLString firstname, lastname; + + if (gCmdLineFirstName.empty()) { - llwarns << "Attempted getLocation with no login view shown" << llendl; - return; + firstname = gSavedSettings.getString("FirstName"); } - - LLComboBox* combo = LLUICtrlFactory::getComboBoxByName(sInstance, "start_location_combo"); - if (combo) + else { - location = combo->getValue().asString(); + firstname = gCmdLineFirstName; } -} - -// static -void LLPanelLogin::refreshLocation( bool force_visible ) -{ - if (!sInstance) return; - - LLComboBox* combo = LLUICtrlFactory::getComboBoxByName(sInstance, "start_location_combo"); - if (!combo) return; - - LLString sim_string = LLURLSimString::sInstance.mSimString; - if (!sim_string.empty()) + + if (gCmdLineLastName.empty()) { - combo->setCurrentByIndex( 3 ); // BUG? Maybe 2? - combo->setTextEntry(sim_string); + lastname = gSavedSettings.getString("LastName"); } else { - BOOL login_last = gSavedSettings.getBOOL("LoginLastLocation"); - combo->setCurrentByIndex( login_last ? 1 : 0 ); + lastname = gCmdLineLastName; } + + LLString version = llformat("%d.%d.%d (%d)", + LL_VERSION_MAJOR, LL_VERSION_MINOR, LL_VERSION_PATCH, LL_VIEWER_BUILD); - BOOL show_start = TRUE; - - if ( ! force_visible ) - show_start = gSavedSettings.getBOOL("ShowStartLocation"); - - sInstance->childSetVisible("start_location_combo", show_start); - sInstance->childSetVisible("start_location_text", show_start); -} - -// static -void LLPanelLogin::close() -{ - if (sInstance) - { - gViewerWindow->getRootView()->removeChild( LLPanelLogin::sInstance ); - - gFocusMgr.setDefaultKeyboardFocus(NULL); - - delete sInstance; - sInstance = NULL; - } -} + char* curl_region = curl_escape(region.c_str(), 0); + char* curl_channel = curl_escape(gChannelName.c_str(), 0); + char* curl_version = curl_escape(version.c_str(), 0); + + oStr << sInstance->childGetValue( "real_url" ).asString() << "&firstname=" << firstname << + "&lastname=" << lastname << "&location=" << location << "®ion=" << curl_region << + "&grid=" << gGridInfo[gGridChoice].mLabel << "&channel=" << curl_channel << + "&version=" << curl_version; -//--------------------------------------------------------------------------- -// Protected methods -//--------------------------------------------------------------------------- + + curl_free(curl_region); + curl_free(curl_channel); + curl_free(curl_version); -// static -void LLPanelLogin::onClickConnect(void *) -{ - if (sInstance && sInstance->mCallback) + if (!gCmdLinePassword.empty()) { - // tell the responder we're not here anymore - if ( gResponsePtr ) - gResponsePtr->setParent( 0 ); - - // JC - Make sure the fields all get committed. - sInstance->setFocus(FALSE); - - LLString first = sInstance->childGetText("first_name_edit"); - LLString last = sInstance->childGetText("last_name_edit"); - if (!first.empty() && !last.empty()) - { - // has both first and last name typed - - // store off custom server entry, if currently selected - LLComboBox* combo = LLUICtrlFactory::getComboBoxByName(sInstance, "server_combo"); - if (combo) - { - S32 selected_server = combo->getValue(); - if (selected_server == GRID_INFO_NONE) - { - LLString custom_server = combo->getValue().asString(); - gSavedSettings.setString("CustomServer", custom_server); - } - } - sInstance->mCallback(0, sInstance->mCallbackData); - } - else - { - // empty first or last name - // same as clicking new account - onClickNewAccount(NULL); - } + oStr << "&password=" << gCmdLinePassword; } -} - - -// static -void LLPanelLogin::newAccountAlertCallback(S32 option, void*) -{ - if (0 == option) + else if (!(password = load_password_from_disk()).empty()) { - llinfos << "Going to account creation URL" << llendl; - LLWeb::loadURL( CREATE_ACCOUNT_URL ); + oStr << "&password=$1$" << password; } - else + if (gAutoLogin) { - sInstance->setFocus(TRUE); + oStr << "&auto_login=TRUE"; } -} - - -// static -void LLPanelLogin::onClickNewAccount(void*) -{ - if (gHideLinks) + if (gSavedSettings.getBOOL("ShowStartLocation")) { - gViewerWindow->alertXml("MustHaveAccountToLogInNoLinks"); - } - else + oStr << "&show_start_location=TRUE"; + } + if (gSavedSettings.getBOOL("RememberPassword")) { - gViewerWindow->alertXml("MustHaveAccountToLogIn", - LLPanelLogin::newAccountAlertCallback); - } + oStr << "&remember_password=TRUE"; + } +#ifndef LL_RELEASE_FOR_DOWNLOAD + oStr << "&show_grid=TRUE"; +#endif + + // navigate to the "real" page + web_browser->navigateTo( oStr.str() ); } +//--------------------------------------------------------------------------- +// Protected methods +//--------------------------------------------------------------------------- + // static void LLPanelLogin::onClickQuit(void*) { @@ -789,22 +668,3 @@ void LLPanelLogin::onClickVersion(void*) { LLFloaterAbout::show(NULL); } - -void LLPanelLogin::onClickForgotPassword(void*) -{ - if (sInstance ) - { - LLWeb::loadURL(sInstance->childGetValue( "forgot_password_url" ).asString()); - } -} - - -// static -void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data) -{ - if (gKeyboard->getKeyDown(KEY_CAPSLOCK) && sCapslockDidNotification == FALSE) - { - LLNotifyBox::showXml("CapsKeyOn"); - sCapslockDidNotification = TRUE; - } -} diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index 447b9ea01c..191e88c25b 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -33,7 +33,7 @@ #define LL_LLPANELLOGIN_H #include "llpanel.h" - +#include "llcommandhandler.h" #include "lldbstrings.h" #include "llmemory.h" #include "llviewerimage.h" @@ -46,6 +46,22 @@ class LLCheckBoxCtrl; class LLButton; class LLComboBox; + +class LLLoginHandler : public LLCommandHandler +{ + public: + LLLoginHandler() : LLCommandHandler("login") { } + bool handle(const LLSD& tokens, const LLSD& queryMap); + bool parseDirectLogin(std::string url); + void parse(const LLSD& queryMap); + + LLUUID mWebLoginKey; + LLString mFirstName; + LLString mLastName; +}; + +extern LLLoginHandler gLoginHandler; + class LLPanelLogin : public LLPanel { @@ -57,39 +73,22 @@ public: virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); virtual void draw(); - virtual void setFocus( BOOL b ); static void show(const LLRect &rect, BOOL show_server, void (*callback)(S32 option, void* user_data), void* callback_data); - static void setFields(const std::string& firstname, const std::string& lastname, - const std::string& password, BOOL remember); - - static void addServer(const char *server, S32 domain_name); - static void refreshLocation( bool force_visible ); - - static void getFields(LLString &firstname, LLString &lastname, - LLString &password, BOOL &remember); - - static BOOL getServer(LLString &server, S32& domain_name); - static void getLocation(LLString &location); - static void close(); void setSiteIsAlive( bool alive ); - static void giveFocus(); - static void mungePassword(LLUICtrl* caller, void* user_data); - + static void loadLoginPage(); + static void giveFocus(); + static void setAlwaysRefresh(bool refresh); + private: - static void onClickConnect(void*); - static void onClickNewAccount(void*); - static void newAccountAlertCallback(S32 option, void*); static void onClickQuit(void*); static void onClickVersion(void*); - static void onClickForgotPassword(void*); - static void onPassKey(LLLineEditor* caller, void* user_data); private: LLPointer<LLViewerImage> mLogoImage; @@ -97,11 +96,7 @@ private: void (*mCallback)(S32 option, void *userdata); void* mCallbackData; - std::string mIncomingPassword; - std::string mMungedPassword; - static LLPanelLogin* sInstance; - static BOOL sCapslockDidNotification; BOOL mHtmlAvailable; }; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index d5af7243a0..267b2340d0 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -329,6 +329,7 @@ BOOL idle_startup() static std::string auth_message; static LLString firstname; static LLString lastname; + static LLUUID web_login_key; static LLString password; static std::vector<const char*> requested_options; @@ -348,7 +349,6 @@ BOOL idle_startup() static S32 location_which = START_LOCATION_ID_LAST; static BOOL show_connect_box = TRUE; - static BOOL remember_password = TRUE; static BOOL stipend_since_login = FALSE; @@ -634,28 +634,34 @@ BOOL idle_startup() // // Log on to system // - if( !gCmdLineFirstName.empty() + if ((!gLoginHandler.mFirstName.empty() && + !gLoginHandler.mLastName.empty() && + !gLoginHandler.mWebLoginKey.isNull()) + || gLoginHandler.parseDirectLogin(LLStartUp::sSLURLCommand) ) + { + firstname = gLoginHandler.mFirstName; + lastname = gLoginHandler.mLastName; + web_login_key = gLoginHandler.mWebLoginKey; + + show_connect_box = FALSE; + } + else if( !gCmdLineFirstName.empty() && !gCmdLineLastName.empty() && !gCmdLinePassword.empty()) { firstname = gCmdLineFirstName; lastname = gCmdLineLastName; - LLMD5 pass((unsigned char*)gCmdLinePassword.c_str()); - char md5pass[33]; /* Flawfinder: ignore */ - pass.hex_digest(md5pass); - password = md5pass; - - remember_password = gSavedSettings.getBOOL("RememberPassword"); - show_connect_box = FALSE; + show_connect_box = TRUE; + gAutoLogin = TRUE; } else if (gAutoLogin || gSavedSettings.getBOOL("AutoLogin")) { firstname = gSavedSettings.getString("FirstName"); lastname = gSavedSettings.getString("LastName"); password = load_password_from_disk(); - remember_password = TRUE; - show_connect_box = FALSE; + gSavedSettings.setBOOL("RememberPassword", TRUE); + show_connect_box = TRUE; } else { @@ -664,7 +670,6 @@ BOOL idle_startup() firstname = gSavedSettings.getString("FirstName"); lastname = gSavedSettings.getString("LastName"); password = load_password_from_disk(); - remember_password = gSavedSettings.getBOOL("RememberPassword"); show_connect_box = TRUE; } @@ -674,7 +679,8 @@ BOOL idle_startup() } if (STATE_LOGIN_SHOW == LLStartUp::getStartupState()) - { + { + llinfos << "Initializing Window" << llendl; gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW); @@ -695,8 +701,6 @@ BOOL idle_startup() // Show the login dialog login_show(); - // connect dialog is already shown, so fill in the names - LLPanelLogin::setFields( firstname, lastname, password, remember_password ); LLPanelLogin::giveFocus(); gSavedSettings.setBOOL("FirstRunThisInstall", FALSE); @@ -708,6 +712,31 @@ BOOL idle_startup() // skip directly to message template verification LLStartUp::setStartupState( STATE_LOGIN_CLEANUP ); } + + // Create selection manager + // Must be done before menus created, because many enabled callbacks + // require its existance. + gSelectMgr = new LLSelectMgr(); + gParcelMgr = new LLViewerParcelMgr(); + gHUDManager = new LLHUDManager(); + gMuteListp = new LLMuteList(); + + // Initialize UI + if (!gNoRender) + { + // Initialize all our tools. Must be done after saved settings loaded. + if ( gToolMgr == NULL ) + { + gToolMgr = new LLToolMgr(); + gToolMgr->initTools(); + } + + // Quickly get something onscreen to look at. + gViewerWindow->initWorldUI(); + } + + gViewerWindow->setNormalControlsVisible( FALSE ); + gLoginMenuBarView->setVisible( TRUE ); timeout.reset(); return do_normal_idle; @@ -725,11 +754,16 @@ BOOL idle_startup() if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState()) { + //reset the values that could have come in from a slurl + if (!gLoginHandler.mWebLoginKey.isNull()) + { + firstname = gLoginHandler.mFirstName; + lastname = gLoginHandler.mLastName; + web_login_key = gLoginHandler.mWebLoginKey; + } + if (show_connect_box) { - // Load all the name information out of the login view - LLPanelLogin::getFields(firstname, lastname, password, remember_password); - // HACK: Try to make not jump on login gKeyboard->resetKeys(); } @@ -789,25 +823,6 @@ BOOL idle_startup() if (show_connect_box) { - LLString server_label; - S32 domain_name_index; - BOOL user_picked_server = LLPanelLogin::getServer( server_label, domain_name_index ); - gGridChoice = (EGridInfo) domain_name_index; - gSavedSettings.setS32("ServerChoice", gGridChoice); - if (gGridChoice == GRID_INFO_OTHER) - { - snprintf(gGridName, MAX_STRING, "%s", server_label.c_str()); /* Flawfinder: ignore */ - } - - if ( user_picked_server ) - { // User picked a grid from the popup, so clear the stored urls and they will be re-generated from gGridChoice - sAuthUris.clear(); - LLAppViewer::instance()->resetURIs(); - } - - LLString location; - LLPanelLogin::getLocation( location ); - LLURLSimString::setString( location ); LLPanelLogin::close(); } @@ -940,11 +955,12 @@ BOOL idle_startup() // a startup URL was specified std::stringstream unescaped_start; unescaped_start << "uri:" - << LLURLSimString::sInstance.mSimName << "&" - << LLURLSimString::sInstance.mX << "&" - << LLURLSimString::sInstance.mY << "&" - << LLURLSimString::sInstance.mZ; + << LLURLSimString::sInstance.mSimName << "&" + << LLURLSimString::sInstance.mX << "&" + << LLURLSimString::sInstance.mY << "&" + << LLURLSimString::sInstance.mZ; start << xml_escape_string(unescaped_start.str().c_str()); + } else if (gSavedSettings.getBOOL("LoginLastLocation")) { @@ -960,13 +976,13 @@ BOOL idle_startup() hashed_mac.update( gMACAddress, MAC_ADDRESS_BYTES ); hashed_mac.finalize(); hashed_mac.hex_digest(hashed_mac_string); - + gUserAuthp->authenticate( sAuthUris[sAuthUriNum].c_str(), auth_method.c_str(), firstname.c_str(), lastname.c_str(), - password.c_str(), + web_login_key, start.str().c_str(), gSkipOptionalUpdate, gAcceptTOS, @@ -976,6 +992,7 @@ BOOL idle_startup() requested_options, hashed_mac_string, LLAppViewer::instance()->getSerialNumber()); + // reset globals gAcceptTOS = FALSE; gAcceptCriticalMessage = FALSE; @@ -1237,15 +1254,7 @@ BOOL idle_startup() if(text) lastname.assign(text); gSavedSettings.setString("FirstName", firstname); gSavedSettings.setString("LastName", lastname); - if (remember_password) - { - save_password_to_disk(password.c_str()); - } - else - { - save_password_to_disk(NULL); - } - gSavedSettings.setBOOL("RememberPassword", remember_password); + gSavedSettings.setBOOL("LoginLastLocation", gSavedSettings.getBOOL("LoginLastLocation")); text = gUserAuthp->getResponse("agent_access"); @@ -1471,14 +1480,6 @@ BOOL idle_startup() // type the name/password again if we crash. gSavedSettings.saveToFile(gSettingsFileName, TRUE); - // Create selection manager - // Must be done before menus created, because many enabled callbacks - // require its existance. - gSelectMgr = new LLSelectMgr(); - gParcelMgr = new LLViewerParcelMgr(); - gHUDManager = new LLHUDManager(); - gMuteListp = new LLMuteList(); - // // Initialize classes w/graphics stuff. // @@ -1547,21 +1548,11 @@ BOOL idle_startup() if ( gViewerWindow != NULL && gToolMgr != NULL ) { // This isn't the first logon attempt, so show the UI gViewerWindow->setNormalControlsVisible( TRUE ); - } + } + gLoginMenuBarView->setVisible( FALSE ); - // Initialize UI if (!gNoRender) { - // Initialize all our tools. Must be done after saved settings loaded. - if ( gToolMgr == NULL ) - { - gToolMgr = new LLToolMgr(); - gToolMgr->initTools(); - } - - // Quickly get something onscreen to look at. - gViewerWindow->initWorldUI(); - // Move the progress view in front of the UI gViewerWindow->moveProgressViewToFront(); @@ -2344,68 +2335,12 @@ void login_show() // UI textures have been previously loaded in doPreloadImages() llinfos << "Setting Servers" << llendl; - - if( GRID_INFO_OTHER == gGridChoice ) - { - LLPanelLogin::addServer( gGridName, GRID_INFO_OTHER ); - } - else - { - LLPanelLogin::addServer( gGridInfo[gGridChoice].mLabel, gGridChoice ); - } - - // Arg! We hate loops! - LLPanelLogin::addServer( gGridInfo[GRID_INFO_DMZ].mLabel, GRID_INFO_DMZ ); - LLPanelLogin::addServer( gGridInfo[GRID_INFO_LOCAL].mLabel, GRID_INFO_LOCAL ); - LLPanelLogin::addServer( gGridInfo[GRID_INFO_AGNI].mLabel, GRID_INFO_AGNI ); - LLPanelLogin::addServer( gGridInfo[GRID_INFO_ADITI].mLabel, GRID_INFO_ADITI ); - LLPanelLogin::addServer( gGridInfo[GRID_INFO_SIVA].mLabel, GRID_INFO_SIVA ); - LLPanelLogin::addServer( gGridInfo[GRID_INFO_DURGA].mLabel, GRID_INFO_DURGA ); - LLPanelLogin::addServer( gGridInfo[GRID_INFO_SHAKTI].mLabel, GRID_INFO_SHAKTI ); - LLPanelLogin::addServer( gGridInfo[GRID_INFO_GANGA].mLabel, GRID_INFO_GANGA ); - LLPanelLogin::addServer( gGridInfo[GRID_INFO_UMA].mLabel, GRID_INFO_UMA ); - LLPanelLogin::addServer( gGridInfo[GRID_INFO_SOMA].mLabel, GRID_INFO_SOMA ); - LLPanelLogin::addServer( gGridInfo[GRID_INFO_VAAK].mLabel, GRID_INFO_VAAK ); } // Callback for when login screen is closed. Option 0 = connect, option 1 = quit. void login_callback(S32 option, void *userdata) { - const S32 CONNECT_OPTION = 0; - const S32 QUIT_OPTION = 1; - if (CONNECT_OPTION == option) - { - LLStartUp::setStartupState( STATE_LOGIN_CLEANUP ); - return; - } - else if (QUIT_OPTION == option) - { - // Make sure we don't save the password if the user is trying to clear it. - LLString first, last, password; - BOOL remember = TRUE; - LLPanelLogin::getFields(first, last, password, remember); - if (!remember) - { - // turn off the setting and write out to disk - gSavedSettings.setBOOL("RememberPassword", FALSE); - gSavedSettings.saveToFile(gSettingsFileName, TRUE); - - // stomp the saved password on disk - save_password_to_disk(NULL); - } - - LLPanelLogin::close(); - - // Next iteration through main loop should shut down the app cleanly. - LLAppViewer::instance()->userQuit(); // gQuit = TRUE; - - return; - } - else - { - llwarns << "Unknown login button clicked" << llendl; - } } LLString load_password_from_disk() @@ -3645,6 +3580,7 @@ void reset_login() if ( gViewerWindow ) { // Hide menus and normal buttons gViewerWindow->setNormalControlsVisible( FALSE ); + gLoginMenuBarView->setVisible( TRUE ); } // Hide any other stuff diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 166209d582..fa8213d662 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -85,6 +85,8 @@ LLToolPie::LLToolPie() BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask) { + if (!gCamera) return FALSE; + //left mouse down always picks transparent gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, leftMouseCallback, TRUE, TRUE); diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp index 5b8583d211..c6d9b2fbe2 100644 --- a/indra/newview/llurldispatcher.cpp +++ b/indra/newview/llurldispatcher.cpp @@ -48,9 +48,6 @@ // library includes #include "llsd.h" -// system includes -#include <boost/tokenizer.hpp> - const std::string SLURL_SL_HELP_PREFIX = "secondlife://app."; const std::string SLURL_SL_PREFIX = "sl://"; const std::string SLURL_SECONDLIFE_PREFIX = "secondlife://"; @@ -111,9 +108,9 @@ bool LLURLDispatcherImpl::isSLURL(const std::string& url) // static bool LLURLDispatcherImpl::isSLURLCommand(const std::string& url) -{ +{ if (matchPrefix(url, SLURL_SL_PREFIX + SLURL_APP_TOKEN) - || matchPrefix(url, SLURL_SECONDLIFE_PREFIX + SLURL_APP_TOKEN) + || matchPrefix(url, SLURL_SECONDLIFE_PREFIX + "/" + SLURL_APP_TOKEN) || matchPrefix(url, SLURL_SLURL_PREFIX + SLURL_APP_TOKEN) ) { return true; @@ -128,6 +125,14 @@ bool LLURLDispatcherImpl::dispatchCore(const std::string& url, bool right_mouse) if (dispatchHelp(url, right_mouse)) return true; if (dispatchApp(url, right_mouse)) return true; if (dispatchRegion(url, right_mouse)) return true; + + /* + // Inform the user we can't handle this + std::map<std::string, std::string> args; + args["[SLURL]"] = url; + gViewerWindow->alertXml("BadURL", args); + */ + return false; } @@ -162,41 +167,14 @@ bool LLURLDispatcherImpl::dispatchApp(const std::string& url, BOOL right_mouse) { return false; } - std::string s = stripProtocol(url); - - // At this point, "secondlife://app/foo/bar/baz/" should be left - // as: "app/foo/bar/baz/" - typedef boost::tokenizer<boost::char_separator<char> > tokenizer; - boost::char_separator<char> sep("/", "", boost::drop_empty_tokens); - tokenizer tokens(s, sep); - tokenizer::iterator it = tokens.begin(); - tokenizer::iterator end = tokens.end(); - - // Build parameter list suitable for LLDispatcher dispatch - if (it == end) return false; - if (*it != "app") return false; - ++it; - - if (it == end) return false; - std::string cmd = *it; - ++it; - - std::vector<std::string> params; - for ( ; it != end; ++it) - { - params.push_back(*it); - } - bool handled = LLCommandDispatcher::dispatch(cmd, params); - if (handled) return true; - - // Inform the user we can't handle this - std::map<std::string, std::string> args; - args["[SLURL]"] = url; - gViewerWindow->alertXml("BadURL", args); - // This was a SLURL with a /app prefix, and we "handled" it by displaying an error dialog, - // so return true. It doesn't need to be parsed any further. - return true; + LLURI uri(url); + LLSD pathArray = uri.pathArray(); + pathArray.erase(0); // erase "app" + std::string cmd = pathArray.get(0); + pathArray.erase(0); // erase "cmd" + bool handled = LLCommandDispatcher::dispatch(cmd, pathArray, uri.queryMap()); + return handled; } // static @@ -209,14 +187,14 @@ bool LLURLDispatcherImpl::dispatchRegion(const std::string& url, BOOL right_mous // Before we're logged in, need to update the startup screen // to tell the user where they are going. - if (LLStartUp::getStartupState() < STATE_CLEANUP) + if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) { // Parse it and stash in globals, it will be dispatched in // STATE_CLEANUP. LLURLSimString::setString(url); // We're at the login screen, so make sure user can see // the login location box to know where they are going. - LLPanelLogin::refreshLocation( true ); + LLPanelLogin::loadLoginPage(); return true; } @@ -312,7 +290,7 @@ class LLTeleportHandler : public LLCommandHandler { public: LLTeleportHandler() : LLCommandHandler("teleport") { } - bool handle(const std::vector<std::string>& tokens) + bool handle(const LLSD& tokens, const LLSD& queryMap) { // construct a "normal" SLURL, resolve the region to // a global position, and teleport to it @@ -323,9 +301,9 @@ public: // build secondlife://De%20Haro/123/45/67 for use in callback std::string url = SLURL_SECONDLIFE_PREFIX; - for (size_t i = 0; i < tokens.size(); ++i) + for (int i = 0; i < tokens.size(); ++i) { - url += tokens[i] + "/"; + url += tokens[i].asString() + "/"; } gWorldMap->sendNamedRegionRequest(region_name, LLURLDispatcherImpl::regionHandleCallback, diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index be595e616c..688b2889c8 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -235,6 +235,7 @@ extern BOOL gAllowSelectAvatar; LLMenuBarGL *gMenuBarView = NULL; LLViewerMenuHolderGL *gMenuHolder = NULL; LLMenuGL *gPopupMenuView = NULL; +LLMenuBarGL *gLoginMenuBarView = NULL; // Pie menus LLPieMenu *gPieSelf = NULL; @@ -750,6 +751,15 @@ void init_menus() // Debug menu visiblity // show_debug_menus(); + + gLoginMenuBarView = (LLMenuBarGL*)gUICtrlFactory->buildMenu("menu_login.xml", gMenuHolder); + LLRect menuBarRect = gLoginMenuBarView->getRect(); + gLoginMenuBarView->setRect(LLRect(menuBarRect.mLeft, menuBarRect.mTop, gViewerWindow->getRootView()->getRect().getWidth() - menuBarRect.mLeft, menuBarRect.mBottom)); + + gLoginMenuBarView->setBackgroundColor( color ); + + gMenuHolder->addChild(gLoginMenuBarView); + } void init_landmark_menu(LLMenuGL* menu) diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index 55fab86089..6814c31eb8 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -141,6 +141,7 @@ extern LLMenuBarGL* gMenuBarView; //extern LLView* gMenuBarHolder; extern LLMenuGL* gPopupMenuView; extern LLViewerMenuHolderGL* gMenuHolder; +extern LLMenuBarGL* gLoginMenuBarView; // Pie menus extern LLPieMenu *gPieSelf; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 74788f6f26..bc41a88e27 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -31,6 +31,7 @@ #include "llviewerprecompiledheaders.h" +#include "llpanellogin.h" #include "llviewerwindow.h" // system library includes @@ -105,6 +106,7 @@ #include "llfloatermap.h" #include "llfloatermute.h" #include "llfloaternamedesc.h" +#include "llfloaterpreference.h" #include "llfloatersnapshot.h" #include "llfloatertools.h" #include "llfloaterworldmap.h" @@ -2842,7 +2844,7 @@ BOOL LLViewerWindow::handlePerFrameHover() // *NOTE: sometimes tools handle the mouse as a captor, so this // logic is a little confusing LLTool *tool = NULL; - if (gToolMgr && gHoverView) + if (gToolMgr && gHoverView && gCamera) { tool = gToolMgr->getCurrentTool(); @@ -2915,8 +2917,8 @@ BOOL LLViewerWindow::handlePerFrameHover() mToolTip->setVisible( TRUE ); } } - - if (tool != gToolNull && tool != gToolInspect && tool != gToolDragAndDrop && !gSavedSettings.getBOOL("FreezeTime")) + + if (tool && tool != gToolNull && tool != gToolInspect && tool != gToolDragAndDrop && !gSavedSettings.getBOOL("FreezeTime")) { LLMouseHandler *captor = gFocusMgr.getMouseCapture(); // With the null, inspect, or drag and drop tool, don't muck diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 39d8c2e640..7bb12f7853 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -450,6 +450,8 @@ class LinuxManifest(ViewerManifest): if self.prefix("linux_tools", ""): self.path("client-readme.txt","README-linux.txt") self.path("wrapper.sh","secondlife") + self.path("handle_secondlifeprotocol.sh") + self.path("register_secondlifeprotocol.sh") self.path("unicode.ttf","unicode.ttf") self.end_prefix("linux_tools") |