automated merge

master
Loren Shih 2010-05-11 15:46:48 -04:00
commit 37dc96ccdd
123 changed files with 16723 additions and 9903 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
@ -208,13 +211,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())
{
@ -224,7 +233,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 << " "
@ -419,7 +428,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";
}
@ -525,10 +531,11 @@ std::string LLUrlEntryObjectIM::getLocation(const std::string &url) const
///
/// 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");
@ -544,7 +551,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");
@ -589,10 +596,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");
@ -610,7 +618,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
@ -709,7 +722,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

@ -460,7 +460,6 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd
}
//llinfos << "*** EXPANDED FILENAME: <" << expanded_filename << ">" << llendl;
return expanded_filename;
}
@ -566,27 +565,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();
@ -604,27 +599,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)
@ -379,6 +380,8 @@ set(viewer_SOURCE_FILES
llscrollingpanelparam.cpp
llsearchcombobox.cpp
llsearchhistory.cpp
llsecapi.cpp
llsechandler_basic.cpp
llselectmgr.cpp
llsidepanelappearance.cpp
llsidepanelinventory.cpp
@ -453,7 +456,6 @@ set(viewer_SOURCE_FILES
llurldispatcherlistener.cpp
llurlhistory.cpp
llurllineeditorctrl.cpp
llurlsimstring.cpp
llurlwhitelist.cpp
llvectorperfoptions.cpp
llversioninfo.cpp
@ -521,6 +523,7 @@ set(viewer_SOURCE_FILES
llvoicechannel.cpp
llvoiceclient.cpp
llvoicevisualizer.cpp
llvoicevivox.cpp
llvoinventorylistener.cpp
llvopartgroup.cpp
llvosky.cpp
@ -890,6 +893,8 @@ set(viewer_HEADER_FILES
llscrollingpanelparam.h
llsearchcombobox.h
llsearchhistory.h
llsecapi.h
llsechandler_basic.h
llselectmgr.h
llsidepanelappearance.h
llsidepanelinventory.h
@ -966,7 +971,6 @@ set(viewer_HEADER_FILES
llurldispatcherlistener.h
llurlhistory.h
llurllineeditorctrl.h
llurlsimstring.h
llurlwhitelist.h
llvectorperfoptions.h
llversioninfo.h
@ -1031,6 +1035,7 @@ set(viewer_HEADER_FILES
llvoicechannel.h
llvoiceclient.h
llvoicevisualizer.h
llvoicevivox.h
llvoinventorylistener.h
llvopartgroup.h
llvosky.h
@ -1426,8 +1431,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_DEPENDENCIES
# The following commented dependencies are determined at variably at build time. Can't do this here.
@ -1644,6 +1649,8 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${WINDOWS_LIBRARIES}
${XMLRPCEPI_LIBRARIES}
${ELFIO_LIBRARIES}
${OPENSSL_LIBRARIES}
${CRYPTO_LIBRARIES}
${LLLOGIN_LIBRARIES}
${GOOGLE_PERFTOOLS_LIBRARIES}
)
@ -1820,6 +1827,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)
@ -1827,6 +1871,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

@ -1265,6 +1265,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>
@ -1641,6 +1652,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>
@ -2378,6 +2400,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>
@ -4458,6 +4503,17 @@
<key>Value</key>
<real>128.0</real>
</map>
<key>MapServerURL</key>
<map>
<key>Comment</key>
<string>World map URL template for locating map tiles</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>http://map.secondlife.com.s3.amazonaws.com/</string>
</map>
<key>MapShowEvents</key>
<map>
<key>Comment</key>
@ -7787,6 +7843,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>
@ -7996,6 +8063,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>ShowBetaGrids</key>
<map>
<key>Comment</key>
<string>Display the beta grids in the grid selection control.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>ShowCrosshairs</key>
<map>
<key>Comment</key>
@ -10462,6 +10540,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>
@ -10473,6 +10562,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>
@ -10605,6 +10716,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>
@ -10649,6 +10771,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

@ -3238,7 +3238,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;
}
@ -3382,7 +3382,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());
@ -2050,7 +2022,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"))
@ -2144,30 +2115,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");
@ -2248,18 +2206,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;
@ -2315,9 +2265,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");
@ -2538,7 +2488,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 down in llappviewerwin32
#ifdef LL_WINDOWS
@ -3915,7 +3865,7 @@ void LLAppViewer::sendLogoutRequest()
gLogoutMaxTime = LOGOUT_REQUEST_TIME;
mLogoutRequestSent = TRUE;
gVoiceClient->leaveChannel();
LLVoiceClient::getInstance()->leaveChannel();
//Set internal status variables and marker files
gLogoutInProgress = TRUE;
@ -4328,7 +4278,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
@ -4341,10 +4291,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

@ -193,7 +193,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

@ -286,7 +286,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

@ -301,7 +301,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());
}
}
@ -471,7 +471,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,7 +133,7 @@ LLCallFloater::~LLCallFloater()
if(LLVoiceClient::instanceExists())
{
LLVoiceClient::instance().removeObserver(this);
LLVoiceClient::getInstance()->removeObserver(this);
}
LLTransientFloaterMgr::getInstance()->removeControlView(this);
}
@ -207,7 +207,6 @@ void LLCallFloater::draw()
void LLCallFloater::onChange()
{
if (NULL == mParticipants) return;
updateParticipantsVoiceState();
// Add newly joined participants.
@ -237,11 +236,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
@ -251,7 +250,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)
@ -291,7 +289,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;
}
@ -470,16 +468,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 = LLVoiceClient::getInstance()->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()
@ -555,7 +552,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
@ -728,7 +725,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() && LLVoiceClient::getInstance()->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

@ -647,20 +647,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

@ -192,7 +192,7 @@ void LLNearbyChatToastPanel::init(LLSD& notification)
style_params_name.font.name(font_name);
style_params_name.font.size(font_style_size);
style_params_name.link_href = LLSLURL::buildCommand("agent",mFromID,"about");
style_params_name.link_href = LLSLURL("agent",mFromID,"about").getSLURLString();
msg_text->appendText(str_sender, FALSE, style_params_name);

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

@ -831,7 +831,7 @@ void LLFloaterBuyLandUI::updateNames()
else
{
mParcelSellerName =
LLSLURL::buildCommand("agent", parcelp->getOwnerID(), "inspect");
LLSLURL("agent", parcelp->getOwnerID(), "inspect").getSLURLString();
}
}
@ -860,7 +860,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

@ -192,7 +192,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"
@ -805,7 +804,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())
@ -817,7 +816,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);
@ -826,9 +825,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

@ -599,7 +599,7 @@ void LLFloaterPreference::onBtnOK()
llinfos << "Can't close preferences!" << llendl;
}
LLPanelLogin::refreshLocation( false );
LLPanelLogin::updateLocationCombo( false );
}
// static
@ -616,7 +616,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

@ -1145,7 +1145,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

@ -273,7 +273,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

@ -59,7 +59,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

@ -342,13 +342,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:
@ -923,7 +923,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)
@ -1720,7 +1720,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);
@ -1847,8 +1847,8 @@ LLCallDialog(payload)
void LLIncomingCallDialog::onLifetimeExpired()
{
// check whether a call is valid or not
if (LLVoiceClient::getInstance()->findSession(mPayload["caller_id"].asUUID()))
std::string session_handle = mPayload["session_handle"].asString();
if (LLVoiceClient::getInstance()->isValidChannel(session_handle))
{
// restart notification's timer if call is still valid
mLifetimeTimer.start();
@ -2083,10 +2083,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
@ -2174,11 +2174,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
{
@ -3090,7 +3087,7 @@ public:
return;
}
if(!LLVoiceClient::voiceEnabled() || !LLVoiceClient::getInstance()->voiceWorking())
if(!LLVoiceClient::getInstance()->voiceEnabled() || !LLVoiceClient::getInstance()->isVoiceWorking())
{
// Don't display voice invites unless the user has voice enabled.
return;

View File

@ -541,8 +541,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
@ -572,6 +571,7 @@ void LLInspectAvatar::updateVolumeSlider()
volume_slider->setEnabled( !is_muted );
F32 volume;
if (is_muted)
{
// it's clearer to display their volume as zero
@ -580,7 +580,7 @@ void LLInspectAvatar::updateVolumeSlider()
else
{
// actual volume
volume = gVoiceClient->getUserVolume(mAvatarID);
volume = LLVoiceClient::getInstance()->getUserVolume(mAvatarID);
}
volume_slider->setValue( (F64)volume );
}
@ -609,7 +609,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->fetch();
}
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

@ -683,9 +683,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(
@ -1043,7 +1042,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();
mMaturityButton->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,11 @@ 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("map-server-url");
requested_options.append("voice-config");
requested_options.append("tutorial_setting");
requested_options.append("login-flags");
requested_options.append("global-textures");
@ -155,20 +161,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 +251,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,
@ -452,20 +465,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"
@ -507,29 +506,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.
@ -561,7 +565,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
@ -650,7 +654,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

@ -164,7 +164,7 @@ BOOL LLPanelAvatarNotes::postBuild()
resetControls();
resetData();
gVoiceClient->addObserver((LLVoiceClientStatusObserver*)this);
LLVoiceClient::getInstance()->addObserver((LLVoiceClientStatusObserver*)this);
return TRUE;
}
@ -375,7 +375,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)
@ -519,7 +519,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();
@ -814,7 +814,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

@ -200,7 +200,7 @@ BOOL LLPanelGroup::postBuild()
mJoinText = panel_general->getChild<LLUICtrl>("join_cost_text");
}
gVoiceClient->addObserver(this);
LLVoiceClient::getInstance()->addObserver(this);
return TRUE;
}
@ -321,7 +321,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
@ -226,29 +221,17 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
LLLineEditor* edit = getChild<LLLineEditor>("password_edit");
if (edit) edit->setDrawAsterixes(TRUE);
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);
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 +287,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 +354,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()
{
@ -493,14 +454,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.
@ -509,7 +470,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)
@ -531,8 +492,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
@ -554,77 +515,127 @@ 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"] = CRED_IDENTIFIER_TYPE_ACCOUNT;
identifier["account_name"] = username;
if (LLPanelLogin::sInstance->mPasswordModified)
{
authenticator = LLSD::emptyMap();
// password is plaintext
authenticator["type"] = CRED_AUTHENTICATOR_TYPE_CLEAR;
authenticator["secret"] = password;
}
}
else
{
std::string first = username.substr(0, separator_index);
std::string last = username.substr(separator_index, username.npos);
LLStringUtil::trim(last);
if (last.find_first_of(' ') == last.npos)
{
LL_INFOS2("Credentials", "Authentication") << "agent: " << username << LL_ENDL;
// traditional firstname / lastname
identifier["type"] = CRED_IDENTIFIER_TYPE_AGENT;
identifier["first_name"] = first;
identifier["last_name"] = last;
if (LLPanelLogin::sInstance->mPasswordModified)
{
authenticator = LLSD::emptyMap();
authenticator["type"] = CRED_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
@ -644,64 +655,112 @@ 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;
}
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_text", show_server);
sInstance->childSetVisible("server_combo", show_server);
#endif
}
// static
void LLPanelLogin::updateLocationUI()
void LLPanelLogin::updateStartSLURL()
{
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 0:
{
LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_LAST));
break;
}
case 1:
{
LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME));
break;
}
default:
{
LLSLURL slurl = LLSLURL(combo->getValue().asString());
if(slurl.getType() == LLSLURL::LOCATION)
{
// we've changed the grid, so update the grid selection
LLStartUp::setStartSLURL(slurl);
}
break;
}
}
}
void LLPanelLogin::setLocation(const LLSLURL& slurl)
{
LLStartUp::setStartSLURL(slurl);
updateServer();
}
// static
void LLPanelLogin::closePanel()
{
@ -735,15 +794,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)
{
@ -775,11 +832,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());
@ -804,30 +860,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);
@ -860,7 +906,7 @@ void LLPanelLogin::loadLoginPage()
#endif
LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
// navigate to the "real" page
if (gSavedSettings.getBOOL("RegInClient"))
{
@ -909,39 +955,66 @@ 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;
}
updateStartSLURL();
std::string username = sInstance->childGetText("username_edit");
if(username.empty())
{
// user must type in something into the username field
LLNotificationsUtil::add("MustHaveAccountToLogIn");
}
else
{
// has both first and last name typed
sInstance->mCallback(0, sInstance->mCallbackData);
LLPointer<LLCredential> cred;
BOOL remember;
getFields(cred, remember);
std::string identifier_type;
cred->identifierType(identifier_type);
LLSD allowed_credential_types;
LLGridManager::getInstance()->getLoginIdentifierTypes(allowed_credential_types);
// check the typed in credential type against the credential types expected by the server.
for(LLSD::array_iterator i = allowed_credential_types.beginArray();
i != allowed_credential_types.endArray();
i++)
{
if(i->asString() == identifier_type)
{
// yay correct credential type
sInstance->mCallback(0, sInstance->mCallbackData);
return;
}
}
// Right now, maingrid is the only thing that is picky about
// credential format, as it doesn't yet allow account (single username)
// format creds. - Rox. James, we wanna fix the message when we change
// this.
LLNotificationsUtil::add("InvalidCredentialFormat");
}
}
}
@ -999,6 +1072,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)
{
// *TODO: use another way to notify user about enabled caps lock, see EXT-6858
@ -1006,54 +1081,88 @@ 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();
std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(!gSavedSettings.getBOOL("ShowBetaGrids"));
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)
@ -1066,3 +1175,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,15 @@ 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 setLocation(const LLSLURL& slurl);
static void updateLocationCombo(bool force_visible); // simply update the combo box
static void closePanel();
void setSiteIsAlive( bool alive );
@ -86,10 +83,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 +100,10 @@ private:
static void onPassKey(LLLineEditor* caller, void* user_data);
static void onSelectServer(LLUICtrl*, void*);
static void onServerComboLostFocus(LLFocusableElement*);
static void updateServerCombo();
static void updateStartSLURL();
static void updateLoginPanelLinks();
private:
LLPointer<LLUIImage> mLogoImage;
@ -111,8 +112,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

@ -624,7 +624,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();
@ -825,7 +825,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

@ -71,10 +71,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

@ -95,7 +95,7 @@ public:
void onChange()
{
uuid_set_t participant_uuids;
LLVoiceClient::getInstance()->getParticipantsUUIDSet(participant_uuids);
LLVoiceClient::getInstance()->getParticipantList(participant_uuids);
// check whether Avaline caller exists among voice participants
@ -558,9 +558,8 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
}
else
{
LLVoiceClient::participantState *participant = LLVoiceClient::getInstance()->findParticipantByID(avatar_id);
mAvatarList->addAvalineItem(avatar_id, mSpeakerMgr->getSessionID(), participant ? participant->mAccountName : LLTrans::getString("AvatarNameWaiting"));
std::string display_name = LLVoiceClient::getInstance()->getDisplayName(avatar_id);
mAvatarList->addAvalineItem(avatar_id, mSpeakerMgr->getSessionID(), display_name.empty() ? display_name : LLTrans::getString("AvatarNameWaiting"));
mAvalineUpdater->watchAvalineCaller(avatar_id);
}
adjustParticipant(avatar_id);
@ -854,7 +853,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() && LLVoiceClient::getInstance()->voiceWorking();
bool can_call = not_agent && LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();
return can_call;
}

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

@ -0,0 +1,194 @@
/**
* @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 <openssl/err.h>
#include <map>
#include "llhttpclient.h"
std::map<std::string, LLPointer<LLSecAPIHandler> > gHandlerMap;
LLPointer<LLSecAPIHandler> gSecAPIHandler;
void initializeSecHandler()
{
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
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();
try
{
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"];
}
}
catch (...)
{
// we could have corrupt data, so simply return a null login param if so
LL_WARNS("AppInit") << "Invalid credential" << LL_ENDL;
}
return result;
}
void LLCredential::identifierType(std::string &idType)
{
if(mIdentifier.has("type"))
{
idType = mIdentifier["type"].asString();
}
else {
idType = std::string();
}
}
void LLCredential::authenticatorType(std::string &idType)
{
if(mAuthenticator.has("type"))
{
idType = mAuthenticator["type"].asString();
}
else {
idType = std::string();
}
}

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

@ -0,0 +1,499 @@
/**
* @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);
}
#define CRED_IDENTIFIER_TYPE_ACCOUNT "account"
#define CRED_IDENTIFIER_TYPE_AGENT "agent"
#define CRED_AUTHENTICATOR_TYPE_CLEAR "clear"
#define CRED_AUTHENTICATOR_TYPE_HASH "hash"
//
// 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 void identifierType(std::string& idType);
virtual LLSD getAuthenticator() { return mAuthenticator; }
virtual void authenticatorType(std::string& authType);
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);
@ -836,42 +799,39 @@ bool idle_startup()
gViewerWindow->moveProgressViewToFront();
//reset the values that could have come in from a slurl
// DEV-42215: Make sure they're not empty -- gFirstname and gLastname
// DEV-42215: Make sure they're not empty -- gUserCredential
// might already have been set from gSavedSettings, and it's too bad
// to overwrite valid values with empty strings.
if (! gLoginHandler.getFirstName().empty() && ! gLoginHandler.getLastName().empty())
{
gFirstname = gLoginHandler.getFirstName();
gLastname = gLoginHandler.getLastName();
LL_DEBUGS("LLStartup") << "STATE_LOGIN_CLEANUP: setting gFirstname, gLastname from gLoginHandler: '" << gFirstname << "' '" << gLastname << "'" << LL_ENDL;
}
if (show_connect_box)
{
// TODO if not use viewer auth
// Load all the name information out of the login view
LLPanelLogin::getFields(&gFirstname, &gLastname, &gPassword);
LLPanelLogin::getFields(gUserCredential, gRememberPassword);
// end TODO
// HACK: Try to make not jump on login
gKeyboard->resetKeys();
}
if (!gFirstname.empty() && !gLastname.empty())
{
gSavedSettings.setString("FirstName", gFirstname);
gSavedSettings.setString("LastName", gLastname);
LL_INFOS("AppInit") << "Attempting login as: " << gFirstname << " " << gLastname << LL_ENDL;
gDebugInfo["LoginName"] = gFirstname + " " + gLastname;
// save the credentials
std::string userid = "unknown";
if(gUserCredential.notNull())
{
userid = gUserCredential->userID();
gSecAPIHandler->saveCredential(gUserCredential, gRememberPassword);
}
gSavedSettings.setBOOL("RememberPassword", gRememberPassword);
LL_INFOS("AppInit") << "Attempting login as: " << userid << LL_ENDL;
gDebugInfo["LoginName"] = userid;
// create necessary directories
// *FIX: these mkdir's should error check
gDirUtilp->setLindenUserDir(gFirstname, gLastname);
gDirUtilp->setLindenUserDir(userid);
LLFile::mkdir(gDirUtilp->getLindenUserDir());
// Set PerAccountSettingsFile to the default value.
std::string per_account_settings_file = LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount");
gSavedSettings.setString("PerAccountSettingsFile",
gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT,
LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount")));
@ -900,9 +860,8 @@ bool idle_startup()
{
gDirUtilp->setChatLogsDir(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
}
gDirUtilp->setPerAccountChatLogsDir(userid);
gDirUtilp->setPerAccountChatLogsDir(gFirstname, gLastname);
LLFile::mkdir(gDirUtilp->getChatLogsDir());
LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir());
@ -923,11 +882,7 @@ bool idle_startup()
if (show_connect_box)
{
std::string location;
LLPanelLogin::getLocation( location );
LLURLSimString::setString( location );
// END TODO
LLSLURL slurl;
LLPanelLogin::closePanel();
}
@ -951,26 +906,21 @@ bool idle_startup()
// their last location, or some URL "-url //sim/x/y[/z]"
// All accounts have both a home and a last location, and we don't support
// more locations than that. Choose the appropriate one. JC
if (LLURLSimString::parse())
{
// a startup URL was specified
agent_location_id = START_LOCATION_ID_URL;
// doesn't really matter what location_which is, since
// gAgentStartLookAt will be overwritten when the
// UserLoginLocationReply arrives
location_which = START_LOCATION_ID_LAST;
}
else if (gSavedSettings.getString("LoginLocation") == "last" )
{
agent_location_id = START_LOCATION_ID_LAST; // last location
location_which = START_LOCATION_ID_LAST;
}
else
{
agent_location_id = START_LOCATION_ID_HOME; // home
location_which = START_LOCATION_ID_HOME;
}
switch (LLStartUp::getStartSLURL().getType())
{
case LLSLURL::LOCATION:
agent_location_id = START_LOCATION_ID_URL;
location_which = START_LOCATION_ID_LAST;
break;
case LLSLURL::LAST_LOCATION:
agent_location_id = START_LOCATION_ID_LAST;
location_which = START_LOCATION_ID_LAST;
break;
default:
agent_location_id = START_LOCATION_ID_HOME;
location_which = START_LOCATION_ID_HOME;
break;
}
gViewerWindow->getWindow()->setCursor(UI_CURSOR_WAIT);
@ -997,7 +947,7 @@ bool idle_startup()
if(STATE_LOGIN_AUTH_INIT == LLStartUp::getStartupState())
{
gDebugInfo["GridName"] = LLViewerLogin::getInstance()->getGridLabel();
gDebugInfo["GridName"] = LLGridManager::getInstance()->getGridLabel();
// Update progress status and the display loop.
auth_desc = LLTrans::getString("LoginInProgress");
@ -1021,11 +971,7 @@ bool idle_startup()
// This call to LLLoginInstance::connect() starts the
// authentication process.
LLSD credentials;
credentials["first"] = gFirstname;
credentials["last"] = gLastname;
credentials["passwd"] = gPassword;
login->connect(credentials);
login->connect(gUserCredential);
LLStartUp::setStartupState( STATE_LOGIN_CURL_UNSTUCK );
return FALSE;
@ -1050,10 +996,11 @@ bool idle_startup()
{
LL_INFOS("LLStartup") << "Login failed, LLLoginInstance::getResponse(): "
<< LLLoginInstance::getInstance()->getResponse() << LL_ENDL;
LLSD response = LLLoginInstance::getInstance()->getResponse();
// Still have error conditions that may need some
// sort of handling.
std::string reason_response = LLLoginInstance::getInstance()->getResponse("reason");
std::string message_response = LLLoginInstance::getInstance()->getResponse("message");
std::string reason_response = response["reason"];
std::string message_response = response["message"];
if(!message_response.empty())
{
@ -1073,8 +1020,8 @@ bool idle_startup()
if(reason_response == "key")
{
// Couldn't login because user/password is wrong
// Clear the password
gPassword = "";
// Clear the credential
gUserCredential->clearAuthenticator();
}
if(reason_response == "update"
@ -1087,18 +1034,65 @@ bool idle_startup()
LLLoginInstance::getInstance()->disconnect();
LLAppViewer::instance()->forceQuit();
}
else
else
{
// Don't pop up a notification in the TOS case because
// LLFloaterTOS::onCancel() already scolded the user.
if (reason_response != "tos")
if (reason_response != "tos")
{
LLSD args;
args["ERROR_MESSAGE"] = emsg.str();
LL_INFOS("LLStartup") << "Notification: " << args << LL_ENDL;
LLNotificationsUtil::add("ErrorMessage", args, LLSD(), login_alert_done);
}
// Don't pop up a notification in the TOS case because
// LLFloaterTOS::onCancel() already scolded the user.
std::string error_code;
if(response.has("errorcode"))
{
error_code = response["errorcode"].asString();
}
if ((reason_response == "CURLError") &&
(error_code == "SSL_CACERT" || error_code == "SSL_PEER_CERTIFICATE") &&
response.has("certificate"))
{
// This was a certificate error, so grab the certificate
// and throw up the appropriate dialog.
LLPointer<LLCertificate> certificate = gSecAPIHandler->getCertificate(response["certificate"]);
if(certificate)
{
LLSD args = transform_cert_args(certificate);
if(error_code == "SSL_CACERT")
{
// if we are handling an untrusted CA, throw up the dialog
// with the 'trust this CA' button.
LLNotificationsUtil::add("TrustCertificateError", args, response,
trust_cert_done);
show_connect_box = true;
}
else
{
// the certificate exception returns a unique string for each type of exception.
// we grab this string via the LLUserAuth object, and use that to grab the localized
// string.
args["REASON"] = LLTrans::getString(message_response);
LLNotificationsUtil::add("GeneralCertificateError", args, response,
general_cert_done);
reset_login();
gSavedSettings.setBOOL("AutoLogin", FALSE);
show_connect_box = true;
}
}
}
else
{
// This wasn't a certificate error, so throw up the normal
// notificatioin message.
LLSD args;
args["ERROR_MESSAGE"] = emsg.str();
LL_INFOS("LLStartup") << "Notification: " << args << LL_ENDL;
LLNotificationsUtil::add("ErrorMessage", args, LLSD(), login_alert_done);
}
}
//setup map of datetime strings to codes and slt & local time offset from utc
// *TODO: Does this need to be here?
LLStringOps::setupDatetimeInfo (false);
@ -1111,7 +1105,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
@ -1122,6 +1121,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);
}
@ -3044,6 +3023,37 @@ bool process_login_success_response()
LLStringOps::setupDatetimeInfo(pacific_daylight_time);
}
// set up the voice configuration. Ultimately, we should pass this up as part of each voice
// channel if we need to move to multiple voice servers per grid.
LLSD voice_config_info = response["voice-config"];
if(voice_config_info.has("VoiceServerType"))
{
gSavedSettings.setString("VoiceServerType", voice_config_info["VoiceServerType"].asString());
}
// Request the map server url
std::string map_server_url = response["map-server-url"];
if(!map_server_url.empty())
{
gSavedSettings.setString("MapServerURL", map_server_url);
}
// Default male and female avatars allowing the user to choose their avatar on first login.
// These may be passed up by SLE to allow choice of enterprise avatars instead of the standard
// "new ruth." Not to be confused with 'initial-outfit' below
LLSD newuser_config = response["newuser-config"];
if(newuser_config.has("DefaultFemaleAvatar"))
{
gSavedSettings.setString("DefaultFemaleAvatar", newuser_config["DefaultFemaleAvatar"].asString());
}
if(newuser_config.has("DefaultMaleAvatar"))
{
gSavedSettings.setString("DefaultMaleAvatar", newuser_config["DefaultMaleAvatar"].asString());
}
// Initial outfit for the user.
// QUESTION: Why can't we simply simply set the users outfit directly
// from a web page into the user info on the server? - Roxie
LLSD initial_outfit = response["initial-outfit"][0];
if(initial_outfit.size())
{
@ -3097,7 +3107,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

@ -443,7 +443,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"
@ -299,10 +298,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

@ -430,7 +430,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" );
}
@ -446,7 +446,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
@ -3468,7 +3468,7 @@ void set_god_level(U8 god_level)
if(gViewerWindow)
{
gViewerWindow->setMenuBackgroundColor(god_level > GOD_NOT,
LLViewerLogin::getInstance()->isInProductionGrid());
LLGridManager::getInstance()->isInProductionGrid());
}
LLSD args;
@ -3508,7 +3508,7 @@ BOOL check_toggle_hacked_godmode(void*)
bool enable_toggle_hacked_godmode(void*)
{
return !LLViewerLogin::getInstance()->isInProductionGrid();
return !LLGridManager::getInstance()->isInProductionGrid();
}
#endif
@ -4381,7 +4381,7 @@ BOOL enable_take()
return TRUE;
#else
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
if (!LLViewerLogin::getInstance()->isInProductionGrid()
if (!LLGridManager::getInstance()->isInProductionGrid()
&& gAgent.isGodlike())
{
return TRUE;
@ -4994,7 +4994,7 @@ bool enable_object_delete()
TRUE;
#else
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
(!LLViewerLogin::getInstance()->isInProductionGrid()
(!LLGridManager::getInstance()->isInProductionGrid()
&& gAgent.isGodlike()) ||
# endif
LLSelectMgr::getInstance()->canDoDelete();
@ -6638,7 +6638,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
{
@ -6700,7 +6700,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

@ -1783,9 +1783,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");
@ -2514,10 +2514,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;
// Note: lie to Nearby Chat, pretending that this is NOT an IM, because
@ -2612,7 +2609,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;
args["MATURITY_STR"] = region_access_str;
args["MATURITY_ICON"] = region_access_icn;
@ -2684,7 +2681,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
@ -3448,7 +3445,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);
@ -5849,7 +5848,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)
@ -6292,7 +6293,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,477 @@
#include "llviewerprecompiledheaders.h"
#include "llviewernetwork.h"
#include "llevents.h"
#include "net.h"
#include "llviewercontrol.h"
#include "lllogin.h"
#include "llsdserialize.h"
#include "llsecapi.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);
addSystemGrid("Agni",
MAINGRID,
"https://login.agni.lindenlab.com/cgi-bin/login.cgi",
"https://secondlife.com/helpers/",
DEFAULT_LOGIN_PAGE);
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;
mGrid = MAINGRID;
}
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/";
}
if (!grid_data.has(GRID_LOGIN_IDENTIFIER_TYPES))
{
// non system grids and grids that haven't already been configured with values
// get both types of credentials.
grid_data[GRID_LOGIN_IDENTIFIER_TYPES] = LLSD::emptyArray();
grid_data[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_AGENT);
grid_data[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_ACCOUNT);
}
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_IDENTIFIER_TYPES] = LLSD::emptyArray();
grid[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_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 +512,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,134 @@
#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 MAINGRID "util.agni.lindenlab.com"
#define GRID_LOGIN_IDENTIFIER_TYPES "login_identifier_types"
// 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"
#include <boost/scoped_ptr.hpp>
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]; }
void getLoginIdentifierTypes(LLSD& idTypes) { idTypes = mGridList[mGrid][GRID_LOGIN_IDENTIFIER_TYPES]; }
// 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

@ -4727,7 +4727,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;
@ -4764,7 +4764,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;
@ -4788,7 +4788,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;
@ -4812,7 +4812,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;
@ -4836,7 +4836,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;
@ -4860,7 +4860,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,16 @@ 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_COPY;
};
}
}
if (prim_media_dnd_enabled)
@ -957,7 +952,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 +1069,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 +1091,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 +1950,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 +1971,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 +2195,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

@ -1268,7 +1268,7 @@ void LLVOAvatar::initInstance(void)
//VTPause(); // VTune
mVoiceVisualizer->setVoiceEnabled( gVoiceClient->getVoiceEnabled( mID ) );
mVoiceVisualizer->setVoiceEnabled( LLVoiceClient::getInstance()->getVoiceEnabled( mID ) );
}
const LLVector3 LLVOAvatar::getRenderPosition() const
@ -2199,8 +2199,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 );
@ -2263,7 +2263,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())
{
@ -2272,7 +2272,7 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
//printf( "gAwayTimer.reset();\n" );
}
mVoiceVisualizer->setSpeakingAmplitude( gVoiceClient->getCurrentPower( mID ) );
mVoiceVisualizer->setSpeakingAmplitude( LLVoiceClient::getInstance()->getCurrentPower( mID ) );
if( isSelf() )
{
@ -2501,7 +2501,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;

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