DEV-45809 - Merge Second Life Enterprise changes into viewer 2.x trunk

Includes: DEV-45800, DEV-45803 - Grid Manager
DEV-45804 - SLURL refactor
DEV-45801 - Single username field (for Identity Evolution and SLE Ldap)
Also,
Includes Certificate Management code allowing the viewer to connect to
grids not signed by a well know key (just like any web browser).  Also
contains secure storage for things like passwords.
The security/certificate code is modular with the intention of adding modules
to directly use the operating system facilities for crypto if available.
(that's much more secure than we'll ever be)

Also, refactor of voice to modularize it, and add a diamondware voice module.
CR:  Aimee, James, Lynx, Mani, Karina and a list of thousands
master
Roxie Linden 2010-04-02 02:03:21 -07:00
commit 9523c70f9d
121 changed files with 16646 additions and 10016 deletions

View File

@ -231,7 +231,8 @@ static BOOL isDefault(const std::string& scheme, U16 port)
void LLURI::parseAuthorityAndPathUsingOpaque()
{
if (mScheme == "http" || mScheme == "https" ||
mScheme == "ftp" || mScheme == "secondlife" )
mScheme == "ftp" || mScheme == "secondlife" ||
mScheme == "x-grid-location-info")
{
if (mEscapedOpaque.substr(0,2) != "//")
{

View File

@ -33,9 +33,12 @@
// We can't use WIN32_LEAN_AND_MEAN here, needs lots of includes.
#if LL_WINDOWS
# undef WIN32_LEAN_AND_MEAN
# include <winsock2.h>
# include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <windows.h>
// ugh, this is ugly. We need to straighten out our linking for this library
#pragma comment(lib, "IPHLPAPI.lib")
#include <iphlpapi.h>
#endif
#include "lldefs.h"
@ -452,67 +455,102 @@ static void get_random_bytes(void *buf, int nbytes)
return;
}
#if LL_WINDOWS
typedef struct _ASTAT_
{
ADAPTER_STATUS adapt;
NAME_BUFFER NameBuff [30];
}ASTAT, * PASTAT;
#if LL_WINDOWS
// Code copied from http://msdn.microsoft.com/en-us/library/aa365939(VS.85).aspx
// This code grabs the first hardware address, rather than the first interface.
// Using a VPN can cause the first returned interface to be changed.
const S32 MAC_ADDRESS_BYTES=6;
// static
S32 LLUUID::getNodeID(unsigned char * node_id)
S32 LLUUID::getNodeID(unsigned char *node_id)
{
ASTAT Adapter;
NCB Ncb;
UCHAR uRetCode;
LANA_ENUM lenum;
int i;
int retval = 0;
memset( &Ncb, 0, sizeof(Ncb) );
Ncb.ncb_command = NCBENUM;
Ncb.ncb_buffer = (UCHAR *)&lenum;
Ncb.ncb_length = sizeof(lenum);
uRetCode = Netbios( &Ncb );
// printf( "The NCBENUM return code is: 0x%x \n", uRetCode );
// Declare and initialize variables.
DWORD dwSize = 0;
DWORD dwRetVal = 0;
int i;
for(i=0; i < lenum.length ;i++)
{
memset( &Ncb, 0, sizeof(Ncb) );
Ncb.ncb_command = NCBRESET;
Ncb.ncb_lana_num = lenum.lana[i];
/* variables used for GetIfTable and GetIfEntry */
MIB_IFTABLE *pIfTable;
MIB_IFROW *pIfRow;
uRetCode = Netbios( &Ncb );
// printf( "The NCBRESET on LANA %d return code is: 0x%x \n",
// lenum.lana[i], uRetCode );
// Allocate memory for our pointers.
pIfTable = (MIB_IFTABLE *) malloc(sizeof (MIB_IFTABLE));
if (pIfTable == NULL)
{
printf("Error allocating memory needed to call GetIfTable\n");
return 0;
}
memset( &Ncb, 0, sizeof (Ncb) );
Ncb.ncb_command = NCBASTAT;
Ncb.ncb_lana_num = lenum.lana[i];
// Before calling GetIfEntry, we call GetIfTable to make
// sure there are entries to get and retrieve the interface index.
strcpy( (char *)Ncb.ncb_callname, "* " ); /* Flawfinder: ignore */
Ncb.ncb_buffer = (unsigned char *)&Adapter;
Ncb.ncb_length = sizeof(Adapter);
// Make an initial call to GetIfTable to get the
// necessary size into dwSize
if (GetIfTable(pIfTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
free(pIfTable);
pIfTable = (MIB_IFTABLE *) malloc(dwSize);
if (pIfTable == NULL)
{
printf("Error allocating memory\n");
return 0;
}
}
// Make a second call to GetIfTable to get the actual
// data we want.
if ((dwRetVal = GetIfTable(pIfTable, &dwSize, 0)) == NO_ERROR)
{
if (pIfTable->dwNumEntries > 0)
{
pIfRow = (MIB_IFROW *) malloc(sizeof (MIB_IFROW));
if (pIfRow == NULL)
{
printf("Error allocating memory\n");
if (pIfTable != NULL)
{
free(pIfTable);
pIfTable = NULL;
}
return 0;
}
uRetCode = Netbios( &Ncb );
// printf( "The NCBASTAT on LANA %d return code is: 0x%x \n",
// lenum.lana[i], uRetCode );
if ( uRetCode == 0 )
{
// printf( "The Ethernet Number on LANA %d is: %02x%02x%02x%02x%02x%02x\n",
// lenum.lana[i],
// Adapter.adapt.adapter_address[0],
// Adapter.adapt.adapter_address[1],
// Adapter.adapt.adapter_address[2],
// Adapter.adapt.adapter_address[3],
// Adapter.adapt.adapter_address[4],
// Adapter.adapt.adapter_address[5] );
memcpy(node_id,Adapter.adapt.adapter_address,6); /* Flawfinder: ignore */
retval = 1;
int limit = MAC_ADDRESS_BYTES;
memcpy(node_id, "\0\0\0\0\0\0", limit); // zero out array of bytes
for (i = 0; i < (int) pIfTable->dwNumEntries; i++)
{
pIfRow->dwIndex = pIfTable->table[i].dwIndex;
if ((dwRetVal = GetIfEntry(pIfRow)) == NO_ERROR)
{
switch (pIfRow->dwType)
{
case IF_TYPE_ETHERNET_CSMACD:
case IF_TYPE_IEEE80211:
limit = min((int) pIfRow->dwPhysAddrLen, limit);
if (pIfRow->dwPhysAddrLen == 0)
break;
memcpy(node_id, (UCHAR *)&pIfRow->bPhysAddr[0], limit); // just incase the PhysAddr is not the expected MAC_Address size
free(pIfTable);
return 1; //return first hardware device found.
break;
}
}
return retval;
case IF_TYPE_OTHER:
case IF_TYPE_PPP:
case IF_TYPE_SOFTWARE_LOOPBACK:
case IF_TYPE_ISO88025_TOKENRING:
case IF_TYPE_IEEE1394:
case IF_TYPE_ATM:
case IF_TYPE_TUNNEL:
default:
break;
}
}
}
}
}
free(pIfTable);
return 0;
}
#elif LL_DARWIN

View File

@ -89,10 +89,6 @@ S32 gCurlMultiCount = 0;
std::vector<LLMutex*> LLCurl::sSSLMutex;
std::string LLCurl::sCAPath;
std::string LLCurl::sCAFile;
// Verify SSL certificates by default (matches libcurl default). The ability
// to alter this flag is only to allow us to suppress verification if it's
// broken for some reason.
bool LLCurl::sSSLVerify = true;
//static
void LLCurl::setCAPath(const std::string& path)
@ -106,18 +102,6 @@ void LLCurl::setCAFile(const std::string& file)
sCAFile = file;
}
//static
void LLCurl::setSSLVerify(bool verify)
{
sSSLVerify = verify;
}
//static
bool LLCurl::getSSLVerify()
{
return sSSLVerify;
}
//static
std::string LLCurl::getVersionString()
{
@ -481,8 +465,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,
setErrorBuffer();
setCA();
setopt(CURLOPT_SSL_VERIFYPEER, LLCurl::getSSLVerify());
setopt(CURLOPT_SSL_VERIFYHOST, LLCurl::getSSLVerify()? 2 : 0);
setopt(CURLOPT_SSL_VERIFYPEER, true);
setopt(CURLOPT_TIMEOUT, CURL_REQUEST_TIMEOUT);
setoptString(CURLOPT_URL, url);
@ -912,6 +895,15 @@ void LLCurlEasyRequest::setReadCallback(curl_read_callback callback, void* userd
}
}
void LLCurlEasyRequest::setSSLCtxCallback(curl_ssl_ctx_callback callback, void* userdata)
{
if (mEasy)
{
mEasy->setopt(CURLOPT_SSL_CTX_FUNCTION, (void*)callback);
mEasy->setopt(CURLOPT_SSL_CTX_DATA, userdata);
}
}
void LLCurlEasyRequest::slist_append(const char* str)
{
if (mEasy)
@ -1061,3 +1053,4 @@ void LLCurl::cleanupClass()
#endif
curl_global_cleanup();
}

View File

@ -157,16 +157,6 @@ public:
*/
static const std::string& getCAPath() { return sCAPath; }
/**
* @ brief Set flag controlling whether to verify HTTPS certs.
*/
static void setSSLVerify(bool verify);
/**
* @ brief Get flag controlling whether to verify HTTPS certs.
*/
static bool getSSLVerify();
/**
* @ brief Initialize LLCurl class
*/
@ -192,7 +182,6 @@ public:
private:
static std::string sCAPath;
static std::string sCAFile;
static bool sSSLVerify;
};
namespace boost
@ -240,6 +229,7 @@ public:
void setHeaderCallback(curl_header_callback callback, void* userdata);
void setWriteCallback(curl_write_callback callback, void* userdata);
void setReadCallback(curl_read_callback callback, void* userdata);
void setSSLCtxCallback(curl_ssl_ctx_callback callback, void* userdata);
void slist_append(const char* str);
void sendRequest(const std::string& url);
void requestComplete();

View File

@ -31,7 +31,7 @@
*/
#include "linden_common.h"
#include <openssl/x509_vfy.h>
#include "llhttpclient.h"
#include "llassetstorage.h"
@ -46,7 +46,10 @@
#include "message.h"
#include <curl/curl.h>
const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f;
LLURLRequest::SSLCertVerifyCallback LLHTTPClient::mCertVerifyCallback = NULL;
////////////////////////////////////////////////////////////////////////////
// Responder class moved to LLCurl
@ -206,13 +209,19 @@ namespace
LLPumpIO* theClientPump = NULL;
}
void LLHTTPClient::setCertVerifyCallback(LLURLRequest::SSLCertVerifyCallback callback)
{
LLHTTPClient::mCertVerifyCallback = callback;
}
static void request(
const std::string& url,
LLURLRequest::ERequestAction method,
Injector* body_injector,
LLCurl::ResponderPtr responder,
const F32 timeout = HTTP_REQUEST_EXPIRY_SECS,
const LLSD& headers = LLSD())
const LLSD& headers = LLSD()
)
{
if (!LLHTTPClient::hasPump())
{
@ -222,7 +231,7 @@ static void request(
LLPumpIO::chain_t chain;
LLURLRequest* req = new LLURLRequest(method, url);
req->checkRootCertificate(LLCurl::getSSLVerify());
req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req);
lldebugs << LLURLRequest::actionAsVerb(method) << " " << url << " "
@ -417,7 +426,6 @@ static LLSD blocking_request(
std::string body_str;
// other request method checks root cert first, we skip?
//req->checkRootCertificate(true);
// * Set curl handle options
curl_easy_setopt(curlp, CURLOPT_NOSIGNAL, 1); // don't use SIGALRM for timeouts

View File

@ -40,7 +40,8 @@
#include <string>
#include <boost/intrusive_ptr.hpp>
#include <openssl/x509_vfy.h>
#include "llurlrequest.h"
#include "llassettype.h"
#include "llcurl.h"
#include "lliopipe.h"
@ -61,6 +62,7 @@ public:
typedef LLCurl::Responder Responder;
typedef LLCurl::ResponderPtr ResponderPtr;
/** @name non-blocking API */
//@{
static void head(
@ -155,7 +157,12 @@ public:
static void setPump(LLPumpIO& pump);
///< must be called before any of the above calls are made
static bool hasPump();
///< for testing
static void setCertVerifyCallback(LLURLRequest::SSLCertVerifyCallback callback);
static LLURLRequest::SSLCertVerifyCallback getCertVerifyCallback() { return mCertVerifyCallback; }
protected:
static LLURLRequest::SSLCertVerifyCallback mCertVerifyCallback;
};
#endif // LL_LLHTTPCLIENT_H

View File

@ -36,7 +36,8 @@
#include "llurlrequest.h"
#include <algorithm>
#include <openssl/x509_vfy.h>
#include <openssl/ssl.h>
#include "llcurl.h"
#include "llioutil.h"
#include "llmemtype.h"
@ -56,6 +57,8 @@ const std::string CONTEXT_TRANSFERED_BYTES("transfered_bytes");
static size_t headerCallback(void* data, size_t size, size_t nmemb, void* user);
/**
* class LLURLRequestDetail
*/
@ -72,6 +75,7 @@ public:
U32 mBodyLimit;
S32 mByteAccumulator;
bool mIsBodyLimitSet;
LLURLRequest::SSLCertVerifyCallback mSSLVerifyCallback;
};
LLURLRequestDetail::LLURLRequestDetail() :
@ -80,7 +84,8 @@ LLURLRequestDetail::LLURLRequestDetail() :
mLastRead(NULL),
mBodyLimit(0),
mByteAccumulator(0),
mIsBodyLimitSet(false)
mIsBodyLimitSet(false),
mSSLVerifyCallback(NULL)
{
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
mCurlRequest = new LLCurlEasyRequest();
@ -94,6 +99,36 @@ LLURLRequestDetail::~LLURLRequestDetail()
mLastRead = NULL;
}
void LLURLRequest::setSSLVerifyCallback(SSLCertVerifyCallback callback, void *param)
{
mDetail->mSSLVerifyCallback = callback;
mDetail->mCurlRequest->setSSLCtxCallback(LLURLRequest::_sslCtxCallback, (void *)this);
mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, true);
mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYHOST, 2);
}
// _sslCtxFunction
// Callback function called when an SSL Context is created via CURL
// used to configure the context for custom cert validation
CURLcode LLURLRequest::_sslCtxCallback(CURL * curl, void *sslctx, void *param)
{
LLURLRequest *req = (LLURLRequest *)param;
if(req == NULL || req->mDetail->mSSLVerifyCallback == NULL)
{
SSL_CTX_set_cert_verify_callback((SSL_CTX *)sslctx, NULL, NULL);
return CURLE_OK;
}
SSL_CTX * ctx = (SSL_CTX *) sslctx;
// disable any default verification for server certs
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
// set the verification callback.
SSL_CTX_set_cert_verify_callback(ctx, req->mDetail->mSSLVerifyCallback, (void *)req);
// the calls are void
return CURLE_OK;
}
/**
* class LLURLRequest
@ -148,6 +183,11 @@ void LLURLRequest::setURL(const std::string& url)
mDetail->mURL = url;
}
std::string LLURLRequest::getURL() const
{
return mDetail->mURL;
}
void LLURLRequest::addHeader(const char* header)
{
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
@ -160,13 +200,6 @@ void LLURLRequest::setBodyLimit(U32 size)
mDetail->mIsBodyLimitSet = true;
}
void LLURLRequest::checkRootCertificate(bool check)
{
mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, (check? TRUE : FALSE));
mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYHOST, (check? 2 : 0));
mDetail->mCurlRequest->setoptString(CURLOPT_ENCODING, "");
}
void LLURLRequest::setCallback(LLURLRequestComplete* callback)
{
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);

View File

@ -44,6 +44,8 @@
#include "lliopipe.h"
#include "llchainio.h"
#include "llerror.h"
#include <openssl/x509_vfy.h>
#include "llcurl.h"
extern const std::string CONTEXT_REQUEST;
@ -72,6 +74,8 @@ class LLURLRequest : public LLIOPipe
{
LOG_CLASS(LLURLRequest);
public:
typedef int (* SSLCertVerifyCallback)(X509_STORE_CTX *ctx, void *param);
/**
* @brief This enumeration is for specifying the type of request.
*/
@ -125,7 +129,7 @@ public:
*
*/
void setURL(const std::string& url);
std::string getURL() const;
/**
* @brief Add a header to the http post.
*
@ -143,8 +147,9 @@ public:
* Set whether request will check that remote server
* certificates are signed by a known root CA when using HTTPS.
*/
void checkRootCertificate(bool check);
void setSSLVerifyCallback(SSLCertVerifyCallback callback, void * param);
/**
* @brief Return at most size bytes of body.
*
@ -189,6 +194,7 @@ public:
* @brief Give this pipe a chance to handle a generated error
*/
virtual EStatus handleError(EStatus status, LLPumpIO* pump);
protected:
/**
@ -217,6 +223,8 @@ protected:
S32 mRequestTransferedBytes;
S32 mResponseTransferedBytes;
static CURLcode _sslCtxCallback(CURL * curl, void *sslctx, void *param);
private:
/**
* @brief Initialize the object. Called during construction.
@ -364,62 +372,6 @@ protected:
};
/**
* @class LLURLRequestClientFactory
* @brief Template class to build url request based client chains
*
* This class eases construction of a basic sd rpc client. Here is an
* example of it's use:
* <code>
* class LLUsefulService : public LLService { ... }<br>
* LLService::registerCreator(<br>
* "useful",<br>
* LLService::creator_t(new LLURLRequestClientFactory<LLUsefulService>))<br>
* </code>
*
* This class should work, but I never got around to using/testing it.
*
*/
#if 0
template<class Client>
class LLURLRequestClientFactory : public LLChainIOFactory
{
public:
LLURLRequestClientFactory(LLURLRequest::ERequestAction action) {}
LLURLRequestClientFactory(
LLURLRequest::ERequestAction action,
const std::string& fixed_url) :
mAction(action),
mURL(fixed_url)
{
}
virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
{
lldebugs << "LLURLRequestClientFactory::build" << llendl;
LLIOPipe::ptr_t service(new Client);
chain.push_back(service);
LLURLRequest* http(new LLURLRequest(mAction));
LLIOPipe::ptr_t http_pipe(http);
// *FIX: how do we know the content type?
//http->addHeader("Content-Type: text/llsd");
if(mURL.empty())
{
chain.push_back(LLIOPipe::ptr_t(new LLContextURLExtractor(http)));
}
else
{
http->setURL(mURL);
}
chain.push_back(http_pipe);
chain.push_back(service);
return true;
}
protected:
LLURLRequest::ERequestAction mAction;
std::string mURL;
};
#endif
/**
* External constants

View File

@ -41,6 +41,9 @@
#include "lltrans.h"
#include "lluicolortable.h"
#define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))"
LLUrlEntryBase::LLUrlEntryBase() :
mColor(LLUIColorTable::instance().getColor("HTMLLinkColor")),
mDisabledLink(false)
@ -303,10 +306,11 @@ std::string LLUrlEntrySLURL::getLocation(const std::string &url) const
//
// LLUrlEntryAgent Describes a Second Life agent Url, e.g.,
// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
//
LLUrlEntryAgent::LLUrlEntryAgent()
{
mPattern = boost::regex("secondlife:///app/agent/[\\da-f-]+/\\w+",
mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/\\w+",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_agent.xml";
mIcon = "Generic_Person";
@ -418,10 +422,11 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa
// LLUrlEntryGroup Describes a Second Life group Url, e.g.,
// secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about
// secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/inspect
// x-grid-location-info://lincoln.lindenlab.com/app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/inspect
//
LLUrlEntryGroup::LLUrlEntryGroup()
{
mPattern = boost::regex("secondlife:///app/group/[\\da-f-]+/\\w+",
mPattern = boost::regex(APP_HEADER_REGEX "/group/[\\da-f-]+/\\w+",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_group.xml";
mIcon = "Generic_Group";
@ -482,7 +487,8 @@ LLUrlEntryInventory::LLUrlEntryInventory()
//*TODO: add supporting of inventory item names with whitespaces
//this pattern cann't parse for example
//secondlife:///app/inventory/0e346d8b-4433-4d66-a6b0-fd37083abc4c/select?name=name with spaces&param2=value
mPattern = boost::regex("secondlife:///app/inventory/[\\da-f-]+/\\w+\\S*",
//x-grid-location-info://lincoln.lindenlab.com/app/inventory/0e346d8b-4433-4d66-a6b0-fd37083abc4c/select?name=name with spaces&param2=value
mPattern = boost::regex(APP_HEADER_REGEX "/inventory/[\\da-f-]+/\\w+\\S*",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_inventory.xml";
}
@ -496,10 +502,11 @@ std::string LLUrlEntryInventory::getLabel(const std::string &url, const LLUrlLab
///
/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
/// x-grid-location-info://lincoln.lindenlab.com/app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
///
LLUrlEntryParcel::LLUrlEntryParcel()
{
mPattern = boost::regex("secondlife:///app/parcel/[\\da-f-]+/about",
mPattern = boost::regex(APP_HEADER_REGEX "/parcel/[\\da-f-]+/about",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_parcel.xml";
mTooltip = LLTrans::getString("TooltipParcelUrl");
@ -515,7 +522,7 @@ std::string LLUrlEntryParcel::getLabel(const std::string &url, const LLUrlLabelC
//
LLUrlEntryPlace::LLUrlEntryPlace()
{
mPattern = boost::regex("secondlife://\\S+/?(\\d+/\\d+/\\d+|\\d+/\\d+)/?",
mPattern = boost::regex("((x-grid-location-info://[-\\w\\.]+/region/)|(secondlife://))\\S+/?(\\d+/\\d+/\\d+|\\d+/\\d+)/?",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_slurl.xml";
mTooltip = LLTrans::getString("TooltipSLURL");
@ -560,10 +567,11 @@ std::string LLUrlEntryPlace::getLocation(const std::string &url) const
//
// LLUrlEntryTeleport Describes a Second Life teleport Url, e.g.,
// secondlife:///app/teleport/Ahern/50/50/50/
// x-grid-location-info://lincoln.lindenlab.com/app/teleport/Ahern/50/50/50/
//
LLUrlEntryTeleport::LLUrlEntryTeleport()
{
mPattern = boost::regex("secondlife:///app/teleport/\\S+(/\\d+)?(/\\d+)?(/\\d+)?/?\\S*",
mPattern = boost::regex(APP_HEADER_REGEX "/teleport/\\S+(/\\d+)?(/\\d+)?(/\\d+)?/?\\S*",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_teleport.xml";
mTooltip = LLTrans::getString("TooltipTeleportUrl");
@ -581,7 +589,12 @@ std::string LLUrlEntryTeleport::getLabel(const std::string &url, const LLUrlLabe
LLURI uri(url);
LLSD path_array = uri.pathArray();
S32 path_parts = path_array.size();
const std::string label = LLTrans::getString("SLurlLabelTeleport");
std::string host = uri.hostName();
std::string label = LLTrans::getString("SLurlLabelTeleport");
if (!host.empty())
{
label += " " + host;
}
if (path_parts == 6)
{
// handle teleport url with (X,Y,Z) coordinates
@ -680,7 +693,7 @@ std::string LLUrlEntrySLLabel::getTooltip(const std::string &string) const
//
LLUrlEntryWorldMap::LLUrlEntryWorldMap()
{
mPattern = boost::regex("secondlife:///app/worldmap/\\S+/?(\\d+)?/?(\\d+)?/?(\\d+)?/?\\S*",
mPattern = boost::regex(APP_HEADER_REGEX "/worldmap/\\S+/?(\\d+)?/?(\\d+)?/?(\\d+)?/?\\S*",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_map.xml";
mTooltip = LLTrans::getString("TooltipMapUrl");

View File

@ -286,6 +286,13 @@ namespace tut
"XXX secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar",
"secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar");
testRegex("Standalone Agent Url ", url,
"x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about",
"x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
testRegex("Standalone Agent Url Multicase with Text", url,
"M x-grid-location-info://lincoln.lindenlab.com/app/AGENT/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about M",
"x-grid-location-info://lincoln.lindenlab.com/app/AGENT/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
}
template<> template<>
@ -315,6 +322,15 @@ namespace tut
testRegex("Group Url multicase", url,
"XXX secondlife:///APP/Group/00005FF3-4044-c79f-9de8-fb28ae0df991/About XXX",
"secondlife:///APP/Group/00005FF3-4044-c79f-9de8-fb28ae0df991/About");
testRegex("Standalone Group Url ", url,
"x-grid-location-info://lincoln.lindenlab.com/app/group/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about",
"x-grid-location-info://lincoln.lindenlab.com/app/group/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
testRegex("Standalone Group Url Multicase ith Text", url,
"M x-grid-location-info://lincoln.lindenlab.com/app/GROUP/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about M",
"x-grid-location-info://lincoln.lindenlab.com/app/GROUP/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
}
template<> template<>
@ -361,7 +377,11 @@ namespace tut
// DEV-35459: SLURLs and teleport Links not parsed properly
testRegex("SLURL with quote", url,
"XXX secondlife://A'ksha%20Oasis/41/166/701 XXX",
"secondlife://A%27ksha%20Oasis/41/166/701");
"secondlife://A%27ksha%20Oasis/41/166/701");
testRegex("Standalone All Hands (50,50) [2] with text", url,
"XXX x-grid-location-info://lincoln.lindenlab.com/region/All%20Hands/50/50/50 XXX",
"x-grid-location-info://lincoln.lindenlab.com/region/All%20Hands/50/50/50");
}
template<> template<>
@ -461,6 +481,10 @@ namespace tut
testRegex("Teleport url with quote", url,
"XXX secondlife:///app/teleport/A'ksha%20Oasis/41/166/701 XXX",
"secondlife:///app/teleport/A%27ksha%20Oasis/41/166/701");
testRegex("Standalone All Hands", url,
"XXX x-grid-location-info://lincoln.lindenlab.com/app/teleport/All%20Hands/50/50/50 XXX",
"x-grid-location-info://lincoln.lindenlab.com/app/teleport/All%20Hands/50/50/50");
}
template<> template<>

View File

@ -459,7 +459,6 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd
}
//llinfos << "*** EXPANDED FILENAME: <" << expanded_filename << ">" << llendl;
return expanded_filename;
}
@ -565,27 +564,23 @@ std::string LLDir::getForbiddenFileChars()
return "\\/:*?\"<>|";
}
void LLDir::setLindenUserDir(const std::string &first, const std::string &last)
void LLDir::setLindenUserDir(const std::string &username)
{
// if both first and last aren't set, that's bad.
if (!first.empty() && !last.empty())
// if the username isn't set, that's bad
if (!username.empty())
{
// some platforms have case-sensitive filesystems, so be
// utterly consistent with our firstname/lastname case.
std::string firstlower(first);
LLStringUtil::toLower(firstlower);
std::string lastlower(last);
LLStringUtil::toLower(lastlower);
std::string userlower(username);
LLStringUtil::toLower(userlower);
LLStringUtil::replaceChar(userlower, ' ', '_');
mLindenUserDir = getOSUserAppDir();
mLindenUserDir += mDirDelimiter;
mLindenUserDir += firstlower;
mLindenUserDir += "_";
mLindenUserDir += lastlower;
llinfos << "Got name for LLDir::setLindenUserDir(first='" << first << "', last='" << last << "')" << llendl;
mLindenUserDir += userlower;
}
else
{
llerrs << "Invalid name for LLDir::setLindenUserDir(first='" << first << "', last='" << last << "')" << llendl;
llerrs << "NULL name for LLDir::setLindenUserDir" << llendl;
}
dumpCurrentDirectories();
@ -603,27 +598,25 @@ void LLDir::setChatLogsDir(const std::string &path)
}
}
void LLDir::setPerAccountChatLogsDir(const std::string &first, const std::string &last)
void LLDir::setPerAccountChatLogsDir(const std::string &username)
{
// if both first and last aren't set, assume we're grabbing the cached dir
if (!first.empty() && !last.empty())
if (!username.empty())
{
// some platforms have case-sensitive filesystems, so be
// utterly consistent with our firstname/lastname case.
std::string firstlower(first);
LLStringUtil::toLower(firstlower);
std::string lastlower(last);
LLStringUtil::toLower(lastlower);
std::string userlower(username);
LLStringUtil::toLower(userlower);
LLStringUtil::replaceChar(userlower, ' ', '_');
mPerAccountChatLogsDir = getChatLogsDir();
mPerAccountChatLogsDir += mDirDelimiter;
mPerAccountChatLogsDir += firstlower;
mPerAccountChatLogsDir += "_";
mPerAccountChatLogsDir += lastlower;
mPerAccountChatLogsDir += userlower;
}
else
{
llwarns << "Invalid name for LLDir::setPerAccountChatLogsDir" << llendl;
llerrs << "NULL name for LLDir::setPerAccountChatLogsDir" << llendl;
}
}
void LLDir::setSkinFolder(const std::string &skin_folder)

View File

@ -137,8 +137,8 @@ class LLDir
static std::string getForbiddenFileChars();
virtual void setChatLogsDir(const std::string &path); // Set the chat logs dir to this user's dir
virtual void setPerAccountChatLogsDir(const std::string &first, const std::string &last); // Set the per user chat log directory.
virtual void setLindenUserDir(const std::string &first, const std::string &last); // Set the linden user dir to this user's dir
virtual void setPerAccountChatLogsDir(const std::string &username); // Set the per user chat log directory.
virtual void setLindenUserDir(const std::string &username); // Set the linden user dir to this user's dir
virtual void setSkinFolder(const std::string &skin_folder);
virtual bool setCacheDir(const std::string &path);

View File

@ -7,6 +7,7 @@ include(Boost)
include(BuildVersion)
include(DBusGlib)
include(DirectX)
include(OpenSSL)
include(DragDrop)
include(ELFIO)
include(FMOD)
@ -371,6 +372,8 @@ set(viewer_SOURCE_FILES
llscrollingpanelparam.cpp
llsearchcombobox.cpp
llsearchhistory.cpp
llsecapi.cpp
llsechandler_basic.cpp
llselectmgr.cpp
llsidepanelappearance.cpp
llsidepanelinventory.cpp
@ -445,7 +448,6 @@ set(viewer_SOURCE_FILES
llurldispatcherlistener.cpp
llurlhistory.cpp
llurllineeditorctrl.cpp
llurlsimstring.cpp
llurlwhitelist.cpp
llvectorperfoptions.cpp
llversioninfo.cpp
@ -512,7 +514,9 @@ set(viewer_SOURCE_FILES
llvoground.cpp
llvoicechannel.cpp
llvoiceclient.cpp
llvoicedw.cpp
llvoicevisualizer.cpp
llvoicevivox.cpp
llvoinventorylistener.cpp
llvopartgroup.cpp
llvosky.cpp
@ -872,6 +876,8 @@ set(viewer_HEADER_FILES
llscrollingpanelparam.h
llsearchcombobox.h
llsearchhistory.h
llsecapi.h
llsechandler_basic.h
llselectmgr.h
llsidepanelappearance.h
llsidepanelinventory.h
@ -948,7 +954,6 @@ set(viewer_HEADER_FILES
llurldispatcherlistener.h
llurlhistory.h
llurllineeditorctrl.h
llurlsimstring.h
llurlwhitelist.h
llvectorperfoptions.h
llversioninfo.h
@ -1012,7 +1017,9 @@ set(viewer_HEADER_FILES
llvoground.h
llvoicechannel.h
llvoiceclient.h
llvoicedw.h
llvoicevisualizer.h
llvoicevivox.h
llvoinventorylistener.h
llvopartgroup.h
llvosky.h
@ -1403,8 +1410,8 @@ if (WINDOWS)
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libtcmalloc_minimal.dll
${SHARED_LIB_STAGING_DIR}/Debug/libtcmalloc_minimal-debug.dll
)
endif(USE_GOOGLE_PERFTOOLS)
endif(USE_GOOGLE_PERFTOOLS)
set(COPY_INPUT_DEPENDECIES
# The following commented dependencies are determined at variably at build time. Can't do this here.
@ -1621,6 +1628,8 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${WINDOWS_LIBRARIES}
${XMLRPCEPI_LIBRARIES}
${ELFIO_LIBRARIES}
${OPENSSL_LIBRARIES}
${CRYPTO_LIBRARIES}
${LLLOGIN_LIBRARIES}
${GOOGLE_PERFTOOLS_LIBRARIES}
)
@ -1797,6 +1806,43 @@ if (LL_TESTS)
"${CMAKE_SOURCE_DIR}/llmessage/tests/test_llsdmessage_peer.py"
)
set(test_libs
${LLMESSAGE_LIBRARIES}
${WINDOWS_LIBRARIES}
${LLVFS_LIBRARIES}
${LLMATH_LIBRARIES}
${LLCOMMON_LIBRARIES}
${GOOGLEMOCK_LIBRARIES}
${OPENSSL_LIBRARIES}
${CRYPTO_LIBRARIES}
)
LL_ADD_INTEGRATION_TEST(llsechandler_basic
llsechandler_basic.cpp
"${test_libs}"
)
LL_ADD_INTEGRATION_TEST(llsecapi
llsecapi.cpp
"${test_libs}"
)
set(llslurl_test_sources
llslurl.cpp
llviewernetwork.cpp
)
LL_ADD_INTEGRATION_TEST(llslurl
"${llslurl_test_sources}"
"${test_libs}"
)
LL_ADD_INTEGRATION_TEST(llviewernetwork
llviewernetwork.cpp
"${test_libs}"
)
#ADD_VIEWER_BUILD_TEST(llmemoryview viewer)
#ADD_VIEWER_BUILD_TEST(llagentaccess viewer)
#ADD_VIEWER_BUILD_TEST(llworldmap viewer)
@ -1804,6 +1850,7 @@ if (LL_TESTS)
#ADD_VIEWER_BUILD_TEST(lltextureinfo viewer)
#ADD_VIEWER_BUILD_TEST(lltextureinfodetails viewer)
#ADD_VIEWER_BUILD_TEST(lltexturestatsuploader viewer)
endif (LL_TESTS)

View File

@ -18,6 +18,33 @@
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>slurl</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>seconlife</string>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/x-grid-location-info</string>
</array>
<key>CFBundleTypeName</key>
<string>Secondlife SLURL</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>SLRL</string>
</array>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSTypeIsPackage</key>
<true/>
<key>NSDocumentClass</key>
<string>SecondLifeSLURL</string>
</dict>
</array>
<key>CFBundleURLTypes</key>
<array>
<dict>
@ -26,6 +53,7 @@
<key>CFBundleURLSchemes</key>
<array>
<string>secondlife</string>
<string>x-grid-location-info</string>
</array>
<key>LSIsAppleDefaultForScheme</key>
<true/>

View File

@ -1264,6 +1264,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>CertStore</key>
<map>
<key>Comment</key>
<string>Specifies the Certificate Store for certificate trust verification</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>default</string>
</map>
<key>ChatBarStealsFocus</key>
<map>
<key>Comment</key>
@ -1640,6 +1651,17 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>CurrentGrid</key>
<map>
<key>Comment</key>
<string>Currently Selected Grid</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string></string>
</map>
<key>CustomServer</key>
<map>
<key>Comment</key>
@ -2366,6 +2388,29 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>DefaultFemaleAvatar</key>
<map>
<key>Comment</key>
<string>Default Female Avatar</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>Female Shape &amp; Outfit</string>
</map>
<key>DefaultMaleAvatar</key>
<map>
<key>Comment</key>
<string>Default Male Avatar</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>Male Shape &amp; Outfit</string>
</map>
<key>DefaultObjectTexture</key>
<map>
<key>Comment</key>
@ -3442,7 +3487,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
<integer>1</integer>
</map>
<key>ForceMandatoryUpdate</key>
<map>
@ -7696,6 +7741,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>SecondLifeEnterprise</key>
<map>
<key>Comment</key>
<string>Enables Second Life Enterprise features</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>SelectMovableOnly</key>
<map>
<key>Comment</key>
@ -8500,7 +8556,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
<integer>1</integer>
</map>
<key>ShowTangentBasis</key>
<map>
@ -10393,6 +10449,17 @@
<key>Value</key>
<string></string>
</map>
<key>VivoxDebugSIPURIHostName</key>
<map>
<key>Comment</key>
<string>Hostname portion of vivox SIP URIs (empty string for the default).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string></string>
</map>
<key>VivoxDebugVoiceAccountServerURI</key>
<map>
<key>Comment</key>
@ -10404,6 +10471,28 @@
<key>Value</key>
<string></string>
</map>
<key>VivoxVoiceHost</key>
<map>
<key>Comment</key>
<string>Client SLVoice host to connect to</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>127.0.0.1</string>
</map>
<key>VivoxVoicePort</key>
<map>
<key>Comment</key>
<string>Client SLVoice port to connect to</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>44125</integer>
</map>
<key>VoiceCallsFriendsOnly</key>
<map>
<key>Comment</key>
@ -10536,6 +10625,17 @@
<key>Value</key>
<string>Default</string>
</map>
<key>VoiceLogFile</key>
<map>
<key>Comment</key>
<string>Log file to use when launching the voice daemon</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string></string>
</map>
<key>VoiceOutputAudioDevice</key>
<map>
<key>Comment</key>
@ -10580,6 +10680,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>VoiceServerType</key>
<map>
<key>Comment</key>
<string>The type of voice server to connect to.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>vivox</string>
</map>
<key>WLSkyDetail</key>
<map>
<key>Comment</key>

View File

@ -797,6 +797,12 @@ WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}\DefaultIcon" "" '"$INSTDIR\$INSTEXE"'
;; URL param must be last item passed to viewer, it ignores subsequent params
;; to avoid parameter injection attacks.
WriteRegExpandStr HKEY_CLASSES_ROOT "${URLNAME}\shell\open\command" "" '"$INSTDIR\$INSTEXE" $INSTFLAGS -url "%1"'
WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info"(default)" "URL:Second Life"
WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info" "URL Protocol" ""
WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info\DefaultIcon" "" '"$INSTDIR\$INSTEXE"'
;; URL param must be last item passed to viewer, it ignores subsequent params
;; to avoid parameter injection attacks.
WriteRegExpandStr HKEY_CLASSES_ROOT "x-grid-location-info\shell\open\command" "" '"$INSTDIR\$INSTEXE" $INSTFLAGS -url "%1"'
; write out uninstaller
WriteUninstaller "$INSTDIR\uninst.exe"

View File

@ -3231,7 +3231,7 @@ bool LLAgent::teleportCore(bool is_local)
// MBW -- Let the voice client know a teleport has begun so it can leave the existing channel.
// This was breaking the case of teleporting within a single sim. Backing it out for now.
// gVoiceClient->leaveChannel();
// LLVoiceClient::getInstance()->leaveChannel();
return true;
}
@ -3375,7 +3375,7 @@ void LLAgent::setTeleportState(ETeleportState state)
if (mTeleportState == TELEPORT_MOVING)
{
// We're outa here. Save "back" slurl.
mTeleportSourceSLURL = LLAgentUI::buildSLURL();
LLAgentUI::buildSLURL(mTeleportSourceSLURL);
}
else if(mTeleportState == TELEPORT_ARRIVING)
{

View File

@ -42,6 +42,7 @@
#include "llpointer.h"
#include "lluicolor.h"
#include "llvoavatardefines.h"
#include "llslurl.h"
extern const BOOL ANIMATE;
extern const U8 AGENT_STATE_TYPING; // Typing indication
@ -514,13 +515,13 @@ public:
public:
static void parseTeleportMessages(const std::string& xml_filename);
const std::string getTeleportSourceSLURL() const { return mTeleportSourceSLURL; }
const void getTeleportSourceSLURL(LLSLURL& slurl) const { slurl = mTeleportSourceSLURL; }
public:
// ! TODO ! Define ERROR and PROGRESS enums here instead of exposing the mappings.
static std::map<std::string, std::string> sTeleportErrorMessages;
static std::map<std::string, std::string> sTeleportProgressMessages;
private:
std::string mTeleportSourceSLURL; // SLURL where last TP began
LLSLURL mTeleportSourceSLURL; // SLURL where last TP began
//--------------------------------------------------------------------
// Teleport Actions

View File

@ -53,7 +53,10 @@ void LLAgentListener::requestTeleport(LLSD const & event_data) const
}
else
{
std::string url = LLSLURL::buildSLURL(event_data["regionname"], event_data["x"], event_data["y"], event_data["z"]);
std::string url = LLSLURL(event_data["regionname"],
LLVector3(event_data["x"].asReal(),
event_data["y"].asReal(),
event_data["z"].asReal())).getSLURLString();
LLURLDispatcher::dispatch(url, NULL, false);
}
}

View File

@ -76,16 +76,15 @@ void LLAgentUI::buildFullname(std::string& name)
}
//static
std::string LLAgentUI::buildSLURL(const bool escaped /*= true*/)
void LLAgentUI::buildSLURL(LLSLURL& slurl, const bool escaped /*= true*/)
{
std::string slurl;
LLViewerRegion *regionp = gAgent.getRegion();
if (regionp)
{
LLVector3d agentPos = gAgent.getPositionGlobal();
slurl = LLSLURL::buildSLURLfromPosGlobal(regionp->getName(), agentPos, escaped);
}
return slurl;
LLSLURL return_slurl;
LLViewerRegion *regionp = gAgent.getRegion();
if (regionp)
{
return_slurl = LLSLURL(regionp->getName(), gAgent.getPositionGlobal());
}
slurl = return_slurl;
}
//static

View File

@ -33,6 +33,8 @@
#ifndef LLAGENTUI_H
#define LLAGENTUI_H
class LLSLURL;
class LLAgentUI
{
public:
@ -48,7 +50,7 @@ public:
static void buildName(std::string& name);
static void buildFullname(std::string &name);
static std::string buildSLURL(const bool escaped = true);
static void buildSLURL(LLSLURL& slurl, const bool escaped = true);
//build location string using the current position of gAgent.
static BOOL buildLocationString(std::string& str, ELocationFormat fmt = LOCATION_FORMAT_LANDMARK);
//build location string using a region position of the avatar.

View File

@ -153,7 +153,7 @@
#include "llworld.h"
#include "llhudeffecttrail.h"
#include "llvectorperfoptions.h"
#include "llurlsimstring.h"
#include "llslurl.h"
#include "llwatchdog.h"
// Included so that constants/settings might be initialized
@ -193,6 +193,9 @@
#include "llparcel.h"
#include "llavatariconctrl.h"
// Include for security api initialization
#include "llsecapi.h"
// *FIX: These extern globals should be cleaned up.
// The globals either represent state/config/resource-storage of either
// this app, or another 'component' of the viewer. App globals should be
@ -507,35 +510,6 @@ public:
}
};
void LLAppViewer::initGridChoice()
{
// Load up the initial grid choice from:
// - hard coded defaults...
// - command line settings...
// - if dev build, persisted settings...
// Set the "grid choice", this is specified by command line.
std::string grid_choice = gSavedSettings.getString("CmdLineGridChoice");
LLViewerLogin::getInstance()->setGridChoice(grid_choice);
// Load last server choice by default
// ignored if the command line grid choice has been set
if(grid_choice.empty())
{
S32 server = gSavedSettings.getS32("ServerChoice");
server = llclamp(server, 0, (S32)GRID_INFO_COUNT - 1);
if(server == GRID_INFO_OTHER)
{
std::string custom_server = gSavedSettings.getString("CustomServer");
LLViewerLogin::getInstance()->setGridChoice(custom_server);
}
else if(server != (S32)GRID_INFO_NONE)
{
LLViewerLogin::getInstance()->setGridChoice((EGridInfo)server);
}
}
}
//virtual
bool LLAppViewer::initSLURLHandler()
{
@ -647,7 +621,6 @@ bool LLAppViewer::init()
LLCurl::initClass();
initThreads();
writeSystemInfo();
// Build a string representing the current version number.
@ -777,10 +750,6 @@ bool LLAppViewer::init()
return false;
}
// Always fetch the Ethernet MAC address, needed both for login
// and password load.
LLUUID::getNodeID(gMACAddress);
// Prepare for out-of-memory situations, during which we will crash on
// purpose and save a dump.
#if LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP
@ -892,6 +861,7 @@ bool LLAppViewer::init()
}
}
// save the graphics card
gDebugInfo["GraphicsCard"] = LLFeatureManager::getInstance()->getGPUString();
@ -902,6 +872,17 @@ bool LLAppViewer::init()
gSimFrames = (F32)gFrameCount;
LLViewerJoystick::getInstance()->init(false);
try {
initializeSecHandler();
}
catch (LLProtectedDataException ex)
{
LLNotificationsUtil::add("CorruptedProtectedDataStore");
}
LLHTTPClient::setCertVerifyCallback(secapiSSLCertVerifyCallback);
gGLActive = FALSE;
if (gSavedSettings.getBOOL("QAMode") && gSavedSettings.getS32("QAModeEventHostPort") > 0)
{
@ -936,13 +917,11 @@ bool LLAppViewer::mainLoop()
gServicePump = new LLPumpIO(gAPRPoolp);
LLHTTPClient::setPump(*gServicePump);
LLCurl::setCAFile(gDirUtilp->getCAFile());
LLCurl::setSSLVerify(! gSavedSettings.getBOOL("NoVerifySSLCert"));
// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
LLVoiceChannel::initClass();
LLVoiceClient::init(gServicePump);
LLVoiceClient::getInstance()->init(gServicePump);
LLTimer frameTimer,idleTimer;
LLTimer debugTime;
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
@ -1273,7 +1252,7 @@ bool LLAppViewer::cleanup()
// to ensure shutdown order
LLMortician::setZealous(TRUE);
LLVoiceClient::terminate();
LLVoiceClient::getInstance()->terminate();
disconnectViewer();
@ -1472,13 +1451,6 @@ bool LLAppViewer::cleanup()
llinfos << "Saving Data" << llendflush;
// Quitting with "Remember Password" turned off should always stomp your
// saved password, whether or not you successfully logged in. JC
if (!gSavedSettings.getBOOL("RememberPassword"))
{
LLStartUp::deletePasswordFromDisk();
}
// Store the time of our current logoff
gSavedPerAccountSettings.setU32("LastLogoff", time_corrected());
@ -2047,7 +2019,6 @@ bool LLAppViewer::initConfiguration()
}
}
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"))
@ -2141,30 +2112,17 @@ bool LLAppViewer::initConfiguration()
// injection and steal passwords. Phoenix. SL-55321
if(clp.hasOption("url"))
{
std::string slurl = clp.getOption("url")[0];
if (LLSLURL::isSLURLCommand(slurl))
{
LLStartUp::sSLURLCommand = slurl;
}
else
{
LLURLSimString::setString(slurl);
}
LLStartUp::setStartSLURL(LLSLURL(clp.getOption("url")[0]));
if(LLStartUp::getStartSLURL().getType() == LLSLURL::LOCATION)
{
LLGridManager::getInstance()->setGridChoice(LLStartUp::getStartSLURL().getGrid());
}
}
else if(clp.hasOption("slurl"))
{
std::string slurl = clp.getOption("slurl")[0];
if(LLSLURL::isSLURL(slurl))
{
if (LLSLURL::isSLURLCommand(slurl))
{
LLStartUp::sSLURLCommand = slurl;
}
else
{
LLURLSimString::setString(slurl);
}
}
LLSLURL start_slurl(clp.getOption("slurl")[0]);
LLStartUp::setStartSLURL(start_slurl);
}
const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
@ -2245,18 +2203,10 @@ bool LLAppViewer::initConfiguration()
// don't call anotherInstanceRunning() when doing URL handoff, as
// it relies on checking a marker file which will not work when running
// out of different directories
std::string slurl;
if (!LLStartUp::sSLURLCommand.empty())
if (LLStartUp::getStartSLURL().isValid())
{
slurl = LLStartUp::sSLURLCommand;
}
else if (LLURLSimString::parse())
{
slurl = LLURLSimString::getURL();
}
if (!slurl.empty())
{
if (sendURLToOtherInstance(slurl))
if (sendURLToOtherInstance(LLStartUp::getStartSLURL().getSLURLString()))
{
// successfully handed off URL to existing instance, exit
return false;
@ -2312,9 +2262,9 @@ bool LLAppViewer::initConfiguration()
// need to do this here - need to have initialized global settings first
std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" );
if ( nextLoginLocation.length() )
if ( !nextLoginLocation.empty() )
{
LLURLSimString::setString( nextLoginLocation );
LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation));
};
gLastRunVersion = gSavedSettings.getString("LastRunVersion");
@ -2535,7 +2485,7 @@ void LLAppViewer::writeSystemInfo()
// The user is not logged on yet, but record the current grid choice login url
// which may have been the intended grid. This can b
gDebugInfo["GridName"] = LLViewerLogin::getInstance()->getGridLabel();
gDebugInfo["GridName"] = LLGridManager::getInstance()->getGridLabel();
// *FIX:Mani - move this ddown in llappviewerwin32
#ifdef LL_WINDOWS
@ -3886,7 +3836,7 @@ void LLAppViewer::sendLogoutRequest()
gLogoutMaxTime = LOGOUT_REQUEST_TIME;
mLogoutRequestSent = TRUE;
gVoiceClient->leaveChannel();
LLVoiceClient::getInstance()->leaveChannel();
//Set internal status variables and marker files
gLogoutInProgress = TRUE;
@ -4306,7 +4256,7 @@ void LLAppViewer::launchUpdater()
#endif
// *TODO change userserver to be grid on both viewer and sim, since
// userserver no longer exists.
query_map["userserver"] = LLViewerLogin::getInstance()->getGridLabel();
query_map["userserver"] = LLGridManager::getInstance()->getGridLabel();
query_map["channel"] = gSavedSettings.getString("VersionChannelName");
// *TODO constantize this guy
// *NOTE: This URL is also used in win_setup/lldownloader.cpp
@ -4319,10 +4269,10 @@ void LLAppViewer::launchUpdater()
LLAppViewer::sUpdaterInfo = new LLAppViewer::LLUpdaterInfo() ;
// if a sim name was passed in via command line parameter (typically through a SLURL)
if ( LLURLSimString::sInstance.mSimString.length() )
if ( LLStartUp::getStartSLURL().getType() == LLSLURL::LOCATION )
{
// record the location to start at next time
gSavedSettings.setString( "NextLoginLocation", LLURLSimString::sInstance.mSimString );
gSavedSettings.setString( "NextLoginLocation", LLStartUp::getStartSLURL().getSLURLString());
};
#if LL_WINDOWS

View File

@ -191,7 +191,6 @@ private:
bool initThreads(); // Initialize viewer threads, return false on failure.
bool initConfiguration(); // Initialize settings from the command line/config file.
void initGridChoice();
bool initCache(); // Initialize local client cache.

View File

@ -604,7 +604,7 @@ void LLAppViewerLinux::handleCrashReporting(bool reportFreeze)
{cmd.c_str(),
ask_dialog,
"-user",
(char*)LLViewerLogin::getInstance()->getGridLabel().c_str(),
(char*)LLGridManager::getInstance()->getGridLabel().c_str(),
"-name",
LLAppViewer::instance()->getSecondLifeTitle().c_str(),
NULL};

View File

@ -44,7 +44,6 @@
#include "llviewernetwork.h"
#include "llviewercontrol.h"
#include "llmd5.h"
#include "llurlsimstring.h"
#include "llfloaterworldmap.h"
#include "llurldispatcher.h"
#include <Carbon/Carbon.h>

View File

@ -282,7 +282,7 @@ bool LLAvatarActions::isCalling(const LLUUID &id)
//static
bool LLAvatarActions::canCall()
{
return LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking();
return LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();
}
// static

View File

@ -319,7 +319,7 @@ void LLBottomTray::onChange(EStatusType status, const std::string &channelURI, b
// skipped to avoid button blinking
if (status != STATUS_JOINING && status!= STATUS_LEFT_CHANNEL)
{
mSpeakBtn->setFlyoutBtnEnabled(LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking());
mSpeakBtn->setFlyoutBtnEnabled(LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking());
}
}
@ -489,7 +489,7 @@ BOOL LLBottomTray::postBuild()
mSpeakBtn->setShowToolTip( getString("VoiceControlBtnToolTip") );
// Registering Chat Bar to receive Voice client status change notifications.
gVoiceClient->addObserver(this);
LLVoiceClient::getInstance()->addObserver(this);
mObjectDefaultWidthMap[RS_BUTTON_GESTURES] = mGesturePanel->getRect().getWidth();
mObjectDefaultWidthMap[RS_BUTTON_MOVEMENT] = mMovementPanel->getRect().getWidth();

View File

@ -133,9 +133,9 @@ LLCallFloater::~LLCallFloater()
// Don't use LLVoiceClient::getInstance() here
// singleton MAY have already been destroyed.
if(gVoiceClient)
if(LLVoiceClient::getInstance())
{
gVoiceClient->removeObserver(this);
LLVoiceClient::getInstance()->removeObserver(this);
}
LLTransientFloaterMgr::getInstance()->removeControlView(this);
}
@ -191,7 +191,7 @@ void LLCallFloater::draw()
// Seems this is a problem somewhere in Voice Client (LLVoiceClient::participantAddedEvent)
// onChange();
bool is_moderator_muted = gVoiceClient->getIsModeratorMuted(gAgentID);
bool is_moderator_muted = LLVoiceClient::getInstance()->getIsModeratorMuted(gAgentID);
if (mIsModeratorMutedVoice != is_moderator_muted)
{
@ -209,7 +209,6 @@ void LLCallFloater::draw()
void LLCallFloater::onChange()
{
if (NULL == mParticipants) return;
updateParticipantsVoiceState();
// Add newly joined participants.
@ -239,11 +238,11 @@ void LLCallFloater::updateSession()
LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel();
if (voice_channel)
{
lldebugs << "Current voice channel: " << voice_channel->getSessionID() << llendl;
LL_DEBUGS("Voice") << "Current voice channel: " << voice_channel->getSessionID() << LL_ENDL;
if (mSpeakerManager && voice_channel->getSessionID() == mSpeakerManager->getSessionID())
{
lldebugs << "Speaker manager is already set for session: " << voice_channel->getSessionID() << llendl;
LL_DEBUGS("Voice") << "Speaker manager is already set for session: " << voice_channel->getSessionID() << LL_ENDL;
return;
}
else
@ -253,7 +252,6 @@ void LLCallFloater::updateSession()
}
const LLUUID& session_id = voice_channel ? voice_channel->getSessionID() : LLUUID::null;
lldebugs << "Set speaker manager for session: " << session_id << llendl;
LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id);
if (im_session)
@ -293,7 +291,7 @@ void LLCallFloater::updateSession()
{
// by default let show nearby chat participants
mSpeakerManager = LLLocalSpeakerMgr::getInstance();
lldebugs << "Set DEFAULT speaker manager" << llendl;
LL_DEBUGS("Voice") << "Set DEFAULT speaker manager" << LL_ENDL;
mVoiceType = VC_LOCAL_CHAT;
}
@ -472,16 +470,15 @@ void LLCallFloater::updateAgentModeratorState()
static void get_voice_participants_uuids(uuid_vec_t& speakers_uuids)
{
// Get a list of participants from VoiceClient
LLVoiceClient::participantMap *voice_map = gVoiceClient->getParticipantList();
if (voice_map)
std::set<LLUUID> participants;
LLVoiceClient::getInstance()->getParticipantList(participants);
for (std::set<LLUUID>::const_iterator iter = participants.begin();
iter != participants.end(); ++iter)
{
for (LLVoiceClient::participantMap::const_iterator iter = voice_map->begin();
iter != voice_map->end(); ++iter)
{
LLUUID id = (*iter).second->mAvatarID;
speakers_uuids.push_back(id);
}
speakers_uuids.push_back(*iter);
}
}
void LLCallFloater::initParticipantsVoiceState()
@ -557,7 +554,7 @@ void LLCallFloater::updateParticipantsVoiceState()
uuid_vec_t::iterator speakers_iter = std::find(speakers_uuids.begin(), speakers_uuids.end(), participant_id);
lldebugs << "processing speaker: " << item->getAvatarName() << ", " << item->getAvatarId() << llendl;
LL_DEBUGS("Voice") << "processing speaker: " << item->getAvatarName() << ", " << item->getAvatarId() << LL_ENDL;
// If an avatarID assigned to a panel is found in a speakers list
// obtained from VoiceClient we assign the JOINED status to the owner
@ -727,7 +724,7 @@ void LLCallFloater::connectToChannel(LLVoiceChannel* channel)
void LLCallFloater::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
{
// check is voice operational and if it doesn't work hide VCP (EXT-4397)
if(LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking())
if(LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking())
{
updateState(new_state);
}

View File

@ -700,6 +700,7 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
args["FIRST"] = first;
args["LAST"] = last;
}
}
}
else

View File

@ -640,20 +640,19 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
if ( chat.mSourceType == CHAT_SOURCE_OBJECT && chat.mFromID.notNull())
{
// for object IMs, create a secondlife:///app/objectim SLapp
std::string url = LLSLURL::buildCommand("objectim", chat.mFromID, "");
std::string url = LLSLURL("objectim", chat.mFromID, "").getSLURLString();
url += "?name=" + chat.mFromName;
url += "&owner=" + args["owner_id"].asString();
std::string slurl = args["slurl"].asString();
if (slurl.empty())
{
LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosAgent(chat.mPosAgent);
if (region)
{
S32 x, y, z;
LLSLURL::globalPosToXYZ(LLVector3d(chat.mPosAgent), x, y, z);
slurl = region->getName() + llformat("/%d/%d/%d", x, y, z);
}
LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosAgent(chat.mPosAgent);
if(region)
{
LLSLURL region_slurl(region->getName(), chat.mPosAgent);
slurl = region_slurl.getLocationString();
}
}
url += "&slurl=" + slurl;

View File

@ -284,7 +284,7 @@ void LLCurrencyUIManager::Impl::startTransaction(TransactionType type,
static std::string transactionURI;
if (transactionURI.empty())
{
transactionURI = LLViewerLogin::getInstance()->getHelperURI() + "currency.php";
transactionURI = LLGridManager::getInstance()->getHelperURI() + "currency.php";
}
delete mTransaction;

View File

@ -266,8 +266,18 @@ LLSD LLFloaterAbout::getInfo()
info["J2C_VERSION"] = LLImageJ2C::getEngineInfo();
bool want_fullname = true;
info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : LLSD();
info["VIVOX_VERSION"] = gVoiceClient ? gVoiceClient->getAPIVersion() : LLTrans::getString("NotConnected");
if(LLVoiceClient::getInstance()->voiceEnabled())
{
LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion();
std::ostringstream version_string;
version_string << version.serverType << " " << version.serverVersion << std::endl;
info["VOICE_VERSION"] = version_string.str();
}
else
{
info["VOICE_VERSION"] = LLTrans::getString("NotConnected");
}
// TODO: Implement media plugin version query
info["QT_WEBKIT_VERSION"] = "4.6 (version number hard-coded)";

View File

@ -830,7 +830,7 @@ void LLFloaterBuyLandUI::updateNames()
else
{
mParcelSellerName =
LLSLURL::buildCommand("agent", parcelp->getOwnerID(), "inspect");
LLSLURL("agent", parcelp->getOwnerID(), "inspect").getSLURLString();
}
}
@ -859,7 +859,7 @@ void LLFloaterBuyLandUI::startTransaction(TransactionType type, const LLXMLRPCVa
static std::string transaction_uri;
if (transaction_uri.empty())
{
transaction_uri = LLViewerLogin::getInstance()->getHelperURI() + "landtool.php";
transaction_uri = LLGridManager::getInstance()->getHelperURI() + "landtool.php";
}
const char* method;

View File

@ -166,7 +166,7 @@ void add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4&
if (chat.mSourceType == CHAT_SOURCE_AGENT &&
chat.mFromID != LLUUID::null)
{
chat.mURL = LLSLURL::buildCommand("agent", chat.mFromID, "inspect");
chat.mURL = LLSLURL("agent", chat.mFromID, "inspect").getSLURLString();
}
// If the chat line has an associated url, link it up to the name.

View File

@ -318,7 +318,7 @@ LLFloaterChatterBox* LLFloaterChatterBox::getInstance()
//static
LLFloater* LLFloaterChatterBox::getCurrentVoiceFloater()
{
if (!LLVoiceClient::voiceEnabled())
if (!LLVoiceClient::getInstance()->voiceEnabled())
{
return NULL;
}

View File

@ -193,7 +193,7 @@ void LLFloaterEvent::processEventInfoReply(LLMessageSystem *msg, void **)
floater->mTBCategory->setText(floater->mEventInfo.mCategoryStr);
floater->mTBDate->setText(floater->mEventInfo.mTimeStr);
floater->mTBDesc->setText(floater->mEventInfo.mDesc);
floater->mTBRunBy->setText(LLSLURL::buildCommand("agent", floater->mEventInfo.mRunByID, "inspect"));
floater->mTBRunBy->setText(LLSLURL("agent", floater->mEventInfo.mRunByID, "inspect").getSLURLString());
floater->mTBDuration->setText(llformat("%d:%.2d", floater->mEventInfo.mDuration / 60, floater->mEventInfo.mDuration % 60));

View File

@ -42,7 +42,6 @@
#include "llnotificationsutil.h"
#include "llparcel.h"
#include "message.h"
#include "lluserauth.h"
#include "llagent.h"
#include "llbutton.h"
@ -804,7 +803,7 @@ void LLPanelLandGeneral::refreshNames()
else
{
// Figure out the owner's name
owner = LLSLURL::buildCommand("agent", parcel->getOwnerID(), "inspect");
owner = LLSLURL("agent", parcel->getOwnerID(), "inspect").getSLURLString();
}
if(LLParcel::OS_LEASE_PENDING == parcel->getOwnershipStatus())
@ -816,7 +815,7 @@ void LLPanelLandGeneral::refreshNames()
std::string group;
if (!parcel->getGroupID().isNull())
{
group = LLSLURL::buildCommand("group", parcel->getGroupID(), "inspect");
group = LLSLURL("group", parcel->getGroupID(), "inspect").getSLURLString();
}
mTextGroup->setText(group);
@ -825,9 +824,9 @@ void LLPanelLandGeneral::refreshNames()
const LLUUID& auth_buyer_id = parcel->getAuthorizedBuyerID();
if(auth_buyer_id.notNull())
{
std::string name;
name = LLSLURL::buildCommand("agent", auth_buyer_id, "inspect");
mSaleInfoForSale2->setTextArg("[BUYER]", name);
std::string name;
name = LLSLURL("agent", auth_buyer_id, "inspect").getSLURLString();
mSaleInfoForSale2->setTextArg("[BUYER]", name);
}
else
{

View File

@ -595,7 +595,7 @@ void LLFloaterPreference::onBtnOK()
llinfos << "Can't close preferences!" << llendl;
}
LLPanelLogin::refreshLocation( false );
LLPanelLogin::updateLocationCombo( false );
}
// static
@ -612,7 +612,7 @@ void LLFloaterPreference::onBtnApply( )
apply();
saveSettings();
LLPanelLogin::refreshLocation( false );
LLPanelLogin::updateLocationCombo( false );
}
// static

View File

@ -2922,8 +2922,7 @@ bool LLDispatchEstateUpdateInfo::operator()(
LLUUID owner_id(strings[1]);
regionp->setOwner(owner_id);
// Update estate owner name in UI
std::string owner_name =
LLSLURL::buildCommand("agent", owner_id, "inspect");
std::string owner_name = LLSLURL("agent", owner_id, "inspect").getSLURLString();
panel->setOwnerName(owner_name);
U32 estate_id = strtoul(strings[2].c_str(), NULL, 10);

View File

@ -126,7 +126,9 @@ void LLFloaterReporter::processRegionInfo(LLMessageSystem* msg)
// virtual
BOOL LLFloaterReporter::postBuild()
{
childSetText("abuse_location_edit", LLAgentUI::buildSLURL());
LLSLURL slurl;
LLAgentUI::buildSLURL(slurl);
childSetText("abuse_location_edit", slurl.getSLURLString());
enableControls(TRUE);
@ -280,7 +282,6 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id)
{
object_owner.append("Unknown");
}
setFromAvatar(mObjectID, object_owner);
}
else
@ -325,7 +326,8 @@ void LLFloaterReporter::setFromAvatar(const LLUUID& avatar_id, const std::string
mAbuserID = mObjectID = avatar_id;
mOwnerName = avatar_name;
std::string avatar_link = LLSLURL::buildCommand("agent", mObjectID, "inspect");
std::string avatar_link =
LLSLURL("agent", mObjectID, "inspect").getSLURLString();
childSetText("owner_name", avatar_link);
childSetText("object_name", avatar_name);
childSetText("abuser_name_edit", avatar_name);
@ -504,7 +506,7 @@ void LLFloaterReporter::setPickedObjectProperties(const std::string& object_name
{
childSetText("object_name", object_name);
std::string owner_link =
LLSLURL::buildCommand("agent", owner_id, "inspect");
LLSLURL("agent", owner_id, "inspect").getSLURLString();
childSetText("owner_name", owner_link);
childSetText("abuser_name_edit", owner_name);
mAbuserID = owner_id;
@ -566,7 +568,7 @@ LLSD LLFloaterReporter::gatherReport()
mCopyrightWarningSeen = FALSE;
std::ostringstream summary;
if (!LLViewerLogin::getInstance()->isInProductionGrid())
if (!LLGridManager::getInstance()->isInProductionGrid())
{
summary << "Preview ";
}

View File

@ -1123,7 +1123,7 @@ void LLSnapshotLivePreview::saveWeb(std::string url)
void LLSnapshotLivePreview::regionNameCallback(std::string url, LLSD body, const std::string& name, S32 x, S32 y, S32 z)
{
body["slurl"] = LLSLURL::buildSLURL(name, x, y, z);
body["slurl"] = LLSLURL(name, LLVector3d(x, y, z)).getSLURLString();
LLHTTPClient::post(url, body,
new LLSendWebResponder());

View File

@ -64,9 +64,6 @@ LLPanelVoiceDeviceSettings::LLPanelVoiceDeviceSettings()
// grab "live" mic volume level
mMicVolume = gSavedSettings.getF32("AudioLevelMic");
// ask for new device enumeration
// now do this in onOpen() instead...
//gVoiceClient->refreshDeviceLists();
}
LLPanelVoiceDeviceSettings::~LLPanelVoiceDeviceSettings()
@ -105,7 +102,7 @@ void LLPanelVoiceDeviceSettings::draw()
refresh();
// let user know that volume indicator is not yet available
bool is_in_tuning_mode = gVoiceClient->inTuningMode();
bool is_in_tuning_mode = LLVoiceClient::getInstance()->inTuningMode();
childSetVisible("wait_text", !is_in_tuning_mode);
LLPanel::draw();
@ -113,7 +110,7 @@ void LLPanelVoiceDeviceSettings::draw()
if (is_in_tuning_mode)
{
const S32 num_bars = 5;
F32 voice_power = gVoiceClient->tuningGetEnergy() / LLVoiceClient::OVERDRIVEN_POWER_LEVEL;
F32 voice_power = LLVoiceClient::getInstance()->tuningGetEnergy() / LLVoiceClient::OVERDRIVEN_POWER_LEVEL;
S32 discrete_power = llmin(num_bars, llfloor(voice_power * (F32)num_bars + 0.1f));
for(S32 power_bar_idx = 0; power_bar_idx < num_bars; power_bar_idx++)
@ -194,13 +191,13 @@ void LLPanelVoiceDeviceSettings::refresh()
LLSlider* volume_slider = getChild<LLSlider>("mic_volume_slider");
// set mic volume tuning slider based on last mic volume setting
F32 current_volume = (F32)volume_slider->getValue().asReal();
gVoiceClient->tuningSetMicVolume(current_volume);
LLVoiceClient::getInstance()->tuningSetMicVolume(current_volume);
// Fill in popup menus
mCtrlInputDevices = getChild<LLComboBox>("voice_input_device");
mCtrlOutputDevices = getChild<LLComboBox>("voice_output_device");
if(!gVoiceClient->deviceSettingsAvailable())
if(!LLVoiceClient::getInstance()->deviceSettingsAvailable())
{
// The combo boxes are disabled, since we can't get the device settings from the daemon just now.
// Put the currently set default (ONLY) in the box, and select it.
@ -219,17 +216,16 @@ void LLPanelVoiceDeviceSettings::refresh()
}
else if (!mDevicesUpdated)
{
LLVoiceClient::deviceList *devices;
LLVoiceClient::deviceList::iterator iter;
LLVoiceDeviceList::const_iterator iter;
if(mCtrlInputDevices)
{
mCtrlInputDevices->removeall();
mCtrlInputDevices->add( getString("default_text"), ADD_BOTTOM );
devices = gVoiceClient->getCaptureDevices();
for(iter=devices->begin(); iter != devices->end(); iter++)
for(iter=LLVoiceClient::getInstance()->getCaptureDevices().begin();
iter != LLVoiceClient::getInstance()->getCaptureDevices().end();
iter++)
{
mCtrlInputDevices->add( *iter, ADD_BOTTOM );
}
@ -245,8 +241,8 @@ void LLPanelVoiceDeviceSettings::refresh()
mCtrlOutputDevices->removeall();
mCtrlOutputDevices->add( getString("default_text"), ADD_BOTTOM );
devices = gVoiceClient->getRenderDevices();
for(iter=devices->begin(); iter != devices->end(); iter++)
for(iter= LLVoiceClient::getInstance()->getRenderDevices().begin();
iter != LLVoiceClient::getInstance()->getRenderDevices().end(); iter++)
{
mCtrlOutputDevices->add( *iter, ADD_BOTTOM );
}
@ -268,37 +264,34 @@ void LLPanelVoiceDeviceSettings::initialize()
mDevicesUpdated = FALSE;
// ask for new device enumeration
gVoiceClient->refreshDeviceLists();
LLVoiceClient::getInstance()->refreshDeviceLists();
// put voice client in "tuning" mode
gVoiceClient->tuningStart();
LLVoiceClient::getInstance()->tuningStart();
LLVoiceChannel::suspend();
}
void LLPanelVoiceDeviceSettings::cleanup()
{
if (gVoiceClient)
{
gVoiceClient->tuningStop();
}
LLVoiceClient::getInstance()->tuningStop();
LLVoiceChannel::resume();
}
// static
void LLPanelVoiceDeviceSettings::onCommitInputDevice(LLUICtrl* ctrl, void* user_data)
{
if(gVoiceClient)
if(LLVoiceClient::getInstance())
{
gVoiceClient->setCaptureDevice(ctrl->getValue().asString());
LLVoiceClient::getInstance()->setCaptureDevice(ctrl->getValue().asString());
}
}
// static
void LLPanelVoiceDeviceSettings::onCommitOutputDevice(LLUICtrl* ctrl, void* user_data)
{
if(gVoiceClient)
if(LLVoiceClient::getInstance())
{
gVoiceClient->setRenderDevice(ctrl->getValue().asString());
LLVoiceClient::getInstance()->setRenderDevice(ctrl->getValue().asString());
}
}

View File

@ -461,7 +461,7 @@ void LLFloaterWorldMap::draw()
childSetEnabled("Teleport", (BOOL)tracking_status);
// childSetEnabled("Clear", (BOOL)tracking_status);
childSetEnabled("Show Destination", (BOOL)tracking_status || LLWorldMap::getInstance()->isTracking());
childSetEnabled("copy_slurl", (mSLURL.size() > 0) );
childSetEnabled("copy_slurl", (mSLURL.isValid()) );
setMouseOpaque(TRUE);
getDragHandle()->setMouseOpaque(TRUE);
@ -660,14 +660,8 @@ void LLFloaterWorldMap::updateLocation()
childSetValue("location", agent_sim_name);
// Figure out where user is
LLVector3d agentPos = gAgent.getPositionGlobal();
S32 agent_x = llround( (F32)fmod( agentPos.mdV[VX], (F64)REGION_WIDTH_METERS ) );
S32 agent_y = llround( (F32)fmod( agentPos.mdV[VY], (F64)REGION_WIDTH_METERS ) );
S32 agent_z = llround( (F32)agentPos.mdV[VZ] );
// Set the current SLURL
mSLURL = LLSLURL::buildSLURL(agent_sim_name, agent_x, agent_y, agent_z);
mSLURL = LLSLURL(agent_sim_name, gAgent.getPositionGlobal());
}
}
@ -694,18 +688,15 @@ void LLFloaterWorldMap::updateLocation()
}
childSetValue("location", sim_name);
F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS );
F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS );
// simNameFromPosGlobal can fail, so don't give the user an invalid SLURL
if ( gotSimName )
{
mSLURL = LLSLURL::buildSLURL(sim_name, llround(region_x), llround(region_y), llround((F32)pos_global.mdV[VZ]));
mSLURL = LLSLURL(sim_name, pos_global);
}
else
{ // Empty SLURL will disable the "Copy SLURL to clipboard" button
mSLURL = "";
mSLURL = LLSLURL();
}
}
}
@ -1174,7 +1165,7 @@ void LLFloaterWorldMap::onClearBtn()
mTrackedStatus = LLTracker::TRACKING_NOTHING;
LLTracker::stopTracking((void *)(intptr_t)TRUE);
LLWorldMap::getInstance()->cancelTracking();
mSLURL = ""; // Clear the SLURL since it's invalid
mSLURL = LLSLURL(); // Clear the SLURL since it's invalid
mSetToUserPosition = TRUE; // Revert back to the current user position
}
@ -1197,10 +1188,10 @@ void LLFloaterWorldMap::onClickTeleportBtn()
void LLFloaterWorldMap::onCopySLURL()
{
getWindow()->copyTextToClipboard(utf8str_to_wstring(mSLURL));
getWindow()->copyTextToClipboard(utf8str_to_wstring(mSLURL.getSLURLString()));
LLSD args;
args["SLURL"] = mSLURL;
args["SLURL"] = mSLURL.getSLURLString();
LLNotificationsUtil::add("CopySLURL", args);
}

View File

@ -43,6 +43,7 @@
#include "llhudtext.h"
#include "llmapimagetype.h"
#include "lltracker.h"
#include "llslurl.h"
class LLEventInfo;
class LLFriendObserver;
@ -183,7 +184,7 @@ private:
LLTracker::ETrackingStatus mTrackedStatus;
std::string mTrackedSimName;
std::string mTrackedAvatarName;
std::string mSLURL;
LLSLURL mSLURL;
};
extern LLFloaterWorldMap* gFloaterWorldMap;

View File

@ -287,7 +287,7 @@ bool LLGroupList::onContextMenuItemEnable(const LLSD& userdata)
return gAgent.getGroupID() != selected_group_id;
if (userdata.asString() == "call")
return real_group_selected && LLVoiceClient::voiceEnabled()&&gVoiceClient->voiceWorking();
return real_group_selected && LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();
return real_group_selected;
}

View File

@ -58,7 +58,6 @@
#include "lltransientfloatermgr.h"
#include "llinventorymodel.h"
#include "llrootview.h"
#include "llspeakers.h"

View File

@ -300,7 +300,7 @@ void LLFloaterIMPanel::onVolumeChange(LLUICtrl* source, void* user_data)
LLFloaterIMPanel* floaterp = (LLFloaterIMPanel*)user_data;
if (floaterp)
{
gVoiceClient->setUserVolume(floaterp->mOtherParticipantUUID, (F32)source->getValue().asReal());
LLVoiceClient::getInstance()->setUserVolume(floaterp->mOtherParticipantUUID, (F32)source->getValue().asReal());
}
}
@ -312,7 +312,7 @@ void LLFloaterIMPanel::draw()
BOOL enable_connect = (region && region->getCapability("ChatSessionRequest") != "")
&& mSessionInitialized
&& LLVoiceClient::voiceEnabled()
&& LLVoiceClient::getInstance()->voiceEnabled()
&& mCallBackEnabled;
// hide/show start call and end call buttons
@ -320,8 +320,8 @@ void LLFloaterIMPanel::draw()
if (!voice_channel)
return;
childSetVisible("end_call_btn", LLVoiceClient::voiceEnabled() && voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED);
childSetVisible("start_call_btn", LLVoiceClient::voiceEnabled() && voice_channel->getState() < LLVoiceChannel::STATE_CALL_STARTED);
childSetVisible("end_call_btn", LLVoiceClient::getInstance()->voiceEnabled() && voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED);
childSetVisible("start_call_btn", LLVoiceClient::getInstance()->voiceEnabled() && voice_channel->getState() < LLVoiceChannel::STATE_CALL_STARTED);
childSetEnabled("start_call_btn", enable_connect);
childSetEnabled("send_btn", !childGetValue("chat_editor").asString().empty());
@ -384,11 +384,11 @@ void LLFloaterIMPanel::draw()
else
{
// refresh volume and mute checkbox
childSetVisible("speaker_volume", LLVoiceClient::voiceEnabled() && voice_channel->isActive());
childSetValue("speaker_volume", gVoiceClient->getUserVolume(mOtherParticipantUUID));
childSetVisible("speaker_volume", LLVoiceClient::getInstance()->voiceEnabled() && voice_channel->isActive());
childSetValue("speaker_volume", LLVoiceClient::getInstance()->getUserVolume(mOtherParticipantUUID));
childSetValue("mute_btn", LLMuteList::getInstance()->isMuted(mOtherParticipantUUID, LLMute::flagVoiceChat));
childSetVisible("mute_btn", LLVoiceClient::voiceEnabled() && voice_channel->isActive());
childSetVisible("mute_btn", LLVoiceClient::getInstance()->voiceEnabled() && voice_channel->isActive());
}
LLFloater::draw();
}

View File

@ -344,13 +344,13 @@ LLIMModel::LLIMSession::~LLIMSession()
mSpeakers = NULL;
// End the text IM session if necessary
if(gVoiceClient && mOtherParticipantID.notNull())
if(LLVoiceClient::getInstance() && mOtherParticipantID.notNull())
{
switch(mType)
{
case IM_NOTHING_SPECIAL:
case IM_SESSION_P2P_INVITE:
gVoiceClient->endUserIMSession(mOtherParticipantID);
LLVoiceClient::getInstance()->endUserIMSession(mOtherParticipantID);
break;
default:
@ -925,7 +925,7 @@ void LLIMModel::sendMessage(const std::string& utf8_text,
if((offline == IM_OFFLINE) && (LLVoiceClient::getInstance()->isOnlineSIP(other_participant_id)))
{
// User is online through the OOW connector, but not with a regular viewer. Try to send the message via SLVoice.
sent = gVoiceClient->sendTextMessage(other_participant_id, utf8_text);
sent = LLVoiceClient::getInstance()->sendTextMessage(other_participant_id, utf8_text);
}
if(!sent)
@ -1717,7 +1717,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)
// skipping "You will now be reconnected to nearby" in notification when call is ended by disabling voice,
// so no reconnection to nearby chat happens (EXT-4397)
bool voice_works = LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking();
bool voice_works = LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();
std::string reconnect_nearby = voice_works ? LLTrans::getString("reconnect_nearby") : std::string();
childSetTextArg("nearby", "[RECONNECT_NEARBY]", reconnect_nearby);
@ -1843,7 +1843,11 @@ LLCallDialog(payload)
void LLIncomingCallDialog::onLifetimeExpired()
{
// check whether a call is valid or not
if (LLVoiceClient::getInstance()->findSession(mPayload["caller_id"].asUUID()))
LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mPayload["session_id"].asUUID());
if(channelp &&
(channelp->getState() != LLVoiceChannel::STATE_NO_CHANNEL_INFO) &&
(channelp->getState() != LLVoiceChannel::STATE_ERROR) &&
(channelp->getState() != LLVoiceChannel::STATE_HUNG_UP))
{
// restart notification's timer if call is still valid
mLifetimeTimer.start();
@ -2077,10 +2081,10 @@ void LLIncomingCallDialog::processCallResponse(S32 response)
{
if (type == IM_SESSION_P2P_INVITE)
{
if(gVoiceClient)
if(LLVoiceClient::getInstance())
{
std::string s = mPayload["session_handle"].asString();
gVoiceClient->declineInvite(s);
LLVoiceClient::getInstance()->declineInvite(s);
}
}
else
@ -2168,11 +2172,8 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response)
{
if (type == IM_SESSION_P2P_INVITE)
{
if(gVoiceClient)
{
std::string s = payload["session_handle"].asString();
gVoiceClient->declineInvite(s);
}
std::string s = payload["session_handle"].asString();
LLVoiceClient::getInstance()->declineInvite(s);
}
else
{
@ -3078,7 +3079,7 @@ public:
return;
}
if(!LLVoiceClient::voiceEnabled())
if(!LLVoiceClient::getInstance()->voiceEnabled())
{
// Don't display voice invites unless the user has voice enabled.
return;

View File

@ -536,8 +536,7 @@ void LLInspectAvatar::toggleSelectedVoice(bool enabled)
void LLInspectAvatar::updateVolumeSlider()
{
bool voice_enabled = gVoiceClient->getVoiceEnabled(mAvatarID);
bool voice_enabled = LLVoiceClient::getInstance()->getVoiceEnabled(mAvatarID);
// Do not display volume slider and mute button if it
// is ourself or we are not in a voice channel together
@ -567,6 +566,7 @@ void LLInspectAvatar::updateVolumeSlider()
volume_slider->setEnabled( !is_muted );
F32 volume;
if (is_muted)
{
// it's clearer to display their volume as zero
@ -575,7 +575,7 @@ void LLInspectAvatar::updateVolumeSlider()
else
{
// actual volume
volume = gVoiceClient->getUserVolume(mAvatarID);
volume = LLVoiceClient::getInstance()->getUserVolume(mAvatarID);
}
volume_slider->setValue( (F64)volume );
}
@ -604,7 +604,7 @@ void LLInspectAvatar::onClickMuteVolume()
void LLInspectAvatar::onVolumeChange(const LLSD& data)
{
F32 volume = (F32)data.asReal();
gVoiceClient->setUserVolume(mAvatarID, volume);
LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume);
}
void LLInspectAvatar::nameUpdatedCallback(

View File

@ -480,7 +480,7 @@ void LLInspectObject::updateCreator(LLSelectNode* nodep)
// Objects cannot be created by a group, so use agent URL format
LLUUID creator_id = nodep->mPermissions->getCreator();
std::string creator_url =
LLSLURL::buildCommand("agent", creator_id, "about");
LLSLURL("agent", creator_id, "about").getSLURLString();
args["[CREATOR]"] = creator_url;
// created by one user but owned by another
@ -490,12 +490,12 @@ void LLInspectObject::updateCreator(LLSelectNode* nodep)
if (group_owned)
{
owner_id = nodep->mPermissions->getGroup();
owner_url = LLSLURL::buildCommand("group", owner_id, "about");
owner_url = LLSLURL("group", owner_id, "about").getSLURLString();
}
else
{
owner_id = nodep->mPermissions->getOwner();
owner_url = LLSLURL::buildCommand("agent", owner_id, "about");
owner_url = LLSLURL("agent", owner_id, "about").getSLURLString();
}
args["[OWNER]"] = owner_url;

View File

@ -176,11 +176,11 @@ void LLInspectRemoteObject::update()
{
if (mGroupOwned)
{
owner = LLSLURL::buildCommand("group", mOwnerID, "about");
owner = LLSLURL("group", mOwnerID, "about").getSLURLString();
}
else
{
owner = LLSLURL::buildCommand("agent", mOwnerID, "about");
owner = LLSLURL("agent", mOwnerID, "about").getSLURLString();
}
}
else

View File

@ -1329,7 +1329,6 @@ bool LLInventoryModel::fetchDescendentsOf(const LLUUID& folder_id)
return cat->fetchDescendents();
}
void LLInventoryModel::cache(
const LLUUID& parent_folder_id,
const LLUUID& agent_id)

View File

@ -299,7 +299,7 @@ void LLLandmarkActions::getSLURLfromPosGlobal(const LLVector3d& global_pos, slur
bool gotSimName = LLWorldMap::getInstance()->simNameFromPosGlobal(global_pos, sim_name);
if (gotSimName)
{
std::string slurl = LLSLURL::buildSLURLfromPosGlobal(sim_name, global_pos, escaped);
std::string slurl = LLSLURL(sim_name, global_pos).getSLURLString();
cb(slurl);
return;
@ -351,7 +351,7 @@ void LLLandmarkActions::onRegionResponseSLURL(slurl_callback_t cb,
bool gotSimName = LLWorldMap::getInstance()->simNameFromPosGlobal(global_pos, sim_name);
if (gotSimName)
{
slurl = LLSLURL::buildSLURLfromPosGlobal(sim_name, global_pos, escaped);
slurl = LLSLURL(sim_name, global_pos).getSLURLString();
}
else
{

View File

@ -668,9 +668,8 @@ void LLLocationInputCtrl::onLocationPrearrange(const LLSD& data)
value["item_type"] = TELEPORT_HISTORY;
value["global_pos"] = result->mGlobalPos.getValue();
std::string region_name = result->mTitle.substr(0, result->mTitle.find(','));
//TODO*: add slurl to teleportitem or parse region name from title
value["tooltip"] = LLSLURL::buildSLURLfromPosGlobal(region_name,
result->mGlobalPos, false);
//TODO*: add Surl to teleportitem or parse region name from title
value["tooltip"] = LLSLURL(region_name, result->mGlobalPos).getSLURLString();
add(result->getTitle(), value);
}
result = std::find_if(result + 1, th_items.end(), boost::bind(
@ -1011,7 +1010,9 @@ void LLLocationInputCtrl::changeLocationPresentation()
if(!mTextEntry->hasSelection() && text == mHumanReadableLocation)
{
//needs unescaped one
mTextEntry->setText(LLAgentUI::buildSLURL(false));
LLSLURL slurl;
LLAgentUI::buildSLURL(slurl, false);
mTextEntry->setText(slurl.getSLURLString());
mTextEntry->selectAll();
mMaturityIcon->setVisible(FALSE);

View File

@ -35,13 +35,14 @@
#include "llloginhandler.h"
// viewer includes
#include "llsecapi.h"
#include "lllogininstance.h" // to check if logged in yet
#include "llpanellogin.h" // save_password_to_disk()
#include "llstartup.h" // getStartupState()
#include "llurlsimstring.h"
#include "llslurl.h"
#include "llviewercontrol.h" // gSavedSettings
#include "llviewernetwork.h" // EGridInfo
#include "llviewerwindow.h" // getWindow()
#include "llviewerwindow.h" // getWindow()
// library includes
#include "llmd5.h"
@ -60,109 +61,33 @@ bool LLLoginHandler::parseDirectLogin(std::string url)
LLURI uri(url);
parse(uri.queryMap());
if (/*mWebLoginKey.isNull() ||*/
mFirstName.empty() ||
mLastName.empty())
{
return false;
}
else
{
return true;
}
// NOTE: Need to add direct login as per identity evolution
return true;
}
void LLLoginHandler::parse(const LLSD& queryMap)
{
//mWebLoginKey = queryMap["web_login_key"].asUUID();
mFirstName = queryMap["first_name"].asString();
mLastName = queryMap["last_name"].asString();
EGridInfo grid_choice = GRID_INFO_NONE;
if (queryMap["grid"].asString() == "aditi")
if (queryMap.has("grid"))
{
grid_choice = GRID_INFO_ADITI;
LLGridManager::getInstance()->setGridChoice(queryMap["grid"].asString());
}
else if (queryMap["grid"].asString() == "agni")
{
grid_choice = GRID_INFO_AGNI;
}
else if (queryMap["grid"].asString() == "siva")
{
grid_choice = GRID_INFO_SIVA;
}
else if (queryMap["grid"].asString() == "damballah")
{
grid_choice = GRID_INFO_DAMBALLAH;
}
else if (queryMap["grid"].asString() == "durga")
{
grid_choice = GRID_INFO_DURGA;
}
else if (queryMap["grid"].asString() == "shakti")
{
grid_choice = GRID_INFO_SHAKTI;
}
else if (queryMap["grid"].asString() == "soma")
{
grid_choice = GRID_INFO_SOMA;
}
else if (queryMap["grid"].asString() == "ganga")
{
grid_choice = GRID_INFO_GANGA;
}
else if (queryMap["grid"].asString() == "vaak")
{
grid_choice = GRID_INFO_VAAK;
}
else if (queryMap["grid"].asString() == "uma")
{
grid_choice = GRID_INFO_UMA;
}
else if (queryMap["grid"].asString() == "mohini")
{
grid_choice = GRID_INFO_MOHINI;
}
else if (queryMap["grid"].asString() == "yami")
{
grid_choice = GRID_INFO_YAMI;
}
else if (queryMap["grid"].asString() == "nandi")
{
grid_choice = GRID_INFO_NANDI;
}
else if (queryMap["grid"].asString() == "mitra")
{
grid_choice = GRID_INFO_MITRA;
}
else if (queryMap["grid"].asString() == "radha")
{
grid_choice = GRID_INFO_RADHA;
}
else if (queryMap["grid"].asString() == "ravi")
{
grid_choice = GRID_INFO_RAVI;
}
else if (queryMap["grid"].asString() == "aruna")
{
grid_choice = GRID_INFO_ARUNA;
}
if(grid_choice != GRID_INFO_NONE)
{
LLViewerLogin::getInstance()->setGridChoice(grid_choice);
}
std::string startLocation = queryMap["location"].asString();
if (startLocation == "specify")
{
LLURLSimString::setString(queryMap["region"].asString());
LLStartUp::setStartSLURL(LLSLURL(LLGridManager::getInstance()->getGridLoginID(),
queryMap["region"].asString()));
}
else if (!startLocation.empty()) // "last" or "home" or ??? (let LLURLSimString figure it out)
else if (startLocation == "home")
{
LLURLSimString::setString(startLocation);
LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME));
}
else if (startLocation == "last")
{
LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_LAST));
}
}
@ -220,40 +145,65 @@ bool LLLoginHandler::handle(const LLSD& tokens,
return true;
}
std::string password = query_map["password"].asString();
if (!password.empty())
if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) //on splash page
{
gSavedSettings.setBOOL("RememberPassword", TRUE);
if (password.substr(0,3) != "$1$")
{
LLMD5 pass((unsigned char*)password.c_str());
char md5pass[33]; /* Flawfinder: ignore */
pass.hex_digest(md5pass);
std::string hashed_password = ll_safe_string(md5pass, 32);
LLStartUp::savePasswordToDisk(hashed_password);
}
}
if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) //on splash page
{
if (!mFirstName.empty() || !mLastName.empty())
{
// Fill in the name, and maybe the password
LLPanelLogin::setFields(mFirstName, mLastName, password);
}
//if (mWebLoginKey.isNull())
//{
// LLPanelLogin::loadLoginPage();
//}
//else
//{
// LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
//}
LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
// as the login page may change from grid to grid, as well as
// things like username/password/etc, we simply refresh the
// login page to make sure everything is set up correctly
LLPanelLogin::loadLoginPage();
LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
}
return true;
}
// Initialize the credentials
// If the passed in URL contains login info, parse
// that into a credential and web login key. Otherwise
// check the command line. If the command line
// does not contain any login creds, load the last saved
// ones from the protected credential store.
// This always returns with a credential structure set in the
// login handler
LLPointer<LLCredential> LLLoginHandler::initializeLoginInfo()
{
LLPointer<LLCredential> result = NULL;
// so try to load it from the UserLoginInfo
result = loadSavedUserLoginInfo();
if (result.isNull())
{
result = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
}
return result;
}
LLPointer<LLCredential> LLLoginHandler::loadSavedUserLoginInfo()
{
// load the saved user login info into a LLCredential.
// perhaps this should be moved.
LLSD cmd_line_login = gSavedSettings.getLLSD("UserLoginInfo");
if (cmd_line_login.size() == 3)
{
LLMD5 pass((unsigned char*)cmd_line_login[2].asString().c_str());
char md5pass[33]; /* Flawfinder: ignore */
pass.hex_digest(md5pass);
LLSD identifier = LLSD::emptyMap();
identifier["type"] = "agent";
identifier["first_name"] = cmd_line_login[0];
identifier["last_name"] = cmd_line_login[1];
LLSD authenticator = LLSD::emptyMap();
authenticator["type"] = "hash";
authenticator["algorithm"] = "md5";
authenticator["secret"] = md5pass;
// yuck, we'll fix this with mani's changes.
gSavedSettings.setBOOL("AutoLogin", TRUE);
return gSecAPIHandler->createCredential(LLGridManager::getInstance()->getGrid(),
identifier, authenticator);
}
return NULL;
}

View File

@ -34,6 +34,7 @@
#define LLLOGINHANDLER_H
#include "llcommandhandler.h"
#include "llsecapi.h"
class LLLoginHandler : public LLCommandHandler
{
@ -46,19 +47,15 @@ class LLLoginHandler : public LLCommandHandler
// secondlife:///app/login?first=Bob&last=Dobbs
bool parseDirectLogin(std::string url);
std::string getFirstName() const { return mFirstName; }
std::string getLastName() const { return mLastName; }
// Web-based login unsupported
//LLUUID getWebLoginKey() const { return mWebLoginKey; }
LLPointer<LLCredential> loadSavedUserLoginInfo();
LLPointer<LLCredential> initializeLoginInfo();
private:
void parse(const LLSD& queryMap);
private:
std::string mFirstName;
std::string mLastName;
//LLUUID mWebLoginKey;
};
extern LLLoginHandler gLoginHandler;

View File

@ -48,13 +48,16 @@
// newview
#include "llviewernetwork.h"
#include "llviewercontrol.h"
#include "llurlsimstring.h"
#include "llslurl.h"
#include "llstartup.h"
#include "llfloaterreg.h"
#include "llnotifications.h"
#include "llwindow.h"
#if LL_LINUX || LL_SOLARIS
#include "lltrans.h"
#endif
#include "llsecapi.h"
#include "llstartup.h"
static const char * const TOS_REPLY_PUMP = "lllogininstance_tos_callback";
static const char * const TOS_LISTENER_NAME = "lllogininstance_tos";
@ -83,14 +86,14 @@ LLLoginInstance::~LLLoginInstance()
{
}
void LLLoginInstance::connect(const LLSD& credentials)
void LLLoginInstance::connect(LLPointer<LLCredential> credentials)
{
std::vector<std::string> uris;
LLViewerLogin::getInstance()->getLoginURIs(uris);
LLGridManager::getInstance()->getLoginURIs(uris);
connect(uris.front(), credentials);
}
void LLLoginInstance::connect(const std::string& uri, const LLSD& credentials)
void LLLoginInstance::connect(const std::string& uri, LLPointer<LLCredential> credentials)
{
mAttemptComplete = false; // Reset attempt complete at this point!
constructAuthParams(credentials);
@ -102,7 +105,7 @@ void LLLoginInstance::reconnect()
// Sort of like connect, only using the pre-existing
// request params.
std::vector<std::string> uris;
LLViewerLogin::getInstance()->getLoginURIs(uris);
LLGridManager::getInstance()->getLoginURIs(uris);
mLoginModule->connect(uris.front(), mRequestData);
}
@ -118,7 +121,7 @@ LLSD LLLoginInstance::getResponse()
return mResponseData;
}
void LLLoginInstance::constructAuthParams(const LLSD& credentials)
void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credential)
{
// Set up auth request options.
//#define LL_MINIMIAL_REQUESTED_OPTIONS
@ -145,8 +148,10 @@ void LLLoginInstance::constructAuthParams(const LLSD& credentials)
requested_options.append("adult_compliant");
//requested_options.append("inventory-targets");
requested_options.append("buddy-list");
requested_options.append("newuser-config");
requested_options.append("ui-config");
#endif
requested_options.append("voice-config");
requested_options.append("tutorial_setting");
requested_options.append("login-flags");
requested_options.append("global-textures");
@ -155,20 +160,18 @@ void LLLoginInstance::constructAuthParams(const LLSD& credentials)
gSavedSettings.setBOOL("UseDebugMenus", TRUE);
requested_options.append("god-connect");
}
// (re)initialize the request params with creds.
LLSD request_params = user_credential->getLoginParams();
char hashed_mac_string[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */
LLMD5 hashed_mac;
hashed_mac.update( gMACAddress, MAC_ADDRESS_BYTES );
unsigned char MACAddress[MAC_ADDRESS_BYTES];
LLUUID::getNodeID(MACAddress);
hashed_mac.update( MACAddress, MAC_ADDRESS_BYTES );
hashed_mac.finalize();
hashed_mac.hex_digest(hashed_mac_string);
// prepend "$1$" to the password to indicate its the md5'd version.
std::string dpasswd("$1$");
dpasswd.append(credentials["passwd"].asString());
// (re)initialize the request params with creds.
LLSD request_params(credentials);
request_params["passwd"] = dpasswd;
request_params["start"] = construct_start_string();
request_params["skipoptional"] = mSkipOptionalUpdate;
request_params["agree_to_tos"] = false; // Always false here. Set true in
@ -247,6 +250,15 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
LLSD data(LLSD::emptyMap());
data["message"] = message_response;
data["reply_pump"] = TOS_REPLY_PUMP;
if(response.has("error_code"))
{
data["error_code"] = response["error_code"];
}
if(response.has("certificate"))
{
data["certificate"] = response["certificate"];
}
LLFloaterReg::showInstance("message_critical", data);
LLEventPumps::instance().obtain(TOS_REPLY_PUMP)
.listen(TOS_LISTENER_NAME,
@ -454,20 +466,31 @@ bool LLLoginInstance::updateDialogCallback(const LLSD& notification, const LLSD&
std::string construct_start_string()
{
std::string start;
if (LLURLSimString::parse())
LLSLURL start_slurl = LLStartUp::getStartSLURL();
switch(start_slurl.getType())
{
// a startup URL was specified
std::string unescaped_start =
case LLSLURL::LOCATION:
{
// a startup URL was specified
LLVector3 position = start_slurl.getPosition();
std::string unescaped_start =
STRINGIZE( "uri:"
<< LLURLSimString::sInstance.mSimName << "&"
<< LLURLSimString::sInstance.mX << "&"
<< LLURLSimString::sInstance.mY << "&"
<< LLURLSimString::sInstance.mZ);
start = xml_escape_string(unescaped_start);
}
else
{
start = gSavedSettings.getString("LoginLocation");
<< start_slurl.getRegion() << "&"
<< position[VX] << "&"
<< position[VY] << "&"
<< position[VZ]);
start = xml_escape_string(unescaped_start);
break;
}
case LLSLURL::HOME_LOCATION:
{
start = "home";
break;
}
default:
{
start = "last";
}
}
return start;
}

View File

@ -36,6 +36,7 @@
#include "lleventdispatcher.h"
#include <boost/scoped_ptr.hpp>
#include <boost/function.hpp>
#include "llsecapi.h"
class LLLogin;
class LLEventStream;
class LLNotificationsInterface;
@ -48,8 +49,8 @@ public:
LLLoginInstance();
~LLLoginInstance();
void connect(const LLSD& credential); // Connect to the current grid choice.
void connect(const std::string& uri, const LLSD& credential); // Connect to the given uri.
void connect(LLPointer<LLCredential> credentials); // Connect to the current grid choice.
void connect(const std::string& uri, LLPointer<LLCredential> credentials); // Connect to the given uri.
void reconnect(); // reconnect using the current credentials.
void disconnect();
@ -81,7 +82,7 @@ public:
void setUpdaterLauncher(const UpdaterLauncherCallback& ulc) { mUpdaterLauncher = ulc; }
private:
void constructAuthParams(const LLSD& credentials);
void constructAuthParams(LLPointer<LLCredential> user_credentials);
void updateApp(bool mandatory, const std::string& message);
bool updateDialogCallback(const LLSD& notification, const LLSD& response);

View File

@ -52,7 +52,6 @@
#include "llsearchcombobox.h"
#include "llsidetray.h"
#include "llslurl.h"
#include "llurlsimstring.h"
#include "llurlregistry.h"
#include "llurldispatcher.h"
#include "llviewerinventory.h"
@ -508,29 +507,34 @@ void LLNavigationBar::onLocationSelection()
std::string region_name;
LLVector3 local_coords(128, 128, 0);
S32 x = 0, y = 0, z = 0;
// Is the typed location a SLURL?
if (LLSLURL::isSLURL(typed_location))
LLSLURL slurl = LLSLURL(typed_location);
if (slurl.getType() == LLSLURL::LOCATION)
{
// Yes. Extract region name and local coordinates from it.
if (LLURLSimString::parse(LLSLURL::stripProtocol(typed_location), &region_name, &x, &y, &z))
local_coords.set(x, y, z);
else
return;
region_name = slurl.getRegion();
local_coords = slurl.getPosition();
}
// we have to do this check after previous, because LLUrlRegistry contains handlers for slurl too
//but we need to know whether typed_location is a simple http url.
else if (LLUrlRegistry::instance().isUrl(typed_location))
else if(!slurl.isValid())
{
// we have to do this check after previous, because LLUrlRegistry contains handlers for slurl too
// but we need to know whether typed_location is a simple http url.
if (LLUrlRegistry::instance().isUrl(typed_location))
{
// display http:// URLs in the media browser, or
// anything else is sent to the search floater
LLWeb::loadURL(typed_location);
return;
}
else
{
// assume that an user has typed the {region name} or possible {region_name, parcel}
region_name = typed_location.substr(0,typed_location.find(','));
}
}
else
{
// assume that an user has typed the {region name} or possible {region_name, parcel}
region_name = typed_location.substr(0,typed_location.find(','));
// was an app slurl, home, whatever. Bail
return;
}
// Resolve the region name to its global coordinates.
@ -562,7 +566,7 @@ void LLNavigationBar::onTeleportFinished(const LLVector3d& global_agent_pos)
*/
LLAgentUI::buildLocationString(location, LLAgentUI::LOCATION_FORMAT_NO_MATURITY,
gAgent.getPosAgentFromGlobal(global_agent_pos));
std::string tooltip (LLSLURL::buildSLURLfromPosGlobal(gAgent.getRegion()->getName(), global_agent_pos, false));
std::string tooltip (LLSLURL(gAgent.getRegion()->getName(), global_agent_pos).getSLURLString());
LLLocationHistoryItem item (location,
global_agent_pos, tooltip,TYPED_REGION_SLURL);// we can add into history only TYPED location
@ -651,7 +655,7 @@ void LLNavigationBar::onRegionNameResponse(
LLVector3d region_pos = from_region_handle(region_handle);
LLVector3d global_pos = region_pos + (LLVector3d) local_coords;
llinfos << "Teleporting to: " << LLSLURL::buildSLURLfromPosGlobal(region_name, global_pos, false) << llendl;
llinfos << "Teleporting to: " << LLSLURL(region_name, global_pos).getSLURLString() << llendl;
gAgent.teleportViaLocation(global_pos);
}

View File

@ -142,7 +142,7 @@ void LLOutputMonitorCtrl::draw()
// Copied from llmediaremotectrl.cpp
// *TODO: Give the LLOutputMonitorCtrl an agent-id to monitor, then
// call directly into gVoiceClient to ask if that agent-id is muted, is
// call directly into LLVoiceClient::getInstance() to ask if that agent-id is muted, is
// speaking, and what power. This avoids duplicating data, which can get
// out of sync.
const F32 LEVEL_0 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL / 3.f;
@ -151,14 +151,14 @@ void LLOutputMonitorCtrl::draw()
if (getVisible() && mAutoUpdate && !mIsMuted && mSpeakerId.notNull())
{
setPower(gVoiceClient->getCurrentPower(mSpeakerId));
setPower(LLVoiceClient::getInstance()->getCurrentPower(mSpeakerId));
if(mIsAgentControl)
{
setIsTalking(gVoiceClient->getUserPTTState());
setIsTalking(LLVoiceClient::getInstance()->getUserPTTState());
}
else
{
setIsTalking(gVoiceClient->getIsSpeaking(mSpeakerId));
setIsTalking(LLVoiceClient::getInstance()->getIsSpeaking(mSpeakerId));
}
}

View File

@ -143,7 +143,7 @@ private:
LLPointer<LLUIImage> mImageLevel2;
LLPointer<LLUIImage> mImageLevel3;
/** whether to deal with gVoiceClient directly */
/** whether to deal with LLVoiceClient::getInstance() directly */
bool mAutoUpdate;
/** uuid of a speaker being monitored */

View File

@ -258,7 +258,7 @@ void LLOverlayBar::refresh()
{
// update "remotes"
childSetVisible("media_remote_container", TRUE);
childSetVisible("voice_remote_container", LLVoiceClient::voiceEnabled());
childSetVisible("voice_remote_container", LLVoiceClient::getInstance()->voiceEnabled());
childSetVisible("state_buttons", TRUE);
}

View File

@ -163,7 +163,7 @@ BOOL LLPanelAvatarNotes::postBuild()
resetControls();
resetData();
gVoiceClient->addObserver((LLVoiceClientStatusObserver*)this);
LLVoiceClient::getInstance()->addObserver((LLVoiceClientStatusObserver*)this);
return TRUE;
}
@ -374,7 +374,7 @@ void LLPanelAvatarNotes::onChange(EStatusType status, const std::string &channel
return;
}
childSetEnabled("call", LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking());
childSetEnabled("call", LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking());
}
void LLPanelAvatarNotes::setAvatarId(const LLUUID& id)
@ -518,7 +518,7 @@ BOOL LLPanelAvatarProfile::postBuild()
pic = getChild<LLTextureCtrl>("real_world_pic");
pic->setFallbackImageName("default_profile_picture.j2c");
gVoiceClient->addObserver((LLVoiceClientStatusObserver*)this);
LLVoiceClient::getInstance()->addObserver((LLVoiceClientStatusObserver*)this);
resetControls();
resetData();
@ -809,7 +809,7 @@ void LLPanelAvatarProfile::onChange(EStatusType status, const std::string &chann
return;
}
childSetEnabled("call", LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking());
childSetEnabled("call", LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking());
}
void LLPanelAvatarProfile::setAvatarId(const LLUUID& id)

View File

@ -201,7 +201,7 @@ BOOL LLPanelGroup::postBuild()
mJoinText = panel_general->getChild<LLUICtrl>("join_cost_text");
}
gVoiceClient->addObserver(this);
LLVoiceClient::getInstance()->addObserver(this);
return TRUE;
}
@ -322,7 +322,7 @@ void LLPanelGroup::onChange(EStatusType status, const std::string &channelURI, b
return;
}
childSetEnabled("btn_call", LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking());
childSetEnabled("btn_call", LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking());
}
void LLPanelGroup::notifyObservers()

View File

@ -81,7 +81,8 @@ void LLPanelChatControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::E
void LLPanelChatControlPanel::updateCallButton()
{
bool voice_enabled = LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking();
// hide/show call button
bool voice_enabled = LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();
LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(mSessionId);
@ -124,7 +125,7 @@ BOOL LLPanelChatControlPanel::postBuild()
childSetAction("end_call_btn", boost::bind(&LLPanelChatControlPanel::onEndCallButtonClicked, this));
childSetAction("voice_ctrls_btn", boost::bind(&LLPanelChatControlPanel::onOpenVoiceControlsClicked, this));
gVoiceClient->addObserver(this);
LLVoiceClient::getInstance()->addObserver(this);
return TRUE;
}

View File

@ -51,11 +51,12 @@
#include "llfocusmgr.h"
#include "lllineeditor.h"
#include "llnotificationsutil.h"
#include "llsecapi.h"
#include "llstartup.h"
#include "lltextbox.h"
#include "llui.h"
#include "lluiconstants.h"
#include "llurlsimstring.h"
#include "llslurl.h"
#include "llversioninfo.h"
#include "llviewerhelp.h"
#include "llviewertexturelist.h"
@ -77,6 +78,7 @@
#pragma warning(disable: 4355) // 'this' used in initializer list
#endif // LL_WINDOWS
#include "llsdserialize.h"
#define USE_VIEWER_AUTH 0
const S32 BLACK_BORDER_HEIGHT = 160;
@ -104,7 +106,6 @@ public:
LLLoginRefreshHandler gLoginRefreshHandler;
// helper class that trys to download a URL from a web site and calls a method
// on parent class indicating if the web server is working or not
class LLIamHereLogin : public LLHTTPClient::Responder
@ -153,10 +154,6 @@ namespace {
boost::intrusive_ptr< LLIamHereLogin > gResponsePtr = 0;
};
void set_start_location(LLUICtrl* ctrl, void* data)
{
LLURLSimString::setString(ctrl->getValue().asString());
}
//---------------------------------------------------------------------------
// Public methods
@ -187,6 +184,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
delete LLPanelLogin::sInstance;
}
mPasswordModified = FALSE;
LLPanelLogin::sInstance = this;
// add to front so we are the bottom-most child
@ -213,10 +211,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
}
#if !USE_VIEWER_AUTH
childSetPrevalidate("first_name_edit", LLTextValidate::validateASCIIPrintableNoSpace);
childSetPrevalidate("last_name_edit", LLTextValidate::validateASCIIPrintableNoSpace);
childSetCommitCallback("password_edit", mungePassword, this);
childSetPrevalidate("username_edit", LLTextValidate::validateASCIIPrintableNoPipe);
getChild<LLLineEditor>("password_edit")->setKeystrokeCallback(onPassKey, this);
// change z sort of clickable text to be behind buttons
@ -228,27 +223,19 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
LLComboBox* combo = getChild<LLComboBox>("start_location_combo");
std::string sim_string = LLURLSimString::sInstance.mSimString;
if(sim_string.empty())
if(LLStartUp::getStartSLURL().getType() != LLSLURL::LOCATION)
{
LLURLSimString::setString(gSavedSettings.getString("LoginLocation"));
sim_string = LLURLSimString::sInstance.mSimString;
LLSLURL slurl(gSavedSettings.getString("LoginLocation"));
LLStartUp::setStartSLURL(slurl);
}
if (!sim_string.empty())
{
// Replace "<Type region name>" with this region name
combo->remove(2);
combo->add( sim_string );
combo->setTextEntry(sim_string);
combo->setCurrentByIndex( 2 );
}
combo->setCommitCallback( &set_start_location, NULL );
updateLocationCombo(false);
combo->setCommitCallback(onSelectLocation, NULL);
LLComboBox* server_choice_combo = sInstance->getChild<LLComboBox>("server_combo");
server_choice_combo->setCommitCallback(onSelectServer, NULL);
server_choice_combo->setFocusLostCallback(boost::bind(onServerComboLostFocus, _1));
updateServerCombo();
childSetAction("connect_btn", onClickConnect, this);
@ -304,17 +291,10 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
// kick off a request to grab the url manually
gResponsePtr = LLIamHereLogin::build( this );
std::string login_page = gSavedSettings.getString("LoginPage");
if (login_page.empty())
{
login_page = getString( "real_url" );
}
LLHTTPClient::head( login_page, gResponsePtr );
#if !USE_VIEWER_AUTH
// Initialize visibility (and don't force visibility - use prefs)
refreshLocation( false );
#endif
LLHTTPClient::head( LLGridManager::getInstance()->getLoginPage(), gResponsePtr );
updateLocationCombo(false);
}
@ -378,21 +358,6 @@ void LLPanelLogin::setSiteIsAlive( bool alive )
}
}
void LLPanelLogin::mungePassword(LLUICtrl* caller, void* user_data)
{
LLPanelLogin* self = (LLPanelLogin*)user_data;
LLLineEditor* editor = (LLLineEditor*)caller;
std::string password = editor->getText();
// Re-md5 if we've changed at all
if (password != self->mIncomingPassword)
{
LLMD5 pass((unsigned char *)password.c_str());
char munged_password[MD5HEX_STR_SIZE];
pass.hex_digest(munged_password);
self->mMungedPassword = munged_password;
}
}
LLPanelLogin::~LLPanelLogin()
{
@ -499,14 +464,14 @@ void LLPanelLogin::giveFocus()
if( sInstance )
{
// Grab focus and move cursor to first blank input field
std::string first = sInstance->childGetText("first_name_edit");
std::string username = sInstance->childGetText("username_edit");
std::string pass = sInstance->childGetText("password_edit");
BOOL have_first = !first.empty();
BOOL have_username = !username.empty();
BOOL have_pass = !pass.empty();
LLLineEditor* edit = NULL;
if (have_first && !have_pass)
if (have_username && !have_pass)
{
// User saved his name but not his password. Move
// focus to password field.
@ -515,7 +480,7 @@ void LLPanelLogin::giveFocus()
else
{
// User doesn't have a name, so start there.
edit = sInstance->getChild<LLLineEditor>("first_name_edit");
edit = sInstance->getChild<LLLineEditor>("username_edit");
}
if (edit)
@ -537,8 +502,8 @@ void LLPanelLogin::showLoginWidgets()
// *TODO: Append all the usual login parameters, like first_login=Y etc.
std::string splash_screen_url = sInstance->getString("real_url");
web_browser->navigateTo( splash_screen_url, "text/html" );
LLUICtrl* first_name_edit = sInstance->getChild<LLUICtrl>("first_name_edit");
first_name_edit->setFocus(TRUE);
LLUICtrl* username_edit = sInstance->getChild<LLUICtrl>("username_edit");
username_edit->setFocus(TRUE);
}
// static
@ -560,77 +525,120 @@ void LLPanelLogin::show(const LLRect &rect,
}
// static
void LLPanelLogin::setFields(const std::string& firstname,
const std::string& lastname,
const std::string& password)
void LLPanelLogin::setFields(LLPointer<LLCredential> credential,
BOOL remember)
{
if (!sInstance)
{
llwarns << "Attempted fillFields with no login view shown" << llendl;
return;
}
LL_INFOS("Credentials") << "Setting login fields to " << *credential << LL_ENDL;
sInstance->childSetText("first_name_edit", firstname);
sInstance->childSetText("last_name_edit", lastname);
// Max "actual" password length is 16 characters.
// Hex digests are always 32 characters.
if (password.length() == 32)
LLSD identifier = credential->getIdentifier();
if((std::string)identifier["type"] == "agent")
{
sInstance->childSetText("username_edit", (std::string)identifier["first_name"] + " " +
(std::string)identifier["last_name"]);
}
else if((std::string)identifier["type"] == "account")
{
sInstance->childSetText("username_edit", (std::string)identifier["account_name"]);
}
else
{
sInstance->childSetText("username_edit", std::string());
}
// if the password exists in the credential, set the password field with
// a filler to get some stars
LLSD authenticator = credential->getAuthenticator();
LL_INFOS("Credentials") << "Setting authenticator field " << authenticator["type"].asString() << LL_ENDL;
if(authenticator.isMap() &&
authenticator.has("secret") &&
(authenticator["secret"].asString().size() > 0))
{
// 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;
sInstance->childSetText("password_edit", std::string("123456789!123456"));
}
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->childSetText("password_edit", std::string());
}
sInstance->childSetValue("remember_check", remember);
}
// static
void LLPanelLogin::addServer(const std::string& server, S32 domain_name)
{
if (!sInstance)
{
llwarns << "Attempted addServer with no login view shown" << llendl;
return;
}
LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo");
combo->add(server, LLSD(domain_name) );
combo->setCurrentByIndex(0);
}
// static
void LLPanelLogin::getFields(std::string *firstname,
std::string *lastname,
std::string *password)
void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
BOOL remember)
{
if (!sInstance)
{
llwarns << "Attempted getFields with no login view shown" << llendl;
return;
}
// load the credential so we can pass back the stored password or hash if the user did
// not modify the password field.
credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
*firstname = sInstance->childGetText("first_name_edit");
LLStringUtil::trim(*firstname);
LLSD identifier = LLSD::emptyMap();
LLSD authenticator = LLSD::emptyMap();
if(credential.notNull())
{
authenticator = credential->getAuthenticator();
}
*lastname = sInstance->childGetText("last_name_edit");
LLStringUtil::trim(*lastname);
std::string username = sInstance->childGetText("username_edit");
LLStringUtil::trim(username);
std::string password = sInstance->childGetText("password_edit");
*password = sInstance->mMungedPassword;
LL_INFOS2("Credentials", "Authentication") << "retrieving username:" << username << LL_ENDL;
// determine if the username is a first/last form or not.
size_t separator_index = username.find_first_of(' ');
if (separator_index == username.npos)
{
LL_INFOS2("Credentials", "Authentication") << "account: " << username << LL_ENDL;
// single username, so this is a 'clear' identifier
identifier["type"] = "account";
identifier["account_name"] = username;
if (LLPanelLogin::sInstance->mPasswordModified)
{
authenticator = LLSD::emptyMap();
// password is plaintext
authenticator["type"] = "clear";
authenticator["secret"] = password;
}
}
else if (separator_index == username.find_last_of(' '))
{
LL_INFOS2("Credentials", "Authentication") << "agent: " << username << LL_ENDL;
// traditional firstname / lastname
identifier["type"] = "agent";
identifier["first_name"] = username.substr(0, separator_index);
identifier["last_name"] = username.substr(separator_index+1, username.npos);
if (LLPanelLogin::sInstance->mPasswordModified)
{
authenticator = LLSD::emptyMap();
authenticator["type"] = "hash";
authenticator["algorithm"] = "md5";
LLMD5 pass((const U8 *)password.c_str());
char md5pass[33]; /* Flawfinder: ignore */
pass.hex_digest(md5pass);
authenticator["secret"] = md5pass;
}
}
credential = gSecAPIHandler->createCredential(LLGridManager::getInstance()->getGrid(), identifier, authenticator);
remember = sInstance->childGetValue("remember_check");
}
// static
@ -650,64 +658,147 @@ BOOL LLPanelLogin::isGridComboDirty()
}
// static
void LLPanelLogin::getLocation(std::string &location)
BOOL LLPanelLogin::areCredentialFieldsDirty()
{
if (!sInstance)
{
llwarns << "Attempted getLocation with no login view shown" << llendl;
return;
llwarns << "Attempted getServer with no login view shown" << llendl;
}
LLComboBox* combo = sInstance->getChild<LLComboBox>("start_location_combo");
location = combo->getValue().asString();
else
{
std::string username = sInstance->childGetText("username_edit");
LLStringUtil::trim(username);
std::string password = sInstance->childGetText("password_edit");
LLLineEditor* ctrl = sInstance->getChild<LLLineEditor>("username_edit");
if(ctrl && ctrl->isDirty())
{
return true;
}
ctrl = sInstance->getChild<LLLineEditor>("password_edit");
if(ctrl && ctrl->isDirty())
{
return true;
}
}
return false;
}
// static
void LLPanelLogin::refreshLocation( bool force_visible )
void LLPanelLogin::updateLocationCombo( bool force_visible )
{
if (!sInstance) return;
#if USE_VIEWER_AUTH
loadLoginPage();
#else
BOOL show_start = TRUE;
if ( ! force_visible )
if (!sInstance)
{
// Don't show on first run after install
// Otherwise ShowStartLocation defaults to true.
show_start = gSavedSettings.getBOOL("ShowStartLocation");
return;
}
llinfos << "updatelocationcombo " << LLStartUp::getStartSLURL().asString() << llendl;
LLComboBox* combo = sInstance->getChild<LLComboBox>("start_location_combo");
switch(LLStartUp::getStartSLURL().getType())
{
case LLSLURL::LOCATION:
{
combo->setCurrentByIndex( 2 );
combo->setTextEntry(LLStartUp::getStartSLURL().getLocationString());
break;
}
case LLSLURL::HOME_LOCATION:
combo->setCurrentByIndex(1);
break;
default:
combo->setCurrentByIndex(0);
break;
}
// Update the value of the location combo.
updateLocationUI();
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);
BOOL show_server = gSavedSettings.getBOOL("ForceShowGrid");
sInstance->childSetVisible("server_combo", show_server);
#endif
sInstance->childSetVisible("server_combo", TRUE);
}
// static
void LLPanelLogin::updateLocationUI()
void LLPanelLogin::onSelectLocation(LLUICtrl*, void*)
{
if (!sInstance) return;
std::string sim_string = LLURLSimString::sInstance.mSimString;
if (!sim_string.empty())
LLComboBox* combo = sInstance->getChild<LLComboBox>("start_location_combo");
S32 index = combo->getCurrentIndex();
switch (index)
{
// Replace "<Type region name>" with this region name
LLComboBox* combo = sInstance->getChild<LLComboBox>("start_location_combo");
combo->remove(2);
combo->add( sim_string );
combo->setTextEntry(sim_string);
combo->setCurrentByIndex( 2 );
case 2:
{
LLSLURL slurl = LLSLURL(combo->getSelectedValue());
if((slurl.getType() == LLSLURL::LOCATION) &&
(slurl.getGrid() != LLStartUp::getStartSLURL().getGrid()))
{
// we've changed the grid, so update the grid selection
try
{
LLStartUp::setStartSLURL(slurl);
}
catch (LLInvalidGridName ex)
{
LLSD args;
args["GRID"] = slurl.getGrid();
LLNotificationsUtil::add("InvalidGrid", args);
return;
}
loadLoginPage();
}
break;
}
case 1:
{
LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME));
break;
}
default:
{
LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_LAST));
break;
}
}
}
// static
void LLPanelLogin::getLocation(LLSLURL& slurl)
{
LLSLURL result;
if (!sInstance)
{
llwarns << "Attempted getLocation with no login view shown" << llendl;
}
LLComboBox* combo = sInstance->getChild<LLComboBox>("start_location_combo");
switch(combo->getCurrentIndex())
{
case 0:
slurl = LLSLURL(LLSLURL::SIM_LOCATION_HOME);
case 1:
slurl = LLSLURL(LLSLURL::SIM_LOCATION_LAST);
default:
slurl = LLSLURL(combo->getValue().asString());
}
}
void LLPanelLogin::setLocation(const LLSLURL& slurl)
{
LLStartUp::setStartSLURL(slurl);
updateServer();
}
// static
void LLPanelLogin::closePanel()
{
@ -741,15 +832,13 @@ void LLPanelLogin::loadLoginPage()
std::ostringstream oStr;
std::string login_page = gSavedSettings.getString("LoginPage");
if (login_page.empty())
{
login_page = sInstance->getString( "real_url" );
}
std::string login_page = LLGridManager::getInstance()->getLoginPage();
oStr << login_page;
// Use the right delimeter depending on how LLURI parses the URL
LLURI login_page_uri = LLURI(login_page);
std::string first_query_delimiter = "&";
if (login_page_uri.queryMap().size() == 0)
{
@ -781,11 +870,10 @@ void LLPanelLogin::loadLoginPage()
curl_free(curl_version);
// Grid
char* curl_grid = curl_escape(LLViewerLogin::getInstance()->getGridLabel().c_str(), 0);
char* curl_grid = curl_escape(LLGridManager::getInstance()->getGridLoginID().c_str(), 0);
oStr << "&grid=" << curl_grid;
curl_free(curl_grid);
gViewerWindow->setMenuBackgroundColor(false, !LLViewerLogin::getInstance()->isInProductionGrid());
gViewerWindow->setMenuBackgroundColor(false, !LLGridManager::getInstance()->isInProductionGrid());
gLoginMenuBarView->setBackgroundColor(gMenuBarView->getBackgroundColor());
@ -810,30 +898,20 @@ void LLPanelLogin::loadLoginPage()
location = gSavedSettings.getString("LoginLocation");
}
std::string firstname, lastname;
std::string username;
if(gSavedSettings.getLLSD("UserLoginInfo").size() == 3)
{
LLSD cmd_line_login = gSavedSettings.getLLSD("UserLoginInfo");
firstname = cmd_line_login[0].asString();
lastname = cmd_line_login[1].asString();
username = cmd_line_login[0].asString() + " " + cmd_line_login[1];
password = cmd_line_login[2].asString();
}
if (firstname.empty())
{
firstname = gSavedSettings.getString("FirstName");
}
if (lastname.empty())
{
lastname = gSavedSettings.getString("LastName");
}
char* curl_region = curl_escape(region.c_str(), 0);
oStr <<"firstname=" << firstname <<
"&lastname=" << lastname << "&location=" << location << "&region=" << curl_region;
oStr <<"username=" << username <<
"&location=" << location << "&region=" << curl_region;
curl_free(curl_region);
@ -866,7 +944,7 @@ void LLPanelLogin::loadLoginPage()
#endif
LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
// navigate to the "real" page
if (gSavedSettings.getBOOL("RegInClient"))
{
@ -915,34 +993,33 @@ void LLPanelLogin::onClickConnect(void *)
// JC - Make sure the fields all get committed.
sInstance->setFocus(FALSE);
std::string first = sInstance->childGetText("first_name_edit");
std::string last = sInstance->childGetText("last_name_edit");
LLComboBox* combo = sInstance->getChild<LLComboBox>("start_location_combo");
std::string combo_text = combo->getSimple();
bool has_first_and_last = !(first.empty() || last.empty());
bool has_location = false;
if(combo_text=="<Type region name>" || combo_text =="")
LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo");
LLSD combo_val = combo->getSelectedValue();
if (combo_val.isUndefined())
{
// *NOTE: Mani - Location field is not always committed by this point!
// This may be duplicate work, but better than not doing the work!
LLURLSimString::sInstance.setString("");
combo_val = combo->getValue();
}
else
{
// *NOTE: Mani - Location field is not always committed by this point!
LLURLSimString::sInstance.setString(combo_text);
has_location = true;
}
if(!has_first_and_last)
{
LLNotificationsUtil::add("MustHaveAccountToLogIn");
}
else if(!has_location)
if(combo_val.isUndefined())
{
LLNotificationsUtil::add("StartRegionEmpty");
return;
}
try
{
LLGridManager::getInstance()->setGridChoice(combo_val.asString());
}
catch (LLInvalidGridName ex)
{
LLSD args;
args["GRID"] = combo_val.asString();
LLNotificationsUtil::add("InvalidGrid", args);
return;
}
std::string username = sInstance->childGetText("username_edit");
if(username.empty())
{
LLNotificationsUtil::add("MustHaveAccountToLogIn");
}
else
{
@ -1005,6 +1082,8 @@ void LLPanelLogin::onClickHelp(void*)
// static
void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data)
{
LLPanelLogin *This = (LLPanelLogin *) user_data;
This->mPasswordModified = TRUE;
if (gKeyboard->getKeyDown(KEY_CAPSLOCK) && sCapslockDidNotification == FALSE)
{
LLNotificationsUtil::add("CapsKeyOn");
@ -1012,54 +1091,90 @@ void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data)
}
}
void LLPanelLogin::updateServer()
{
try
{
updateServerCombo();
// if they've selected another grid, we should load the credentials
// for that grid and set them to the UI.
if(sInstance && !sInstance->areCredentialFieldsDirty())
{
LLPointer<LLCredential> credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
bool remember = sInstance->childGetValue("remember_check");
sInstance->setFields(credential, remember);
}
// grid changed so show new splash screen (possibly)
loadLoginPage();
updateLocationCombo(LLStartUp::getStartSLURL().getType() == LLSLURL::LOCATION);
}
catch (LLInvalidGridName ex)
{
// do nothing
}
}
void LLPanelLogin::updateServerCombo()
{
if (!sInstance)
{
return;
}
// We add all of the possible values, sorted, and then add a bar and the current value at the top
LLComboBox* server_choice_combo = sInstance->getChild<LLComboBox>("server_combo");
server_choice_combo->removeall();
#ifdef LL_RELEASE_FOR_DOWNLOAD
std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(TRUE);
#else
std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(FALSE);
#endif
for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin();
grid_choice != known_grids.end();
grid_choice++)
{
if (!grid_choice->first.empty())
{
server_choice_combo->add(grid_choice->second, grid_choice->first, ADD_SORTED);
}
}
server_choice_combo->addSeparator(ADD_TOP);
server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(),
LLGridManager::getInstance()->getGrid(), ADD_TOP);
server_choice_combo->selectFirstItem();
}
// static
void LLPanelLogin::onSelectServer(LLUICtrl*, void*)
{
// *NOTE: The paramters for this method are ignored.
// LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe, void*)
// calls this method.
LL_INFOS("AppInit") << "onSelectServer" << LL_ENDL;
// The user twiddled with the grid choice ui.
// apply the selection to the grid setting.
std::string grid_label;
S32 grid_index;
LLPointer<LLCredential> credential;
LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo");
LLSD combo_val = combo->getValue();
if (LLSD::TypeInteger == combo_val.type())
LLSD combo_val = combo->getSelectedValue();
if (combo_val.isUndefined())
{
grid_index = combo->getValue().asInteger();
if ((S32)GRID_INFO_OTHER == grid_index)
{
// This happens if the user specifies a custom grid
// via command line.
grid_label = combo->getSimple();
}
combo_val = combo->getValue();
}
else
{
// no valid selection, return other
grid_index = (S32)GRID_INFO_OTHER;
grid_label = combo_val.asString();
}
// This new seelction will override preset uris
combo = sInstance->getChild<LLComboBox>("start_location_combo");
combo->setCurrentByIndex(1);
LLStartUp::setStartSLURL(LLSLURL(gSavedSettings.getString("LoginLocation")));
LLGridManager::getInstance()->setGridChoice(combo_val.asString());
// This new selection will override preset uris
// from the command line.
LLViewerLogin* vl = LLViewerLogin::getInstance();
vl->resetURIs();
if(grid_index != GRID_INFO_OTHER)
{
vl->setGridChoice((EGridInfo)grid_index);
}
else
{
vl->setGridChoice(grid_label);
}
// grid changed so show new splash screen (possibly)
loadLoginPage();
updateServer();
updateLocationCombo(false);
updateLoginPanelLinks();
}
void LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe)
@ -1072,3 +1187,14 @@ void LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe)
onSelectServer(combo, NULL);
}
}
void LLPanelLogin::updateLoginPanelLinks()
{
LLSD grid_data = LLGridManager::getInstance()->getGridInfo();
bool system_grid = grid_data.has(GRID_IS_SYSTEM_GRID_VALUE);
// need to call through sInstance, as it's called from onSelectServer, which
// is static.
sInstance->childSetVisible("create_new_account_text", system_grid);
sInstance->childSetVisible("forgot_password_text", system_grid);
}

View File

@ -41,6 +41,8 @@
class LLLineEditor;
class LLUIImage;
class LLPanelLoginListener;
class LLSLURL;
class LLCredential;
class LLPanelLogin:
public LLPanel,
@ -65,20 +67,16 @@ public:
void (*callback)(S32 option, void* user_data),
void* callback_data);
// Remember password checkbox is set via gSavedSettings "RememberPassword"
static void setFields(const std::string& firstname, const std::string& lastname,
const std::string& password);
static void setFields(LLPointer<LLCredential> credential, BOOL remember);
static void addServer(const std::string& server, S32 domain_name);
static void refreshLocation( bool force_visible );
static void updateLocationUI();
static void getFields(std::string *firstname, std::string *lastname,
std::string *password);
static void getFields(LLPointer<LLCredential>& credential, BOOL remember);
static BOOL isGridComboDirty();
static void getLocation(std::string &location);
static BOOL areCredentialFieldsDirty();
static void getLocation(LLSLURL& slurl);
static void setLocation(const LLSLURL& slurl);
static void updateLocationCombo(bool force_visible); // simply update the combo box
static void closePanel();
void setSiteIsAlive( bool alive );
@ -86,10 +84,10 @@ public:
static void loadLoginPage();
static void giveFocus();
static void setAlwaysRefresh(bool refresh);
static void mungePassword(LLUICtrl* caller, void* user_data);
// inherited from LLViewerMediaObserver
/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
static void updateServer(); // update the combo box, change the login page to the new server, clear the combo
private:
friend class LLPanelLoginListener;
@ -103,6 +101,10 @@ private:
static void onPassKey(LLLineEditor* caller, void* user_data);
static void onSelectServer(LLUICtrl*, void*);
static void onServerComboLostFocus(LLFocusableElement*);
static void updateServerCombo();
static void onSelectLocation(LLUICtrl*, void*);
static void updateLoginPanelLinks();
private:
LLPointer<LLUIImage> mLogoImage;
@ -111,8 +113,7 @@ private:
void (*mCallback)(S32 option, void *userdata);
void* mCallbackData;
std::string mIncomingPassword;
std::string mMungedPassword;
BOOL mPasswordModified;
static LLPanelLogin* sInstance;
static BOOL sCapslockDidNotification;

View File

@ -619,7 +619,7 @@ BOOL LLPanelPeople::postBuild()
if(recent_view_sort)
mRecentViewSortMenuHandle = recent_view_sort->getHandle();
gVoiceClient->addObserver(this);
LLVoiceClient::getInstance()->addObserver(this);
// call this method in case some list is empty and buttons can be in inconsistent state
updateButtons();
@ -809,7 +809,7 @@ void LLPanelPeople::updateButtons()
}
}
bool enable_calls = gVoiceClient->voiceWorking() && gVoiceClient->voiceEnabled();
bool enable_calls = LLVoiceClient::getInstance()->isVoiceWorking() && LLVoiceClient::getInstance()->voiceEnabled();
buttonSetEnabled("teleport_btn", friends_tab_active && item_selected && isFriendOnline(selected_uuids.front()));
buttonSetEnabled("view_profile_btn", item_selected);

View File

@ -70,10 +70,7 @@ void LLPanelPlacesTab::onRegionResponse(const LLVector3d& landmark_global_pos,
std::string sl_url;
if ( gotSimName )
{
F32 region_x = (F32)fmod( landmark_global_pos.mdV[VX], (F64)REGION_WIDTH_METERS );
F32 region_y = (F32)fmod( landmark_global_pos.mdV[VY], (F64)REGION_WIDTH_METERS );
sl_url = LLSLURL::buildSLURL(sim_name, llround(region_x), llround(region_y), llround((F32)landmark_global_pos.mdV[VZ]));
sl_url = LLSLURL(sim_name, landmark_global_pos).getSLURLString();
}
else
{

View File

@ -346,7 +346,6 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
{
if (mExcludeAgent && gAgent.getID() == avatar_id) return;
if (mAvatarList->contains(avatar_id)) return;
mAvatarList->getIDs().push_back(avatar_id);
mAvatarList->setDirty();
adjustParticipant(avatar_id);
@ -632,7 +631,7 @@ bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD&
else if (item == "can_call")
{
bool not_agent = mUUIDs.front() != gAgentID;
bool can_call = not_agent && LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking();
bool can_call = not_agent && LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();
return can_call;
}

161
indra/newview/llsecapi.cpp Normal file
View File

@ -0,0 +1,161 @@
/**
* @file llsecapi.cpp
* @brief Security API for services such as certificate handling
* secure local storage, etc.
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlife.com/developers/opensource/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at http://secondlife.com/developers/opensource/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llsecapi.h"
#include "llsechandler_basic.h"
#include <openssl/evp.h>
#include <map>
#include "llhttpclient.h"
std::map<std::string, LLPointer<LLSecAPIHandler> > gHandlerMap;
LLPointer<LLSecAPIHandler> gSecAPIHandler;
void initializeSecHandler()
{
OpenSSL_add_all_algorithms();
OpenSSL_add_all_ciphers();
OpenSSL_add_all_digests();
gHandlerMap[BASIC_SECHANDLER] = new LLSecAPIBasicHandler();
// Currently, we only have the Basic handler, so we can point the main sechandler
// pointer to the basic handler. Later, we'll create a wrapper handler that
// selects the appropriate sechandler as needed, for instance choosing the
// mac keyring handler, with fallback to the basic sechandler
gSecAPIHandler = gHandlerMap[BASIC_SECHANDLER];
// initialize all SecAPIHandlers
LLProtectedDataException ex = LLProtectedDataException("");
std::map<std::string, LLPointer<LLSecAPIHandler> >::const_iterator itr;
for(itr = gHandlerMap.begin(); itr != gHandlerMap.end(); ++itr)
{
LLPointer<LLSecAPIHandler> handler = (*itr).second;
try
{
handler->init();
}
catch (LLProtectedDataException e)
{
ex = e;
}
}
if (ex.getMessage().length() > 0 ) // an exception was thrown.
{
throw ex;
}
}
// start using a given security api handler. If the string is empty
// the default is used
LLPointer<LLSecAPIHandler> getSecHandler(const std::string& handler_type)
{
if (gHandlerMap.find(handler_type) != gHandlerMap.end())
{
return gHandlerMap[handler_type];
}
else
{
return LLPointer<LLSecAPIHandler>(NULL);
}
}
// register a handler
void registerSecHandler(const std::string& handler_type,
LLPointer<LLSecAPIHandler>& handler)
{
gHandlerMap[handler_type] = handler;
}
std::ostream& operator <<(std::ostream& s, const LLCredential& cred)
{
return s << (std::string)cred;
}
// secapiSSLCertVerifyCallback
// basic callback called when a cert verification is requested.
// calls SECAPI to validate the context
// not initialized in the above initialization function, due to unit tests
// see llappviewer
int secapiSSLCertVerifyCallback(X509_STORE_CTX *ctx, void *param)
{
LLURLRequest *req = (LLURLRequest *)param;
LLPointer<LLCertificateStore> store = gSecAPIHandler->getCertificateStore("");
LLPointer<LLCertificateChain> chain = gSecAPIHandler->getCertificateChain(ctx);
LLSD validation_params = LLSD::emptyMap();
LLURI uri(req->getURL());
validation_params[CERT_HOSTNAME] = uri.hostName();
try
{
chain->validate(VALIDATION_POLICY_SSL, store, validation_params);
}
catch (LLCertValidationTrustException& cert_exception)
{
LL_WARNS("AppInit") << "Cert not trusted: " << cert_exception.getMessage() << LL_ENDL;
return 0;
}
catch (LLCertException& cert_exception)
{
LL_WARNS("AppInit") << "cert error " << cert_exception.getMessage() << LL_ENDL;
return 0;
}
catch (...)
{
LL_WARNS("AppInit") << "cert error " << LL_ENDL;
return 0;
}
return 1;
}
LLSD LLCredential::getLoginParams()
{
LLSD result = LLSD::emptyMap();
if (mIdentifier["type"].asString() == "agent")
{
// legacy credential
result["passwd"] = "$1$" + mAuthenticator["secret"].asString();
result["first"] = mIdentifier["first_name"];
result["last"] = mIdentifier["last_name"];
}
else if (mIdentifier["type"].asString() == "account")
{
result["username"] = mIdentifier["account_name"];
result["passwd"] = mAuthenticator["secret"];
}
return result;
}

493
indra/newview/llsecapi.h Normal file
View File

@ -0,0 +1,493 @@
/**
* @file llsecapi.h
* @brief Security API for services such as certificate handling
* secure local storage, etc.
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlife.com/developers/opensource/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at http://secondlife.com/developers/opensource/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LLSECAPI_H
#define LLSECAPI_H
#include <vector>
#include <openssl/x509.h>
#include <ostream>
#ifdef LL_WINDOWS
#pragma warning(disable:4250)
#endif // LL_WINDOWS
// All error handling is via exceptions.
#define CERT_SUBJECT_NAME "subject_name"
#define CERT_ISSUER_NAME "issuer_name"
#define CERT_NAME_CN "commonName"
#define CERT_SUBJECT_NAME_STRING "subject_name_string"
#define CERT_ISSUER_NAME_STRING "issuer_name_string"
#define CERT_SERIAL_NUMBER "serial_number"
#define CERT_VALID_FROM "valid_from"
#define CERT_VALID_TO "valid_to"
#define CERT_SHA1_DIGEST "sha1_digest"
#define CERT_MD5_DIGEST "md5_digest"
#define CERT_HOSTNAME "hostname"
#define CERT_BASIC_CONSTRAINTS "basicConstraints"
#define CERT_BASIC_CONSTRAINTS_CA "CA"
#define CERT_BASIC_CONSTRAINTS_PATHLEN "pathLen"
#define CERT_KEY_USAGE "keyUsage"
#define CERT_KU_DIGITAL_SIGNATURE "digitalSignature"
#define CERT_KU_NON_REPUDIATION "nonRepudiation"
#define CERT_KU_KEY_ENCIPHERMENT "keyEncipherment"
#define CERT_KU_DATA_ENCIPHERMENT "dataEncipherment"
#define CERT_KU_KEY_AGREEMENT "keyAgreement"
#define CERT_KU_CERT_SIGN "certSigning"
#define CERT_KU_CRL_SIGN "crlSigning"
#define CERT_KU_ENCIPHER_ONLY "encipherOnly"
#define CERT_KU_DECIPHER_ONLY "decipherOnly"
#define BASIC_SECHANDLER "BASIC_SECHANDLER"
#define CERT_VALIDATION_DATE "validation_date"
#define CERT_EXTENDED_KEY_USAGE "extendedKeyUsage"
#define CERT_EKU_SERVER_AUTH SN_server_auth
#define CERT_SUBJECT_KEY_IDENTFIER "subjectKeyIdentifier"
#define CERT_AUTHORITY_KEY_IDENTIFIER "authorityKeyIdentifier"
#define CERT_AUTHORITY_KEY_IDENTIFIER_ID "authorityKeyIdentifierId"
#define CERT_AUTHORITY_KEY_IDENTIFIER_NAME "authorityKeyIdentifierName"
#define CERT_AUTHORITY_KEY_IDENTIFIER_SERIAL "authorityKeyIdentifierSerial"
// validate the current time lies within
// the validation period of the cert
#define VALIDATION_POLICY_TIME 1
// validate that the CA, or some cert in the chain
// lies within the certificate store
#define VALIDATION_POLICY_TRUSTED 2
// validate that the subject name of
// the cert contains the passed in hostname
// or validates against the hostname
#define VALIDATION_POLICY_HOSTNAME 4
// validate that the cert contains the SSL EKU
#define VALIDATION_POLICY_SSL_KU 8
// validate that the cert contains the SSL EKU
#define VALIDATION_POLICY_CA_KU 16
#define VALIDATION_POLICY_CA_BASIC_CONSTRAINTS 32
// validate that the cert is correct for SSL
#define VALIDATION_POLICY_SSL (VALIDATION_POLICY_TIME | \
VALIDATION_POLICY_HOSTNAME | \
VALIDATION_POLICY_TRUSTED | \
VALIDATION_POLICY_SSL_KU | \
VALIDATION_POLICY_CA_BASIC_CONSTRAINTS | \
VALIDATION_POLICY_CA_KU)
class LLProtectedDataException
{
public:
LLProtectedDataException(const char *msg)
{
LL_WARNS("SECAPI") << "Protected Data Error: " << (std::string)msg << LL_ENDL;
mMsg = (std::string)msg;
}
std::string getMessage() { return mMsg; }
protected:
std::string mMsg;
};
// class LLCertificate
// parent class providing an interface for certifiate.
// LLCertificates are considered unmodifiable
// Certificates are pulled out of stores, or created via
// factory calls
class LLCertificate : public LLRefCount
{
LOG_CLASS(LLCertificate);
public:
LLCertificate() {}
virtual ~LLCertificate() {}
// return a PEM encoded certificate. The encoding
// includes the -----BEGIN CERTIFICATE----- and end certificate elements
virtual std::string getPem() const=0;
// return a DER encoded certificate
virtual std::vector<U8> getBinary() const=0;
// return an LLSD object containing information about the certificate
// such as its name, signature, expiry time, serial number
virtual LLSD getLLSD() const=0;
// return an openSSL X509 struct for the certificate
virtual X509* getOpenSSLX509() const=0;
};
// class LLCertificateVector
// base class for a list of certificates.
class LLCertificateVector : public LLRefCount
{
public:
LLCertificateVector() {};
virtual ~LLCertificateVector() {};
// base iterator implementation class, providing
// the functionality needed for the iterator class.
class iterator_impl : public LLRefCount
{
public:
iterator_impl() {};
virtual ~iterator_impl() {};
virtual void seek(bool incr)=0;
virtual LLPointer<iterator_impl> clone() const=0;
virtual bool equals(const LLPointer<iterator_impl>& _iter) const=0;
virtual LLPointer<LLCertificate> get()=0;
};
// iterator class
class iterator
{
public:
iterator(LLPointer<iterator_impl> impl) : mImpl(impl) {}
iterator() : mImpl(NULL) {}
iterator(const iterator& _iter) {mImpl = _iter.mImpl->clone(); }
~iterator() {}
iterator& operator++() { if(mImpl.notNull()) mImpl->seek(true); return *this;}
iterator& operator--() { if(mImpl.notNull()) mImpl->seek(false); return *this;}
iterator operator++(int) { iterator result = *this; if(mImpl.notNull()) mImpl->seek(true); return result;}
iterator operator--(int) { iterator result = *this; if(mImpl.notNull()) mImpl->seek(false); return result;}
LLPointer<LLCertificate> operator*() { return mImpl->get(); }
LLPointer<iterator_impl> mImpl;
protected:
friend bool operator==(const LLCertificateVector::iterator& _lhs, const LLCertificateVector::iterator& _rhs);
bool equals(const iterator& _iter) const { return mImpl->equals(_iter.mImpl); }
};
// numeric indexer
virtual LLPointer<LLCertificate> operator[](int)=0;
// Iteration
virtual iterator begin()=0;
virtual iterator end()=0;
// find a cert given params
virtual iterator find(const LLSD& params) =0;
// return the number of certs in the store
virtual int size() const = 0;
// append the cert to the store. if a copy of the cert already exists in the store, it is removed first
virtual void add(LLPointer<LLCertificate> cert)=0;
// insert the cert to the store. if a copy of the cert already exists in the store, it is removed first
virtual void insert(iterator location, LLPointer<LLCertificate> cert)=0;
// remove a certificate from the store
virtual LLPointer<LLCertificate> erase(iterator cert)=0;
};
// class LLCertificateStore
// represents a store of certificates, typically a store of root CA
// certificates. The store can be persisted, and can be used to validate
// a cert chain
//
class LLCertificateStore : virtual public LLCertificateVector
{
public:
LLCertificateStore() {}
virtual ~LLCertificateStore() {}
// persist the store
virtual void save()=0;
// return the store id
virtual std::string storeId() const=0;
};
// class LLCertificateChain
// Class representing a chain of certificates in order, with the
// first element being the child cert.
class LLCertificateChain : virtual public LLCertificateVector
{
public:
LLCertificateChain() {}
virtual ~LLCertificateChain() {}
// validate a certificate chain given the params.
// Will throw exceptions on error
virtual void validate(int validation_policy,
LLPointer<LLCertificateStore> ca_store,
const LLSD& validation_params) =0;
};
inline
bool operator==(const LLCertificateVector::iterator& _lhs, const LLCertificateVector::iterator& _rhs)
{
return _lhs.equals(_rhs);
}
inline
bool operator!=(const LLCertificateVector::iterator& _lhs, const LLCertificateVector::iterator& _rhs)
{
return !(_lhs == _rhs);
}
//
// LLCredential - interface for credentials providing the following functionality:
// * persistance of credential information based on grid (for saving username/password)
// * serialization to an OGP identifier/authenticator pair
//
class LLCredential : public LLRefCount
{
public:
LLCredential() {}
LLCredential(const std::string& grid)
{
mGrid = grid;
mIdentifier = LLSD::emptyMap();
mAuthenticator = LLSD::emptyMap();
}
virtual ~LLCredential() {}
virtual void setCredentialData(const LLSD& identifier, const LLSD& authenticator)
{
mIdentifier = identifier;
mAuthenticator = authenticator;
}
virtual LLSD getIdentifier() { return mIdentifier; }
virtual LLSD getAuthenticator() { return mAuthenticator; }
virtual LLSD getLoginParams();
virtual std::string getGrid() { return mGrid; }
virtual void clearAuthenticator() { mAuthenticator = LLSD(); }
virtual std::string userID() const { return std::string("unknown");}
virtual std::string asString() const { return std::string("unknown");}
operator std::string() const { return asString(); }
protected:
LLSD mIdentifier;
LLSD mAuthenticator;
std::string mGrid;
};
std::ostream& operator <<(std::ostream& s, const LLCredential& cred);
// All error handling is via exceptions.
class LLCertException
{
public:
LLCertException(LLPointer<LLCertificate> cert, const char* msg)
{
mCert = cert;
LL_WARNS("SECAPI") << "Certificate Error: " << (std::string)msg << LL_ENDL;
mMsg = (std::string)msg;
}
LLPointer<LLCertificate> getCert() { return mCert; }
std::string getMessage() { return mMsg; }
protected:
LLPointer<LLCertificate> mCert;
std::string mMsg;
};
class LLInvalidCertificate : public LLCertException
{
public:
LLInvalidCertificate(LLPointer<LLCertificate> cert) : LLCertException(cert, "CertInvalid")
{
}
protected:
};
class LLCertValidationTrustException : public LLCertException
{
public:
LLCertValidationTrustException(LLPointer<LLCertificate> cert) : LLCertException(cert, "CertUntrusted")
{
}
protected:
};
class LLCertValidationHostnameException : public LLCertException
{
public:
LLCertValidationHostnameException(std::string hostname,
LLPointer<LLCertificate> cert) : LLCertException(cert, "CertInvalidHostname")
{
mHostname = hostname;
}
std::string getHostname() { return mHostname; }
protected:
std::string mHostname;
};
class LLCertValidationExpirationException : public LLCertException
{
public:
LLCertValidationExpirationException(LLPointer<LLCertificate> cert,
LLDate current_time) : LLCertException(cert, "CertExpired")
{
mTime = current_time;
}
LLDate GetTime() { return mTime; }
protected:
LLDate mTime;
};
class LLCertKeyUsageValidationException : public LLCertException
{
public:
LLCertKeyUsageValidationException(LLPointer<LLCertificate> cert) : LLCertException(cert, "CertKeyUsage")
{
}
protected:
};
class LLCertBasicConstraintsValidationException : public LLCertException
{
public:
LLCertBasicConstraintsValidationException(LLPointer<LLCertificate> cert) : LLCertException(cert, "CertBasicConstraints")
{
}
protected:
};
class LLCertValidationInvalidSignatureException : public LLCertException
{
public:
LLCertValidationInvalidSignatureException(LLPointer<LLCertificate> cert) : LLCertException(cert, "CertInvalidSignature")
{
}
protected:
};
// LLSecAPIHandler Class
// Interface handler class for the various security storage handlers.
class LLSecAPIHandler : public LLRefCount
{
public:
LLSecAPIHandler() {}
virtual ~LLSecAPIHandler() {}
// initialize the SecAPIHandler
virtual void init() {};
// instantiate a certificate from a pem string
virtual LLPointer<LLCertificate> getCertificate(const std::string& pem_cert)=0;
// instiate a certificate from an openssl X509 structure
virtual LLPointer<LLCertificate> getCertificate(X509* openssl_cert)=0;
// instantiate a chain from an X509_STORE_CTX
virtual LLPointer<LLCertificateChain> getCertificateChain(const X509_STORE_CTX* chain)=0;
// instantiate a cert store given it's id. if a persisted version
// exists, it'll be loaded. If not, one will be created (but not
// persisted)
virtual LLPointer<LLCertificateStore> getCertificateStore(const std::string& store_id)=0;
// persist data in a protected store
virtual void setProtectedData(const std::string& data_type,
const std::string& data_id,
const LLSD& data)=0;
// retrieve protected data
virtual LLSD getProtectedData(const std::string& data_type,
const std::string& data_id)=0;
// delete a protected data item from the store
virtual void deleteProtectedData(const std::string& data_type,
const std::string& data_id)=0;
virtual LLPointer<LLCredential> createCredential(const std::string& grid,
const LLSD& identifier,
const LLSD& authenticator)=0;
virtual LLPointer<LLCredential> loadCredential(const std::string& grid)=0;
virtual void saveCredential(LLPointer<LLCredential> cred, bool save_authenticator)=0;
virtual void deleteCredential(LLPointer<LLCredential> cred)=0;
};
void initializeSecHandler();
// retrieve a security api depending on the api type
LLPointer<LLSecAPIHandler> getSecHandler(const std::string& handler_type);
void registerSecHandler(const std::string& handler_type,
LLPointer<LLSecAPIHandler>& handler);
extern LLPointer<LLSecAPIHandler> gSecAPIHandler;
int secapiSSLCertVerifyCallback(X509_STORE_CTX *ctx, void *param);
#endif // LL_SECAPI_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,285 @@
/**
* @file llsechandler_basic.h
* @brief Security API for services such as certificate handling
* secure local storage, etc.
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlife.com/developers/opensource/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at http://secondlife.com/developers/opensource/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LLSECHANDLER_BASIC
#define LLSECHANDLER_BASIC
#include "llsecapi.h"
#include <vector>
#include <openssl/x509.h>
// helpers
extern LLSD cert_name_from_X509_NAME(X509_NAME* name);
extern std::string cert_string_name_from_X509_NAME(X509_NAME* name);
extern std::string cert_string_from_asn1_integer(ASN1_INTEGER* value);
extern LLDate cert_date_from_asn1_time(ASN1_TIME* asn1_time);
extern std::string cert_get_digest(const std::string& digest_type, X509 *cert);
// class LLCertificate
//
class LLBasicCertificate : public LLCertificate
{
public:
LOG_CLASS(LLBasicCertificate);
LLBasicCertificate(const std::string& pem_cert);
LLBasicCertificate(X509* openSSLX509);
virtual ~LLBasicCertificate();
virtual std::string getPem() const;
virtual std::vector<U8> getBinary() const;
virtual LLSD getLLSD() const;
virtual X509* getOpenSSLX509() const;
// set llsd elements for testing
void setLLSD(const std::string name, const LLSD& value) { mLLSDInfo[name] = value; }
protected:
// certificates are stored as X509 objects, as validation and
// other functionality is via openssl
X509* mCert;
LLSD& _initLLSD();
LLSD mLLSDInfo;
};
// class LLBasicCertificateVector
// Class representing a list of certificates
// This implementation uses a stl vector of certificates.
class LLBasicCertificateVector : virtual public LLCertificateVector
{
public:
LLBasicCertificateVector() {}
virtual ~LLBasicCertificateVector() {}
// Implementation of the basic iterator implementation.
// The implementation uses a vector iterator derived from
// the vector in the LLBasicCertificateVector class
class BasicIteratorImpl : public iterator_impl
{
public:
BasicIteratorImpl(std::vector<LLPointer<LLCertificate> >::iterator _iter) { mIter = _iter;}
virtual ~BasicIteratorImpl() {};
// seek forward or back. Used by the operator++/operator-- implementations
virtual void seek(bool incr)
{
if(incr)
{
mIter++;
}
else
{
mIter--;
}
}
// create a copy of the iterator implementation class, used by the iterator copy constructor
virtual LLPointer<iterator_impl> clone() const
{
return new BasicIteratorImpl(mIter);
}
virtual bool equals(const LLPointer<iterator_impl>& _iter) const
{
const BasicIteratorImpl *rhs_iter = dynamic_cast<const BasicIteratorImpl *>(_iter.get());
return (mIter == rhs_iter->mIter);
}
virtual LLPointer<LLCertificate> get()
{
return *mIter;
}
protected:
friend class LLBasicCertificateVector;
std::vector<LLPointer<LLCertificate> >::iterator mIter;
};
// numeric index of the vector
virtual LLPointer<LLCertificate> operator[](int _index) { return mCerts[_index];}
// Iteration
virtual iterator begin() { return iterator(new BasicIteratorImpl(mCerts.begin())); }
virtual iterator end() { return iterator(new BasicIteratorImpl(mCerts.end())); }
// find a cert given params
virtual iterator find(const LLSD& params);
// return the number of certs in the store
virtual int size() const { return mCerts.size(); }
// insert the cert to the store. if a copy of the cert already exists in the store, it is removed first
virtual void add(LLPointer<LLCertificate> cert) { insert(end(), cert); }
// insert the cert to the store. if a copy of the cert already exists in the store, it is removed first
virtual void insert(iterator _iter, LLPointer<LLCertificate> cert);
// remove a certificate from the store
virtual LLPointer<LLCertificate> erase(iterator _iter);
protected:
std::vector<LLPointer<LLCertificate> >mCerts;
};
// class LLCertificateStore
// represents a store of certificates, typically a store of root CA
// certificates. The store can be persisted, and can be used to validate
// a cert chain
//
class LLBasicCertificateStore : virtual public LLBasicCertificateVector, public LLCertificateStore
{
public:
LLBasicCertificateStore(const std::string& filename);
void load_from_file(const std::string& filename);
virtual ~LLBasicCertificateStore();
// persist the store
virtual void save();
// return the store id
virtual std::string storeId() const;
protected:
std::vector<LLPointer<LLCertificate> >mCerts;
std::string mFilename;
};
// class LLCertificateChain
// Class representing a chain of certificates in order, with the
// first element being the child cert.
class LLBasicCertificateChain : virtual public LLBasicCertificateVector, public LLCertificateChain
{
public:
LLBasicCertificateChain(const X509_STORE_CTX * store);
virtual ~LLBasicCertificateChain() {}
// validate a certificate chain against a certificate store, using the
// given validation policy.
virtual void validate(int validation_policy,
LLPointer<LLCertificateStore> ca_store,
const LLSD& validation_params);
};
// LLSecAPIBasicCredential class
class LLSecAPIBasicCredential : public LLCredential
{
public:
LLSecAPIBasicCredential(const std::string& grid) : LLCredential(grid) {}
virtual ~LLSecAPIBasicCredential() {}
// return a value representing the user id, (could be guid, name, whatever)
virtual std::string userID() const;
// printible string identifying the credential.
virtual std::string asString() const;
};
// LLSecAPIBasicHandler Class
// Interface handler class for the various security storage handlers.
class LLSecAPIBasicHandler : public LLSecAPIHandler
{
public:
LLSecAPIBasicHandler(const std::string& protected_data_filename,
const std::string& legacy_password_path);
LLSecAPIBasicHandler();
void init();
virtual ~LLSecAPIBasicHandler();
// instantiate a certificate from a pem string
virtual LLPointer<LLCertificate> getCertificate(const std::string& pem_cert);
// instiate a certificate from an openssl X509 structure
virtual LLPointer<LLCertificate> getCertificate(X509* openssl_cert);
// instantiate a chain from an X509_STORE_CTX
virtual LLPointer<LLCertificateChain> getCertificateChain(const X509_STORE_CTX* chain);
// instantiate a cert store given it's id. if a persisted version
// exists, it'll be loaded. If not, one will be created (but not
// persisted)
virtual LLPointer<LLCertificateStore> getCertificateStore(const std::string& store_id);
// persist data in a protected store
virtual void setProtectedData(const std::string& data_type,
const std::string& data_id,
const LLSD& data);
// retrieve protected data
virtual LLSD getProtectedData(const std::string& data_type,
const std::string& data_id);
// delete a protected data item from the store
virtual void deleteProtectedData(const std::string& data_type,
const std::string& data_id);
// credential management routines
virtual LLPointer<LLCredential> createCredential(const std::string& grid,
const LLSD& identifier,
const LLSD& authenticator);
virtual LLPointer<LLCredential> loadCredential(const std::string& grid);
virtual void saveCredential(LLPointer<LLCredential> cred, bool save_authenticator);
virtual void deleteCredential(LLPointer<LLCredential> cred);
protected:
void _readProtectedData();
void _writeProtectedData();
std::string _legacyLoadPassword();
std::string mProtectedDataFilename;
LLSD mProtectedDataMap;
LLPointer<LLBasicCertificateStore> mStore;
std::string mLegacyPasswordPath;
};
bool valueCompareLLSD(const LLSD& lhs, const LLSD& rhs);
#endif // LLSECHANDLER_BASIC

View File

@ -2435,7 +2435,7 @@ BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, std::string& name)
if (identical)
{
name = LLSLURL::buildCommand("agent", first_id, "inspect");
name = LLSLURL("agent", first_id, "inspect").getSLURLString();
}
else
{
@ -2494,11 +2494,11 @@ BOOL LLSelectMgr::selectGetOwner(LLUUID& result_id, std::string& name)
BOOL public_owner = (first_id.isNull() && !first_group_owned);
if (first_group_owned)
{
name = LLSLURL::buildCommand("group", first_id, "inspect");
name = LLSLURL("group", first_id, "inspect").getSLURLString();
}
else if(!public_owner)
{
name = LLSLURL::buildCommand("agent", first_id, "inspect");
name = LLSLURL("agent", first_id, "inspect").getSLURLString();
}
else
{
@ -2558,7 +2558,7 @@ BOOL LLSelectMgr::selectGetLastOwner(LLUUID& result_id, std::string& name)
BOOL public_owner = (first_id.isNull());
if(!public_owner)
{
name = LLSLURL::buildCommand("agent", first_id, "inspect");
name = LLSLURL("agent", first_id, "inspect").getSLURLString();
}
else
{

View File

@ -1,10 +1,11 @@
/**
* @file llslurl.cpp
* @brief SLURL manipulation
* @file llurlsimstring.cpp (was llsimurlstring.cpp)
* @brief Handles "SLURL fragments" like Ahern/123/45 for
* startup processing, login screen, prefs, etc.
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
* Copyright (c) 2006-2010, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@ -12,13 +13,12 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* online at http://secondlife.com/developers/opensource/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* online at http://secondlife.com/developers/opensource/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
@ -34,155 +34,443 @@
#include "llslurl.h"
#include "llweb.h"
#include "llurlregistry.h"
const std::string LLSLURL::PREFIX_SL_HELP = "secondlife://app.";
const std::string LLSLURL::PREFIX_SL = "sl://";
const std::string LLSLURL::PREFIX_SECONDLIFE = "secondlife://";
const std::string LLSLURL::PREFIX_SLURL_OLD = "http://slurl.com/secondlife/";
// For DnD - even though www.slurl.com redirects to slurl.com in a browser, you can copy and drag
#include "llpanellogin.h"
#include "llviewercontrol.h"
#include "llviewernetwork.h"
#include "llfiltersd2xmlrpc.h"
#include "curl/curl.h"
const char* LLSLURL::SLURL_HTTP_SCHEME = "http";
const char* LLSLURL::SLURL_HTTPS_SCHEME = "https";
const char* LLSLURL::SLURL_SECONDLIFE_SCHEME = "secondlife";
const char* LLSLURL::SLURL_SECONDLIFE_PATH = "secondlife";
const char* LLSLURL::SLURL_COM = "slurl.com";
// For DnD - even though www.slurl.com redirects to slurl.com in a browser, you can copy and drag
// text with www.slurl.com or a link explicitly pointing at www.slurl.com so testing for this
// version is required also.
const std::string LLSLURL::PREFIX_SLURL_WWW = "http://www.slurl.com/secondlife/";
const std::string LLSLURL::PREFIX_SLURL = "http://maps.secondlife.com/secondlife/";
const char* LLSLURL::WWW_SLURL_COM = "www.slurl.com";
const char* LLSLURL::MAPS_SECONDLIFE_COM = "maps.secondlife.com";
const char* LLSLURL::SLURL_X_GRID_LOCATION_INFO_SCHEME = "x-grid-location-info";
const char* LLSLURL::SLURL_APP_PATH = "app";
const char* LLSLURL::SLURL_REGION_PATH = "region";
const char* LLSLURL::SIM_LOCATION_HOME = "home";
const char* LLSLURL::SIM_LOCATION_LAST = "last";
const std::string LLSLURL::APP_TOKEN = "app/";
// static
std::string LLSLURL::stripProtocol(const std::string& url)
// resolve a simstring from a slurl
LLSLURL::LLSLURL(const std::string& slurl)
{
std::string stripped = url;
if (matchPrefix(stripped, PREFIX_SL_HELP))
// by default we go to agni.
mType = INVALID;
LL_INFOS("AppInit") << "SLURL: " << slurl << LL_ENDL;
if(slurl == SIM_LOCATION_HOME)
{
stripped.erase(0, PREFIX_SL_HELP.length());
mType = HOME_LOCATION;
}
else if (matchPrefix(stripped, PREFIX_SL))
else if(slurl.empty() || (slurl == SIM_LOCATION_LAST))
{
stripped.erase(0, PREFIX_SL.length());
}
else if (matchPrefix(stripped, PREFIX_SECONDLIFE))
{
stripped.erase(0, PREFIX_SECONDLIFE.length());
}
else if (matchPrefix(stripped, PREFIX_SLURL))
{
stripped.erase(0, PREFIX_SLURL.length());
}
else if (matchPrefix(stripped, PREFIX_SLURL_OLD))
{
stripped.erase(0, PREFIX_SLURL_OLD.length());
}
else if (matchPrefix(stripped, PREFIX_SLURL_WWW))
{
stripped.erase(0, PREFIX_SLURL_WWW.length());
}
return stripped;
}
// static
bool LLSLURL::isSLURL(const std::string& url)
{
if (matchPrefix(url, PREFIX_SL_HELP)) return true;
if (matchPrefix(url, PREFIX_SL)) return true;
if (matchPrefix(url, PREFIX_SECONDLIFE)) return true;
if (matchPrefix(url, PREFIX_SLURL)) return true;
if (matchPrefix(url, PREFIX_SLURL_OLD)) return true;
if (matchPrefix(url, PREFIX_SLURL_WWW)) return true;
return false;
}
bool LLSLURL::isValidSLURL(const std::string& url)
{
std::string temp_url(url);
//"www." may appear in DnD- see description of PREFIX_SLURL_WWW.
// If it is found, we remove it because it isn't expected in regexp.
if (matchPrefix(url, PREFIX_SLURL_WWW))
{
size_t position = url.find("www.");
temp_url.erase(position,4);
}
return LLUrlRegistry::getInstance()->isUrl(temp_url);
}
// static
bool LLSLURL::isSLURLCommand(const std::string& url)
{
if (matchPrefix(url, PREFIX_SL + APP_TOKEN) ||
matchPrefix(url, PREFIX_SECONDLIFE + "/" + APP_TOKEN) ||
matchPrefix(url, PREFIX_SLURL + APP_TOKEN) ||
matchPrefix(url, PREFIX_SLURL_WWW + APP_TOKEN) ||
matchPrefix(url, PREFIX_SLURL_OLD + APP_TOKEN) )
{
return true;
}
return false;
}
// static
bool LLSLURL::isSLURLHelp(const std::string& url)
{
return matchPrefix(url, PREFIX_SL_HELP);
}
// static
std::string LLSLURL::buildSLURL(const std::string& regionname, S32 x, S32 y, S32 z)
{
std::string slurl = PREFIX_SLURL + regionname + llformat("/%d/%d/%d",x,y,z);
slurl = LLWeb::escapeURL( slurl );
return slurl;
}
// static
std::string LLSLURL::buildCommand(const char* noun, const LLUUID& id, const char* verb)
{
std::string slurl = llformat("secondlife:///app/%s/%s/%s",
noun, id.asString().c_str(), verb);
return slurl;
}
// static
std::string LLSLURL::buildUnescapedSLURL(const std::string& regionname, S32 x, S32 y, S32 z)
{
std::string unescapedslurl = PREFIX_SLURL + regionname + llformat("/%d/%d/%d",x,y,z);
return unescapedslurl;
}
// static
std::string LLSLURL::buildSLURLfromPosGlobal(const std::string& regionname,
const LLVector3d& global_pos,
bool escaped /*= true*/)
{
S32 x, y, z;
globalPosToXYZ(global_pos, x, y, z);
if(escaped)
{
return buildSLURL(regionname, x, y, z);
mType = LAST_LOCATION;
}
else
{
return buildUnescapedSLURL(regionname, x, y, z);
LLURI slurl_uri;
// parse the slurl as a uri
if(slurl.find(':') == std::string::npos)
{
// There may be no scheme ('secondlife:' etc.) passed in. In that case
// we want to normalize the slurl by putting the appropriate scheme
// in front of the slurl. So, we grab the appropriate slurl base
// from the grid manager which may be http://slurl.com/secondlife/ for maingrid, or
// https://<hostname>/region/ for Standalone grid (the word region, not the region name)
// these slurls are typically passed in from the 'starting location' box on the login panel,
// where the user can type in <regionname>/<x>/<y>/<z>
std::string fixed_slurl = LLGridManager::getInstance()->getSLURLBase();
// the slurl that was passed in might have a prepended /, or not. So,
// we strip off the prepended '/' so we don't end up with http://slurl.com/secondlife/<region>/<x>/<y>/<z>
// or some such.
if(slurl[0] == '/')
{
fixed_slurl += slurl.substr(1);
}
else
{
fixed_slurl += slurl;
}
// We then load the slurl into a LLURI form
slurl_uri = LLURI(fixed_slurl);
}
else
{
// as we did have a scheme, implying a URI style slurl, we
// simply parse it as a URI
slurl_uri = LLURI(slurl);
}
LLSD path_array = slurl_uri.pathArray();
// determine whether it's a maingrid URI or an Standalone/open style URI
// by looking at the scheme. If it's a 'secondlife:' slurl scheme or
// 'sl:' scheme, we know it's maingrid
// At the end of this if/else block, we'll have determined the grid,
// and the slurl type (APP or LOCATION)
if(slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME)
{
// parse a maingrid style slurl. We know the grid is maingrid
// so grab it.
// A location slurl for maingrid (with the special schemes) can be in the form
// secondlife://<regionname>/<x>/<y>/<z>
// or
// secondlife://<Grid>/secondlife/<region>/<x>/<y>/<z>
// where if grid is empty, it specifies Agni
// An app style slurl for maingrid can be
// secondlife://<Grid>/app/<app parameters>
// where an empty grid implies Agni
// we'll start by checking the top of the 'path' which will be
// either 'app', 'secondlife', or <x>.
// default to maingrid
mGrid = MAINGRID;
if ((path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH) ||
(path_array[0].asString() == LLSLURL::SLURL_APP_PATH))
{
// it's in the form secondlife://<grid>/(app|secondlife)
// so parse the grid name to derive the grid ID
if (!slurl_uri.hostName().empty())
{
mGrid = LLGridManager::getInstance()->getGridByLabel(slurl_uri.hostName());
}
else if(path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH)
{
// If the slurl is in the form secondlife:///secondlife/<region> form,
// then we are in fact on maingrid.
mGrid = MAINGRID;
}
else if(path_array[0].asString() == LLSLURL::SLURL_APP_PATH)
{
// for app style slurls, where no grid name is specified, assume the currently
// selected or logged in grid.
mGrid = LLGridManager::getInstance()->getGrid();
}
if(mGrid.empty())
{
// we couldn't find the grid in the grid manager, so bail
return;
}
// set the type as appropriate.
if(path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH)
{
mType = LOCATION;
}
else
{
mType = APP;
}
path_array.erase(0);
}
else
{
// it wasn't a /secondlife/<region> or /app/<params>, so it must be secondlife://<region>
// therefore the hostname will be the region name, and it's a location type
mType = LOCATION;
// 'normalize' it so the region name is in fact the head of the path_array
path_array.insert(0, slurl_uri.hostName());
}
}
else if((slurl_uri.scheme() == LLSLURL::SLURL_HTTP_SCHEME) ||
(slurl_uri.scheme() == LLSLURL::SLURL_HTTPS_SCHEME) ||
(slurl_uri.scheme() == LLSLURL::SLURL_X_GRID_LOCATION_INFO_SCHEME))
{
// We're dealing with either a Standalone style slurl or slurl.com slurl
if ((slurl_uri.hostName() == LLSLURL::SLURL_COM) ||
(slurl_uri.hostName() == LLSLURL::WWW_SLURL_COM) ||
(slurl_uri.hostName() == LLSLURL::MAPS_SECONDLIFE_COM))
{
// slurl.com implies maingrid
mGrid = MAINGRID;
}
else
{
// As it's a Standalone grid/open, we will always have a hostname, as Standalone/open style
// urls are properly formed, unlike the stinky maingrid style
mGrid = slurl_uri.hostName();
}
if (path_array.size() == 0)
{
// um, we need a path...
return;
}
// we need to normalize the urls so
// the path portion starts with the 'command' that we want to do
// it can either be region or app.
if ((path_array[0].asString() == LLSLURL::SLURL_REGION_PATH) ||
(path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH))
{
// strip off 'region' or 'secondlife'
path_array.erase(0);
// it's a location
mType = LOCATION;
}
else if (path_array[0].asString() == LLSLURL::SLURL_APP_PATH)
{
mType = APP;
path_array.erase(0);
// leave app appended.
}
else
{
// not a valid https/http/x-grid-location-info slurl, so it'll likely just be a URL
return;
}
}
else
{
// invalid scheme, so bail
return;
}
if(path_array.size() == 0)
{
// we gotta have some stuff after the specifier as to whether it's a region or command
return;
}
// now that we know whether it's an app slurl or a location slurl,
// parse the slurl into the proper data structures.
if(mType == APP)
{
// grab the app command type and strip it (could be a command to jump somewhere,
// or whatever )
mAppCmd = path_array[0].asString();
path_array.erase(0);
// Grab the parameters
mAppPath = path_array;
// and the query
mAppQuery = slurl_uri.query();
mAppQueryMap = slurl_uri.queryMap();
return;
}
else if(mType == LOCATION)
{
// at this point, head of the path array should be [ <region>, <x>, <y>, <z> ] where x, y and z
// are collectively optional
// are optional
mRegion = LLURI::unescape(path_array[0].asString());
path_array.erase(0);
// parse the x, y, z
if(path_array.size() >= 3)
{
mPosition = LLVector3(path_array);
if((F32(mPosition[VX]) < 0.f) ||
(mPosition[VX] > REGION_WIDTH_METERS) ||
(F32(mPosition[VY]) < 0.f) ||
(mPosition[VY] > REGION_WIDTH_METERS) ||
(F32(mPosition[VZ]) < 0.f) ||
(mPosition[VZ] > REGION_HEIGHT_METERS))
{
mType = INVALID;
return;
}
}
else
{
// if x, y and z were not fully passed in, go to the middle of the region.
// teleport will adjust the actual location to make sure you're on the ground
// and such
mPosition = LLVector3(REGION_WIDTH_METERS/2, REGION_WIDTH_METERS/2, 0);
}
}
}
}
// static
bool LLSLURL::matchPrefix(const std::string& url, const std::string& prefix)
// Create a slurl for the middle of the region
LLSLURL::LLSLURL(const std::string& grid,
const std::string& region)
{
std::string test_prefix = url.substr(0, prefix.length());
LLStringUtil::toLower(test_prefix);
return test_prefix == prefix;
mGrid = grid;
mRegion = region;
mType = LOCATION;
mPosition = LLVector3((F64)REGION_WIDTH_METERS/2, (F64)REGION_WIDTH_METERS/2, 0);
}
void LLSLURL::globalPosToXYZ(const LLVector3d& pos, S32& x, S32& y, S32& z)
// create a slurl given the position. The position will be modded with the region
// width handling global positions as well
LLSLURL::LLSLURL(const std::string& grid,
const std::string& region,
const LLVector3& position)
{
x = llround((F32)fmod(pos.mdV[VX], (F64)REGION_WIDTH_METERS));
y = llround((F32)fmod(pos.mdV[VY], (F64)REGION_WIDTH_METERS));
z = llround((F32)pos.mdV[VZ]);
mGrid = grid;
mRegion = region;
S32 x = llround( (F32)fmod( position[VX], (F32)REGION_WIDTH_METERS ) );
S32 y = llround( (F32)fmod( position[VY], (F32)REGION_WIDTH_METERS ) );
S32 z = llround( (F32)position[VZ] );
mType = LOCATION;
mPosition = LLVector3(x, y, z);
}
// create a simstring
LLSLURL::LLSLURL(const std::string& region,
const LLVector3& position)
{
*this = LLSLURL(LLGridManager::getInstance()->getGrid(),
region, position);
}
// create a slurl from a global position
LLSLURL::LLSLURL(const std::string& grid,
const std::string& region,
const LLVector3d& global_position)
{
*this = LLSLURL(grid,
region, LLVector3(global_position.mdV[VX],
global_position.mdV[VY],
global_position.mdV[VZ]));
}
// create a slurl from a global position
LLSLURL::LLSLURL(const std::string& region,
const LLVector3d& global_position)
{
*this = LLSLURL(LLGridManager::getInstance()->getGrid(),
region, global_position);
}
LLSLURL::LLSLURL(const std::string& command, const LLUUID&id, const std::string& verb)
{
mType = APP;
mAppCmd = command;
mAppPath = LLSD::emptyArray();
mAppPath.append(LLSD(id));
mAppPath.append(LLSD(verb));
}
std::string LLSLURL::getSLURLString() const
{
switch(mType)
{
case HOME_LOCATION:
return SIM_LOCATION_HOME;
case LAST_LOCATION:
return SIM_LOCATION_LAST;
case LOCATION:
{
// lookup the grid
S32 x = llround( (F32)mPosition[VX] );
S32 y = llround( (F32)mPosition[VY] );
S32 z = llround( (F32)mPosition[VZ] );
return LLGridManager::getInstance()->getSLURLBase(mGrid) +
LLURI::escape(mRegion) + llformat("/%d/%d/%d",x,y,z);
}
case APP:
{
std::ostringstream app_url;
app_url << LLGridManager::getInstance()->getAppSLURLBase() << "/" << mAppCmd;
for(LLSD::array_const_iterator i = mAppPath.beginArray();
i != mAppPath.endArray();
i++)
{
app_url << "/" << i->asString();
}
if(mAppQuery.length() > 0)
{
app_url << "?" << mAppQuery;
}
return app_url.str();
}
default:
LL_WARNS("AppInit") << "Unexpected SLURL type for SLURL string" << (int)mType << LL_ENDL;
return std::string();
}
}
std::string LLSLURL::getLoginString() const
{
std::stringstream unescaped_start;
switch(mType)
{
case LOCATION:
unescaped_start << "uri:"
<< mRegion << "&"
<< llround(mPosition[0]) << "&"
<< llround(mPosition[1]) << "&"
<< llround(mPosition[2]);
break;
case HOME_LOCATION:
unescaped_start << "home";
break;
case LAST_LOCATION:
unescaped_start << "last";
break;
default:
LL_WARNS("AppInit") << "Unexpected SLURL type for login string" << (int)mType << LL_ENDL;
break;
}
return xml_escape_string(unescaped_start.str());
}
bool LLSLURL::operator==(const LLSLURL& rhs)
{
if(rhs.mType != mType) return false;
switch(mType)
{
case LOCATION:
return ((mGrid == rhs.mGrid) &&
(mRegion == rhs.mRegion) &&
(mPosition == rhs.mPosition));
case APP:
return getSLURLString() == rhs.getSLURLString();
case HOME_LOCATION:
case LAST_LOCATION:
return true;
default:
return false;
}
}
bool LLSLURL::operator !=(const LLSLURL& rhs)
{
return !(*this == rhs);
}
std::string LLSLURL::getLocationString() const
{
return llformat("%s/%d/%d/%d",
mRegion.c_str(),
(int)llround(mPosition[0]),
(int)llround(mPosition[1]),
(int)llround(mPosition[2]));
}
std::string LLSLURL::asString() const
{
std::ostringstream result;
result << " mAppCmd:" << getAppCmd() <<
" mAppPath:" + getAppPath().asString() <<
" mAppQueryMap:" + getAppQueryMap().asString() <<
" mAppQuery: " + getAppQuery() <<
" mGrid: " + getGrid() <<
" mRegion: " + getRegion() <<
" mPosition: " <<
" mType: " << mType <<
" mPosition: " << mPosition;
return result.str();
}

View File

@ -1,10 +1,11 @@
/**
/**
* @file llslurl.h
* @brief SLURL manipulation
* @brief Handles "SLURL fragments" like Ahern/123/45 for
* startup processing, login screen, prefs, etc.
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
* Copyright (c) 2006-2010, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@ -12,13 +13,12 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* online at http://secondlife.com/developers/opensource/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* online at http://secondlife.com/developers/opensource/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
@ -29,85 +29,84 @@
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LLSLURL_H
#define LLSLURL_H
#ifndef LL_SLURL_H
#define LL_SLURL_H
#include "llstring.h"
#include <string>
// IAN BUG: where should this live?
// IAN BUG: are static utility functions right? See LLUUID.
// question of whether to have a LLSLURL object or a
// some of this was moved from LLURLDispatcher
// represents a location in a grid
/**
* SLURL manipulation
*/
class LLSLURL
{
public:
static const std::string PREFIX_SL_HELP;
static const std::string PREFIX_SL;
static const std::string PREFIX_SECONDLIFE;
static const std::string PREFIX_SLURL;
static const std::string PREFIX_SLURL_OLD;
static const std::string PREFIX_SLURL_WWW;
static const char* SLURL_HTTPS_SCHEME;
static const char* SLURL_HTTP_SCHEME;
static const char* SLURL_SL_SCHEME;
static const char* SLURL_SECONDLIFE_SCHEME;
static const char* SLURL_SECONDLIFE_PATH;
static const char* SLURL_COM;
static const char* WWW_SLURL_COM;
static const char* MAPS_SECONDLIFE_COM;
static const char* SLURL_X_GRID_LOCATION_INFO_SCHEME;
static LLSLURL START_LOCATION;
static const char* SIM_LOCATION_HOME;
static const char* SIM_LOCATION_LAST;
static const char* SLURL_APP_PATH;
static const char* SLURL_REGION_PATH;
enum SLURL_TYPE {
INVALID,
LOCATION,
HOME_LOCATION,
LAST_LOCATION,
APP,
HELP
};
LLSLURL(): mType(LAST_LOCATION) { }
LLSLURL(const std::string& slurl);
LLSLURL(const std::string& grid, const std::string& region);
LLSLURL(const std::string& region, const LLVector3& position);
LLSLURL(const std::string& grid, const std::string& region, const LLVector3& position);
LLSLURL(const std::string& grid, const std::string& region, const LLVector3d& global_position);
LLSLURL(const std::string& region, const LLVector3d& global_position);
LLSLURL(const std::string& command, const LLUUID&id, const std::string& verb);
SLURL_TYPE getType() const { return mType; }
std::string getSLURLString() const;
std::string getLoginString() const;
std::string getLocationString() const;
std::string getGrid() const { return mGrid; }
std::string getRegion() const { return mRegion; }
LLVector3 getPosition() const { return mPosition; }
std::string getAppCmd() const { return mAppCmd; }
std::string getAppQuery() const { return mAppQuery; }
LLSD getAppQueryMap() const { return mAppQueryMap; }
LLSD getAppPath() const { return mAppPath; }
bool isValid() const { return mType != INVALID; }
bool isSpatial() const { return (mType == LAST_LOCATION) || (mType == HOME_LOCATION) || (mType == LOCATION); }
bool operator==(const LLSLURL& rhs);
bool operator!=(const LLSLURL&rhs);
static const std::string APP_TOKEN;
/**
* Is this any sort of secondlife:// or sl:// URL?
*/
static bool isSLURL(const std::string& url);
/**
* Returns true if url is proven valid by regexp check from LLUrlRegistry
*/
static bool isValidSLURL(const std::string& url);
/**
* Is this a special secondlife://app/ URL?
*/
static bool isSLURLCommand(const std::string& url);
/**
* Not sure what it is.
*/
static bool isSLURLHelp(const std::string& url);
/**
* builds: http://slurl.com/secondlife/Region%20Name/x/y/z/ escaping result url.
*/
static std::string buildSLURL(const std::string& regionname, S32 x, S32 y, S32 z);
/// Build a SLURL like secondlife:///app/agent/<uuid>/inspect
static std::string buildCommand(const char* noun, const LLUUID& id, const char* verb);
/**
* builds: http://slurl.com/secondlife/Region Name/x/y/z/ without escaping result url.
*/
static std::string buildUnescapedSLURL(const std::string& regionname, S32 x, S32 y, S32 z);
/**
* builds SLURL from global position. Returns escaped or unescaped url.
* Returns escaped url by default.
*/
static std::string buildSLURLfromPosGlobal(const std::string& regionname,
const LLVector3d& global_pos,
bool escaped = true);
/**
* Strip protocol part from the URL.
*/
static std::string stripProtocol(const std::string& url);
/**
* Convert global position to X, Y Z
*/
static void globalPosToXYZ(const LLVector3d& pos, S32& x, S32& y, S32& z);
private:
static bool matchPrefix(const std::string& url, const std::string& prefix);
std::string asString() const ;
protected:
SLURL_TYPE mType;
// used for Apps and Help
std::string mAppCmd;
LLSD mAppPath;
LLSD mAppQueryMap;
std::string mAppQuery;
std::string mGrid; // reference to grid manager grid
std::string mRegion;
LLVector3 mPosition;
};
#endif
#endif // LLSLURL_H

View File

@ -59,9 +59,9 @@ LLSpeakButton::Params::Params()
void LLSpeakButton::draw()
{
// gVoiceClient is the authoritative global source of info regarding our open-mic state, we merely reflect that state.
bool openmic = gVoiceClient->getUserPTTState();
bool voiceenabled = gVoiceClient->voiceEnabled();
// LLVoiceClient::getInstance() is the authoritative global source of info regarding our open-mic state, we merely reflect that state.
bool openmic = LLVoiceClient::getInstance()->getUserPTTState();
bool voiceenabled = LLVoiceClient::getInstance()->voiceEnabled();
mSpeakBtn->setToggleState(openmic && voiceenabled);
mOutputMonitor->setIsMuted(!voiceenabled);
LLUICtrl::draw();
@ -176,11 +176,11 @@ void LLSpeakButton::setLabelVisible(bool visible)
void LLSpeakButton::onMouseDown_SpeakBtn()
{
bool down = true;
gVoiceClient->inputUserControlState(down); // this method knows/care about whether this translates into a toggle-to-talk or down-to-talk
LLVoiceClient::getInstance()->inputUserControlState(down); // this method knows/care about whether this translates into a toggle-to-talk or down-to-talk
}
void LLSpeakButton::onMouseUp_SpeakBtn()
{
bool down = false;
gVoiceClient->inputUserControlState(down);
LLVoiceClient::getInstance()->inputUserControlState(down);
}

View File

@ -299,7 +299,7 @@ LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::strin
void LLSpeakerMgr::update(BOOL resort_ok)
{
if (!gVoiceClient)
if (!LLVoiceClient::getInstance())
{
return;
}
@ -313,7 +313,7 @@ void LLSpeakerMgr::update(BOOL resort_ok)
}
// update status of all current speakers
BOOL voice_channel_active = (!mVoiceChannel && gVoiceClient->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive());
BOOL voice_channel_active = (!mVoiceChannel && LLVoiceClient::getInstance()->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive());
for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end();)
{
LLUUID speaker_id = speaker_it->first;
@ -321,21 +321,21 @@ void LLSpeakerMgr::update(BOOL resort_ok)
speaker_map_t::iterator cur_speaker_it = speaker_it++;
if (voice_channel_active && gVoiceClient->getVoiceEnabled(speaker_id))
if (voice_channel_active && LLVoiceClient::getInstance()->getVoiceEnabled(speaker_id))
{
speakerp->mSpeechVolume = gVoiceClient->getCurrentPower(speaker_id);
BOOL moderator_muted_voice = gVoiceClient->getIsModeratorMuted(speaker_id);
speakerp->mSpeechVolume = LLVoiceClient::getInstance()->getCurrentPower(speaker_id);
BOOL moderator_muted_voice = LLVoiceClient::getInstance()->getIsModeratorMuted(speaker_id);
if (moderator_muted_voice != speakerp->mModeratorMutedVoice)
{
speakerp->mModeratorMutedVoice = moderator_muted_voice;
speakerp->fireEvent(new LLSpeakerVoiceModerationEvent(speakerp));
}
if (gVoiceClient->getOnMuteList(speaker_id) || speakerp->mModeratorMutedVoice)
if (LLVoiceClient::getInstance()->getOnMuteList(speaker_id) || speakerp->mModeratorMutedVoice)
{
speakerp->mStatus = LLSpeaker::STATUS_MUTED;
}
else if (gVoiceClient->getIsSpeaking(speaker_id))
else if (LLVoiceClient::getInstance()->getIsSpeaking(speaker_id))
{
// reset inactivity expiration
if (speakerp->mStatus != LLSpeaker::STATUS_SPEAKING)
@ -417,19 +417,21 @@ void LLSpeakerMgr::update(BOOL resort_ok)
void LLSpeakerMgr::updateSpeakerList()
{
// are we bound to the currently active voice channel?
if ((!mVoiceChannel && gVoiceClient->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive()))
if ((!mVoiceChannel && LLVoiceClient::getInstance()->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive()))
{
LLVoiceClient::participantMap* participants = gVoiceClient->getParticipantList();
if(participants)
std::set<LLUUID> participants;
LLVoiceClient::getInstance()->getParticipantList(participants);
// add new participants to our list of known speakers
for (std::set<LLUUID>::iterator participant_it = participants.begin();
participant_it != participants.end();
++participant_it)
{
LLVoiceClient::participantMap::iterator participant_it;
setSpeaker(*participant_it,
LLVoiceClient::getInstance()->getDisplayName(*participant_it),
LLSpeaker::STATUS_VOICE_ACTIVE,
(LLVoiceClient::getInstance()->isParticipantAvatar(*participant_it)?LLSpeaker::SPEAKER_AGENT:LLSpeaker::SPEAKER_EXTERNAL));
// add new participants to our list of known speakers
for (participant_it = participants->begin(); participant_it != participants->end(); ++participant_it)
{
LLVoiceClient::participantState* participantp = participant_it->second;
setSpeaker(participantp->mAvatarID, participantp->mDisplayName, LLSpeaker::STATUS_VOICE_ACTIVE, (participantp->isAvatar()?LLSpeaker::SPEAKER_AGENT:LLSpeaker::SPEAKER_EXTERNAL));
}
}
}
}
@ -519,7 +521,7 @@ void LLSpeakerMgr::speakerChatted(const LLUUID& speaker_id)
BOOL LLSpeakerMgr::isVoiceActive()
{
// mVoiceChannel = NULL means current voice channel, whatever it is
return LLVoiceClient::voiceEnabled() && mVoiceChannel && mVoiceChannel->isActive();
return LLVoiceClient::getInstance()->voiceEnabled() && mVoiceChannel && mVoiceChannel->isActive();
}

View File

@ -158,7 +158,7 @@ void SpeakingIndicatorManager::registerSpeakingIndicator(const LLUUID& speaker_i
mSpeakingIndicators.insert(value_type);
speaker_ids_t speakers_uuids;
BOOL is_in_same_voice = LLVoiceClient::getInstance()->findParticipantByID(speaker_id) != NULL;
BOOL is_in_same_voice = LLVoiceClient::getInstance()->isParticipant(speaker_id);
speakers_uuids.insert(speaker_id);
switchSpeakerIndicators(speakers_uuids, is_in_same_voice);
@ -210,7 +210,7 @@ void SpeakingIndicatorManager::onChange()
LL_DEBUGS("SpeakingIndicator") << "Voice participant list was changed, updating indicators" << LL_ENDL;
speaker_ids_t speakers_uuids;
LLVoiceClient::getInstance()->getParticipantsUUIDSet(speakers_uuids);
LLVoiceClient::getInstance()->getParticipantList(speakers_uuids);
LL_DEBUGS("SpeakingIndicator") << "Switching all OFF, count: " << mSwitchedIndicatorsOn.size() << LL_ENDL;
// switch all indicators off

View File

@ -147,7 +147,7 @@
#include "lltrans.h"
#include "llui.h"
#include "llurldispatcher.h"
#include "llurlsimstring.h"
#include "llslurl.h"
#include "llurlhistory.h"
#include "llurlwhitelist.h"
#include "llvieweraudio.h"
@ -192,6 +192,7 @@
#include "llinventorybridge.h"
#include "llappearancemgr.h"
#include "llavatariconctrl.h"
#include "llvoicechannel.h"
#include "lllogin.h"
#include "llevents.h"
@ -228,11 +229,11 @@ static std::string sInitialOutfitGender; // "male" or "female"
static bool gUseCircuitCallbackCalled = false;
EStartupState LLStartUp::gStartupState = STATE_FIRST;
LLSLURL LLStartUp::sStartSLURL;
// *NOTE:Mani - to reconcile with giab changes...
static std::string gFirstname;
static std::string gLastname;
static std::string gPassword;
static LLPointer<LLCredential> gUserCredential;
static std::string gDisplayName;
static BOOL gRememberPassword = TRUE;
static U64 gFirstSimHandle = 0;
static LLHost gFirstSim;
@ -249,7 +250,6 @@ boost::scoped_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener(
void login_show();
void login_callback(S32 option, void* userdata);
bool is_hex_string(U8* str, S32 len);
void show_first_run_dialog();
bool first_run_dialog_callback(const LLSD& notification, const LLSD& response);
void set_startup_status(const F32 frac, const std::string& string, const std::string& msg);
@ -262,6 +262,9 @@ bool callback_choose_gender(const LLSD& notification, const LLSD& response);
void init_start_screen(S32 location_id);
void release_start_screen();
void reset_login();
LLSD transform_cert_args(LLPointer<LLCertificate> cert);
void general_cert_done(const LLSD& notification, const LLSD& response);
void trust_cert_done(const LLSD& notification, const LLSD& response);
void apply_udp_blacklist(const std::string& csv);
bool process_login_success_response();
void transition_back_to_login_panel(const std::string& emsg);
@ -364,7 +367,7 @@ bool idle_startup()
if ( STATE_FIRST == LLStartUp::getStartupState() )
{
gViewerWindow->showCursor();
gViewerWindow->showCursor();
gViewerWindow->getWindow()->setCursor(UI_CURSOR_WAIT);
/////////////////////////////////////////////////
@ -662,69 +665,25 @@ bool idle_startup()
//
// Log on to system
//
if (!LLStartUp::sSLURLCommand.empty())
if (gUserCredential.isNull())
{
// this might be a secondlife:///app/login URL
gLoginHandler.parseDirectLogin(LLStartUp::sSLURLCommand);
gUserCredential = gLoginHandler.initializeLoginInfo();
}
if (!gLoginHandler.getFirstName().empty()
|| !gLoginHandler.getLastName().empty()
/*|| !gLoginHandler.getWebLoginKey().isNull()*/ )
if (gUserCredential.isNull())
{
// We have at least some login information on a SLURL
gFirstname = gLoginHandler.getFirstName();
gLastname = gLoginHandler.getLastName();
LL_DEBUGS("LLStartup") << "STATE_FIRST: setting gFirstname, gLastname from gLoginHandler: '" << gFirstname << "' '" << gLastname << "'" << LL_ENDL;
// Show the login screen if we don't have everything
show_connect_box =
gFirstname.empty() || gLastname.empty();
show_connect_box = TRUE;
}
else if(gSavedSettings.getLLSD("UserLoginInfo").size() == 3)
{
LLSD cmd_line_login = gSavedSettings.getLLSD("UserLoginInfo");
gFirstname = cmd_line_login[0].asString();
gLastname = cmd_line_login[1].asString();
LL_DEBUGS("LLStartup") << "Setting gFirstname, gLastname from gSavedSettings(\"UserLoginInfo\"): '" << gFirstname << "' '" << gLastname << "'" << LL_ENDL;
LLMD5 pass((unsigned char*)cmd_line_login[2].asString().c_str());
char md5pass[33]; /* Flawfinder: ignore */
pass.hex_digest(md5pass);
gPassword = md5pass;
#ifdef USE_VIEWER_AUTH
show_connect_box = true;
#else
show_connect_box = false;
#endif
gSavedSettings.setBOOL("AutoLogin", TRUE);
}
else if (gSavedSettings.getBOOL("AutoLogin"))
else if (gSavedSettings.getBOOL("AutoLogin"))
{
gFirstname = gSavedSettings.getString("FirstName");
gLastname = gSavedSettings.getString("LastName");
LL_DEBUGS("LLStartup") << "AutoLogin: setting gFirstname, gLastname from gSavedSettings(\"First|LastName\"): '" << gFirstname << "' '" << gLastname << "'" << LL_ENDL;
gPassword = LLStartUp::loadPasswordFromDisk();
gSavedSettings.setBOOL("RememberPassword", TRUE);
#ifdef USE_VIEWER_AUTH
show_connect_box = true;
#else
show_connect_box = false;
#endif
gRememberPassword = TRUE;
gSavedSettings.setBOOL("RememberPassword", TRUE);
show_connect_box = false;
}
else
else
{
// if not automatically logging in, display login dialog
// a valid grid is selected
gFirstname = gSavedSettings.getString("FirstName");
gLastname = gSavedSettings.getString("LastName");
LL_DEBUGS("LLStartup") << "normal login: setting gFirstname, gLastname from gSavedSettings(\"First|LastName\"): '" << gFirstname << "' '" << gLastname << "'" << LL_ENDL;
gPassword = LLStartUp::loadPasswordFromDisk();
show_connect_box = true;
gRememberPassword = gSavedSettings.getBOOL("RememberPassword");
show_connect_box = TRUE;
}
// Go to the next startup state
LLStartUp::setStartupState( STATE_BROWSER_INIT );
return FALSE;
@ -756,8 +715,10 @@ bool idle_startup()
// Load all the name information out of the login view
// NOTE: Hits "Attempted getFields with no login view shown" warning, since we don't
// show the login view until login_show() is called below.
// LLPanelLogin::getFields(gFirstname, gLastname, gPassword);
if (gUserCredential.isNull())
{
gUserCredential = gLoginHandler.initializeLoginInfo();
}
if (gNoRender)
{
LL_ERRS("AppInit") << "Need to autologin or use command line with norender!" << LL_ENDL;
@ -768,8 +729,10 @@ bool idle_startup()
// Show the login dialog
login_show();
// connect dialog is already shown, so fill in the names
LLPanelLogin::setFields( gFirstname, gLastname, gPassword);
if (gUserCredential.notNull())
{
LLPanelLogin::setFields( gUserCredential, gRememberPassword);
}
LLPanelLogin::giveFocus();
gSavedSettings.setBOOL("FirstRunThisInstall", FALSE);
@ -839,39 +802,36 @@ bool idle_startup()
// DEV-42215: Make sure they're not empty -- gFirstname and gLastname
// might already have been set from gSavedSettings, and it's too bad
// to overwrite valid values with empty strings.
if (! gLoginHandler.getFirstName().empty() && ! gLoginHandler.getLastName().empty())
{
gFirstname = gLoginHandler.getFirstName();
gLastname = gLoginHandler.getLastName();
LL_DEBUGS("LLStartup") << "STATE_LOGIN_CLEANUP: setting gFirstname, gLastname from gLoginHandler: '" << gFirstname << "' '" << gLastname << "'" << LL_ENDL;
}
if (show_connect_box)
{
// TODO if not use viewer auth
// Load all the name information out of the login view
LLPanelLogin::getFields(&gFirstname, &gLastname, &gPassword);
LLPanelLogin::getFields(gUserCredential, gRememberPassword);
// end TODO
// HACK: Try to make not jump on login
gKeyboard->resetKeys();
}
if (!gFirstname.empty() && !gLastname.empty())
{
gSavedSettings.setString("FirstName", gFirstname);
gSavedSettings.setString("LastName", gLastname);
LL_INFOS("AppInit") << "Attempting login as: " << gFirstname << " " << gLastname << LL_ENDL;
gDebugInfo["LoginName"] = gFirstname + " " + gLastname;
// save the credentials
std::string userid = "unknown";
if(gUserCredential.notNull())
{
userid = gUserCredential->userID();
gSecAPIHandler->saveCredential(gUserCredential, gRememberPassword);
}
gSavedSettings.setBOOL("RememberPassword", gRememberPassword);
LL_INFOS("AppInit") << "Attempting login as: " << userid << LL_ENDL;
gDebugInfo["LoginName"] = userid;
// create necessary directories
// *FIX: these mkdir's should error check
gDirUtilp->setLindenUserDir(gFirstname, gLastname);
gDirUtilp->setLindenUserDir(userid);
LLFile::mkdir(gDirUtilp->getLindenUserDir());
// Set PerAccountSettingsFile to the default value.
std::string per_account_settings_file = LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount");
gSavedSettings.setString("PerAccountSettingsFile",
gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT,
LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount")));
@ -901,9 +861,8 @@ bool idle_startup()
{
gDirUtilp->setChatLogsDir(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
}
gDirUtilp->setPerAccountChatLogsDir(userid);
gDirUtilp->setPerAccountChatLogsDir(gFirstname, gLastname);
LLFile::mkdir(gDirUtilp->getChatLogsDir());
LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir());
@ -924,11 +883,7 @@ bool idle_startup()
if (show_connect_box)
{
std::string location;
LLPanelLogin::getLocation( location );
LLURLSimString::setString( location );
// END TODO
LLSLURL slurl;
LLPanelLogin::closePanel();
}
@ -952,26 +907,21 @@ bool idle_startup()
// their last location, or some URL "-url //sim/x/y[/z]"
// All accounts have both a home and a last location, and we don't support
// more locations than that. Choose the appropriate one. JC
if (LLURLSimString::parse())
{
// a startup URL was specified
agent_location_id = START_LOCATION_ID_URL;
// doesn't really matter what location_which is, since
// gAgentStartLookAt will be overwritten when the
// UserLoginLocationReply arrives
location_which = START_LOCATION_ID_LAST;
}
else if (gSavedSettings.getString("LoginLocation") == "last" )
{
agent_location_id = START_LOCATION_ID_LAST; // last location
location_which = START_LOCATION_ID_LAST;
}
else
{
agent_location_id = START_LOCATION_ID_HOME; // home
location_which = START_LOCATION_ID_HOME;
}
switch (LLStartUp::getStartSLURL().getType())
{
case LLSLURL::LOCATION:
agent_location_id = START_LOCATION_ID_URL;
location_which = START_LOCATION_ID_LAST;
break;
case LLSLURL::LAST_LOCATION:
agent_location_id = START_LOCATION_ID_LAST;
location_which = START_LOCATION_ID_LAST;
break;
default:
agent_location_id = START_LOCATION_ID_HOME;
location_which = START_LOCATION_ID_HOME;
break;
}
gViewerWindow->getWindow()->setCursor(UI_CURSOR_WAIT);
@ -998,7 +948,7 @@ bool idle_startup()
if(STATE_LOGIN_AUTH_INIT == LLStartUp::getStartupState())
{
gDebugInfo["GridName"] = LLViewerLogin::getInstance()->getGridLabel();
gDebugInfo["GridName"] = LLGridManager::getInstance()->getGridLabel();
// Update progress status and the display loop.
auth_desc = LLTrans::getString("LoginInProgress");
@ -1022,11 +972,7 @@ bool idle_startup()
// This call to LLLoginInstance::connect() starts the
// authentication process.
LLSD credentials;
credentials["first"] = gFirstname;
credentials["last"] = gLastname;
credentials["passwd"] = gPassword;
login->connect(credentials);
login->connect(gUserCredential);
LLStartUp::setStartupState( STATE_LOGIN_CURL_UNSTUCK );
return FALSE;
@ -1051,10 +997,11 @@ bool idle_startup()
{
LL_INFOS("LLStartup") << "Login failed, LLLoginInstance::getResponse(): "
<< LLLoginInstance::getInstance()->getResponse() << LL_ENDL;
LLSD response = LLLoginInstance::getInstance()->getResponse();
// Still have error conditions that may need some
// sort of handling.
std::string reason_response = LLLoginInstance::getInstance()->getResponse("reason");
std::string message_response = LLLoginInstance::getInstance()->getResponse("message");
std::string reason_response = response["reason"];
std::string message_response = response["message"];
if(!message_response.empty())
{
@ -1074,8 +1021,8 @@ bool idle_startup()
if(reason_response == "key")
{
// Couldn't login because user/password is wrong
// Clear the password
gPassword = "";
// Clear the credential
gUserCredential->clearAuthenticator();
}
if(reason_response == "update"
@ -1088,18 +1035,65 @@ bool idle_startup()
LLLoginInstance::getInstance()->disconnect();
LLAppViewer::instance()->forceQuit();
}
else
else
{
// Don't pop up a notification in the TOS case because
// LLFloaterTOS::onCancel() already scolded the user.
if (reason_response != "tos")
if (reason_response != "tos")
{
LLSD args;
args["ERROR_MESSAGE"] = emsg.str();
LL_INFOS("LLStartup") << "Notification: " << args << LL_ENDL;
LLNotificationsUtil::add("ErrorMessage", args, LLSD(), login_alert_done);
}
// Don't pop up a notification in the TOS case because
// LLFloaterTOS::onCancel() already scolded the user.
std::string error_code;
if(response.has("errorcode"))
{
error_code = response["errorcode"].asString();
}
if ((reason_response == "CURLError") &&
(error_code == "SSL_CACERT" || error_code == "SSL_PEER_CERTIFICATE") &&
response.has("certificate"))
{
// This was a certificate error, so grab the certificate
// and throw up the appropriate dialog.
LLPointer<LLCertificate> certificate = gSecAPIHandler->getCertificate(response["certificate"]);
if(certificate)
{
LLSD args = transform_cert_args(certificate);
if(error_code == "SSL_CACERT")
{
// if we are handling an untrusted CA, throw up the dialog
// with the 'trust this CA' button.
LLNotificationsUtil::add("TrustCertificateError", args, response,
trust_cert_done);
show_connect_box = true;
}
else
{
// the certificate exception returns a unique string for each type of exception.
// we grab this string via the LLUserAuth object, and use that to grab the localized
// string.
args["REASON"] = LLTrans::getString(message_response);
LLNotificationsUtil::add("GeneralCertificateError", args, response,
general_cert_done);
reset_login();
gSavedSettings.setBOOL("AutoLogin", FALSE);
show_connect_box = true;
}
}
}
else
{
// This wasn't a certificate error, so throw up the normal
// notificatioin message.
LLSD args;
args["ERROR_MESSAGE"] = emsg.str();
LL_INFOS("LLStartup") << "Notification: " << args << LL_ENDL;
LLNotificationsUtil::add("ErrorMessage", args, LLSD(), login_alert_done);
}
}
//setup map of datetime strings to codes and slt & local time offset from utc
// *TODO: Does this need to be here?
LLStringOps::setupDatetimeInfo (false);
@ -1112,7 +1106,12 @@ bool idle_startup()
if(process_login_success_response())
{
// Pass the user information to the voice chat server interface.
gVoiceClient->userAuthorized(gFirstname, gLastname, gAgentID);
LLVoiceClient::getInstance()->userAuthorized(gUserCredential->userID(), gAgentID);
// create the default proximal channel
LLVoiceChannel::initClass();
// update the voice settings
LLVoiceClient::getInstance()->updateSettings();
LLGridManager::getInstance()->setFavorite();
LLStartUp::setStartupState( STATE_WORLD_INIT);
}
else
@ -1123,6 +1122,7 @@ bool idle_startup()
LLNotificationsUtil::add("ErrorMessage", args, LLSD(), login_alert_done);
transition_back_to_login_panel(emsg.str());
show_connect_box = true;
return FALSE;
}
}
return FALSE;
@ -1807,9 +1807,12 @@ bool idle_startup()
// thus, do not show this alert.
if (!gAgent.isFirstLogin())
{
bool url_ok = LLURLSimString::sInstance.parse();
if ((url_ok && gAgentStartLocation == "url") ||
(!url_ok && ((gAgentStartLocation == gSavedSettings.getString("LoginLocation")))))
llinfos << "gAgentStartLocation : " << gAgentStartLocation << llendl;
LLSLURL start_slurl = LLStartUp::getStartSLURL();
if (((start_slurl.getType() == LLSLURL::LOCATION) && (gAgentStartLocation == "url")) ||
((start_slurl.getType() == LLSLURL::LAST_LOCATION) && (gAgentStartLocation == "last")) ||
((start_slurl.getType() == LLSLURL::HOME_LOCATION) && (gAgentStartLocation == "home")))
{
// Start location is OK
// Disabled code to restore camera location and focus if logging in to default location
@ -1831,17 +1834,23 @@ bool idle_startup()
else
{
std::string msg;
if (url_ok)
switch(start_slurl.getType())
{
msg = "AvatarMovedDesired";
}
else if (gSavedSettings.getString("LoginLocation") == "home")
{
msg = "AvatarMovedHome";
}
else
{
msg = "AvatarMovedLast";
case LLSLURL::LOCATION:
{
msg = "AvatarMovedDesired";
break;
}
case LLSLURL::HOME_LOCATION:
{
msg = "AvatarMovedHome";
break;
}
default:
{
msg = "AvatarMovedLast";
}
}
LLNotificationsUtil::add(msg);
}
@ -2057,20 +2066,9 @@ void login_show()
#endif
LLPanelLogin::show( gViewerWindow->getWindowRectScaled(),
bUseDebugLogin,
bUseDebugLogin || gSavedSettings.getBOOL("SecondLifeEnterprise"),
login_callback, NULL );
// UI textures have been previously loaded in doPreloadImages()
LL_DEBUGS("AppInit") << "Setting Servers" << LL_ENDL;
LLPanelLogin::addServer(LLViewerLogin::getInstance()->getGridLabel(), LLViewerLogin::getInstance()->getGridChoice());
LLViewerLogin* vl = LLViewerLogin::getInstance();
for(int grid_index = GRID_INFO_ADITI; grid_index < GRID_INFO_OTHER; ++grid_index)
{
LLPanelLogin::addServer(vl->getKnownGridLabel((EGridInfo)grid_index), grid_index);
}
}
// Callback for when login screen is closed. Option 0 = connect, option 1 = quit.
@ -2086,9 +2084,6 @@ void login_callback(S32 option, void *userdata)
}
else if (QUIT_OPTION == option) // *TODO: THIS CODE SEEMS TO BE UNREACHABLE!!!!! login_callback is never called with option equal to QUIT_OPTION
{
// Make sure we don't save the password if the user is trying to clear it.
std::string first, last, password;
LLPanelLogin::getFields(&first, &last, &password);
if (!gSavedSettings.getBOOL("RememberPassword"))
{
// turn off the setting and write out to disk
@ -2111,142 +2106,6 @@ void login_callback(S32 option, void *userdata)
}
}
// static
std::string LLStartUp::loadPasswordFromDisk()
{
// Only load password if we also intend to save it (otherwise the user
// wonders what we're doing behind his back). JC
BOOL remember_password = gSavedSettings.getBOOL("RememberPassword");
if (!remember_password)
{
return std::string("");
}
std::string hashed_password("");
// Look for legacy "marker" password from settings.ini
hashed_password = gSavedSettings.getString("Marker");
if (!hashed_password.empty())
{
// Stomp the Marker entry.
gSavedSettings.setString("Marker", "");
// Return that password.
return hashed_password;
}
std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
"password.dat");
LLFILE* fp = LLFile::fopen(filepath, "rb"); /* Flawfinder: ignore */
if (!fp)
{
return hashed_password;
}
// UUID is 16 bytes, written into ASCII is 32 characters
// without trailing \0
const S32 HASHED_LENGTH = 32;
U8 buffer[HASHED_LENGTH+1];
if (1 != fread(buffer, HASHED_LENGTH, 1, fp))
{
return hashed_password;
}
fclose(fp);
// Decipher with MAC address
LLXORCipher cipher(gMACAddress, 6);
cipher.decrypt(buffer, HASHED_LENGTH);
buffer[HASHED_LENGTH] = '\0';
// Check to see if the mac address generated a bad hashed
// password. It should be a hex-string or else the mac adress has
// changed. This is a security feature to make sure that if you
// get someone's password.dat file, you cannot hack their account.
if(is_hex_string(buffer, HASHED_LENGTH))
{
hashed_password.assign((char*)buffer);
}
return hashed_password;
}
// static
void LLStartUp::savePasswordToDisk(const std::string& hashed_password)
{
std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
"password.dat");
LLFILE* fp = LLFile::fopen(filepath, "wb"); /* Flawfinder: ignore */
if (!fp)
{
return;
}
// Encipher with MAC address
const S32 HASHED_LENGTH = 32;
U8 buffer[HASHED_LENGTH+1];
LLStringUtil::copy((char*)buffer, hashed_password.c_str(), HASHED_LENGTH+1);
LLXORCipher cipher(gMACAddress, 6);
cipher.encrypt(buffer, HASHED_LENGTH);
if (fwrite(buffer, HASHED_LENGTH, 1, fp) != 1)
{
LL_WARNS("AppInit") << "Short write" << LL_ENDL;
}
fclose(fp);
}
// static
void LLStartUp::deletePasswordFromDisk()
{
std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
"password.dat");
LLFile::remove(filepath);
}
bool is_hex_string(U8* str, S32 len)
{
bool rv = true;
U8* c = str;
while(rv && len--)
{
switch(*c)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
++c;
break;
default:
rv = false;
break;
}
}
return rv;
}
void show_first_run_dialog()
{
LLNotificationsUtil::add("FirstRun", LLSD(), LLSD(), first_run_dialog_callback);
@ -2288,7 +2147,7 @@ bool login_alert_status(const LLSD& notification, const LLSD& response)
// break;
case 2: // Teleport
// Restart the login process, starting at our home locaton
LLURLSimString::setString("home");
LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME));
LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
break;
default:
@ -2508,30 +2367,35 @@ void asset_callback_nothing(LLVFS*, const LLUUID&, LLAssetType::EType, void*, S3
const std::string COMMON_GESTURES_FOLDER = "Common Gestures";
const std::string MALE_GESTURES_FOLDER = "Male Gestures";
const std::string FEMALE_GESTURES_FOLDER = "Female Gestures";
const std::string MALE_OUTFIT_FOLDER = "Male Shape & Outfit";
const std::string FEMALE_OUTFIT_FOLDER = "Female Shape & Outfit";
const S32 OPT_CLOSED_WINDOW = -1;
const S32 OPT_MALE = 0;
const S32 OPT_FEMALE = 1;
const S32 OPT_TRUST_CERT = 0;
const S32 OPT_CANCEL_TRUST = 1;
bool callback_choose_gender(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
{
// These defaults are returned from the server on login. They are set in login.xml.
// If no default is returned from the server, they are retrieved from settings.xml.
S32 option = LLNotification::getSelectedOption(notification, response);
switch(option)
{
case OPT_MALE:
LLStartUp::loadInitialOutfit( MALE_OUTFIT_FOLDER, "male" );
break;
case OPT_FEMALE:
case OPT_CLOSED_WINDOW:
default:
LLStartUp::loadInitialOutfit( FEMALE_OUTFIT_FOLDER, "female" );
break;
case OPT_MALE:
LLStartUp::loadInitialOutfit( gSavedSettings.getString("DefaultMaleAvatar"), "male" );
break;
case OPT_FEMALE:
case OPT_CLOSED_WINDOW:
default:
LLStartUp::loadInitialOutfit( gSavedSettings.getString("DefaultFemaleAvatar"), "female" );
break;
}
return false;
}
void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
const std::string& gender_name )
{
@ -2746,7 +2610,6 @@ void reset_login()
//---------------------------------------------------------------------------
std::string LLStartUp::sSLURLCommand;
bool LLStartUp::canGoFullscreen()
{
@ -2779,41 +2642,145 @@ void LLStartUp::fontInit()
bool LLStartUp::dispatchURL()
{
// ok, if we've gotten this far and have a startup URL
if (!sSLURLCommand.empty())
if (!getStartSLURL().isValid())
{
LLMediaCtrl* web = NULL;
const bool trusted_browser = false;
LLURLDispatcher::dispatch(sSLURLCommand, web, trusted_browser);
return false;
}
else if (LLURLSimString::parse())
{
if(getStartSLURL().getType() != LLSLURL::APP)
{
// If we started with a location, but we're already
// at that location, don't pop dialogs open.
LLVector3 pos = gAgent.getPositionAgent();
F32 dx = pos.mV[VX] - (F32)LLURLSimString::sInstance.mX;
F32 dy = pos.mV[VY] - (F32)LLURLSimString::sInstance.mY;
LLVector3 slurlpos = getStartSLURL().getPosition();
F32 dx = pos.mV[VX] - slurlpos.mV[VX];
F32 dy = pos.mV[VY] - slurlpos.mV[VY];
const F32 SLOP = 2.f; // meters
if( LLURLSimString::sInstance.mSimName != gAgent.getRegion()->getName()
if( getStartSLURL().getRegion() != gAgent.getRegion()->getName()
|| (dx*dx > SLOP*SLOP)
|| (dy*dy > SLOP*SLOP) )
{
std::string url = LLURLSimString::getURL();
LLMediaCtrl* web = NULL;
const bool trusted_browser = false;
LLURLDispatcher::dispatch(url, web, trusted_browser);
LLURLDispatcher::dispatch(getStartSLURL().getSLURLString(),
NULL, false);
}
return true;
}
return false;
}
void LLStartUp::setStartSLURL(const LLSLURL& slurl)
{
sStartSLURL = slurl;
switch(slurl.getType())
{
case LLSLURL::HOME_LOCATION:
{
gSavedSettings.setString("LoginLocation", LLSLURL::SIM_LOCATION_HOME);
break;
}
case LLSLURL::LAST_LOCATION:
{
gSavedSettings.setString("LoginLocation", LLSLURL::SIM_LOCATION_LAST);
break;
}
default:
LLGridManager::getInstance()->setGridChoice(slurl.getGrid());
break;
}
}
bool login_alert_done(const LLSD& notification, const LLSD& response)
{
LLPanelLogin::giveFocus();
return false;
}
// parse the certificate information into args for the
// certificate notifications
LLSD transform_cert_args(LLPointer<LLCertificate> cert)
{
LLSD args = LLSD::emptyMap();
std::string value;
LLSD cert_info = cert->getLLSD();
// convert all of the elements in the cert into
// args for the xml dialog, so we have flexability to
// display various parts of the cert by only modifying
// the cert alert dialog xml.
for(LLSD::map_iterator iter = cert_info.beginMap();
iter != cert_info.endMap();
iter++)
{
// key usage and extended key usage
// are actually arrays, and we want to format them as comma separated
// strings, so special case those.
LLSDSerialize::toXML(cert_info[iter->first], std::cout);
if((iter->first== std::string(CERT_KEY_USAGE)) |
(iter->first == std::string(CERT_EXTENDED_KEY_USAGE)))
{
value = "";
LLSD usage = cert_info[iter->first];
for (LLSD::array_iterator usage_iter = usage.beginArray();
usage_iter != usage.endArray();
usage_iter++)
{
if(usage_iter != usage.beginArray())
{
value += ", ";
}
value += (*usage_iter).asString();
}
}
else
{
value = iter->second.asString();
}
std::string name = iter->first;
std::transform(name.begin(), name.end(), name.begin(),
(int(*)(int))toupper);
args[name.c_str()] = value;
}
return args;
}
// when we handle a cert error, give focus back to the login panel
void general_cert_done(const LLSD& notification, const LLSD& response)
{
LLStartUp::setStartupState( STATE_LOGIN_SHOW );
LLPanelLogin::giveFocus();
}
// check to see if the user wants to trust the cert.
// if they do, add it to the cert store and
void trust_cert_done(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotification::getSelectedOption(notification, response);
switch(option)
{
case OPT_TRUST_CERT:
{
LLPointer<LLCertificate> cert = gSecAPIHandler->getCertificate(notification["payload"]["certificate"]);
LLPointer<LLCertificateStore> store = gSecAPIHandler->getCertificateStore(gSavedSettings.getString("CertStore"));
store->add(cert);
store->save();
LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
break;
}
case OPT_CANCEL_TRUST:
reset_login();
gSavedSettings.setBOOL("AutoLogin", FALSE);
LLStartUp::setStartupState( STATE_LOGIN_SHOW );
default:
LLPanelLogin::giveFocus();
break;
}
}
void apply_udp_blacklist(const std::string& csv)
{
@ -2861,33 +2828,45 @@ bool process_login_success_response()
text = response["secure_session_id"].asString();
if(!text.empty()) gAgent.mSecureSessionID.set(text);
text = response["first_name"].asString();
if(!text.empty())
{
// Remove quotes from string. Login.cgi sends these to force
// names that look like numbers into strings.
gFirstname.assign(text);
LLStringUtil::replaceChar(gFirstname, '"', ' ');
LLStringUtil::trim(gFirstname);
}
text = response["last_name"].asString();
if(!text.empty())
{
gLastname.assign(text);
}
gSavedSettings.setString("FirstName", gFirstname);
gSavedSettings.setString("LastName", gLastname);
// if the response contains a display name, use that,
// otherwise if the response contains a first and/or last name,
// use those. Otherwise use the credential identifier
if (gSavedSettings.getBOOL("RememberPassword"))
gDisplayName = "";
if (response.has("display_name"))
{
// Successful login means the password is valid, so save it.
LLStartUp::savePasswordToDisk(gPassword);
gDisplayName.assign(response["display_name"].asString());
if(!gDisplayName.empty())
{
// Remove quotes from string. Login.cgi sends these to force
// names that look like numbers into strings.
LLStringUtil::replaceChar(gDisplayName, '"', ' ');
LLStringUtil::trim(gDisplayName);
}
}
else
if(gDisplayName.empty())
{
// Don't leave password from previous session sitting around
// during this login session.
LLStartUp::deletePasswordFromDisk();
if(response.has("first_name"))
{
gDisplayName.assign(response["first_name"].asString());
LLStringUtil::replaceChar(gDisplayName, '"', ' ');
LLStringUtil::trim(gDisplayName);
}
if(response.has("last_name"))
{
text.assign(response["last_name"].asString());
LLStringUtil::replaceChar(text, '"', ' ');
LLStringUtil::trim(text);
if(!gDisplayName.empty())
{
gDisplayName += " ";
}
gDisplayName += text;
}
}
if(gDisplayName.empty())
{
gDisplayName.assign(gUserCredential->asString());
}
// this is their actual ability to access content
@ -2981,7 +2960,7 @@ bool process_login_success_response()
// replace the default help URL format
gSavedSettings.setString("HelpURLFormat",text);
// don't fall back to Nebraska's pre-connection static help
// don't fall back to Standalone's pre-connection static help
gSavedSettings.setBOOL("HelpUseLocal", false);
}
@ -3043,7 +3022,44 @@ bool process_login_success_response()
//setup map of datetime strings to codes and slt & local time offset from utc
LLStringOps::setupDatetimeInfo(pacific_daylight_time);
}
static const char* CONFIG_OPTIONS[] = {"voice-config", "newuser-config"};
for (int i = 0; i < sizeof(CONFIG_OPTIONS)/sizeof(CONFIG_OPTIONS[0]); i++)
{
LLSD options = response[CONFIG_OPTIONS[i]];
if (!options.isArray() && (options.size() < 1) && !options[0].isMap())
{
continue;
}
llinfos << "config option " << CONFIG_OPTIONS[i][0] << "response " << options << llendl;
for(LLSD::map_iterator option_it = options[0].beginMap();
option_it != options[0].endMap();
option_it++)
{
llinfos << "trying option " << option_it->first << llendl;
LLPointer<LLControlVariable> control = gSavedSettings.getControl(option_it->first);
if(control.notNull())
{
if(control->isType(TYPE_BOOLEAN))
{
llinfos << "Setting BOOL from login " << option_it->first << " " << option_it->second << llendl;
gSavedSettings.setBOOL(option_it->first, !((option_it->second == "F") ||
(option_it->second == "false") ||
(!option_it->second)));
}
else if (control->isType(TYPE_STRING))
{
llinfos << "Setting String from login " << option_it->first << " " << option_it->second << llendl;
gSavedSettings.setString(option_it->first, option_it->second);
}
// we don't support other types now
}
}
}
LLSD initial_outfit = response["initial-outfit"][0];
if(initial_outfit.size())
{
@ -3097,7 +3113,7 @@ bool process_login_success_response()
bool success = false;
// JC: gesture loading done below, when we have an asset system
// in place. Don't delete/clear user_credentials until then.
// in place. Don't delete/clear gUserCredentials until then.
if(gAgentID.notNull()
&& gAgentSessionID.notNull()
&& gMessageSystem->mOurCircuitCode

View File

@ -38,6 +38,7 @@
class LLViewerTexture ;
class LLEventPump;
class LLStartupListener;
class LLSLURL;
// functions
bool idle_startup();
@ -101,26 +102,18 @@ public:
static void loadInitialOutfit( const std::string& outfit_folder_name,
const std::string& gender_name );
// Load MD5 of user's password from local disk file.
static std::string loadPasswordFromDisk();
// Record MD5 of user's password for subsequent login.
static void savePasswordToDisk(const std::string& hashed_password);
// Delete the saved password local disk file.
static void deletePasswordFromDisk();
static bool dispatchURL();
// if we have a SLURL or sim string ("Ahern/123/45") that started
// the viewer, dispatch it
static std::string sSLURLCommand;
// *HACK: On startup, if we were passed a secondlife://app/do/foo
// command URL, store it for later processing.
static void postStartupState();
static void setStartSLURL(const LLSLURL& slurl);
static LLSLURL& getStartSLURL() { return sStartSLURL; }
private:
static LLSLURL sStartSLURL;
static std::string startupStateToString(EStartupState state);
static EStartupState gStartupState; // Do not set directly, use LLStartup::setStartupState
static boost::scoped_ptr<LLEventPump> sStateWatcher;

View File

@ -51,7 +51,7 @@ const LLStyle::Params &LLStyleMap::lookupAgent(const LLUUID &source)
style_params.color.control = "HTMLLinkColor";
style_params.readonly_color.control = "HTMLLinkColor";
style_params.link_href =
LLSLURL::buildCommand("agent", source, "inspect");
LLSLURL("agent", source, "inspect").getSLURLString();
}
else
{

View File

@ -286,5 +286,11 @@ const char * LLURL::getFullPath()
return(sReturnString);
}
const char * LLURL::getAuthority()
{
strncpy(LLURL::sReturnString,mAuthority, LL_MAX_PATH -1); /* Flawfinder: ignore */
LLURL::sReturnString[LL_MAX_PATH -1] = '\0';
return(sReturnString);
}
char LLURL::sReturnString[LL_MAX_PATH] = "";

View File

@ -79,6 +79,7 @@ public:
virtual const char *getFQURL() const;
virtual const char *getFullPath();
virtual const char *getAuthority();
virtual const char *updateRelativePath(const LLURL &url);

View File

@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
* Copyright (c) 2010, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@ -12,13 +12,12 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* online at http://secondlife.com/developers/opensource/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* online at http://secondlife.com/developers/opensource/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
@ -45,10 +44,10 @@
#include "llsidetray.h"
#include "llslurl.h"
#include "llstartup.h" // gStartupState
#include "llurlsimstring.h"
#include "llweb.h"
#include "llworldmapmessage.h"
#include "llurldispatcherlistener.h"
#include "llviewernetwork.h"
// library includes
#include "llnotificationsutil.h"
@ -59,25 +58,25 @@ static LLURLDispatcherListener sURLDispatcherListener;
class LLURLDispatcherImpl
{
public:
static bool dispatch(const std::string& url,
static bool dispatch(const LLSLURL& slurl,
LLMediaCtrl* web,
bool trusted_browser);
// returns true if handled or explicitly blocked.
static bool dispatchRightClick(const std::string& url);
static bool dispatchRightClick(const LLSLURL& slurl);
private:
static bool dispatchCore(const std::string& url,
static bool dispatchCore(const LLSLURL& slurl,
bool right_mouse,
LLMediaCtrl* web,
bool trusted_browser);
// handles both left and right click
static bool dispatchHelp(const std::string& url, bool right_mouse);
static bool dispatchHelp(const LLSLURL& slurl, bool right_mouse);
// Handles sl://app.floater.html.help by showing Help floater.
// Returns true if handled.
static bool dispatchApp(const std::string& url,
static bool dispatchApp(const LLSLURL& slurl,
bool right_mouse,
LLMediaCtrl* web,
bool trusted_browser);
@ -85,16 +84,16 @@ private:
// by showing panel in Search floater.
// Returns true if handled or explicitly blocked.
static bool dispatchRegion(const std::string& url, bool right_mouse);
static bool dispatchRegion(const LLSLURL& slurl, bool right_mouse);
// handles secondlife://Ahern/123/45/67/
// Returns true if handled.
static void regionHandleCallback(U64 handle, const std::string& url,
static void regionHandleCallback(U64 handle, const LLSLURL& slurl,
const LLUUID& snapshot_id, bool teleport);
// Called by LLWorldMap when a location has been resolved to a
// region name
static void regionNameCallback(U64 handle, const std::string& url,
static void regionNameCallback(U64 handle, const LLSLURL& slurl,
const LLUUID& snapshot_id, bool teleport);
// Called by LLWorldMap when a region name has been resolved to a
// location in-world, used by places-panel display.
@ -103,65 +102,57 @@ private:
};
// static
bool LLURLDispatcherImpl::dispatchCore(const std::string& url,
bool LLURLDispatcherImpl::dispatchCore(const LLSLURL& slurl,
bool right_mouse,
LLMediaCtrl* web,
bool trusted_browser)
{
if (url.empty()) return false;
//if (dispatchHelp(url, right_mouse)) return true;
if (dispatchApp(url, right_mouse, web, trusted_browser)) return true;
if (dispatchRegion(url, right_mouse)) return true;
//if (dispatchHelp(slurl, right_mouse)) return true;
switch(slurl.getType())
{
case LLSLURL::APP:
return dispatchApp(slurl, right_mouse, web, trusted_browser);
case LLSLURL::LOCATION:
return dispatchRegion(slurl, right_mouse);
default:
return false;
}
/*
// Inform the user we can't handle this
std::map<std::string, std::string> args;
args["SLURL"] = url;
args["SLURL"] = slurl;
r;
*/
return false;
}
// static
bool LLURLDispatcherImpl::dispatch(const std::string& url,
bool LLURLDispatcherImpl::dispatch(const LLSLURL& slurl,
LLMediaCtrl* web,
bool trusted_browser)
{
llinfos << "url: " << url << llendl;
const bool right_click = false;
return dispatchCore(url, right_click, web, trusted_browser);
return dispatchCore(slurl, right_click, web, trusted_browser);
}
// static
bool LLURLDispatcherImpl::dispatchRightClick(const std::string& url)
bool LLURLDispatcherImpl::dispatchRightClick(const LLSLURL& slurl)
{
llinfos << "url: " << url << llendl;
const bool right_click = true;
LLMediaCtrl* web = NULL;
const bool trusted_browser = false;
return dispatchCore(url, right_click, web, trusted_browser);
return dispatchCore(slurl, right_click, web, trusted_browser);
}
// static
bool LLURLDispatcherImpl::dispatchApp(const std::string& url,
bool LLURLDispatcherImpl::dispatchApp(const LLSLURL& slurl,
bool right_mouse,
LLMediaCtrl* web,
bool trusted_browser)
{
// ensure the URL is in the secondlife:///app/ format
if (!LLSLURL::isSLURLCommand(url))
{
return false;
}
LLURI uri(url);
LLSD pathArray = uri.pathArray();
pathArray.erase(0); // erase "app"
std::string cmd = pathArray.get(0);
pathArray.erase(0); // erase "cmd"
llinfos << "cmd: " << slurl.getAppCmd() << " path: " << slurl.getAppPath() << " query: " << slurl.getAppQuery() << llendl;
bool handled = LLCommandDispatcher::dispatch(
cmd, pathArray, uri.queryMap(), web, trusted_browser);
slurl.getAppCmd(), slurl.getAppPath(), slurl.getAppQuery(), web, trusted_browser);
// alert if we didn't handle this secondlife:///app/ SLURL
// (but still return true because it is a valid app SLURL)
@ -173,81 +164,72 @@ bool LLURLDispatcherImpl::dispatchApp(const std::string& url,
}
// static
bool LLURLDispatcherImpl::dispatchRegion(const std::string& url, bool right_mouse)
bool LLURLDispatcherImpl::dispatchRegion(const LLSLURL& slurl, bool right_mouse)
{
if (!LLSLURL::isSLURL(url))
{
return false;
}
std::string sim_string = LLSLURL::stripProtocol(url);
std::string region_name;
S32 x = 128;
S32 y = 128;
S32 z = 0;
if (! LLURLSimString::parse(sim_string, &region_name, &x, &y, &z))
{
return false;
}
if(slurl.getType() != LLSLURL::LOCATION)
{
return false;
}
// Before we're logged in, need to update the startup screen
// to tell the user where they are going.
if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP)
{
// Parse it and stash in globals, it will be dispatched in
// STATE_CLEANUP.
LLURLSimString::setString(url);
// We're at the login screen, so make sure user can see
// the login location box to know where they are going.
LLPanelLogin::refreshLocation( true );
LLPanelLogin::setLocation(slurl);
return true;
}
// LLFloaterURLDisplay functionality moved to LLPanelPlaces in Side Tray.
//LLFloaterURLDisplay* url_displayp = LLFloaterReg::getTypedInstance<LLFloaterURLDisplay>("preview_url",LLSD());
//if(url_displayp) url_displayp->setName(region_name);
//LLFloaterURLDisplay* slurl_displayp = LLFloaterReg::getTypedInstance<LLFloaterURLDisplay>("preview_url",LLSD());
//if(slurl_displayp) slurl_displayp->setName(region_name);
// Request a region handle by name
LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name,
LLURLDispatcherImpl::regionNameCallback,
url,
false); // don't teleport
LLWorldMapMessage::getInstance()->sendNamedRegionRequest(slurl.getRegion(),
LLURLDispatcherImpl::regionNameCallback,
slurl.getSLURLString(),
false); // don't teleport
return true;
}
/*static*/
void LLURLDispatcherImpl::regionNameCallback(U64 region_handle, const std::string& url, const LLUUID& snapshot_id, bool teleport)
void LLURLDispatcherImpl::regionNameCallback(U64 region_handle, const LLSLURL& slurl, const LLUUID& snapshot_id, bool teleport)
{
std::string sim_string = LLSLURL::stripProtocol(url);
std::string region_name;
S32 x = 128;
S32 y = 128;
S32 z = 0;
if (LLURLSimString::parse(sim_string, &region_name, &x, &y, &z))
{
regionHandleCallback(region_handle, url, snapshot_id, teleport);
}
if(slurl.getType() == LLSLURL::LOCATION)
{
regionHandleCallback(region_handle, slurl, snapshot_id, teleport);
}
}
/* static */
void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const std::string& url, const LLUUID& snapshot_id, bool teleport)
void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const LLSLURL& slurl, const LLUUID& snapshot_id, bool teleport)
{
std::string sim_string = LLSLURL::stripProtocol(url);
std::string region_name;
S32 x = 128;
S32 y = 128;
S32 z = 0;
LLURLSimString::parse(sim_string, &region_name, &x, &y, &z);
LLVector3 local_pos;
local_pos.mV[VX] = (F32)x;
local_pos.mV[VY] = (F32)y;
local_pos.mV[VZ] = (F32)z;
// we can't teleport cross grid at this point
if((!LLGridManager::getInstance()->isSystemGrid(slurl.getGrid()) || !LLGridManager::getInstance()->isSystemGrid()) &&
(slurl.getGrid() != LLGridManager::getInstance()->getGrid()))
{
LLSD args;
args["SLURL"] = slurl.getLocationString();
args["CURRENT_GRID"] = LLGridManager::getInstance()->getGridLabel();
LLSD grid_info = LLGridManager::getInstance()->getGridInfo(slurl.getGrid());
if(grid_info.has(GRID_LABEL_VALUE))
{
args["GRID"] = grid_info[GRID_LABEL_VALUE].asString();
}
else
{
args["GRID"] = slurl.getGrid();
}
LLNotificationsUtil::add("CantTeleportToGrid", args);
return;
}
LLVector3d global_pos = from_region_handle(region_handle);
global_pos += LLVector3d(local_pos);
global_pos += LLVector3d(slurl.getPosition());
if (teleport)
{
@ -271,8 +253,8 @@ void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const std::str
// LLFloaterURLDisplay functionality moved to LLPanelPlaces in Side Tray.
// // display informational floater, allow user to click teleport btn
// LLFloaterURLDisplay* url_displayp = LLFloaterReg::getTypedInstance<LLFloaterURLDisplay>("preview_url",LLSD());
// if(url_displayp)
// LLFloaterURLDisplay* slurl_displayp = LLFloaterReg::getTypedInstance<LLFloaterURLDisplay>("preview_url",LLSD());
// if(slurl_displayp)
// {
// url_displayp->displayParcelInfo(region_handle, local_pos);
// if(snapshot_id.notNull())
@ -287,7 +269,7 @@ void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const std::str
//---------------------------------------------------------------------------
// Teleportation links are handled here because they are tightly coupled
// to URL parsing and sim-fragment parsing
// to SLURL parsing and sim-fragment parsing
class LLTeleportHandler : public LLCommandHandler
{
public:
@ -303,18 +285,21 @@ public:
// a global position, and teleport to it
if (tokens.size() < 1) return false;
// Region names may be %20 escaped.
std::string region_name = LLURLSimString::unescapeRegionName(tokens[0]);
// build secondlife://De%20Haro/123/45/67 for use in callback
std::string url = LLSLURL::PREFIX_SECONDLIFE;
for (int i = 0; i < tokens.size(); ++i)
LLVector3 coords(128, 128, 0);
if (tokens.size() <= 4)
{
url += tokens[i].asString() + "/";
coords = LLVector3(tokens[1].asReal(),
tokens[2].asReal(),
tokens[3].asReal());
}
// Region names may be %20 escaped.
std::string region_name = LLURI::unescape(tokens[0]);
LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name,
LLURLDispatcherImpl::regionHandleCallback,
url,
LLSLURL(region_name, coords).getSLURLString(),
true); // teleport
return true;
}
@ -324,21 +309,21 @@ LLTeleportHandler gTeleportHandler;
//---------------------------------------------------------------------------
// static
bool LLURLDispatcher::dispatch(const std::string& url,
bool LLURLDispatcher::dispatch(const std::string& slurl,
LLMediaCtrl* web,
bool trusted_browser)
{
return LLURLDispatcherImpl::dispatch(url, web, trusted_browser);
return LLURLDispatcherImpl::dispatch(LLSLURL(slurl), web, trusted_browser);
}
// static
bool LLURLDispatcher::dispatchRightClick(const std::string& url)
bool LLURLDispatcher::dispatchRightClick(const std::string& slurl)
{
return LLURLDispatcherImpl::dispatchRightClick(url);
return LLURLDispatcherImpl::dispatchRightClick(LLSLURL(slurl));
}
// static
bool LLURLDispatcher::dispatchFromTextEditor(const std::string& url)
bool LLURLDispatcher::dispatchFromTextEditor(const std::string& slurl)
{
// *NOTE: Text editors are considered sources of trusted URLs
// in order to make avatar profile links in chat history work.
@ -348,5 +333,7 @@ bool LLURLDispatcher::dispatchFromTextEditor(const std::string& url)
// *TODO: Make this trust model more refined. JC
const bool trusted_browser = true;
LLMediaCtrl* web = NULL;
return LLURLDispatcherImpl::dispatch(url, web, trusted_browser);
return LLURLDispatcherImpl::dispatch(LLSLURL(slurl), web, trusted_browser);
}

View File

@ -2,9 +2,9 @@
* @file llurldispatcher.h
* @brief Central registry for all SL URL handlers
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
* Copyright (c) 2007-2010, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@ -12,13 +12,12 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* online at http://secondlife.com/developers/opensource/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* online at http://secondlife.com/developers/opensource/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
@ -31,16 +30,16 @@
*/
#ifndef LLURLDISPATCHER_H
#define LLURLDISPATCHER_H
class LLMediaCtrl;
class LLURLDispatcher
{
public:
static bool dispatch(const std::string& url,
static bool dispatch(const std::string& slurl,
LLMediaCtrl* web,
bool trusted_browser);
bool trusted_browser);
// At startup time and on clicks in internal web browsers,
// teleport, open map, or run requested command.
// @param url
@ -54,9 +53,9 @@ public:
// that navigates to trusted (Linden Lab) pages.
// Returns true if someone handled the URL.
static bool dispatchRightClick(const std::string& url);
static bool dispatchRightClick(const std::string& slurl);
static bool dispatchFromTextEditor(const std::string& url);
static bool dispatchFromTextEditor(const std::string& slurl);
};
#endif

View File

@ -89,7 +89,7 @@ void LLURLLineEditor::copyEscapedURLToClipboard()
const std::string unescaped_text = wstring_to_utf8str(mText.getWString().substr(left_pos, length));
LLWString text_to_copy;
if (LLSLURL::isSLURL(unescaped_text))
if (LLSLURL(unescaped_text).isValid())
text_to_copy = utf8str_to_wstring(LLWeb::escapeURL(unescaped_text));
else
text_to_copy = utf8str_to_wstring(unescaped_text);

View File

@ -157,21 +157,21 @@ void audio_update_volume(bool force_update)
LLViewerMedia::setVolume( media_muted ? 0.0f : media_volume );
// Voice
if (gVoiceClient)
if (LLVoiceClient::getInstance())
{
F32 voice_volume = gSavedSettings.getF32("AudioLevelVoice");
voice_volume = mute_volume * master_volume * voice_volume;
BOOL voice_mute = gSavedSettings.getBOOL("MuteVoice");
gVoiceClient->setVoiceVolume(voice_mute ? 0.f : voice_volume);
gVoiceClient->setMicGain(voice_mute ? 0.f : gSavedSettings.getF32("AudioLevelMic"));
LLVoiceClient::getInstance()->setVoiceVolume(voice_mute ? 0.f : voice_volume);
LLVoiceClient::getInstance()->setMicGain(voice_mute ? 0.f : gSavedSettings.getF32("AudioLevelMic"));
if (!gViewerWindow->getActive() && (gSavedSettings.getBOOL("MuteWhenMinimized")))
{
gVoiceClient->setMuteMic(true);
LLVoiceClient::getInstance()->setMuteMic(true);
}
else
{
gVoiceClient->setMuteMic(false);
LLVoiceClient::getInstance()->setMuteMic(false);
}
}
}

View File

@ -413,9 +413,9 @@ bool handleHighResSnapshotChanged(const LLSD& newvalue)
bool handleVoiceClientPrefsChanged(const LLSD& newvalue)
{
if(gVoiceClient)
if(LLVoiceClient::getInstance())
{
gVoiceClient->updateSettings();
LLVoiceClient::getInstance()->updateSettings();
}
return true;
}
@ -446,7 +446,7 @@ bool handleVelocityInterpolate(const LLSD& newvalue)
bool handleForceShowGrid(const LLSD& newvalue)
{
LLPanelLogin::refreshLocation( false );
LLPanelLogin::updateServer( );
return true;
}

View File

@ -36,7 +36,6 @@
#include "llnotificationsutil.h"
#include "llsdserialize.h"
#include "message.h"
#include "indra_constants.h"
#include "llagent.h"
#include "llagentcamera.h"
@ -264,10 +263,14 @@ void LLViewerInventoryItem::fetchFromServer(void) const
// we have to check region. It can be null after region was destroyed. See EXT-245
if (region)
{
if( ALEXANDRIA_LINDEN_ID.getString() == mPermissions.getOwner().getString())
url = region->getCapability("FetchLib");
else
url = region->getCapability("FetchInventory");
if(gAgent.getID() != mPermissions.getOwner())
{
url = region->getCapability("FetchLib");
}
else
{
url = region->getCapability("FetchInventory");
}
}
else
{

View File

@ -429,7 +429,7 @@ void init_menus()
gPopupMenuView->setBackgroundColor( color );
// If we are not in production, use a different color to make it apparent.
if (LLViewerLogin::getInstance()->isInProductionGrid())
if (LLGridManager::getInstance()->isInProductionGrid())
{
color = LLUIColorTable::instance().getColor( "MenuBarBgColor" );
}
@ -445,7 +445,7 @@ void init_menus()
menu_bar_holder->addChild(gMenuBarView);
gViewerWindow->setMenuBackgroundColor(false,
LLViewerLogin::getInstance()->isInProductionGrid());
LLGridManager::getInstance()->isInProductionGrid());
// Assume L$10 for now, the server will tell us the real cost at login
// *TODO:Also fix cost in llfolderview.cpp for Inventory menus
@ -3467,7 +3467,7 @@ void set_god_level(U8 god_level)
if(gViewerWindow)
{
gViewerWindow->setMenuBackgroundColor(god_level > GOD_NOT,
LLViewerLogin::getInstance()->isInProductionGrid());
LLGridManager::getInstance()->isInProductionGrid());
}
LLSD args;
@ -3507,7 +3507,7 @@ BOOL check_toggle_hacked_godmode(void*)
bool enable_toggle_hacked_godmode(void*)
{
return !LLViewerLogin::getInstance()->isInProductionGrid();
return !LLGridManager::getInstance()->isInProductionGrid();
}
#endif
@ -4378,7 +4378,7 @@ BOOL enable_take()
return TRUE;
#else
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
if (!LLViewerLogin::getInstance()->isInProductionGrid()
if (!LLGridManager::getInstance()->isInProductionGrid()
&& gAgent.isGodlike())
{
return TRUE;
@ -4991,7 +4991,7 @@ bool enable_object_delete()
TRUE;
#else
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
(!LLViewerLogin::getInstance()->isInProductionGrid()
(!LLGridManager::getInstance()->isInProductionGrid()
&& gAgent.isGodlike()) ||
# endif
LLSelectMgr::getInstance()->canDoDelete();
@ -6627,7 +6627,7 @@ bool enable_object_take_copy()
all_valid = true;
#ifndef HACKED_GODLIKE_VIEWER
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
if (LLViewerLogin::getInstance()->isInProductionGrid()
if (LLGridManager::getInstance()->isInProductionGrid()
|| !gAgent.isGodlike())
# endif
{
@ -6689,7 +6689,7 @@ BOOL enable_save_into_inventory(void*)
return TRUE;
#else
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
if (!LLViewerLogin::getInstance()->isInProductionGrid()
if (!LLGridManager::getInstance()->isInProductionGrid()
&& gAgent.isGodlike())
{
return TRUE;

View File

@ -1573,9 +1573,9 @@ void inventory_offer_handler(LLOfferInfo* info)
payload["give_inventory_notification"] = FALSE;
args["OBJECTFROMNAME"] = info->mFromName;
args["NAME"] = info->mFromName;
args["NAME_SLURL"] = LLSLURL::buildCommand("agent", info->mFromID, "about");
args["NAME_SLURL"] = LLSLURL("agent", info->mFromID, "about").getSLURLString();
std::string verb = "select?name=" + LLURI::escape(msg);
args["ITEM_SLURL"] = LLSLURL::buildCommand("inventory", info->mObjectID, verb.c_str());
args["ITEM_SLURL"] = LLSLURL("inventory", info->mObjectID, verb.c_str()).getSLURLString();
LLNotification::Params p("ObjectGiveItem");
@ -2244,10 +2244,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
query_string["groupowned"] = "true";
}
std::ostringstream link;
link << "secondlife:///app/objectim/" << session_id << LLURI::mapToQueryString(query_string);
chat.mURL = link.str();
chat.mURL = LLSLURL("objectim", session_id, "").getSLURLString();
chat.mText = message;
chat.mSourceType = CHAT_SOURCE_OBJECT;
@ -2330,7 +2327,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
{
LLSD args;
// *TODO: Translate -> [FIRST] [LAST] (maybe)
args["NAME_SLURL"] = LLSLURL::buildCommand("agent", from_id, "about");
args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
args["MESSAGE"] = message;
LLSD payload;
payload["from_id"] = from_id;
@ -2396,7 +2393,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
}
else
{
args["NAME_SLURL"] = LLSLURL::buildCommand("agent", from_id, "about");
args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
if(message.empty())
{
//support for frienship offers from clients before July 2008
@ -3155,7 +3152,9 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
{
// Chat the "back" SLURL. (DEV-4907)
LLSD substitution = LLSD().with("[T_SLURL]", gAgent.getTeleportSourceSLURL());
LLSLURL slurl;
gAgent.getTeleportSourceSLURL(slurl);
LLSD substitution = LLSD().with("[T_SLURL]", slurl.getSLURLString());
std::string completed_from = LLAgent::sTeleportProgressMessages["completed_from"];
LLStringUtil::format(completed_from, substitution);
@ -5548,7 +5547,9 @@ void send_group_notice(const LLUUID& group_id,
bool handle_lure_callback(const LLSD& notification, const LLSD& response)
{
std::string text = response["message"].asString();
text.append("\r\n").append(LLAgentUI::buildSLURL());
LLSLURL slurl;
LLAgentUI::buildSLURL(slurl);
text.append("\r\n").append(slurl.getSLURLString());
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if(0 == option)
@ -5991,7 +5992,7 @@ void process_covenant_reply(LLMessageSystem* msg, void**)
LLFloaterBuyLand::updateEstateName(estate_name);
std::string owner_name =
LLSLURL::buildCommand("agent", estate_owner_id, "inspect");
LLSLURL("agent", estate_owner_id, "inspect").getSLURLString();
LLPanelEstateCovenant::updateEstateOwnerName(owner_name);
LLPanelLandCovenant::updateEstateOwnerName(owner_name);
LLFloaterBuyLand::updateEstateOwnerName(owner_name);

View File

@ -5,7 +5,7 @@
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
* Copyright (c) 2006-2010, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@ -13,13 +13,12 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* online at http://secondlife.com/developers/opensource/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* online at http://secondlife.com/developers/opensource/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
@ -34,303 +33,478 @@
#include "llviewerprecompiledheaders.h"
#include "llviewernetwork.h"
#include "llevents.h"
#include "net.h"
#include "llviewercontrol.h"
#include "lllogin.h"
#include "llsdserialize.h"
#include "llweb.h"
struct LLGridData
{
const char* mLabel;
const char* mName;
const char* mLoginURI;
const char* mHelperURI;
};
static LLGridData gGridInfo[GRID_INFO_COUNT] =
{
{ "None", "", "", ""},
{ "Aditi",
"util.aditi.lindenlab.com",
"https://login.aditi.lindenlab.com/cgi-bin/login.cgi",
"http://aditi-secondlife.webdev.lindenlab.com/helpers/" },
{ "Agni",
"util.agni.lindenlab.com",
"https://login.agni.lindenlab.com/cgi-bin/login.cgi",
"https://secondlife.com/helpers/" },
{ "Aruna",
"util.aruna.lindenlab.com",
"https://login.aruna.lindenlab.com/cgi-bin/login.cgi",
"http://aruna-secondlife.webdev.lindenlab.com/helpers/" },
{ "Bharati",
"util.bharati.lindenlab.com",
"https://login.bharati.lindenlab.com/cgi-bin/login.cgi",
"http://bharati-secondlife.webdev.lindenlab.com/helpers/" },
{ "Chandra",
"util.chandra.lindenlab.com",
"https://login.chandra.lindenlab.com/cgi-bin/login.cgi",
"http://chandra-secondlife.webdev.lindenlab.com/helpers/" },
{ "Damballah",
"util.damballah.lindenlab.com",
"https://login.damballah.lindenlab.com/cgi-bin/login.cgi",
"http://damballah-secondlife.webdev.lindenlab.com/helpers/" },
{ "Danu",
"util.danu.lindenlab.com",
"https://login.danu.lindenlab.com/cgi-bin/login.cgi",
"http://danu-secondlife.webdev.lindenlab.com/helpers/" },
{ "Durga",
"util.durga.lindenlab.com",
"https://login.durga.lindenlab.com/cgi-bin/login.cgi",
"http://durga-secondlife.webdev.lindenlab.com/helpers/" },
{ "Ganga",
"util.ganga.lindenlab.com",
"https://login.ganga.lindenlab.com/cgi-bin/login.cgi",
"http://ganga-secondlife.webdev.lindenlab.com/helpers/" },
{ "Mitra",
"util.mitra.lindenlab.com",
"https://login.mitra.lindenlab.com/cgi-bin/login.cgi",
"http://mitra-secondlife.webdev.lindenlab.com/helpers/" },
{ "Mohini",
"util.mohini.lindenlab.com",
"https://login.mohini.lindenlab.com/cgi-bin/login.cgi",
"http://mohini-secondlife.webdev.lindenlab.com/helpers/" },
{ "Nandi",
"util.nandi.lindenlab.com",
"https://login.nandi.lindenlab.com/cgi-bin/login.cgi",
"http://nandi-secondlife.webdev.lindenlab.com/helpers/" },
{ "Parvati",
"util.parvati.lindenlab.com",
"https://login.parvati.lindenlab.com/cgi-bin/login.cgi",
"http://parvati-secondlife.webdev.lindenlab.com/helpers/" },
{ "Radha",
"util.radha.lindenlab.com",
"https://login.radha.lindenlab.com/cgi-bin/login.cgi",
"http://radha-secondlife.webdev.lindenlab.com/helpers/" },
{ "Ravi",
"util.ravi.lindenlab.com",
"https://login.ravi.lindenlab.com/cgi-bin/login.cgi",
"http://ravi-secondlife.webdev.lindenlab.com/helpers/" },
{ "Siva",
"util.siva.lindenlab.com",
"https://login.siva.lindenlab.com/cgi-bin/login.cgi",
"http://siva-secondlife.webdev.lindenlab.com/helpers/" },
{ "Shakti",
"util.shakti.lindenlab.com",
"https://login.shakti.lindenlab.com/cgi-bin/login.cgi",
"http://shakti-secondlife.webdev.lindenlab.com/helpers/" },
{ "Skanda",
"util.skanda.lindenlab.com",
"https://login.skanda.lindenlab.com/cgi-bin/login.cgi",
"http://skanda-secondlife.webdev.lindenlab.com/helpers/" },
{ "Soma",
"util.soma.lindenlab.com",
"https://login.soma.lindenlab.com/cgi-bin/login.cgi",
"http://soma-secondlife.webdev.lindenlab.com/helpers/" },
{ "Uma",
"util.uma.lindenlab.com",
"https://login.uma.lindenlab.com/cgi-bin/login.cgi",
"http://uma-secondlife.webdev.lindenlab.com/helpers/" },
{ "Vaak",
"util.vaak.lindenlab.com",
"https://login.vaak.lindenlab.com/cgi-bin/login.cgi",
"http://vaak-secondlife.webdev.lindenlab.com/helpers/" },
{ "Yami",
"util.yami.lindenlab.com",
"https://login.yami.lindenlab.com/cgi-bin/login.cgi",
"http://yami-secondlife.webdev.lindenlab.com/helpers/" },
{ "Local",
"localhost",
"https://login.dmz.lindenlab.com/cgi-bin/login.cgi",
"" },
{ "Other",
"",
"https://login.dmz.lindenlab.com/cgi-bin/login.cgi",
"" }
};
const EGridInfo DEFAULT_GRID_CHOICE = GRID_INFO_AGNI;
unsigned char gMACAddress[MAC_ADDRESS_BYTES]; /* Flawfinder: ignore */
LLViewerLogin::LLViewerLogin() :
mGridChoice(DEFAULT_GRID_CHOICE)
const char* DEFAULT_LOGIN_PAGE = "http://secondlife.com/app/login/";
const char* SYSTEM_GRID_SLURL_BASE = "secondlife://%s/secondlife/";
const char* MAIN_GRID_SLURL_BASE = "http://maps.secondlife.com/secondlife/";
const char* SYSTEM_GRID_APP_SLURL_BASE = "secondlife:///app";
const char* DEFAULT_SLURL_BASE = "https://%s/region/";
const char* DEFAULT_APP_SLURL_BASE = "x-grid-location-info://%s/app";
LLGridManager::LLGridManager()
{
// by default, we use the 'grids.xml' file in the user settings directory
// this file is an LLSD file containing multiple grid definitions.
// This file does not contain definitions for secondlife.com grids,
// as that would be a security issue when they are overwritten by
// an attacker. Don't want someone snagging a password.
std::string grid_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
"grids.xml");
initialize(grid_file);
}
LLViewerLogin::~LLViewerLogin()
{
}
void LLViewerLogin::setGridChoice(EGridInfo grid)
{
if(grid < 0 || grid >= GRID_INFO_COUNT)
LLGridManager::LLGridManager(const std::string& grid_file)
{
// initialize with an explicity grid file for testing.
initialize(grid_file);
}
//
// LLGridManager - class for managing the list of known grids, and the current
// selection
//
//
// LLGridManager::initialze - initialize the list of known grids based
// on the fixed list of linden grids (fixed for security reasons)
// the grids.xml file
// and the command line.
void LLGridManager::initialize(const std::string& grid_file)
{
// default grid list.
// Don't move to a modifiable file for security reasons,
mGrid.clear() ;
// set to undefined
mGridList = LLSD();
mGridFile = grid_file;
// as we don't want an attacker to override our grid list
// to point the default grid to an invalid grid
addSystemGrid("None", "", "", "", DEFAULT_LOGIN_PAGE);
#ifndef LL_RELEASE_FOR_DOWNLOAD
addSystemGrid("Agni",
MAINGRID,
"https://login.agni.lindenlab.com/cgi-bin/login.cgi",
"https://secondlife.com/helpers/",
DEFAULT_LOGIN_PAGE);
#else
addSystemGrid("Secondlife.com",
MAINGRID,
"https://login.agni.lindenlab.com/cgi-bin/login.cgi",
"https://secondlife.com/helpers/",
DEFAULT_LOGIN_PAGE,
"Agni");
#endif // LL_RELEASE_FOR_DOWNLOAD
addSystemGrid("Aditi",
"util.aditi.lindenlab.com",
"https://login.aditi.lindenlab.com/cgi-bin/login.cgi",
"http://aditi-secondlife.webdev.lindenlab.com/helpers/",
DEFAULT_LOGIN_PAGE);
addSystemGrid("Aruna",
"util.aruna.lindenlab.com",
"https://login.aruna.lindenlab.com/cgi-bin/login.cgi",
"http://aruna-secondlife.webdev.lindenlab.com/helpers/",
DEFAULT_LOGIN_PAGE);
addSystemGrid("Durga",
"util.durga.lindenlab.com",
"https://login.durga.lindenlab.com/cgi-bin/login.cgi",
"http://durga-secondlife.webdev.lindenlab.com/helpers/",
DEFAULT_LOGIN_PAGE);
addSystemGrid("Ganga",
"util.ganga.lindenlab.com",
"https://login.ganga.lindenlab.com/cgi-bin/login.cgi",
"http://ganga-secondlife.webdev.lindenlab.com/helpers/",
DEFAULT_LOGIN_PAGE);
addSystemGrid("Mitra",
"util.mitra.lindenlab.com",
"https://login.mitra.lindenlab.com/cgi-bin/login.cgi",
"http://mitra-secondlife.webdev.lindenlab.com/helpers/",
DEFAULT_LOGIN_PAGE);
addSystemGrid("Mohini",
"util.mohini.lindenlab.com",
"https://login.mohini.lindenlab.com/cgi-bin/login.cgi",
"http://mohini-secondlife.webdev.lindenlab.com/helpers/",
DEFAULT_LOGIN_PAGE);
addSystemGrid("Nandi",
"util.nandi.lindenlab.com",
"https://login.nandi.lindenlab.com/cgi-bin/login.cgi",
"http://nandi-secondlife.webdev.lindenlab.com/helpers/",
DEFAULT_LOGIN_PAGE);
addSystemGrid("Radha",
"util.radha.lindenlab.com",
"https://login.radha.lindenlab.com/cgi-bin/login.cgi",
"http://radha-secondlife.webdev.lindenlab.com/helpers/",
DEFAULT_LOGIN_PAGE);
addSystemGrid("Ravi",
"util.ravi.lindenlab.com",
"https://login.ravi.lindenlab.com/cgi-bin/login.cgi",
"http://ravi-secondlife.webdev.lindenlab.com/helpers/",
DEFAULT_LOGIN_PAGE);
addSystemGrid("Siva",
"util.siva.lindenlab.com",
"https://login.siva.lindenlab.com/cgi-bin/login.cgi",
"http://siva-secondlife.webdev.lindenlab.com/helpers/",
DEFAULT_LOGIN_PAGE);
addSystemGrid("Shakti",
"util.shakti.lindenlab.com",
"https://login.shakti.lindenlab.com/cgi-bin/login.cgi",
"http://shakti-secondlife.webdev.lindenlab.com/helpers/",
DEFAULT_LOGIN_PAGE);
addSystemGrid("Soma",
"util.soma.lindenlab.com",
"https://login.soma.lindenlab.com/cgi-bin/login.cgi",
"http://soma-secondlife.webdev.lindenlab.com/helpers/",
DEFAULT_LOGIN_PAGE);
addSystemGrid("Uma",
"util.uma.lindenlab.com",
"https://login.uma.lindenlab.com/cgi-bin/login.cgi",
"http://uma-secondlife.webdev.lindenlab.com/helpers/",
DEFAULT_LOGIN_PAGE);
addSystemGrid("Vaak",
"util.vaak.lindenlab.com",
"https://login.vaak.lindenlab.com/cgi-bin/login.cgi",
"http://vaak-secondlife.webdev.lindenlab.com/helpers/",
DEFAULT_LOGIN_PAGE);
addSystemGrid("Yami",
"util.yami.lindenlab.com",
"https://login.yami.lindenlab.com/cgi-bin/login.cgi",
"http://yami-secondlife.webdev.lindenlab.com/helpers/",
DEFAULT_LOGIN_PAGE);
addSystemGrid("Local (Linden)",
"localhost",
"https://login.dmz.lindenlab.com/cgi-bin/login.cgi",
"",
DEFAULT_LOGIN_PAGE);
LLSD other_grids;
llifstream llsd_xml;
if (!grid_file.empty())
{
llerrs << "Invalid grid index specified." << llendl;
return;
llsd_xml.open( grid_file.c_str(), std::ios::in | std::ios::binary );
// parse through the gridfile, inserting grids into the list unless
// they overwrite a linden grid.
if( llsd_xml.is_open())
{
LLSDSerialize::fromXMLDocument( other_grids, llsd_xml );
if(other_grids.isMap())
{
for(LLSD::map_iterator grid_itr = other_grids.beginMap();
grid_itr != other_grids.endMap();
++grid_itr)
{
LLSD::String key_name = grid_itr->first;
LLSD grid = grid_itr->second;
// TODO: Make sure gridfile specified label is not
// a system grid label
LL_INFOS("GridManager") << "reading: " << key_name << LL_ENDL;
if (mGridList.has(key_name) &&
mGridList[key_name].has(GRID_IS_SYSTEM_GRID_VALUE))
{
LL_INFOS("GridManager") << "Cannot override grid " << key_name << " as it's a system grid" << LL_ENDL;
// If the system grid does exist in the grids file, and it's marked as a favorite, set it as a favorite.
if(grid_itr->second.has(GRID_IS_FAVORITE_VALUE) && grid_itr->second[GRID_IS_FAVORITE_VALUE].asBoolean() )
{
mGridList[key_name][GRID_IS_FAVORITE_VALUE] = TRUE;
}
}
else
{
try
{
addGrid(grid);
LL_INFOS("GridManager") << "Added grid: " << key_name << LL_ENDL;
}
catch (...)
{
}
}
}
llsd_xml.close();
}
}
}
// load a grid from the command line.
// if the actual grid name is specified from the command line,
// set it as the 'selected' grid.
mGrid = gSavedSettings.getString("CmdLineGridChoice");
LL_INFOS("GridManager") << "Grid Name: " << mGrid << LL_ENDL;
// If a command line login URI was passed in, so we should add the command
// line grid to the list of grids
if(mGridChoice != grid || gSavedSettings.getS32("ServerChoice") != grid)
LLSD cmd_line_login_uri = gSavedSettings.getLLSD("CmdLineLoginURI");
if (cmd_line_login_uri.isString())
{
mGridChoice = grid;
if(GRID_INFO_LOCAL == mGridChoice)
LL_INFOS("GridManager") << "adding cmd line login uri" << LL_ENDL;
// grab the other related URI values
std::string cmd_line_helper_uri = gSavedSettings.getString("CmdLineHelperURI");
std::string cmd_line_login_page = gSavedSettings.getString("LoginPage");
// we've a cmd line login, so add a grid for the command line,
// overwriting any existing grids
LLSD grid = LLSD::emptyMap();
grid[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray();
grid[GRID_LOGIN_URI_VALUE].append(cmd_line_login_uri);
LL_INFOS("GridManager") << "cmd line login uri: " << cmd_line_login_uri.asString() << LL_ENDL;
LLURI uri(cmd_line_login_uri.asString());
if (mGrid.empty())
{
mGridName = LOOPBACK_ADDRESS_STRING;
// if a grid name was not passed in via the command line,
// then set the grid name based on the hostname of the
// login uri
mGrid = uri.hostName();
}
else if(GRID_INFO_OTHER == mGridChoice)
grid[GRID_VALUE] = mGrid;
if (mGridList.has(mGrid) && mGridList[mGrid].has(GRID_LABEL_VALUE))
{
// *FIX:Mani - could this possibly be valid?
mGridName = "other";
grid[GRID_LABEL_VALUE] = mGridList[mGrid][GRID_LABEL_VALUE];
}
else
{
mGridName = gGridInfo[mGridChoice].mLabel;
grid[GRID_LABEL_VALUE] = mGrid;
}
if(!cmd_line_helper_uri.empty())
{
grid[GRID_HELPER_URI_VALUE] = cmd_line_helper_uri;
}
gSavedSettings.setS32("ServerChoice", mGridChoice);
gSavedSettings.setString("CustomServer", "");
if(!cmd_line_login_page.empty())
{
grid[GRID_LOGIN_PAGE_VALUE] = cmd_line_login_page;
}
// if the login page, helper URI value, and so on are not specified,
// add grid will generate them.
// Also, we will override a system grid if values are passed in via the command
// line, for testing. These values will not be remembered though.
if (mGridList.has(mGrid) && mGridList[mGrid].has(GRID_IS_SYSTEM_GRID_VALUE))
{
grid[GRID_IS_SYSTEM_GRID_VALUE] = TRUE;
}
addGrid(grid);
}
// if a grid was not passed in via the command line, grab it from the CurrentGrid setting.
if (mGrid.empty())
{
mGrid = gSavedSettings.getString("CurrentGrid");
}
if (mGrid.empty() || !mGridList.has(mGrid))
{
// the grid name was empty, or the grid isn't actually in the list, then set it to the
// appropriate default.
LL_INFOS("GridManager") << "Resetting grid as grid name " << mGrid << " is not in the list" << LL_ENDL;
#if LL_RELEASE_FOR_DOWNLOAD
mGrid = MAINGRID;
#else
mGrid = "";
#endif
}
LL_INFOS("GridManager") << "Selected grid is " << mGrid << LL_ENDL;
gSavedSettings.setString("CurrentGrid", mGrid);
}
LLGridManager::~LLGridManager()
{
saveFavorites();
}
//
// LLGridManager::addGrid - add a grid to the grid list, populating the needed values
// if they're not populated yet.
//
void LLGridManager::addGrid(LLSD& grid_data)
{
if (grid_data.isMap() && grid_data.has(GRID_VALUE))
{
std::string grid = utf8str_tolower(grid_data[GRID_VALUE]);
// grid should be in the form of a dns address
if (!grid.empty() &&
grid.find_first_not_of("abcdefghijklmnopqrstuvwxyz1234567890-_. ") != std::string::npos)
{
printf("grid name: %s", grid.c_str());
throw LLInvalidGridName(grid);
}
// populate the other values if they don't exist
if (!grid_data.has(GRID_LABEL_VALUE))
{
grid_data[GRID_LABEL_VALUE] = grid;
}
if (!grid_data.has(GRID_ID_VALUE))
{
grid_data[GRID_ID_VALUE] = grid;
}
// if the grid data doesn't include any of the URIs, then
// generate them from the grid, which should be a dns address
if (!grid_data.has(GRID_LOGIN_URI_VALUE))
{
grid_data[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray();
grid_data[GRID_LOGIN_URI_VALUE].append(std::string("https://") +
grid + "/cgi-bin/login.cgi");
}
// Populate to the default values
if (!grid_data.has(GRID_LOGIN_PAGE_VALUE))
{
grid_data[GRID_LOGIN_PAGE_VALUE] = std::string("http://") + grid + "/app/login/";
}
if (!grid_data.has(GRID_HELPER_URI_VALUE))
{
grid_data[GRID_HELPER_URI_VALUE] = std::string("https://") + grid + "/helpers/";
}
LL_INFOS("GridManager") << "ADDING: " << grid << LL_ENDL;
mGridList[grid] = grid_data;
}
}
void LLViewerLogin::setGridChoice(const std::string& grid_name)
//
// LLGridManager::addSystemGrid - helper for adding a system grid.
void LLGridManager::addSystemGrid(const std::string& label,
const std::string& name,
const std::string& login,
const std::string& helper,
const std::string& login_page,
const std::string& login_id)
{
LLSD grid = LLSD::emptyMap();
grid[GRID_VALUE] = name;
grid[GRID_LABEL_VALUE] = label;
grid[GRID_HELPER_URI_VALUE] = helper;
grid[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray();
grid[GRID_LOGIN_URI_VALUE].append(login);
grid[GRID_LOGIN_PAGE_VALUE] = login_page;
grid[GRID_IS_SYSTEM_GRID_VALUE] = TRUE;
grid[GRID_LOGIN_CREDENTIAL_PAGE_TYPE_VALUE] = GRID_LOGIN_CREDENTIAL_PAGE_TYPE_AGENT;
grid[GRID_APP_SLURL_BASE] = SYSTEM_GRID_APP_SLURL_BASE;
if (login_id.empty())
{
grid[GRID_ID_VALUE] = name;
}
else
{
grid[GRID_ID_VALUE] = login_id;
}
// only add the system grids beyond agni to the visible list
// if we're building a debug version.
if (name == std::string(MAINGRID))
{
grid[GRID_SLURL_BASE] = MAIN_GRID_SLURL_BASE;
grid[GRID_IS_FAVORITE_VALUE] = TRUE;
}
else
{
grid[GRID_SLURL_BASE] = llformat(SYSTEM_GRID_SLURL_BASE, label.c_str());
}
addGrid(grid);
}
// return a list of grid name -> grid label mappings for UI purposes
std::map<std::string, std::string> LLGridManager::getKnownGrids(bool favorite_only)
{
std::map<std::string, std::string> result;
for(LLSD::map_iterator grid_iter = mGridList.beginMap();
grid_iter != mGridList.endMap();
grid_iter++)
{
if(!favorite_only || grid_iter->second.has(GRID_IS_FAVORITE_VALUE))
{
result[grid_iter->first] = grid_iter->second[GRID_LABEL_VALUE].asString();
}
}
return result;
}
void LLGridManager::setGridChoice(const std::string& grid)
{
// Set the grid choice based on a string.
// The string can be:
// - a grid label from the gGridInfo table
// - a hostname
// - 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.setLLSD("CmdLineLoginURI", LLSD::emptyArray());
gSavedSettings.setString("CmdLineHelperURI", "");
}
EGridInfo LLViewerLogin::getGridChoice() const
{
return mGridChoice;
}
std::string LLViewerLogin::getGridLabel() const
{
if(mGridChoice == GRID_INFO_NONE)
// loop through. We could do just a hash lookup but we also want to match
// on label
for(LLSD::map_iterator grid_iter = mGridList.beginMap();
grid_iter != mGridList.endMap();
grid_iter++)
{
return "None";
}
else if(mGridChoice < GRID_INFO_OTHER)
{
return gGridInfo[mGridChoice].mLabel;
}
return mGridName;
}
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<std::string>& uris) const
{
// return the login uri set on the command line.
LLControlVariable* c = gSavedSettings.getControl("CmdLineLoginURI");
if(c)
{
LLSD v = c->getValue();
if(v.isArray())
if((grid == grid_iter->first) ||
(grid == grid_iter->second[GRID_LABEL_VALUE].asString()))
{
for(LLSD::array_const_iterator itr = v.beginArray();
itr != v.endArray(); ++itr)
{
std::string uri = itr->asString();
if(!uri.empty())
{
uris.push_back(uri);
}
}
}
else
{
std::string uri = v.asString();
if(!uri.empty())
{
uris.push_back(uri);
}
mGrid = grid_iter->second[GRID_VALUE].asString();
gSavedSettings.setString("CurrentGrid", grid_iter->second[GRID_VALUE]);
return;
}
}
LLSD grid_data = LLSD::emptyMap();
grid_data[GRID_VALUE] = grid;
addGrid(grid_data);
mGrid = grid;
gSavedSettings.setString("CurrentGrid", grid);
}
// If there was no command line uri...
if(uris.empty())
std::string LLGridManager::getGridByLabel( const std::string &grid_label)
{
for(LLSD::map_iterator grid_iter = mGridList.beginMap();
grid_iter != mGridList.endMap();
grid_iter++)
{
// 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)
if (grid_iter->second.has(GRID_LABEL_VALUE) && (grid_iter->second[GRID_LABEL_VALUE].asString() == grid_label))
{
uris.push_back(gGridInfo[mGridChoice].mLoginURI);
}
else
{
uris.push_back(mGridName);
return grid_iter->first;
}
}
return std::string();
}
void LLGridManager::getLoginURIs(std::vector<std::string>& uris)
{
uris.clear();
for (LLSD::array_iterator llsd_uri = mGridList[mGrid][GRID_LOGIN_URI_VALUE].beginArray();
llsd_uri != mGridList[mGrid][GRID_LOGIN_URI_VALUE].endArray();
llsd_uri++)
{
uris.push_back(llsd_uri->asString());
}
}
std::string LLViewerLogin::getHelperURI() 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;
}
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;
}
bool LLViewerLogin::isInProductionGrid()
bool LLGridManager::isInProductionGrid()
{
// *NOTE:Mani This used to compare GRID_INFO_AGNI to gGridChoice,
// but it seems that loginURI trumps that.
std::vector<std::string> uris;
getLoginURIs(uris);
if (uris.size() < 1)
{
return 1;
}
LLStringUtil::toLower(uris[0]);
if((uris[0].find("agni") != std::string::npos))
{
@ -339,3 +513,51 @@ bool LLViewerLogin::isInProductionGrid()
return false;
}
void LLGridManager::saveFavorites()
{
// filter out just those marked as favorites
LLSD output_grid_list = LLSD::emptyMap();
for(LLSD::map_iterator grid_iter = mGridList.beginMap();
grid_iter != mGridList.endMap();
grid_iter++)
{
if(grid_iter->second.has(GRID_IS_FAVORITE_VALUE))
{
output_grid_list[grid_iter->first] = grid_iter->second;
}
}
llofstream llsd_xml;
llsd_xml.open( mGridFile.c_str(), std::ios::out | std::ios::binary);
LLSDSerialize::toPrettyXML(output_grid_list, llsd_xml);
llsd_xml.close();
}
// build a slurl for the given region within the selected grid
std::string LLGridManager::getSLURLBase(const std::string& grid)
{
std::string grid_base;
if(mGridList.has(grid) && mGridList[grid].has(GRID_SLURL_BASE))
{
return mGridList[grid][GRID_SLURL_BASE].asString();
}
else
{
return llformat(DEFAULT_SLURL_BASE, grid.c_str());
}
}
// build a slurl for the given region within the selected grid
std::string LLGridManager::getAppSLURLBase(const std::string& grid)
{
std::string grid_base;
if(mGridList.has(grid) && mGridList[grid].has(GRID_APP_SLURL_BASE))
{
return mGridList[grid][GRID_APP_SLURL_BASE].asString();
}
else
{
return llformat(DEFAULT_APP_SLURL_BASE, grid.c_str());
}
}

View File

@ -5,7 +5,7 @@
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
* Copyright (c) 2006-2010, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@ -13,13 +13,12 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* online at http://secondlife.com/developers/opensource/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* online at http://secondlife.com/developers/opensource/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
@ -33,83 +32,136 @@
#ifndef LL_LLVIEWERNETWORK_H
#define LL_LLVIEWERNETWORK_H
extern const char* DEFAULT_LOGIN_PAGE;
#define GRID_VALUE "name"
#define GRID_LABEL_VALUE "label"
#define GRID_ID_VALUE "grid_login_id"
#define GRID_LOGIN_URI_VALUE "login_uri"
#define GRID_HELPER_URI_VALUE "helper_uri"
#define GRID_LOGIN_PAGE_VALUE "login_page"
#define GRID_IS_SYSTEM_GRID_VALUE "system_grid"
#define GRID_IS_FAVORITE_VALUE "favorite"
#define GRID_LOGIN_CREDENTIAL_PAGE_TYPE_VALUE "credential_type"
#define GRID_LOGIN_CREDENTIAL_PAGE_TYPE_AGENT "agent"
#define GRID_LOGIN_CREDENTIAL_PAGE_TYPE_ACCOUNT "account"
#define MAINGRID "util.agni.lindenlab.com"
#include <boost/scoped_ptr.hpp>
// defines slurl formats associated with various grids.
// we need to continue to support existing forms, as slurls
// are shared between viewers that may not understand newer
// forms.
#define GRID_SLURL_BASE "slurl_base"
#define GRID_APP_SLURL_BASE "app_slurl_base"
class LLHost;
class LLLogin;
enum EGridInfo
{
GRID_INFO_NONE,
GRID_INFO_ADITI,
GRID_INFO_AGNI,
GRID_INFO_ARUNA,
GRID_INFO_BHARATI,
GRID_INFO_CHANDRA,
GRID_INFO_DAMBALLAH,
GRID_INFO_DANU,
GRID_INFO_DURGA,
GRID_INFO_GANGA,
GRID_INFO_MITRA,
GRID_INFO_MOHINI,
GRID_INFO_NANDI,
GRID_INFO_PARVATI,
GRID_INFO_RADHA,
GRID_INFO_RAVI,
GRID_INFO_SIVA,
GRID_INFO_SHAKTI,
GRID_INFO_SKANDA,
GRID_INFO_SOMA,
GRID_INFO_UMA,
GRID_INFO_VAAK,
GRID_INFO_YAMI,
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.
*
**/
class LLViewerLogin : public LLSingleton<LLViewerLogin>
class LLInvalidGridName
{
public:
LLViewerLogin();
~LLViewerLogin();
LLInvalidGridName(std::string grid) : mGrid(grid)
{
}
protected:
std::string mGrid;
};
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 A class to manage the grids available to the viewer
* including persistance. This class also maintains the currently
* selected grid.
*
**/
class LLGridManager : public LLSingleton<LLGridManager>
{
public:
// when the grid manager is instantiated, the default grids are automatically
// loaded, and the grids favorites list is loaded from the xml file.
LLGridManager(const std::string& grid_file);
LLGridManager();
~LLGridManager();
void initialize(const std::string& grid_file);
// grid list management
// add a grid to the list of grids
void addGrid(LLSD& grid_info);
/**
* @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;
std::string getKnownGridLabel(EGridInfo grid_index) const;
void getLoginURIs(std::vector<std::string>& uris) const;
std::string getHelperURI() const;
// retrieve a map of grid-name <-> label
// by default only return the user visible grids
std::map<std::string, std::string> getKnownGrids(bool favorites_only=FALSE);
LLSD getGridInfo(const std::string& grid)
{
if(mGridList.has(grid))
{
return mGridList[grid];
}
else
{
return LLSD();
}
}
// current grid management
// select a given grid as the current grid. If the grid
// is not a known grid, then it's assumed to be a dns name for the
// grid, and the various URIs will be automatically generated.
void setGridChoice(const std::string& grid);
std::string getGridLabel() { return mGridList[mGrid][GRID_LABEL_VALUE]; }
std::string getGrid() const { return mGrid; }
void getLoginURIs(std::vector<std::string>& uris);
std::string getHelperURI() {return mGridList[mGrid][GRID_HELPER_URI_VALUE];}
std::string getLoginPage() {return mGridList[mGrid][GRID_LOGIN_PAGE_VALUE];}
std::string getGridLoginID() { return mGridList[mGrid][GRID_ID_VALUE]; }
std::string getLoginPage(const std::string& grid) { return mGridList[grid][GRID_LOGIN_PAGE_VALUE]; }
// build a slurl for the given region within the selected grid
std::string getSLURLBase(const std::string& grid);
std::string getSLURLBase() { return getSLURLBase(mGrid); }
std::string getAppSLURLBase(const std::string& grid);
std::string getAppSLURLBase() { return getAppSLURLBase(mGrid); }
LLSD getGridInfo() { return mGridList[mGrid]; }
std::string getGridByLabel( const std::string &grid_label);
bool isSystemGrid(const std::string& grid)
{
return mGridList.has(grid) &&
mGridList[grid].has(GRID_IS_SYSTEM_GRID_VALUE) &&
mGridList[grid][GRID_IS_SYSTEM_GRID_VALUE].asBoolean();
}
bool isSystemGrid() { return isSystemGrid(mGrid); }
// Mark this grid as a favorite that should be persisited on 'save'
// this is currently used to persist a grid after a successful login
void setFavorite() { mGridList[mGrid][GRID_IS_FAVORITE_VALUE] = TRUE; }
bool isInProductionGrid();
void saveFavorites();
void clearFavorites();
private:
EGridInfo mGridChoice;
std::string mGridName;
protected:
// helper function for adding the predefined grids
void addSystemGrid(const std::string& label,
const std::string& name,
const std::string& login,
const std::string& helper,
const std::string& login_page,
const std::string& login_id = "");
std::string mGrid;
std::string mGridFile;
LLSD mGridList;
};
const S32 MAC_ADDRESS_BYTES = 6;
extern unsigned char gMACAddress[MAC_ADDRESS_BYTES]; /* Flawfinder: ignore */
#endif

View File

@ -4726,7 +4726,7 @@ BOOL LLViewerObject::permYouOwner() const
return TRUE;
#else
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
if (!LLViewerLogin::getInstance()->isInProductionGrid()
if (!LLGridManager::getInstance()->isInProductionGrid()
&& (gAgent.getGodLevel() >= GOD_MAINTENANCE))
{
return TRUE;
@ -4763,7 +4763,7 @@ BOOL LLViewerObject::permOwnerModify() const
return TRUE;
#else
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
if (!LLViewerLogin::getInstance()->isInProductionGrid()
if (!LLGridManager::getInstance()->isInProductionGrid()
&& (gAgent.getGodLevel() >= GOD_MAINTENANCE))
{
return TRUE;
@ -4787,7 +4787,7 @@ BOOL LLViewerObject::permModify() const
return TRUE;
#else
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
if (!LLViewerLogin::getInstance()->isInProductionGrid()
if (!LLGridManager::getInstance()->isInProductionGrid()
&& (gAgent.getGodLevel() >= GOD_MAINTENANCE))
{
return TRUE;
@ -4811,7 +4811,7 @@ BOOL LLViewerObject::permCopy() const
return TRUE;
#else
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
if (!LLViewerLogin::getInstance()->isInProductionGrid()
if (!LLGridManager::getInstance()->isInProductionGrid()
&& (gAgent.getGodLevel() >= GOD_MAINTENANCE))
{
return TRUE;
@ -4835,7 +4835,7 @@ BOOL LLViewerObject::permMove() const
return TRUE;
#else
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
if (!LLViewerLogin::getInstance()->isInProductionGrid()
if (!LLGridManager::getInstance()->isInProductionGrid()
&& (gAgent.getGodLevel() >= GOD_MAINTENANCE))
{
return TRUE;
@ -4859,7 +4859,7 @@ BOOL LLViewerObject::permTransfer() const
return TRUE;
#else
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
if (!LLViewerLogin::getInstance()->isInProductionGrid()
if (!LLGridManager::getInstance()->isInProductionGrid()
&& (gAgent.getGodLevel() >= GOD_MAINTENANCE))
{
return TRUE;

View File

@ -768,9 +768,11 @@ void send_stats()
system["ram"] = (S32) gSysMemory.getPhysicalMemoryKB();
system["os"] = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
system["cpu"] = gSysCPU.getCPUString();
unsigned char MACAddress[MAC_ADDRESS_BYTES];
LLUUID::getNodeID(MACAddress);
std::string macAddressString = llformat("%02x-%02x-%02x-%02x-%02x-%02x",
gMACAddress[0],gMACAddress[1],gMACAddress[2],
gMACAddress[3],gMACAddress[4],gMACAddress[5]);
MACAddress[0],MACAddress[1],MACAddress[2],
MACAddress[3],MACAddress[4],MACAddress[5]);
system["mac_address"] = macAddressString;
system["serial_number"] = LLAppViewer::instance()->getSerialNumber();
std::string gpu_desc = llformat(

View File

@ -85,7 +85,6 @@
#include "lltooltip.h"
#include "llmediaentry.h"
#include "llurldispatcher.h"
#include "llurlsimstring.h"
// newview includes
#include "llagent.h"
@ -799,7 +798,7 @@ BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK m
BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask)
{
BOOL down = TRUE;
gVoiceClient->middleMouseState(true);
LLVoiceClient::getInstance()->middleMouseState(true);
handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down);
// Always handled as far as the OS is concerned.
@ -826,20 +825,15 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi
if (slurl_dnd_enabled)
{
// special case SLURLs
// isValidSLURL() call was added here to make sure that dragged SLURL is valid (EXT-4964)
if ( LLSLURL::isSLURL( data ) && LLSLURL::isValidSLURL( data ) )
LLSLURL dropped_slurl(data);
if(dropped_slurl.isSpatial())
{
if (drop)
{
LLURLDispatcher::dispatch( data, NULL, true );
LLURLSimString::setStringRaw( LLSLURL::stripProtocol( data ) );
LLPanelLogin::refreshLocation( true );
LLPanelLogin::updateLocationUI();
LLURLDispatcher::dispatch( dropped_slurl.getSLURLString(), NULL, true );
return LLWindowCallbacks::DND_MOVE;
}
return LLWindowCallbacks::DND_MOVE;
};
}
}
if (prim_media_dnd_enabled)
@ -957,7 +951,7 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi
BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
{
BOOL down = FALSE;
gVoiceClient->middleMouseState(false);
LLVoiceClient::getInstance()->middleMouseState(false);
handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down);
// Always handled as far as the OS is concerned.
@ -1074,7 +1068,7 @@ void LLViewerWindow::handleFocusLost(LLWindow *window)
BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated)
{
// Let the voice chat code check for its PTT key. Note that this never affects event processing.
gVoiceClient->keyDown(key, mask);
LLVoiceClient::getInstance()->keyDown(key, mask);
if (gAwayTimer.getElapsedTimeF32() > MIN_AFK_TIME)
{
@ -1096,7 +1090,7 @@ BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated)
BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask)
{
// Let the voice chat code check for its PTT key. Note that this never affects event processing.
gVoiceClient->keyUp(key, mask);
LLVoiceClient::getInstance()->keyUp(key, mask);
return FALSE;
}
@ -1955,7 +1949,7 @@ void LLViewerWindow::setNormalControlsVisible( BOOL visible )
// ...and set the menu color appropriately.
setMenuBackgroundColor(gAgent.getGodLevel() > GOD_NOT,
LLViewerLogin::getInstance()->isInProductionGrid());
LLGridManager::getInstance()->isInProductionGrid());
}
if ( gStatusBar )
@ -1976,15 +1970,15 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)
LLSD args;
LLColor4 new_bg_color;
if(god_mode && LLViewerLogin::getInstance()->isInProductionGrid())
if(god_mode && LLGridManager::getInstance()->isInProductionGrid())
{
new_bg_color = LLUIColorTable::instance().getColor( "MenuBarGodBgColor" );
}
else if(god_mode && !LLViewerLogin::getInstance()->isInProductionGrid())
else if(god_mode && !LLGridManager::getInstance()->isInProductionGrid())
{
new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionGodBgColor" );
}
else if(!god_mode && !LLViewerLogin::getInstance()->isInProductionGrid())
else if(!god_mode && !LLGridManager::getInstance()->isInProductionGrid())
{
new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" );
}
@ -2200,7 +2194,6 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
}
return TRUE;
}
// hidden edit menu for cut/copy/paste
if (gEditMenu && gEditMenu->handleAcceleratorKey(key, mask))
{

View File

@ -1266,7 +1266,7 @@ void LLVOAvatar::initInstance(void)
//VTPause(); // VTune
mVoiceVisualizer->setVoiceEnabled( gVoiceClient->getVoiceEnabled( mID ) );
mVoiceVisualizer->setVoiceEnabled( LLVoiceClient::getInstance()->getVoiceEnabled( mID ) );
}
const LLVector3 LLVOAvatar::getRenderPosition() const
@ -2197,8 +2197,8 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
}
static LLUICachedControl<bool> visualizers_in_calls("ShowVoiceVisualizersInCalls", false);
bool voice_enabled = (visualizers_in_calls || gVoiceClient->inProximalChannel()) &&
gVoiceClient->getVoiceEnabled(mID);
bool voice_enabled = (visualizers_in_calls || LLVoiceClient::getInstance()->inProximalChannel()) &&
LLVoiceClient::getInstance()->getVoiceEnabled(mID);
idleUpdateVoiceVisualizer( voice_enabled );
idleUpdateMisc( detailed_update );
@ -2261,7 +2261,7 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
// Notice the calls to "gAwayTimer.reset()". This resets the timer that determines how long the avatar has been
// "away", so that the avatar doesn't lapse into away-mode (and slump over) while the user is still talking.
//-----------------------------------------------------------------------------------------------------------------
if (gVoiceClient->getIsSpeaking( mID ))
if (LLVoiceClient::getInstance()->getIsSpeaking( mID ))
{
if (!mVoiceVisualizer->getCurrentlySpeaking())
{
@ -2270,7 +2270,7 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
//printf( "gAwayTimer.reset();\n" );
}
mVoiceVisualizer->setSpeakingAmplitude( gVoiceClient->getCurrentPower( mID ) );
mVoiceVisualizer->setSpeakingAmplitude( LLVoiceClient::getInstance()->getCurrentPower( mID ) );
if( isSelf() )
{
@ -2499,7 +2499,7 @@ F32 LLVOAvatar::calcMorphAmount()
void LLVOAvatar::idleUpdateLipSync(bool voice_enabled)
{
// Use the Lipsync_Ooh and Lipsync_Aah morphs for lip sync
if ( voice_enabled && (gVoiceClient->lipSyncEnabled()) && gVoiceClient->getIsSpeaking( mID ) )
if ( voice_enabled && (LLVoiceClient::getInstance()->lipSyncEnabled()) && LLVoiceClient::getInstance()->getIsSpeaking( mID ) )
{
F32 ooh_morph_amount = 0.0f;
F32 aah_morph_amount = 0.0f;

View File

@ -72,9 +72,9 @@ private:
void LLVoiceCallCapResponder::error(U32 status, const std::string& reason)
{
llwarns << "LLVoiceCallCapResponder::error("
LL_WARNS("Voice") << "LLVoiceCallCapResponder::error("
<< status << ": " << reason << ")"
<< llendl;
<< LL_ENDL;
LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID);
if ( channelp )
{
@ -104,8 +104,8 @@ void LLVoiceCallCapResponder::result(const LLSD& content)
LLSD::map_const_iterator iter;
for(iter = content.beginMap(); iter != content.endMap(); ++iter)
{
llinfos << "LLVoiceCallCapResponder::result got "
<< iter->first << llendl;
LL_DEBUGS("Voice") << "LLVoiceCallCapResponder::result got "
<< iter->first << LL_ENDL;
}
channelp->setChannelInfo(
@ -131,10 +131,8 @@ LLVoiceChannel::LLVoiceChannel(const LLUUID& session_id, const std::string& sess
{
// a voice channel already exists for this session id, so this instance will be orphaned
// the end result should simply be the failure to make voice calls
llwarns << "Duplicate voice channels registered for session_id " << session_id << llendl;
LL_WARNS("Voice") << "Duplicate voice channels registered for session_id " << session_id << LL_ENDL;
}
LLVoiceClient::getInstance()->addObserver(this);
}
LLVoiceChannel::~LLVoiceChannel()
@ -145,7 +143,7 @@ LLVoiceChannel::~LLVoiceChannel()
// later in other destructors anyway). EXT-5524
if(LLVoiceClient::instanceExists())
{
gVoiceClient->removeObserver(this);
LLVoiceClient::getInstance()->removeObserver(this);
}
sVoiceChannelMap.erase(mSessionID);
@ -165,13 +163,13 @@ void LLVoiceChannel::setChannelInfo(
if (mURI.empty())
{
LLNotificationsUtil::add("VoiceChannelJoinFailed", mNotifyArgs);
llwarns << "Received empty URI for channel " << mSessionName << llendl;
LL_WARNS("Voice") << "Received empty URI for channel " << mSessionName << LL_ENDL;
deactivate();
}
else if (mCredentials.empty())
{
LLNotificationsUtil::add("VoiceChannelJoinFailed", mNotifyArgs);
llwarns << "Received empty credentials for channel " << mSessionName << llendl;
LL_WARNS("Voice") << "Received empty credentials for channel " << mSessionName << LL_ENDL;
deactivate();
}
else
@ -286,13 +284,14 @@ void LLVoiceChannel::deactivate()
//Default mic is OFF when leaving voice calls
if (gSavedSettings.getBOOL("AutoDisengageMic") &&
sCurrentVoiceChannel == this &&
gVoiceClient->getUserPTTState())
LLVoiceClient::getInstance()->getUserPTTState())
{
gSavedSettings.setBOOL("PTTCurrentlyEnabled", true);
gVoiceClient->inputUserControlState(true);
LLVoiceClient::getInstance()->inputUserControlState(true);
}
}
LLVoiceClient::getInstance()->removeObserver(this);
if (sCurrentVoiceChannel == this)
{
// default channel is proximal channel
@ -332,7 +331,9 @@ void LLVoiceChannel::activate()
{
setState(STATE_CALL_STARTED);
}
LLVoiceClient::getInstance()->addObserver(this);
//do not send earlier, channel should be initialized, should not be in STATE_NO_CHANNEL_INFO state
sCurrentVoiceChannelChangedSignal(this->mSessionID);
}
@ -374,6 +375,11 @@ LLVoiceChannel* LLVoiceChannel::getChannelByURI(std::string uri)
}
}
LLVoiceChannel* LLVoiceChannel::getCurrentVoiceChannel()
{
return sCurrentVoiceChannel;
}
void LLVoiceChannel::updateSessionID(const LLUUID& new_session_id)
{
sVoiceChannelMap.erase(sVoiceChannelMap.find(mSessionID));
@ -425,7 +431,6 @@ void LLVoiceChannel::initClass()
sCurrentVoiceChannel = LLVoiceChannelProximal::getInstance();
}
//static
void LLVoiceChannel::suspend()
{
@ -441,7 +446,7 @@ void LLVoiceChannel::resume()
{
if (sSuspended)
{
if (gVoiceClient->voiceEnabled())
if (LLVoiceClient::getInstance()->voiceEnabled())
{
if (sSuspendedVoiceChannel)
{
@ -511,9 +516,9 @@ void LLVoiceChannelGroup::activate()
#endif
//Mic default state is OFF on initiating/joining Ad-Hoc/Group calls
if (gVoiceClient->getUserPTTState() && gVoiceClient->getPTTIsToggle())
if (LLVoiceClient::getInstance()->getUserPTTState() && LLVoiceClient::getInstance()->getPTTIsToggle())
{
gVoiceClient->inputUserControlState(true);
LLVoiceClient::getInstance()->inputUserControlState(true);
}
}
@ -560,7 +565,7 @@ void LLVoiceChannelGroup::setChannelInfo(
else
{
//*TODO: notify user
llwarns << "Received invalid credentials for channel " << mSessionName << llendl;
LL_WARNS("Voice") << "Received invalid credentials for channel " << mSessionName << LL_ENDL;
deactivate();
}
}
@ -659,7 +664,6 @@ void LLVoiceChannelGroup::setState(EState state)
LLVoiceChannelProximal::LLVoiceChannelProximal() :
LLVoiceChannel(LLUUID::null, LLStringUtil::null)
{
activate();
}
BOOL LLVoiceChannelProximal::isActive()
@ -671,13 +675,13 @@ void LLVoiceChannelProximal::activate()
{
if (callStarted()) return;
LLVoiceChannel::activate();
if (callStarted())
if((LLVoiceChannel::sCurrentVoiceChannel != this) && (LLVoiceChannel::getState() == STATE_CONNECTED))
{
// this implicitly puts you back in the spatial channel
LLVoiceClient::getInstance()->leaveNonSpatialChannel();
// we're connected to a non-spatial channel, so disconnect.
LLVoiceClient::getInstance()->leaveNonSpatialChannel();
}
LLVoiceChannel::activate();
}
void LLVoiceChannelProximal::onChange(EStatusType type, const std::string &channelURI, bool proximal)
@ -707,7 +711,7 @@ void LLVoiceChannelProximal::handleStatusChange(EStatusType status)
return;
case STATUS_VOICE_DISABLED:
//skip showing "Voice not available at your current location" when agent voice is disabled (EXT-4749)
if(LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking())
if(LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking())
{
//TODO: remove or redirect this call status notification
// LLCallInfoDialog::show("unavailable", mNotifyArgs);
@ -767,7 +771,7 @@ LLVoiceChannelP2P::LLVoiceChannelP2P(const LLUUID& session_id, const std::string
void LLVoiceChannelP2P::handleStatusChange(EStatusType type)
{
llinfos << "P2P CALL CHANNEL STATUS CHANGE: incoming=" << int(mReceivedCall) << " newstatus=" << LLVoiceClientStatusObserver::status2string(type) << " (mState=" << mState << ")" << llendl;
LL_INFOS("Voice") << "P2P CALL CHANNEL STATUS CHANGE: incoming=" << int(mReceivedCall) << " newstatus=" << LLVoiceClientStatusObserver::status2string(type) << " (mState=" << mState << ")" << LL_ENDL;
// status updates
switch(type)
@ -841,9 +845,9 @@ void LLVoiceChannelP2P::activate()
LLRecentPeople::instance().add(mOtherUserID);
//Default mic is ON on initiating/joining P2P calls
if (!gVoiceClient->getUserPTTState() && gVoiceClient->getPTTIsToggle())
if (!LLVoiceClient::getInstance()->getUserPTTState() && LLVoiceClient::getInstance()->getPTTIsToggle())
{
gVoiceClient->inputUserControlState(true);
LLVoiceClient::getInstance()->inputUserControlState(true);
}
}
}
@ -906,7 +910,7 @@ void LLVoiceChannelP2P::setSessionHandle(const std::string& handle, const std::s
void LLVoiceChannelP2P::setState(EState state)
{
llinfos << "P2P CALL STATE CHANGE: incoming=" << int(mReceivedCall) << " oldstate=" << mState << " newstate=" << state << llendl;
LL_INFOS("Voice") << "P2P CALL STATE CHANGE: incoming=" << int(mReceivedCall) << " oldstate=" << mState << " newstate=" << state << LL_ENDL;
if (mReceivedCall) // incoming call
{

Some files were not shown because too many files have changed in this diff Show More