From a556c2e84fc121dacdbb00629c68371b72c5cb7a Mon Sep 17 00:00:00 2001 From: Jacek Antonelli Date: Mon, 29 Jun 2009 17:25:47 -0500 Subject: Updated URL for Mac OpenAL libs package. --- linden/install.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linden') diff --git a/linden/install.xml b/linden/install.xml index 224cd65..b213b94 100644 --- a/linden/install.xml +++ b/linden/install.xml @@ -1128,7 +1128,7 @@ anguage Infrstructure (CLI) international standard md5sum f30b851e089108978c8218295a405159 url - http://thomas.shikami.mooo.com/install_pkgs/openal-darwin-20090418.tar.bz2 + http://imprudenceviewer.org/download/libs/openal-darwin-20090418.tar.bz2 linux -- cgit v1.1 From 7067b31a6114089217e482bfecc58fd56bed4272 Mon Sep 17 00:00:00 2001 From: Armin Weatherwax Date: Fri, 26 Jun 2009 09:39:58 +0200 Subject: BROKEN logoff/relog crashing inconsistently on various startup states. --- linden/indra/llcommon/llstring.h | 1 + linden/indra/newview/CMakeLists.txt | 21 +- .../indra/newview/app_settings/default_grids.xml | 51 ++ linden/indra/newview/app_settings/settings.xml | 33 + linden/indra/newview/authentication_controller.cpp | 80 ++ linden/indra/newview/authentication_controller.h | 42 ++ linden/indra/newview/authentication_floater.cpp | 75 ++ linden/indra/newview/authentication_floater.h | 35 + linden/indra/newview/authentication_model.cpp | 111 +++ linden/indra/newview/authentication_model.h | 53 ++ linden/indra/newview/controllerlogin.cpp | 142 ++++ linden/indra/newview/controllerlogin.h | 55 ++ linden/indra/newview/controllerpasswords.cpp | 41 + linden/indra/newview/controllerpasswords.h | 37 + linden/indra/newview/floaterlogin.cpp | 834 +++++++++++++++++++++ linden/indra/newview/floaterlogin.h | 98 +++ linden/indra/newview/hippoGridManager.cpp | 597 +++++++++++++++ linden/indra/newview/hippoGridManager.h | 171 +++++ linden/indra/newview/hippoLimits.cpp | 54 ++ linden/indra/newview/hippoLimits.h | 33 + linden/indra/newview/hippoRestRequest.cpp | 54 ++ linden/indra/newview/hippoRestRequest.h | 16 + linden/indra/newview/hippoUpdate.cpp | 92 +++ linden/indra/newview/hippoUpdate.h | 12 + linden/indra/newview/llappviewer.cpp | 162 +++- linden/indra/newview/llappviewer.h | 20 +- linden/indra/newview/llappviewerlinux.h | 3 +- linden/indra/newview/llcallingcard.cpp | 12 + linden/indra/newview/llcallingcard.h | 2 +- linden/indra/newview/lldrawable.h | 1 + linden/indra/newview/llfloaterworldmap.cpp | 157 +++- linden/indra/newview/llfloaterworldmap.h | 7 +- linden/indra/newview/llpanellogin.cpp | 157 +++- linden/indra/newview/llpanellogin.h | 8 +- linden/indra/newview/llprogressview.cpp | 2 +- linden/indra/newview/llstartup.cpp | 205 +++-- linden/indra/newview/llstartup.h | 9 +- linden/indra/newview/lluserauth.cpp | 53 +- linden/indra/newview/llviewermenufile.cpp | 15 +- linden/indra/newview/llviewermessage.cpp | 2 +- linden/indra/newview/llviewermessage.h | 2 +- linden/indra/newview/llviewernetwork.cpp | 201 +---- linden/indra/newview/llviewernetwork.h | 63 +- linden/indra/newview/llviewerobject.h | 1 + linden/indra/newview/llwearablelist.cpp | 10 +- linden/indra/newview/prefpanelpasswords.cpp | 40 + linden/indra/newview/prefpanelpasswords.h | 30 + .../newview/skins/default/xui/en-us/alerts.xml | 17 + .../skins/default/xui/en-us/floater_login.xml | 185 +++++ .../skins/default/xui/en-us/floater_world_map.xml | 98 ++- .../skins/default/xui/en-us/menu_viewer.xml | 4 + .../skins/default/xui/en-us/panel_login.xml | 4 + .../xui/en-us/panel_preferences_network.xml | 25 +- 53 files changed, 3793 insertions(+), 440 deletions(-) create mode 100644 linden/indra/newview/app_settings/default_grids.xml create mode 100644 linden/indra/newview/authentication_controller.cpp create mode 100644 linden/indra/newview/authentication_controller.h create mode 100644 linden/indra/newview/authentication_floater.cpp create mode 100644 linden/indra/newview/authentication_floater.h create mode 100644 linden/indra/newview/authentication_model.cpp create mode 100644 linden/indra/newview/authentication_model.h create mode 100644 linden/indra/newview/controllerlogin.cpp create mode 100644 linden/indra/newview/controllerlogin.h create mode 100644 linden/indra/newview/controllerpasswords.cpp create mode 100644 linden/indra/newview/controllerpasswords.h create mode 100644 linden/indra/newview/floaterlogin.cpp create mode 100644 linden/indra/newview/floaterlogin.h create mode 100644 linden/indra/newview/hippoGridManager.cpp create mode 100644 linden/indra/newview/hippoGridManager.h create mode 100644 linden/indra/newview/hippoLimits.cpp create mode 100644 linden/indra/newview/hippoLimits.h create mode 100644 linden/indra/newview/hippoRestRequest.cpp create mode 100644 linden/indra/newview/hippoRestRequest.h create mode 100644 linden/indra/newview/hippoUpdate.cpp create mode 100644 linden/indra/newview/hippoUpdate.h create mode 100644 linden/indra/newview/prefpanelpasswords.cpp create mode 100644 linden/indra/newview/prefpanelpasswords.h create mode 100644 linden/indra/newview/skins/default/xui/en-us/floater_login.xml (limited to 'linden') diff --git a/linden/indra/llcommon/llstring.h b/linden/indra/llcommon/llstring.h index 720b163..93bd89a 100644 --- a/linden/indra/llcommon/llstring.h +++ b/linden/indra/llcommon/llstring.h @@ -36,6 +36,7 @@ #include #include #endif +#include "linden_common.h" const char LL_UNKNOWN_CHAR = '?'; diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index 34aa29f..07285f1 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -61,6 +61,15 @@ include_directories( ) set(viewer_SOURCE_FILES + authentication_controller.cpp + authentication_floater.cpp + authentication_model.cpp + controllerlogin.cpp + controllerpasswords.cpp + floaterlogin.cpp + hippoGridManager.cpp + hippoLimits.cpp + hippoRestRequest.cpp llagent.cpp llagentdata.cpp llagentlanguage.cpp @@ -431,6 +440,7 @@ set(viewer_SOURCE_FILES llxmlrpctransaction.cpp noise.cpp pipeline.cpp + prefpanelpasswords.cpp ) set(VIEWER_BINARY_NAME "imprudence-bin" CACHE STRING @@ -453,7 +463,15 @@ endif (LINUX) set(viewer_HEADER_FILES CMakeLists.txt ViewerInstall.cmake - + authentication_controller.h + authentication_floater.h + authentication_model.h + controllerlogin.h + controllerpasswords.h + floaterlogin.h + hippoGridManager.h + hippoLimits.h + hippoRestRequest.h llagent.h llagentdata.h llagentlanguage.h @@ -831,6 +849,7 @@ set(viewer_HEADER_FILES macmain.h noise.h pipeline.h + prefpanelpasswords.h randgauss.h VertexCache.h VorbisFramework.h diff --git a/linden/indra/newview/app_settings/default_grids.xml b/linden/indra/newview/app_settings/default_grids.xml new file mode 100644 index 0000000..f4feb0c --- /dev/null +++ b/linden/indra/newview/app_settings/default_grids.xml @@ -0,0 +1,51 @@ + + + + + + + default_grids_version0 + + + + + gridnickosgrid + gridnameOSGrid + platformOpenSim + loginurihttp://osgrid.org:8002/ + loginpagehttp://osgrid.org/loginscreen.php + helperurihttp://osgrid.org/ + websitehttp://osgrid.org/ + supporthttp://osgrid.org/ + registerhttp://osgrid.org/index.php?page=create + passwordhttp://osgrid.org/index.php?page=change + + + + + gridnicksecondlife + gridnameSecond Life + platformSecondLife + loginurihttps://login.agni.lindenlab.com/cgi-bin/login.cgi + loginpagehttp://secondlife.com/app/login/ + helperurihttps://secondlife.com/helpers/ + websitehttp://secondlife.com/ + supporthttp://secondlife.com/support/ + registerhttp://secondlife.com/registration/ + passwordhttp://secondlife.com/account/request.php + + + + + gridnicklocal + gridnameLocal Host + platformOpenSim + loginurihttp://127.0.0.1:9000/ + helperurihttp://127.0.0.1:9000/ + + + + diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index 5c76185..a8d7a08 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -10509,5 +10509,38 @@ Value 0 + DefaultGrid + + Comment + Nickname of the default grid + Persist + 1 + Type + String + Value + secondlife + + KeepAppearance + + Comment + Keep appearance across grid teleport + Persist + 1 + Type + Boolean + Value + 0 + + CheckForGridUpdates + + Comment + Check for grid info updates on the web server + Persist + 1 + Type + Boolean + Value + 1 + diff --git a/linden/indra/newview/authentication_controller.cpp b/linden/indra/newview/authentication_controller.cpp new file mode 100644 index 0000000..a060409 --- /dev/null +++ b/linden/indra/newview/authentication_controller.cpp @@ -0,0 +1,80 @@ +/* + * AuthenticationController.cpp + * SecondLife + * + * Created by RMS on 7/1/08. + * + */ + +#include "llviewerprecompiledheaders.h" +#include "authentication_floater.h" +#include "llviewerobject.h" +#include "llcheckboxctrl.h" +#include "llselectmgr.h" +#include "authentication_controller.h" + +// Statics +std::string AuthenticationController::target_grid; +std::string AuthenticationController::username; +std::string AuthenticationController::password; +BOOL AuthenticationController::store_pw = FALSE; + +AuthenticationController::AuthenticationController(const std::string& tg, void (*cb)(void*)) +{ + target_grid = tg; + callback = cb; +} + +AuthenticationController::~AuthenticationController() +{ +} + +// user interface callbacks: all static +void AuthenticationController::onCommitUser(LLUICtrl* ctrl, void* userdata) +{ + AuthenticationFloater *floater = (AuthenticationFloater*)userdata; + username = floater->childGetText("User_edit"); +} + +void AuthenticationController::onCommitPassword(LLUICtrl* ctrl, void* userdata) +{ + AuthenticationFloater *floater = (AuthenticationFloater*)userdata; + password = floater->childGetText("Password_edit"); +} + +void AuthenticationController::onCommitRemember(LLUICtrl* ctrl, void* userdata) +{ + LLViewerObject *object = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(); + if(!object) return; + + LLCheckBoxCtrl *check = (LLCheckBoxCtrl*)ctrl; + store_pw = check->get(); +} + +void AuthenticationController::onAccept(void* userdata) +{ + +} + +void AuthenticationController::onCancel(void* userdata) +{ + AuthenticationFloater *floater = (AuthenticationFloater*)userdata; + floater->cancel(); + floater->close(); +} + +void AuthenticationController::onClickRegister(void* userdata) +{ + llinfos << "onClickRegister" << llendl; +} + +void AuthenticationController::retrieveStoredAccountData(void* userdata) +{ + +} + +// static +std::string AuthenticationController::getTargetGrid() +{ + return target_grid; +} diff --git a/linden/indra/newview/authentication_controller.h b/linden/indra/newview/authentication_controller.h new file mode 100644 index 0000000..db875ea --- /dev/null +++ b/linden/indra/newview/authentication_controller.h @@ -0,0 +1,42 @@ +/* + * AuthenticationController.h + * SecondLife + * + * Created by RMS on 7/1/08. + * + */ + +#ifndef PL_AuthenticationController_H +#define PL_AuthenticationController_H + +#include "llfloater.h" + +class AuthenticationController +{ +public: + AuthenticationController(const std::string& tg, void (*cb)(void*)); + virtual ~AuthenticationController(); + + // line editor callbacks + static void onCommitUser(LLUICtrl* ctrl, void* userdata); + static void onCommitPassword(LLUICtrl* ctrl, void* userdata); + static void onCommitRemember(LLUICtrl* ctrl, void* userdata); + // button callbacks + static void onAccept(void* userdata); + static void onCancel(void* userdata); + static void onClickRegister(void* userdata); + + void retrieveStoredAccountData(void* userdata); + static std::string getTargetGrid(); + +private: + static std::string target_grid; + static std::string username; + static std::string password; + static BOOL store_pw; + void (*callback)(void*); +}; + + +#endif // PL_AuthenticationController_H + diff --git a/linden/indra/newview/authentication_floater.cpp b/linden/indra/newview/authentication_floater.cpp new file mode 100644 index 0000000..2fc7add --- /dev/null +++ b/linden/indra/newview/authentication_floater.cpp @@ -0,0 +1,75 @@ +/* + * AuthenticationFloater.cpp + * Cross-grid authentication system view. + * + * Created by RMS on 7/1/08. + * + */ + + +#include "llviewerprecompiledheaders.h" +#include "authentication_floater.h" +#include "lluictrlfactory.h" + +// Statics +AuthenticationFloater* AuthenticationFloater::sInstance = NULL; +AuthenticationController* AuthenticationFloater::sController = NULL; + +AuthenticationFloater::AuthenticationFloater() +: LLFloater("floater_authentication") +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_authentication.xml"); + + childSetTextArg("Intro_text", "[TARGET_GRID]", sController->getTargetGrid()); + + childSetCommitCallback("User_edit", controller()->onCommitUser, this); + childSetCommitCallback("Password_edit", controller()->onCommitPassword, this); + childSetCommitCallback("Remember_check", controller()->onCommitRemember, this); + + childSetAction("OK", controller()->onAccept, this); + childSetAction("Cancel", controller()->onCancel, this); + childSetAction("Register", controller()->onClickRegister, this); + + setDefaultBtn("OK"); +} + +AuthenticationFloater::~AuthenticationFloater() +{ + sInstance = NULL; + delete sController; + sController = NULL; +} + +// static +void AuthenticationFloater::show(void* userdata) +{ + std::string target_grid; + void (*cb)(void*) = NULL; + + if (!userdata) + { + target_grid = "Authentication Test"; + } + + if (!sInstance) + sInstance = new AuthenticationFloater(); + if (!sController) + sController = new AuthenticationController(target_grid, cb); + + sInstance->open(); +} + +void AuthenticationFloater::accept() +{ + llinfos << "accept" << llendl; +} + +void AuthenticationFloater::cancel() +{ + llinfos << "cancel" << llendl; +} + +AuthenticationController* AuthenticationFloater::controller() +{ + return sController; +} diff --git a/linden/indra/newview/authentication_floater.h b/linden/indra/newview/authentication_floater.h new file mode 100644 index 0000000..b24426b --- /dev/null +++ b/linden/indra/newview/authentication_floater.h @@ -0,0 +1,35 @@ +/* + * AuthenticationFloater.h + * Cross-grid authentication system view. + * + * Created by RMS on 7/1/08. + * + */ + +#ifndef PL_AuthenticationFloater_H +#define PL_AuthenticationFloater_H + +#include "llfloater.h" +#include "authentication_controller.h" + +class AuthenticationFloater : public LLFloater +{ +public: + AuthenticationFloater(); + virtual ~AuthenticationFloater(); + + static void show(void* userdata); + static void accept(); + static void cancel(); + + // data accessors + static AuthenticationController* controller(); + +private: + // static because we only need one floater + static AuthenticationFloater* sInstance; + static AuthenticationController* sController; +}; + + +#endif // PL_AuthenticationFloater_H diff --git a/linden/indra/newview/authentication_model.cpp b/linden/indra/newview/authentication_model.cpp new file mode 100644 index 0000000..763ab4a --- /dev/null +++ b/linden/indra/newview/authentication_model.cpp @@ -0,0 +1,111 @@ +/* + * authentication_model.cpp + * SecondLife + * + * Created by RMS on 7/17/08. + * + */ + +#include "llviewerprecompiledheaders.h" + +#include "lldir.h" +#include "llfile.h" +#include "llsdserialize.h" +#include "authentication_model.h" + +AuthenticationModel::AuthenticationModel() +{ + loadPersistentData(); +} + +AuthenticationModel::~AuthenticationModel() +{ + savePersistentData(); +} + +void AuthenticationModel::loadPersistentData() +{ + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, + "cross_grid_authentication.xml"); + LLSD auth_llsd; + llifstream file; + file.open(filename); + if(file.is_open()) + LLSDSerialize::fromXML(mAuthLLSD, file); +} + +void AuthenticationModel::savePersistentData() +{ + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, + "cross_grid_authentication.xml"); + llofstream ofile; + ofile.open(filename); + LLSDSerialize::toPrettyXML(mAuthLLSD, ofile); +} + +void AuthenticationModel::revert() +{ + loadPersistentData(); +} + +AuthenticationModel::connection_t AuthenticationModel::subscribeToModelUpdates + (event_t::slot_function_type subscriber) +{ + return mEventUpdate.connect(subscriber); +} + +void AuthenticationModel::unsubscribe(connection_t subscriber) +{ + subscriber.disconnect(); +} + +/* setters */ +void AuthenticationModel::addAccount(const std::string &grid, const std::string &accountName, + const std::string &accountPassword) +{ + mAuthLLSD[grid][accountName] = LLSD::LLSD(accountPassword); + mEventUpdate(); +} + +void AuthenticationModel::removeAccount(const std::string &grid, const std::string &accountName) +{ + mAuthLLSD[grid].erase(accountName); + mEventUpdate(); +} + +void AuthenticationModel::changePassword(const std::string &grid, const std::string &accountName, + const std::string &newPassword) +{ + mAuthLLSD[grid][accountName] = newPassword; + // no event necessary: passwords aren't displayed in any view +} + +/* getters */ + +void AuthenticationModel::getAllAccountNames(std::list &names) +{ + // TODO: implement this for account management +} + +void AuthenticationModel::getAccountNames(const std::string &grid, std::set &names) +{ + if(!mAuthLLSD.has(grid)) + return; + + for(LLSD::map_const_iterator it = mAuthLLSD[grid].beginMap(); + it != mAuthLLSD[grid].endMap(); ++it) + { + names.insert(it->first); + } +} + +void AuthenticationModel::getPassword(const std::string &grid, const std::string &accountName, + std::string &password) +{ + password = mAuthLLSD[grid][accountName].asString(); +} + +void AuthenticationModel::requestUpdate() +{ + mEventUpdate(); +} diff --git a/linden/indra/newview/authentication_model.h b/linden/indra/newview/authentication_model.h new file mode 100644 index 0000000..858e936 --- /dev/null +++ b/linden/indra/newview/authentication_model.h @@ -0,0 +1,53 @@ +/* + * authentication_model.h + * SecondLife + * + * Created by RMS on 7/17/08. + * + */ + +#ifndef PL_authentication_model_H +#define PL_authentication_model_H + +#include +#include +#include +#include +#include +#include "lluuid.h" +#include "llmemory.h" +#include "llsd.h" + +class AuthenticationModel : public LLSingleton +{ +public: + typedef boost::signal event_t; + typedef boost::signals::connection connection_t; + + AuthenticationModel(); + virtual ~AuthenticationModel(); + + void loadPersistentData(); + void savePersistentData(); + void revert(); + + /* generic update, pull model: */ + connection_t subscribeToModelUpdates(event_t::slot_function_type subscriber); + void unsubscribe(connection_t subscriber); + + /* setters */ + void addAccount(const std::string &grid, const std::string &accountName, const std::string &accountPassword); + void removeAccount(const std::string &grid, const std::string &accountName); + void changePassword(const std::string &grid, const std::string &accountName, const std::string &newPassword); + + /* getters */ + void getAllAccountNames(std::list &names); + void getAccountNames(const std::string &grid, std::set &names); + void getPassword(const std::string &grid, const std::string &accountName, std::string &password); + void requestUpdate(); +protected: + LLSD mAuthLLSD; +private: + event_t mEventUpdate; +}; +#endif // PL_authentication_model_H diff --git a/linden/indra/newview/controllerlogin.cpp b/linden/indra/newview/controllerlogin.cpp new file mode 100644 index 0000000..9dd61a6 --- /dev/null +++ b/linden/indra/newview/controllerlogin.cpp @@ -0,0 +1,142 @@ +/* + * controllerlogin.cpp + * SecondLife + * + * Created by RMS on 7/16/08. + * + */ +#include "llerror.h" +#include "llmd5.h" +#include +#include "controllerlogin.h" + +LoginController::LoginController(LoginFloater *floater, AuthenticationModel *authModel, const std::string &grid) +: mFloater(floater), mModel(authModel), mGrid(grid) +{ + // set up the user interface subview pointers + name_combo = mFloater->getChild("name_combo"); + password_edit = mFloater->getChild("password_edit"); + start_location_combo= mFloater->getChild("start_location_combo"); + remember_check = mFloater->getChild("remember_check"); + connect_btn = mFloater->getChild("connect_btn"); + quit_btn = mFloater->getChild("quit_btn"); + server_combo = mFloater->getChild("server_combo"); + + // callbacks + // TODO: account creation and version information callbacks + name_combo->setCommitCallback(onCommitName); + name_combo->setCallbackUserData(this); + password_edit->setCommitCallback(onCommitPassword); + password_edit->setCallbackUserData(mFloater); + connect_btn->setClickedCallback(onAccept, this); + quit_btn->setClickedCallback(onCancel, this); + + // subscribe to the model + mModelConnection = mModel->subscribeToModelUpdates(boost::bind(&LoginController::update, this)); + // request an initial update + mModel->requestUpdate(); +} + +LoginController::~LoginController() +{ + mModel->unsubscribe(mModelConnection); +} + +void LoginController::update() +{ + // when we want to update, we need to make sure it's relevant to our + // interests and make the change as smooth as possible for the user + std::set newAccountNames; + mModel->getAccountNames(mGrid, newAccountNames); + + if(mAccountNames == newAccountNames) + return; + + name_combo->removeall(); + + for(std::set::iterator it = newAccountNames.begin(); + it != newAccountNames.end(); ++it) + { + name_combo->add(*it); + } + + name_combo->sortByName(); + mAccountNames.swap(newAccountNames); +} + +void LoginController::mungePassword(std::string &password) +{ + LLMD5 pass((unsigned char *)password.c_str()); + char munged_password[MD5HEX_STR_SIZE]; + pass.hex_digest(munged_password); + password = munged_password; +} + +// user interface callbacks + +void LoginController::onCommitName(LLUICtrl *control, void *userdata) +{ + // look at this shit it fills in the password box if it finds a stored account + // and auto checks remember password + LoginController *controller = (LoginController *)userdata; + LoginFloater *floater = controller->mFloater; + + std::string loginname = floater->childGetText("name_combo"); + std::set::iterator it = controller->mAccountNames.find(loginname); + if(it != controller->mAccountNames.end()) + { + std::string loginpassword; + + controller->mModel->getPassword(controller->mGrid, loginname, loginpassword); + LoginFloater::setFields(loginname, loginpassword, true); + } +} + +void LoginController::onCommitPassword(LLUICtrl *control, void *userdata) +{ + LoginFloater *floater = (LoginFloater *)userdata; + LLLineEditor *editor = (LLLineEditor *)control; + std::string password = editor->getText(); + + // when we have a new password we need to MD5 it and tell the floater + if(!floater->isSamePassword(password)) + { + mungePassword(password); + floater->setPassword(password); + } +} + +void LoginController::onAccept(void* userdata) +{ + // this here does the main work of telling the model we need to write + // account data + LoginController *controller = (LoginController *)userdata; + LoginFloater *floater = controller->mFloater; + + if(!floater->childGetValue("remember_check")) + { + LoginFloater::accept(); + return; + } + + std::string username = floater->childGetText("name_combo"); + std::string password = floater->getPassword(); + + if(controller->mAccountNames.find(username) != controller->mAccountNames.end()) + { + controller->mModel->changePassword(controller->mGrid, username, password); + } + + else + { + controller->mModel->addAccount(controller->mGrid, username, password); + } + controller->mModel->savePersistentData(); + LoginFloater::accept(); +} + +void LoginController::onCancel(void* userdata) +{ + // if the user backs out of the dialog we tell it to clean up and such + LoginFloater::cancel_old(); +} diff --git a/linden/indra/newview/controllerlogin.h b/linden/indra/newview/controllerlogin.h new file mode 100644 index 0000000..a187558 --- /dev/null +++ b/linden/indra/newview/controllerlogin.h @@ -0,0 +1,55 @@ +/* + * controllerlogin.h + * SecondLife + * + * Created by RMS on 7/16/08. + * + */ +#ifndef PL_controllerlogin_H +#define PL_controllerlogin_H + +#include +#include +#include "llcombobox.h" +#include "lllineeditor.h" +#include "llcheckboxctrl.h" +#include "llbutton.h" +#include "floaterlogin.h" +#include "authentication_model.h" + +class LoginController +{ +public: + LoginController(LoginFloater *floater, AuthenticationModel *authModel, const std::string &grid); + virtual ~LoginController(); + virtual void update(); +protected: + LoginFloater *mFloater; + AuthenticationModel *mModel; + std::string mGrid; +private: + AuthenticationModel::connection_t mModelConnection; + + static void mungePassword(std::string &password); + + // UI subview pointers + LLComboBox *name_combo; + LLLineEditor *password_edit; + LLComboBox *start_location_combo; + LLCheckBoxCtrl *remember_check; + LLButton *connect_btn; + LLButton *quit_btn; + LLComboBox *server_combo; + + // state + std::set mAccountNames; + + // user interface callbacks + // TODO: find an alternative to linden callbacks + static void onCommitName(LLUICtrl *control, void *userdata); + static void onCommitPassword(LLUICtrl *control, void *userdata); + static void onAccept(void* userdata); + static void onCancel(void* userdata); +}; + +#endif // PL_controllerlogin_H diff --git a/linden/indra/newview/controllerpasswords.cpp b/linden/indra/newview/controllerpasswords.cpp new file mode 100644 index 0000000..6e39d9a --- /dev/null +++ b/linden/indra/newview/controllerpasswords.cpp @@ -0,0 +1,41 @@ +/* + * controllerpasswords.cpp + * SecondLife + * + * Created by RMS on 8/5/08. + * + */ + +#include "authentication_model.h" +#include "prefpanelpasswords.h" +#include "controllerpasswords.h" + +PasswordsController::PasswordsController(PasswordsPrefPanel *panel) +: mPanel(panel) +{ + accounts_list = mPanel->getChild("accounts_list"); + remove_btn = mPanel->getChild("remove_btn"); + mModel = AuthenticationModel::getInstance(); + + // subscribe to the model + mModelConnection = mModel->subscribeToModelUpdates(boost::bind(&PasswordsController::update, this)); + // request an initial update + mModel->requestUpdate(); +} + +PasswordsController::~PasswordsController() +{ + mModel->unsubscribe(mModelConnection); + mModel = NULL; +} + +void PasswordsController::update() +{ + std::list newAccountData; + mModel->getAllAccountNames(newAccountData); + + if(mAccountData == newAccountData) + return; + + accounts_list->deleteAllItems(); +} diff --git a/linden/indra/newview/controllerpasswords.h b/linden/indra/newview/controllerpasswords.h new file mode 100644 index 0000000..e656659 --- /dev/null +++ b/linden/indra/newview/controllerpasswords.h @@ -0,0 +1,37 @@ +/* + * controllerpasswords.h + * SecondLife + * + * Created by RMS on 8/5/08. + * + */ + +#include +#include +#include "llscrolllistctrl.h" +#include "llbutton.h" +#include "authentication_model.h" + +#ifndef PL_controllerpasswords_H +#define PL_controllerpasswords_H +class PasswordsPrefPanel; + +class PasswordsController +{ +public: + PasswordsController(PasswordsPrefPanel *panel); + virtual ~PasswordsController(); + virtual void update(); +protected: + LLScrollListCtrl *accounts_list; + LLButton *remove_btn; +private: + AuthenticationModel::connection_t mModelConnection; + + PasswordsPrefPanel *mPanel; + AuthenticationModel *mModel; + + std::list mAccountData; +}; + +#endif // PL_controllerpasswords_H diff --git a/linden/indra/newview/floaterlogin.cpp b/linden/indra/newview/floaterlogin.cpp new file mode 100644 index 0000000..b943c4e --- /dev/null +++ b/linden/indra/newview/floaterlogin.cpp @@ -0,0 +1,834 @@ +/* + * floaterlogin.cpp + * SecondLife + * + * Created by RMS on 7/15/08. + * + */ + +#include "llviewerprecompiledheaders.h" + +#include +#include "llviewercontrol.h" +#include "llviewerbuild.h" +#include "llcombobox.h" +#include "llscrolllistctrl.h" +#include "llmd5.h" +#include "llurlsimstring.h" +#include "lluictrlfactory.h" +#include "controllerlogin.h" +#include "floaterlogin.h" +#include "hippoGridManager.h" +#include "llviewernetwork.h" +#include "llpanellogin.h" + +#define PASSWORD_FILLER "123456789!123456" + +LoginFloater* LoginFloater::sInstance = NULL; +LoginController* LoginFloater::sController = NULL; +AuthenticationModel* LoginFloater::sModel = NULL; +bool LoginFloater::sIsInitialLogin; +std::string LoginFloater::sGrid; + +LoginFloater::LoginFloater(void (*callback)(S32 option, void* user_data), + void *cb_data) +: LLFloater("floater_login"), mCallback(callback), mCallbackData(cb_data) +{ + + mState = NORMAL; + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_login.xml"); + + + llwarns << "LoginFloater called" << llendl; + + + // configure the floater interface for non-initial login + setCanMinimize(!sIsInitialLogin); + setCanClose(!sIsInitialLogin); + setCanDrag(!sIsInitialLogin); + childSetVisible("server_combo", sIsInitialLogin); + + if(!sIsInitialLogin) + { + LLButton* quit_btn = getChild("quit_btn"); + quit_btn->setLabel(std::string("Cancel")); + setTitle(std::string("Grid Manager")); + } + + center(); + LLLineEditor* edit = getChild("password_edit"); + if (edit) edit->setDrawAsterixes(TRUE); + LLComboBox* combo = getChild("start_location_combo"); + combo->setAllowTextEntry(TRUE, 128, FALSE); + + BOOL login_last = gSavedSettings.getBOOL("LoginLastLocation"); + std::string sim_string = LLURLSimString::sInstance.mSimString; + if (!sim_string.empty()) + { + // Replace "" 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 ); + } + + LLTextBox* version_text = getChild("version_text"); + std::string version = llformat("%d.%d.%d (%d)", + LL_VERSION_MAJOR, + LL_VERSION_MINOR, + LL_VERSION_PATCH, + LL_VIEWER_BUILD ); + version_text->setText(version); + + LLTextBox* channel_text = getChild("channel_text"); + channel_text->setText(gSavedSettings.getString("VersionChannelName")); + + sendChildToBack(getChildView("channel_text")); + sendChildToBack(getChildView("version_text")); + sendChildToBack(getChildView("forgot_password_text")); + + setDefaultBtn("connect_btn"); + + + +} + + +LoginFloater::~LoginFloater() +{ + delete LoginFloater::sController; + + LoginFloater::sModel = NULL; + LoginFloater::sController = NULL; + LoginFloater::sInstance = NULL; +} + +void LoginFloater::close() +{ + if(sInstance) + { + delete sInstance; + sInstance = NULL; + } +} + +BOOL LoginFloater::postBuild() +{ + requires("grid_selector"); + requires("gridnick"); + requires("platform"); + requires("gridname"); + requires("loginuri"); + requires("loginpage"); + requires("helperuri"); + requires("website"); + requires("first_name"); + requires("last_name"); + requires("password"); + //requires("search"); + requires("btn_delete"); + requires("btn_add"); + requires("btn_copy"); + requires("set_default"); + requires("btn_gridinfo"); + requires("btn_help_render_compat"); + if (!checkRequirements()) return false; + LLLineEditor* password_edit = getChild("password"); + if (password_edit) password_edit->setDrawAsterixes(TRUE); + + childSetAction("btn_delete", onClickDelete, this); + childSetAction("btn_add", onClickAdd, this); + childSetAction("btn_copy", onClickCopy, this); + childSetAction("btn_apply", onClickApply, this); + childSetAction("set_default", onClickDefault, this); + childSetAction("btn_cancel", onClickCancel, this); +//KOW childSetAction("set_default", onClickDefault, this); +//KOW childSetAction("btn_gridinfo", onClickGridInfo, this); +//KOW childSetAction("btn_help_render_compat", onClickHelpRenderCompat, this); + + childSetCommitCallback("grid_selector", onSelectGrid, this); +//KOW childSetCommitCallback("platform", onSelectPlatform, this); + + // !!!### server_choice_combo->setFocusLostCallback(onServerComboLostFocus); + +//KOW update(); + return TRUE; +} + +void LoginFloater::refresh_grids() +{ + const std::string &defaultGrid = gHippoGridManager->getDefaultGridNick(); + LLScrollListCtrl *grids = sInstance->getChild("grid_selector"); + S32 selectIndex = -1, i = 0; + grids->deleteAllItems(); + if (defaultGrid != "") { + LLSD value; + value["id"] = defaultGrid; + value["columns"][0]["column"] = "grid"; + value["columns"][0]["value"] = defaultGrid; + grids->addElement(value); + selectIndex = i++; + } + + HippoGridManager::GridIterator it, end = gHippoGridManager->endGrid(); + for (it = gHippoGridManager->beginGrid(); it != end; ++it) { + const std::string &grid = it->second->getGridNick(); + if (grid != defaultGrid) { + LLSD value; + value["id"] = grid; + value["columns"][0]["column"] = "grid"; + value["columns"][0]["value"] = grid; + grids->addElement(value); + + if (grid == sInstance->mCurGrid) selectIndex = i; + i++; + } + } + if ((sInstance->mState == ADD_NEW) || (sInstance->mState == ADD_COPY)) { + grids->addElement(""); + selectIndex = i++; + } + if (selectIndex >= 0) { + //grids->setCurrentByIndex(selectIndex); + } else { + //grids->setLabel(LLStringExplicit("")); // LLComboBox::removeall() does not clear the label + } + + sInstance->childSetTextArg("default_grid", "[DEFAULT]", (defaultGrid != "")? defaultGrid: " "); + + sInstance->childSetEnabled("btn_delete", (selectIndex >= 0)); + sInstance->childSetEnabled("btn_copy", (sInstance->mState == NORMAL) && (selectIndex >= 0)); + sInstance->childSetEnabled("set_default", (sInstance->mState == NORMAL) && (selectIndex > 0)); + sInstance->childSetEnabled("gridnick", (sInstance->mState == ADD_NEW) || (sInstance->mState == ADD_COPY)); + + + LLComboBox *platform = sInstance->getChild("platform"); + platform->removeall(); + for (int p=HippoGridInfo::PLATFORM_OTHER; padd(HippoGridInfo::getPlatformString(static_cast(p))); + + + if (sInstance->mState == NORMAL) { + HippoGridInfo *gridInfo = gHippoGridManager->getGrid(sInstance->mCurGrid); + if (gridInfo) { + sInstance->childSetText("gridnick", gridInfo->getGridNick()); + platform->setCurrentByIndex(gridInfo->getPlatform()); + //sInstance->childSetText("grid_name", gridInfo->getGridName()); + sInstance->childSetText("loginuri", gridInfo->getLoginUri()); + sInstance->childSetText("loginpage", gridInfo->getLoginPage()); + sInstance->childSetText("helperuri", gridInfo->getHelperUri()); + sInstance->childSetText("website", gridInfo->getWebSite()); + sInstance->childSetText("first_name", gridInfo->getFirstName()); + sInstance->childSetText("last_name", gridInfo->getLastName()); + if(gridInfo->getAvatarPassword().length() == 32) + sInstance->childSetText("password", std::string(PASSWORD_FILLER)); + else if(gridInfo->getPasswordUrl().empty()) + sInstance->childSetText("password", std::string("")); +/* + if (gridInfo->getPlatform() == HippoGridInfo::PLATFORM_SECONDLIFE) { + //childSetEnabled("search", false); + //childSetText("search", LLStringExplicit("")); + childSetEnabled("render_compat", false); + childSetValue("render_compat", false); + } else { + //childSetEnabled("search", true); + //childSetText("search", gridInfo->getSearchUrl()); + childSetEnabled("render_compat", true); + childSetValue("render_compat", gridInfo->isRenderCompat()); + } + */ + } else { + std::string empty = ""; + sInstance->childSetText("gridnick", empty); + platform->setCurrentByIndex(HippoGridInfo::PLATFORM_OTHER); + sInstance->childSetText("gridname", empty); + sInstance->childSetText("loginuri", empty); + sInstance->childSetText("loginpage", empty); + sInstance->childSetText("helperuri", empty); + sInstance->childSetText("website", empty); + sInstance->childSetText("first_name", empty); + sInstance->childSetText("last_name", empty); + sInstance->childSetText("password", empty); + sInstance->childSetEnabled("render_compat", true); + sInstance->childSetValue("render_compat", true); + } + } else if (sInstance->mState == ADD_NEW) { + llwarns << "ADD_NEW" << llendl; + std::string required = ""; + std::string empty = ""; + sInstance->childSetText("gridnick", required); + platform->setCurrentByIndex(HippoGridInfo::PLATFORM_OTHER); + sInstance->childSetText("gridname", empty); + sInstance->childSetText("loginuri", required); + sInstance->childSetText("loginpage", empty); + sInstance->childSetText("helperuri", empty); + sInstance->childSetText("website", empty); + sInstance->childSetText("first_name", empty); + sInstance->childSetText("last_name", empty); + sInstance->childSetText("password", empty); + //childSetEnabled("search", true); + //childSetText("search", empty); + sInstance->childSetEnabled("render_compat", true); + sInstance->childSetValue("render_compat", true); + } else if (sInstance->mState == ADD_COPY) { + llwarns << "ADD_COPY" << llendl; + sInstance->childSetText("gridnick", LLStringExplicit("")); + } else { + llwarns << "Illegal state " << sInstance->mState << '.' << llendl; + } + return; +} + +void LoginFloater::update() +{ + mState = NORMAL; + mCurGrid = gHippoGridManager->getCurrentGridNick(); + refresh_grids(); + //KOW gHippoLimits->setLimits(); +} + +void LoginFloater::applyChanges() +{ + HippoGridInfo *gridInfo = gHippoGridManager->getGrid(mCurGrid); + if (gridInfo) + { + if (gridInfo->getGridNick() == childGetValue("gridnick").asString()) + { + gridInfo->setPlatform(childGetValue("platform")); + gridInfo->setGridName(childGetValue("gridname")); + gridInfo->setLoginUri(childGetValue("loginuri")); + gridInfo->setLoginPage(childGetValue("loginpage")); + gridInfo->setHelperUri(childGetValue("helperuri")); + gridInfo->setWebSite(childGetValue("website")); + gridInfo->setFirstName(childGetValue("first_name")); + gridInfo->setLastName(childGetValue("last_name")); + //gridInfo->setSearchUrl(childGetValue("search")); + gridInfo->setRenderCompat(childGetValue("render_compat")); + + if(childGetValue("password").asString().empty()) + gridInfo->setPasswordUrl(std::string("")); + else if(childGetValue("password").asString() != std::string(PASSWORD_FILLER)) + { + // store account authentication data + std::string auth_password = childGetValue("password"); + std::string hashed_password; + hashPassword(auth_password, hashed_password); + gridInfo->setAvatarPassword(hashed_password); + } + LLPanelLogin::setFields(gridInfo->getFirstName(), gridInfo->getLastName(), + gridInfo->getAvatarPassword(), true); + } + else + { + llwarns << "Grid nickname mismatch, ignoring changes." << llendl; + } + } +} + + +bool LoginFloater::createNewGrid() +{ + // check nickname + std::string gridnick = childGetValue("gridnick"); + if (gridnick == "") gridnick = ""; + HippoGridInfo::cleanUpGridNick(gridnick); + childSetValue("gridnick", (gridnick != "")? gridnick: ""); + if (gridnick == "") { + //KOW gViewerWindow->alertXml("GridsNoNick"); + return false; + } + if (gHippoGridManager->getGrid(gridnick)) { + LLStringUtil::format_map_t args; + args["[NAME]"] = gridnick; + //KOW gViewerWindow->alertXml("GridExists", args); + return false; + } + + // check login URI + std::string loginuri = childGetValue("loginuri"); + if ((loginuri == "") || (loginuri == "")) { + LLStringUtil::format_map_t args; + args["[NAME]"] = gridnick; + //KOW gViewerWindow->alertXml("GridsNoLoginUri", args); + return false; + } + + // create new grid + HippoGridInfo *grid = new HippoGridInfo(gridnick); + grid->setPlatform(childGetValue("platform")); + grid->setGridName(childGetValue("gridname")); + grid->setLoginUri(loginuri); + grid->setLoginPage(childGetValue("loginpage")); + grid->setHelperUri(childGetValue("helperuri")); + grid->setWebSite(childGetValue("website")); + grid->setFirstName(childGetValue("first_name")); + grid->setLastName(childGetValue("last_name")); + //grid->setSearchUrl(childGetValue("search")); + grid->setRenderCompat(childGetValue("render_compat")); + gHippoGridManager->addGrid(grid); + + if(childGetValue("password").asString().empty()) + grid->setAvatarPassword(std::string("")); + else + { + std::string hashed_password; + hashPassword(childGetValue("password"), hashed_password); + grid->setAvatarPassword(hashed_password); + } + + mCurGrid = gridnick; + return true; +} + +void LoginFloater::apply() +{ + if (mState == NORMAL) { + applyChanges(); + } else if ((mState == ADD_NEW) || (mState == ADD_COPY)) { + if (!createNewGrid()) return; + } else { + llwarns << "Illegal state " << mState << '.' << llendl; + return; + } + //gHippoGridManager->setCurrentGrid(mCurGrid); + //gHippoGridManager->setDefaultGrid(mCurGrid); + //LLPanelLogin::refreshLoginPage(); + gHippoGridManager->saveFile(); + LLPanelLogin::addServer(LLViewerLogin::getInstance()->getGridLabel()); +} + +void LoginFloater::setDefault() +{ + if (mState == NORMAL) { + applyChanges(); + } else if ((mState == ADD_NEW) || (mState == ADD_COPY)) { + if (!createNewGrid()) return; + } else { + llwarns << "Illegal state " << mState << '.' << llendl; + return; + } + gHippoGridManager->setCurrentGrid(mCurGrid); + gHippoGridManager->setDefaultGrid(mCurGrid); + llwarns << "I think me grid is " << mCurGrid << llendl; + //LLPanelLogin::refreshLoginPage(); + gHippoGridManager->saveFile(); + LLPanelLogin::addServer(LLViewerLogin::getInstance()->getGridLabel()); +} + +void LoginFloater::cancel() +{ + gHippoGridManager->discardAndReload(); + LoginFloater::sModel->revert(); + update(); +} + +void LoginFloater::onSelectGrid(LLUICtrl* ctrl, void *data) +{ + LoginFloater* self = (LoginFloater*)data; + if (self->mState == NORMAL) { + self->applyChanges(); + } else if ((self->mState == ADD_NEW) || (self->mState == ADD_COPY)) { + if (self->createNewGrid()) { + self->mState = NORMAL; + } else { + //LLCtrlListInterface *grids = self->childGetListInterface("search_results"); + //if (!grids) return; + + //LLSD selected_value = grids->getSelectedValue(); + //std::string sim_name = selected_value.asString(); + + LLComboBox *grids = self->getChild("grid_selector"); + grids->setCurrentByIndex(grids->getItemCount() - 1); + return; + } + } else { + llwarns << "Illegal state " << self->mState << '.' << llendl; + return; + } + self->mCurGrid = ctrl->getValue().asString(); + llwarns << "I think me grid is " << self->mCurGrid << llendl; + + self->refresh_grids(); +} + +//static +void LoginFloater::onClickDelete(void *data) +{ + llwarns << "onclickdelete" << llendl; + LoginFloater* self = (LoginFloater*)data; + if (self->mState == NORMAL) + gHippoGridManager->deleteGrid(self->mCurGrid); + self->update(); +} + +//static +void LoginFloater::onClickAdd(void *data) +{ + llwarns << "add" << llendl; + LoginFloater* self = (LoginFloater*)data; + self->mState = ADD_NEW; + self->refresh_grids(); +} + + +//static +void LoginFloater::onClickCopy(void *data) +{ + llwarns << "copy" << llendl; + LoginFloater* self = (LoginFloater*)data; + self->mState = ADD_COPY; + self->refresh_grids(); +} + +//static +void LoginFloater::onClickApply(void *data) +{ + sInstance->apply(); +} + +//static +void LoginFloater::onClickDefault(void *data) +{ + sInstance->setDefault(); +} + +//static +void LoginFloater::onClickCancel(void *data) +{ + sInstance->cancel(); +} + +void LoginFloater::setAlwaysRefresh(bool refresh) +{ + // wargames 2: dead code, LLPanelLogin compatibility + return; +} + +void LoginFloater::refreshLocation( bool force_visible ) +{ + + llwarns << "refreshLocation called" << llendl; + + if (!sInstance) return; + + LLComboBox* combo = sInstance->getChild("start_location_combo"); + + if (LLURLSimString::parse()) + { + combo->setCurrentByIndex( 3 ); // BUG? Maybe 2? + combo->setTextEntry(LLURLSimString::sInstance.mSimString); + } + else + { + BOOL login_last = gSavedSettings.getBOOL("LoginLastLocation"); + combo->setCurrentByIndex( login_last ? 1 : 0 ); + } + + 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); + sInstance->childSetVisible("server_combo", TRUE); +} + +void LoginFloater::newShow(const std::string &grid, bool initialLogin, + void (*callback)(S32 option, void* user_data), + void* callback_data) +{ + + llwarns << "newShow called" << llendl; + if(NULL==sInstance) + { + LoginFloater::sGrid = grid; + LoginFloater::sIsInitialLogin = initialLogin; + sInstance = new LoginFloater(callback, callback_data); + + llwarns << "sInstance assigned. sInstance=" << sInstance << llendl; + } + + // floater controller requires initialized floater and model + if(NULL==sModel) + sModel = AuthenticationModel::getInstance(); + if(NULL==sController) + //sController = new LoginController(sInstance, sModel, sGrid); + + + + llwarns << "newshow called" << llendl; + sInstance->mCurGrid = gHippoGridManager->getCurrentGridNick(); + refresh_grids(); + + // we're important + sInstance->setFrontmost(TRUE); + sInstance->setFocus(TRUE); + +} + +void LoginFloater::testShow(void *lies) +{ + // this is if we want to call LoginFloater from a menu option + // or you know whatever + newShow(std::string("Test"), false, testCallback, NULL); +} + +void LoginFloater::testCallback(S32 option, void *user_data) +{ + // test callback, referenced by testShow() + if(LOGIN_OPTION_CONNECT == option) + { + llinfos << "this is how we connect to a METAVERSE" << llendl; + std::string first, last, password; + BOOL remember = TRUE; + getFields(first, last, password, remember); + llinfos << "first\t\tlast\t\tpassword" << llendl; + llinfos << first << "\t\t" << last << "\t\t" << password << llendl; + } + else if(LOGIN_OPTION_QUIT == option) + { + llinfos << "my login, she die" << llendl; + llinfos << ":(" << llendl; + close(); + } +} + +void LoginFloater::show(const LLRect &rect, BOOL show_server, + void (*callback)(S32 option, void* user_data), + void* callback_data) +{ + // we don't need a grid passed in because this is old-style login + std::string grid = ""; + newShow(grid, TRUE, callback, callback_data); +} + +void LoginFloater::setFocus(BOOL b) +{ + if(b != hasFocus()) + { + if(b) + { + LoginFloater::giveFocus(); + } + else + { + LLPanel::setFocus(b); + } + } +} + +void LoginFloater::giveFocus() +{ + LLComboBox *combo = NULL; + + if(NULL==sInstance) + { + llwarns << "giveFocus has no LoginFloater instance. sInstance=" << sInstance << llendl; + return; + } + + // for our combo box approach, selecting the combo box is almost always + // the right thing to do on the floater receiving focus + combo = sInstance->getChild("name_combo"); + combo->setFocus(TRUE); +} + +void LoginFloater::getFields(std::string &firstname, std::string &lastname, std::string &password, + BOOL &remember) +{ + if (!sInstance) + { + llwarns << "Attempted getFields with no login view shown" << llendl; + return; + } + + std::string loginname = sInstance->childGetText("name_combo"); + + LLStringUtil::replaceTabsWithSpaces(loginname, 1); + LLStringUtil::trim(loginname); + std::vector loginVec; + boost::split(loginVec, loginname, boost::is_any_of(" "), boost::token_compress_on); + if(loginVec.size() == 2) + { + firstname = loginVec[0]; + lastname = loginVec[1]; + } + + password = sInstance->mMungedPassword; + remember = sInstance->childGetValue("remember_check"); +} + +void LoginFloater::getFields(std::string &loginname, std::string &password, BOOL &remember) +{ + std::string first, last, pass; + BOOL rem; + getFields(first, last, pass, rem); + loginname = first + " " + last; + password = pass; + remember = rem; +} + +void LoginFloater::setFields(const std::string& firstname, const std::string& lastname, const std::string& password, + BOOL remember) +{ + if (!sInstance) + { + llwarns << "Attempted setFields with no login view shown" << llendl; + return; + } + + std::string loginname = firstname + " " + lastname; + sInstance->childSetText("name_combo", loginname); + + // 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; + } + + sInstance->childSetValue("remember_check", remember); +} + +void LoginFloater::setFields(const std::string &loginname, const std::string &password, BOOL remember) +{ + std::vector loginVec; + boost::split(loginVec, loginname, boost::is_any_of(" "), boost::token_compress_on); + setFields(loginVec[0], loginVec[1], password, remember); +} + +BOOL LoginFloater::isGridComboDirty() +{ + BOOL user_picked = FALSE; + if (!sInstance) + { + llwarns << "Attempted getServer with no login view shown" << llendl; + } + else + { + LLComboBox* combo = sInstance->getChild("server_combo"); + user_picked = combo->isDirty(); + } + return user_picked; +} + +void LoginFloater::getLocation(std::string &location) +{ + if (!sInstance) + { + llwarns << "Attempted getLocation with no login view shown" << llendl; + return; + } + + LLComboBox* combo = sInstance->getChild("start_location_combo"); + location = combo->getValue().asString(); +} + +std::string& LoginFloater::getPassword() +{ + return mMungedPassword; +} + +void LoginFloater::setPassword(std::string &password) +{ + mMungedPassword = password; +} + +bool LoginFloater::isSamePassword(std::string &password) +{ + return mMungedPassword == password; +} + +void LoginFloater::addServer(const std::string& server, S32 domain_name) +{ + if (!sInstance) + { + llwarns << "Attempted addServer with no login view shown" << llendl; + return; + } + + LLComboBox* combo = sInstance->getChild("server_combo"); + combo->add(server, LLSD(domain_name) ); + combo->setCurrentByIndex(0); +} + +void LoginFloater::accept() +{ + if(NULL==sInstance || NULL==sInstance->mCallback) + return; + + sInstance->setFocus(FALSE); + + std::string name_combo = sInstance->childGetText("name_combo"); + if(!name_combo.empty()) + { + sInstance->mCallback(LOGIN_OPTION_CONNECT, sInstance->mCallbackData); + } + else + { + // TODO: new account call goes here + return; + } +} + +void LoginFloater::cancel_old() +{ + if(NULL==sInstance) + return; + + if(sInstance->sIsInitialLogin) + { + // send a callback that indicates we're quitting or closing + if(sInstance->mCallback) + sInstance->mCallback(LOGIN_OPTION_QUIT, sInstance->mCallbackData); + return; + } + + sInstance->close(); +} + +void LoginFloater::hashPassword(const std::string& password, std::string& hashedPassword) +{ + // Max "actual" password length is 16 characters. + // Hex digests are always 32 characters. + if (password.length() == 32) + { + hashedPassword = password; + } + else + { + // this is a normal text password + LLMD5 pass((unsigned char *)password.c_str()); + char munged_password[MD5HEX_STR_SIZE]; + pass.hex_digest(munged_password); + hashedPassword = munged_password; + } + +} + diff --git a/linden/indra/newview/floaterlogin.h b/linden/indra/newview/floaterlogin.h new file mode 100644 index 0000000..1800897 --- /dev/null +++ b/linden/indra/newview/floaterlogin.h @@ -0,0 +1,98 @@ +/* + * floaterlogin.h + * SecondLife + * + * Created by RMS on 7/15/08. + * + */ +#ifndef PL_floaterlogin_H +#define PL_floaterlogin_H + +#define LOGIN_OPTION_CONNECT 0 +#define LOGIN_OPTION_QUIT 1 + +#include "llfloater.h" + +class LoginController; +class AuthenticationModel; + +class LoginFloater : public LLFloater +{ +public: + LoginFloater(void (*callback)(S32 option, void *user_data), + void *callback_data); + virtual ~LoginFloater(); + + virtual BOOL postBuild(); + + static void refresh_grids(); + void apply(); + void setDefault(); + void cancel(); + + // new-style login methods + static void newShow(const std::string &grid, bool initialLogin, + void (*callback)(S32 option, void *user_data), + void *callback_data); + static void testShow(void *lies); + static void testCallback(S32 option, void *user_data); + virtual std::string& getPassword(); + virtual void setPassword(std::string &password); + virtual bool isSamePassword(std::string &password); + static void getFields(std::string &loginname, std::string &password, + BOOL &remember); + static void setFields(const std::string &loginname, const std::string &password, + BOOL remember); + + // LLLoginPanel compatibility + //TODO: Make this not suck + static void show(const LLRect &rect, BOOL show_server, + void (*callback)(S32 option, void *user_data), + void *callback_data); + static void close(); + static void setAlwaysRefresh(bool refresh); + static void refreshLocation(bool force_visible); + virtual void setFocus(BOOL b); + static void giveFocus(); + static void getFields(std::string& firstname, std::string& lastname, + std::string& password, BOOL& remember); + static void setFields(const std::string& firstname, const std::string &lastname, + const std::string& password, BOOL remember); + static void getLocation(std::string &location); + static BOOL isGridComboDirty(); + static void addServer(const std::string& server, S32 domain_name); + static void accept(); + static void cancel_old(); + static void hashPassword(const std::string& password, std::string& hashedPassword); +protected: + static bool sIsInitialLogin; + static std::string sGrid; +private: + enum State { NORMAL, ADD_NEW, ADD_COPY }; + State mState; + std::string mCurGrid; + + std::string mIncomingPassword; + std::string mMungedPassword; + + void applyChanges(); + bool createNewGrid(); + void update(); + + static void onSelectGrid(LLUICtrl *ctrl, void *data); + static void onClickDelete(void *data); + static void onClickAdd(void *data); + static void onClickCopy(void *data); + static void onClickApply(void *data); + static void onClickDefault(void *data); + static void onClickCancel(void *data); + + static LoginFloater *sInstance; + static LoginController *sController; + static AuthenticationModel *sModel; + + void (*mCallback)(S32 option, void *userdata); + void *mCallbackData; +}; + +#endif // PL_floaterlogin_H diff --git a/linden/indra/newview/hippoGridManager.cpp b/linden/indra/newview/hippoGridManager.cpp new file mode 100644 index 0000000..8415adb --- /dev/null +++ b/linden/indra/newview/hippoGridManager.cpp @@ -0,0 +1,597 @@ + + +#include "hippoGridManager.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include "llviewercontrol.h" +#include "llweb.h" + +#include "hippoRestRequest.h" + + +// ******************************************************************** +// Global Variables + +HippoGridManager *gHippoGridManager = 0; + +HippoGridInfo HippoGridInfo::FALLBACK_GRIDINFO(""); + + + +// ******************************************************************** +// ******************************************************************** +// HippoGridInfo +// ******************************************************************** +// ******************************************************************** + + +// ******************************************************************** +// Initialize + +HippoGridInfo::HippoGridInfo(const std::string &gridNick) : + mPlatform(PLATFORM_OTHER), + mGridNick(gridNick), + mRenderCompat(true), + mCurrencySymbol("OS$"), + mRealCurrencySymbol("US$"), + mDirectoryFee(30) +{ + cleanUpGridNick(mGridNick); +} + + +void HippoGridInfo::setPlatform(Platform platform) +{ + mPlatform = platform; + mCurrencySymbol = (mPlatform == PLATFORM_SECONDLIFE)? "L$": "OS$"; +} + + +void HippoGridInfo::setPlatform(const std::string &platform) +{ + std::string tmp = platform; + for (unsigned i=0; imXmlState = XML_GRIDNICK; + else if (strcasecmp(name, "gridname") == 0) + self->mXmlState = XML_GRIDNAME; + else if (strcasecmp(name, "platform") == 0) + self->mXmlState = XML_PLATFORM; + else if ((strcasecmp(name, "login") == 0) || (strcasecmp(name, "loginuri") == 0)) + self->mXmlState = XML_LOGINURI; + else if ((strcasecmp(name, "welcome") == 0) || (strcasecmp(name, "loginpage") == 0)) + self->mXmlState = XML_LOGINPAGE; + else if ((strcasecmp(name, "economy") == 0) || (strcasecmp(name, "helperuri") == 0)) + self->mXmlState = XML_HELPERURI; + else if ((strcasecmp(name, "about") == 0) || (strcasecmp(name, "website") == 0)) + self->mXmlState = XML_WEBSITE; + else if ((strcasecmp(name, "help") == 0) || (strcasecmp(name, "support") == 0)) + self->mXmlState = XML_SUPPORT; + else if ((strcasecmp(name, "register") == 0) || (strcasecmp(name, "account") == 0)) + self->mXmlState = XML_REGISTER; + else if (strcasecmp(name, "password") == 0) + self->mXmlState = XML_PASSWORD; + //else if (strcasecmp(name, "search") == 0) + //self->mXmlState = XML_SEARCH; +} + +//static +void HippoGridInfo::onXmlElementEnd(void *userData, const XML_Char *name) +{ + HippoGridInfo *self = (HippoGridInfo*)userData; + self->mXmlState = XML_VOID; +} + +//static +void HippoGridInfo::onXmlCharacterData(void *userData, const XML_Char *s, int len) +{ + HippoGridInfo *self = (HippoGridInfo*)userData; + switch (self->mXmlState) { + + case XML_GRIDNICK: + if (self->mGridNick == "") self->mGridNick.assign(s, len); + cleanUpGridNick(self->mGridNick); + break; + + case XML_PLATFORM: { + std::string platform(s, len); + self->setPlatform(platform); + break; + } + + case XML_LOGINURI: + self->mLoginUri.assign(s, len); + cleanUpUri(self->mLoginUri); + break; + + case XML_HELPERURI: + self->mHelperUri.assign(s, len); + cleanUpUri(self->mHelperUri); + break; + + case XML_SEARCH: + //self->mSearchUrl.assign(s, len); + //cleanUpQueryUrl(mSearchUrl); + break; + + case XML_GRIDNAME: self->mGridName.assign(s, len); break; + case XML_LOGINPAGE: self->mLoginPage.assign(s, len); break; + case XML_WEBSITE: self->mWebSite.assign(s, len); break; + case XML_SUPPORT: self->mSupportUrl.assign(s, len); break; + case XML_REGISTER: self->mRegisterUrl.assign(s, len); break; + case XML_PASSWORD: self->mPasswordUrl.assign(s, len); break; + + case XML_VOID: break; + } +} + + +bool HippoGridInfo::retrieveGridInfo() +{ + if (mLoginUri == "") return false; + + std::string reply; + int result = HippoRestRequest::getBlocking(mLoginUri + "get_grid_info", &reply); + if (result != 200) return false; + + llinfos << "Received: " << reply << llendl; + + bool success = true; + XML_Parser parser = XML_ParserCreate(0); + XML_SetUserData(parser, this); + XML_SetElementHandler(parser, onXmlElementStart, onXmlElementEnd); + XML_SetCharacterDataHandler(parser, onXmlCharacterData); + mXmlState = XML_VOID; + if (!XML_Parse(parser, reply.data(), reply.size(), TRUE)) { + llwarns << "XML Parse Error: " << XML_ErrorString(XML_GetErrorCode(parser)) << llendl; + success = false; + } + XML_ParserFree(parser); + + return success; +} + + +std::string HippoGridInfo::getUploadFee() const +{ + std::string fee; + formatFee(fee, LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(), true); + return fee; +} + +std::string HippoGridInfo::getGroupCreationFee() const +{ + std::string fee; + formatFee(fee, LLGlobalEconomy::Singleton::getInstance()->getPriceGroupCreate(), false); + return fee; +} + +std::string HippoGridInfo::getDirectoryFee() const +{ + std::string fee; + formatFee(fee, mDirectoryFee, true); + if (fee != "free") fee += "/week"; + return fee; +} + +void HippoGridInfo::formatFee(std::string &fee, int cost, bool showFree) const +{ + if (showFree && (cost == 0)) { + fee = "free"; + } else { + fee = llformat("%s%d", getCurrencySymbol().c_str(), cost); + } +} + + +// ******************************************************************** +// Static Helpers + +// static +const char *HippoGridInfo::getPlatformString(Platform platform) +{ + static const char *platformStrings[PLATFORM_LAST] = { + "Other", "OpenSim", "SecondLife" + }; + + if ((platform < PLATFORM_OTHER) || (platform >= PLATFORM_LAST)) + platform = PLATFORM_OTHER; + return platformStrings[platform]; +} + + +// static +void HippoGridInfo::cleanUpGridNick(std::string &gridnick) +{ + std::string tmp; + int size = gridnick.size(); + for (int i=0; i::iterator it, end = mGridInfo.end(); + for (it=mGridInfo.begin(); it != end; ++it) { + delete it->second; + } + mGridInfo.clear(); +} + + +void HippoGridManager::init() +{ + HippoGridInfo::initFallback(); + loadFromFile(); + + // !!!### gSavedSettings.getControl("CmdLineLoginURI"); + // !!!### gSavedSettings.getString("CmdLineLoginPage"); + // !!!### gSavedSettings.getString("CmdLineHelperURI"); + // !!!### LLString::compareInsensitive(gGridInfo[grid_index].mLabel, grid_name.c_str())) +} + + +void HippoGridManager::discardAndReload() +{ + cleanup(); + loadFromFile(); +} + + +// ******************************************************************** +// Public Access + +HippoGridInfo *HippoGridManager::getGrid(const std::string &grid) const +{ + std::map::const_iterator it; + it = mGridInfo.find(grid); + if (it != mGridInfo.end()) { + return it->second; + } else { + return 0; + } +} + + +HippoGridInfo *HippoGridManager::getCurrentGrid() const +{ + HippoGridInfo *grid = getGrid(mCurrentGrid); + if (grid) { + return grid; + } else { + return &HippoGridInfo::FALLBACK_GRIDINFO; + } +} + + +void HippoGridManager::addGrid(HippoGridInfo *grid) +{ + if (!grid) return; + const std::string &nick = grid->getGridNick(); + if (nick == "") { + llwarns << "Ignoring to try adding grid with empty nick." << llendl; + delete grid; + return; + } + if (mGridInfo.find(nick) != mGridInfo.end()) { + llwarns << "Ignoring to try adding existing grid " << nick << '.' << llendl; + delete grid; + return; + } + mGridInfo[nick] = grid; +} + + +void HippoGridManager::deleteGrid(const std::string &grid) +{ + GridIterator it = mGridInfo.find(grid); + if (it == mGridInfo.end()) { + llwarns << "Trying to delete non-existing grid " << grid << '.' << llendl; + return; + } + mGridInfo.erase(it); + llinfos << "Number of grids now: " << mGridInfo.size() << llendl; + if (mGridInfo.empty()) llinfos << "Grid info map is empty." << llendl; + if (grid == mDefaultGrid) + setDefaultGrid(""); // sets first grid, if map not empty + if (grid == mCurrentGrid) + mCurrentGrid = mDefaultGrid; +} + + +void HippoGridManager::setDefaultGrid(const std::string &grid) +{ + GridIterator it = mGridInfo.find(grid); + if (it != mGridInfo.end()) { + mDefaultGrid = grid; + } else if (mGridInfo.find("secondlife") != mGridInfo.end()) { + mDefaultGrid = "secondlife"; + } else if (!mGridInfo.empty()) { + mDefaultGrid = mGridInfo.begin()->first; + } else { + mDefaultGrid = ""; + } +} + + +void HippoGridManager::setCurrentGrid(const std::string &grid) +{ + GridIterator it = mGridInfo.find(grid); + if (it != mGridInfo.end()) { + mCurrentGrid = grid; + } else if (!mGridInfo.empty()) { + llwarns << "Unknown grid '" << grid << "'. Setting to default grid." << llendl; + mCurrentGrid = mDefaultGrid; + } +} + + +// ******************************************************************** +// Persistent Store + +void HippoGridManager::loadFromFile() +{ + mDefaultGridsVersion = 0; + // load user grid info + parseFile(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "grid_info.xml"), false); + // merge default grid info, if newer. Force load, if list of grids is empty. + parseFile(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "default_grids.xml"), !mGridInfo.empty()); + // merge grid info from web site, if newer. Force load, if list of grids is empty. + if (gSavedSettings.getBOOL("CheckForGridUpdates")) + parseUrl("http://opensim-viewer.sourceforge.net/db/grids.php", !mGridInfo.empty()); + + setDefaultGrid(gSavedSettings.getString("DefaultGrid")); + setCurrentGrid(gSavedSettings.getString("CmdLineGridChoice")); +} + + +void HippoGridManager::parseUrl(const char *url, bool mergeIfNewer) +{ + llinfos << "Loading grid info from '" << url << "'." << llendl; + + // query update server + std::string escaped_url = LLWeb::escapeURL(url); + LLSD response = LLHTTPClient::blockingGet(url); + + // check response, return on error + S32 status = response["status"].asInteger(); + if ((status != 200) || !response["body"].isArray()) { + llinfos << "GridInfo Update failed (" << status << "): " + << (response["body"].isString()? response["body"].asString(): "") + << llendl; + return; + } + + LLSD gridInfo = response["body"]; + parseData(gridInfo, mergeIfNewer); +} + +void HippoGridManager::parseFile(const std::string &fileName, bool mergeIfNewer) +{ + llifstream infile; + infile.open(fileName.c_str()); + if(!infile.is_open()) { + llwarns << "Cannot find grid info file " << fileName << " to load." << llendl; + return; + } + + LLSD gridInfo; + if (LLSDSerialize::fromXML(gridInfo, infile) <= 0) { + llwarns << "Unable to parse grid info file " << fileName << '.' << llendl; + return; + } + + llinfos << "Loading grid info file " << fileName << '.' << llendl; + parseData(gridInfo, mergeIfNewer); +} + + +void HippoGridManager::parseData(LLSD &gridInfo, bool mergeIfNewer) +{ + if (mergeIfNewer) { + LLSD::array_const_iterator it, end = gridInfo.endArray(); + for (it = gridInfo.beginArray(); it != end; ++it) { + LLSD gridMap = *it; + if (gridMap.has("default_grids_version")) { + int version = gridMap["default_grids_version"]; + if (version <= mDefaultGridsVersion) return; + else break; + } + } + if (it == end) { + llwarns << "Grid data has no version number." << llendl; + return; + } + } + + llinfos << "Loading grid data." << llendl; + + LLSD::array_const_iterator it, end = gridInfo.endArray(); + for (it = gridInfo.beginArray(); it != end; ++it) { + LLSD gridMap = *it; + if (gridMap.has("default_grids_version")) { + mDefaultGridsVersion = gridMap["default_grids_version"]; + } else if (gridMap.has("gridnick") && gridMap.has("loginuri")) { + std::string gridnick = gridMap["gridnick"]; + HippoGridInfo *grid; + GridIterator it = mGridInfo.find(gridnick); + bool newGrid = (it == mGridInfo.end()); + if (newGrid) { + // create new grid info + grid = new HippoGridInfo(gridnick); + } else { + // update existing grid info + grid = it->second; + } + grid->setLoginUri(gridMap["loginuri"]); + if (gridMap.has("platform")) grid->setPlatform(gridMap["platform"]); + if (gridMap.has("gridname")) grid->setGridName(gridMap["gridname"]); + if (gridMap.has("loginpage")) grid->setLoginPage(gridMap["loginpage"]); + if (gridMap.has("helperuri")) grid->setHelperUri(gridMap["helperuri"]); + if (gridMap.has("website")) grid->setWebSite(gridMap["website"]); + if (gridMap.has("support")) grid->setSupportUrl(gridMap["support"]); + if (gridMap.has("register")) grid->setRegisterUrl(gridMap["register"]); + if (gridMap.has("password")) grid->setPasswordUrl(gridMap["password"]); + //if (gridMap.has("search")) grid->setSearchUrl(gridMap["search"]); + if (gridMap.has("render_compat")) grid->setRenderCompat(gridMap["render_compat"]); + if (gridMap.has("firstname")) grid->setFirstName(gridMap["firstname"]); + if (gridMap.has("lastname")) grid->setLastName(gridMap["lastname"]); + if (gridMap.has("avatarpassword")) grid->setAvatarPassword(gridMap["avatarpassword"]); + if (newGrid) addGrid(grid); + } + } +} + + +void HippoGridManager::saveFile() +{ + // save default grid to client settings + gSavedSettings.setString("DefaultGrid", mDefaultGrid); + + // build LLSD + LLSD gridInfo; + gridInfo[0]["default_grids_version"] = mDefaultGridsVersion; + + // add grids + S32 i = 1; + GridIterator it, end = mGridInfo.end(); + for (it = mGridInfo.begin(); it != end; ++it, i++) { + HippoGridInfo *grid = it->second; + gridInfo[i]["gridnick"] = grid->getGridNick(); + gridInfo[i]["platform"] = HippoGridInfo::getPlatformString(grid->getPlatform()); + gridInfo[i]["gridname"] = grid->getGridName(); + gridInfo[i]["loginuri"] = grid->getLoginUri(); + gridInfo[i]["loginpage"] = grid->getLoginPage(); + gridInfo[i]["helperuri"] = grid->getHelperUri(); + gridInfo[i]["website"] = grid->getWebSite(); + gridInfo[i]["support"] = grid->getSupportUrl(); + gridInfo[i]["register"] = grid->getRegisterUrl(); + gridInfo[i]["firstname"] = grid->getFirstName(); + gridInfo[i]["lastname"] = grid->getLastName(); + gridInfo[i]["avatarpassword"] = grid->getAvatarPassword(); + + //gridInfo[i]["search"] = grid->getSearchUrl(); + gridInfo[i]["render_compat"] = grid->isRenderCompat(); + } + + // write client grid info file + std::string fileName = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "grid_info.xml"); + llofstream file; + file.open(fileName.c_str()); + if (file.is_open()) { + LLSDSerialize::toPrettyXML(gridInfo, file); + file.close(); + llinfos << "Saved grids to " << fileName << llendl; + } else { + llerrs << "Unable to open grid info file: " << fileName << llendl; + } +} diff --git a/linden/indra/newview/hippoGridManager.h b/linden/indra/newview/hippoGridManager.h new file mode 100644 index 0000000..933a944 --- /dev/null +++ b/linden/indra/newview/hippoGridManager.h @@ -0,0 +1,171 @@ +#ifndef __HIPPO_GRID_MANAGER_H__ +#define __HIPPO_GRID_MANAGER_H__ + + +#include +#include + +#ifndef XML_STATIC +#define XML_STATIC +#endif +#include + + +class LLSD; + + +class HippoGridInfo +{ +public: + enum Platform { + PLATFORM_OTHER = 0, + PLATFORM_OPENSIM, + PLATFORM_SECONDLIFE, + PLATFORM_LAST + }; + enum SearchType { + SEARCH_ALL_EMPTY, + SEARCH_ALL_QUERY, + SEARCH_ALL_TEMPLATE + }; + + explicit HippoGridInfo(const std::string &gridNick); + + Platform getPlatform() const { return mPlatform; } + const std::string &getGridNick() const { return mGridNick; } + const std::string &getGridName() const { return mGridName; } + const std::string &getLoginUri() const { return mLoginUri; } + const std::string &getLoginPage() const { return mLoginPage; } + const std::string &getHelperUri() const { return mHelperUri; } + const std::string &getWebSite() const { return mWebSite; } + const std::string &getSupportUrl() const { return mSupportUrl; } + const std::string &getRegisterUrl() const { return mRegisterUrl; } + const std::string &getPasswordUrl() const { return mPasswordUrl; } + const std::string &getSearchUrl() const { return mSearchUrl; } + const std::string &getFirstName() const { return mFirstName; } + const std::string &getLastName() const { return mLastName; } + const std::string &getAvatarPassword() const { return mAvatarPassword; } + std::string getSearchUrl(SearchType ty) const; + bool isRenderCompat() const { return mRenderCompat; } + + const std::string &getCurrencySymbol() const { return mCurrencySymbol; } + const std::string &getRealCurrencySymbol() const { return mRealCurrencySymbol; } + std::string getUploadFee() const; + std::string getGroupCreationFee() const; + std::string getDirectoryFee() const; + + bool isOpenSimulator() const { return (mPlatform == PLATFORM_OPENSIM ); } + bool isSecondLife() const { return (mPlatform == PLATFORM_SECONDLIFE); } + + void setPlatform (const std::string &platform); + void setPlatform (Platform platform); + void setGridName (const std::string &gridName) { mGridName = gridName; } + void setLoginUri (const std::string &loginUri) { mLoginUri = loginUri; cleanUpUri(mLoginUri); } + void setLoginPage(const std::string &loginPage) { mLoginPage = loginPage; } + void setHelperUri(const std::string &helperUri) { mHelperUri = helperUri; cleanUpUri(mHelperUri); } + void setWebSite (const std::string &website) { mWebSite = website; } + void setSupportUrl(const std::string &url) { mSupportUrl = url; } + void setRegisterUrl(const std::string &url) { mRegisterUrl = url; } + void setPasswordUrl(const std::string &url) { mPasswordUrl = url; } + void setSearchUrl(const std::string &url) { mSearchUrl = url; } + void setRenderCompat(bool compat) { mRenderCompat = compat; } + void setFirstName(const std::string &firstName) { mFirstName = firstName; } //aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + void setLastName(const std::string &lastName) { mLastName = lastName; } + void setAvatarPassword(const std::string &avatarPassword) { mAvatarPassword = avatarPassword; } + + void setCurrencySymbol(const std::string &sym) { mCurrencySymbol = sym.substr(0, 3); } + void setRealCurrencySymbol(const std::string &sym) { mRealCurrencySymbol = sym.substr(0, 3); } + void setDirectoryFee(int fee) { mDirectoryFee = fee; } + + bool retrieveGridInfo(); + + static const char *getPlatformString(Platform platform); + static void cleanUpGridNick(std::string &gridnick); + + static HippoGridInfo FALLBACK_GRIDINFO; + static void initFallback(); + +private: + Platform mPlatform; + std::string mGridNick; + std::string mGridName; + std::string mLoginUri; + std::string mLoginPage; + std::string mHelperUri; + std::string mWebSite; + std::string mSupportUrl; + std::string mRegisterUrl; + std::string mPasswordUrl; + std::string mSearchUrl; + std::string mFirstName; + std::string mLastName; + std::string mAvatarPassword; + bool mRenderCompat; + + std::string mCurrencySymbol; + std::string mRealCurrencySymbol; + int mDirectoryFee; + + // for parsing grid info XML + enum XmlState { + XML_VOID, XML_GRIDNICK, XML_PLATFORM, XML_GRIDNAME, + XML_LOGINURI, XML_LOGINPAGE, XML_HELPERURI, + XML_WEBSITE, XML_SUPPORT, XML_REGISTER, XML_PASSWORD, XML_SEARCH + }; + XmlState mXmlState; + + static void cleanUpUri(std::string &uri); + void formatFee(std::string &fee, int cost, bool showFree) const; + + static void onXmlElementStart(void *userData, const XML_Char *name, const XML_Char **atts); + static void onXmlElementEnd(void *userData, const XML_Char *name); + static void onXmlCharacterData(void *userData, const XML_Char *s, int len); +}; + + +class HippoGridManager +{ +public: + HippoGridManager(); + ~HippoGridManager(); + + void init(); + void saveFile(); + void discardAndReload(); + + HippoGridInfo *getGrid(const std::string &grid) const; + HippoGridInfo *getConnectedGrid() const { return (mConnectedGrid)? mConnectedGrid: getCurrentGrid(); } + HippoGridInfo *getCurrentGrid() const; + const std::string &getDefaultGridNick() const { return mDefaultGrid; } + const std::string &getCurrentGridNick() const { return mCurrentGrid; } + + void setDefaultGrid(const std::string &grid); + void setCurrentGrid(const std::string &grid); + void setCurrentGridAsConnected() { mConnectedGrid = getCurrentGrid(); } + + void addGrid(HippoGridInfo *grid); + void deleteGrid(const std::string &grid); + + typedef std::map::iterator GridIterator; + GridIterator beginGrid() { return mGridInfo.begin(); } + GridIterator endGrid() { return mGridInfo.end(); } + +private: + std::map mGridInfo; + std::string mDefaultGrid; + std::string mCurrentGrid; + HippoGridInfo *mConnectedGrid; + int mDefaultGridsVersion; + + void cleanup(); + void loadFromFile(); + void parseFile(const std::string &fileName, bool mergeIfNewer); + void parseUrl(const char *url, bool mergeIfNewer); + void parseData(LLSD &gridInfo, bool mergeIfNewer); +}; + + +extern HippoGridManager *gHippoGridManager; + + +#endif diff --git a/linden/indra/newview/hippoLimits.cpp b/linden/indra/newview/hippoLimits.cpp new file mode 100644 index 0000000..63a5899 --- /dev/null +++ b/linden/indra/newview/hippoLimits.cpp @@ -0,0 +1,54 @@ + + +#include "hippoLimits.h" + +#include "hippoGridManager.h" + +#include + + +HippoLimits *gHippoLimits = 0; + + +HippoLimits::HippoLimits() +{ + setLimits(); +} + + +void HippoLimits::setLimits() +{ + if (gHippoGridManager->getConnectedGrid()->getPlatform() == HippoGridInfo::PLATFORM_SECONDLIFE) { + setSecondLifeLimits(); + } else { + setOpenSimLimits(); + } +} + + +void HippoLimits::setOpenSimLimits() +{ + mMaxAgentGroups = 100; + mMaxPrimScale = 256.0f; + mMaxHeight = 10000.0f; + if (gHippoGridManager->getConnectedGrid()->isRenderCompat()) { + llinfos << "Using rendering compatible OpenSim limits." << llendl; + mMinHoleSize = 0.05f; + mMaxHollow = 0.95f; + } else { + llinfos << "Using Hippo OpenSim limits." << llendl; + mMinHoleSize = 0.01f; + mMaxHollow = 0.99f; + } +} + +void HippoLimits::setSecondLifeLimits() +{ + llinfos << "Using Second Life limits." << llendl; + mMaxAgentGroups = 25; + mMaxPrimScale = 10.0f; + mMaxHeight = 4096.0f; + mMinHoleSize = 0.05f; + mMaxHollow = 0.95f; +} + diff --git a/linden/indra/newview/hippoLimits.h b/linden/indra/newview/hippoLimits.h new file mode 100644 index 0000000..333a979 --- /dev/null +++ b/linden/indra/newview/hippoLimits.h @@ -0,0 +1,33 @@ +#ifndef __HIPPO_LIMITS_H__ +#define __HIPPO_LIMITS_H__ + + +class HippoLimits +{ +public: + HippoLimits(); + + int getMaxAgentGroups() const { return mMaxAgentGroups; } + float getMaxHeight() const { return mMaxHeight; } + float getMinHoleSize() const { return mMinHoleSize; } + float getMaxHollow() const { return mMaxHollow; } + float getMaxPrimScale() const { return mMaxPrimScale; } + + void setLimits(); + +private: + int mMaxAgentGroups; + float mMaxHeight; + float mMinHoleSize; + float mMaxHollow; + float mMaxPrimScale; + + void setOpenSimLimits(); + void setSecondLifeLimits(); +}; + + +extern HippoLimits *gHippoLimits; + + +#endif diff --git a/linden/indra/newview/hippoRestRequest.cpp b/linden/indra/newview/hippoRestRequest.cpp new file mode 100644 index 0000000..ab8a557 --- /dev/null +++ b/linden/indra/newview/hippoRestRequest.cpp @@ -0,0 +1,54 @@ + + +#include "hippoRestRequest.h" + +#ifndef CURL_STATICLIB +#define CURL_STATICLIB 1 +#endif +#include + +#include +#include + + +static size_t curlWrite(void *ptr, size_t size, size_t nmemb, void *userData) +{ + std::string *result = (std::string*)userData; + size_t bytes = (size * nmemb); + result->append((char*)ptr, bytes); + return nmemb; +} + + +//static +int HippoRestRequest::getBlocking(const std::string &url, std::string *result) +{ + llinfos << "Requesting: " << url << llendl; + + char curlErrorBuffer[CURL_ERROR_SIZE]; + CURL* curlp = curl_easy_init(); + + curl_easy_setopt(curlp, CURLOPT_NOSIGNAL, 1); // don't use SIGALRM for timeouts + curl_easy_setopt(curlp, CURLOPT_TIMEOUT, 5); // seconds + + curl_easy_setopt(curlp, CURLOPT_WRITEFUNCTION, curlWrite); + curl_easy_setopt(curlp, CURLOPT_WRITEDATA, result); + curl_easy_setopt(curlp, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curlp, CURLOPT_ERRORBUFFER, curlErrorBuffer); + curl_easy_setopt(curlp, CURLOPT_FAILONERROR, 1); + + *result = ""; + S32 curlSuccess = curl_easy_perform(curlp); + S32 httpStatus = 499; + curl_easy_getinfo(curlp, CURLINFO_RESPONSE_CODE, &httpStatus); + + if (curlSuccess != 0) { + llwarns << "CURL ERROR (HTTP Status " << httpStatus << "): " << curlErrorBuffer << llendl; + } else if (httpStatus != 200) { + llwarns << "HTTP Error " << httpStatus << ", but no Curl error." << llendl; + } + + curl_easy_cleanup(curlp); + return httpStatus; +} + diff --git a/linden/indra/newview/hippoRestRequest.h b/linden/indra/newview/hippoRestRequest.h new file mode 100644 index 0000000..e43233c --- /dev/null +++ b/linden/indra/newview/hippoRestRequest.h @@ -0,0 +1,16 @@ +#ifndef __HIPPO_REST_REQTUEST_H__ +#define __HIPPO_REST_REQTUEST_H__ + + +#include + + +class HippoRestRequest +{ + public: + static int getBlocking(const std::string &url, std::string *result); + +}; + + +#endif diff --git a/linden/indra/newview/hippoUpdate.cpp b/linden/indra/newview/hippoUpdate.cpp new file mode 100644 index 0000000..7a33487 --- /dev/null +++ b/linden/indra/newview/hippoUpdate.cpp @@ -0,0 +1,92 @@ + +#include "hippoUpdate.h" + +#include +#include +#include + +#include +#include +#include +#include +#include "llviewercontrol.h" +#include "llviewernetwork.h" +#include "llweb.h" +#include + + +std::string gHippoChannel; + + +// static +bool HippoUpdate::checkUpdate() +{ + llinfos << "Hippo Update Check..." << llendl; + + // get channel name + gHippoChannel = gSavedSettings.getString("ChannelName"); + + // get mac address + char macAddress[18]; + sprintf(macAddress, "%02x:%02x:%02x:%02x:%02x:%02x", + gMACAddress[0], gMACAddress[1], gMACAddress[2], gMACAddress[3], gMACAddress[4], gMACAddress[5]); + + // build URL for update check + char url[1000]; + snprintf(url, 1000, +/* "http://update.mjm.game-host.org/os/viewer.php?" + "product=%s&channel=%s&" + "version_major=%d&version_minor=%d&version_patch=%d&version_base=%s&" + "platform=%s&mac=%s", + LL_PRODUCT, LL_CHANNEL_CSTR, + LL_VERSION_MAJOR, LL_VERSION_MINOR, LL_VERSION_PATCH, LL_VERSION_BASE, + LL_PLATFORM*/"", macAddress); + + // query update server + std::string escaped_url = LLWeb::escapeURL(url); + LLSD response = LLHTTPClient::blockingGet(escaped_url.c_str()); + + // check response, return on error + S32 status = response["status"].asInteger(); + if ((status != 200) || !response["body"].isMap()) { + llinfos << "Hippo Update failed (" << status << "): " + << (response["body"].isString()? response["body"].asString(): "") + << llendl; + return true; + } + + // get data from response + LLSD data = response["body"]; + std::string webpage = (data.has("webpage") && data["webpage"].isString())? data["webpage"].asString(): ""; + std::string message = (data.has("message") && data["message"].isString())? data["message"].asString(): ""; + std::string yourVersion = (data.has("yourVersion") && data["yourVersion"].isString())? data["yourVersion"].asString(): ""; + std::string curVersion = (data.has("curVersion") && data["curVersion"].isString())? data["curVersion"].asString(): ""; + bool update = (data.has("update") && data["update"].isBoolean())? data["update"].asBoolean(): false; + bool mandatory = (data.has("mandatory") && data["mandatory"].isBoolean())? data["mandatory"].asBoolean(): false; + + // log and return, if no update available + llinfos << "Your version is " << yourVersion << ", current version is " << curVersion << '.' << llendl; + if (!update) return true; + llinfos << "Update is " << (mandatory? "mandatory.": "optional.") << llendl; + + // show update dialog + char msg[1000]; + snprintf(msg, 1000, + "There is a new viewer version available.\n" + "\n" + "Your version: %s\n" + "Current version: %s\n" + "%s\n" + "Do you want to visit the web site?", + yourVersion.c_str(), curVersion.c_str(), + mandatory? "\nThis is a mandatory update.\n": ""); + S32 button = OSMessageBox(msg, "Hippo OpenSim Viewer Update", OSMB_YESNO); + if (button == OSBTN_YES) { + llinfos << "Taking user to " << webpage << llendl; + LLWeb::loadURLExternal(webpage); + // exit the viewer + return false; + } + + return !mandatory; +} diff --git a/linden/indra/newview/hippoUpdate.h b/linden/indra/newview/hippoUpdate.h new file mode 100644 index 0000000..632b2ef --- /dev/null +++ b/linden/indra/newview/hippoUpdate.h @@ -0,0 +1,12 @@ +#ifndef __HIPPO_UPDATE_H__ +#define __HIPPO_UPDATE_H__ + + +class HippoUpdate +{ + public: + static bool checkUpdate(); +}; + + +#endif diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index 4d53c88..60faaf2 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp @@ -125,6 +125,7 @@ #include "llvectorperfoptions.h" #include "llurlsimstring.h" #include "llwatchdog.h" +#include "llcallingcard.h" // Included so that constants/settings might be initialized // in save_settings_to_globals() @@ -164,6 +165,10 @@ #include "llcommandlineparser.h" +#include "hippoGridManager.h" +#include "hippoLimits.h" +#include "hippoUpdate.h" + // annoying detail to determine whether font prefs are over-ridden #if LL_LINUX # define LL_DYNAMIC_FONT_DISCOVERY 1 @@ -192,22 +197,35 @@ //---------------------------------------------------------------------------- // viewer.cpp - these are only used in viewer, should be easily moved. +extern void disable_win_error_reporting(); #if LL_DARWIN +#include extern void init_apple_menu(const char* product); +extern OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn); +extern OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn); +extern OSStatus simpleDialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata); +#include #endif // LL_DARWIN + extern BOOL gRandomizeFramerate; extern BOOL gPeriodicSlowFrame; extern BOOL gDebugGL; //////////////////////////////////////////////////////////// // All from the last globals push... + + const F32 DEFAULT_AFK_TIMEOUT = 5.f * 60.f; // time with no input before user flagged as Away From Keyboard F32 gSimLastTime; // Used in LLAppViewer::init and send_stats() F32 gSimFrames; +std::string gDisabledMessage; // Set in LLAppViewer::initConfiguration used in idle_startup + +BOOL gHideLinks = FALSE; // Set in LLAppViewer::initConfiguration, used externally + BOOL gAllowIdleAFK = TRUE; BOOL gAllowTapTapHoldRun = TRUE; BOOL gShowObjectUpdates = FALSE; @@ -233,7 +251,7 @@ F32 gFPSClamped = 10.f; // Pretend we start at target rate. F32 gFrameDTClamped = 0.f; // Time between adjacent checks to network for packets U64 gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds U32 gFrameStalls = 0; -const F64 FRAME_STALL_THRESHOLD = 1.0; +const F64 FRAME_STALL_THRESHOLD = 5.0; LLTimer gRenderStartTime; LLFrameTimer gForegroundTime; @@ -302,7 +320,8 @@ std::string gLoginPage; std::vector gLoginURIs; static std::string gHelperURI; -LLAppViewer::LLUpdaterInfo *LLAppViewer::sUpdaterInfo = NULL ; +//FIXME +//LLAppViewer::LLUpdaterInfo *LLAppViewer::sUpdaterInfo = NULL ; void idle_afk_check() { @@ -453,7 +472,7 @@ static void settings_modify() gSavedSettings.setBOOL("VectorizeSkin", FALSE); #endif } - +/* void LLAppViewer::initGridChoice() { // Load up the initial grid choice from: @@ -470,7 +489,7 @@ void LLAppViewer::initGridChoice() if(grid_choice.empty()) { S32 server = gSavedSettings.getS32("ServerChoice"); - server = llclamp(server, 0, (S32)GRID_INFO_COUNT - 1); + //server = llclamp(server, 0, (S32)GRID_INFO_COUNT - 1); if(server == GRID_INFO_OTHER) { std::string custom_server = gSavedSettings.getString("CustomServer"); @@ -478,11 +497,12 @@ void LLAppViewer::initGridChoice() } else if(server != (S32)GRID_INFO_NONE) { - LLViewerLogin::getInstance()->setGridChoice((EGridInfo)server); + llwarns << "setgridchoice = " << server << llendl; + LLViewerLogin::getInstance()->setGridChoice(server); } } } - +*/ //virtual bool LLAppViewer::initSLURLHandler() { @@ -521,6 +541,7 @@ LLAppViewer::LLAppViewer() : mSecondInstance(false), mSavedFinalSnapshot(false), mQuitRequested(false), + mLogoutRequested(false), mLogoutRequestSent(false), mYieldTime(-1), mMainloopTimeout(NULL), @@ -662,7 +683,6 @@ bool LLAppViewer::init() ui_audio_callback, &LLUI::sGLScaleFactor); LLWeb::initClass(); // do this after LLUI - LLTextEditor::setURLCallbacks(&LLWeb::loadURL, &LLURLDispatcher::dispatchFromTextEditor, &LLURLDispatcher::dispatchFromTextEditor); @@ -683,6 +703,7 @@ bool LLAppViewer::init() // load MIME type -> media impl mappings LLMIMETypes::parseMIMETypes( std::string("mime_types.xml") ); + // Copy settings to globals. *TODO: Remove or move to appropriage class initializers settings_to_globals(); // Setup settings listeners @@ -1117,12 +1138,21 @@ bool LLAppViewer::cleanup() // to ensure shutdown order LLMortician::setZealous(TRUE); + if (mQuitRequested) LLVoiceClient::terminate(); disconnectViewer(); llinfos << "Viewer disconnected" << llendflush; + + + + + //this deletes all your buddies + LLAvatarTracker::instance().reset(); + + if (mQuitRequested) display_cleanup(); release_start_screen(); // just in case @@ -1137,6 +1167,13 @@ bool LLAppViewer::cleanup() LLKeyframeDataCache::clear(); + //clear all the chat off the screen + gConsole->clear(); + + if (!mQuitRequested) //if we are doing a soft cleanup, bail here + { + return true; + } // End TransferManager before deleting systems it depends on (Audio, VFS, AssetStorage) #if 0 // this seems to get us stuck in an infinite loop... gTransferManager.cleanup(); @@ -1242,6 +1279,9 @@ bool LLAppViewer::cleanup() // viewer UI relies on keyboard so keep it aound until viewer UI isa gone delete gKeyboard; gKeyboard = NULL; + // Clean up selection managers after UI is destroyed, as UI + // may be observing them. + LLSelectMgr::cleanupGlobals(); LLViewerObject::cleanupVOClasses(); @@ -1251,6 +1291,7 @@ bool LLAppViewer::cleanup() LLTracker::cleanupInstance(); + // *FIX: This is handled in LLAppViewerWin32::cleanup(). // I'm keeping the comment to remember its order in cleanup, // in case of unforseen dependency. @@ -1319,6 +1360,7 @@ bool LLAppViewer::cleanup() // save mute list. gMuteList used to also be deleted here too. LLMuteList::getInstance()->cache(gAgent.getID()); + if (mPurgeOnExit) { llinfos << "Purging all cache files on exit" << llendflush; @@ -1819,7 +1861,14 @@ bool LLAppViewer::initConfiguration() } } - initGridChoice(); + //init Hippo grid manager + if (!gHippoGridManager) { + gHippoGridManager = new HippoGridManager(); + gHippoGridManager->init(); + } + + + //initGridChoice(); // If we have specified crash on startup, set the global so we'll trigger the crash at the right time if(clp.hasOption("crashonstartup")) @@ -1836,7 +1885,6 @@ bool LLAppViewer::initConfiguration() // achieve this. For now... // *NOTE:Mani The command line parser parses tokens and is - // setup to bail after parsing the '--url' option or the // first option specified without a '--option' flag (or // any other option that uses the 'last_option' setting - // see LLControlGroupCLP::configure()) @@ -1894,6 +1942,22 @@ bool LLAppViewer::initConfiguration() // llerrs << "Failed to parse skin definition." << llendl; // } + // LLXmlTreeNode* rootp = skin_def_tree.getRoot(); + // LLXmlTreeNode* disabled_message_node = rootp->getChildByName("disabled_message"); + // if (disabled_message_node) + // { + // gDisabledMessage = disabled_message_node->getContents(); + // } + + // static LLStdStringHandle hide_links_string = LLXmlTree::addAttributeString("hide_links"); + // rootp->getFastAttributeBOOL(hide_links_string, gHideLinks); + + // // Legacy string. This flag really meant we didn't want to expose references to "Second Life". + // // Just set gHideLinks instead. + // static LLStdStringHandle silent_string = LLXmlTree::addAttributeString("silent_update"); + // BOOL silent_update; + // rootp->getFastAttributeBOOL(silent_string, silent_update); + // gHideLinks = (gHideLinks || silent_update); //} #if LL_DARWIN @@ -2315,7 +2379,7 @@ void LLAppViewer::handleViewerCrash() gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName(); gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath(); gDebugInfo["SessionLength"] = F32(LLFrameTimer::getElapsedSeconds()); - gDebugInfo["StartupState"] = LLStartUp::getStartupStateString(); +//FIXME gDebugInfo["StartupState"] = LLStartUp::getStartupStateString(); gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer) getCurrentRSS() >> 10; if(gLogoutInProgress) @@ -2542,28 +2606,55 @@ void LLAppViewer::removeMarkerFile(bool leave_logout_marker) } } + +//this gets called after we get a packet back from the +//server saying we are logged out, or if the packet times +//out void LLAppViewer::forceQuit() { + + LL_INFOS("forceQuit") << "Destroying the entire world" << LL_ENDL; + if (mQuitRequested) LLApp::setQuitting(); + else + { + if (mLogoutRequested) //we just finished a logout request + { + //LLStartUp::setStartupState( STATE_LOGIN_SHOW ); + LLStartUp::resetLogin(); + cleanup(); + mLogoutRequested=false; + mLogoutRequestSent=false; + } + } } -void LLAppViewer::requestQuit() +void LLAppViewer::requestLogout(bool quit_after) { - llinfos << "requestQuit" << llendl; + + mLogoutRequested=true; + if(quit_after) + mQuitRequested=true; + else + mQuitRequested=false; + + llinfos << "requestLogout" << llendl; LLViewerRegion* region = gAgent.getRegion(); - if( (LLStartUp::getStartupState() < STATE_STARTED) || !region ) + if( (LLStartUp::getStartupState() >= STATE_STARTED) && region ) { - // Quit immediately - forceQuit(); - return; - } - LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE); effectp->setPositionGlobal(gAgent.getPositionGlobal()); effectp->setColor(LLColor4U(gAgent.getEffectColor())); LLHUDManager::getInstance()->sendEffects(); + send_stats(); + } + else + { + mQuitRequested=true; + LLAppViewer::instance()->forceQuit(); + } // Attempt to close all floaters that might be // editing things. @@ -2573,17 +2664,14 @@ void LLAppViewer::requestQuit() gFloaterView->closeAllChildren(true); } - send_stats(); - gLogoutTimer.reset(); - mQuitRequested = true; } static void finish_quit(S32 option, void *userdata) { if (option == 0) { - LLAppViewer::instance()->requestQuit(); + LLAppViewer::instance()->requestLogout(true); } } @@ -2592,6 +2680,12 @@ void LLAppViewer::userQuit() gViewerWindow->alertXml("ConfirmQuit", finish_quit, NULL); } +//static +void LLAppViewer::userLogout(void *userdata) +{ + LLAppViewer::instance()->requestLogout(false); +} + static void finish_early_exit(S32 option, void* userdata) { LLAppViewer::instance()->forceQuit(); @@ -2619,6 +2713,7 @@ void LLAppViewer::abortQuit() { llinfos << "abortQuit()" << llendl; mQuitRequested = false; + mLogoutRequested = false; } bool LLAppViewer::initCache() @@ -2895,7 +2990,7 @@ void finish_forced_disconnect(S32 /* option */, void* /* userdata */) void LLAppViewer::forceDisconnect(const std::string& mesg) { - if (gDoDisconnect) + if (gDoDisconnect||mQuitRequested||mLogoutRequested) { // Already popped up one of these dialogs, don't // do this again. @@ -3198,9 +3293,12 @@ void LLAppViewer::idle() // Check for away from keyboard, kick idle agents. idle_afk_check(); + if (!gDisconnected) //check again + { // Update statistics for this frame update_statistics(gFrameCount); } + } //////////////////////////////////////// // @@ -3401,7 +3499,7 @@ void LLAppViewer::idle() // Handle shutdown process, for example, // wait for floaters to close, send quit message, // forcibly quit if it has taken too long - if (mQuitRequested) + if (mQuitRequested || mLogoutRequested) { idleShutdown(); } @@ -3501,12 +3599,12 @@ void LLAppViewer::sendLogoutRequest() if (mLogoutMarkerFile) { llinfos << "Created logout marker file " << mLogoutMarkerFileName << llendl; - apr_file_close(mLogoutMarkerFile); } else { llwarns << "Cannot create logout marker file " << mLogoutMarkerFileName << llendl; } + apr_file_close(mLogoutMarkerFile); } } @@ -3523,6 +3621,9 @@ static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME; void LLAppViewer::idleNetwork() { + if (gDisconnected) + return; + pingMainloopTimeout("idleNetwork"); gObjectList.mNumNewObjects = 0; @@ -3609,7 +3710,11 @@ void LLAppViewer::idleNetwork() gObjectList.mNumNewObjectsStat.addValue(gObjectList.mNumNewObjects); + if (gDisconnected) + return; + // Retransmit unacknowledged packets. + if (gXferManager) gXferManager->retransmitUnackedPackets(); gAssetStorage->checkForTimeouts(); @@ -3619,7 +3724,7 @@ void LLAppViewer::idleNetwork() // Check that the circuit between the viewer and the agent's current // region is still alive LLViewerRegion *agent_region = gAgent.getRegion(); - if (agent_region) + if ((agent_region)&&(LLStartUp::getStartupState() == STATE_STARTED)) { LLUUID this_region_id = agent_region->getRegionID(); bool this_region_alive = agent_region->isAlive(); @@ -3639,6 +3744,9 @@ void LLAppViewer::disconnectViewer() { return; } + + //set this true now, to prevent things from trying to access the network we are destroying + gDisconnected = TRUE; // // Cleanup after quitting. // @@ -3688,8 +3796,8 @@ void LLAppViewer::disconnectViewer() // Now we just ask the LLWorld singleton to cleanly shut down. LLWorld::getInstance()->destroyClass(); + if (mQuitRequested) cleanup_xfer_manager(); - gDisconnected = TRUE; } void LLAppViewer::forceErrorLLError() diff --git a/linden/indra/newview/llappviewer.h b/linden/indra/newview/llappviewer.h index 3be5de7..8d8e30f 100644 --- a/linden/indra/newview/llappviewer.h +++ b/linden/indra/newview/llappviewer.h @@ -61,13 +61,15 @@ public: // Application control void forceQuit(); // Puts the viewer into 'shutting down without error' mode. - void requestQuit(); // Request a quit. A kinder, gentler quit. + void requestLogout(bool quit_after); // Request a logout, optionally quitting after void userQuit(); // The users asks to quit. Confirm, then requestQuit() + static void userLogout(void *userdata); //graceful logout without quit void earlyExit(const std::string& msg); // Display an error dialog and forcibly quit. void forceExit(S32 arg); // exit() immediately (after some cleanup). void abortQuit(); // Called to abort a quit request. bool quitRequested() { return mQuitRequested; } + bool logoutRequested() { return mLogoutRequested; } bool logoutRequestSent() { return mLogoutRequestSent; } void writeDebugInfo(); @@ -157,11 +159,12 @@ protected: virtual std::string generateSerialNumber() = 0; // Platforms specific classes generate this. + private: bool initThreads(); // Initialize viewer threads, return false on failure. bool initConfiguration(); // Initialize settings from the command line/config file. - void initGridChoice(); + //void initGridChoice(); bool initCache(); // Initialize local client cache. void purgeCache(); // Clear the local cache. @@ -211,6 +214,7 @@ private: bool mSavedFinalSnapshot; bool mQuitRequested; // User wants to quit, may have modified documents open. + bool mLogoutRequested; // User wants to log out, but not quit bool mLogoutRequestSent; // Disconnect message sent to simulator, no longer safe to send messages to the sim. S32 mYieldTime; LLSD mSettingsFileList; @@ -220,15 +224,6 @@ private: // for tracking viewer<->region circuit death bool mAgentRegionLastAlive; LLUUID mAgentRegionLastID; - -public: - //some information for updater - typedef struct - { - std::string mUpdateExePath; - std::ostringstream mParams; - }LLUpdaterInfo ; - static LLUpdaterInfo *sUpdaterInfo ; }; // consts from viewer.h @@ -239,6 +234,9 @@ const S32 AGENT_UPDATES_PER_SECOND = 10; // // "// llstartup" indicates that llstartup is the only client for this global. + +extern std::string gDisabledMessage; // llstartup +extern BOOL gHideLinks; // used by llpanellogin, lllfloaterbuycurrency, llstartup extern LLSD gDebugInfo; extern BOOL gAllowIdleAFK; diff --git a/linden/indra/newview/llappviewerlinux.h b/linden/indra/newview/llappviewerlinux.h index b464e48..2f5c13b 100644 --- a/linden/indra/newview/llappviewerlinux.h +++ b/linden/indra/newview/llappviewerlinux.h @@ -61,9 +61,10 @@ public: protected: virtual bool beingDebugged(); - + virtual bool restoreErrorTrap(); virtual void handleCrashReporting(bool reportFreeze); + virtual void handleSyncCrashTrace(); virtual bool initLogging(); diff --git a/linden/indra/newview/llcallingcard.cpp b/linden/indra/newview/llcallingcard.cpp index 1d353fa..ccecef9 100644 --- a/linden/indra/newview/llcallingcard.cpp +++ b/linden/indra/newview/llcallingcard.cpp @@ -136,8 +136,20 @@ LLAvatarTracker::~LLAvatarTracker() deleteTrackingData(); std::for_each(mObservers.begin(), mObservers.end(), DeletePointer()); std::for_each(mBuddyInfo.begin(), mBuddyInfo.end(), DeletePairedPointer()); + mObservers.erase(mObservers.begin(), mObservers.end()); + mBuddyInfo.erase(mBuddyInfo.begin(), mBuddyInfo.end()); } + +void LLAvatarTracker::reset() +{ + std::for_each(mBuddyInfo.begin(), mBuddyInfo.end(), DeletePairedPointer()); + mBuddyInfo.erase(mBuddyInfo.begin(), mBuddyInfo.end()); + mModifyMask |= LLFriendObserver::REMOVE; + notifyObservers(); +} + + void LLAvatarTracker::track(const LLUUID& avatar_id, const std::string& name) { deleteTrackingData(); diff --git a/linden/indra/newview/llcallingcard.h b/linden/indra/newview/llcallingcard.h index cbcb237..21eea2b 100644 --- a/linden/indra/newview/llcallingcard.h +++ b/linden/indra/newview/llcallingcard.h @@ -85,7 +85,7 @@ class LLAvatarTracker { public: static LLAvatarTracker& instance() { return sInstance; } - + void reset(); void track(const LLUUID& avatar_id, const std::string& name); void untrack(const LLUUID& avatar_id); bool isTrackedAgentValid() { return mTrackedAgentValid; } diff --git a/linden/indra/newview/lldrawable.h b/linden/indra/newview/lldrawable.h index 15ad2e1..8f18be0 100644 --- a/linden/indra/newview/lldrawable.h +++ b/linden/indra/newview/lldrawable.h @@ -49,6 +49,7 @@ #include "llviewerobject.h" #include "llrect.h" #include "llappviewer.h" // for gFrameTimeSeconds +#include "llimagej2c.h" class LLCamera; class LLDrawPool; diff --git a/linden/indra/newview/llfloaterworldmap.cpp b/linden/indra/newview/llfloaterworldmap.cpp index bc61d8a..b235265 100644 --- a/linden/indra/newview/llfloaterworldmap.cpp +++ b/linden/indra/newview/llfloaterworldmap.cpp @@ -68,6 +68,12 @@ #include "llappviewer.h" #include "llmapimagetype.h" #include "llweb.h" +#include "floaterlogin.h" +#include "llstartup.h" +#include "hippoGridManager.h" +#include "floaterlogin.h" +#include "llpanellogin.h" + #include "llglheaders.h" @@ -237,6 +243,10 @@ BOOL LLFloaterWorldMap::postBuild() landmark_combo->setTextEntryCallback( onComboTextEntry ); } + childSetCommitCallback("grid_combo", onSelectServer, this); + + childSetAction("Grid Manager", onGridManager, this); + childSetAction("Go Home", onGoHome, this); childSetAction("Teleport", onClickTeleportBtn, this); @@ -327,6 +337,8 @@ void LLFloaterWorldMap::show(void*, BOOL center_on_target) // If nothing is being tracked, set flag so the user position will be found gFloaterWorldMap->mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING ); + + LLFloaterWorldMap::addServer(gHippoGridManager->getDefaultGridNick()); } if (center_on_target) @@ -371,6 +383,48 @@ void LLFloaterWorldMap::hide(void*) } +// static +void LLFloaterWorldMap::addServer(const std::string& server) +{ + const std::string &defaultGrid = gHippoGridManager->getDefaultGridNick(); + + LLCtrlListInterface *grids = gFloaterWorldMap->childGetListInterface("grid_combo"); + if (!grids) return; + + // Delete all but the "None" entry + S32 list_size = grids->getItemCount(); + while (list_size > 1) + { + grids->selectNthItem(1); + grids->operateOnSelection(LLCtrlListInterface::OP_DELETE); + --list_size; + } + + + //LLComboBox *grids = gFloaterWorldMap->getChild("grid_combo"); + S32 selectIndex = -1, i = 0; + //grids->removeall(); + if (defaultGrid != "") { + grids->addSimpleElement(defaultGrid); + selectIndex = i++; + } + HippoGridManager::GridIterator it, end = gHippoGridManager->endGrid(); + for (it = gHippoGridManager->beginGrid(); it != end; ++it) { + const std::string &grid = it->second->getGridNick(); + if (grid != defaultGrid) { + grids->addSimpleElement(grid); + //if (grid == mCurGrid) selectIndex = i; + i++; + } + } + grids->selectFirstItem(); + //grids->setCurrentByIndex(0); + + //LLComboBox* combo = sInstance->getChild("server_combo"); + //combo->add(server, LLSD(domain_name) ); + //combo->setCurrentByIndex(0); +} + // virtual void LLFloaterWorldMap::setVisible( BOOL visible ) { @@ -443,7 +497,10 @@ void LLFloaterWorldMap::draw() childSetEnabled("Go Home", enable_go_home); updateLocation(); - + + LLComboBox *grid_combo = getChild("grid_combo"); + std::string current_grid = gHippoGridManager->getConnectedGrid()->getGridNick(); + LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus(); if (LLTracker::TRACKING_AVATAR == tracking_status) { @@ -489,7 +546,19 @@ void LLFloaterWorldMap::draw() centerOnTarget(TRUE); } - childSetEnabled("Teleport", (BOOL)tracking_status); + //GRID MANAGER + if (grid_combo->getSelectedValue().asString() != "None") + { + childSetEnabled("Teleport", TRUE); + childSetColor("grid_icon", gTrackColor); + } + else + { + childSetEnabled("Teleport", (BOOL)tracking_status); + childSetColor("grid_icon", gDisabledTrackColor); + } + //END GRID MANAGER + // childSetEnabled("Clear", (BOOL)tracking_status); childSetEnabled("Show Destination", (BOOL)tracking_status || LLWorldMap::getInstance()->mIsTrackingUnknownLocation); childSetEnabled("copy_slurl", (mSLURL.size() > 0) ); @@ -743,7 +812,7 @@ void LLFloaterWorldMap::updateLocation() void LLFloaterWorldMap::trackURL(const std::string& region_name, S32 x_coord, S32 y_coord, S32 z_coord) { LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromName(region_name); - z_coord = llclamp(z_coord, 0, 4096); + z_coord = llclamp(z_coord, 0, 1000); if (sim_info) { LLVector3 local_pos; @@ -953,6 +1022,18 @@ void LLFloaterWorldMap::clearLocationSelection(BOOL clear_ui) } +void LLFloaterWorldMap::clearGridSelection(BOOL clear_ui) +{ + if (clear_ui || !childHasKeyboardFocus("grid_combo")) + { + LLCtrlListInterface *list = childGetListInterface("grid_combo"); + if (list) + { + list->selectByValue( "None" ); + } + } +} + void LLFloaterWorldMap::clearLandmarkSelection(BOOL clear_ui) { if (clear_ui || !childHasKeyboardFocus("landmark combo")) @@ -1050,9 +1131,18 @@ void LLFloaterWorldMap::onPanBtn( void* userdata ) } // static +void LLFloaterWorldMap::onGridManager(void*) +{ + LoginFloater::newShow(std::string("Test"), false, LoginFloater::testCallback, NULL); + //gAgent.teleportHome(); + //gFloaterWorldMap->close(); +} + +// static void LLFloaterWorldMap::onGoHome(void*) { gAgent.teleportHomeConfirm(); + gFloaterWorldMap->close(); } @@ -1135,6 +1225,9 @@ void LLFloaterWorldMap::onLandmarkComboCommit( LLUICtrl* ctrl, void* userdata ) item_id.setNull(); } } + //GRID MANAGER HAX + self->clearGridSelection(TRUE); + //END GRID MANAGER HAX self->trackLandmark( item_id); onShowTargetBtn(self); @@ -1186,6 +1279,10 @@ void LLFloaterWorldMap::onAvatarComboCommit( LLUICtrl* ctrl, void* userdata ) const LLUUID& new_avatar_id = list->getCurrentID(); if (new_avatar_id.notNull()) { + //GRID MANAGER HAX + self->clearGridSelection(TRUE); + //END GRID MANAGER HAX + std::string name; LLComboBox* combo = gFloaterWorldMap->getChild("friend combo"); if (combo) name = combo->getSimple(); @@ -1267,6 +1364,10 @@ void LLFloaterWorldMap::onClearBtn(void* data) LLWorldMap::getInstance()->mIsTrackingUnknownLocation = FALSE; self->mSLURL = ""; // Clear the SLURL since it's invalid self->mSetToUserPosition = TRUE; // Revert back to the current user position + //KOW TODO clear grid combo red ring, clear grid combo. + //GRID MANAGER HAX + self->clearGridSelection(TRUE); + //END GRID MANAGER HAX } // static @@ -1376,6 +1477,39 @@ void LLFloaterWorldMap::fly() // protected void LLFloaterWorldMap::teleport() { + //BEGIN CROSS GRIP TP// + LLComboBox *grid_combo = getChild("grid_combo"); + std::string current_grid = gHippoGridManager->getConnectedGrid()->getGridNick(); + + // BUG: the client crashes if fed an invalid grid through this interface, which shouldn't happen + if(//grid_combo && grid_combo->getSelectedValue().asString() != current_grid || gSavedSettings.getBOOL("CmdLineLoginURI") && + grid_combo->getSelectedValue().asString() != "None" && + !grid_combo->getSelectedValue().asString().empty()) + { + HippoGridInfo *gridInfo = gHippoGridManager->getGrid(grid_combo->getSelectedValue().asString()); + //DEBUG + + llwarns << "tp button current grid = " << grid_combo->getSelectedValue().asString() << llendl; + std::string firstName = gridInfo->getFirstName(); + std::string lastName = gridInfo->getLastName(); + std::string loginPassword = gridInfo->getAvatarPassword(); + + if(!firstName.empty() && !lastName.empty()) + { + gLoginHandler.mFirstName = firstName; + gLoginHandler.mLastName = lastName; + gLoginHandler.mPassword = loginPassword; + } + + gHippoGridManager->setCurrentGrid(gridInfo->getGridNick()); + gHippoGridManager->setDefaultGrid(gridInfo->getGridNick()); + //this doesn't work :( gSavedSettings.setBOOL("CmdLineLoginURI", FALSE); + LLStartUp::setShouldAutoLogin(true); + LLAppViewer::instance()->requestLogout(false); + return; + } + //END CROSS GRID TP// + BOOL teleport_home = FALSE; LLVector3d pos_global; LLAvatarTracker& av_tracker = LLAvatarTracker::instance(); @@ -1666,3 +1800,20 @@ void LLFloaterWorldMap::onCommitSearchResult(LLUICtrl*, void* userdata) onShowTargetBtn(self); } + +// static +void LLFloaterWorldMap::onSelectServer(LLUICtrl* ctrl, void* userdata) +{ + //GRID MANAGER COMBO BOX CLICKED// + llwarns << "onSelectServer called" << llendl; + //snip from onClearBtn (bless this mess) + LLFloaterWorldMap* self = (LLFloaterWorldMap*) userdata; + self->mTrackedStatus = LLTracker::TRACKING_NOTHING; + LLTracker::stopTracking((void *)(intptr_t)TRUE); + //LLTracker::stopTracking(NULL); + LLWorldMap::getInstance()->mIsTrackingUnknownLocation = FALSE; + self->mSLURL = ""; // Clear the SLURL since it's invalid + self->mSetToUserPosition = TRUE; // Revert back to the current user position + + self->setDefaultBtn("Teleport"); +} diff --git a/linden/indra/newview/llfloaterworldmap.h b/linden/indra/newview/llfloaterworldmap.h index 568d3cc..2f444b9 100644 --- a/linden/indra/newview/llfloaterworldmap.h +++ b/linden/indra/newview/llfloaterworldmap.h @@ -67,6 +67,8 @@ public: static void toggle(void*); static void hide(void*); + static void addServer(const std::string& server); + /*virtual*/ void reshape( S32 width, S32 height, BOOL called_from_parent = TRUE ); /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); @@ -100,6 +102,7 @@ public: void clearLocationSelection(BOOL clear_ui = FALSE); void clearAvatarSelection(BOOL clear_ui = FALSE); void clearLandmarkSelection(BOOL clear_ui = FALSE); + void clearGridSelection(BOOL clear_ui = FALSE); // Adjust the maximally zoomed out limit of the zoom slider so you can // see the whole world, plus a little. @@ -114,8 +117,9 @@ public: protected: static void onPanBtn( void* userdata ); - static void onGoHome(void* data); + static void onGridManager(void* data); + static void onGoHome(void* data); static void onLandmarkComboPrearrange( LLUICtrl* ctrl, void* data ); static void onLandmarkComboCommit( LLUICtrl* ctrl, void* data ); @@ -157,6 +161,7 @@ protected: static void onLocationCommit( void* userdata ); static void onCommitLocation( LLUICtrl* ctrl, void* userdata ); static void onCommitSearchResult( LLUICtrl* ctrl, void* userdata ); + static void onSelectServer(LLUICtrl*, void* userdata); void cacheLandmarkPosition(); diff --git a/linden/indra/newview/llpanellogin.cpp b/linden/indra/newview/llpanellogin.cpp index c26f70f..873920c 100644 --- a/linden/indra/newview/llpanellogin.cpp +++ b/linden/indra/newview/llpanellogin.cpp @@ -34,6 +34,8 @@ #include "llpanellogin.h" #include "llpanelgeneral.h" +#include "hippoGridManager.h" + #include "indra_constants.h" // for key and mask constants #include "llfontgl.h" #include "llmd5.h" @@ -63,17 +65,22 @@ #include "llviewernetwork.h" #include "llviewerwindow.h" // to link into child list #include "llnotify.h" +#include "llappviewer.h" // for gHideLinks #include "llurlsimstring.h" #include "lluictrlfactory.h" #include "llhttpclient.h" #include "llweb.h" #include "llwebbrowserctrl.h" +#include "llfloaterhtml.h" + #include "llfloaterhtmlhelp.h" #include "llfloatertos.h" #include "llglheaders.h" +#include "floaterlogin.h" + #define USE_VIEWER_AUTH 0 std::string load_password_from_disk(void); @@ -130,21 +137,8 @@ void LLLoginHandler::parse(const LLSD& queryMap) mFirstName = queryMap["first_name"].asString(); mLastName = queryMap["last_name"].asString(); - EGridInfo grid_choice = GRID_INFO_NONE; - if (queryMap["grid"].asString() == "sl beta grid") - { - grid_choice = GRID_INFO_ADITI; - } - else if (queryMap["grid"].asString() == "sl main grid") - { - grid_choice = GRID_INFO_AGNI; - } - - if(grid_choice != GRID_INFO_NONE) - { - LLViewerLogin::getInstance()->setGridChoice(grid_choice); - } - + const std::string &grid = queryMap["grid"].asString(); + if (grid != "") gHippoGridManager->setCurrentGrid(grid); std::string startLocation = queryMap["location"].asString(); if (startLocation == "specify") @@ -258,11 +252,6 @@ namespace { boost::intrusive_ptr< LLIamHereLogin > gResponsePtr = 0; }; -void set_start_location(LLUICtrl* ctrl, void* data) -{ - LLURLSimString::setString(ctrl->getValue().asString()); -} - //--------------------------------------------------------------------------- // Public methods //--------------------------------------------------------------------------- @@ -349,13 +338,13 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, combo->setCurrentByIndex( 0 ); } - combo->setCommitCallback( &set_start_location ); LLComboBox* server_choice_combo = sInstance->getChild("server_combo"); server_choice_combo->setCommitCallback(onSelectServer); - server_choice_combo->setFocusLostCallback(onServerComboLostFocus); + //server_choice_combo->setFocusLostCallback(onServerComboLostFocus); childSetAction("connect_btn", onClickConnect, this); + childSetAction("grid_btn", onClickGrid, this); setDefaultBtn("connect_btn"); @@ -657,6 +646,7 @@ void LLPanelLogin::show(const LLRect &rect, // Make sure that focus always goes here (and use the latest sInstance that was just created) gFocusMgr.setDefaultKeyboardFocus(sInstance); + LLPanelLogin::addServer(LLViewerLogin::getInstance()->getGridLabel()); } // static @@ -701,7 +691,7 @@ void LLPanelLogin::setFields(const std::string& firstname, const std::string& la // static -void LLPanelLogin::addServer(const std::string& server, S32 domain_name) +void LLPanelLogin::addServer(const std::string& server) { if (!sInstance) { @@ -709,17 +699,29 @@ void LLPanelLogin::addServer(const std::string& server, S32 domain_name) return; } - LLComboBox* combo = sInstance->getChild("server_combo"); - combo->add(server, LLSD(domain_name) ); - combo->setCurrentByIndex(0); -} + const std::string &defaultGrid = gHippoGridManager->getDefaultGridNick(); + LLComboBox *grids = sInstance->getChild("server_combo"); + S32 selectIndex = -1, i = 0; + grids->removeall(); + if (defaultGrid != "") { + grids->add(defaultGrid); + selectIndex = i++; + } + HippoGridManager::GridIterator it, end = gHippoGridManager->endGrid(); + for (it = gHippoGridManager->beginGrid(); it != end; ++it) { + const std::string &grid = it->second->getGridNick(); + if (grid != defaultGrid) { + grids->add(grid); + //if (grid == mCurGrid) selectIndex = i; + i++; + } + } + grids->setCurrentByIndex(0); -// static -void LLPanelLogin::setServer(S32 domain_name) -{ - LLComboBox* combo = sInstance->getChild("server_combo"); - combo->setCurrentByIndex(domain_name); + //LLComboBox* combo = sInstance->getChild("server_combo"); + //combo->add(server, LLSD(domain_name) ); + //combo->setCurrentByIndex(0); } // static @@ -800,7 +802,12 @@ void LLPanelLogin::refreshLocation( bool force_visible ) sInstance->childSetVisible("start_location_combo", show_start); sInstance->childSetVisible("start_location_text", show_start); +/*#if LL_RELEASE_FOR_DOWNLOAD + BOOL show_server = gSavedSettings.getBOOL("ForceShowGrid"); + sInstance->childSetVisible("server_combo", show_server); +#else*/ sInstance->childSetVisible("server_combo", TRUE); +//#endif #endif } @@ -833,18 +840,39 @@ void LLPanelLogin::setAlwaysRefresh(bool refresh) } +// static +void LLPanelLogin::refreshLoginPage() +{ + if (!sInstance) return; + + sInstance->childSetVisible("create_new_account_text", + !gHippoGridManager->getConnectedGrid()->getRegisterUrl().empty()); + sInstance->childSetVisible("forgot_password_text", + !gHippoGridManager->getConnectedGrid()->getPasswordUrl().empty()); + + // kick off a request to grab the url manually + gResponsePtr = LLIamHereLogin::build(sInstance); + std::string login_page = gHippoGridManager->getConnectedGrid()->getLoginPage(); + if (!login_page.empty()) { + LLHTTPClient::head(login_page, gResponsePtr); + } else { + sInstance->setSiteIsAlive(false); + } +} + void LLPanelLogin::loadLoginPage() { if (!sInstance) return; - std::ostringstream oStr; - std::string login_page = gSavedSettings.getString("LoginPage"); - if (login_page.empty()) - { - login_page = sInstance->getString( "real_url" ); + std::string login_page = gHippoGridManager->getConnectedGrid()->getLoginPage(); + if (login_page.empty()) { + sInstance->setSiteIsAlive(false); + return; } + + std::ostringstream oStr; oStr << login_page; // Use the right delimeter depending on how LLURI parses the URL @@ -879,11 +907,12 @@ void LLPanelLogin::loadLoginPage() curl_free(curl_version); // Grid - char* curl_grid = curl_escape(LLViewerLogin::getInstance()->getGridCodeName().c_str(), 0); + char* curl_grid = curl_escape(LLViewerLogin::getInstance()->getGridLabel().c_str(), 0); oStr << "&grid=" << curl_grid; curl_free(curl_grid); gViewerWindow->setMenuBackgroundColor(false, !LLViewerLogin::getInstance()->isInProductionGrid()); + //LLViewerLogin::getInstance()->setMenuColor(); gLoginMenuBarView->setBackgroundColor(gMenuBarView->getBackgroundColor()); @@ -1017,12 +1046,27 @@ void LLPanelLogin::onClickConnect(void *) } else { + if (gHideLinks) + { + gViewerWindow->alertXml("MustHaveAccountToLogInNoLinks"); + } + else + { gViewerWindow->alertXml("MustHaveAccountToLogIn", LLPanelLogin::newAccountAlertCallback); } } } +} +void LLPanelLogin::onClickGrid(void *) +{ + if (sInstance && sInstance->mCallback) + { + LoginFloater::newShow(std::string("Test"), false, LoginFloater::testCallback, NULL); + } +} + // static void LLPanelLogin::newAccountAlertCallback(S32 option, void*) @@ -1088,7 +1132,7 @@ void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data) } // static -void LLPanelLogin::onSelectServer(LLUICtrl*, void*) +void LLPanelLogin::onSelectServer(LLUICtrl* ctrl, void*) { // *NOTE: The paramters for this method are ignored. // LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe, void*) @@ -1097,11 +1141,31 @@ void LLPanelLogin::onSelectServer(LLUICtrl*, void*) // The user twiddled with the grid choice ui. // apply the selection to the grid setting. std::string grid_label; - S32 grid_index; + //S32 grid_index; LLComboBox* combo = sInstance->getChild("server_combo"); LLSD combo_val = combo->getValue(); + std::string mCurGrid = ctrl->getValue().asString(); + //KOW + gHippoGridManager->setCurrentGrid(mCurGrid); + //gHippoGridManager->setDefaultGrid(mCurGrid); + //gHippoGridManager->saveFile(); + HippoGridInfo *gridInfo = gHippoGridManager->getGrid(mCurGrid); + if (gridInfo) { + //childSetText("gridnick", gridInfo->getGridNick()); + //platform->setCurrentByIndex(gridInfo->getPlatform()); + //childSetText("gridname", gridInfo->getGridName()); + LLPanelLogin::setFields( gridInfo->getFirstName(), gridInfo->getLastName(), gridInfo->getAvatarPassword(), 1 ); + } + //gHippoGridManager->setCurrentGrid(mCurGrid); + + + + llwarns << "current grid = " << mCurGrid << llendl; + + /* + if (LLSD::TypeInteger == combo_val.type()) { grid_index = combo->getValue().asInteger(); @@ -1126,17 +1190,27 @@ void LLPanelLogin::onSelectServer(LLUICtrl*, void*) vl->resetURIs(); if(grid_index != GRID_INFO_OTHER) { - vl->setGridChoice((EGridInfo)grid_index); + vl->setGridChoice(grid_index); } else { vl->setGridChoice(grid_label); } + // clear the password if we are switching grids so we don't send + // the wrong pass to the wrong grid. + if (sInstance) + { + // no method to clear a text box? + const std::string nothing(""); + sInstance->childSetText("password_edit", nothing); + } + */ // grid changed so show new splash screen (possibly) loadLoginPage(); } +/* void LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe, void*) { LLComboBox* combo = sInstance->getChild("server_combo"); @@ -1145,3 +1219,4 @@ void LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe, void*) onSelectServer(combo, NULL); } } +*/ diff --git a/linden/indra/newview/llpanellogin.h b/linden/indra/newview/llpanellogin.h index a303e32..8a9747b 100644 --- a/linden/indra/newview/llpanellogin.h +++ b/linden/indra/newview/llpanellogin.h @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2002&license=viewergpl$ * - * Copyright (c) 2002-2009, Linden Research, Inc. + * Copyright (c) 2002-2008, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -60,6 +60,7 @@ class LLLoginHandler : public LLCommandHandler LLUUID mWebLoginKey; std::string mFirstName; std::string mLastName; + std::string mPassword; }; extern LLLoginHandler gLoginHandler; @@ -86,8 +87,7 @@ public: static void setFields(const std::string& firstname, const std::string& lastname, const std::string& password, BOOL remember); - static void addServer(const std::string& server, S32 domain_name); - static void setServer(S32 domain_name); + static void addServer(const std::string& server); static void refreshLocation( bool force_visible ); static void getFields(std::string& firstname, std::string& lastname, @@ -101,12 +101,14 @@ public: void setSiteIsAlive( bool alive ); static void loadLoginPage(); + static void refreshLoginPage(); static void giveFocus(); static void setAlwaysRefresh(bool refresh); static void mungePassword(LLUICtrl* caller, void* user_data); private: static void onClickConnect(void*); + static void onClickGrid(void*); static void onClickNewAccount(void*); static void newAccountAlertCallback(S32 option, void*); static void onClickQuit(void*); diff --git a/linden/indra/newview/llprogressview.cpp b/linden/indra/newview/llprogressview.cpp index a38aada..157dc6c 100644 --- a/linden/indra/newview/llprogressview.cpp +++ b/linden/indra/newview/llprogressview.cpp @@ -407,7 +407,7 @@ void LLProgressView::onCancelButtonClicked(void*) { if (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE) { - LLAppViewer::instance()->requestQuit(); + LLAppViewer::instance()->requestLogout(true); } else { diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index aca3cac..8f9b728 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp @@ -29,7 +29,14 @@ * $/LicenseInfo$ */ -#include "llviewerprecompiledheaders.h" +// #include "llviewerprecompiledheaders.h" + + +#if LL_WINDOWS + #define WIN32_LEAN_AND_MEAN + #include + #include +#endif #include "llstartup.h" @@ -190,6 +197,8 @@ #include "lldxhardware.h" #endif +#include "hippoGridManager.h" +#include "hippoLimits.h" // // exported globals // @@ -222,7 +231,8 @@ static std::string sInitialOutfitGender; // "male" or "female" static bool gUseCircuitCallbackCalled = false; EStartupState LLStartUp::gStartupState = STATE_FIRST; - +bool LLStartUp::mStartedOnce = false; +bool LLStartUp::mShouldAutoLogin = false; // // local function declaration @@ -248,7 +258,6 @@ void dialog_choose_gender_first_start(); void callback_choose_gender(S32 option, void* userdata); void init_start_screen(S32 location_id); void release_start_screen(); -void reset_login(); void apply_udp_blacklist(const std::string& csv); void callback_cache_name(const LLUUID& id, const std::string& firstname, const std::string& lastname, BOOL is_group, void* data) @@ -322,6 +331,7 @@ bool idle_startup() static S32 timeout_count = 0; static LLTimer login_time; + static LLFrameTimer wearables_timer; // until this is encapsulated, this little hack for the // auth/transform loop will do. @@ -654,7 +664,7 @@ bool idle_startup() show_connect_box = false; } - else if(gSavedSettings.getLLSD("UserLoginInfo").size() == 3) + else if((gSavedSettings.getLLSD("UserLoginInfo").size() == 3) && !LLStartUp::shouldAutoLogin()) { LLSD cmd_line_login = gSavedSettings.getLLSD("UserLoginInfo"); firstname = cmd_line_login[0].asString(); @@ -721,12 +731,19 @@ bool idle_startup() if (STATE_LOGIN_SHOW == LLStartUp::getStartupState()) { LL_DEBUGS("AppInit") << "Initializing Window" << LL_ENDL; + sAuthUris.clear(); + sAuthUriNum = -1; gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW); // Push our window frontmost gViewerWindow->getWindow()->show(); timeout_count = 0; + + if(LLStartUp::shouldAutoLogin()) + { + show_connect_box = false; + } if (show_connect_box) { @@ -809,6 +826,18 @@ bool idle_startup() lastname = gLoginHandler.mLastName; web_login_key = gLoginHandler.mWebLoginKey; } + + if(!gLoginHandler.mPassword.empty()) + { + firstname = gLoginHandler.mFirstName; + lastname = gLoginHandler.mLastName; + password = gLoginHandler.mPassword; + + gLoginHandler.mFirstName = ""; + gLoginHandler.mLastName = ""; + gLoginHandler.mPassword = ""; + LLStartUp::setShouldAutoLogin(false); + } if (show_connect_box) { @@ -836,10 +865,11 @@ bool idle_startup() } gSavedSettings.setBOOL("RememberPassword", remember_password); - LL_INFOS("AppInit") << "Attempting login as: " << firstname << " " << lastname << LL_ENDL; + LL_INFOS("AppInit") << "Attempting login as: " << firstname << " " << lastname << " " << password << LL_ENDL; gDebugInfo["LoginName"] = firstname + " " + lastname; } + gHippoGridManager->setCurrentGridAsConnected(); // create necessary directories // *FIX: these mkdir's should error check gDirUtilp->setLindenUserDir(firstname, lastname); @@ -1031,6 +1061,10 @@ bool idle_startup() LLStringUtil::format_map_t args; args["[APP_NAME]"] = LLAppViewer::instance()->getSecondLifeTitle(); auth_desc = LLTrans::getString("LoginInProgress", args); + + //Since we are about to login, we don't want the client to attempt auto login + //again until the user does a grid2grid teleport. + LLStartUp::setShouldAutoLogin(false); LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE ); } @@ -1070,13 +1104,15 @@ bool idle_startup() hashed_mac.hex_digest(hashed_mac_string); // TODO if statement here to use web_login_key + if(web_login_key.isNull()){ sAuthUriNum = llclamp(sAuthUriNum, 0, (S32)sAuthUris.size()-1); LLUserAuth::getInstance()->authenticate( sAuthUris[sAuthUriNum], auth_method, firstname, lastname, - password, // web_login_key, + password, + //web_login_key, start.str(), gSkipOptionalUpdate, gAcceptTOS, @@ -1085,6 +1121,22 @@ bool idle_startup() requested_options, hashed_mac_string, LLAppViewer::instance()->getSerialNumber()); + } else { + LLUserAuth::getInstance()->authenticate( + sAuthUris[sAuthUriNum], + auth_method, + firstname, + lastname, + web_login_key, + start.str(), + gSkipOptionalUpdate, + gAcceptTOS, + gAcceptCriticalMessage, + gLastExecEvent, + requested_options, + hashed_mac_string, + LLAppViewer::instance()->getSerialNumber()); + } // reset globals gAcceptTOS = FALSE; @@ -1144,7 +1196,6 @@ bool idle_startup() LL_DEBUGS("AppInit") << "STATE_LOGIN_PROCESS_RESPONSE" << LL_ENDL; std::ostringstream emsg; bool quit = false; - bool update = false; std::string login_response; std::string reason_response; std::string message_response; @@ -1188,7 +1239,11 @@ bool idle_startup() reason_response = LLUserAuth::getInstance()->getResponse("reason"); message_response = LLUserAuth::getInstance()->getResponse("message"); - if (!message_response.empty()) + if (gHideLinks && reason_response == "disabled") + { + emsg << gDisabledMessage; + } + else if (!message_response.empty()) { // XUI: fix translation for strings returned during login // We need a generic table for translations @@ -1246,7 +1301,16 @@ bool idle_startup() if(reason_response == "update") { auth_message = LLUserAuth::getInstance()->getResponse("message"); - update = true; + if (show_connect_box) + { + update_app(TRUE, auth_message); + LLStartUp::setStartupState( STATE_UPDATE_CHECK ); + return false; + } + else + { + quit = true; + } } if(reason_response == "optional") { @@ -1284,21 +1348,6 @@ bool idle_startup() break; } - if (update || gSavedSettings.getBOOL("ForceMandatoryUpdate")) - { - gSavedSettings.setBOOL("ForceMandatoryUpdate", FALSE); - if (show_connect_box) - { - update_app(TRUE, auth_message); - LLStartUp::setStartupState( STATE_UPDATE_CHECK ); - return false; - } - else - { - quit = true; - } - } - // Version update and we're not showing the dialog if(quit) { @@ -1511,6 +1560,42 @@ bool idle_startup() } } + // Override grid info with anything sent in the login response + std::string tmp = LLUserAuth::getInstance()->getResponse("gridname"); + if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setGridName(tmp); + tmp = LLUserAuth::getInstance()->getResponse("loginuri"); + if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setLoginUri(tmp); + tmp = LLUserAuth::getInstance()->getResponse("welcome"); + if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setLoginPage(tmp); + tmp = LLUserAuth::getInstance()->getResponse("loginpage"); + if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setLoginPage(tmp); + tmp = LLUserAuth::getInstance()->getResponse("economy"); + if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setHelperUri(tmp); + tmp = LLUserAuth::getInstance()->getResponse("helperuri"); + if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setHelperUri(tmp); + tmp = LLUserAuth::getInstance()->getResponse("about"); + if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setWebSite(tmp); + tmp = LLUserAuth::getInstance()->getResponse("website"); + if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setWebSite(tmp); + tmp = LLUserAuth::getInstance()->getResponse("help"); + if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setSupportUrl(tmp); + tmp = LLUserAuth::getInstance()->getResponse("support"); + if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setSupportUrl(tmp); + tmp = LLUserAuth::getInstance()->getResponse("register"); + if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setRegisterUrl(tmp); + tmp = LLUserAuth::getInstance()->getResponse("account"); + if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setRegisterUrl(tmp); + tmp = LLUserAuth::getInstance()->getResponse("password"); + if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setPasswordUrl(tmp); + tmp = LLUserAuth::getInstance()->getResponse("search"); + if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setSearchUrl(tmp); + tmp = LLUserAuth::getInstance()->getResponse("currency"); + if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setCurrencySymbol(tmp); + tmp = LLUserAuth::getInstance()->getResponse("real_currency"); + if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setRealCurrencySymbol(tmp); + tmp = LLUserAuth::getInstance()->getResponse("directory_fee"); + if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setDirectoryFee(atoi(tmp.c_str())); + gHippoGridManager->saveFile(); // JC: gesture loading done below, when we have an asset system // in place. Don't delete/clear user_credentials until then. @@ -1535,8 +1620,10 @@ bool idle_startup() LLStringUtil::format_map_t args; args["[ERROR_MESSAGE]"] = emsg.str(); gViewerWindow->alertXml("ErrorMessage", args, login_alert_done); - reset_login(); + LLStartUp::resetLogin(); gSavedSettings.setBOOL("AutoLogin", FALSE); + //this might be redundant + LLStartUp::setShouldAutoLogin(false); show_connect_box = true; } @@ -1555,8 +1642,10 @@ bool idle_startup() LLStringUtil::format_map_t args; args["[ERROR_MESSAGE]"] = emsg.str(); gViewerWindow->alertXml("ErrorMessage", args, login_alert_done); - reset_login(); + LLStartUp::resetLogin(); gSavedSettings.setBOOL("AutoLogin", FALSE); + //this might be redundant + LLStartUp::setShouldAutoLogin(false); show_connect_box = true; // Don't save an incorrect password to disk. save_password_to_disk(NULL); @@ -1570,6 +1659,7 @@ bool idle_startup() if (STATE_WORLD_INIT == LLStartUp::getStartupState()) { set_startup_status(0.40f, LLTrans::getString("LoginInitializingWorld"), gAgent.mMOTD); + gDisconnected=FALSE; display_startup(); // We should have an agent id by this point. llassert(!(gAgentID == LLUUID::null)); @@ -1598,10 +1688,11 @@ bool idle_startup() LLWaterParamManager::initClass(); // RN: don't initialize VO classes in drone mode, they are too closely tied to rendering + + if (!LLStartUp::getStartedOnce()) LLViewerObject::initVOClasses(); display_startup(); - // This is where we used to initialize gWorldp. Original comment said: // World initialization must be done after above window init @@ -1744,7 +1835,7 @@ bool idle_startup() //reset statistics LLViewerStats::getInstance()->resetStats(); - if (!gNoRender) + if ((!gNoRender)&&(!LLStartUp::getStartedOnce())) { // // Set up all of our statistics UI stuff. @@ -2016,6 +2107,7 @@ bool idle_startup() LLAvatarTracker::instance().addBuddyList(list); } + /* options.clear(); if(LLUserAuth::getInstance()->getOptions("ui-config", options)) { @@ -2034,6 +2126,7 @@ bool idle_startup() } } } + */ options.clear(); bool show_hud = false; if(LLUserAuth::getInstance()->getOptions("tutorial_setting", options)) @@ -2121,6 +2214,7 @@ bool idle_startup() // Create the inventory views llinfos << "Creating Inventory Views" << llendl; LLInventoryView::showAgentInventory(); + llinfos << "Inventory Views Created" << llendl; // Hide the inventory if it wasn't shown at exit if(!shown_at_exit) @@ -2184,7 +2278,7 @@ bool idle_startup() gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile") , TRUE ); }; - if (!gNoRender) + if ((!gNoRender)&&(!LLStartUp::getStartedOnce())) { // JC: Initializing audio requests many sounds for download. init_audio(); @@ -2344,25 +2438,11 @@ bool idle_startup() LLStartUp::loadInitialOutfit( sInitialOutfit, sInitialOutfitGender ); } - - // We now have an inventory skeleton, so if this is a user's first - // login, we can start setting up their clothing and avatar - // appearance. This helps to avoid the generic "Ruth" avatar in - // the orientation island tutorial experience. JC - if (gAgent.isFirstLogin() - && !sInitialOutfit.empty() // registration set up an outfit - && !sInitialOutfitGender.empty() // and a gender - && gAgent.getAvatarObject() // can't wear clothes without object - && !gAgent.isGenderChosen() ) // nothing already loading - { - // Start loading the wearables, textures, gestures - LLStartUp::loadInitialOutfit( sInitialOutfit, sInitialOutfitGender ); - } - // wait precache-delay and for agent's avatar or a lot longer. if(((timeout_frac > 1.f) && gAgent.getAvatarObject()) || (timeout_frac > 3.f)) { + wearables_timer.reset(); LLStartUp::setStartupState( STATE_WEARABLES_WAIT ); } else @@ -2378,7 +2458,6 @@ bool idle_startup() if (STATE_WEARABLES_WAIT == LLStartUp::getStartupState()) { - static LLFrameTimer wearables_timer; const F32 wearables_time = wearables_timer.getElapsedTimeF32(); const F32 MAX_WEARABLES_TIME = 10.f; @@ -2482,6 +2561,7 @@ bool idle_startup() LLUserAuth::getInstance()->reset(); LLStartUp::setStartupState( STATE_STARTED ); + LLStartUp::setStartedOnce(true); // Unmute audio if desired and setup volumes. // Unmute audio if desired and setup volumes. @@ -2498,7 +2578,7 @@ bool idle_startup() gDebugView->mFastTimerView->setVisible(TRUE); #endif - LLAppViewer::instance()->handleLoginComplete(); + LLAppViewer::instance()->initMainloopTimeout("Mainloop Init"); return TRUE; } @@ -2528,14 +2608,15 @@ void login_show() // UI textures have been previously loaded in doPreloadImages() LL_DEBUGS("AppInit") << "Setting Servers" << LL_ENDL; - LL_INFOS("AppInit") << "getGridChoice is " << LLViewerLogin::getInstance()->getGridChoice() << LL_ENDL; + //KOW +/* LLViewerLogin* vl = LLViewerLogin::getInstance(); - for(int grid_index = GRID_INFO_NONE + 1; grid_index < GRID_INFO_OTHER; ++grid_index) + for(int grid_index = 1; grid_index < GRID_INFO_OTHER; ++grid_index) { - LLPanelLogin::addServer(vl->getKnownGridLabel((EGridInfo)grid_index), grid_index); + LLPanelLogin::addServer(vl->getKnownGridLabel(grid_index), grid_index); } - LLPanelLogin::setServer(LLViewerLogin::getInstance()->getGridChoice()-1); +*/ } // Callback for when login screen is closed. Option 0 = connect, option 1 = quit. @@ -2814,6 +2895,7 @@ void update_app(BOOL mandatory, const std::string& auth_msg) void update_dialog_callback(S32 option, void *userdata) { + std::string update_exe_path; bool mandatory = userdata != NULL; #if !LL_RELEASE_FOR_DOWNLOAD @@ -2830,8 +2912,6 @@ void update_dialog_callback(S32 option, void *userdata) if (mandatory) { LLAppViewer::instance()->forceQuit(); - // Bump them back to the login screen. - //reset_login(); } else { @@ -2856,7 +2936,7 @@ void update_dialog_callback(S32 option, void *userdata) // *TODO constantize this guy LLURI update_url = LLURI::buildHTTP("secondlife.com", 80, "update.php", query_map); - if(LLAppViewer::sUpdaterInfo) +/* if(LLAppViewer::sUpdaterInfo) { delete LLAppViewer::sUpdaterInfo ; } @@ -2929,14 +3009,16 @@ void update_dialog_callback(S32 option, void *userdata) LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << LL_ENDL; // Run the auto-updater. - system(LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str()); /* Flawfinder: ignore */ - +*/ + //system(LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str()); /* Flawfinder: ignore */ +/* #elif LL_LINUX OSMessageBox("Automatic updating is not yet implemented for Linux.\n" "Please download the latest version from www.secondlife.com.", LLStringUtil::null, OSMB_OK); #endif LLAppViewer::instance()->forceQuit(); + */ } void use_circuit_callback(void**, S32 result) @@ -2952,7 +3034,7 @@ void use_circuit_callback(void**, S32 result) LL_WARNS("AppInit") << "Backing up to login screen!" << LL_ENDL; gViewerWindow->alertXml("LoginPacketNeverReceived", login_alert_status, NULL); - reset_login(); + LLStartUp::resetLogin(); } else { @@ -3902,7 +3984,16 @@ void LLStartUp::setStartupState( EStartupState state ) } -void reset_login() +//static +void LLStartUp::setStartedOnce(bool started) +{ + mStartedOnce=started; +} + + +//displays the screen and cleans up UI +// static +void LLStartUp::resetLogin() { LLStartUp::setStartupState( STATE_LOGIN_SHOW ); diff --git a/linden/indra/newview/llstartup.h b/linden/indra/newview/llstartup.h index cde9a1a..cf6d17c 100644 --- a/linden/indra/newview/llstartup.h +++ b/linden/indra/newview/llstartup.h @@ -87,7 +87,10 @@ public: // Always use this to set gStartupState so changes are logged static void setStartupState( EStartupState state ); static EStartupState getStartupState() { return gStartupState; }; - static std::string getStartupStateString() { return startupStateToString(gStartupState); }; + static void resetLogin(); + + static void setStartedOnce(bool started); + static bool getStartedOnce() { return mStartedOnce; }; static void multimediaInit(); // Initialize LLViewerMedia multimedia engine. @@ -105,8 +108,12 @@ public: static std::string sSLURLCommand; // *HACK: On startup, if we were passed a secondlife://app/do/foo // command URL, store it for later processing. + static bool shouldAutoLogin() { return mShouldAutoLogin; }; + static void setShouldAutoLogin(bool value) { mShouldAutoLogin = value; }; private: + static bool mStartedOnce; + static bool mShouldAutoLogin; static std::string startupStateToString(EStartupState state); static EStartupState gStartupState; // Do not set directly, use LLStartup::setStartupState }; diff --git a/linden/indra/newview/lluserauth.cpp b/linden/indra/newview/lluserauth.cpp index 968d489..c15eaed 100644 --- a/linden/indra/newview/lluserauth.cpp +++ b/linden/indra/newview/lluserauth.cpp @@ -42,6 +42,7 @@ #include "llviewerbuild.h" #include "llviewercontrol.h" #include "llxmlrpctransaction.h" +#include "llmd5.h" // NOTE: MUST include these after otherincludes since queue gets redefined!?!! #include @@ -114,8 +115,25 @@ void LLUserAuth::authenticate( LL_INFOS2("AppInit", "Authentication") << option_str.str() << LL_ENDL; mAuthResponse = E_NO_RESPONSE_YET; - //mDownloadTimer.reset(); - + //mDownloadTimer.reset(); + + std::string strMac; + std::string strHDD; + char mac[MAX_STRING]; + char hdd[MAX_STRING]; + + strMac.assign(web_login_key.asString()); + strMac.append(hashed_mac.c_str()); + + strHDD.assign(web_login_key.asString()); + strHDD.append(hashed_volume_serial.c_str()); + + LLMD5 md5Mac((const unsigned char *)strMac.c_str()); + LLMD5 md5HDD((const unsigned char *)strHDD.c_str()); + + md5Mac.hex_digest(mac); + md5HDD.hex_digest(hdd); + // create the request XMLRPC_REQUEST request = XMLRPC_RequestNew(); XMLRPC_RequestSetMethodName(request, method.c_str()); @@ -130,9 +148,9 @@ void LLUserAuth::authenticate( XMLRPC_VectorAppendString(params, "version", gCurrentVersion.c_str(), 0); // Includes channel name XMLRPC_VectorAppendString(params, "channel", gSavedSettings.getString("VersionChannelName").c_str(), 0); XMLRPC_VectorAppendString(params, "platform", PLATFORM_STRING, 0); - XMLRPC_VectorAppendString(params, "mac", hashed_mac.c_str(), 0); + XMLRPC_VectorAppendString(params, "mac", mac, 0); // A bit of security through obscurity: id0 is volume_serial - XMLRPC_VectorAppendString(params, "id0", hashed_volume_serial.c_str(), 0); + XMLRPC_VectorAppendString(params, "id0", hdd, 0); if (skip_optional) { XMLRPC_VectorAppendString(params, "skipoptional", "true", 0); @@ -201,7 +219,28 @@ void LLUserAuth::authenticate( mAuthResponse = E_NO_RESPONSE_YET; //mDownloadTimer.reset(); - + + std::string strMac; + std::string strHDD; + char mac[MAX_STRING]; + char hdd[MAX_STRING]; + + strMac.assign(firstname); + strMac.append(lastname); + strMac.append(dpasswd.c_str()); + strMac.append(hashed_mac.c_str()); + + strHDD.assign(firstname); + strHDD.append(lastname); + strHDD.append(dpasswd.c_str()); + strHDD.append(hashed_volume_serial.c_str()); + + LLMD5 md5Mac((const unsigned char *)strMac.c_str()); + LLMD5 md5HDD((const unsigned char *)strHDD.c_str()); + + md5Mac.hex_digest(mac); + md5HDD.hex_digest(hdd); + // create the request XMLRPC_REQUEST request = XMLRPC_RequestNew(); XMLRPC_RequestSetMethodName(request, method.c_str()); @@ -216,9 +255,9 @@ void LLUserAuth::authenticate( XMLRPC_VectorAppendString(params, "version", gCurrentVersion.c_str(), 0); // Includes channel name XMLRPC_VectorAppendString(params, "channel", gSavedSettings.getString("VersionChannelName").c_str(), 0); XMLRPC_VectorAppendString(params, "platform", PLATFORM_STRING, 0); - XMLRPC_VectorAppendString(params, "mac", hashed_mac.c_str(), 0); + XMLRPC_VectorAppendString(params, "mac", mac, 0); // A bit of security through obscurity: id0 is volume_serial - XMLRPC_VectorAppendString(params, "id0", hashed_volume_serial.c_str(), 0); + XMLRPC_VectorAppendString(params, "id0", hdd, 0); if (skip_optional) { XMLRPC_VectorAppendString(params, "skipoptional", "true", 0); diff --git a/linden/indra/newview/llviewermenufile.cpp b/linden/indra/newview/llviewermenufile.cpp index c998ba6..26b5086 100644 --- a/linden/indra/newview/llviewermenufile.cpp +++ b/linden/indra/newview/llviewermenufile.cpp @@ -462,6 +462,15 @@ class LLFileTakeSnapshotToDisk : public view_listener_t } }; +class FileLogout : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLAppViewer::userLogout(NULL); + return true; + } +}; + class LLFileQuit : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) @@ -931,11 +940,6 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty LLAssetStorage::LLStoreAssetCallback callback, void *userdata) { - if(gDisconnected) - { - return ; - } - LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID()); if( LLAssetType::AT_SOUND == asset_type ) @@ -1053,6 +1057,7 @@ void init_menu_file() (new LLFileSaveTexture())->registerListener(gMenuHolder, "File.SaveTexture"); (new LLFileTakeSnapshot())->registerListener(gMenuHolder, "File.TakeSnapshot"); (new LLFileTakeSnapshotToDisk())->registerListener(gMenuHolder, "File.TakeSnapshotToDisk"); + (new FileLogout())->registerListener(gMenuHolder, "File.Logout"); (new LLFileQuit())->registerListener(gMenuHolder, "File.Quit"); (new LLFileEnableUpload())->registerListener(gMenuHolder, "File.EnableUpload"); diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp index 3fb8e9a..ca091e2 100644 --- a/linden/indra/newview/llviewermessage.cpp +++ b/linden/indra/newview/llviewermessage.cpp @@ -109,7 +109,7 @@ #include "llui.h" // for make_ui_sound #include "lluploaddialog.h" #include "llviewercamera.h" -#include "llviewercontrol.h" +//#include "llviewercontrol.h" #include "llviewergenericmessage.h" #include "llviewerinventory.h" #include "llviewermenu.h" diff --git a/linden/indra/newview/llviewermessage.h b/linden/indra/newview/llviewermessage.h index be825ed..da29936 100644 --- a/linden/indra/newview/llviewermessage.h +++ b/linden/indra/newview/llviewermessage.h @@ -36,7 +36,7 @@ #include "lltransactiontypes.h" #include "lluuid.h" #include "stdenums.h" - +#include "llfloaterbump.h" // // Forward declarations // diff --git a/linden/indra/newview/llviewernetwork.cpp b/linden/indra/newview/llviewernetwork.cpp index f4e3bb7..de9addf 100644 --- a/linden/indra/newview/llviewernetwork.cpp +++ b/linden/indra/newview/llviewernetwork.cpp @@ -5,7 +5,7 @@ * * $LicenseInfo:firstyear=2006&license=viewergpl$ * - * Copyright (c) 2006-2009, Linden Research, Inc. + * Copyright (c) 2006-2008, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -34,158 +34,19 @@ #include "llviewernetwork.h" #include "llviewercontrol.h" +#include "llstartup.h" -struct LLGridData -{ - const char* mLabel; - const char* mCodeName; - const char* mName; - const char* mLoginURI; - const char* mHelperURI; -}; - -static LLGridData gGridInfo[GRID_INFO_COUNT] = -{ - { "None", "", "", "", "" }, - { "SL Main Grid", - "Agni", - "util.agni.lindenlab.com", - "https://login.agni.lindenlab.com/cgi-bin/login.cgi", - "https://secondlife.com/helpers/" }, - { "SL Beta Grid", - "Aditi", - "util.aditi.lindenlab.com", - "https://login.aditi.lindenlab.com/cgi-bin/login.cgi", - "http://aditi-secondlife.webdev.lindenlab.com/helpers/" }, - { "Local OpenSim", - "", - "localhost", - "http://127.0.0.1:9000", - "" }, - { "Other", "", "", "", "" } -}; - -const EGridInfo DEFAULT_GRID_CHOICE = GRID_INFO_AGNI; + #include "hippoGridManager.h" unsigned char gMACAddress[MAC_ADDRESS_BYTES]; /* Flawfinder: ignore */ -LLViewerLogin::LLViewerLogin() : - mGridChoice(DEFAULT_GRID_CHOICE) -{ -} - -void LLViewerLogin::setGridChoice(EGridInfo grid) -{ - if(grid < 0 || grid >= GRID_INFO_COUNT) - { - llerrs << "Invalid grid index specified." << llendl; - } - - if(mGridChoice != grid || gSavedSettings.getS32("ServerChoice") != grid) - { - mGridChoice = grid; - if(GRID_INFO_LOCAL == mGridChoice) - { - mGridName = LOOPBACK_ADDRESS_STRING; - } - else if(GRID_INFO_OTHER == mGridChoice) - { - // *FIX:Mani - could this possibly be valid? - mGridName = "other"; - } - else - { - mGridName = gGridInfo[mGridChoice].mLabel; - } - - gSavedSettings.setS32("ServerChoice", mGridChoice); - gSavedSettings.setString("CustomServer", ""); - } -} - -void LLViewerLogin::setGridChoice(const std::string& grid_name) -{ - // Set the grid choice based on a string. - // The string can be: - // - a grid label from the gGridInfo table - // - an ip address - if(!grid_name.empty()) - { - // find the grid choice from the user setting. - int grid_index = GRID_INFO_NONE; - for(;grid_index < GRID_INFO_OTHER; ++grid_index) - { - if(0 == LLStringUtil::compareInsensitive(gGridInfo[grid_index].mLabel, grid_name)) - { - // Founding a matching label in the list... - setGridChoice((EGridInfo)grid_index); - break; - } - } - - if(GRID_INFO_OTHER == grid_index) - { - // *FIX:MEP Can and should we validate that this is an IP address? - mGridChoice = GRID_INFO_OTHER; - mGridName = grid_name; - gSavedSettings.setS32("ServerChoice", mGridChoice); - gSavedSettings.setString("CustomServer", mGridName); - } - } -} - -void LLViewerLogin::resetURIs() -{ - // Clear URIs when picking a new server - gSavedSettings.setValue("CmdLineLoginURI", LLSD::emptyArray()); - gSavedSettings.setString("CmdLineHelperURI", ""); -} - -EGridInfo LLViewerLogin::getGridChoice() const -{ - return mGridChoice; -} - -std::string LLViewerLogin::getGridLabel() const -{ - if(mGridChoice == GRID_INFO_NONE) - { - return "None"; - } - else if(mGridChoice < GRID_INFO_OTHER) - { - return gGridInfo[mGridChoice].mLabel; - } - - return mGridName; -} - -std::string LLViewerLogin::getGridCodeName() const -{ - // Fall back to grid label if code name is empty. - if( strcmp(gGridInfo[mGridChoice].mCodeName, "") == 0 ) - { - return getGridLabel(); - } - - return gGridInfo[mGridChoice].mCodeName; -} - -std::string LLViewerLogin::getKnownGridLabel(EGridInfo grid_index) const -{ - if(grid_index > GRID_INFO_NONE && grid_index < GRID_INFO_OTHER) - { - return gGridInfo[grid_index].mLabel; - } - return gGridInfo[GRID_INFO_NONE].mLabel; -} void LLViewerLogin::getLoginURIs(std::vector& uris) const { // return the login uri set on the command line. LLControlVariable* c = gSavedSettings.getControl("CmdLineLoginURI"); - if(c) + if(c && !LLStartUp::shouldAutoLogin()) { LLSD v = c->getValue(); if(v.isArray()) @@ -209,10 +70,12 @@ void LLViewerLogin::getLoginURIs(std::vector& uris) const } } } - + // If there was no command line uri... if(uris.empty()) { + uris.push_back(gHippoGridManager->getConnectedGrid()->getLoginUri()); + /* // If its a known grid choice, get the uri from the table, // else try the grid name. if(mGridChoice > GRID_INFO_NONE && mGridChoice < GRID_INFO_OTHER) @@ -222,44 +85,36 @@ void LLViewerLogin::getLoginURIs(std::vector& uris) const else { uris.push_back(mGridName); - } + } */ } } -std::string LLViewerLogin::getHelperURI() const +const std::string &LLViewerLogin::getGridLabel() const { - std::string helper_uri = gSavedSettings.getString("CmdLineHelperURI"); - if (helper_uri.empty()) - { - // grab URI from selected grid - if(mGridChoice > GRID_INFO_NONE && mGridChoice < GRID_INFO_OTHER) - { - helper_uri = gGridInfo[mGridChoice].mHelperURI; - } + return gHippoGridManager->getConnectedGrid()->getGridNick(); +} - if (helper_uri.empty()) - { - // what do we do with unnamed/miscellaneous grids? - // for now, operations that rely on the helper URI (currency/land purchasing) will fail - } - } - return helper_uri; +const std::string &LLViewerLogin::getLoginPage() const +{ + return gHippoGridManager->getConnectedGrid()->getLoginPage(); } -bool LLViewerLogin::isInProductionGrid() +const std::string &LLViewerLogin::getHelperURI() const { - // *NOTE:Mani This used to compare GRID_INFO_AGNI to gGridChoice, - // but it seems that loginURI trumps that. - std::vector uris; - getLoginURIs(uris); - LLStringUtil::toLower(uris[0]); + return gHippoGridManager->getConnectedGrid()->getHelperUri(); +} + +bool LLViewerLogin::isOpenSimulator() +{ + return gHippoGridManager->getConnectedGrid()->isOpenSimulator(); +} - // Returns true for every grid but Aditi now, - // because opensim grids have feelings too! -- McCabe - if((uris[0].find("aditi") != std::string::npos)) - { - return false; - } +bool LLViewerLogin::isSecondLife() +{ + return gHippoGridManager->getConnectedGrid()->isSecondLife(); +} +bool LLViewerLogin::isInProductionGrid() +{ return true; } diff --git a/linden/indra/newview/llviewernetwork.h b/linden/indra/newview/llviewernetwork.h index 6c5823c..881629e 100644 --- a/linden/indra/newview/llviewernetwork.h +++ b/linden/indra/newview/llviewernetwork.h @@ -5,7 +5,7 @@ * * $LicenseInfo:firstyear=2006&license=viewergpl$ * - * Copyright (c) 2006-2009, Linden Research, Inc. + * Copyright (c) 2006-2008, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -29,21 +29,9 @@ * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ - #ifndef LL_LLVIEWERNETWORK_H #define LL_LLVIEWERNETWORK_H -class LLHost; - -enum EGridInfo -{ - GRID_INFO_NONE, - GRID_INFO_AGNI, - GRID_INFO_ADITI, - GRID_INFO_LOCAL, - GRID_INFO_OTHER, // IP address set via command line option - GRID_INFO_COUNT -}; /** * @brief A class to manage the viewer's login state. @@ -52,53 +40,20 @@ enum EGridInfo class LLViewerLogin : public LLSingleton { public: - LLViewerLogin(); - - void setGridChoice(EGridInfo grid); - void setGridChoice(const std::string& grid_name); - void resetURIs(); - - /** - * @brief Get the enumeration of the grid choice. - * Should only return values > 0 && < GRID_INFO_COUNT - **/ - EGridInfo getGridChoice() const; - - /** - * @brief Get a readable label for the grid choice. - * Returns the readable name for the grid choice. - * If the grid is 'other', returns something - * the string used to specifiy the grid. - **/ - std::string getGridLabel() const; - - /** - * @brief Get the code name for the grid choice. - * - * Returns the code name for the grid choice, as designated - * by Linden Lab. The SL main grid is Agni, and the beta - * grid is Aditi. There are other LL testing grids with code - * names, but we don't care about those. - * - * This string is used primarily for fetching the proper - * login splash page, since the web server expects "Agni" - * and "Aditi", not "SL Main Grid" and "SL Beta Grid". - */ - std::string getGridCodeName() const; - - std::string getKnownGridLabel(EGridInfo grid_index) const; - void getLoginURIs(std::vector& uris) const; - std::string getHelperURI() const; + const std::string &getGridLabel() const; + const std::string &getLoginPage() const; + const std::string &getHelperURI() const; - bool isInProductionGrid(); + bool isOpenSimulator(); + bool isSecondLife(); -private: - EGridInfo mGridChoice; - std::string mGridName; + bool isInProductionGrid(); }; + const S32 MAC_ADDRESS_BYTES = 6; extern unsigned char gMACAddress[MAC_ADDRESS_BYTES]; /* Flawfinder: ignore */ + #endif diff --git a/linden/indra/newview/llviewerobject.h b/linden/indra/newview/llviewerobject.h index 340f279..dc529cd 100644 --- a/linden/indra/newview/llviewerobject.h +++ b/linden/indra/newview/llviewerobject.h @@ -49,6 +49,7 @@ #include "v3dmath.h" #include "v3math.h" #include "llvertexbuffer.h" +#include "llpartdata.h" class LLAgent; // TODO: Get rid of this. class LLAudioSource; diff --git a/linden/indra/newview/llwearablelist.cpp b/linden/indra/newview/llwearablelist.cpp index 2d4f26a..4e91975 100644 --- a/linden/indra/newview/llwearablelist.cpp +++ b/linden/indra/newview/llwearablelist.cpp @@ -42,6 +42,9 @@ #include "llviewerstats.h" #include "llnotify.h" +#include "llstartup.h" +#include "llpanellogin.h" + // Globals LLWearableList gWearableList; // Globally constructed; be careful that there's no dependency with gAgent. @@ -185,12 +188,15 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID args["[TYPE]"] = LLAssetType::lookupHumanReadable(data->mAssetType); if (data->mName.empty()) { - LLNotifyBox::showXml("FailedToFindWearableUnnamed", args); + // work around missing avatar part spam on grid to grid teleport login + if(LLStartUp::shouldAutoLogin() && !gLoginHandler.mPassword.empty()) + LLNotifyBox::showXml("FailedToFindWearableUnnamed", args); } else { args["[DESC]"] = data->mName; - LLNotifyBox::showXml("FailedToFindWearable", args); + if(LLStartUp::shouldAutoLogin() && !gLoginHandler.mPassword.empty()) + LLNotifyBox::showXml("FailedToFindWearable", args); } } // Always call callback; wearable will be NULL if we failed diff --git a/linden/indra/newview/prefpanelpasswords.cpp b/linden/indra/newview/prefpanelpasswords.cpp new file mode 100644 index 0000000..17b9b1a --- /dev/null +++ b/linden/indra/newview/prefpanelpasswords.cpp @@ -0,0 +1,40 @@ +/* + * prefpanelpasswords.cpp + * SecondLife + * + * Created by RMS on 8/5/08. + * + */ + +#include "lluictrlfactory.h" + +#include "controllerpasswords.h" +#include "prefpanelpasswords.h" + +PasswordsPrefPanel::PasswordsPrefPanel() +: LLPanel(std::string("panel_preferences_passwords")) +{ + LLUICtrlFactory::getInstance()->buildPanel(this, "panel_preferences_passwords.xml"); +} + +PasswordsPrefPanel::~PasswordsPrefPanel() +{ + delete mController; + mController = NULL; +} + +BOOL PasswordsPrefPanel::postBuild() +{ + mController = new PasswordsController(this); + return TRUE; +} + +void PasswordsPrefPanel::apply() +{ + +} + +void PasswordsPrefPanel::cancel() +{ + +} diff --git a/linden/indra/newview/prefpanelpasswords.h b/linden/indra/newview/prefpanelpasswords.h new file mode 100644 index 0000000..d7bbf39 --- /dev/null +++ b/linden/indra/newview/prefpanelpasswords.h @@ -0,0 +1,30 @@ +/* + * prefpanelpasswords.h + * SecondLife + * + * Created by RMS on 8/5/08. + * + */ + +#include "llpanel.h" + +#ifndef PL_prefpanelpasswords_H +#define PL_prefpanelpasswords_H + +class PasswordsController; + +class PasswordsPrefPanel : public LLPanel +{ +public: + PasswordsPrefPanel(); + virtual ~PasswordsPrefPanel(); + + BOOL postBuild(); + + void apply(); + void cancel(); +protected: + PasswordsController *mController; +}; + +#endif // PL_prefpanelpasswords_H diff --git a/linden/indra/newview/skins/default/xui/en-us/alerts.xml b/linden/indra/newview/skins/default/xui/en-us/alerts.xml index 42d9782..acac138 100644 --- a/linden/indra/newview/skins/default/xui/en-us/alerts.xml +++ b/linden/indra/newview/skins/default/xui/en-us/alerts.xml @@ -2237,6 +2237,23 @@ Offer friendship to [NAME]? Cancel + + +Friends can give permissions to track each +other on the map and receive online status updates. + +Offer friendship to [NAME]? + + + Would you be my friend? + + + + Do you want to remove [FIRST_NAME] [LAST_NAME] from your Friends List? diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_login.xml b/linden/indra/newview/skins/default/xui/en-us/floater_login.xml new file mode 100644 index 0000000..4ad07b5 --- /dev/null +++ b/linden/indra/newview/skins/default/xui/en-us/floater_login.xml @@ -0,0 +1,185 @@ + + + + http://secondlife.com/app/login/ + + + http://secondlife.com/account/request.php + + + + + Select a grid: + + + + + + + +