diff options
21 files changed, 7804 insertions, 7804 deletions
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index bc66832ad0..7f4f670ed0 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -1,2249 +1,2249 @@ -/** 
 - * @file llsdserialize.cpp
 - * @author Phoenix
 - * @date 2006-03-05
 - * @brief Implementation of LLSD parsers and formatters
 - *
 - * $LicenseInfo:firstyear=2006&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc.
 - * 
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - * 
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - * 
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - * 
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#include "linden_common.h"
 -#include "llsdserialize.h"
 -#include "llpointer.h"
 -#include "llstreamtools.h" // for fullread
 -
 -#include <iostream>
 -#include "apr_base64.h"
 -
 -#ifdef LL_STANDALONE
 -# include <zlib.h>
 -#else
 -# include "zlib/zlib.h"  // for davep's dirty little zip functions
 -#endif
 -
 -#if !LL_WINDOWS
 -#include <netinet/in.h> // htonl & ntohl
 -#endif
 -
 -#include "lldate.h"
 -#include "llsd.h"
 -#include "llstring.h"
 -#include "lluri.h"
 -
 -// File constants
 -static const int MAX_HDR_LEN = 20;
 -static const char LEGACY_NON_HEADER[] = "<llsd>";
 -const std::string LLSD_BINARY_HEADER("LLSD/Binary");
 -const std::string LLSD_XML_HEADER("LLSD/XML");
 -
 -//used to deflate a gzipped asset (currently used for navmeshes)
 -#define windowBits 15
 -#define ENABLE_ZLIB_GZIP 32
 -
 -/**
 - * LLSDSerialize
 - */
 -
 -// static
 -void LLSDSerialize::serialize(const LLSD& sd, std::ostream& str, ELLSD_Serialize type, U32 options)
 -{
 -	LLPointer<LLSDFormatter> f = NULL;
 -
 -	switch (type)
 -	{
 -	case LLSD_BINARY:
 -		str << "<? " << LLSD_BINARY_HEADER << " ?>\n";
 -		f = new LLSDBinaryFormatter;
 -		break;
 -
 -	case LLSD_XML:
 -		str << "<? " << LLSD_XML_HEADER << " ?>\n";
 -		f = new LLSDXMLFormatter;
 -		break;
 -
 -	default:
 -		llwarns << "serialize request for unknown ELLSD_Serialize" << llendl;
 -	}
 -
 -	if (f.notNull())
 -	{
 -		f->format(sd, str, options);
 -	}
 -}
 -
 -// static
 -bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, S32 max_bytes)
 -{
 -	LLPointer<LLSDParser> p = NULL;
 -	char hdr_buf[MAX_HDR_LEN + 1] = ""; /* Flawfinder: ignore */
 -	int i;
 -	int inbuf = 0;
 -	bool legacy_no_header = false;
 -	bool fail_if_not_legacy = false;
 -	std::string header;
 -
 -	/*
 -	 * Get the first line before anything.
 -	 */
 -	str.get(hdr_buf, MAX_HDR_LEN, '\n');
 -	if (str.fail())
 -	{
 -		str.clear();
 -		fail_if_not_legacy = true;
 -	}
 -
 -	if (!strncasecmp(LEGACY_NON_HEADER, hdr_buf, strlen(LEGACY_NON_HEADER))) /* Flawfinder: ignore */
 -	{
 -		legacy_no_header = true;
 -		inbuf = (int)str.gcount();
 -	}
 -	else
 -	{
 -		if (fail_if_not_legacy)
 -			goto fail;
 -		/*
 -		* Remove the newline chars
 -		*/
 -		for (i = 0; i < MAX_HDR_LEN; i++)
 -		{
 -			if (hdr_buf[i] == 0 || hdr_buf[i] == '\r' ||
 -				hdr_buf[i] == '\n')
 -			{
 -				hdr_buf[i] = 0;
 -				break;
 -			}
 -		}
 -		header = hdr_buf;
 -
 -		std::string::size_type start = std::string::npos;
 -		std::string::size_type end = std::string::npos;
 -		start = header.find_first_not_of("<? ");
 -		if (start != std::string::npos)
 -		{
 -			end = header.find_first_of(" ?", start);
 -		}
 -		if ((start == std::string::npos) || (end == std::string::npos))
 -			goto fail;
 -
 -		header = header.substr(start, end - start);
 -		ws(str);
 -	}
 -	/*
 -	 * Create the parser as appropriate
 -	 */
 -	if (legacy_no_header)
 -	{	// Create a LLSD XML parser, and parse the first chunk read above
 -		LLSDXMLParser* x = new LLSDXMLParser();
 -		x->parsePart(hdr_buf, inbuf);	// Parse the first part that was already read
 -		x->parseLines(str, sd);			// Parse the rest of it
 -		delete x;
 -		return true;
 -	}
 -
 -	if (header == LLSD_BINARY_HEADER)
 -	{
 -		p = new LLSDBinaryParser;
 -	}
 -	else if (header == LLSD_XML_HEADER)
 -	{
 -		p = new LLSDXMLParser;
 -	}
 -	else
 -	{
 -		llwarns << "deserialize request for unknown ELLSD_Serialize" << llendl;
 -	}
 -
 -	if (p.notNull())
 -	{
 -		p->parse(str, sd, max_bytes);
 -		return true;
 -	}
 -
 -fail:
 -	llwarns << "deserialize LLSD parse failure" << llendl;
 -	return false;
 -}
 -
 -/**
 - * Endian handlers
 - */
 -#if LL_BIG_ENDIAN
 -U64 ll_htonll(U64 hostlonglong) { return hostlonglong; }
 -U64 ll_ntohll(U64 netlonglong) { return netlonglong; }
 -F64 ll_htond(F64 hostlonglong) { return hostlonglong; }
 -F64 ll_ntohd(F64 netlonglong) { return netlonglong; }
 -#else
 -// I read some comments one a indicating that doing an integer add
 -// here would be faster than a bitwise or. For now, the or has
 -// programmer clarity, since the intended outcome matches the
 -// operation.
 -U64 ll_htonll(U64 hostlonglong)
 -{
 -	return ((U64)(htonl((U32)((hostlonglong >> 32) & 0xFFFFFFFF))) |
 -			((U64)(htonl((U32)(hostlonglong & 0xFFFFFFFF))) << 32));
 -}
 -U64 ll_ntohll(U64 netlonglong)
 -{
 -	return ((U64)(ntohl((U32)((netlonglong >> 32) & 0xFFFFFFFF))) |
 -			((U64)(ntohl((U32)(netlonglong & 0xFFFFFFFF))) << 32));
 -}
 -union LLEndianSwapper
 -{
 -	F64 d;
 -	U64 i;
 -};
 -F64 ll_htond(F64 hostdouble)
 -{
 -	LLEndianSwapper tmp;
 -	tmp.d = hostdouble;
 -	tmp.i = ll_htonll(tmp.i);
 -	return tmp.d;
 -}
 -F64 ll_ntohd(F64 netdouble)
 -{
 -	LLEndianSwapper tmp;
 -	tmp.d = netdouble;
 -	tmp.i = ll_ntohll(tmp.i);
 -	return tmp.d;
 -}
 -#endif
 -
 -/**
 - * Local functions.
 - */
 -/**
 - * @brief Figure out what kind of string it is (raw or delimited) and handoff.
 - *
 - * @param istr The stream to read from.
 - * @param value [out] The string which was found.
 - * @param max_bytes The maximum possible length of the string. Passing in
 - * a negative value will skip this check.
 - * @return Returns number of bytes read off of the stream. Returns
 - * PARSE_FAILURE (-1) on failure.
 - */
 -int deserialize_string(std::istream& istr, std::string& value, S32 max_bytes);
 -
 -/**
 - * @brief Parse a delimited string. 
 - *
 - * @param istr The stream to read from, with the delimiter already popped.
 - * @param value [out] The string which was found.
 - * @param d The delimiter to use.
 - * @return Returns number of bytes read off of the stream. Returns
 - * PARSE_FAILURE (-1) on failure.
 - */
 -int deserialize_string_delim(std::istream& istr, std::string& value, char d);
 -
 -/**
 - * @brief Read a raw string off the stream.
 - *
 - * @param istr The stream to read from, with the (len) parameter
 - * leading the stream.
 - * @param value [out] The string which was found.
 - * @param d The delimiter to use.
 - * @param max_bytes The maximum possible length of the string. Passing in
 - * a negative value will skip this check.
 - * @return Returns number of bytes read off of the stream. Returns
 - * PARSE_FAILURE (-1) on failure.
 - */
 -int deserialize_string_raw(
 -	std::istream& istr,
 -	std::string& value,
 -	S32 max_bytes);
 -
 -/**
 - * @brief helper method for dealing with the different notation boolean format.
 - *
 - * @param istr The stream to read from with the leading character stripped.
 - * @param data [out] the result of the parse.
 - * @param compare The string to compare the boolean against
 - * @param vale The value to assign to data if the parse succeeds.
 - * @return Returns number of bytes read off of the stream. Returns
 - * PARSE_FAILURE (-1) on failure.
 - */
 -int deserialize_boolean(
 -	std::istream& istr,
 -	LLSD& data,
 -	const std::string& compare,
 -	bool value);
 -
 -/**
 - * @brief Do notation escaping of a string to an ostream.
 - *
 - * @param value The string to escape and serialize
 - * @param str The stream to serialize to.
 - */
 -void serialize_string(const std::string& value, std::ostream& str);
 -
 -
 -/**
 - * Local constants.
 - */
 -static const std::string NOTATION_TRUE_SERIAL("true");
 -static const std::string NOTATION_FALSE_SERIAL("false");
 -
 -static const char BINARY_TRUE_SERIAL = '1';
 -static const char BINARY_FALSE_SERIAL = '0';
 -
 -
 -/**
 - * LLSDParser
 - */
 -LLSDParser::LLSDParser()
 -	: mCheckLimits(true), mMaxBytesLeft(0), mParseLines(false)
 -{
 -}
 -
 -// virtual
 -LLSDParser::~LLSDParser()
 -{ }
 -
 -S32 LLSDParser::parse(std::istream& istr, LLSD& data, S32 max_bytes)
 -{
 -	mCheckLimits = (LLSDSerialize::SIZE_UNLIMITED == max_bytes) ? false : true;
 -	mMaxBytesLeft = max_bytes;
 -	return doParse(istr, data);
 -}
 -
 -
 -// Parse using routine to get() lines, faster than parse()
 -S32 LLSDParser::parseLines(std::istream& istr, LLSD& data)
 -{
 -	mCheckLimits = false;
 -	mParseLines = true;
 -	return doParse(istr, data);
 -}
 -
 -
 -int LLSDParser::get(std::istream& istr) const
 -{
 -	if(mCheckLimits) --mMaxBytesLeft;
 -	return istr.get();
 -}
 -
 -std::istream& LLSDParser::get(
 -	std::istream& istr,
 -	char* s,
 -	std::streamsize n,
 -	char delim) const
 -{
 -	istr.get(s, n, delim);
 -	if(mCheckLimits) mMaxBytesLeft -= (int)istr.gcount();
 -	return istr;
 -}
 -
 -std::istream& LLSDParser::get(
 -		std::istream& istr,
 -		std::streambuf& sb,
 -		char delim) const		
 -{
 -	istr.get(sb, delim);
 -	if(mCheckLimits) mMaxBytesLeft -= (int)istr.gcount();
 -	return istr;
 -}
 -
 -std::istream& LLSDParser::ignore(std::istream& istr) const
 -{
 -	istr.ignore();
 -	if(mCheckLimits) --mMaxBytesLeft;
 -	return istr;
 -}
 -
 -std::istream& LLSDParser::putback(std::istream& istr, char c) const
 -{
 -	istr.putback(c);
 -	if(mCheckLimits) ++mMaxBytesLeft;
 -	return istr;
 -}
 -
 -std::istream& LLSDParser::read(
 -	std::istream& istr,
 -	char* s,
 -	std::streamsize n) const
 -{
 -	istr.read(s, n);
 -	if(mCheckLimits) mMaxBytesLeft -= (int)istr.gcount();
 -	return istr;
 -}
 -
 -void LLSDParser::account(S32 bytes) const
 -{
 -	if(mCheckLimits) mMaxBytesLeft -= bytes;
 -}
 -
 -
 -/**
 - * LLSDNotationParser
 - */
 -LLSDNotationParser::LLSDNotationParser()
 -{
 -}	
 -
 -// virtual
 -LLSDNotationParser::~LLSDNotationParser()
 -{ }
 -
 -// virtual
 -S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data) const
 -{
 -	// map: { string:object, string:object }
 -	// array: [ object, object, object ]
 -	// undef: !
 -	// boolean: true | false | 1 | 0 | T | F | t | f | TRUE | FALSE
 -	// integer: i####
 -	// real: r####
 -	// uuid: u####
 -	// string: "g'day" | 'have a "nice" day' | s(size)"raw data"
 -	// uri: l"escaped"
 -	// date: d"YYYY-MM-DDTHH:MM:SS.FFZ"
 -	// binary: b##"ff3120ab1" | b(size)"raw data"
 -	char c;
 -	c = istr.peek();
 -	while(isspace(c))
 -	{
 -		// pop the whitespace.
 -		c = get(istr);
 -		c = istr.peek();
 -		continue;
 -	}
 -	if(!istr.good())
 -	{
 -		return 0;
 -	}
 -	S32 parse_count = 1;
 -	switch(c)
 -	{
 -	case '{':
 -	{
 -		S32 child_count = parseMap(istr, data);
 -		if((child_count == PARSE_FAILURE) || data.isUndefined())
 -		{
 -			parse_count = PARSE_FAILURE;
 -		}
 -		else
 -		{
 -			parse_count += child_count;
 -		}
 -		if(istr.fail())
 -		{
 -			llinfos << "STREAM FAILURE reading map." << llendl;
 -			parse_count = PARSE_FAILURE;
 -		}
 -		break;
 -	}
 -
 -	case '[':
 -	{
 -		S32 child_count = parseArray(istr, data);
 -		if((child_count == PARSE_FAILURE) || data.isUndefined())
 -		{
 -			parse_count = PARSE_FAILURE;
 -		}
 -		else
 -		{
 -			parse_count += child_count;
 -		}
 -		if(istr.fail())
 -		{
 -			llinfos << "STREAM FAILURE reading array." << llendl;
 -			parse_count = PARSE_FAILURE;
 -		}
 -		break;
 -	}
 -
 -	case '!':
 -		c = get(istr);
 -		data.clear();
 -		break;
 -
 -	case '0':
 -		c = get(istr);
 -		data = false;
 -		break;
 -
 -	case 'F':
 -	case 'f':
 -		ignore(istr);
 -		c = istr.peek();
 -		if(isalpha(c))
 -		{
 -			int cnt = deserialize_boolean(
 -				istr,
 -				data,
 -				NOTATION_FALSE_SERIAL,
 -				false);
 -			if(PARSE_FAILURE == cnt) parse_count = cnt;
 -			else account(cnt);
 -		}
 -		else
 -		{
 -			data = false;
 -		}
 -		if(istr.fail())
 -		{
 -			llinfos << "STREAM FAILURE reading boolean." << llendl;
 -			parse_count = PARSE_FAILURE;
 -		}
 -		break;
 -
 -	case '1':
 -		c = get(istr);
 -		data = true;
 -		break;
 -
 -	case 'T':
 -	case 't':
 -		ignore(istr);
 -		c = istr.peek();
 -		if(isalpha(c))
 -		{
 -			int cnt = deserialize_boolean(istr,data,NOTATION_TRUE_SERIAL,true);
 -			if(PARSE_FAILURE == cnt) parse_count = cnt;
 -			else account(cnt);
 -		}
 -		else
 -		{
 -			data = true;
 -		}
 -		if(istr.fail())
 -		{
 -			llinfos << "STREAM FAILURE reading boolean." << llendl;
 -			parse_count = PARSE_FAILURE;
 -		}
 -		break;
 -
 -	case 'i':
 -	{
 -		c = get(istr);
 -		S32 integer = 0;
 -		istr >> integer;
 -		data = integer;
 -		if(istr.fail())
 -		{
 -			llinfos << "STREAM FAILURE reading integer." << llendl;
 -			parse_count = PARSE_FAILURE;
 -		}
 -		break;
 -	}
 -
 -	case 'r':
 -	{
 -		c = get(istr);
 -		F64 real = 0.0;
 -		istr >> real;
 -		data = real;
 -		if(istr.fail())
 -		{
 -			llinfos << "STREAM FAILURE reading real." << llendl;
 -			parse_count = PARSE_FAILURE;
 -		}
 -		break;
 -	}
 -
 -	case 'u':
 -	{
 -		c = get(istr);
 -		LLUUID id;
 -		istr >> id;
 -		data = id;
 -		if(istr.fail())
 -		{
 -			llinfos << "STREAM FAILURE reading uuid." << llendl;
 -			parse_count = PARSE_FAILURE;
 -		}
 -		break;
 -	}
 -
 -	case '\"':
 -	case '\'':
 -	case 's':
 -		if(!parseString(istr, data))
 -		{
 -			parse_count = PARSE_FAILURE;
 -		}
 -		if(istr.fail())
 -		{
 -			llinfos << "STREAM FAILURE reading string." << llendl;
 -			parse_count = PARSE_FAILURE;
 -		}
 -		break;
 -
 -	case 'l':
 -	{
 -		c = get(istr); // pop the 'l'
 -		c = get(istr); // pop the delimiter
 -		std::string str;
 -		int cnt = deserialize_string_delim(istr, str, c);
 -		if(PARSE_FAILURE == cnt)
 -		{
 -			parse_count = PARSE_FAILURE;
 -		}
 -		else
 -		{
 -			data = LLURI(str);
 -			account(cnt);
 -		}
 -		if(istr.fail())
 -		{
 -			llinfos << "STREAM FAILURE reading link." << llendl;
 -			parse_count = PARSE_FAILURE;
 -		}
 -		break;
 -	}
 -
 -	case 'd':
 -	{
 -		c = get(istr); // pop the 'd'
 -		c = get(istr); // pop the delimiter
 -		std::string str;
 -		int cnt = deserialize_string_delim(istr, str, c);
 -		if(PARSE_FAILURE == cnt)
 -		{
 -			parse_count = PARSE_FAILURE;
 -		}
 -		else
 -		{
 -			data = LLDate(str);
 -			account(cnt);
 -		}
 -		if(istr.fail())
 -		{
 -			llinfos << "STREAM FAILURE reading date." << llendl;
 -			parse_count = PARSE_FAILURE;
 -		}
 -		break;
 -	}
 -
 -	case 'b':
 -		if(!parseBinary(istr, data))
 -		{
 -			parse_count = PARSE_FAILURE;
 -		}
 -		if(istr.fail())
 -		{
 -			llinfos << "STREAM FAILURE reading data." << llendl;
 -			parse_count = PARSE_FAILURE;
 -		}
 -		break;
 -
 -	default:
 -		parse_count = PARSE_FAILURE;
 -		llinfos << "Unrecognized character while parsing: int(" << (int)c
 -			<< ")" << llendl;
 -		break;
 -	}
 -	if(PARSE_FAILURE == parse_count)
 -	{
 -		data.clear();
 -	}
 -	return parse_count;
 -}
 -
 -S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map) const
 -{
 -	// map: { string:object, string:object }
 -	map = LLSD::emptyMap();
 -	S32 parse_count = 0;
 -	char c = get(istr);
 -	if(c == '{')
 -	{
 -		// eat commas, white
 -		bool found_name = false;
 -		std::string name;
 -		c = get(istr);
 -		while(c != '}' && istr.good())
 -		{
 -			if(!found_name)
 -			{
 -				if((c == '\"') || (c == '\'') || (c == 's'))
 -				{
 -					putback(istr, c);
 -					found_name = true;
 -					int count = deserialize_string(istr, name, mMaxBytesLeft);
 -					if(PARSE_FAILURE == count) return PARSE_FAILURE;
 -					account(count);
 -				}
 -				c = get(istr);
 -			}
 -			else
 -			{
 -				if(isspace(c) || (c == ':'))
 -				{
 -					c = get(istr);
 -					continue;
 -				}
 -				putback(istr, c);
 -				LLSD child;
 -				S32 count = doParse(istr, child);
 -				if(count > 0)
 -				{
 -					// There must be a value for every key, thus
 -					// child_count must be greater than 0.
 -					parse_count += count;
 -					map.insert(name, child);
 -				}
 -				else
 -				{
 -					return PARSE_FAILURE;
 -				}
 -				found_name = false;
 -				c = get(istr);
 -			}
 -		}
 -		if(c != '}')
 -		{
 -			map.clear();
 -			return PARSE_FAILURE;
 -		}
 -	}
 -	return parse_count;
 -}
 -
 -S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array) const
 -{
 -	// array: [ object, object, object ]
 -	array = LLSD::emptyArray();
 -	S32 parse_count = 0;
 -	char c = get(istr);
 -	if(c == '[')
 -	{
 -		// eat commas, white
 -		c = get(istr);
 -		while((c != ']') && istr.good())
 -		{
 -			LLSD child;
 -			if(isspace(c) || (c == ','))
 -			{
 -				c = get(istr);
 -				continue;
 -			}
 -			putback(istr, c);
 -			S32 count = doParse(istr, child);
 -			if(PARSE_FAILURE == count)
 -			{
 -				return PARSE_FAILURE;
 -			}
 -			else
 -			{
 -				parse_count += count;
 -				array.append(child);
 -			}
 -			c = get(istr);
 -		}
 -		if(c != ']')
 -		{
 -			return PARSE_FAILURE;
 -		}
 -	}
 -	return parse_count;
 -}
 -
 -bool LLSDNotationParser::parseString(std::istream& istr, LLSD& data) const
 -{
 -	std::string value;
 -	int count = deserialize_string(istr, value, mMaxBytesLeft);
 -	if(PARSE_FAILURE == count) return false;
 -	account(count);
 -	data = value;
 -	return true;
 -}
 -
 -bool LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const
 -{
 -	// binary: b##"ff3120ab1"
 -	// or: b(len)"..."
 -
 -	// I want to manually control those values here to make sure the
 -	// parser doesn't break when someone changes a constant somewhere
 -	// else.
 -	const U32 BINARY_BUFFER_SIZE = 256;
 -	const U32 STREAM_GET_COUNT = 255;
 -
 -	// need to read the base out.
 -	char buf[BINARY_BUFFER_SIZE];		/* Flawfinder: ignore */
 -	get(istr, buf, STREAM_GET_COUNT, '"');
 -	char c = get(istr);
 -	if(c != '"') return false;
 -	if(0 == strncmp("b(", buf, 2))
 -	{
 -		// We probably have a valid raw binary stream. determine
 -		// the size, and read it.
 -		S32 len = strtol(buf + 2, NULL, 0);
 -		if(mCheckLimits && (len > mMaxBytesLeft)) return false;
 -		std::vector<U8> value;
 -		if(len)
 -		{
 -			value.resize(len);
 -			account((int)fullread(istr, (char *)&value[0], len));
 -		}
 -		c = get(istr); // strip off the trailing double-quote
 -		data = value;
 -	}
 -	else if(0 == strncmp("b64", buf, 3))
 -	{
 -		// *FIX: A bit inefficient, but works for now. To make the
 -		// format better, I would need to add a hint into the
 -		// serialization format that indicated how long it was.
 -		std::stringstream coded_stream;
 -		get(istr, *(coded_stream.rdbuf()), '\"');
 -		c = get(istr);
 -		std::string encoded(coded_stream.str());
 -		S32 len = apr_base64_decode_len(encoded.c_str());
 -		std::vector<U8> value;
 -		if(len)
 -		{
 -			value.resize(len);
 -			len = apr_base64_decode_binary(&value[0], encoded.c_str());
 -			value.resize(len);
 -		}
 -		data = value;
 -	}
 -	else if(0 == strncmp("b16", buf, 3))
 -	{
 -		// yay, base 16. We pop the next character which is either a
 -		// double quote or base 16 data. If it's a double quote, we're
 -		// done parsing. If it's not, put the data back, and read the
 -		// stream until the next double quote.
 -		char* read;	 /*Flawfinder: ignore*/
 -		U8 byte;
 -		U8 byte_buffer[BINARY_BUFFER_SIZE];
 -		U8* write;
 -		std::vector<U8> value;
 -		c = get(istr);
 -		while(c != '"')
 -		{
 -			putback(istr, c);
 -			read = buf;
 -			write = byte_buffer;
 -			get(istr, buf, STREAM_GET_COUNT, '"');
 -			c = get(istr);
 -			while(*read != '\0')	 /*Flawfinder: ignore*/
 -			{
 -				byte = hex_as_nybble(*read++);
 -				byte = byte << 4;
 -				byte |= hex_as_nybble(*read++);
 -				*write++ = byte;
 -			}
 -			// copy the data out of the byte buffer
 -			value.insert(value.end(), byte_buffer, write);
 -		}
 -		data = value;
 -	}
 -	else
 -	{
 -		return false;
 -	}
 -	return true;
 -}
 -
 -
 -/**
 - * LLSDBinaryParser
 - */
 -LLSDBinaryParser::LLSDBinaryParser()
 -{
 -}
 -
 -// virtual
 -LLSDBinaryParser::~LLSDBinaryParser()
 -{
 -}
 -
 -// virtual
 -S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const
 -{
 -/**
 - * Undefined: '!'<br>
 - * Boolean: 't' for true 'f' for false<br>
 - * Integer: 'i' + 4 bytes network byte order<br>
 - * Real: 'r' + 8 bytes IEEE double<br>
 - * UUID: 'u' + 16 byte unsigned integer<br>
 - * String: 's' + 4 byte integer size + string<br>
 - *  strings also secretly support the notation format
 - * Date: 'd' + 8 byte IEEE double for seconds since epoch<br>
 - * URI: 'l' + 4 byte integer size + string uri<br>
 - * Binary: 'b' + 4 byte integer size + binary data<br>
 - * Array: '[' + 4 byte integer size  + all values + ']'<br>
 - * Map: '{' + 4 byte integer size  every(key + value) + '}'<br>
 - *  map keys are serialized as s + 4 byte integer size + string or in the
 - *  notation format.
 - */
 -	char c;
 -	c = get(istr);
 -	if(!istr.good())
 -	{
 -		return 0;
 -	}
 -	S32 parse_count = 1;
 -	switch(c)
 -	{
 -	case '{':
 -	{
 -		S32 child_count = parseMap(istr, data);
 -		if((child_count == PARSE_FAILURE) || data.isUndefined())
 -		{
 -			parse_count = PARSE_FAILURE;
 -		}
 -		else
 -		{
 -			parse_count += child_count;
 -		}
 -		if(istr.fail())
 -		{
 -			llinfos << "STREAM FAILURE reading binary map." << llendl;
 -			parse_count = PARSE_FAILURE;
 -		}
 -		break;
 -	}
 -
 -	case '[':
 -	{
 -		S32 child_count = parseArray(istr, data);
 -		if((child_count == PARSE_FAILURE) || data.isUndefined())
 -		{
 -			parse_count = PARSE_FAILURE;
 -		}
 -		else
 -		{
 -			parse_count += child_count;
 -		}
 -		if(istr.fail())
 -		{
 -			llinfos << "STREAM FAILURE reading binary array." << llendl;
 -			parse_count = PARSE_FAILURE;
 -		}
 -		break;
 -	}
 -
 -	case '!':
 -		data.clear();
 -		break;
 -
 -	case '0':
 -		data = false;
 -		break;
 -
 -	case '1':
 -		data = true;
 -		break;
 -
 -	case 'i':
 -	{
 -		U32 value_nbo = 0;
 -		read(istr, (char*)&value_nbo, sizeof(U32));	 /*Flawfinder: ignore*/
 -		data = (S32)ntohl(value_nbo);
 -		if(istr.fail())
 -		{
 -			llinfos << "STREAM FAILURE reading binary integer." << llendl;
 -		}
 -		break;
 -	}
 -
 -	case 'r':
 -	{
 -		F64 real_nbo = 0.0;
 -		read(istr, (char*)&real_nbo, sizeof(F64));	 /*Flawfinder: ignore*/
 -		data = ll_ntohd(real_nbo);
 -		if(istr.fail())
 -		{
 -			llinfos << "STREAM FAILURE reading binary real." << llendl;
 -		}
 -		break;
 -	}
 -
 -	case 'u':
 -	{
 -		LLUUID id;
 -		read(istr, (char*)(&id.mData), UUID_BYTES);	 /*Flawfinder: ignore*/
 -		data = id;
 -		if(istr.fail())
 -		{
 -			llinfos << "STREAM FAILURE reading binary uuid." << llendl;
 -		}
 -		break;
 -	}
 -
 -	case '\'':
 -	case '"':
 -	{
 -		std::string value;
 -		int cnt = deserialize_string_delim(istr, value, c);
 -		if(PARSE_FAILURE == cnt)
 -		{
 -			parse_count = PARSE_FAILURE;
 -		}
 -		else
 -		{
 -			data = value;
 -			account(cnt);
 -		}
 -		if(istr.fail())
 -		{
 -			llinfos << "STREAM FAILURE reading binary (notation-style) string."
 -				<< llendl;
 -			parse_count = PARSE_FAILURE;
 -		}
 -		break;
 -	}
 -
 -	case 's':
 -	{
 -		std::string value;
 -		if(parseString(istr, value))
 -		{
 -			data = value;
 -		}
 -		else
 -		{
 -			parse_count = PARSE_FAILURE;
 -		}
 -		if(istr.fail())
 -		{
 -			llinfos << "STREAM FAILURE reading binary string." << llendl;
 -			parse_count = PARSE_FAILURE;
 -		}
 -		break;
 -	}
 -
 -	case 'l':
 -	{
 -		std::string value;
 -		if(parseString(istr, value))
 -		{
 -			data = LLURI(value);
 -		}
 -		else
 -		{
 -			parse_count = PARSE_FAILURE;
 -		}
 -		if(istr.fail())
 -		{
 -			llinfos << "STREAM FAILURE reading binary link." << llendl;
 -			parse_count = PARSE_FAILURE;
 -		}
 -		break;
 -	}
 -
 -	case 'd':
 -	{
 -		F64 real = 0.0;
 -		read(istr, (char*)&real, sizeof(F64));	 /*Flawfinder: ignore*/
 -		data = LLDate(real);
 -		if(istr.fail())
 -		{
 -			llinfos << "STREAM FAILURE reading binary date." << llendl;
 -			parse_count = PARSE_FAILURE;
 -		}
 -		break;
 -	}
 -
 -	case 'b':
 -	{
 -		// We probably have a valid raw binary stream. determine
 -		// the size, and read it.
 -		U32 size_nbo = 0;
 -		read(istr, (char*)&size_nbo, sizeof(U32));	/*Flawfinder: ignore*/
 -		S32 size = (S32)ntohl(size_nbo);
 -		if(mCheckLimits && (size > mMaxBytesLeft))
 -		{
 -			parse_count = PARSE_FAILURE;
 -		}
 -		else
 -		{
 -			std::vector<U8> value;
 -			if(size > 0)
 -			{
 -				value.resize(size);
 -				account((int)fullread(istr, (char*)&value[0], size));
 -			}
 -			data = value;
 -		}
 -		if(istr.fail())
 -		{
 -			llinfos << "STREAM FAILURE reading binary." << llendl;
 -			parse_count = PARSE_FAILURE;
 -		}
 -		break;
 -	}
 -
 -	default:
 -		parse_count = PARSE_FAILURE;
 -		llinfos << "Unrecognized character while parsing: int(" << (int)c
 -			<< ")" << llendl;
 -		break;
 -	}
 -	if(PARSE_FAILURE == parse_count)
 -	{
 -		data.clear();
 -	}
 -	return parse_count;
 -}
 -
 -S32 LLSDBinaryParser::parseMap(std::istream& istr, LLSD& map) const
 -{
 -	map = LLSD::emptyMap();
 -	U32 value_nbo = 0;
 -	read(istr, (char*)&value_nbo, sizeof(U32));		 /*Flawfinder: ignore*/
 -	S32 size = (S32)ntohl(value_nbo);
 -	S32 parse_count = 0;
 -	S32 count = 0;
 -	char c = get(istr);
 -	while(c != '}' && (count < size) && istr.good())
 -	{
 -		std::string name;
 -		switch(c)
 -		{
 -		case 'k':
 -			if(!parseString(istr, name))
 -			{
 -				return PARSE_FAILURE;
 -			}
 -			break;
 -		case '\'':
 -		case '"':
 -		{
 -			int cnt = deserialize_string_delim(istr, name, c);
 -			if(PARSE_FAILURE == cnt) return PARSE_FAILURE;
 -			account(cnt);
 -			break;
 -		}
 -		}
 -		LLSD child;
 -		S32 child_count = doParse(istr, child);
 -		if(child_count > 0)
 -		{
 -			// There must be a value for every key, thus child_count
 -			// must be greater than 0.
 -			parse_count += child_count;
 -			map.insert(name, child);
 -		}
 -		else
 -		{
 -			return PARSE_FAILURE;
 -		}
 -		++count;
 -		c = get(istr);
 -	}
 -	if((c != '}') || (count < size))
 -	{
 -		// Make sure it is correctly terminated and we parsed as many
 -		// as were said to be there.
 -		return PARSE_FAILURE;
 -	}
 -	return parse_count;
 -}
 -
 -S32 LLSDBinaryParser::parseArray(std::istream& istr, LLSD& array) const
 -{
 -	array = LLSD::emptyArray();
 -	U32 value_nbo = 0;
 -	read(istr, (char*)&value_nbo, sizeof(U32));		 /*Flawfinder: ignore*/
 -	S32 size = (S32)ntohl(value_nbo);
 -
 -	// *FIX: This would be a good place to reserve some space in the
 -	// array...
 -
 -	S32 parse_count = 0;
 -	S32 count = 0;
 -	char c = istr.peek();
 -	while((c != ']') && (count < size) && istr.good())
 -	{
 -		LLSD child;
 -		S32 child_count = doParse(istr, child);
 -		if(PARSE_FAILURE == child_count)
 -		{
 -			return PARSE_FAILURE;
 -		}
 -		if(child_count)
 -		{
 -			parse_count += child_count;
 -			array.append(child);
 -		}
 -		++count;
 -		c = istr.peek();
 -	}
 -	c = get(istr);
 -	if((c != ']') || (count < size))
 -	{
 -		// Make sure it is correctly terminated and we parsed as many
 -		// as were said to be there.
 -		return PARSE_FAILURE;
 -	}
 -	return parse_count;
 -}
 -
 -bool LLSDBinaryParser::parseString(
 -	std::istream& istr,
 -	std::string& value) const
 -{
 -	// *FIX: This is memory inefficient.
 -	U32 value_nbo = 0;
 -	read(istr, (char*)&value_nbo, sizeof(U32));		 /*Flawfinder: ignore*/
 -	S32 size = (S32)ntohl(value_nbo);
 -	if(mCheckLimits && (size > mMaxBytesLeft)) return false;
 -	std::vector<char> buf;
 -	if(size)
 -	{
 -		buf.resize(size);
 -		account((int)fullread(istr, &buf[0], size));
 -		value.assign(buf.begin(), buf.end());
 -	}
 -	return true;
 -}
 -
 -
 -/**
 - * LLSDFormatter
 - */
 -LLSDFormatter::LLSDFormatter() :
 -	mBoolAlpha(false)
 -{
 -}
 -
 -// virtual
 -LLSDFormatter::~LLSDFormatter()
 -{ }
 -
 -void LLSDFormatter::boolalpha(bool alpha)
 -{
 -	mBoolAlpha = alpha;
 -}
 -
 -void LLSDFormatter::realFormat(const std::string& format)
 -{
 -	mRealFormat = format;
 -}
 -
 -void LLSDFormatter::formatReal(LLSD::Real real, std::ostream& ostr) const
 -{
 -	std::string buffer = llformat(mRealFormat.c_str(), real);
 -	ostr << buffer;
 -}
 -
 -/**
 - * LLSDNotationFormatter
 - */
 -LLSDNotationFormatter::LLSDNotationFormatter()
 -{
 -}
 -
 -// virtual
 -LLSDNotationFormatter::~LLSDNotationFormatter()
 -{ }
 -
 -// static
 -std::string LLSDNotationFormatter::escapeString(const std::string& in)
 -{
 -	std::ostringstream ostr;
 -	serialize_string(in, ostr);
 -	return ostr.str();
 -}
 -
 -// virtual
 -S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 options) const
 -{
 -	S32 format_count = 1;
 -	switch(data.type())
 -	{
 -	case LLSD::TypeMap:
 -	{
 -		ostr << "{";
 -		bool need_comma = false;
 -		LLSD::map_const_iterator iter = data.beginMap();
 -		LLSD::map_const_iterator end = data.endMap();
 -		for(; iter != end; ++iter)
 -		{
 -			if(need_comma) ostr << ",";
 -			need_comma = true;
 -			ostr << '\'';
 -			serialize_string((*iter).first, ostr);
 -			ostr << "':";
 -			format_count += format((*iter).second, ostr);
 -		}
 -		ostr << "}";
 -		break;
 -	}
 -
 -	case LLSD::TypeArray:
 -	{
 -		ostr << "[";
 -		bool need_comma = false;
 -		LLSD::array_const_iterator iter = data.beginArray();
 -		LLSD::array_const_iterator end = data.endArray();
 -		for(; iter != end; ++iter)
 -		{
 -			if(need_comma) ostr << ",";
 -			need_comma = true;
 -			format_count += format(*iter, ostr);
 -		}
 -		ostr << "]";
 -		break;
 -	}
 -
 -	case LLSD::TypeUndefined:
 -		ostr << "!";
 -		break;
 -
 -	case LLSD::TypeBoolean:
 -		if(mBoolAlpha ||
 -#if( LL_WINDOWS || __GNUC__ > 2)
 -		   (ostr.flags() & std::ios::boolalpha)
 -#else
 -		   (ostr.flags() & 0x0100)
 -#endif
 -			)
 -		{
 -			ostr << (data.asBoolean()
 -					 ? NOTATION_TRUE_SERIAL : NOTATION_FALSE_SERIAL);
 -		}
 -		else
 -		{
 -			ostr << (data.asBoolean() ? 1 : 0);
 -		}
 -		break;
 -
 -	case LLSD::TypeInteger:
 -		ostr << "i" << data.asInteger();
 -		break;
 -
 -	case LLSD::TypeReal:
 -		ostr << "r";
 -		if(mRealFormat.empty())
 -		{
 -			ostr << data.asReal();
 -		}
 -		else
 -		{
 -			formatReal(data.asReal(), ostr);
 -		}
 -		break;
 -
 -	case LLSD::TypeUUID:
 -		ostr << "u" << data.asUUID();
 -		break;
 -
 -	case LLSD::TypeString:
 -		ostr << '\'';
 -		serialize_string(data.asString(), ostr);
 -		ostr << '\'';
 -		break;
 -
 -	case LLSD::TypeDate:
 -		ostr << "d\"" << data.asDate() << "\"";
 -		break;
 -
 -	case LLSD::TypeURI:
 -		ostr << "l\"";
 -		serialize_string(data.asString(), ostr);
 -		ostr << "\"";
 -		break;
 -
 -	case LLSD::TypeBinary:
 -	{
 -		// *FIX: memory inefficient.
 -		std::vector<U8> buffer = data.asBinary();
 -		ostr << "b(" << buffer.size() << ")\"";
 -		if(buffer.size()) ostr.write((const char*)&buffer[0], buffer.size());
 -		ostr << "\"";
 -		break;
 -	}
 -
 -	default:
 -		// *NOTE: This should never happen.
 -		ostr << "!";
 -		break;
 -	}
 -	return format_count;
 -}
 -
 -
 -/**
 - * LLSDBinaryFormatter
 - */
 -LLSDBinaryFormatter::LLSDBinaryFormatter()
 -{
 -}
 -
 -// virtual
 -LLSDBinaryFormatter::~LLSDBinaryFormatter()
 -{ }
 -
 -// virtual
 -S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 options) const
 -{
 -	S32 format_count = 1;
 -	switch(data.type())
 -	{
 -	case LLSD::TypeMap:
 -	{
 -		ostr.put('{');
 -		U32 size_nbo = htonl(data.size());
 -		ostr.write((const char*)(&size_nbo), sizeof(U32));
 -		LLSD::map_const_iterator iter = data.beginMap();
 -		LLSD::map_const_iterator end = data.endMap();
 -		for(; iter != end; ++iter)
 -		{
 -			ostr.put('k');
 -			formatString((*iter).first, ostr);
 -			format_count += format((*iter).second, ostr);
 -		}
 -		ostr.put('}');
 -		break;
 -	}
 -
 -	case LLSD::TypeArray:
 -	{
 -		ostr.put('[');
 -		U32 size_nbo = htonl(data.size());
 -		ostr.write((const char*)(&size_nbo), sizeof(U32));
 -		LLSD::array_const_iterator iter = data.beginArray();
 -		LLSD::array_const_iterator end = data.endArray();
 -		for(; iter != end; ++iter)
 -		{
 -			format_count += format(*iter, ostr);
 -		}
 -		ostr.put(']');
 -		break;
 -	}
 -
 -	case LLSD::TypeUndefined:
 -		ostr.put('!');
 -		break;
 -
 -	case LLSD::TypeBoolean:
 -		if(data.asBoolean()) ostr.put(BINARY_TRUE_SERIAL);
 -		else ostr.put(BINARY_FALSE_SERIAL);
 -		break;
 -
 -	case LLSD::TypeInteger:
 -	{
 -		ostr.put('i');
 -		U32 value_nbo = htonl(data.asInteger());
 -		ostr.write((const char*)(&value_nbo), sizeof(U32));
 -		break;
 -	}
 -
 -	case LLSD::TypeReal:
 -	{
 -		ostr.put('r');
 -		F64 value_nbo = ll_htond(data.asReal());
 -		ostr.write((const char*)(&value_nbo), sizeof(F64));
 -		break;
 -	}
 -
 -	case LLSD::TypeUUID:
 -		ostr.put('u');
 -		ostr.write((const char*)(&(data.asUUID().mData)), UUID_BYTES);
 -		break;
 -
 -	case LLSD::TypeString:
 -		ostr.put('s');
 -		formatString(data.asString(), ostr);
 -		break;
 -
 -	case LLSD::TypeDate:
 -	{
 -		ostr.put('d');
 -		F64 value = data.asReal();
 -		ostr.write((const char*)(&value), sizeof(F64));
 -		break;
 -	}
 -
 -	case LLSD::TypeURI:
 -		ostr.put('l');
 -		formatString(data.asString(), ostr);
 -		break;
 -
 -	case LLSD::TypeBinary:
 -	{
 -		// *FIX: memory inefficient.
 -		ostr.put('b');
 -		std::vector<U8> buffer = data.asBinary();
 -		U32 size_nbo = htonl(buffer.size());
 -		ostr.write((const char*)(&size_nbo), sizeof(U32));
 -		if(buffer.size()) ostr.write((const char*)&buffer[0], buffer.size());
 -		break;
 -	}
 -
 -	default:
 -		// *NOTE: This should never happen.
 -		ostr.put('!');
 -		break;
 -	}
 -	return format_count;
 -}
 -
 -void LLSDBinaryFormatter::formatString(
 -	const std::string& string,
 -	std::ostream& ostr) const
 -{
 -	U32 size_nbo = htonl(string.size());
 -	ostr.write((const char*)(&size_nbo), sizeof(U32));
 -	ostr.write(string.c_str(), string.size());
 -}
 -
 -/**
 - * local functions
 - */
 -int deserialize_string(std::istream& istr, std::string& value, S32 max_bytes)
 -{
 -	int c = istr.get();
 -	if(istr.fail())
 -	{
 -		// No data in stream, bail out but mention the character we
 -		// grabbed.
 -		return LLSDParser::PARSE_FAILURE;
 -	}
 -
 -	int rv = LLSDParser::PARSE_FAILURE;
 -	switch(c)
 -	{
 -	case '\'':
 -	case '"':
 -		rv = deserialize_string_delim(istr, value, c);
 -		break;
 -	case 's':
 -		// technically, less than max_bytes, but this is just meant to
 -		// catch egregious protocol errors. parse errors will be
 -		// caught in the case of incorrect counts.
 -		rv = deserialize_string_raw(istr, value, max_bytes);
 -		break;
 -	default:
 -		break;
 -	}
 -	if(LLSDParser::PARSE_FAILURE == rv) return rv;
 -	return rv + 1; // account for the character grabbed at the top.
 -}
 -
 -int deserialize_string_delim(
 -	std::istream& istr,
 -	std::string& value,
 -	char delim)
 -{
 -	std::ostringstream write_buffer;
 -	bool found_escape = false;
 -	bool found_hex = false;
 -	bool found_digit = false;
 -	U8 byte = 0;
 -	int count = 0;
 -
 -	while (true)
 -	{
 -		int next_byte = istr.get();
 -		++count;
 -
 -		if(istr.fail())
 -		{
 -			// If our stream is empty, break out
 -			value = write_buffer.str();
 -			return LLSDParser::PARSE_FAILURE;
 -		}
 -
 -		char next_char = (char)next_byte; // Now that we know it's not EOF
 -		
 -		if(found_escape)
 -		{
 -			// next character(s) is a special sequence.
 -			if(found_hex)
 -			{
 -				if(found_digit)
 -				{
 -					found_digit = false;
 -					found_hex = false;
 -					found_escape = false;
 -					byte = byte << 4;
 -					byte |= hex_as_nybble(next_char);
 -					write_buffer << byte;
 -					byte = 0;
 -				}
 -				else
 -				{
 -					// next character is the first nybble of
 -					//
 -					found_digit = true;
 -					byte = hex_as_nybble(next_char);
 -				}
 -			}
 -			else if(next_char == 'x')
 -			{
 -				found_hex = true;
 -			}
 -			else
 -			{
 -				switch(next_char)
 -				{
 -				case 'a':
 -					write_buffer << '\a';
 -					break;
 -				case 'b':
 -					write_buffer << '\b';
 -					break;
 -				case 'f':
 -					write_buffer << '\f';
 -					break;
 -				case 'n':
 -					write_buffer << '\n';
 -					break;
 -				case 'r':
 -					write_buffer << '\r';
 -					break;
 -				case 't':
 -					write_buffer << '\t';
 -					break;
 -				case 'v':
 -					write_buffer << '\v';
 -					break;
 -				default:
 -					write_buffer << next_char;
 -					break;
 -				}
 -				found_escape = false;
 -			}
 -		}
 -		else if(next_char == '\\')
 -		{
 -			found_escape = true;
 -		}
 -		else if(next_char == delim)
 -		{
 -			break;
 -		}
 -		else
 -		{
 -			write_buffer << next_char;
 -		}
 -	}
 -
 -	value = write_buffer.str();
 -	return count;
 -}
 -
 -int deserialize_string_raw(
 -	std::istream& istr,
 -	std::string& value,
 -	S32 max_bytes)
 -{
 -	int count = 0;
 -	const S32 BUF_LEN = 20;
 -	char buf[BUF_LEN];		/* Flawfinder: ignore */
 -	istr.get(buf, BUF_LEN - 1, ')');
 -	count += (int)istr.gcount();
 -	int c = istr.get();
 -	c = istr.get();
 -	count += 2;
 -	if(((c == '"') || (c == '\'')) && (buf[0] == '('))
 -	{
 -		// We probably have a valid raw string. determine
 -		// the size, and read it.
 -		// *FIX: This is memory inefficient.
 -		S32 len = strtol(buf + 1, NULL, 0);
 -		if((max_bytes>0)&&(len>max_bytes)) return LLSDParser::PARSE_FAILURE;
 -		std::vector<char> buf;
 -		if(len)
 -		{
 -			buf.resize(len);
 -			count += (int)fullread(istr, (char *)&buf[0], len);
 -			value.assign(buf.begin(), buf.end());
 -		}
 -		c = istr.get();
 -		++count;
 -		if(!((c == '"') || (c == '\'')))
 -		{
 -			return LLSDParser::PARSE_FAILURE;
 -		}
 -	}
 -	else
 -	{
 -		return LLSDParser::PARSE_FAILURE;
 -	}
 -	return count;
 -}
 -
 -static const char* NOTATION_STRING_CHARACTERS[256] =
 -{
 -	"\\x00",	// 0
 -	"\\x01",	// 1
 -	"\\x02",	// 2
 -	"\\x03",	// 3
 -	"\\x04",	// 4
 -	"\\x05",	// 5
 -	"\\x06",	// 6
 -	"\\a",		// 7
 -	"\\b",		// 8
 -	"\\t",		// 9
 -	"\\n",		// 10
 -	"\\v",		// 11
 -	"\\f",		// 12
 -	"\\r",		// 13
 -	"\\x0e",	// 14
 -	"\\x0f",	// 15
 -	"\\x10",	// 16
 -	"\\x11",	// 17
 -	"\\x12",	// 18
 -	"\\x13",	// 19
 -	"\\x14",	// 20
 -	"\\x15",	// 21
 -	"\\x16",	// 22
 -	"\\x17",	// 23
 -	"\\x18",	// 24
 -	"\\x19",	// 25
 -	"\\x1a",	// 26
 -	"\\x1b",	// 27
 -	"\\x1c",	// 28
 -	"\\x1d",	// 29
 -	"\\x1e",	// 30
 -	"\\x1f",	// 31
 -	" ",		// 32
 -	"!",		// 33
 -	"\"",		// 34
 -	"#",		// 35
 -	"$",		// 36
 -	"%",		// 37
 -	"&",		// 38
 -	"\\'",		// 39
 -	"(",		// 40
 -	")",		// 41
 -	"*",		// 42
 -	"+",		// 43
 -	",",		// 44
 -	"-",		// 45
 -	".",		// 46
 -	"/",		// 47
 -	"0",		// 48
 -	"1",		// 49
 -	"2",		// 50
 -	"3",		// 51
 -	"4",		// 52
 -	"5",		// 53
 -	"6",		// 54
 -	"7",		// 55
 -	"8",		// 56
 -	"9",		// 57
 -	":",		// 58
 -	";",		// 59
 -	"<",		// 60
 -	"=",		// 61
 -	">",		// 62
 -	"?",		// 63
 -	"@",		// 64
 -	"A",		// 65
 -	"B",		// 66
 -	"C",		// 67
 -	"D",		// 68
 -	"E",		// 69
 -	"F",		// 70
 -	"G",		// 71
 -	"H",		// 72
 -	"I",		// 73
 -	"J",		// 74
 -	"K",		// 75
 -	"L",		// 76
 -	"M",		// 77
 -	"N",		// 78
 -	"O",		// 79
 -	"P",		// 80
 -	"Q",		// 81
 -	"R",		// 82
 -	"S",		// 83
 -	"T",		// 84
 -	"U",		// 85
 -	"V",		// 86
 -	"W",		// 87
 -	"X",		// 88
 -	"Y",		// 89
 -	"Z",		// 90
 -	"[",		// 91
 -	"\\\\",		// 92
 -	"]",		// 93
 -	"^",		// 94
 -	"_",		// 95
 -	"`",		// 96
 -	"a",		// 97
 -	"b",		// 98
 -	"c",		// 99
 -	"d",		// 100
 -	"e",		// 101
 -	"f",		// 102
 -	"g",		// 103
 -	"h",		// 104
 -	"i",		// 105
 -	"j",		// 106
 -	"k",		// 107
 -	"l",		// 108
 -	"m",		// 109
 -	"n",		// 110
 -	"o",		// 111
 -	"p",		// 112
 -	"q",		// 113
 -	"r",		// 114
 -	"s",		// 115
 -	"t",		// 116
 -	"u",		// 117
 -	"v",		// 118
 -	"w",		// 119
 -	"x",		// 120
 -	"y",		// 121
 -	"z",		// 122
 -	"{",		// 123
 -	"|",		// 124
 -	"}",		// 125
 -	"~",		// 126
 -	"\\x7f",	// 127
 -	"\\x80",	// 128
 -	"\\x81",	// 129
 -	"\\x82",	// 130
 -	"\\x83",	// 131
 -	"\\x84",	// 132
 -	"\\x85",	// 133
 -	"\\x86",	// 134
 -	"\\x87",	// 135
 -	"\\x88",	// 136
 -	"\\x89",	// 137
 -	"\\x8a",	// 138
 -	"\\x8b",	// 139
 -	"\\x8c",	// 140
 -	"\\x8d",	// 141
 -	"\\x8e",	// 142
 -	"\\x8f",	// 143
 -	"\\x90",	// 144
 -	"\\x91",	// 145
 -	"\\x92",	// 146
 -	"\\x93",	// 147
 -	"\\x94",	// 148
 -	"\\x95",	// 149
 -	"\\x96",	// 150
 -	"\\x97",	// 151
 -	"\\x98",	// 152
 -	"\\x99",	// 153
 -	"\\x9a",	// 154
 -	"\\x9b",	// 155
 -	"\\x9c",	// 156
 -	"\\x9d",	// 157
 -	"\\x9e",	// 158
 -	"\\x9f",	// 159
 -	"\\xa0",	// 160
 -	"\\xa1",	// 161
 -	"\\xa2",	// 162
 -	"\\xa3",	// 163
 -	"\\xa4",	// 164
 -	"\\xa5",	// 165
 -	"\\xa6",	// 166
 -	"\\xa7",	// 167
 -	"\\xa8",	// 168
 -	"\\xa9",	// 169
 -	"\\xaa",	// 170
 -	"\\xab",	// 171
 -	"\\xac",	// 172
 -	"\\xad",	// 173
 -	"\\xae",	// 174
 -	"\\xaf",	// 175
 -	"\\xb0",	// 176
 -	"\\xb1",	// 177
 -	"\\xb2",	// 178
 -	"\\xb3",	// 179
 -	"\\xb4",	// 180
 -	"\\xb5",	// 181
 -	"\\xb6",	// 182
 -	"\\xb7",	// 183
 -	"\\xb8",	// 184
 -	"\\xb9",	// 185
 -	"\\xba",	// 186
 -	"\\xbb",	// 187
 -	"\\xbc",	// 188
 -	"\\xbd",	// 189
 -	"\\xbe",	// 190
 -	"\\xbf",	// 191
 -	"\\xc0",	// 192
 -	"\\xc1",	// 193
 -	"\\xc2",	// 194
 -	"\\xc3",	// 195
 -	"\\xc4",	// 196
 -	"\\xc5",	// 197
 -	"\\xc6",	// 198
 -	"\\xc7",	// 199
 -	"\\xc8",	// 200
 -	"\\xc9",	// 201
 -	"\\xca",	// 202
 -	"\\xcb",	// 203
 -	"\\xcc",	// 204
 -	"\\xcd",	// 205
 -	"\\xce",	// 206
 -	"\\xcf",	// 207
 -	"\\xd0",	// 208
 -	"\\xd1",	// 209
 -	"\\xd2",	// 210
 -	"\\xd3",	// 211
 -	"\\xd4",	// 212
 -	"\\xd5",	// 213
 -	"\\xd6",	// 214
 -	"\\xd7",	// 215
 -	"\\xd8",	// 216
 -	"\\xd9",	// 217
 -	"\\xda",	// 218
 -	"\\xdb",	// 219
 -	"\\xdc",	// 220
 -	"\\xdd",	// 221
 -	"\\xde",	// 222
 -	"\\xdf",	// 223
 -	"\\xe0",	// 224
 -	"\\xe1",	// 225
 -	"\\xe2",	// 226
 -	"\\xe3",	// 227
 -	"\\xe4",	// 228
 -	"\\xe5",	// 229
 -	"\\xe6",	// 230
 -	"\\xe7",	// 231
 -	"\\xe8",	// 232
 -	"\\xe9",	// 233
 -	"\\xea",	// 234
 -	"\\xeb",	// 235
 -	"\\xec",	// 236
 -	"\\xed",	// 237
 -	"\\xee",	// 238
 -	"\\xef",	// 239
 -	"\\xf0",	// 240
 -	"\\xf1",	// 241
 -	"\\xf2",	// 242
 -	"\\xf3",	// 243
 -	"\\xf4",	// 244
 -	"\\xf5",	// 245
 -	"\\xf6",	// 246
 -	"\\xf7",	// 247
 -	"\\xf8",	// 248
 -	"\\xf9",	// 249
 -	"\\xfa",	// 250
 -	"\\xfb",	// 251
 -	"\\xfc",	// 252
 -	"\\xfd",	// 253
 -	"\\xfe",	// 254
 -	"\\xff"		// 255
 -};
 -
 -void serialize_string(const std::string& value, std::ostream& str)
 -{
 -	std::string::const_iterator it = value.begin();
 -	std::string::const_iterator end = value.end();
 -	U8 c;
 -	for(; it != end; ++it)
 -	{
 -		c = (U8)(*it);
 -		str << NOTATION_STRING_CHARACTERS[c];
 -	}
 -}
 -
 -int deserialize_boolean(
 -	std::istream& istr,
 -	LLSD& data,
 -	const std::string& compare,
 -	bool value)
 -{
 -	//
 -	// this method is a little goofy, because it gets the stream at
 -	// the point where the t or f has already been
 -	// consumed. Basically, parse for a patch to the string passed in
 -	// starting at index 1. If it's a match:
 -	//  * assign data to value
 -	//  * return the number of bytes read
 -	// otherwise:
 -	//  * set data to LLSD::null
 -	//  * return LLSDParser::PARSE_FAILURE (-1)
 -	//
 -	int bytes_read = 0;
 -	std::string::size_type ii = 0;
 -	char c = istr.peek();
 -	while((++ii < compare.size())
 -		  && (tolower(c) == (int)compare[ii])
 -		  && istr.good())
 -	{
 -		istr.ignore();
 -		++bytes_read;
 -		c = istr.peek();
 -	}
 -	if(compare.size() != ii)
 -	{
 -		data.clear();
 -		return LLSDParser::PARSE_FAILURE;
 -	}
 -	data = value;
 -	return bytes_read;
 -}
 -
 -std::ostream& operator<<(std::ostream& s, const LLSD& llsd)
 -{
 -	s << LLSDNotationStreamer(llsd);
 -	return s;
 -}
 -
 -
 -//dirty little zippers -- yell at davep if these are horrid
 -
 -//return a string containing gzipped bytes of binary serialized LLSD
 -// VERY inefficient -- creates several copies of LLSD block in memory
 -std::string zip_llsd(LLSD& data)
 -{ 
 -	std::stringstream llsd_strm;
 -
 -	LLSDSerialize::toBinary(data, llsd_strm);
 -
 -	const U32 CHUNK = 65536;
 -
 -	z_stream strm;
 -	strm.zalloc = Z_NULL;
 -	strm.zfree = Z_NULL;
 -	strm.opaque = Z_NULL;
 -
 -	S32 ret = deflateInit(&strm, Z_BEST_COMPRESSION);
 -	if (ret != Z_OK)
 -	{
 -		llwarns << "Failed to compress LLSD block." << llendl;
 -		return std::string();
 -	}
 -
 -	std::string source = llsd_strm.str();
 -
 -	U8 out[CHUNK];
 -
 -	strm.avail_in = source.size();
 -	strm.next_in = (U8*) source.data();
 -	U8* output = NULL;
 -
 -	U32 cur_size = 0;
 -
 -	U32 have = 0;
 -
 -	do
 -	{
 -		strm.avail_out = CHUNK;
 -		strm.next_out = out;
 -
 -		ret = deflate(&strm, Z_FINISH);
 -		if (ret == Z_OK || ret == Z_STREAM_END)
 -		{ //copy result into output
 -			if (strm.avail_out >= CHUNK)
 -			{
 -				free(output);
 -				llwarns << "Failed to compress LLSD block." << llendl;
 -				return std::string();
 -			}
 -
 -			have = CHUNK-strm.avail_out;
 -			output = (U8*) realloc(output, cur_size+have);
 -			memcpy(output+cur_size, out, have);
 -			cur_size += have;
 -		}
 -		else 
 -		{
 -			free(output);
 -			llwarns << "Failed to compress LLSD block." << llendl;
 -			return std::string();
 -		}
 -	}
 -	while (ret == Z_OK);
 -
 -	std::string::size_type size = cur_size;
 -
 -	std::string result((char*) output, size);
 -	deflateEnd(&strm);
 -	free(output);
 -
 -#if 0 //verify results work with unzip_llsd
 -	std::istringstream test(result);
 -	LLSD test_sd;
 -	if (!unzip_llsd(test_sd, test, result.size()))
 -	{
 -		llerrs << "Invalid compression result!" << llendl;
 -	}
 -#endif
 -
 -	return result;
 -}
 -
 -//decompress a block of LLSD from provided istream
 -// not very efficient -- creats a copy of decompressed LLSD block in memory
 -// and deserializes from that copy using LLSDSerialize
 -bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
 -{
 -	U8* result = NULL;
 -	U32 cur_size = 0;
 -	z_stream strm;
 -		
 -	const U32 CHUNK = 65536;
 -
 -	U8 *in = new U8[size];
 -	is.read((char*) in, size); 
 -
 -	U8 out[CHUNK];
 -		
 -	strm.zalloc = Z_NULL;
 -	strm.zfree = Z_NULL;
 -	strm.opaque = Z_NULL;
 -	strm.avail_in = size;
 -	strm.next_in = in;
 -
 -	S32 ret = inflateInit(&strm);
 -	
 -	do
 -	{
 -		strm.avail_out = CHUNK;
 -		strm.next_out = out;
 -		ret = inflate(&strm, Z_NO_FLUSH);
 -		if (ret == Z_STREAM_ERROR)
 -		{
 -			inflateEnd(&strm);
 -			free(result);
 -			delete [] in;
 -			return false;
 -		}
 -		
 -		switch (ret)
 -		{
 -		case Z_NEED_DICT:
 -			ret = Z_DATA_ERROR;
 -		case Z_DATA_ERROR:
 -		case Z_MEM_ERROR:
 -			inflateEnd(&strm);
 -			free(result);
 -			delete [] in;
 -			return false;
 -			break;
 -		}
 -
 -		U32 have = CHUNK-strm.avail_out;
 -
 -		result = (U8*) realloc(result, cur_size + have);
 -		memcpy(result+cur_size, out, have);
 -		cur_size += have;
 -
 -	} while (ret == Z_OK);
 -
 -	inflateEnd(&strm);
 -	delete [] in;
 -
 -	if (ret != Z_STREAM_END)
 -	{
 -		free(result);
 -		return false;
 -	}
 -
 -	//result now points to the decompressed LLSD block
 -	{
 -		std::string res_str((char*) result, cur_size);
 -
 -		std::string deprecated_header("<? LLSD/Binary ?>");
 -
 -		if (res_str.substr(0, deprecated_header.size()) == deprecated_header)
 -		{
 -			res_str = res_str.substr(deprecated_header.size()+1, cur_size);
 -		}
 -		cur_size = res_str.size();
 -
 -		std::istringstream istr(res_str);
 -		
 -		if (!LLSDSerialize::fromBinary(data, istr, cur_size))
 -		{
 -			llwarns << "Failed to unzip LLSD block" << llendl;
 -			free(result);
 -			return false;
 -		}		
 -	}
 -
 -	free(result);
 -	return true;
 -}
 -//This unzip function will only work with a gzip header and trailer - while the contents
 -//of the actual compressed data is the same for either format (gzip vs zlib ), the headers
 -//and trailers are different for the formats.
 -U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32 size )
 -{
 -	U8* result = NULL;
 -	U32 cur_size = 0;
 -	z_stream strm;
 -		
 -	const U32 CHUNK = 0x4000;
 -
 -	U8 *in = new U8[size];
 -	is.read((char*) in, size); 
 -
 -	U8 out[CHUNK];
 -		
 -	strm.zalloc = Z_NULL;
 -	strm.zfree = Z_NULL;
 -	strm.opaque = Z_NULL;
 -	strm.avail_in = size;
 -	strm.next_in = in;
 -
 -	
 -	S32 ret = inflateInit2(&strm,  windowBits | ENABLE_ZLIB_GZIP );
 -	do
 -	{
 -		strm.avail_out = CHUNK;
 -		strm.next_out = out;
 -		ret = inflate(&strm, Z_NO_FLUSH);
 -		if (ret == Z_STREAM_ERROR)
 -		{
 -			inflateEnd(&strm);
 -			free(result);
 -			delete [] in;
 -			valid = false;
 -		}
 -		
 -		switch (ret)
 -		{
 -		case Z_NEED_DICT:
 -			ret = Z_DATA_ERROR;
 -		case Z_DATA_ERROR:
 -		case Z_MEM_ERROR:
 -			inflateEnd(&strm);
 -			free(result);
 -			delete [] in;
 -			valid = false;
 -			break;
 -		}
 -
 -		U32 have = CHUNK-strm.avail_out;
 -
 -		result = (U8*) realloc(result, cur_size + have);
 -		memcpy(result+cur_size, out, have);
 -		cur_size += have;
 -
 -	} while (ret == Z_OK);
 -
 -	inflateEnd(&strm);
 -	delete [] in;
 -
 -	if (ret != Z_STREAM_END)
 -	{
 -		free(result);
 -		valid = false;
 -		return NULL;
 -	}
 -
 -	//result now points to the decompressed LLSD block
 -	{
 -		outsize= cur_size;
 -		valid = true;		
 -	}
 -
 -	return result;
 -}
 -
 -
 +/**  + * @file llsdserialize.cpp + * @author Phoenix + * @date 2006-03-05 + * @brief Implementation of LLSD parsers and formatters + * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "llsdserialize.h" +#include "llpointer.h" +#include "llstreamtools.h" // for fullread + +#include <iostream> +#include "apr_base64.h" + +#ifdef LL_STANDALONE +# include <zlib.h> +#else +# include "zlib/zlib.h"  // for davep's dirty little zip functions +#endif + +#if !LL_WINDOWS +#include <netinet/in.h> // htonl & ntohl +#endif + +#include "lldate.h" +#include "llsd.h" +#include "llstring.h" +#include "lluri.h" + +// File constants +static const int MAX_HDR_LEN = 20; +static const char LEGACY_NON_HEADER[] = "<llsd>"; +const std::string LLSD_BINARY_HEADER("LLSD/Binary"); +const std::string LLSD_XML_HEADER("LLSD/XML"); + +//used to deflate a gzipped asset (currently used for navmeshes) +#define windowBits 15 +#define ENABLE_ZLIB_GZIP 32 + +/** + * LLSDSerialize + */ + +// static +void LLSDSerialize::serialize(const LLSD& sd, std::ostream& str, ELLSD_Serialize type, U32 options) +{ +	LLPointer<LLSDFormatter> f = NULL; + +	switch (type) +	{ +	case LLSD_BINARY: +		str << "<? " << LLSD_BINARY_HEADER << " ?>\n"; +		f = new LLSDBinaryFormatter; +		break; + +	case LLSD_XML: +		str << "<? " << LLSD_XML_HEADER << " ?>\n"; +		f = new LLSDXMLFormatter; +		break; + +	default: +		llwarns << "serialize request for unknown ELLSD_Serialize" << llendl; +	} + +	if (f.notNull()) +	{ +		f->format(sd, str, options); +	} +} + +// static +bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, S32 max_bytes) +{ +	LLPointer<LLSDParser> p = NULL; +	char hdr_buf[MAX_HDR_LEN + 1] = ""; /* Flawfinder: ignore */ +	int i; +	int inbuf = 0; +	bool legacy_no_header = false; +	bool fail_if_not_legacy = false; +	std::string header; + +	/* +	 * Get the first line before anything. +	 */ +	str.get(hdr_buf, MAX_HDR_LEN, '\n'); +	if (str.fail()) +	{ +		str.clear(); +		fail_if_not_legacy = true; +	} + +	if (!strncasecmp(LEGACY_NON_HEADER, hdr_buf, strlen(LEGACY_NON_HEADER))) /* Flawfinder: ignore */ +	{ +		legacy_no_header = true; +		inbuf = (int)str.gcount(); +	} +	else +	{ +		if (fail_if_not_legacy) +			goto fail; +		/* +		* Remove the newline chars +		*/ +		for (i = 0; i < MAX_HDR_LEN; i++) +		{ +			if (hdr_buf[i] == 0 || hdr_buf[i] == '\r' || +				hdr_buf[i] == '\n') +			{ +				hdr_buf[i] = 0; +				break; +			} +		} +		header = hdr_buf; + +		std::string::size_type start = std::string::npos; +		std::string::size_type end = std::string::npos; +		start = header.find_first_not_of("<? "); +		if (start != std::string::npos) +		{ +			end = header.find_first_of(" ?", start); +		} +		if ((start == std::string::npos) || (end == std::string::npos)) +			goto fail; + +		header = header.substr(start, end - start); +		ws(str); +	} +	/* +	 * Create the parser as appropriate +	 */ +	if (legacy_no_header) +	{	// Create a LLSD XML parser, and parse the first chunk read above +		LLSDXMLParser* x = new LLSDXMLParser(); +		x->parsePart(hdr_buf, inbuf);	// Parse the first part that was already read +		x->parseLines(str, sd);			// Parse the rest of it +		delete x; +		return true; +	} + +	if (header == LLSD_BINARY_HEADER) +	{ +		p = new LLSDBinaryParser; +	} +	else if (header == LLSD_XML_HEADER) +	{ +		p = new LLSDXMLParser; +	} +	else +	{ +		llwarns << "deserialize request for unknown ELLSD_Serialize" << llendl; +	} + +	if (p.notNull()) +	{ +		p->parse(str, sd, max_bytes); +		return true; +	} + +fail: +	llwarns << "deserialize LLSD parse failure" << llendl; +	return false; +} + +/** + * Endian handlers + */ +#if LL_BIG_ENDIAN +U64 ll_htonll(U64 hostlonglong) { return hostlonglong; } +U64 ll_ntohll(U64 netlonglong) { return netlonglong; } +F64 ll_htond(F64 hostlonglong) { return hostlonglong; } +F64 ll_ntohd(F64 netlonglong) { return netlonglong; } +#else +// I read some comments one a indicating that doing an integer add +// here would be faster than a bitwise or. For now, the or has +// programmer clarity, since the intended outcome matches the +// operation. +U64 ll_htonll(U64 hostlonglong) +{ +	return ((U64)(htonl((U32)((hostlonglong >> 32) & 0xFFFFFFFF))) | +			((U64)(htonl((U32)(hostlonglong & 0xFFFFFFFF))) << 32)); +} +U64 ll_ntohll(U64 netlonglong) +{ +	return ((U64)(ntohl((U32)((netlonglong >> 32) & 0xFFFFFFFF))) | +			((U64)(ntohl((U32)(netlonglong & 0xFFFFFFFF))) << 32)); +} +union LLEndianSwapper +{ +	F64 d; +	U64 i; +}; +F64 ll_htond(F64 hostdouble) +{ +	LLEndianSwapper tmp; +	tmp.d = hostdouble; +	tmp.i = ll_htonll(tmp.i); +	return tmp.d; +} +F64 ll_ntohd(F64 netdouble) +{ +	LLEndianSwapper tmp; +	tmp.d = netdouble; +	tmp.i = ll_ntohll(tmp.i); +	return tmp.d; +} +#endif + +/** + * Local functions. + */ +/** + * @brief Figure out what kind of string it is (raw or delimited) and handoff. + * + * @param istr The stream to read from. + * @param value [out] The string which was found. + * @param max_bytes The maximum possible length of the string. Passing in + * a negative value will skip this check. + * @return Returns number of bytes read off of the stream. Returns + * PARSE_FAILURE (-1) on failure. + */ +int deserialize_string(std::istream& istr, std::string& value, S32 max_bytes); + +/** + * @brief Parse a delimited string.  + * + * @param istr The stream to read from, with the delimiter already popped. + * @param value [out] The string which was found. + * @param d The delimiter to use. + * @return Returns number of bytes read off of the stream. Returns + * PARSE_FAILURE (-1) on failure. + */ +int deserialize_string_delim(std::istream& istr, std::string& value, char d); + +/** + * @brief Read a raw string off the stream. + * + * @param istr The stream to read from, with the (len) parameter + * leading the stream. + * @param value [out] The string which was found. + * @param d The delimiter to use. + * @param max_bytes The maximum possible length of the string. Passing in + * a negative value will skip this check. + * @return Returns number of bytes read off of the stream. Returns + * PARSE_FAILURE (-1) on failure. + */ +int deserialize_string_raw( +	std::istream& istr, +	std::string& value, +	S32 max_bytes); + +/** + * @brief helper method for dealing with the different notation boolean format. + * + * @param istr The stream to read from with the leading character stripped. + * @param data [out] the result of the parse. + * @param compare The string to compare the boolean against + * @param vale The value to assign to data if the parse succeeds. + * @return Returns number of bytes read off of the stream. Returns + * PARSE_FAILURE (-1) on failure. + */ +int deserialize_boolean( +	std::istream& istr, +	LLSD& data, +	const std::string& compare, +	bool value); + +/** + * @brief Do notation escaping of a string to an ostream. + * + * @param value The string to escape and serialize + * @param str The stream to serialize to. + */ +void serialize_string(const std::string& value, std::ostream& str); + + +/** + * Local constants. + */ +static const std::string NOTATION_TRUE_SERIAL("true"); +static const std::string NOTATION_FALSE_SERIAL("false"); + +static const char BINARY_TRUE_SERIAL = '1'; +static const char BINARY_FALSE_SERIAL = '0'; + + +/** + * LLSDParser + */ +LLSDParser::LLSDParser() +	: mCheckLimits(true), mMaxBytesLeft(0), mParseLines(false) +{ +} + +// virtual +LLSDParser::~LLSDParser() +{ } + +S32 LLSDParser::parse(std::istream& istr, LLSD& data, S32 max_bytes) +{ +	mCheckLimits = (LLSDSerialize::SIZE_UNLIMITED == max_bytes) ? false : true; +	mMaxBytesLeft = max_bytes; +	return doParse(istr, data); +} + + +// Parse using routine to get() lines, faster than parse() +S32 LLSDParser::parseLines(std::istream& istr, LLSD& data) +{ +	mCheckLimits = false; +	mParseLines = true; +	return doParse(istr, data); +} + + +int LLSDParser::get(std::istream& istr) const +{ +	if(mCheckLimits) --mMaxBytesLeft; +	return istr.get(); +} + +std::istream& LLSDParser::get( +	std::istream& istr, +	char* s, +	std::streamsize n, +	char delim) const +{ +	istr.get(s, n, delim); +	if(mCheckLimits) mMaxBytesLeft -= (int)istr.gcount(); +	return istr; +} + +std::istream& LLSDParser::get( +		std::istream& istr, +		std::streambuf& sb, +		char delim) const		 +{ +	istr.get(sb, delim); +	if(mCheckLimits) mMaxBytesLeft -= (int)istr.gcount(); +	return istr; +} + +std::istream& LLSDParser::ignore(std::istream& istr) const +{ +	istr.ignore(); +	if(mCheckLimits) --mMaxBytesLeft; +	return istr; +} + +std::istream& LLSDParser::putback(std::istream& istr, char c) const +{ +	istr.putback(c); +	if(mCheckLimits) ++mMaxBytesLeft; +	return istr; +} + +std::istream& LLSDParser::read( +	std::istream& istr, +	char* s, +	std::streamsize n) const +{ +	istr.read(s, n); +	if(mCheckLimits) mMaxBytesLeft -= (int)istr.gcount(); +	return istr; +} + +void LLSDParser::account(S32 bytes) const +{ +	if(mCheckLimits) mMaxBytesLeft -= bytes; +} + + +/** + * LLSDNotationParser + */ +LLSDNotationParser::LLSDNotationParser() +{ +}	 + +// virtual +LLSDNotationParser::~LLSDNotationParser() +{ } + +// virtual +S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data) const +{ +	// map: { string:object, string:object } +	// array: [ object, object, object ] +	// undef: ! +	// boolean: true | false | 1 | 0 | T | F | t | f | TRUE | FALSE +	// integer: i#### +	// real: r#### +	// uuid: u#### +	// string: "g'day" | 'have a "nice" day' | s(size)"raw data" +	// uri: l"escaped" +	// date: d"YYYY-MM-DDTHH:MM:SS.FFZ" +	// binary: b##"ff3120ab1" | b(size)"raw data" +	char c; +	c = istr.peek(); +	while(isspace(c)) +	{ +		// pop the whitespace. +		c = get(istr); +		c = istr.peek(); +		continue; +	} +	if(!istr.good()) +	{ +		return 0; +	} +	S32 parse_count = 1; +	switch(c) +	{ +	case '{': +	{ +		S32 child_count = parseMap(istr, data); +		if((child_count == PARSE_FAILURE) || data.isUndefined()) +		{ +			parse_count = PARSE_FAILURE; +		} +		else +		{ +			parse_count += child_count; +		} +		if(istr.fail()) +		{ +			llinfos << "STREAM FAILURE reading map." << llendl; +			parse_count = PARSE_FAILURE; +		} +		break; +	} + +	case '[': +	{ +		S32 child_count = parseArray(istr, data); +		if((child_count == PARSE_FAILURE) || data.isUndefined()) +		{ +			parse_count = PARSE_FAILURE; +		} +		else +		{ +			parse_count += child_count; +		} +		if(istr.fail()) +		{ +			llinfos << "STREAM FAILURE reading array." << llendl; +			parse_count = PARSE_FAILURE; +		} +		break; +	} + +	case '!': +		c = get(istr); +		data.clear(); +		break; + +	case '0': +		c = get(istr); +		data = false; +		break; + +	case 'F': +	case 'f': +		ignore(istr); +		c = istr.peek(); +		if(isalpha(c)) +		{ +			int cnt = deserialize_boolean( +				istr, +				data, +				NOTATION_FALSE_SERIAL, +				false); +			if(PARSE_FAILURE == cnt) parse_count = cnt; +			else account(cnt); +		} +		else +		{ +			data = false; +		} +		if(istr.fail()) +		{ +			llinfos << "STREAM FAILURE reading boolean." << llendl; +			parse_count = PARSE_FAILURE; +		} +		break; + +	case '1': +		c = get(istr); +		data = true; +		break; + +	case 'T': +	case 't': +		ignore(istr); +		c = istr.peek(); +		if(isalpha(c)) +		{ +			int cnt = deserialize_boolean(istr,data,NOTATION_TRUE_SERIAL,true); +			if(PARSE_FAILURE == cnt) parse_count = cnt; +			else account(cnt); +		} +		else +		{ +			data = true; +		} +		if(istr.fail()) +		{ +			llinfos << "STREAM FAILURE reading boolean." << llendl; +			parse_count = PARSE_FAILURE; +		} +		break; + +	case 'i': +	{ +		c = get(istr); +		S32 integer = 0; +		istr >> integer; +		data = integer; +		if(istr.fail()) +		{ +			llinfos << "STREAM FAILURE reading integer." << llendl; +			parse_count = PARSE_FAILURE; +		} +		break; +	} + +	case 'r': +	{ +		c = get(istr); +		F64 real = 0.0; +		istr >> real; +		data = real; +		if(istr.fail()) +		{ +			llinfos << "STREAM FAILURE reading real." << llendl; +			parse_count = PARSE_FAILURE; +		} +		break; +	} + +	case 'u': +	{ +		c = get(istr); +		LLUUID id; +		istr >> id; +		data = id; +		if(istr.fail()) +		{ +			llinfos << "STREAM FAILURE reading uuid." << llendl; +			parse_count = PARSE_FAILURE; +		} +		break; +	} + +	case '\"': +	case '\'': +	case 's': +		if(!parseString(istr, data)) +		{ +			parse_count = PARSE_FAILURE; +		} +		if(istr.fail()) +		{ +			llinfos << "STREAM FAILURE reading string." << llendl; +			parse_count = PARSE_FAILURE; +		} +		break; + +	case 'l': +	{ +		c = get(istr); // pop the 'l' +		c = get(istr); // pop the delimiter +		std::string str; +		int cnt = deserialize_string_delim(istr, str, c); +		if(PARSE_FAILURE == cnt) +		{ +			parse_count = PARSE_FAILURE; +		} +		else +		{ +			data = LLURI(str); +			account(cnt); +		} +		if(istr.fail()) +		{ +			llinfos << "STREAM FAILURE reading link." << llendl; +			parse_count = PARSE_FAILURE; +		} +		break; +	} + +	case 'd': +	{ +		c = get(istr); // pop the 'd' +		c = get(istr); // pop the delimiter +		std::string str; +		int cnt = deserialize_string_delim(istr, str, c); +		if(PARSE_FAILURE == cnt) +		{ +			parse_count = PARSE_FAILURE; +		} +		else +		{ +			data = LLDate(str); +			account(cnt); +		} +		if(istr.fail()) +		{ +			llinfos << "STREAM FAILURE reading date." << llendl; +			parse_count = PARSE_FAILURE; +		} +		break; +	} + +	case 'b': +		if(!parseBinary(istr, data)) +		{ +			parse_count = PARSE_FAILURE; +		} +		if(istr.fail()) +		{ +			llinfos << "STREAM FAILURE reading data." << llendl; +			parse_count = PARSE_FAILURE; +		} +		break; + +	default: +		parse_count = PARSE_FAILURE; +		llinfos << "Unrecognized character while parsing: int(" << (int)c +			<< ")" << llendl; +		break; +	} +	if(PARSE_FAILURE == parse_count) +	{ +		data.clear(); +	} +	return parse_count; +} + +S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map) const +{ +	// map: { string:object, string:object } +	map = LLSD::emptyMap(); +	S32 parse_count = 0; +	char c = get(istr); +	if(c == '{') +	{ +		// eat commas, white +		bool found_name = false; +		std::string name; +		c = get(istr); +		while(c != '}' && istr.good()) +		{ +			if(!found_name) +			{ +				if((c == '\"') || (c == '\'') || (c == 's')) +				{ +					putback(istr, c); +					found_name = true; +					int count = deserialize_string(istr, name, mMaxBytesLeft); +					if(PARSE_FAILURE == count) return PARSE_FAILURE; +					account(count); +				} +				c = get(istr); +			} +			else +			{ +				if(isspace(c) || (c == ':')) +				{ +					c = get(istr); +					continue; +				} +				putback(istr, c); +				LLSD child; +				S32 count = doParse(istr, child); +				if(count > 0) +				{ +					// There must be a value for every key, thus +					// child_count must be greater than 0. +					parse_count += count; +					map.insert(name, child); +				} +				else +				{ +					return PARSE_FAILURE; +				} +				found_name = false; +				c = get(istr); +			} +		} +		if(c != '}') +		{ +			map.clear(); +			return PARSE_FAILURE; +		} +	} +	return parse_count; +} + +S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array) const +{ +	// array: [ object, object, object ] +	array = LLSD::emptyArray(); +	S32 parse_count = 0; +	char c = get(istr); +	if(c == '[') +	{ +		// eat commas, white +		c = get(istr); +		while((c != ']') && istr.good()) +		{ +			LLSD child; +			if(isspace(c) || (c == ',')) +			{ +				c = get(istr); +				continue; +			} +			putback(istr, c); +			S32 count = doParse(istr, child); +			if(PARSE_FAILURE == count) +			{ +				return PARSE_FAILURE; +			} +			else +			{ +				parse_count += count; +				array.append(child); +			} +			c = get(istr); +		} +		if(c != ']') +		{ +			return PARSE_FAILURE; +		} +	} +	return parse_count; +} + +bool LLSDNotationParser::parseString(std::istream& istr, LLSD& data) const +{ +	std::string value; +	int count = deserialize_string(istr, value, mMaxBytesLeft); +	if(PARSE_FAILURE == count) return false; +	account(count); +	data = value; +	return true; +} + +bool LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const +{ +	// binary: b##"ff3120ab1" +	// or: b(len)"..." + +	// I want to manually control those values here to make sure the +	// parser doesn't break when someone changes a constant somewhere +	// else. +	const U32 BINARY_BUFFER_SIZE = 256; +	const U32 STREAM_GET_COUNT = 255; + +	// need to read the base out. +	char buf[BINARY_BUFFER_SIZE];		/* Flawfinder: ignore */ +	get(istr, buf, STREAM_GET_COUNT, '"'); +	char c = get(istr); +	if(c != '"') return false; +	if(0 == strncmp("b(", buf, 2)) +	{ +		// We probably have a valid raw binary stream. determine +		// the size, and read it. +		S32 len = strtol(buf + 2, NULL, 0); +		if(mCheckLimits && (len > mMaxBytesLeft)) return false; +		std::vector<U8> value; +		if(len) +		{ +			value.resize(len); +			account((int)fullread(istr, (char *)&value[0], len)); +		} +		c = get(istr); // strip off the trailing double-quote +		data = value; +	} +	else if(0 == strncmp("b64", buf, 3)) +	{ +		// *FIX: A bit inefficient, but works for now. To make the +		// format better, I would need to add a hint into the +		// serialization format that indicated how long it was. +		std::stringstream coded_stream; +		get(istr, *(coded_stream.rdbuf()), '\"'); +		c = get(istr); +		std::string encoded(coded_stream.str()); +		S32 len = apr_base64_decode_len(encoded.c_str()); +		std::vector<U8> value; +		if(len) +		{ +			value.resize(len); +			len = apr_base64_decode_binary(&value[0], encoded.c_str()); +			value.resize(len); +		} +		data = value; +	} +	else if(0 == strncmp("b16", buf, 3)) +	{ +		// yay, base 16. We pop the next character which is either a +		// double quote or base 16 data. If it's a double quote, we're +		// done parsing. If it's not, put the data back, and read the +		// stream until the next double quote. +		char* read;	 /*Flawfinder: ignore*/ +		U8 byte; +		U8 byte_buffer[BINARY_BUFFER_SIZE]; +		U8* write; +		std::vector<U8> value; +		c = get(istr); +		while(c != '"') +		{ +			putback(istr, c); +			read = buf; +			write = byte_buffer; +			get(istr, buf, STREAM_GET_COUNT, '"'); +			c = get(istr); +			while(*read != '\0')	 /*Flawfinder: ignore*/ +			{ +				byte = hex_as_nybble(*read++); +				byte = byte << 4; +				byte |= hex_as_nybble(*read++); +				*write++ = byte; +			} +			// copy the data out of the byte buffer +			value.insert(value.end(), byte_buffer, write); +		} +		data = value; +	} +	else +	{ +		return false; +	} +	return true; +} + + +/** + * LLSDBinaryParser + */ +LLSDBinaryParser::LLSDBinaryParser() +{ +} + +// virtual +LLSDBinaryParser::~LLSDBinaryParser() +{ +} + +// virtual +S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const +{ +/** + * Undefined: '!'<br> + * Boolean: 't' for true 'f' for false<br> + * Integer: 'i' + 4 bytes network byte order<br> + * Real: 'r' + 8 bytes IEEE double<br> + * UUID: 'u' + 16 byte unsigned integer<br> + * String: 's' + 4 byte integer size + string<br> + *  strings also secretly support the notation format + * Date: 'd' + 8 byte IEEE double for seconds since epoch<br> + * URI: 'l' + 4 byte integer size + string uri<br> + * Binary: 'b' + 4 byte integer size + binary data<br> + * Array: '[' + 4 byte integer size  + all values + ']'<br> + * Map: '{' + 4 byte integer size  every(key + value) + '}'<br> + *  map keys are serialized as s + 4 byte integer size + string or in the + *  notation format. + */ +	char c; +	c = get(istr); +	if(!istr.good()) +	{ +		return 0; +	} +	S32 parse_count = 1; +	switch(c) +	{ +	case '{': +	{ +		S32 child_count = parseMap(istr, data); +		if((child_count == PARSE_FAILURE) || data.isUndefined()) +		{ +			parse_count = PARSE_FAILURE; +		} +		else +		{ +			parse_count += child_count; +		} +		if(istr.fail()) +		{ +			llinfos << "STREAM FAILURE reading binary map." << llendl; +			parse_count = PARSE_FAILURE; +		} +		break; +	} + +	case '[': +	{ +		S32 child_count = parseArray(istr, data); +		if((child_count == PARSE_FAILURE) || data.isUndefined()) +		{ +			parse_count = PARSE_FAILURE; +		} +		else +		{ +			parse_count += child_count; +		} +		if(istr.fail()) +		{ +			llinfos << "STREAM FAILURE reading binary array." << llendl; +			parse_count = PARSE_FAILURE; +		} +		break; +	} + +	case '!': +		data.clear(); +		break; + +	case '0': +		data = false; +		break; + +	case '1': +		data = true; +		break; + +	case 'i': +	{ +		U32 value_nbo = 0; +		read(istr, (char*)&value_nbo, sizeof(U32));	 /*Flawfinder: ignore*/ +		data = (S32)ntohl(value_nbo); +		if(istr.fail()) +		{ +			llinfos << "STREAM FAILURE reading binary integer." << llendl; +		} +		break; +	} + +	case 'r': +	{ +		F64 real_nbo = 0.0; +		read(istr, (char*)&real_nbo, sizeof(F64));	 /*Flawfinder: ignore*/ +		data = ll_ntohd(real_nbo); +		if(istr.fail()) +		{ +			llinfos << "STREAM FAILURE reading binary real." << llendl; +		} +		break; +	} + +	case 'u': +	{ +		LLUUID id; +		read(istr, (char*)(&id.mData), UUID_BYTES);	 /*Flawfinder: ignore*/ +		data = id; +		if(istr.fail()) +		{ +			llinfos << "STREAM FAILURE reading binary uuid." << llendl; +		} +		break; +	} + +	case '\'': +	case '"': +	{ +		std::string value; +		int cnt = deserialize_string_delim(istr, value, c); +		if(PARSE_FAILURE == cnt) +		{ +			parse_count = PARSE_FAILURE; +		} +		else +		{ +			data = value; +			account(cnt); +		} +		if(istr.fail()) +		{ +			llinfos << "STREAM FAILURE reading binary (notation-style) string." +				<< llendl; +			parse_count = PARSE_FAILURE; +		} +		break; +	} + +	case 's': +	{ +		std::string value; +		if(parseString(istr, value)) +		{ +			data = value; +		} +		else +		{ +			parse_count = PARSE_FAILURE; +		} +		if(istr.fail()) +		{ +			llinfos << "STREAM FAILURE reading binary string." << llendl; +			parse_count = PARSE_FAILURE; +		} +		break; +	} + +	case 'l': +	{ +		std::string value; +		if(parseString(istr, value)) +		{ +			data = LLURI(value); +		} +		else +		{ +			parse_count = PARSE_FAILURE; +		} +		if(istr.fail()) +		{ +			llinfos << "STREAM FAILURE reading binary link." << llendl; +			parse_count = PARSE_FAILURE; +		} +		break; +	} + +	case 'd': +	{ +		F64 real = 0.0; +		read(istr, (char*)&real, sizeof(F64));	 /*Flawfinder: ignore*/ +		data = LLDate(real); +		if(istr.fail()) +		{ +			llinfos << "STREAM FAILURE reading binary date." << llendl; +			parse_count = PARSE_FAILURE; +		} +		break; +	} + +	case 'b': +	{ +		// We probably have a valid raw binary stream. determine +		// the size, and read it. +		U32 size_nbo = 0; +		read(istr, (char*)&size_nbo, sizeof(U32));	/*Flawfinder: ignore*/ +		S32 size = (S32)ntohl(size_nbo); +		if(mCheckLimits && (size > mMaxBytesLeft)) +		{ +			parse_count = PARSE_FAILURE; +		} +		else +		{ +			std::vector<U8> value; +			if(size > 0) +			{ +				value.resize(size); +				account((int)fullread(istr, (char*)&value[0], size)); +			} +			data = value; +		} +		if(istr.fail()) +		{ +			llinfos << "STREAM FAILURE reading binary." << llendl; +			parse_count = PARSE_FAILURE; +		} +		break; +	} + +	default: +		parse_count = PARSE_FAILURE; +		llinfos << "Unrecognized character while parsing: int(" << (int)c +			<< ")" << llendl; +		break; +	} +	if(PARSE_FAILURE == parse_count) +	{ +		data.clear(); +	} +	return parse_count; +} + +S32 LLSDBinaryParser::parseMap(std::istream& istr, LLSD& map) const +{ +	map = LLSD::emptyMap(); +	U32 value_nbo = 0; +	read(istr, (char*)&value_nbo, sizeof(U32));		 /*Flawfinder: ignore*/ +	S32 size = (S32)ntohl(value_nbo); +	S32 parse_count = 0; +	S32 count = 0; +	char c = get(istr); +	while(c != '}' && (count < size) && istr.good()) +	{ +		std::string name; +		switch(c) +		{ +		case 'k': +			if(!parseString(istr, name)) +			{ +				return PARSE_FAILURE; +			} +			break; +		case '\'': +		case '"': +		{ +			int cnt = deserialize_string_delim(istr, name, c); +			if(PARSE_FAILURE == cnt) return PARSE_FAILURE; +			account(cnt); +			break; +		} +		} +		LLSD child; +		S32 child_count = doParse(istr, child); +		if(child_count > 0) +		{ +			// There must be a value for every key, thus child_count +			// must be greater than 0. +			parse_count += child_count; +			map.insert(name, child); +		} +		else +		{ +			return PARSE_FAILURE; +		} +		++count; +		c = get(istr); +	} +	if((c != '}') || (count < size)) +	{ +		// Make sure it is correctly terminated and we parsed as many +		// as were said to be there. +		return PARSE_FAILURE; +	} +	return parse_count; +} + +S32 LLSDBinaryParser::parseArray(std::istream& istr, LLSD& array) const +{ +	array = LLSD::emptyArray(); +	U32 value_nbo = 0; +	read(istr, (char*)&value_nbo, sizeof(U32));		 /*Flawfinder: ignore*/ +	S32 size = (S32)ntohl(value_nbo); + +	// *FIX: This would be a good place to reserve some space in the +	// array... + +	S32 parse_count = 0; +	S32 count = 0; +	char c = istr.peek(); +	while((c != ']') && (count < size) && istr.good()) +	{ +		LLSD child; +		S32 child_count = doParse(istr, child); +		if(PARSE_FAILURE == child_count) +		{ +			return PARSE_FAILURE; +		} +		if(child_count) +		{ +			parse_count += child_count; +			array.append(child); +		} +		++count; +		c = istr.peek(); +	} +	c = get(istr); +	if((c != ']') || (count < size)) +	{ +		// Make sure it is correctly terminated and we parsed as many +		// as were said to be there. +		return PARSE_FAILURE; +	} +	return parse_count; +} + +bool LLSDBinaryParser::parseString( +	std::istream& istr, +	std::string& value) const +{ +	// *FIX: This is memory inefficient. +	U32 value_nbo = 0; +	read(istr, (char*)&value_nbo, sizeof(U32));		 /*Flawfinder: ignore*/ +	S32 size = (S32)ntohl(value_nbo); +	if(mCheckLimits && (size > mMaxBytesLeft)) return false; +	std::vector<char> buf; +	if(size) +	{ +		buf.resize(size); +		account((int)fullread(istr, &buf[0], size)); +		value.assign(buf.begin(), buf.end()); +	} +	return true; +} + + +/** + * LLSDFormatter + */ +LLSDFormatter::LLSDFormatter() : +	mBoolAlpha(false) +{ +} + +// virtual +LLSDFormatter::~LLSDFormatter() +{ } + +void LLSDFormatter::boolalpha(bool alpha) +{ +	mBoolAlpha = alpha; +} + +void LLSDFormatter::realFormat(const std::string& format) +{ +	mRealFormat = format; +} + +void LLSDFormatter::formatReal(LLSD::Real real, std::ostream& ostr) const +{ +	std::string buffer = llformat(mRealFormat.c_str(), real); +	ostr << buffer; +} + +/** + * LLSDNotationFormatter + */ +LLSDNotationFormatter::LLSDNotationFormatter() +{ +} + +// virtual +LLSDNotationFormatter::~LLSDNotationFormatter() +{ } + +// static +std::string LLSDNotationFormatter::escapeString(const std::string& in) +{ +	std::ostringstream ostr; +	serialize_string(in, ostr); +	return ostr.str(); +} + +// virtual +S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 options) const +{ +	S32 format_count = 1; +	switch(data.type()) +	{ +	case LLSD::TypeMap: +	{ +		ostr << "{"; +		bool need_comma = false; +		LLSD::map_const_iterator iter = data.beginMap(); +		LLSD::map_const_iterator end = data.endMap(); +		for(; iter != end; ++iter) +		{ +			if(need_comma) ostr << ","; +			need_comma = true; +			ostr << '\''; +			serialize_string((*iter).first, ostr); +			ostr << "':"; +			format_count += format((*iter).second, ostr); +		} +		ostr << "}"; +		break; +	} + +	case LLSD::TypeArray: +	{ +		ostr << "["; +		bool need_comma = false; +		LLSD::array_const_iterator iter = data.beginArray(); +		LLSD::array_const_iterator end = data.endArray(); +		for(; iter != end; ++iter) +		{ +			if(need_comma) ostr << ","; +			need_comma = true; +			format_count += format(*iter, ostr); +		} +		ostr << "]"; +		break; +	} + +	case LLSD::TypeUndefined: +		ostr << "!"; +		break; + +	case LLSD::TypeBoolean: +		if(mBoolAlpha || +#if( LL_WINDOWS || __GNUC__ > 2) +		   (ostr.flags() & std::ios::boolalpha) +#else +		   (ostr.flags() & 0x0100) +#endif +			) +		{ +			ostr << (data.asBoolean() +					 ? NOTATION_TRUE_SERIAL : NOTATION_FALSE_SERIAL); +		} +		else +		{ +			ostr << (data.asBoolean() ? 1 : 0); +		} +		break; + +	case LLSD::TypeInteger: +		ostr << "i" << data.asInteger(); +		break; + +	case LLSD::TypeReal: +		ostr << "r"; +		if(mRealFormat.empty()) +		{ +			ostr << data.asReal(); +		} +		else +		{ +			formatReal(data.asReal(), ostr); +		} +		break; + +	case LLSD::TypeUUID: +		ostr << "u" << data.asUUID(); +		break; + +	case LLSD::TypeString: +		ostr << '\''; +		serialize_string(data.asString(), ostr); +		ostr << '\''; +		break; + +	case LLSD::TypeDate: +		ostr << "d\"" << data.asDate() << "\""; +		break; + +	case LLSD::TypeURI: +		ostr << "l\""; +		serialize_string(data.asString(), ostr); +		ostr << "\""; +		break; + +	case LLSD::TypeBinary: +	{ +		// *FIX: memory inefficient. +		std::vector<U8> buffer = data.asBinary(); +		ostr << "b(" << buffer.size() << ")\""; +		if(buffer.size()) ostr.write((const char*)&buffer[0], buffer.size()); +		ostr << "\""; +		break; +	} + +	default: +		// *NOTE: This should never happen. +		ostr << "!"; +		break; +	} +	return format_count; +} + + +/** + * LLSDBinaryFormatter + */ +LLSDBinaryFormatter::LLSDBinaryFormatter() +{ +} + +// virtual +LLSDBinaryFormatter::~LLSDBinaryFormatter() +{ } + +// virtual +S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 options) const +{ +	S32 format_count = 1; +	switch(data.type()) +	{ +	case LLSD::TypeMap: +	{ +		ostr.put('{'); +		U32 size_nbo = htonl(data.size()); +		ostr.write((const char*)(&size_nbo), sizeof(U32)); +		LLSD::map_const_iterator iter = data.beginMap(); +		LLSD::map_const_iterator end = data.endMap(); +		for(; iter != end; ++iter) +		{ +			ostr.put('k'); +			formatString((*iter).first, ostr); +			format_count += format((*iter).second, ostr); +		} +		ostr.put('}'); +		break; +	} + +	case LLSD::TypeArray: +	{ +		ostr.put('['); +		U32 size_nbo = htonl(data.size()); +		ostr.write((const char*)(&size_nbo), sizeof(U32)); +		LLSD::array_const_iterator iter = data.beginArray(); +		LLSD::array_const_iterator end = data.endArray(); +		for(; iter != end; ++iter) +		{ +			format_count += format(*iter, ostr); +		} +		ostr.put(']'); +		break; +	} + +	case LLSD::TypeUndefined: +		ostr.put('!'); +		break; + +	case LLSD::TypeBoolean: +		if(data.asBoolean()) ostr.put(BINARY_TRUE_SERIAL); +		else ostr.put(BINARY_FALSE_SERIAL); +		break; + +	case LLSD::TypeInteger: +	{ +		ostr.put('i'); +		U32 value_nbo = htonl(data.asInteger()); +		ostr.write((const char*)(&value_nbo), sizeof(U32)); +		break; +	} + +	case LLSD::TypeReal: +	{ +		ostr.put('r'); +		F64 value_nbo = ll_htond(data.asReal()); +		ostr.write((const char*)(&value_nbo), sizeof(F64)); +		break; +	} + +	case LLSD::TypeUUID: +		ostr.put('u'); +		ostr.write((const char*)(&(data.asUUID().mData)), UUID_BYTES); +		break; + +	case LLSD::TypeString: +		ostr.put('s'); +		formatString(data.asString(), ostr); +		break; + +	case LLSD::TypeDate: +	{ +		ostr.put('d'); +		F64 value = data.asReal(); +		ostr.write((const char*)(&value), sizeof(F64)); +		break; +	} + +	case LLSD::TypeURI: +		ostr.put('l'); +		formatString(data.asString(), ostr); +		break; + +	case LLSD::TypeBinary: +	{ +		// *FIX: memory inefficient. +		ostr.put('b'); +		std::vector<U8> buffer = data.asBinary(); +		U32 size_nbo = htonl(buffer.size()); +		ostr.write((const char*)(&size_nbo), sizeof(U32)); +		if(buffer.size()) ostr.write((const char*)&buffer[0], buffer.size()); +		break; +	} + +	default: +		// *NOTE: This should never happen. +		ostr.put('!'); +		break; +	} +	return format_count; +} + +void LLSDBinaryFormatter::formatString( +	const std::string& string, +	std::ostream& ostr) const +{ +	U32 size_nbo = htonl(string.size()); +	ostr.write((const char*)(&size_nbo), sizeof(U32)); +	ostr.write(string.c_str(), string.size()); +} + +/** + * local functions + */ +int deserialize_string(std::istream& istr, std::string& value, S32 max_bytes) +{ +	int c = istr.get(); +	if(istr.fail()) +	{ +		// No data in stream, bail out but mention the character we +		// grabbed. +		return LLSDParser::PARSE_FAILURE; +	} + +	int rv = LLSDParser::PARSE_FAILURE; +	switch(c) +	{ +	case '\'': +	case '"': +		rv = deserialize_string_delim(istr, value, c); +		break; +	case 's': +		// technically, less than max_bytes, but this is just meant to +		// catch egregious protocol errors. parse errors will be +		// caught in the case of incorrect counts. +		rv = deserialize_string_raw(istr, value, max_bytes); +		break; +	default: +		break; +	} +	if(LLSDParser::PARSE_FAILURE == rv) return rv; +	return rv + 1; // account for the character grabbed at the top. +} + +int deserialize_string_delim( +	std::istream& istr, +	std::string& value, +	char delim) +{ +	std::ostringstream write_buffer; +	bool found_escape = false; +	bool found_hex = false; +	bool found_digit = false; +	U8 byte = 0; +	int count = 0; + +	while (true) +	{ +		int next_byte = istr.get(); +		++count; + +		if(istr.fail()) +		{ +			// If our stream is empty, break out +			value = write_buffer.str(); +			return LLSDParser::PARSE_FAILURE; +		} + +		char next_char = (char)next_byte; // Now that we know it's not EOF +		 +		if(found_escape) +		{ +			// next character(s) is a special sequence. +			if(found_hex) +			{ +				if(found_digit) +				{ +					found_digit = false; +					found_hex = false; +					found_escape = false; +					byte = byte << 4; +					byte |= hex_as_nybble(next_char); +					write_buffer << byte; +					byte = 0; +				} +				else +				{ +					// next character is the first nybble of +					// +					found_digit = true; +					byte = hex_as_nybble(next_char); +				} +			} +			else if(next_char == 'x') +			{ +				found_hex = true; +			} +			else +			{ +				switch(next_char) +				{ +				case 'a': +					write_buffer << '\a'; +					break; +				case 'b': +					write_buffer << '\b'; +					break; +				case 'f': +					write_buffer << '\f'; +					break; +				case 'n': +					write_buffer << '\n'; +					break; +				case 'r': +					write_buffer << '\r'; +					break; +				case 't': +					write_buffer << '\t'; +					break; +				case 'v': +					write_buffer << '\v'; +					break; +				default: +					write_buffer << next_char; +					break; +				} +				found_escape = false; +			} +		} +		else if(next_char == '\\') +		{ +			found_escape = true; +		} +		else if(next_char == delim) +		{ +			break; +		} +		else +		{ +			write_buffer << next_char; +		} +	} + +	value = write_buffer.str(); +	return count; +} + +int deserialize_string_raw( +	std::istream& istr, +	std::string& value, +	S32 max_bytes) +{ +	int count = 0; +	const S32 BUF_LEN = 20; +	char buf[BUF_LEN];		/* Flawfinder: ignore */ +	istr.get(buf, BUF_LEN - 1, ')'); +	count += (int)istr.gcount(); +	int c = istr.get(); +	c = istr.get(); +	count += 2; +	if(((c == '"') || (c == '\'')) && (buf[0] == '(')) +	{ +		// We probably have a valid raw string. determine +		// the size, and read it. +		// *FIX: This is memory inefficient. +		S32 len = strtol(buf + 1, NULL, 0); +		if((max_bytes>0)&&(len>max_bytes)) return LLSDParser::PARSE_FAILURE; +		std::vector<char> buf; +		if(len) +		{ +			buf.resize(len); +			count += (int)fullread(istr, (char *)&buf[0], len); +			value.assign(buf.begin(), buf.end()); +		} +		c = istr.get(); +		++count; +		if(!((c == '"') || (c == '\''))) +		{ +			return LLSDParser::PARSE_FAILURE; +		} +	} +	else +	{ +		return LLSDParser::PARSE_FAILURE; +	} +	return count; +} + +static const char* NOTATION_STRING_CHARACTERS[256] = +{ +	"\\x00",	// 0 +	"\\x01",	// 1 +	"\\x02",	// 2 +	"\\x03",	// 3 +	"\\x04",	// 4 +	"\\x05",	// 5 +	"\\x06",	// 6 +	"\\a",		// 7 +	"\\b",		// 8 +	"\\t",		// 9 +	"\\n",		// 10 +	"\\v",		// 11 +	"\\f",		// 12 +	"\\r",		// 13 +	"\\x0e",	// 14 +	"\\x0f",	// 15 +	"\\x10",	// 16 +	"\\x11",	// 17 +	"\\x12",	// 18 +	"\\x13",	// 19 +	"\\x14",	// 20 +	"\\x15",	// 21 +	"\\x16",	// 22 +	"\\x17",	// 23 +	"\\x18",	// 24 +	"\\x19",	// 25 +	"\\x1a",	// 26 +	"\\x1b",	// 27 +	"\\x1c",	// 28 +	"\\x1d",	// 29 +	"\\x1e",	// 30 +	"\\x1f",	// 31 +	" ",		// 32 +	"!",		// 33 +	"\"",		// 34 +	"#",		// 35 +	"$",		// 36 +	"%",		// 37 +	"&",		// 38 +	"\\'",		// 39 +	"(",		// 40 +	")",		// 41 +	"*",		// 42 +	"+",		// 43 +	",",		// 44 +	"-",		// 45 +	".",		// 46 +	"/",		// 47 +	"0",		// 48 +	"1",		// 49 +	"2",		// 50 +	"3",		// 51 +	"4",		// 52 +	"5",		// 53 +	"6",		// 54 +	"7",		// 55 +	"8",		// 56 +	"9",		// 57 +	":",		// 58 +	";",		// 59 +	"<",		// 60 +	"=",		// 61 +	">",		// 62 +	"?",		// 63 +	"@",		// 64 +	"A",		// 65 +	"B",		// 66 +	"C",		// 67 +	"D",		// 68 +	"E",		// 69 +	"F",		// 70 +	"G",		// 71 +	"H",		// 72 +	"I",		// 73 +	"J",		// 74 +	"K",		// 75 +	"L",		// 76 +	"M",		// 77 +	"N",		// 78 +	"O",		// 79 +	"P",		// 80 +	"Q",		// 81 +	"R",		// 82 +	"S",		// 83 +	"T",		// 84 +	"U",		// 85 +	"V",		// 86 +	"W",		// 87 +	"X",		// 88 +	"Y",		// 89 +	"Z",		// 90 +	"[",		// 91 +	"\\\\",		// 92 +	"]",		// 93 +	"^",		// 94 +	"_",		// 95 +	"`",		// 96 +	"a",		// 97 +	"b",		// 98 +	"c",		// 99 +	"d",		// 100 +	"e",		// 101 +	"f",		// 102 +	"g",		// 103 +	"h",		// 104 +	"i",		// 105 +	"j",		// 106 +	"k",		// 107 +	"l",		// 108 +	"m",		// 109 +	"n",		// 110 +	"o",		// 111 +	"p",		// 112 +	"q",		// 113 +	"r",		// 114 +	"s",		// 115 +	"t",		// 116 +	"u",		// 117 +	"v",		// 118 +	"w",		// 119 +	"x",		// 120 +	"y",		// 121 +	"z",		// 122 +	"{",		// 123 +	"|",		// 124 +	"}",		// 125 +	"~",		// 126 +	"\\x7f",	// 127 +	"\\x80",	// 128 +	"\\x81",	// 129 +	"\\x82",	// 130 +	"\\x83",	// 131 +	"\\x84",	// 132 +	"\\x85",	// 133 +	"\\x86",	// 134 +	"\\x87",	// 135 +	"\\x88",	// 136 +	"\\x89",	// 137 +	"\\x8a",	// 138 +	"\\x8b",	// 139 +	"\\x8c",	// 140 +	"\\x8d",	// 141 +	"\\x8e",	// 142 +	"\\x8f",	// 143 +	"\\x90",	// 144 +	"\\x91",	// 145 +	"\\x92",	// 146 +	"\\x93",	// 147 +	"\\x94",	// 148 +	"\\x95",	// 149 +	"\\x96",	// 150 +	"\\x97",	// 151 +	"\\x98",	// 152 +	"\\x99",	// 153 +	"\\x9a",	// 154 +	"\\x9b",	// 155 +	"\\x9c",	// 156 +	"\\x9d",	// 157 +	"\\x9e",	// 158 +	"\\x9f",	// 159 +	"\\xa0",	// 160 +	"\\xa1",	// 161 +	"\\xa2",	// 162 +	"\\xa3",	// 163 +	"\\xa4",	// 164 +	"\\xa5",	// 165 +	"\\xa6",	// 166 +	"\\xa7",	// 167 +	"\\xa8",	// 168 +	"\\xa9",	// 169 +	"\\xaa",	// 170 +	"\\xab",	// 171 +	"\\xac",	// 172 +	"\\xad",	// 173 +	"\\xae",	// 174 +	"\\xaf",	// 175 +	"\\xb0",	// 176 +	"\\xb1",	// 177 +	"\\xb2",	// 178 +	"\\xb3",	// 179 +	"\\xb4",	// 180 +	"\\xb5",	// 181 +	"\\xb6",	// 182 +	"\\xb7",	// 183 +	"\\xb8",	// 184 +	"\\xb9",	// 185 +	"\\xba",	// 186 +	"\\xbb",	// 187 +	"\\xbc",	// 188 +	"\\xbd",	// 189 +	"\\xbe",	// 190 +	"\\xbf",	// 191 +	"\\xc0",	// 192 +	"\\xc1",	// 193 +	"\\xc2",	// 194 +	"\\xc3",	// 195 +	"\\xc4",	// 196 +	"\\xc5",	// 197 +	"\\xc6",	// 198 +	"\\xc7",	// 199 +	"\\xc8",	// 200 +	"\\xc9",	// 201 +	"\\xca",	// 202 +	"\\xcb",	// 203 +	"\\xcc",	// 204 +	"\\xcd",	// 205 +	"\\xce",	// 206 +	"\\xcf",	// 207 +	"\\xd0",	// 208 +	"\\xd1",	// 209 +	"\\xd2",	// 210 +	"\\xd3",	// 211 +	"\\xd4",	// 212 +	"\\xd5",	// 213 +	"\\xd6",	// 214 +	"\\xd7",	// 215 +	"\\xd8",	// 216 +	"\\xd9",	// 217 +	"\\xda",	// 218 +	"\\xdb",	// 219 +	"\\xdc",	// 220 +	"\\xdd",	// 221 +	"\\xde",	// 222 +	"\\xdf",	// 223 +	"\\xe0",	// 224 +	"\\xe1",	// 225 +	"\\xe2",	// 226 +	"\\xe3",	// 227 +	"\\xe4",	// 228 +	"\\xe5",	// 229 +	"\\xe6",	// 230 +	"\\xe7",	// 231 +	"\\xe8",	// 232 +	"\\xe9",	// 233 +	"\\xea",	// 234 +	"\\xeb",	// 235 +	"\\xec",	// 236 +	"\\xed",	// 237 +	"\\xee",	// 238 +	"\\xef",	// 239 +	"\\xf0",	// 240 +	"\\xf1",	// 241 +	"\\xf2",	// 242 +	"\\xf3",	// 243 +	"\\xf4",	// 244 +	"\\xf5",	// 245 +	"\\xf6",	// 246 +	"\\xf7",	// 247 +	"\\xf8",	// 248 +	"\\xf9",	// 249 +	"\\xfa",	// 250 +	"\\xfb",	// 251 +	"\\xfc",	// 252 +	"\\xfd",	// 253 +	"\\xfe",	// 254 +	"\\xff"		// 255 +}; + +void serialize_string(const std::string& value, std::ostream& str) +{ +	std::string::const_iterator it = value.begin(); +	std::string::const_iterator end = value.end(); +	U8 c; +	for(; it != end; ++it) +	{ +		c = (U8)(*it); +		str << NOTATION_STRING_CHARACTERS[c]; +	} +} + +int deserialize_boolean( +	std::istream& istr, +	LLSD& data, +	const std::string& compare, +	bool value) +{ +	// +	// this method is a little goofy, because it gets the stream at +	// the point where the t or f has already been +	// consumed. Basically, parse for a patch to the string passed in +	// starting at index 1. If it's a match: +	//  * assign data to value +	//  * return the number of bytes read +	// otherwise: +	//  * set data to LLSD::null +	//  * return LLSDParser::PARSE_FAILURE (-1) +	// +	int bytes_read = 0; +	std::string::size_type ii = 0; +	char c = istr.peek(); +	while((++ii < compare.size()) +		  && (tolower(c) == (int)compare[ii]) +		  && istr.good()) +	{ +		istr.ignore(); +		++bytes_read; +		c = istr.peek(); +	} +	if(compare.size() != ii) +	{ +		data.clear(); +		return LLSDParser::PARSE_FAILURE; +	} +	data = value; +	return bytes_read; +} + +std::ostream& operator<<(std::ostream& s, const LLSD& llsd) +{ +	s << LLSDNotationStreamer(llsd); +	return s; +} + + +//dirty little zippers -- yell at davep if these are horrid + +//return a string containing gzipped bytes of binary serialized LLSD +// VERY inefficient -- creates several copies of LLSD block in memory +std::string zip_llsd(LLSD& data) +{  +	std::stringstream llsd_strm; + +	LLSDSerialize::toBinary(data, llsd_strm); + +	const U32 CHUNK = 65536; + +	z_stream strm; +	strm.zalloc = Z_NULL; +	strm.zfree = Z_NULL; +	strm.opaque = Z_NULL; + +	S32 ret = deflateInit(&strm, Z_BEST_COMPRESSION); +	if (ret != Z_OK) +	{ +		llwarns << "Failed to compress LLSD block." << llendl; +		return std::string(); +	} + +	std::string source = llsd_strm.str(); + +	U8 out[CHUNK]; + +	strm.avail_in = source.size(); +	strm.next_in = (U8*) source.data(); +	U8* output = NULL; + +	U32 cur_size = 0; + +	U32 have = 0; + +	do +	{ +		strm.avail_out = CHUNK; +		strm.next_out = out; + +		ret = deflate(&strm, Z_FINISH); +		if (ret == Z_OK || ret == Z_STREAM_END) +		{ //copy result into output +			if (strm.avail_out >= CHUNK) +			{ +				free(output); +				llwarns << "Failed to compress LLSD block." << llendl; +				return std::string(); +			} + +			have = CHUNK-strm.avail_out; +			output = (U8*) realloc(output, cur_size+have); +			memcpy(output+cur_size, out, have); +			cur_size += have; +		} +		else  +		{ +			free(output); +			llwarns << "Failed to compress LLSD block." << llendl; +			return std::string(); +		} +	} +	while (ret == Z_OK); + +	std::string::size_type size = cur_size; + +	std::string result((char*) output, size); +	deflateEnd(&strm); +	free(output); + +#if 0 //verify results work with unzip_llsd +	std::istringstream test(result); +	LLSD test_sd; +	if (!unzip_llsd(test_sd, test, result.size())) +	{ +		llerrs << "Invalid compression result!" << llendl; +	} +#endif + +	return result; +} + +//decompress a block of LLSD from provided istream +// not very efficient -- creats a copy of decompressed LLSD block in memory +// and deserializes from that copy using LLSDSerialize +bool unzip_llsd(LLSD& data, std::istream& is, S32 size) +{ +	U8* result = NULL; +	U32 cur_size = 0; +	z_stream strm; +		 +	const U32 CHUNK = 65536; + +	U8 *in = new U8[size]; +	is.read((char*) in, size);  + +	U8 out[CHUNK]; +		 +	strm.zalloc = Z_NULL; +	strm.zfree = Z_NULL; +	strm.opaque = Z_NULL; +	strm.avail_in = size; +	strm.next_in = in; + +	S32 ret = inflateInit(&strm); +	 +	do +	{ +		strm.avail_out = CHUNK; +		strm.next_out = out; +		ret = inflate(&strm, Z_NO_FLUSH); +		if (ret == Z_STREAM_ERROR) +		{ +			inflateEnd(&strm); +			free(result); +			delete [] in; +			return false; +		} +		 +		switch (ret) +		{ +		case Z_NEED_DICT: +			ret = Z_DATA_ERROR; +		case Z_DATA_ERROR: +		case Z_MEM_ERROR: +			inflateEnd(&strm); +			free(result); +			delete [] in; +			return false; +			break; +		} + +		U32 have = CHUNK-strm.avail_out; + +		result = (U8*) realloc(result, cur_size + have); +		memcpy(result+cur_size, out, have); +		cur_size += have; + +	} while (ret == Z_OK); + +	inflateEnd(&strm); +	delete [] in; + +	if (ret != Z_STREAM_END) +	{ +		free(result); +		return false; +	} + +	//result now points to the decompressed LLSD block +	{ +		std::string res_str((char*) result, cur_size); + +		std::string deprecated_header("<? LLSD/Binary ?>"); + +		if (res_str.substr(0, deprecated_header.size()) == deprecated_header) +		{ +			res_str = res_str.substr(deprecated_header.size()+1, cur_size); +		} +		cur_size = res_str.size(); + +		std::istringstream istr(res_str); +		 +		if (!LLSDSerialize::fromBinary(data, istr, cur_size)) +		{ +			llwarns << "Failed to unzip LLSD block" << llendl; +			free(result); +			return false; +		}		 +	} + +	free(result); +	return true; +} +//This unzip function will only work with a gzip header and trailer - while the contents +//of the actual compressed data is the same for either format (gzip vs zlib ), the headers +//and trailers are different for the formats. +U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32 size ) +{ +	U8* result = NULL; +	U32 cur_size = 0; +	z_stream strm; +		 +	const U32 CHUNK = 0x4000; + +	U8 *in = new U8[size]; +	is.read((char*) in, size);  + +	U8 out[CHUNK]; +		 +	strm.zalloc = Z_NULL; +	strm.zfree = Z_NULL; +	strm.opaque = Z_NULL; +	strm.avail_in = size; +	strm.next_in = in; + +	 +	S32 ret = inflateInit2(&strm,  windowBits | ENABLE_ZLIB_GZIP ); +	do +	{ +		strm.avail_out = CHUNK; +		strm.next_out = out; +		ret = inflate(&strm, Z_NO_FLUSH); +		if (ret == Z_STREAM_ERROR) +		{ +			inflateEnd(&strm); +			free(result); +			delete [] in; +			valid = false; +		} +		 +		switch (ret) +		{ +		case Z_NEED_DICT: +			ret = Z_DATA_ERROR; +		case Z_DATA_ERROR: +		case Z_MEM_ERROR: +			inflateEnd(&strm); +			free(result); +			delete [] in; +			valid = false; +			break; +		} + +		U32 have = CHUNK-strm.avail_out; + +		result = (U8*) realloc(result, cur_size + have); +		memcpy(result+cur_size, out, have); +		cur_size += have; + +	} while (ret == Z_OK); + +	inflateEnd(&strm); +	delete [] in; + +	if (ret != Z_STREAM_END) +	{ +		free(result); +		valid = false; +		return NULL; +	} + +	//result now points to the decompressed LLSD block +	{ +		outsize= cur_size; +		valid = true;		 +	} + +	return result; +} + + diff --git a/indra/llprimitive/object_flags.h b/indra/llprimitive/object_flags.h index f7f6841b53..b06a5ad4e3 100644 --- a/indra/llprimitive/object_flags.h +++ b/indra/llprimitive/object_flags.h @@ -1,75 +1,75 @@ -/** 
 - * @file object_flags.h
 - * @brief Flags for object creation and transmission
 - *
 - * $LicenseInfo:firstyear=2001&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc.
 - * 
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - * 
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - * 
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - * 
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#ifndef LL_OBJECT_FLAGS_H
 -#define LL_OBJECT_FLAGS_H
 -
 -// downstream flags from sim->viewer
 -const U32   FLAGS_USE_PHYSICS          = (1U << 0);
 -const U32   FLAGS_CREATE_SELECTED      = (1U << 1);
 -const U32   FLAGS_OBJECT_MODIFY        = (1U << 2);
 -const U32   FLAGS_OBJECT_COPY          = (1U << 3);
 -const U32   FLAGS_OBJECT_ANY_OWNER     = (1U << 4);
 -const U32   FLAGS_OBJECT_YOU_OWNER     = (1U << 5);
 -const U32   FLAGS_SCRIPTED             = (1U << 6);
 -const U32   FLAGS_HANDLE_TOUCH         = (1U << 7);
 -const U32   FLAGS_OBJECT_MOVE          = (1U << 8);
 -const U32   FLAGS_TAKES_MONEY          = (1U << 9);
 -const U32   FLAGS_PHANTOM              = (1U << 10);
 -const U32   FLAGS_INVENTORY_EMPTY      = (1U << 11);
 -const U32   FLAGS_OBJECT_PERMANENT     = (1U << 12);
 -const U32   FLAGS_CHARACTER            = (1U << 13);
 -//const U32 FLAGS_UNUSED_000           = (1U << 14); // was FLAGS_JOINT_LP2P
 -const U32   FLAGS_INCLUDE_IN_SEARCH    = (1U << 15);
 -const U32   FLAGS_ALLOW_INVENTORY_DROP = (1U << 16);
 -const U32   FLAGS_OBJECT_TRANSFER      = (1U << 17);
 -const U32   FLAGS_OBJECT_GROUP_OWNED   = (1U << 18);
 -//const U32 FLAGS_UNUSED_001           = (1U << 19); // was FLAGS_OBJECT_YOU_OFFICER
 -const U32   FLAGS_CAMERA_DECOUPLED     = (1U << 20);
 -const U32   FLAGS_ANIM_SOURCE          = (1U << 21);
 -const U32   FLAGS_CAMERA_SOURCE        = (1U << 22);
 -//const U32 FLAGS_UNUSED_002           = (1U << 23); // was FLAGS_CAST_SHADOWS
 -//const U32 FLAGS_UNUSED_003           = (1U << 24);
 -//const U32 FLAGS_UNUSED_004           = (1U << 25);
 -//const U32 FLAGS_UNUSED_005           = (1U << 26);
 -//const U32 FLAGS_UNUSED_006           = (1U << 27);
 -const U32   FLAGS_OBJECT_OWNER_MODIFY  = (1U << 28);
 -const U32   FLAGS_TEMPORARY_ON_REZ     = (1U << 29);
 -//const U32 FLAGS_UNUSED_007           = (1U << 30); // was FLAGS_TEMPORARY
 -//const U32 FLAGS_UNUSED_008           = (1U << 31); // was FLAGS_ZLIB_COMPRESSED
 -const U32   FLAGS_LOCAL                = FLAGS_ANIM_SOURCE | FLAGS_CAMERA_SOURCE;
 -
 -typedef enum e_havok_joint_type
 -{
 -	HJT_INVALID = 0,
 -	HJT_HINGE  	= 1,
 -	HJT_POINT 	= 2,
 -//	HJT_LPOINT 	= 3,
 -//	HJT_WHEEL 	= 4,
 -	HJT_EOF 	= 3
 -} EHavokJointType;
 -
 -#endif
 +/**  + * @file object_flags.h + * @brief Flags for object creation and transmission + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_OBJECT_FLAGS_H +#define LL_OBJECT_FLAGS_H + +// downstream flags from sim->viewer +const U32   FLAGS_USE_PHYSICS          = (1U << 0); +const U32   FLAGS_CREATE_SELECTED      = (1U << 1); +const U32   FLAGS_OBJECT_MODIFY        = (1U << 2); +const U32   FLAGS_OBJECT_COPY          = (1U << 3); +const U32   FLAGS_OBJECT_ANY_OWNER     = (1U << 4); +const U32   FLAGS_OBJECT_YOU_OWNER     = (1U << 5); +const U32   FLAGS_SCRIPTED             = (1U << 6); +const U32   FLAGS_HANDLE_TOUCH         = (1U << 7); +const U32   FLAGS_OBJECT_MOVE          = (1U << 8); +const U32   FLAGS_TAKES_MONEY          = (1U << 9); +const U32   FLAGS_PHANTOM              = (1U << 10); +const U32   FLAGS_INVENTORY_EMPTY      = (1U << 11); +const U32   FLAGS_OBJECT_PERMANENT     = (1U << 12); +const U32   FLAGS_CHARACTER            = (1U << 13); +//const U32 FLAGS_UNUSED_000           = (1U << 14); // was FLAGS_JOINT_LP2P +const U32   FLAGS_INCLUDE_IN_SEARCH    = (1U << 15); +const U32   FLAGS_ALLOW_INVENTORY_DROP = (1U << 16); +const U32   FLAGS_OBJECT_TRANSFER      = (1U << 17); +const U32   FLAGS_OBJECT_GROUP_OWNED   = (1U << 18); +//const U32 FLAGS_UNUSED_001           = (1U << 19); // was FLAGS_OBJECT_YOU_OFFICER +const U32   FLAGS_CAMERA_DECOUPLED     = (1U << 20); +const U32   FLAGS_ANIM_SOURCE          = (1U << 21); +const U32   FLAGS_CAMERA_SOURCE        = (1U << 22); +//const U32 FLAGS_UNUSED_002           = (1U << 23); // was FLAGS_CAST_SHADOWS +//const U32 FLAGS_UNUSED_003           = (1U << 24); +//const U32 FLAGS_UNUSED_004           = (1U << 25); +//const U32 FLAGS_UNUSED_005           = (1U << 26); +//const U32 FLAGS_UNUSED_006           = (1U << 27); +const U32   FLAGS_OBJECT_OWNER_MODIFY  = (1U << 28); +const U32   FLAGS_TEMPORARY_ON_REZ     = (1U << 29); +//const U32 FLAGS_UNUSED_007           = (1U << 30); // was FLAGS_TEMPORARY +//const U32 FLAGS_UNUSED_008           = (1U << 31); // was FLAGS_ZLIB_COMPRESSED +const U32   FLAGS_LOCAL                = FLAGS_ANIM_SOURCE | FLAGS_CAMERA_SOURCE; + +typedef enum e_havok_joint_type +{ +	HJT_INVALID = 0, +	HJT_HINGE  	= 1, +	HJT_POINT 	= 2, +//	HJT_LPOINT 	= 3, +//	HJT_WHEEL 	= 4, +	HJT_EOF 	= 3 +} EHavokJointType; + +#endif diff --git a/indra/newview/llfloaterpathfindingbasic.cpp b/indra/newview/llfloaterpathfindingbasic.cpp index 19d6742559..40752352ea 100644 --- a/indra/newview/llfloaterpathfindingbasic.cpp +++ b/indra/newview/llfloaterpathfindingbasic.cpp @@ -1,167 +1,167 @@ -/** 
 -* @file llfloaterpathfindingbasic.cpp
 -* @author William Todd Stinson
 -* @brief "Pathfinding basic" floater, allowing for basic freezing and unfreezing of the pathfinding avatar mode.
 -*
 -* $LicenseInfo:firstyear=2002&license=viewerlgpl$
 -* Second Life Viewer Source Code
 -* Copyright (C) 2010, Linden Research, Inc.
 -* 
 -* This library is free software; you can redistribute it and/or
 -* modify it under the terms of the GNU Lesser General Public
 -* License as published by the Free Software Foundation;
 -* version 2.1 of the License only.
 -* 
 -* This library is distributed in the hope that it will be useful,
 -* but WITHOUT ANY WARRANTY; without even the implied warranty of
 -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 -* Lesser General Public License for more details.
 -* 
 -* You should have received a copy of the GNU Lesser General Public
 -* License along with this library; if not, write to the Free Software
 -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 -* 
 -* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 -* $/LicenseInfo$
 -*/
 -
 -#include "llviewerprecompiledheaders.h"
 -#include "llfloaterpathfindingbasic.h"
 -#include "llsd.h"
 -#include "lltextbase.h"
 -#include "llbutton.h"
 -#include "llpathfindingmanager.h"
 -
 -#include <boost/bind.hpp>
 -
 -//---------------------------------------------------------------------------
 -// LLFloaterPathfindingBasic
 -//---------------------------------------------------------------------------
 -
 -BOOL LLFloaterPathfindingBasic::postBuild()
 -{
 -	mStatusText = findChild<LLTextBase>("status_label");
 -	llassert(mStatusText != NULL);
 -
 -	mUnfreezeLabel = findChild<LLTextBase>("unfreeze_label");
 -	llassert(mUnfreezeLabel != NULL);
 -
 -	mUnfreezeButton = findChild<LLButton>("enter_unfrozen_mode");
 -	llassert(mUnfreezeButton != NULL);
 -	mUnfreezeButton->setCommitCallback(boost::bind(&LLFloaterPathfindingBasic::onUnfreezeClicked, this));
 -
 -	mFreezeLabel = findChild<LLTextBase>("freeze_label");
 -	llassert(mFreezeLabel != NULL);
 -
 -	mFreezeButton = findChild<LLButton>("enter_frozen_mode");
 -	llassert(mFreezeButton != NULL);
 -	mFreezeButton->setCommitCallback(boost::bind(&LLFloaterPathfindingBasic::onFreezeClicked, this));
 -
 -	return LLFloater::postBuild();
 -}
 -
 -void LLFloaterPathfindingBasic::onOpen(const LLSD& pKey)
 -{
 -	LLFloater::onOpen(pKey);
 -
 -	if (!mAgentStateSlot.connected())
 -	{
 -		mAgentStateSlot = LLPathfindingManager::getInstance()->registerAgentStateListener(boost::bind(&LLFloaterPathfindingBasic::onAgentStateCB, this, _1));
 -	}
 -	setAgentState(LLPathfindingManager::getInstance()->getAgentState());
 -}
 -
 -void LLFloaterPathfindingBasic::onClose(bool pIsAppQuitting)
 -{
 -	if (mAgentStateSlot.connected())
 -	{
 -		mAgentStateSlot.disconnect();
 -	}
 -
 -	LLFloater::onClose(pIsAppQuitting);
 -}
 -
 -LLFloaterPathfindingBasic::LLFloaterPathfindingBasic(const LLSD& pSeed)
 -	: LLFloater(pSeed),
 -	mStatusText(NULL),
 -	mUnfreezeLabel(NULL),
 -	mUnfreezeButton(NULL),
 -	mFreezeLabel(NULL),
 -	mFreezeButton(NULL),
 -	mAgentStateSlot()
 -{
 -}
 -
 -LLFloaterPathfindingBasic::~LLFloaterPathfindingBasic()
 -{
 -}
 -
 -void LLFloaterPathfindingBasic::onUnfreezeClicked()
 -{
 -	mUnfreezeButton->setEnabled(FALSE);
 -	LLPathfindingManager::getInstance()->requestSetAgentState(LLPathfindingManager::kAgentStateUnfrozen);
 -}
 -
 -void LLFloaterPathfindingBasic::onFreezeClicked()
 -{
 -	mUnfreezeButton->setEnabled(FALSE);
 -	LLPathfindingManager::getInstance()->requestSetAgentState(LLPathfindingManager::kAgentStateFrozen);
 -}
 -
 -void LLFloaterPathfindingBasic::onAgentStateCB(LLPathfindingManager::EAgentState pAgentState)
 -{
 -	setAgentState(pAgentState);
 -}
 -
 -void LLFloaterPathfindingBasic::setAgentState(LLPathfindingManager::EAgentState pAgentState)
 -{
 -	static const LLColor4 errorColor = LLUIColorTable::instance().getColor("PathfindingErrorColor");
 -	LLStyle::Params styleParams;
 -
 -	switch (pAgentState)
 -	{
 -	case LLPathfindingManager::kAgentStateUnknown : 
 -		mStatusText->setVisible(TRUE);
 -		mStatusText->setText((LLStringExplicit)getString("status_querying_state"), styleParams);
 -		break;
 -	case LLPathfindingManager::kAgentStateNotEnabled : 
 -		mStatusText->setVisible(TRUE);
 -		styleParams.color = errorColor;
 -		mStatusText->setText((LLStringExplicit)getString("status_pathfinding_not_enabled"), styleParams);
 -		break;
 -	case LLPathfindingManager::kAgentStateError : 
 -		mStatusText->setVisible(TRUE);
 -		styleParams.color = errorColor;
 -		mStatusText->setText((LLStringExplicit)getString("status_unable_to_change_state"), styleParams);
 -		break;
 -	default :
 -		mStatusText->setVisible(FALSE);
 -		break;
 -	}
 -
 -	switch (LLPathfindingManager::getInstance()->getLastKnownNonErrorAgentState())
 -	{
 -	case LLPathfindingManager::kAgentStateUnknown : 
 -	case LLPathfindingManager::kAgentStateNotEnabled : 
 -		mUnfreezeLabel->setEnabled(FALSE);
 -		mUnfreezeButton->setEnabled(FALSE);
 -		mFreezeLabel->setEnabled(FALSE);
 -		mFreezeButton->setEnabled(FALSE);
 -		break;
 -	case LLPathfindingManager::kAgentStateFrozen : 
 -		mUnfreezeLabel->setEnabled(TRUE);
 -		mUnfreezeButton->setEnabled(TRUE);
 -		mFreezeLabel->setEnabled(FALSE);
 -		mFreezeButton->setEnabled(FALSE);
 -		break;
 -	case LLPathfindingManager::kAgentStateUnfrozen : 
 -		mUnfreezeLabel->setEnabled(FALSE);
 -		mUnfreezeButton->setEnabled(FALSE);
 -		mFreezeLabel->setEnabled(TRUE);
 -		mFreezeButton->setEnabled(TRUE);
 -		break;
 -	default :
 -		llassert(0);
 -		break;
 -	}
 -}
 +/**  +* @file llfloaterpathfindingbasic.cpp +* @author William Todd Stinson +* @brief "Pathfinding basic" floater, allowing for basic freezing and unfreezing of the pathfinding avatar mode. +* +* $LicenseInfo:firstyear=2002&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2010, Linden Research, Inc. +*  +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +*  +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +* Lesser General Public License for more details. +*  +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA +*  +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" +#include "llfloaterpathfindingbasic.h" +#include "llsd.h" +#include "lltextbase.h" +#include "llbutton.h" +#include "llpathfindingmanager.h" + +#include <boost/bind.hpp> + +//--------------------------------------------------------------------------- +// LLFloaterPathfindingBasic +//--------------------------------------------------------------------------- + +BOOL LLFloaterPathfindingBasic::postBuild() +{ +	mStatusText = findChild<LLTextBase>("status_label"); +	llassert(mStatusText != NULL); + +	mUnfreezeLabel = findChild<LLTextBase>("unfreeze_label"); +	llassert(mUnfreezeLabel != NULL); + +	mUnfreezeButton = findChild<LLButton>("enter_unfrozen_mode"); +	llassert(mUnfreezeButton != NULL); +	mUnfreezeButton->setCommitCallback(boost::bind(&LLFloaterPathfindingBasic::onUnfreezeClicked, this)); + +	mFreezeLabel = findChild<LLTextBase>("freeze_label"); +	llassert(mFreezeLabel != NULL); + +	mFreezeButton = findChild<LLButton>("enter_frozen_mode"); +	llassert(mFreezeButton != NULL); +	mFreezeButton->setCommitCallback(boost::bind(&LLFloaterPathfindingBasic::onFreezeClicked, this)); + +	return LLFloater::postBuild(); +} + +void LLFloaterPathfindingBasic::onOpen(const LLSD& pKey) +{ +	LLFloater::onOpen(pKey); + +	if (!mAgentStateSlot.connected()) +	{ +		mAgentStateSlot = LLPathfindingManager::getInstance()->registerAgentStateListener(boost::bind(&LLFloaterPathfindingBasic::onAgentStateCB, this, _1)); +	} +	setAgentState(LLPathfindingManager::getInstance()->getAgentState()); +} + +void LLFloaterPathfindingBasic::onClose(bool pIsAppQuitting) +{ +	if (mAgentStateSlot.connected()) +	{ +		mAgentStateSlot.disconnect(); +	} + +	LLFloater::onClose(pIsAppQuitting); +} + +LLFloaterPathfindingBasic::LLFloaterPathfindingBasic(const LLSD& pSeed) +	: LLFloater(pSeed), +	mStatusText(NULL), +	mUnfreezeLabel(NULL), +	mUnfreezeButton(NULL), +	mFreezeLabel(NULL), +	mFreezeButton(NULL), +	mAgentStateSlot() +{ +} + +LLFloaterPathfindingBasic::~LLFloaterPathfindingBasic() +{ +} + +void LLFloaterPathfindingBasic::onUnfreezeClicked() +{ +	mUnfreezeButton->setEnabled(FALSE); +	LLPathfindingManager::getInstance()->requestSetAgentState(LLPathfindingManager::kAgentStateUnfrozen); +} + +void LLFloaterPathfindingBasic::onFreezeClicked() +{ +	mUnfreezeButton->setEnabled(FALSE); +	LLPathfindingManager::getInstance()->requestSetAgentState(LLPathfindingManager::kAgentStateFrozen); +} + +void LLFloaterPathfindingBasic::onAgentStateCB(LLPathfindingManager::EAgentState pAgentState) +{ +	setAgentState(pAgentState); +} + +void LLFloaterPathfindingBasic::setAgentState(LLPathfindingManager::EAgentState pAgentState) +{ +	static const LLColor4 errorColor = LLUIColorTable::instance().getColor("PathfindingErrorColor"); +	LLStyle::Params styleParams; + +	switch (pAgentState) +	{ +	case LLPathfindingManager::kAgentStateUnknown :  +		mStatusText->setVisible(TRUE); +		mStatusText->setText((LLStringExplicit)getString("status_querying_state"), styleParams); +		break; +	case LLPathfindingManager::kAgentStateNotEnabled :  +		mStatusText->setVisible(TRUE); +		styleParams.color = errorColor; +		mStatusText->setText((LLStringExplicit)getString("status_pathfinding_not_enabled"), styleParams); +		break; +	case LLPathfindingManager::kAgentStateError :  +		mStatusText->setVisible(TRUE); +		styleParams.color = errorColor; +		mStatusText->setText((LLStringExplicit)getString("status_unable_to_change_state"), styleParams); +		break; +	default : +		mStatusText->setVisible(FALSE); +		break; +	} + +	switch (LLPathfindingManager::getInstance()->getLastKnownNonErrorAgentState()) +	{ +	case LLPathfindingManager::kAgentStateUnknown :  +	case LLPathfindingManager::kAgentStateNotEnabled :  +		mUnfreezeLabel->setEnabled(FALSE); +		mUnfreezeButton->setEnabled(FALSE); +		mFreezeLabel->setEnabled(FALSE); +		mFreezeButton->setEnabled(FALSE); +		break; +	case LLPathfindingManager::kAgentStateFrozen :  +		mUnfreezeLabel->setEnabled(TRUE); +		mUnfreezeButton->setEnabled(TRUE); +		mFreezeLabel->setEnabled(FALSE); +		mFreezeButton->setEnabled(FALSE); +		break; +	case LLPathfindingManager::kAgentStateUnfrozen :  +		mUnfreezeLabel->setEnabled(FALSE); +		mUnfreezeButton->setEnabled(FALSE); +		mFreezeLabel->setEnabled(TRUE); +		mFreezeButton->setEnabled(TRUE); +		break; +	default : +		llassert(0); +		break; +	} +} diff --git a/indra/newview/llfloaterpathfindingcharacters.cpp b/indra/newview/llfloaterpathfindingcharacters.cpp index 9998d25c7d..ee97063352 100644 --- a/indra/newview/llfloaterpathfindingcharacters.cpp +++ b/indra/newview/llfloaterpathfindingcharacters.cpp @@ -1,558 +1,558 @@ -/** 
 - * @file llfloaterpathfindingcharacters.cpp
 - * @author William Todd Stinson
 - * @brief "Pathfinding characters" floater, allowing for identification of pathfinding characters and their cpu usage.
 - *
 - * $LicenseInfo:firstyear=2002&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc.
 - * 
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - * 
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - * 
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - * 
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#include "llviewerprecompiledheaders.h"
 -#include "llfloater.h"
 -#include "llfloaterpathfindingcharacters.h"
 -#include "llpathfindingcharacterlist.h"
 -#include "llsd.h"
 -#include "llagent.h"
 -#include "llhandle.h"
 -#include "llfloaterreg.h"
 -#include "lltextbase.h"
 -#include "llscrolllistitem.h"
 -#include "llscrolllistctrl.h"
 -#include "llcheckboxctrl.h"
 -#include "llradiogroup.h"
 -#include "llbutton.h"
 -#include "llresmgr.h"
 -#include "llviewerregion.h"
 -#include "llhttpclient.h"
 -#include "lluuid.h"
 -#include "llviewerobject.h"
 -#include "llviewerobjectlist.h"
 -#include "llviewermenu.h"
 -#include "llselectmgr.h"
 -#include "llenvmanager.h"
 -
 -//---------------------------------------------------------------------------
 -// LLFloaterPathfindingCharacters
 -//---------------------------------------------------------------------------
 -
 -BOOL LLFloaterPathfindingCharacters::postBuild()
 -{
 -	mCharactersScrollList = findChild<LLScrollListCtrl>("pathfinding_characters");
 -	llassert(mCharactersScrollList != NULL);
 -	mCharactersScrollList->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onCharactersSelectionChange, this));
 -	mCharactersScrollList->sortByColumnIndex(0, true);
 -
 -	mCharactersStatus = findChild<LLTextBase>("characters_status");
 -	llassert(mCharactersStatus != NULL);
 -
 -	mRefreshListButton = findChild<LLButton>("refresh_characters_list");
 -	llassert(mRefreshListButton != NULL);
 -	mRefreshListButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onRefreshCharactersClicked, this));
 -
 -	mSelectAllButton = findChild<LLButton>("select_all_characters");
 -	llassert(mSelectAllButton != NULL);
 -	mSelectAllButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onSelectAllCharactersClicked, this));
 -
 -	mSelectNoneButton = findChild<LLButton>("select_none_characters");
 -	llassert(mSelectNoneButton != NULL);
 -	mSelectNoneButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onSelectNoneCharactersClicked, this));
 -
 -	mShowBeaconCheckBox = findChild<LLCheckBoxCtrl>("show_beacon");
 -	llassert(mShowBeaconCheckBox != NULL);
 -
 -	mTakeButton = findChild<LLButton>("take_characters");
 -	llassert(mTakeButton != NULL)
 -	mTakeButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onTakeCharactersClicked, this));
 -
 -	mTakeCopyButton = findChild<LLButton>("take_copy_characters");
 -	llassert(mTakeCopyButton != NULL)
 -	mTakeCopyButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onTakeCopyCharactersClicked, this));
 -
 -	mReturnButton = findChild<LLButton>("return_characters");
 -	llassert(mReturnButton != NULL)
 -	mReturnButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onReturnCharactersClicked, this));
 -
 -	mDeleteButton = findChild<LLButton>("delete_characters");
 -	llassert(mDeleteButton != NULL)
 -	mDeleteButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onDeleteCharactersClicked, this));
 -
 -	mTeleportButton = findChild<LLButton>("teleport_to_character");
 -	llassert(mTeleportButton != NULL)
 -	mTeleportButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onTeleportCharacterToMeClicked, this));
 -
 -	return LLFloater::postBuild();
 -}
 -
 -void LLFloaterPathfindingCharacters::onOpen(const LLSD& pKey)
 -{
 -	LLFloater::onOpen(pKey);
 -
 -	requestGetCharacters();
 -	selectNoneCharacters();
 -	mCharactersScrollList->setCommitOnSelectionChange(true);
 -
 -	if (!mSelectionUpdateSlot.connected())
 -	{
 -		mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterPathfindingCharacters::updateControls, this));
 -	}
 -
 -	if (!mRegionBoundarySlot.connected())
 -	{
 -		mRegionBoundarySlot = LLEnvManagerNew::instance().setRegionChangeCallback(boost::bind(&LLFloaterPathfindingCharacters::onRegionBoundaryCross, this));
 -	}
 -}
 -
 -void LLFloaterPathfindingCharacters::onClose(bool pAppQuitting)
 -{
 -	if (mRegionBoundarySlot.connected())
 -	{
 -		mRegionBoundarySlot.disconnect();
 -	}
 -
 -	if (mSelectionUpdateSlot.connected())
 -	{
 -		mSelectionUpdateSlot.disconnect();
 -	}
 -
 -	mCharactersScrollList->setCommitOnSelectionChange(false);
 -	selectNoneCharacters();
 -	if (mCharacterSelection.notNull())
 -	{
 -		mCharacterSelection.clear();
 -	}
 -
 -	LLFloater::onClose(pAppQuitting);
 -}
 -
 -void LLFloaterPathfindingCharacters::draw()
 -{
 -	if (mShowBeaconCheckBox->get())
 -	{
 -		std::vector<LLScrollListItem*> selectedItems = mCharactersScrollList->getAllSelected();
 -		if (!selectedItems.empty())
 -		{
 -			int numSelectedItems = selectedItems.size();
 -
 -			std::vector<LLViewerObject *> viewerObjects;
 -			viewerObjects.reserve(numSelectedItems);
 -
 -			for (std::vector<LLScrollListItem*>::const_iterator selectedItemIter = selectedItems.begin();
 -				selectedItemIter != selectedItems.end(); ++selectedItemIter)
 -			{
 -				const LLScrollListItem *selectedItem = *selectedItemIter;
 -
 -				const std::string &objectName = selectedItem->getColumn(0)->getValue().asString();
 -
 -				LLViewerObject *viewerObject = gObjectList.findObject(selectedItem->getUUID());
 -				if (viewerObject != NULL)
 -				{
 -					gObjectList.addDebugBeacon(viewerObject->getPositionAgent(), objectName, LLColor4(0.f, 0.f, 1.f, 0.8f), LLColor4(1.f, 1.f, 1.f, 1.f), 6);
 -				}
 -			}
 -		}
 -	}
 -
 -	LLFloater::draw();
 -}
 -
 -void LLFloaterPathfindingCharacters::openCharactersViewer()
 -{
 -	LLFloaterReg::toggleInstanceOrBringToFront("pathfinding_characters");
 -}
 -
 -LLFloaterPathfindingCharacters::LLFloaterPathfindingCharacters(const LLSD& pSeed)
 -	: LLFloater(pSeed),
 -	mCharactersScrollList(NULL),
 -	mCharactersStatus(NULL),
 -	mRefreshListButton(NULL),
 -	mSelectAllButton(NULL),
 -	mSelectNoneButton(NULL),
 -	mShowBeaconCheckBox(NULL),
 -	mTakeButton(NULL),
 -	mTakeCopyButton(NULL),
 -	mReturnButton(NULL),
 -	mDeleteButton(NULL),
 -	mTeleportButton(NULL),
 -	mMessagingState(kMessagingUnknown),
 -	mMessagingRequestId(0U),
 -	mCharacterListPtr(),
 -	mCharacterSelection(),
 -	mSelectionUpdateSlot()
 -{
 -}
 -
 -LLFloaterPathfindingCharacters::~LLFloaterPathfindingCharacters()
 -{
 -}
 -
 -LLFloaterPathfindingCharacters::EMessagingState LLFloaterPathfindingCharacters::getMessagingState() const
 -{
 -	return mMessagingState;
 -}
 -
 -void LLFloaterPathfindingCharacters::setMessagingState(EMessagingState pMessagingState)
 -{
 -	mMessagingState = pMessagingState;
 -	updateControls();
 -}
 -
 -void LLFloaterPathfindingCharacters::requestGetCharacters()
 -{
 -	switch (LLPathfindingManager::getInstance()->requestGetCharacters(++mMessagingRequestId, boost::bind(&LLFloaterPathfindingCharacters::handleNewCharacters, this, _1, _2, _3)))
 -	{
 -	case LLPathfindingManager::kRequestStarted :
 -		setMessagingState(kMessagingGetRequestSent);
 -		break;
 -	case LLPathfindingManager::kRequestCompleted :
 -		clearCharacters();
 -		setMessagingState(kMessagingComplete);
 -		break;
 -	case LLPathfindingManager::kRequestNotEnabled :
 -		clearCharacters();
 -		setMessagingState(kMessagingNotEnabled);
 -		break;
 -	case LLPathfindingManager::kRequestError :
 -		setMessagingState(kMessagingGetError);
 -		break;
 -	default :
 -		setMessagingState(kMessagingGetError);
 -		llassert(0);
 -		break;
 -	}
 -}
 -
 -void LLFloaterPathfindingCharacters::handleNewCharacters(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pCharacterRequestStatus, LLPathfindingCharacterListPtr pCharacterListPtr)
 -{
 -	llassert(pRequestId <= mMessagingRequestId);
 -	if (pRequestId == mMessagingRequestId)
 -	{
 -		mCharacterListPtr = pCharacterListPtr;
 -		updateScrollList();
 -
 -		switch (pCharacterRequestStatus)
 -		{
 -		case LLPathfindingManager::kRequestCompleted :
 -			setMessagingState(kMessagingComplete);
 -			break;
 -		case LLPathfindingManager::kRequestError :
 -			setMessagingState(kMessagingGetError);
 -			break;
 -		default :
 -			setMessagingState(kMessagingGetError);
 -			llassert(0);
 -			break;
 -		}
 -	}
 -}
 -
 -void LLFloaterPathfindingCharacters::onCharactersSelectionChange()
 -{
 -	mCharacterSelection.clear();
 -	LLSelectMgr::getInstance()->deselectAll();
 -
 -	std::vector<LLScrollListItem*> selectedItems = mCharactersScrollList->getAllSelected();
 -	if (!selectedItems.empty())
 -	{
 -		int numSelectedItems = selectedItems.size();
 -
 -		std::vector<LLViewerObject *> viewerObjects;
 -		viewerObjects.reserve(numSelectedItems);
 -
 -		for (std::vector<LLScrollListItem*>::const_iterator selectedItemIter = selectedItems.begin();
 -			selectedItemIter != selectedItems.end(); ++selectedItemIter)
 -		{
 -			const LLScrollListItem *selectedItem = *selectedItemIter;
 -
 -			LLViewerObject *viewerObject = gObjectList.findObject(selectedItem->getUUID());
 -			if (viewerObject != NULL)
 -			{
 -				viewerObjects.push_back(viewerObject);
 -			}
 -		}
 -
 -		if (!viewerObjects.empty())
 -		{
 -			mCharacterSelection = LLSelectMgr::getInstance()->selectObjectAndFamily(viewerObjects);
 -		}
 -	}
 -
 -	updateControls();
 -}
 -
 -void LLFloaterPathfindingCharacters::onRefreshCharactersClicked()
 -{
 -	requestGetCharacters();
 -}
 -
 -void LLFloaterPathfindingCharacters::onSelectAllCharactersClicked()
 -{
 -	selectAllCharacters();
 -}
 -
 -void LLFloaterPathfindingCharacters::onSelectNoneCharactersClicked()
 -{
 -	selectNoneCharacters();
 -}
 -
 -void LLFloaterPathfindingCharacters::onTakeCharactersClicked()
 -{
 -	handle_take();
 -}
 -
 -void LLFloaterPathfindingCharacters::onTakeCopyCharactersClicked()
 -{
 -	handle_take_copy();
 -}
 -
 -void LLFloaterPathfindingCharacters::onReturnCharactersClicked()
 -{
 -	handle_object_return();
 -}
 -
 -void LLFloaterPathfindingCharacters::onDeleteCharactersClicked()
 -{
 -	handle_object_delete();
 -}
 -
 -void LLFloaterPathfindingCharacters::onTeleportCharacterToMeClicked()
 -{
 -	std::vector<LLScrollListItem*> selectedItems = mCharactersScrollList->getAllSelected();
 -	llassert(selectedItems.size() == 1);
 -	if (selectedItems.size() == 1)
 -	{
 -		std::vector<LLScrollListItem*>::const_reference selectedItemRef = selectedItems.front();
 -		const LLScrollListItem *selectedItem = selectedItemRef;
 -		LLPathfindingCharacterList::const_iterator characterIter = mCharacterListPtr->find(selectedItem->getUUID().asString());
 -		const LLPathfindingCharacterPtr &characterPtr = characterIter->second;
 -		const LLVector3 &characterLocation = characterPtr->getLocation();
 -
 -		LLViewerRegion* region = gAgent.getRegion();
 -		if (region != NULL)
 -		{
 -			gAgent.teleportRequest(region->getHandle(), characterLocation, true);
 -		}
 -	}
 -}
 -
 -void LLFloaterPathfindingCharacters::onRegionBoundaryCross()
 -{
 -	requestGetCharacters();
 -}
 -
 -void LLFloaterPathfindingCharacters::selectAllCharacters()
 -{
 -	mCharactersScrollList->selectAll();
 -}
 -
 -void LLFloaterPathfindingCharacters::selectNoneCharacters()
 -{
 -	mCharactersScrollList->deselectAllItems();
 -}
 -
 -void LLFloaterPathfindingCharacters::clearCharacters()
 -{
 -	if (mCharacterListPtr != NULL)
 -	{
 -		mCharacterListPtr->clear();
 -	}
 -	updateScrollList();
 -}
 -
 -void LLFloaterPathfindingCharacters::updateControls()
 -{
 -	updateStatusMessage();
 -	updateEnableStateOnListActions();
 -	updateEnableStateOnEditFields();
 -}
 -
 -void LLFloaterPathfindingCharacters::updateScrollList()
 -{
 -	std::vector<LLScrollListItem*> selectedItems = mCharactersScrollList->getAllSelected();
 -	int numSelectedItems = selectedItems.size();
 -	uuid_vec_t selectedUUIDs;
 -	if (numSelectedItems > 0)
 -	{
 -		selectedUUIDs.reserve(selectedItems.size());
 -		for (std::vector<LLScrollListItem*>::const_iterator itemIter = selectedItems.begin();
 -			itemIter != selectedItems.end(); ++itemIter)
 -		{
 -			const LLScrollListItem *listItem = *itemIter;
 -			selectedUUIDs.push_back(listItem->getUUID());
 -		}
 -	}
 -
 -	S32 origScrollPosition = mCharactersScrollList->getScrollPos();
 -	mCharactersScrollList->deleteAllItems();
 -
 -	if (mCharacterListPtr != NULL)
 -	{
 -		for (LLPathfindingCharacterList::const_iterator characterIter = mCharacterListPtr->begin();
 -			characterIter != mCharacterListPtr->end(); ++characterIter)
 -		{
 -			const LLPathfindingCharacterPtr& character(characterIter->second);
 -			LLSD element = buildCharacterScrollListElement(character);
 -			mCharactersScrollList->addElement(element);
 -		}
 -	}
 -
 -	mCharactersScrollList->selectMultiple(selectedUUIDs);
 -	mCharactersScrollList->setScrollPos(origScrollPosition);
 -	updateControls();
 -}
 -
 -LLSD LLFloaterPathfindingCharacters::buildCharacterScrollListElement(const LLPathfindingCharacterPtr pCharacterPtr) const
 -{
 -	LLSD columns;
 -
 -	columns[0]["column"] = "name";
 -	columns[0]["value"] = pCharacterPtr->getName();
 -	columns[0]["font"] = "SANSSERIF";
 -
 -	columns[1]["column"] = "description";
 -	columns[1]["value"] = pCharacterPtr->getDescription();
 -	columns[1]["font"] = "SANSSERIF";
 -
 -	columns[2]["column"] = "owner";
 -	columns[2]["value"] = pCharacterPtr->getOwnerName();
 -	columns[2]["font"] = "SANSSERIF";
 -
 -	S32 cpuTime = llround(pCharacterPtr->getCPUTime());
 -	std::string cpuTimeString = llformat("%d", cpuTime);
 -	LLStringUtil::format_map_t string_args;
 -	string_args["[CPU_TIME]"] = cpuTimeString;
 -
 -	columns[3]["column"] = "cpu_time";
 -	columns[3]["value"] = getString("character_cpu_time", string_args);
 -	columns[3]["font"] = "SANSSERIF";
 -
 -	columns[4]["column"] = "altitude";
 -	columns[4]["value"] = llformat("%1.0f m", pCharacterPtr->getLocation()[2]);
 -	columns[4]["font"] = "SANSSERIF";
 -
 -	LLSD element;
 -	element["id"] = pCharacterPtr->getUUID().asString();
 -	element["column"] = columns;
 -
 -	return element;
 -}
 -
 -void LLFloaterPathfindingCharacters::updateStatusMessage()
 -{
 -	static const LLColor4 errorColor = LLUIColorTable::instance().getColor("PathfindingErrorColor");
 -	static const LLColor4 warningColor = LLUIColorTable::instance().getColor("PathfindingWarningColor");
 -
 -	std::string statusText("");
 -	LLStyle::Params styleParams;
 -
 -	switch (getMessagingState())
 -	{
 -	case kMessagingUnknown:
 -		statusText = getString("characters_messaging_initial");
 -		styleParams.color = errorColor;
 -		break;
 -	case kMessagingGetRequestSent :
 -		statusText = getString("characters_messaging_get_inprogress");
 -		styleParams.color = warningColor;
 -		break;
 -	case kMessagingGetError :
 -		statusText = getString("characters_messaging_get_error");
 -		styleParams.color = errorColor;
 -		break;
 -	case kMessagingComplete :
 -		if (mCharactersScrollList->isEmpty())
 -		{
 -			statusText = getString("characters_messaging_complete_none_found");
 -		}
 -		else
 -		{
 -			S32 numItems = mCharactersScrollList->getItemCount();
 -			S32 numSelectedItems = mCharactersScrollList->getNumSelected();
 -
 -			LLLocale locale(LLStringUtil::getLocale());
 -			std::string numItemsString;
 -			LLResMgr::getInstance()->getIntegerString(numItemsString, numItems);
 -
 -			std::string numSelectedItemsString;
 -			LLResMgr::getInstance()->getIntegerString(numSelectedItemsString, numSelectedItems);
 -
 -			LLStringUtil::format_map_t string_args;
 -			string_args["[NUM_SELECTED]"] = numSelectedItemsString;
 -			string_args["[NUM_TOTAL]"] = numItemsString;
 -			statusText = getString("characters_messaging_complete_available", string_args);
 -		}
 -		break;
 -	case kMessagingNotEnabled:
 -		statusText = getString("characters_messaging_not_enabled");
 -		styleParams.color = errorColor;
 -		break;
 -	default:
 -		statusText = getString("characters_messaging_initial");
 -		styleParams.color = errorColor;
 -		llassert(0);
 -		break;
 -	}
 -
 -	mCharactersStatus->setText((LLStringExplicit)statusText, styleParams);
 -}
 -
 -void LLFloaterPathfindingCharacters::updateEnableStateOnListActions()
 -{
 -	switch (getMessagingState())
 -	{
 -	case kMessagingUnknown:
 -	case kMessagingGetRequestSent :
 -		mRefreshListButton->setEnabled(FALSE);
 -		mSelectAllButton->setEnabled(FALSE);
 -		mSelectNoneButton->setEnabled(FALSE);
 -		break;
 -	case kMessagingGetError :
 -	case kMessagingNotEnabled :
 -		mRefreshListButton->setEnabled(TRUE);
 -		mSelectAllButton->setEnabled(FALSE);
 -		mSelectNoneButton->setEnabled(FALSE);
 -		break;
 -	case kMessagingComplete :
 -		{
 -			int numItems = mCharactersScrollList->getItemCount();
 -			int numSelectedItems = mCharactersScrollList->getNumSelected();
 -			mRefreshListButton->setEnabled(TRUE);
 -			mSelectAllButton->setEnabled(numSelectedItems < numItems);
 -			mSelectNoneButton->setEnabled(numSelectedItems > 0);
 -		}
 -		break;
 -	default:
 -		llassert(0);
 -		break;
 -	}
 -}
 -
 -void LLFloaterPathfindingCharacters::updateEnableStateOnEditFields()
 -{
 -	int numSelectedItems = mCharactersScrollList->getNumSelected();
 -	bool isEditEnabled = (numSelectedItems > 0);
 -
 -	mShowBeaconCheckBox->setEnabled(isEditEnabled);
 -	mTakeButton->setEnabled(isEditEnabled && visible_take_object());
 -	mTakeCopyButton->setEnabled(isEditEnabled && enable_object_take_copy());
 -	mReturnButton->setEnabled(isEditEnabled && enable_object_return());
 -	mDeleteButton->setEnabled(isEditEnabled && enable_object_delete());
 -	mTeleportButton->setEnabled(numSelectedItems == 1);
 -}
 +/**  + * @file llfloaterpathfindingcharacters.cpp + * @author William Todd Stinson + * @brief "Pathfinding characters" floater, allowing for identification of pathfinding characters and their cpu usage. + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llfloater.h" +#include "llfloaterpathfindingcharacters.h" +#include "llpathfindingcharacterlist.h" +#include "llsd.h" +#include "llagent.h" +#include "llhandle.h" +#include "llfloaterreg.h" +#include "lltextbase.h" +#include "llscrolllistitem.h" +#include "llscrolllistctrl.h" +#include "llcheckboxctrl.h" +#include "llradiogroup.h" +#include "llbutton.h" +#include "llresmgr.h" +#include "llviewerregion.h" +#include "llhttpclient.h" +#include "lluuid.h" +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "llviewermenu.h" +#include "llselectmgr.h" +#include "llenvmanager.h" + +//--------------------------------------------------------------------------- +// LLFloaterPathfindingCharacters +//--------------------------------------------------------------------------- + +BOOL LLFloaterPathfindingCharacters::postBuild() +{ +	mCharactersScrollList = findChild<LLScrollListCtrl>("pathfinding_characters"); +	llassert(mCharactersScrollList != NULL); +	mCharactersScrollList->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onCharactersSelectionChange, this)); +	mCharactersScrollList->sortByColumnIndex(0, true); + +	mCharactersStatus = findChild<LLTextBase>("characters_status"); +	llassert(mCharactersStatus != NULL); + +	mRefreshListButton = findChild<LLButton>("refresh_characters_list"); +	llassert(mRefreshListButton != NULL); +	mRefreshListButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onRefreshCharactersClicked, this)); + +	mSelectAllButton = findChild<LLButton>("select_all_characters"); +	llassert(mSelectAllButton != NULL); +	mSelectAllButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onSelectAllCharactersClicked, this)); + +	mSelectNoneButton = findChild<LLButton>("select_none_characters"); +	llassert(mSelectNoneButton != NULL); +	mSelectNoneButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onSelectNoneCharactersClicked, this)); + +	mShowBeaconCheckBox = findChild<LLCheckBoxCtrl>("show_beacon"); +	llassert(mShowBeaconCheckBox != NULL); + +	mTakeButton = findChild<LLButton>("take_characters"); +	llassert(mTakeButton != NULL) +	mTakeButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onTakeCharactersClicked, this)); + +	mTakeCopyButton = findChild<LLButton>("take_copy_characters"); +	llassert(mTakeCopyButton != NULL) +	mTakeCopyButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onTakeCopyCharactersClicked, this)); + +	mReturnButton = findChild<LLButton>("return_characters"); +	llassert(mReturnButton != NULL) +	mReturnButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onReturnCharactersClicked, this)); + +	mDeleteButton = findChild<LLButton>("delete_characters"); +	llassert(mDeleteButton != NULL) +	mDeleteButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onDeleteCharactersClicked, this)); + +	mTeleportButton = findChild<LLButton>("teleport_to_character"); +	llassert(mTeleportButton != NULL) +	mTeleportButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onTeleportCharacterToMeClicked, this)); + +	return LLFloater::postBuild(); +} + +void LLFloaterPathfindingCharacters::onOpen(const LLSD& pKey) +{ +	LLFloater::onOpen(pKey); + +	requestGetCharacters(); +	selectNoneCharacters(); +	mCharactersScrollList->setCommitOnSelectionChange(true); + +	if (!mSelectionUpdateSlot.connected()) +	{ +		mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterPathfindingCharacters::updateControls, this)); +	} + +	if (!mRegionBoundarySlot.connected()) +	{ +		mRegionBoundarySlot = LLEnvManagerNew::instance().setRegionChangeCallback(boost::bind(&LLFloaterPathfindingCharacters::onRegionBoundaryCross, this)); +	} +} + +void LLFloaterPathfindingCharacters::onClose(bool pAppQuitting) +{ +	if (mRegionBoundarySlot.connected()) +	{ +		mRegionBoundarySlot.disconnect(); +	} + +	if (mSelectionUpdateSlot.connected()) +	{ +		mSelectionUpdateSlot.disconnect(); +	} + +	mCharactersScrollList->setCommitOnSelectionChange(false); +	selectNoneCharacters(); +	if (mCharacterSelection.notNull()) +	{ +		mCharacterSelection.clear(); +	} + +	LLFloater::onClose(pAppQuitting); +} + +void LLFloaterPathfindingCharacters::draw() +{ +	if (mShowBeaconCheckBox->get()) +	{ +		std::vector<LLScrollListItem*> selectedItems = mCharactersScrollList->getAllSelected(); +		if (!selectedItems.empty()) +		{ +			int numSelectedItems = selectedItems.size(); + +			std::vector<LLViewerObject *> viewerObjects; +			viewerObjects.reserve(numSelectedItems); + +			for (std::vector<LLScrollListItem*>::const_iterator selectedItemIter = selectedItems.begin(); +				selectedItemIter != selectedItems.end(); ++selectedItemIter) +			{ +				const LLScrollListItem *selectedItem = *selectedItemIter; + +				const std::string &objectName = selectedItem->getColumn(0)->getValue().asString(); + +				LLViewerObject *viewerObject = gObjectList.findObject(selectedItem->getUUID()); +				if (viewerObject != NULL) +				{ +					gObjectList.addDebugBeacon(viewerObject->getPositionAgent(), objectName, LLColor4(0.f, 0.f, 1.f, 0.8f), LLColor4(1.f, 1.f, 1.f, 1.f), 6); +				} +			} +		} +	} + +	LLFloater::draw(); +} + +void LLFloaterPathfindingCharacters::openCharactersViewer() +{ +	LLFloaterReg::toggleInstanceOrBringToFront("pathfinding_characters"); +} + +LLFloaterPathfindingCharacters::LLFloaterPathfindingCharacters(const LLSD& pSeed) +	: LLFloater(pSeed), +	mCharactersScrollList(NULL), +	mCharactersStatus(NULL), +	mRefreshListButton(NULL), +	mSelectAllButton(NULL), +	mSelectNoneButton(NULL), +	mShowBeaconCheckBox(NULL), +	mTakeButton(NULL), +	mTakeCopyButton(NULL), +	mReturnButton(NULL), +	mDeleteButton(NULL), +	mTeleportButton(NULL), +	mMessagingState(kMessagingUnknown), +	mMessagingRequestId(0U), +	mCharacterListPtr(), +	mCharacterSelection(), +	mSelectionUpdateSlot() +{ +} + +LLFloaterPathfindingCharacters::~LLFloaterPathfindingCharacters() +{ +} + +LLFloaterPathfindingCharacters::EMessagingState LLFloaterPathfindingCharacters::getMessagingState() const +{ +	return mMessagingState; +} + +void LLFloaterPathfindingCharacters::setMessagingState(EMessagingState pMessagingState) +{ +	mMessagingState = pMessagingState; +	updateControls(); +} + +void LLFloaterPathfindingCharacters::requestGetCharacters() +{ +	switch (LLPathfindingManager::getInstance()->requestGetCharacters(++mMessagingRequestId, boost::bind(&LLFloaterPathfindingCharacters::handleNewCharacters, this, _1, _2, _3))) +	{ +	case LLPathfindingManager::kRequestStarted : +		setMessagingState(kMessagingGetRequestSent); +		break; +	case LLPathfindingManager::kRequestCompleted : +		clearCharacters(); +		setMessagingState(kMessagingComplete); +		break; +	case LLPathfindingManager::kRequestNotEnabled : +		clearCharacters(); +		setMessagingState(kMessagingNotEnabled); +		break; +	case LLPathfindingManager::kRequestError : +		setMessagingState(kMessagingGetError); +		break; +	default : +		setMessagingState(kMessagingGetError); +		llassert(0); +		break; +	} +} + +void LLFloaterPathfindingCharacters::handleNewCharacters(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pCharacterRequestStatus, LLPathfindingCharacterListPtr pCharacterListPtr) +{ +	llassert(pRequestId <= mMessagingRequestId); +	if (pRequestId == mMessagingRequestId) +	{ +		mCharacterListPtr = pCharacterListPtr; +		updateScrollList(); + +		switch (pCharacterRequestStatus) +		{ +		case LLPathfindingManager::kRequestCompleted : +			setMessagingState(kMessagingComplete); +			break; +		case LLPathfindingManager::kRequestError : +			setMessagingState(kMessagingGetError); +			break; +		default : +			setMessagingState(kMessagingGetError); +			llassert(0); +			break; +		} +	} +} + +void LLFloaterPathfindingCharacters::onCharactersSelectionChange() +{ +	mCharacterSelection.clear(); +	LLSelectMgr::getInstance()->deselectAll(); + +	std::vector<LLScrollListItem*> selectedItems = mCharactersScrollList->getAllSelected(); +	if (!selectedItems.empty()) +	{ +		int numSelectedItems = selectedItems.size(); + +		std::vector<LLViewerObject *> viewerObjects; +		viewerObjects.reserve(numSelectedItems); + +		for (std::vector<LLScrollListItem*>::const_iterator selectedItemIter = selectedItems.begin(); +			selectedItemIter != selectedItems.end(); ++selectedItemIter) +		{ +			const LLScrollListItem *selectedItem = *selectedItemIter; + +			LLViewerObject *viewerObject = gObjectList.findObject(selectedItem->getUUID()); +			if (viewerObject != NULL) +			{ +				viewerObjects.push_back(viewerObject); +			} +		} + +		if (!viewerObjects.empty()) +		{ +			mCharacterSelection = LLSelectMgr::getInstance()->selectObjectAndFamily(viewerObjects); +		} +	} + +	updateControls(); +} + +void LLFloaterPathfindingCharacters::onRefreshCharactersClicked() +{ +	requestGetCharacters(); +} + +void LLFloaterPathfindingCharacters::onSelectAllCharactersClicked() +{ +	selectAllCharacters(); +} + +void LLFloaterPathfindingCharacters::onSelectNoneCharactersClicked() +{ +	selectNoneCharacters(); +} + +void LLFloaterPathfindingCharacters::onTakeCharactersClicked() +{ +	handle_take(); +} + +void LLFloaterPathfindingCharacters::onTakeCopyCharactersClicked() +{ +	handle_take_copy(); +} + +void LLFloaterPathfindingCharacters::onReturnCharactersClicked() +{ +	handle_object_return(); +} + +void LLFloaterPathfindingCharacters::onDeleteCharactersClicked() +{ +	handle_object_delete(); +} + +void LLFloaterPathfindingCharacters::onTeleportCharacterToMeClicked() +{ +	std::vector<LLScrollListItem*> selectedItems = mCharactersScrollList->getAllSelected(); +	llassert(selectedItems.size() == 1); +	if (selectedItems.size() == 1) +	{ +		std::vector<LLScrollListItem*>::const_reference selectedItemRef = selectedItems.front(); +		const LLScrollListItem *selectedItem = selectedItemRef; +		LLPathfindingCharacterList::const_iterator characterIter = mCharacterListPtr->find(selectedItem->getUUID().asString()); +		const LLPathfindingCharacterPtr &characterPtr = characterIter->second; +		const LLVector3 &characterLocation = characterPtr->getLocation(); + +		LLViewerRegion* region = gAgent.getRegion(); +		if (region != NULL) +		{ +			gAgent.teleportRequest(region->getHandle(), characterLocation, true); +		} +	} +} + +void LLFloaterPathfindingCharacters::onRegionBoundaryCross() +{ +	requestGetCharacters(); +} + +void LLFloaterPathfindingCharacters::selectAllCharacters() +{ +	mCharactersScrollList->selectAll(); +} + +void LLFloaterPathfindingCharacters::selectNoneCharacters() +{ +	mCharactersScrollList->deselectAllItems(); +} + +void LLFloaterPathfindingCharacters::clearCharacters() +{ +	if (mCharacterListPtr != NULL) +	{ +		mCharacterListPtr->clear(); +	} +	updateScrollList(); +} + +void LLFloaterPathfindingCharacters::updateControls() +{ +	updateStatusMessage(); +	updateEnableStateOnListActions(); +	updateEnableStateOnEditFields(); +} + +void LLFloaterPathfindingCharacters::updateScrollList() +{ +	std::vector<LLScrollListItem*> selectedItems = mCharactersScrollList->getAllSelected(); +	int numSelectedItems = selectedItems.size(); +	uuid_vec_t selectedUUIDs; +	if (numSelectedItems > 0) +	{ +		selectedUUIDs.reserve(selectedItems.size()); +		for (std::vector<LLScrollListItem*>::const_iterator itemIter = selectedItems.begin(); +			itemIter != selectedItems.end(); ++itemIter) +		{ +			const LLScrollListItem *listItem = *itemIter; +			selectedUUIDs.push_back(listItem->getUUID()); +		} +	} + +	S32 origScrollPosition = mCharactersScrollList->getScrollPos(); +	mCharactersScrollList->deleteAllItems(); + +	if (mCharacterListPtr != NULL) +	{ +		for (LLPathfindingCharacterList::const_iterator characterIter = mCharacterListPtr->begin(); +			characterIter != mCharacterListPtr->end(); ++characterIter) +		{ +			const LLPathfindingCharacterPtr& character(characterIter->second); +			LLSD element = buildCharacterScrollListElement(character); +			mCharactersScrollList->addElement(element); +		} +	} + +	mCharactersScrollList->selectMultiple(selectedUUIDs); +	mCharactersScrollList->setScrollPos(origScrollPosition); +	updateControls(); +} + +LLSD LLFloaterPathfindingCharacters::buildCharacterScrollListElement(const LLPathfindingCharacterPtr pCharacterPtr) const +{ +	LLSD columns; + +	columns[0]["column"] = "name"; +	columns[0]["value"] = pCharacterPtr->getName(); +	columns[0]["font"] = "SANSSERIF"; + +	columns[1]["column"] = "description"; +	columns[1]["value"] = pCharacterPtr->getDescription(); +	columns[1]["font"] = "SANSSERIF"; + +	columns[2]["column"] = "owner"; +	columns[2]["value"] = pCharacterPtr->getOwnerName(); +	columns[2]["font"] = "SANSSERIF"; + +	S32 cpuTime = llround(pCharacterPtr->getCPUTime()); +	std::string cpuTimeString = llformat("%d", cpuTime); +	LLStringUtil::format_map_t string_args; +	string_args["[CPU_TIME]"] = cpuTimeString; + +	columns[3]["column"] = "cpu_time"; +	columns[3]["value"] = getString("character_cpu_time", string_args); +	columns[3]["font"] = "SANSSERIF"; + +	columns[4]["column"] = "altitude"; +	columns[4]["value"] = llformat("%1.0f m", pCharacterPtr->getLocation()[2]); +	columns[4]["font"] = "SANSSERIF"; + +	LLSD element; +	element["id"] = pCharacterPtr->getUUID().asString(); +	element["column"] = columns; + +	return element; +} + +void LLFloaterPathfindingCharacters::updateStatusMessage() +{ +	static const LLColor4 errorColor = LLUIColorTable::instance().getColor("PathfindingErrorColor"); +	static const LLColor4 warningColor = LLUIColorTable::instance().getColor("PathfindingWarningColor"); + +	std::string statusText(""); +	LLStyle::Params styleParams; + +	switch (getMessagingState()) +	{ +	case kMessagingUnknown: +		statusText = getString("characters_messaging_initial"); +		styleParams.color = errorColor; +		break; +	case kMessagingGetRequestSent : +		statusText = getString("characters_messaging_get_inprogress"); +		styleParams.color = warningColor; +		break; +	case kMessagingGetError : +		statusText = getString("characters_messaging_get_error"); +		styleParams.color = errorColor; +		break; +	case kMessagingComplete : +		if (mCharactersScrollList->isEmpty()) +		{ +			statusText = getString("characters_messaging_complete_none_found"); +		} +		else +		{ +			S32 numItems = mCharactersScrollList->getItemCount(); +			S32 numSelectedItems = mCharactersScrollList->getNumSelected(); + +			LLLocale locale(LLStringUtil::getLocale()); +			std::string numItemsString; +			LLResMgr::getInstance()->getIntegerString(numItemsString, numItems); + +			std::string numSelectedItemsString; +			LLResMgr::getInstance()->getIntegerString(numSelectedItemsString, numSelectedItems); + +			LLStringUtil::format_map_t string_args; +			string_args["[NUM_SELECTED]"] = numSelectedItemsString; +			string_args["[NUM_TOTAL]"] = numItemsString; +			statusText = getString("characters_messaging_complete_available", string_args); +		} +		break; +	case kMessagingNotEnabled: +		statusText = getString("characters_messaging_not_enabled"); +		styleParams.color = errorColor; +		break; +	default: +		statusText = getString("characters_messaging_initial"); +		styleParams.color = errorColor; +		llassert(0); +		break; +	} + +	mCharactersStatus->setText((LLStringExplicit)statusText, styleParams); +} + +void LLFloaterPathfindingCharacters::updateEnableStateOnListActions() +{ +	switch (getMessagingState()) +	{ +	case kMessagingUnknown: +	case kMessagingGetRequestSent : +		mRefreshListButton->setEnabled(FALSE); +		mSelectAllButton->setEnabled(FALSE); +		mSelectNoneButton->setEnabled(FALSE); +		break; +	case kMessagingGetError : +	case kMessagingNotEnabled : +		mRefreshListButton->setEnabled(TRUE); +		mSelectAllButton->setEnabled(FALSE); +		mSelectNoneButton->setEnabled(FALSE); +		break; +	case kMessagingComplete : +		{ +			int numItems = mCharactersScrollList->getItemCount(); +			int numSelectedItems = mCharactersScrollList->getNumSelected(); +			mRefreshListButton->setEnabled(TRUE); +			mSelectAllButton->setEnabled(numSelectedItems < numItems); +			mSelectNoneButton->setEnabled(numSelectedItems > 0); +		} +		break; +	default: +		llassert(0); +		break; +	} +} + +void LLFloaterPathfindingCharacters::updateEnableStateOnEditFields() +{ +	int numSelectedItems = mCharactersScrollList->getNumSelected(); +	bool isEditEnabled = (numSelectedItems > 0); + +	mShowBeaconCheckBox->setEnabled(isEditEnabled); +	mTakeButton->setEnabled(isEditEnabled && visible_take_object()); +	mTakeCopyButton->setEnabled(isEditEnabled && enable_object_take_copy()); +	mReturnButton->setEnabled(isEditEnabled && enable_object_return()); +	mDeleteButton->setEnabled(isEditEnabled && enable_object_delete()); +	mTeleportButton->setEnabled(numSelectedItems == 1); +} diff --git a/indra/newview/llfloaterpathfindingcharacters.h b/indra/newview/llfloaterpathfindingcharacters.h index e0f1c22eac..b7b326b885 100644 --- a/indra/newview/llfloaterpathfindingcharacters.h +++ b/indra/newview/llfloaterpathfindingcharacters.h @@ -1,128 +1,128 @@ -/** 
 -* @file llfloaterpathfindingcharacters.h
 -* @author William Todd Stinson
 -* @brief "Pathfinding characters" floater, allowing for identification of pathfinding characters and their cpu usage.
 -*
 -* $LicenseInfo:firstyear=2002&license=viewerlgpl$
 -* Second Life Viewer Source Code
 -* Copyright (C) 2010, Linden Research, Inc.
 -* 
 -* This library is free software; you can redistribute it and/or
 -* modify it under the terms of the GNU Lesser General Public
 -* License as published by the Free Software Foundation;
 -* version 2.1 of the License only.
 -* 
 -* This library is distributed in the hope that it will be useful,
 -* but WITHOUT ANY WARRANTY; without even the implied warranty of
 -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 -* Lesser General Public License for more details.
 -* 
 -* You should have received a copy of the GNU Lesser General Public
 -* License along with this library; if not, write to the Free Software
 -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 -* 
 -* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 -* $/LicenseInfo$
 -*/
 -
 -#ifndef LL_LLFLOATERPATHFINDINGCHARACTERS_H
 -#define LL_LLFLOATERPATHFINDINGCHARACTERS_H
 -
 -#include <string>
 -#include <map>
 -
 -#include "llfloater.h"
 -#include "llpathfindingcharacter.h"
 -#include "llpathfindingcharacterlist.h"
 -#include "llpathfindingmanager.h"
 -#include "llselectmgr.h"
 -
 -#include <boost/signals2.hpp>
 -
 -class LLSD;
 -class LLTextBase;
 -class LLScrollListCtrl;
 -class LLCheckBoxCtrl;
 -class LLRadioGroup;
 -class LLButton;
 -
 -class LLFloaterPathfindingCharacters
 -	:	public LLFloater
 -{
 -	friend class LLFloaterReg;
 -
 -public:
 -	typedef enum
 -	{
 -		kMessagingUnknown,
 -		kMessagingGetRequestSent,
 -		kMessagingGetError,
 -		kMessagingComplete,
 -		kMessagingNotEnabled
 -	} EMessagingState;
 -
 -	virtual BOOL postBuild();
 -	virtual void onOpen(const LLSD& pKey);
 -	virtual void onClose(bool pAppQuitting);
 -	virtual void draw();
 -
 -	static void openCharactersViewer();
 -
 -protected:
 -
 -private:
 -	LLScrollListCtrl *mCharactersScrollList;
 -	LLTextBase       *mCharactersStatus;
 -	LLButton         *mRefreshListButton;
 -	LLButton         *mSelectAllButton;
 -	LLButton         *mSelectNoneButton;
 -	LLCheckBoxCtrl   *mShowBeaconCheckBox;
 -	LLButton         *mTakeButton;
 -	LLButton         *mTakeCopyButton;
 -	LLButton         *mReturnButton;
 -	LLButton         *mDeleteButton;
 -	LLButton         *mTeleportButton;
 -
 -	EMessagingState                    mMessagingState;
 -	LLPathfindingManager::request_id_t mMessagingRequestId;
 -	LLPathfindingCharacterListPtr      mCharacterListPtr;
 -	LLObjectSelectionHandle            mCharacterSelection;
 -	boost::signals2::connection        mSelectionUpdateSlot;
 -	boost::signals2::connection        mRegionBoundarySlot;
 -
 -	// Does its own instance management, so clients not allowed
 -	// to allocate or destroy.
 -	LLFloaterPathfindingCharacters(const LLSD& pSeed);
 -	virtual ~LLFloaterPathfindingCharacters();
 -
 -	EMessagingState getMessagingState() const;
 -	void            setMessagingState(EMessagingState pMessagingState);
 -
 -	void requestGetCharacters();
 -	void handleNewCharacters(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pCharacterRequestStatus, LLPathfindingCharacterListPtr pCharacterListPtr);
 -
 -	void onCharactersSelectionChange();
 -	void onRefreshCharactersClicked();
 -	void onSelectAllCharactersClicked();
 -	void onSelectNoneCharactersClicked();
 -	void onTakeCharactersClicked();
 -	void onTakeCopyCharactersClicked();
 -	void onReturnCharactersClicked();
 -	void onDeleteCharactersClicked();
 -	void onTeleportCharacterToMeClicked();
 -	void onRegionBoundaryCross();
 -
 -	void selectAllCharacters();
 -	void selectNoneCharacters();
 -	void clearCharacters();
 -
 -	void updateControls();
 -	void updateScrollList();
 -	LLSD buildCharacterScrollListElement(const LLPathfindingCharacterPtr pCharacterPtr) const;
 -
 -	void updateStatusMessage();
 -	void updateEnableStateOnListActions();
 -	void updateEnableStateOnEditFields();
 -};
 -
 -#endif // LL_LLFLOATERPATHFINDINGCHARACTERS_H
 +/**  +* @file llfloaterpathfindingcharacters.h +* @author William Todd Stinson +* @brief "Pathfinding characters" floater, allowing for identification of pathfinding characters and their cpu usage. +* +* $LicenseInfo:firstyear=2002&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2010, Linden Research, Inc. +*  +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +*  +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +* Lesser General Public License for more details. +*  +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA +*  +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +* $/LicenseInfo$ +*/ + +#ifndef LL_LLFLOATERPATHFINDINGCHARACTERS_H +#define LL_LLFLOATERPATHFINDINGCHARACTERS_H + +#include <string> +#include <map> + +#include "llfloater.h" +#include "llpathfindingcharacter.h" +#include "llpathfindingcharacterlist.h" +#include "llpathfindingmanager.h" +#include "llselectmgr.h" + +#include <boost/signals2.hpp> + +class LLSD; +class LLTextBase; +class LLScrollListCtrl; +class LLCheckBoxCtrl; +class LLRadioGroup; +class LLButton; + +class LLFloaterPathfindingCharacters +	:	public LLFloater +{ +	friend class LLFloaterReg; + +public: +	typedef enum +	{ +		kMessagingUnknown, +		kMessagingGetRequestSent, +		kMessagingGetError, +		kMessagingComplete, +		kMessagingNotEnabled +	} EMessagingState; + +	virtual BOOL postBuild(); +	virtual void onOpen(const LLSD& pKey); +	virtual void onClose(bool pAppQuitting); +	virtual void draw(); + +	static void openCharactersViewer(); + +protected: + +private: +	LLScrollListCtrl *mCharactersScrollList; +	LLTextBase       *mCharactersStatus; +	LLButton         *mRefreshListButton; +	LLButton         *mSelectAllButton; +	LLButton         *mSelectNoneButton; +	LLCheckBoxCtrl   *mShowBeaconCheckBox; +	LLButton         *mTakeButton; +	LLButton         *mTakeCopyButton; +	LLButton         *mReturnButton; +	LLButton         *mDeleteButton; +	LLButton         *mTeleportButton; + +	EMessagingState                    mMessagingState; +	LLPathfindingManager::request_id_t mMessagingRequestId; +	LLPathfindingCharacterListPtr      mCharacterListPtr; +	LLObjectSelectionHandle            mCharacterSelection; +	boost::signals2::connection        mSelectionUpdateSlot; +	boost::signals2::connection        mRegionBoundarySlot; + +	// Does its own instance management, so clients not allowed +	// to allocate or destroy. +	LLFloaterPathfindingCharacters(const LLSD& pSeed); +	virtual ~LLFloaterPathfindingCharacters(); + +	EMessagingState getMessagingState() const; +	void            setMessagingState(EMessagingState pMessagingState); + +	void requestGetCharacters(); +	void handleNewCharacters(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pCharacterRequestStatus, LLPathfindingCharacterListPtr pCharacterListPtr); + +	void onCharactersSelectionChange(); +	void onRefreshCharactersClicked(); +	void onSelectAllCharactersClicked(); +	void onSelectNoneCharactersClicked(); +	void onTakeCharactersClicked(); +	void onTakeCopyCharactersClicked(); +	void onReturnCharactersClicked(); +	void onDeleteCharactersClicked(); +	void onTeleportCharacterToMeClicked(); +	void onRegionBoundaryCross(); + +	void selectAllCharacters(); +	void selectNoneCharacters(); +	void clearCharacters(); + +	void updateControls(); +	void updateScrollList(); +	LLSD buildCharacterScrollListElement(const LLPathfindingCharacterPtr pCharacterPtr) const; + +	void updateStatusMessage(); +	void updateEnableStateOnListActions(); +	void updateEnableStateOnEditFields(); +}; + +#endif // LL_LLFLOATERPATHFINDINGCHARACTERS_H diff --git a/indra/newview/llfloaterpathfindinglinksets.cpp b/indra/newview/llfloaterpathfindinglinksets.cpp index 9701002d7d..240b5bb741 100644 --- a/indra/newview/llfloaterpathfindinglinksets.cpp +++ b/indra/newview/llfloaterpathfindinglinksets.cpp @@ -1,1259 +1,1259 @@ -/** 
 -* @file llfloaterpathfindinglinksets.cpp
 -* @author William Todd Stinson
 -* @brief "Pathfinding linksets" floater, allowing manipulation of the Havok AI pathfinding settings.
 -*
 -* $LicenseInfo:firstyear=2002&license=viewerlgpl$
 -* Second Life Viewer Source Code
 -* Copyright (C) 2010, Linden Research, Inc.
 -* 
 -* This library is free software; you can redistribute it and/or
 -* modify it under the terms of the GNU Lesser General Public
 -* License as published by the Free Software Foundation;
 -* version 2.1 of the License only.
 -* 
 -* This library is distributed in the hope that it will be useful,
 -* but WITHOUT ANY WARRANTY; without even the implied warranty of
 -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 -* Lesser General Public License for more details.
 -* 
 -* You should have received a copy of the GNU Lesser General Public
 -* License along with this library; if not, write to the Free Software
 -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 -* 
 -* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 -* $/LicenseInfo$
 -*/
 -
 -#include "llviewerprecompiledheaders.h"
 -#include "llfloater.h"
 -#include "llfloaterreg.h"
 -#include "llfloaterpathfindinglinksets.h"
 -#include "llsd.h"
 -#include "lluuid.h"
 -#include "v3math.h"
 -#include "lltextvalidate.h"
 -#include "llagent.h"
 -#include "lltextbase.h"
 -#include "lllineeditor.h"
 -#include "llscrolllistitem.h"
 -#include "llscrolllistctrl.h"
 -#include "llcombobox.h"
 -#include "llcheckboxctrl.h"
 -#include "llbutton.h"
 -#include "llresmgr.h"
 -#include "llviewerregion.h"
 -#include "llselectmgr.h"
 -#include "llviewermenu.h"
 -#include "llviewerobject.h"
 -#include "llviewerobjectlist.h"
 -#include "llpathfindinglinkset.h"
 -#include "llpathfindinglinksetlist.h"
 -#include "llpathfindingmanager.h"
 -#include "llnotificationsutil.h"
 -#include "llenvmanager.h"
 -
 -#include <boost/bind.hpp>
 -#include <boost/signals2.hpp>
 -
 -#define XUI_LINKSET_USE_NONE             0
 -#define XUI_LINKSET_USE_WALKABLE         1
 -#define XUI_LINKSET_USE_STATIC_OBSTACLE  2
 -#define XUI_LINKSET_USE_DYNAMIC_OBSTACLE 3
 -#define XUI_LINKSET_USE_MATERIAL_VOLUME  4
 -#define XUI_LINKSET_USE_EXCLUSION_VOLUME 5
 -#define XUI_LINKSET_USE_DYNAMIC_PHANTOM  6
 -
 -//---------------------------------------------------------------------------
 -// LLFloaterPathfindingLinksets
 -//---------------------------------------------------------------------------
 -
 -BOOL LLFloaterPathfindingLinksets::postBuild()
 -{
 -	childSetAction("apply_filters", boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
 -	childSetAction("clear_filters", boost::bind(&LLFloaterPathfindingLinksets::onClearFiltersClicked, this));
 -
 -	mFilterByName = findChild<LLLineEditor>("filter_by_name");
 -	llassert(mFilterByName != NULL);
 -	mFilterByName->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
 -	mFilterByName->setSelectAllonFocusReceived(true);
 -	mFilterByName->setCommitOnFocusLost(true);
 -
 -	mFilterByDescription = findChild<LLLineEditor>("filter_by_description");
 -	llassert(mFilterByDescription != NULL);
 -	mFilterByDescription->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
 -	mFilterByDescription->setSelectAllonFocusReceived(true);
 -	mFilterByDescription->setCommitOnFocusLost(true);
 -
 -	mFilterByLinksetUse = findChild<LLComboBox>("filter_by_linkset_use");
 -	llassert(mFilterByLinksetUse != NULL);
 -	mFilterByLinksetUse->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
 -
 -	mLinksetsScrollList = findChild<LLScrollListCtrl>("pathfinding_linksets");
 -	llassert(mLinksetsScrollList != NULL);
 -	mLinksetsScrollList->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onLinksetsSelectionChange, this));
 -	mLinksetsScrollList->sortByColumnIndex(0, true);
 -
 -	mLinksetsStatus = findChild<LLTextBase>("linksets_status");
 -	llassert(mLinksetsStatus != NULL);
 -
 -	mRefreshListButton = findChild<LLButton>("refresh_linksets_list");
 -	llassert(mRefreshListButton != NULL);
 -	mRefreshListButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onRefreshLinksetsClicked, this));
 -
 -	mSelectAllButton = findChild<LLButton>("select_all_linksets");
 -	llassert(mSelectAllButton != NULL);
 -	mSelectAllButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onSelectAllLinksetsClicked, this));
 -
 -	mSelectNoneButton = findChild<LLButton>("select_none_linksets");
 -	llassert(mSelectNoneButton != NULL);
 -	mSelectNoneButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onSelectNoneLinksetsClicked, this));
 -
 -	mShowBeaconCheckBox = findChild<LLCheckBoxCtrl>("show_beacon");
 -	llassert(mShowBeaconCheckBox != NULL);
 -
 -	mTakeButton = findChild<LLButton>("take_linksets");
 -	llassert(mTakeButton != NULL);
 -	mTakeButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onTakeClicked, this));
 -
 -	mTakeCopyButton = findChild<LLButton>("take_copy_linksets");
 -	llassert(mTakeCopyButton != NULL);
 -	mTakeCopyButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onTakeCopyClicked, this));
 -
 -	mReturnButton = findChild<LLButton>("return_linksets");
 -	llassert(mReturnButton != NULL);
 -	mReturnButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onReturnClicked, this));
 -
 -	mDeleteButton = findChild<LLButton>("delete_linksets");
 -	llassert(mDeleteButton != NULL);
 -	mDeleteButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onDeleteClicked, this));
 -
 -	mTeleportButton = findChild<LLButton>("teleport_me_to_linkset");
 -	llassert(mTeleportButton != NULL);
 -	mTeleportButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onTeleportClicked, this));
 -
 -	mEditLinksetUse = findChild<LLComboBox>("edit_linkset_use");
 -	llassert(mEditLinksetUse != NULL);
 -
 -	mEditLinksetUse->clearRows();
 -
 -	mEditLinksetUseUnset = mEditLinksetUse->addElement(buildLinksetUseScrollListElement(getString("linkset_choose_use"), XUI_LINKSET_USE_NONE));
 -	llassert(mEditLinksetUseUnset != NULL);
 -
 -	mEditLinksetUseWalkable = mEditLinksetUse->addElement(buildLinksetUseScrollListElement(getLinksetUseString(LLPathfindingLinkset::kWalkable), XUI_LINKSET_USE_WALKABLE));
 -	llassert(mEditLinksetUseWalkable != NULL);
 -
 -	mEditLinksetUseStaticObstacle = mEditLinksetUse->addElement(buildLinksetUseScrollListElement(getLinksetUseString(LLPathfindingLinkset::kStaticObstacle), XUI_LINKSET_USE_STATIC_OBSTACLE));
 -	llassert(mEditLinksetUseStaticObstacle != NULL);
 -
 -	mEditLinksetUseDynamicObstacle = mEditLinksetUse->addElement(buildLinksetUseScrollListElement(getLinksetUseString(LLPathfindingLinkset::kDynamicObstacle), XUI_LINKSET_USE_DYNAMIC_OBSTACLE));
 -	llassert(mEditLinksetUseDynamicObstacle != NULL);
 -
 -	mEditLinksetUseMaterialVolume = mEditLinksetUse->addElement(buildLinksetUseScrollListElement(getLinksetUseString(LLPathfindingLinkset::kMaterialVolume), XUI_LINKSET_USE_MATERIAL_VOLUME));
 -	llassert(mEditLinksetUseMaterialVolume != NULL);
 -
 -	mEditLinksetUseExclusionVolume = mEditLinksetUse->addElement(buildLinksetUseScrollListElement(getLinksetUseString(LLPathfindingLinkset::kExclusionVolume), XUI_LINKSET_USE_EXCLUSION_VOLUME));
 -	llassert(mEditLinksetUseExclusionVolume != NULL);
 -
 -	mEditLinksetUseDynamicPhantom = mEditLinksetUse->addElement(buildLinksetUseScrollListElement(getLinksetUseString(LLPathfindingLinkset::kDynamicPhantom), XUI_LINKSET_USE_DYNAMIC_PHANTOM));
 -	llassert(mEditLinksetUseDynamicPhantom != NULL);
 -
 -	mEditLinksetUse->selectFirstItem();
 -
 -	mLabelWalkabilityCoefficients = findChild<LLTextBase>("walkability_coefficients_label");
 -	llassert(mLabelWalkabilityCoefficients != NULL);
 -
 -	mLabelEditA = findChild<LLTextBase>("edit_a_label");
 -	llassert(mLabelEditA != NULL);
 -
 -	mEditA = findChild<LLLineEditor>("edit_a_value");
 -	llassert(mEditA != NULL);
 -	mEditA->setPrevalidate(LLTextValidate::validateNonNegativeS32);
 -	mEditA->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1));
 -
 -	mLabelEditB = findChild<LLTextBase>("edit_b_label");
 -	llassert(mLabelEditB != NULL);
 -
 -	mEditB = findChild<LLLineEditor>("edit_b_value");
 -	llassert(mEditB != NULL);
 -	mEditB->setPrevalidate(LLTextValidate::validateNonNegativeS32);
 -	mEditB->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1));
 -
 -	mLabelEditC = findChild<LLTextBase>("edit_c_label");
 -	llassert(mLabelEditC != NULL);
 -
 -	mEditC = findChild<LLLineEditor>("edit_c_value");
 -	llassert(mEditC != NULL);
 -	mEditC->setPrevalidate(LLTextValidate::validateNonNegativeS32);
 -	mEditC->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1));
 -
 -	mLabelEditD = findChild<LLTextBase>("edit_d_label");
 -	llassert(mLabelEditD != NULL);
 -
 -	mEditD = findChild<LLLineEditor>("edit_d_value");
 -	llassert(mEditD != NULL);
 -	mEditD->setPrevalidate(LLTextValidate::validateNonNegativeS32);
 -	mEditD->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1));
 -
 -	mApplyEditsButton = findChild<LLButton>("apply_edit_values");
 -	llassert(mApplyEditsButton != NULL);
 -	mApplyEditsButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyChangesClicked, this));
 -
 -	return LLFloater::postBuild();
 -}
 -
 -void LLFloaterPathfindingLinksets::onOpen(const LLSD& pKey)
 -{
 -	LLFloater::onOpen(pKey);
 -
 -	requestGetLinksets();
 -	selectNoneLinksets();
 -	mLinksetsScrollList->setCommitOnSelectionChange(true);
 -
 -	if (!mAgentStateSlot.connected())
 -	{
 -		mAgentStateSlot = LLPathfindingManager::getInstance()->registerAgentStateListener(boost::bind(&LLFloaterPathfindingLinksets::onAgentStateCB, this, _1));
 -	}
 -
 -	if (!mSelectionUpdateSlot.connected())
 -	{
 -		mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterPathfindingLinksets::updateControls, this));
 -	}
 -
 -	if (!mRegionBoundarySlot.connected())
 -	{
 -		mRegionBoundarySlot = LLEnvManagerNew::instance().setRegionChangeCallback(boost::bind(&LLFloaterPathfindingLinksets::onRegionBoundaryCross, this));
 -	}
 -}
 -
 -void LLFloaterPathfindingLinksets::onClose(bool pAppQuitting)
 -{
 -	if (mRegionBoundarySlot.connected())
 -	{
 -		mRegionBoundarySlot.disconnect();
 -	}
 -
 -	if (mSelectionUpdateSlot.connected())
 -	{
 -		mSelectionUpdateSlot.disconnect();
 -	}
 -
 -	if (mAgentStateSlot.connected())
 -	{
 -		mAgentStateSlot.disconnect();
 -	}
 -
 -	mLinksetsScrollList->setCommitOnSelectionChange(false);
 -	selectNoneLinksets();
 -	if (mLinksetsSelection.notNull())
 -	{
 -		mLinksetsSelection.clear();
 -	}
 -
 -	LLFloater::onClose(pAppQuitting);
 -}
 -
 -void LLFloaterPathfindingLinksets::draw()
 -{
 -	if (mShowBeaconCheckBox->get())
 -	{
 -		std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected();
 -		if (!selectedItems.empty())
 -		{
 -			int numSelectedItems = selectedItems.size();
 -
 -			std::vector<LLViewerObject *> viewerObjects;
 -			viewerObjects.reserve(numSelectedItems);
 -
 -			for (std::vector<LLScrollListItem*>::const_iterator selectedItemIter = selectedItems.begin();
 -				selectedItemIter != selectedItems.end(); ++selectedItemIter)
 -			{
 -				const LLScrollListItem *selectedItem = *selectedItemIter;
 -
 -				LLViewerObject *viewerObject = gObjectList.findObject(selectedItem->getUUID());
 -				if (viewerObject != NULL)
 -				{
 -					const std::string &objectName = selectedItem->getColumn(0)->getValue().asString();
 -					gObjectList.addDebugBeacon(viewerObject->getPositionAgent(), objectName, LLColor4(0.f, 0.f, 1.f, 0.8f), LLColor4(1.f, 1.f, 1.f, 1.f), 6);
 -				}
 -			}
 -		}
 -	}
 -
 -	LLFloater::draw();
 -}
 -
 -void LLFloaterPathfindingLinksets::openLinksetsEditor()
 -{
 -	LLFloaterReg::toggleInstanceOrBringToFront("pathfinding_linksets");
 -}
 -
 -LLFloaterPathfindingLinksets::LLFloaterPathfindingLinksets(const LLSD& pSeed)
 -	: LLFloater(pSeed),
 -	mFilterByName(NULL),
 -	mFilterByDescription(NULL),
 -	mFilterByLinksetUse(NULL),
 -	mLinksetsScrollList(NULL),
 -	mLinksetsStatus(NULL),
 -	mRefreshListButton(NULL),
 -	mSelectAllButton(NULL),
 -	mSelectNoneButton(NULL),
 -	mShowBeaconCheckBox(NULL),
 -	mTakeButton(NULL),
 -	mTakeCopyButton(NULL),
 -	mReturnButton(NULL),
 -	mDeleteButton(NULL),
 -	mTeleportButton(NULL),
 -	mEditLinksetUse(NULL),
 -	mLabelWalkabilityCoefficients(NULL),
 -	mLabelEditA(NULL),
 -	mEditA(NULL),
 -	mLabelEditB(NULL),
 -	mEditB(NULL),
 -	mLabelEditC(NULL),
 -	mEditC(NULL),
 -	mLabelEditD(NULL),
 -	mEditD(NULL),
 -	mApplyEditsButton(NULL),
 -	mMessagingState(kMessagingUnknown),
 -	mMessagingRequestId(0U),
 -	mLinksetsListPtr(),
 -	mLinksetsSelection(),
 -	mAgentStateSlot(),
 -	mSelectionUpdateSlot()
 -{
 -}
 -
 -LLFloaterPathfindingLinksets::~LLFloaterPathfindingLinksets()
 -{
 -}
 -
 -LLFloaterPathfindingLinksets::EMessagingState LLFloaterPathfindingLinksets::getMessagingState() const
 -{
 -	return mMessagingState;
 -}
 -
 -void LLFloaterPathfindingLinksets::setMessagingState(EMessagingState pMessagingState)
 -{
 -	mMessagingState = pMessagingState;
 -	updateControls();
 -}
 -
 -void LLFloaterPathfindingLinksets::requestGetLinksets()
 -{
 -	switch (LLPathfindingManager::getInstance()->requestGetLinksets(++mMessagingRequestId, boost::bind(&LLFloaterPathfindingLinksets::handleNewLinksets, this, _1, _2, _3)))
 -	{
 -	case LLPathfindingManager::kRequestStarted :
 -		setMessagingState(kMessagingGetRequestSent);
 -		break;
 -	case LLPathfindingManager::kRequestCompleted :
 -		clearLinksets();
 -		setMessagingState(kMessagingComplete);
 -		break;
 -	case LLPathfindingManager::kRequestNotEnabled :
 -		clearLinksets();
 -		setMessagingState(kMessagingNotEnabled);
 -		break;
 -	case LLPathfindingManager::kRequestError :
 -		setMessagingState(kMessagingGetError);
 -		break;
 -	default :
 -		setMessagingState(kMessagingGetError);
 -		llassert(0);
 -		break;
 -	}
 -}
 -
 -void LLFloaterPathfindingLinksets::requestSetLinksets(LLPathfindingLinksetListPtr pLinksetList, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD)
 -{
 -	switch (LLPathfindingManager::getInstance()->requestSetLinksets(++mMessagingRequestId, pLinksetList, pLinksetUse, pA, pB, pC, pD, boost::bind(&LLFloaterPathfindingLinksets::handleUpdateLinksets, this, _1, _2, _3)))
 -	{
 -	case LLPathfindingManager::kRequestStarted :
 -		setMessagingState(kMessagingSetRequestSent);
 -		break;
 -	case LLPathfindingManager::kRequestCompleted :
 -		setMessagingState(kMessagingComplete);
 -		break;
 -	case LLPathfindingManager::kRequestNotEnabled :
 -		clearLinksets();
 -		setMessagingState(kMessagingNotEnabled);
 -		break;
 -	case LLPathfindingManager::kRequestError :
 -		setMessagingState(kMessagingSetError);
 -		break;
 -	default :
 -		setMessagingState(kMessagingSetError);
 -		llassert(0);
 -		break;
 -	}
 -}
 -
 -void LLFloaterPathfindingLinksets::handleNewLinksets(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pLinksetsRequestStatus, LLPathfindingLinksetListPtr pLinksetsListPtr)
 -{
 -	llassert(pRequestId <= mMessagingRequestId);
 -	if (pRequestId == mMessagingRequestId)
 -	{
 -		mLinksetsListPtr = pLinksetsListPtr;
 -		updateScrollList();
 -
 -		switch (pLinksetsRequestStatus)
 -		{
 -		case LLPathfindingManager::kRequestCompleted :
 -			setMessagingState(kMessagingComplete);
 -			break;
 -		case LLPathfindingManager::kRequestError :
 -			setMessagingState(kMessagingGetError);
 -			break;
 -		default :
 -			setMessagingState(kMessagingGetError);
 -			llassert(0);
 -			break;
 -		}
 -	}
 -}
 -
 -void LLFloaterPathfindingLinksets::handleUpdateLinksets(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pLinksetsRequestStatus, LLPathfindingLinksetListPtr pLinksetsListPtr)
 -{
 -	llassert(pRequestId <= mMessagingRequestId);
 -	if (pRequestId == mMessagingRequestId)
 -	{
 -		if (mLinksetsListPtr == NULL)
 -		{
 -			mLinksetsListPtr = pLinksetsListPtr;
 -		}
 -		else
 -		{
 -			mLinksetsListPtr->update(*pLinksetsListPtr);
 -		}
 -		updateScrollList();
 -
 -		switch (pLinksetsRequestStatus)
 -		{
 -		case LLPathfindingManager::kRequestCompleted :
 -			setMessagingState(kMessagingComplete);
 -			break;
 -		case LLPathfindingManager::kRequestError :
 -			setMessagingState(kMessagingSetError);
 -			break;
 -		default :
 -			setMessagingState(kMessagingSetError);
 -			llassert(0);
 -			break;
 -		}
 -	}
 -}
 -
 -void LLFloaterPathfindingLinksets::onApplyAllFilters()
 -{
 -	applyFilters();
 -}
 -
 -void LLFloaterPathfindingLinksets::onClearFiltersClicked()
 -{
 -	clearFilters();
 -}
 -
 -void LLFloaterPathfindingLinksets::onLinksetsSelectionChange()
 -{
 -	mLinksetsSelection.clear();
 -	LLSelectMgr::getInstance()->deselectAll();
 -
 -	std::vector<LLScrollListItem *> selectedItems = mLinksetsScrollList->getAllSelected();
 -	if (!selectedItems.empty())
 -	{
 -		int numSelectedItems = selectedItems.size();
 -
 -		std::vector<LLViewerObject *>viewerObjects;
 -		viewerObjects.reserve(numSelectedItems);
 -
 -		for (std::vector<LLScrollListItem *>::const_iterator selectedItemIter = selectedItems.begin();
 -			selectedItemIter != selectedItems.end(); ++selectedItemIter)
 -		{
 -			const LLScrollListItem *selectedItem = *selectedItemIter;
 -
 -			LLViewerObject *viewerObject = gObjectList.findObject(selectedItem->getUUID());
 -			if (viewerObject != NULL)
 -			{
 -				viewerObjects.push_back(viewerObject);
 -			}
 -		}
 -
 -		if (!viewerObjects.empty())
 -		{
 -			mLinksetsSelection = LLSelectMgr::getInstance()->selectObjectAndFamily(viewerObjects);
 -		}
 -	}
 -
 -	updateEditFieldValues();
 -	updateControls();
 -}
 -
 -void LLFloaterPathfindingLinksets::onRefreshLinksetsClicked()
 -{
 -	requestGetLinksets();
 -}
 -
 -void LLFloaterPathfindingLinksets::onSelectAllLinksetsClicked()
 -{
 -	selectAllLinksets();
 -}
 -
 -void LLFloaterPathfindingLinksets::onSelectNoneLinksetsClicked()
 -{
 -	selectNoneLinksets();
 -}
 -
 -void LLFloaterPathfindingLinksets::onTakeClicked()
 -{
 -	handle_take();
 -}
 -
 -void LLFloaterPathfindingLinksets::onTakeCopyClicked()
 -{
 -	handle_take_copy();
 -}
 -
 -void LLFloaterPathfindingLinksets::onReturnClicked()
 -{
 -	handle_object_return();
 -}
 -
 -void LLFloaterPathfindingLinksets::onDeleteClicked()
 -{
 -	handle_object_delete();
 -}
 -
 -void LLFloaterPathfindingLinksets::onTeleportClicked()
 -{
 -	std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected();
 -	llassert(selectedItems.size() == 1);
 -	if (selectedItems.size() == 1)
 -	{
 -		std::vector<LLScrollListItem*>::const_reference selectedItemRef = selectedItems.front();
 -		const LLScrollListItem *selectedItem = selectedItemRef;
 -		llassert(mLinksetsListPtr != NULL);
 -		LLPathfindingLinksetList::const_iterator linksetIter = mLinksetsListPtr->find(selectedItem->getUUID().asString());
 -		const LLPathfindingLinksetPtr linksetPtr = linksetIter->second;
 -		const LLVector3 &linksetLocation = linksetPtr->getLocation();
 -
 -		LLViewerRegion* region = gAgent.getRegion();
 -		if (region != NULL)
 -		{
 -			gAgent.teleportRequest(region->getHandle(), linksetLocation, true);
 -		}
 -	}
 -}
 -
 -void LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered(LLUICtrl *pUICtrl)
 -{
 -	LLLineEditor *pLineEditor = static_cast<LLLineEditor *>(pUICtrl);
 -	llassert(pLineEditor != NULL);
 -
 -	const std::string &valueString = pLineEditor->getText();
 -	S32 value = static_cast<S32>(atoi(valueString.c_str()));
 -
 -	if ((value < LLPathfindingLinkset::MIN_WALKABILITY_VALUE) || (value > LLPathfindingLinkset::MAX_WALKABILITY_VALUE))
 -	{
 -		value = llclamp(value, LLPathfindingLinkset::MIN_WALKABILITY_VALUE, LLPathfindingLinkset::MAX_WALKABILITY_VALUE);
 -		pLineEditor->setValue(LLSD(value));
 -	}
 -}
 -
 -void LLFloaterPathfindingLinksets::onApplyChangesClicked()
 -{
 -	applyEdit();
 -}
 -
 -void LLFloaterPathfindingLinksets::onAgentStateCB(LLPathfindingManager::EAgentState pAgentState)
 -{
 -	updateControls();
 -}
 -
 -void LLFloaterPathfindingLinksets::onRegionBoundaryCross()
 -{
 -	requestGetLinksets();
 -}
 -
 -void LLFloaterPathfindingLinksets::applyFilters()
 -{
 -	updateScrollList();
 -}
 -
 -void LLFloaterPathfindingLinksets::clearFilters()
 -{
 -	mFilterByName->clear();
 -	mFilterByDescription->clear();
 -	setFilterLinksetUse(LLPathfindingLinkset::kUnknown);
 -	updateScrollList();
 -}
 -
 -void LLFloaterPathfindingLinksets::selectAllLinksets()
 -{
 -	mLinksetsScrollList->selectAll();
 -}
 -
 -void LLFloaterPathfindingLinksets::selectNoneLinksets()
 -{
 -	mLinksetsScrollList->deselectAllItems();
 -}
 -
 -void LLFloaterPathfindingLinksets::clearLinksets()
 -{
 -	if (mLinksetsListPtr != NULL)
 -	{
 -		mLinksetsListPtr->clear();
 -	}
 -	updateScrollList();
 -}
 -
 -void LLFloaterPathfindingLinksets::updateControls()
 -{
 -	updateStatusMessage();
 -	updateEnableStateOnListActions();
 -	updateEnableStateOnEditFields();
 -}
 -
 -void LLFloaterPathfindingLinksets::updateEditFieldValues()
 -{
 -	std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected();
 -	int numSelectedItems = selectedItems.size();
 -	if (numSelectedItems <= 0)
 -	{
 -		mEditLinksetUse->selectFirstItem();
 -		mEditA->clear();
 -		mEditB->clear();
 -		mEditC->clear();
 -		mEditD->clear();
 -	}
 -	else
 -	{
 -		LLScrollListItem *firstItem = selectedItems.front();
 -
 -		llassert(mLinksetsListPtr != NULL);
 -		LLPathfindingLinksetList::const_iterator linksetIter = mLinksetsListPtr->find(firstItem->getUUID().asString());
 -		const LLPathfindingLinksetPtr linksetPtr(linksetIter->second);
 -
 -		setEditLinksetUse(linksetPtr->getLinksetUse());
 -		mEditA->setValue(LLSD(linksetPtr->getWalkabilityCoefficientA()));
 -		mEditB->setValue(LLSD(linksetPtr->getWalkabilityCoefficientB()));
 -		mEditC->setValue(LLSD(linksetPtr->getWalkabilityCoefficientC()));
 -		mEditD->setValue(LLSD(linksetPtr->getWalkabilityCoefficientD()));
 -		updateEnableStateOnEditLinksetUse();
 -	}
 -}
 -
 -void LLFloaterPathfindingLinksets::updateScrollList()
 -{
 -	std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected();
 -	int numSelectedItems = selectedItems.size();
 -	uuid_vec_t selectedUUIDs;
 -	if (numSelectedItems > 0)
 -	{
 -		selectedUUIDs.reserve(selectedItems.size());
 -		for (std::vector<LLScrollListItem*>::const_iterator itemIter = selectedItems.begin();
 -			itemIter != selectedItems.end(); ++itemIter)
 -		{
 -			const LLScrollListItem *listItem = *itemIter;
 -			selectedUUIDs.push_back(listItem->getUUID());
 -		}
 -	}
 -
 -	S32 origScrollPosition = mLinksetsScrollList->getScrollPos();
 -	mLinksetsScrollList->deleteAllItems();
 -
 -	if (mLinksetsListPtr != NULL)
 -	{
 -		std::string nameFilter = mFilterByName->getText();
 -		std::string descriptionFilter = mFilterByDescription->getText();
 -		LLPathfindingLinkset::ELinksetUse linksetUseFilter = getFilterLinksetUse();
 -		bool isFilteringName = !nameFilter.empty();
 -		bool isFilteringDescription = !descriptionFilter.empty();
 -		bool isFilteringLinksetUse = (linksetUseFilter != LLPathfindingLinkset::kUnknown);
 -
 -		const LLVector3& avatarPosition = gAgent.getPositionAgent();
 -
 -		if (isFilteringName || isFilteringDescription || isFilteringLinksetUse)
 -		{
 -			LLStringUtil::toUpper(nameFilter);
 -			LLStringUtil::toUpper(descriptionFilter);
 -			for (LLPathfindingLinksetList::const_iterator linksetIter = mLinksetsListPtr->begin();
 -				linksetIter != mLinksetsListPtr->end(); ++linksetIter)
 -			{
 -				const LLPathfindingLinksetPtr linksetPtr(linksetIter->second);
 -				std::string linksetName = (linksetPtr->isTerrain() ? getString("linkset_terrain_name") : linksetPtr->getName());
 -				std::string linksetDescription = linksetPtr->getDescription();
 -				LLStringUtil::toUpper(linksetName);
 -				LLStringUtil::toUpper(linksetDescription);
 -				if ((!isFilteringName || (linksetName.find(nameFilter) != std::string::npos)) &&
 -					(!isFilteringDescription || (linksetDescription.find(descriptionFilter) != std::string::npos)) &&
 -					(!isFilteringLinksetUse || (linksetPtr->getLinksetUse() == linksetUseFilter)))
 -				{
 -					LLSD element = buildLinksetScrollListElement(linksetPtr, avatarPosition);
 -					mLinksetsScrollList->addElement(element);
 -				}
 -			}
 -		}
 -		else
 -		{
 -			for (LLPathfindingLinksetList::const_iterator linksetIter = mLinksetsListPtr->begin();
 -				linksetIter != mLinksetsListPtr->end(); ++linksetIter)
 -			{
 -				const LLPathfindingLinksetPtr linksetPtr(linksetIter->second);
 -				LLSD element = buildLinksetScrollListElement(linksetPtr, avatarPosition);
 -				mLinksetsScrollList->addElement(element);
 -			}
 -		}
 -	}
 -
 -	mLinksetsScrollList->selectMultiple(selectedUUIDs);
 -	mLinksetsScrollList->setScrollPos(origScrollPosition);
 -	updateEditFieldValues();
 -	updateControls();
 -}
 -
 -LLSD LLFloaterPathfindingLinksets::buildLinksetScrollListElement(const LLPathfindingLinksetPtr pLinksetPtr, const LLVector3 &pAvatarPosition) const
 -{
 -	LLSD columns;
 -
 -	if (pLinksetPtr->isTerrain())
 -	{
 -		columns[0]["column"] = "name";
 -		columns[0]["value"] = getString("linkset_terrain_name");
 -		columns[0]["font"] = "SANSSERIF";
 -
 -		columns[1]["column"] = "description";
 -		columns[1]["value"] = getString("linkset_terrain_description");
 -		columns[1]["font"] = "SANSSERIF";
 -
 -		columns[2]["column"] = "land_impact";
 -		columns[2]["value"] = getString("linkset_terrain_land_impact");
 -		columns[2]["font"] = "SANSSERIF";
 -
 -		columns[3]["column"] = "dist_from_you";
 -		columns[3]["value"] = getString("linkset_terrain_dist_from_you");
 -		columns[3]["font"] = "SANSSERIF";
 -	}
 -	else
 -	{
 -		columns[0]["column"] = "name";
 -		columns[0]["value"] = pLinksetPtr->getName();
 -		columns[0]["font"] = "SANSSERIF";
 -
 -		columns[1]["column"] = "description";
 -		columns[1]["value"] = pLinksetPtr->getDescription();
 -		columns[1]["font"] = "SANSSERIF";
 -
 -		columns[2]["column"] = "land_impact";
 -		columns[2]["value"] = llformat("%1d", pLinksetPtr->getLandImpact());
 -		columns[2]["font"] = "SANSSERIF";
 -
 -		columns[3]["column"] = "dist_from_you";
 -		columns[3]["value"] = llformat("%1.0f m", dist_vec(pAvatarPosition, pLinksetPtr->getLocation()));
 -		columns[3]["font"] = "SANSSERIF";
 -	}
 -
 -	columns[4]["column"] = "linkset_use";
 -	std::string linksetUse = getLinksetUseString(pLinksetPtr->getLinksetUse());
 -	if (pLinksetPtr->isTerrain())
 -	{
 -		linksetUse += (" " + getString("linkset_is_terrain"));
 -	}
 -	else if (!pLinksetPtr->isModifiable() && pLinksetPtr->canBeVolume())
 -	{
 -		linksetUse += (" " + getString("linkset_is_restricted_state"));
 -	}
 -	else if (pLinksetPtr->isModifiable() && !pLinksetPtr->canBeVolume())
 -	{
 -		linksetUse += (" " + getString("linkset_is_non_volume_state"));
 -	}
 -	else if (!pLinksetPtr->isModifiable() && !pLinksetPtr->canBeVolume())
 -	{
 -		linksetUse += (" " + getString("linkset_is_restricted_non_volume_state"));
 -	}
 -	columns[4]["value"] = linksetUse;
 -	columns[4]["font"] = "SANSSERIF";
 -
 -	columns[5]["column"] = "a_percent";
 -	columns[5]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientA());
 -	columns[5]["font"] = "SANSSERIF";
 -
 -	columns[6]["column"] = "b_percent";
 -	columns[6]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientB());
 -	columns[6]["font"] = "SANSSERIF";
 -
 -	columns[7]["column"] = "c_percent";
 -	columns[7]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientC());
 -	columns[7]["font"] = "SANSSERIF";
 -
 -	columns[8]["column"] = "d_percent";
 -	columns[8]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientD());
 -	columns[8]["font"] = "SANSSERIF";
 -
 -	LLSD element;
 -	element["id"] = pLinksetPtr->getUUID().asString();
 -	element["column"] = columns;
 -
 -	return element;
 -}
 -
 -LLSD LLFloaterPathfindingLinksets::buildLinksetUseScrollListElement(const std::string &label, S32 value) const
 -{
 -	LLSD columns;
 -
 -	columns[0]["column"] = "name";
 -	columns[0]["relwidth"] = static_cast<LLSD::Real>(100.0f);
 -	columns[0]["value"] = label;
 -	columns[0]["font"] = "SANSSERIF";
 -
 -	LLSD element;
 -	element["value"] = value;
 -	element["column"] = columns;
 -
 -	return element;
 -}
 -
 -bool LLFloaterPathfindingLinksets::isShowUnmodifiablePhantomWarning(LLPathfindingLinkset::ELinksetUse linksetUse) const
 -{
 -	bool showWarning = false;
 -
 -	if (linksetUse != LLPathfindingLinkset::kUnknown)
 -	{
 -		std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected();
 -		if (!selectedItems.empty())
 -		{
 -			for (std::vector<LLScrollListItem*>::const_iterator selectedItemIter = selectedItems.begin();
 -				!showWarning && (selectedItemIter != selectedItems.end()); ++selectedItemIter)
 -			{
 -				const LLScrollListItem *selectedItem = *selectedItemIter;
 -				llassert(mLinksetsListPtr != NULL);
 -				LLPathfindingLinksetList::const_iterator linksetIter = mLinksetsListPtr->find(selectedItem->getUUID().asString());
 -				llassert(linksetIter != mLinksetsListPtr->end());
 -				const LLPathfindingLinksetPtr linksetPtr = linksetIter->second;
 -				showWarning = linksetPtr->isShowUnmodifiablePhantomWarning(linksetUse);
 -			}
 -		}
 -	}
 -
 -	return showWarning;
 -}
 -
 -bool LLFloaterPathfindingLinksets::isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse linksetUse) const
 -{
 -	bool showWarning = false;
 -
 -	if (linksetUse != LLPathfindingLinkset::kUnknown)
 -	{
 -		std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected();
 -		if (!selectedItems.empty())
 -		{
 -			for (std::vector<LLScrollListItem*>::const_iterator selectedItemIter = selectedItems.begin();
 -				!showWarning && (selectedItemIter != selectedItems.end()); ++selectedItemIter)
 -			{
 -				const LLScrollListItem *selectedItem = *selectedItemIter;
 -				llassert(mLinksetsListPtr != NULL);
 -				LLPathfindingLinksetList::const_iterator linksetIter = mLinksetsListPtr->find(selectedItem->getUUID().asString());
 -				llassert(linksetIter != mLinksetsListPtr->end());
 -				const LLPathfindingLinksetPtr linksetPtr = linksetIter->second;
 -				showWarning = linksetPtr->isShowCannotBeVolumeWarning(linksetUse);
 -			}
 -		}
 -	}
 -
 -	return showWarning;
 -}
 -
 -void LLFloaterPathfindingLinksets::updateStatusMessage()
 -{
 -	static const LLColor4 errorColor = LLUIColorTable::instance().getColor("PathfindingErrorColor");
 -	static const LLColor4 warningColor = LLUIColorTable::instance().getColor("PathfindingWarningColor");
 -
 -	std::string statusText("");
 -	LLStyle::Params styleParams;
 -
 -	switch (getMessagingState())
 -	{
 -	case kMessagingUnknown:
 -		statusText = getString("linksets_messaging_initial");
 -		styleParams.color = errorColor;
 -		break;
 -	case kMessagingGetRequestSent :
 -		statusText = getString("linksets_messaging_get_inprogress");
 -		styleParams.color = warningColor;
 -		break;
 -	case kMessagingGetError :
 -		statusText = getString("linksets_messaging_get_error");
 -		styleParams.color = errorColor;
 -		break;
 -	case kMessagingSetRequestSent :
 -		statusText = getString("linksets_messaging_set_inprogress");
 -		styleParams.color = warningColor;
 -		break;
 -	case kMessagingSetError :
 -		statusText = getString("linksets_messaging_set_error");
 -		styleParams.color = errorColor;
 -		break;
 -	case kMessagingComplete :
 -		if (mLinksetsScrollList->isEmpty())
 -		{
 -			statusText = getString("linksets_messaging_complete_none_found");
 -		}
 -		else
 -		{
 -			S32 numItems = mLinksetsScrollList->getItemCount();
 -			S32 numSelectedItems = mLinksetsScrollList->getNumSelected();
 -
 -			LLLocale locale(LLStringUtil::getLocale());
 -			std::string numItemsString;
 -			LLResMgr::getInstance()->getIntegerString(numItemsString, numItems);
 -
 -			std::string numSelectedItemsString;
 -			LLResMgr::getInstance()->getIntegerString(numSelectedItemsString, numSelectedItems);
 -
 -			LLStringUtil::format_map_t string_args;
 -			string_args["[NUM_SELECTED]"] = numSelectedItemsString;
 -			string_args["[NUM_TOTAL]"] = numItemsString;
 -			statusText = getString("linksets_messaging_complete_available", string_args);
 -		}
 -		break;
 -	case kMessagingNotEnabled :
 -		statusText = getString("linksets_messaging_not_enabled");
 -		styleParams.color = errorColor;
 -		break;
 -	default:
 -		statusText = getString("linksets_messaging_initial");
 -		styleParams.color = errorColor;
 -		llassert(0);
 -		break;
 -	}
 -
 -	mLinksetsStatus->setText((LLStringExplicit)statusText, styleParams);
 -}
 -
 -void LLFloaterPathfindingLinksets::updateEnableStateOnListActions()
 -{
 -	switch (getMessagingState())
 -	{
 -	case kMessagingUnknown:
 -	case kMessagingGetRequestSent :
 -	case kMessagingSetRequestSent :
 -		mRefreshListButton->setEnabled(FALSE);
 -		mSelectAllButton->setEnabled(FALSE);
 -		mSelectNoneButton->setEnabled(FALSE);
 -		break;
 -	case kMessagingGetError :
 -	case kMessagingSetError :
 -	case kMessagingNotEnabled :
 -		mRefreshListButton->setEnabled(TRUE);
 -		mSelectAllButton->setEnabled(FALSE);
 -		mSelectNoneButton->setEnabled(FALSE);
 -		break;
 -	case kMessagingComplete :
 -		{
 -			int numItems = mLinksetsScrollList->getItemCount();
 -			int numSelectedItems = mLinksetsScrollList->getNumSelected();
 -			mRefreshListButton->setEnabled(TRUE);
 -			mSelectAllButton->setEnabled(numSelectedItems < numItems);
 -			mSelectNoneButton->setEnabled(numSelectedItems > 0);
 -		}
 -		break;
 -	default:
 -		llassert(0);
 -		break;
 -	}
 -}
 -
 -void LLFloaterPathfindingLinksets::updateEnableStateOnEditFields()
 -{
 -	int numSelectedItems = mLinksetsScrollList->getNumSelected();
 -	bool isEditEnabled = ((numSelectedItems > 0) && LLPathfindingManager::getInstance()->isAllowAlterPermanent());
 -
 -	mShowBeaconCheckBox->setEnabled(numSelectedItems > 0);
 -	mTakeButton->setEnabled(isEditEnabled && visible_take_object());
 -	mTakeCopyButton->setEnabled(isEditEnabled && enable_object_take_copy());
 -	mReturnButton->setEnabled(isEditEnabled && enable_object_return());
 -	mDeleteButton->setEnabled(isEditEnabled && enable_object_delete());
 -	mTeleportButton->setEnabled(numSelectedItems == 1);
 -
 -	mEditLinksetUse->setEnabled(isEditEnabled);
 -
 -	mLabelWalkabilityCoefficients->setEnabled(isEditEnabled);
 -	mLabelEditA->setEnabled(isEditEnabled);
 -	mLabelEditB->setEnabled(isEditEnabled);
 -	mLabelEditC->setEnabled(isEditEnabled);
 -	mLabelEditD->setEnabled(isEditEnabled);
 -	mEditA->setEnabled(isEditEnabled);
 -	mEditB->setEnabled(isEditEnabled);
 -	mEditC->setEnabled(isEditEnabled);
 -	mEditD->setEnabled(isEditEnabled);
 -
 -	mApplyEditsButton->setEnabled(isEditEnabled && (getMessagingState() == kMessagingComplete));
 -}
 -
 -void LLFloaterPathfindingLinksets::updateEnableStateOnEditLinksetUse()
 -{
 -	BOOL useWalkable = FALSE;
 -	BOOL useStaticObstacle = FALSE;
 -	BOOL useDynamicObstacle = FALSE;
 -	BOOL useMaterialVolume = FALSE;
 -	BOOL useExclusionVolume = FALSE;
 -	BOOL useDynamicPhantom = FALSE;
 -
 -	std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected();
 -	if (!selectedItems.empty())
 -	{
 -		for (std::vector<LLScrollListItem*>::const_iterator selectedItemIter = selectedItems.begin();
 -			!(useWalkable && useStaticObstacle && useDynamicObstacle && useMaterialVolume && useExclusionVolume && useDynamicPhantom) && (selectedItemIter != selectedItems.end());
 -			++selectedItemIter)
 -		{
 -			const LLScrollListItem *selectedItem = *selectedItemIter;
 -			llassert(mLinksetsListPtr != NULL);
 -			LLPathfindingLinksetList::const_iterator linksetIter = mLinksetsListPtr->find(selectedItem->getUUID().asString());
 -			llassert(linksetIter != mLinksetsListPtr->end());
 -			const LLPathfindingLinksetPtr linksetPtr = linksetIter->second;
 -
 -			if (linksetPtr->isTerrain())
 -			{
 -				useWalkable = TRUE;
 -			}
 -			else
 -			{
 -				if (linksetPtr->isModifiable())
 -				{
 -					useWalkable = TRUE;
 -					useStaticObstacle = TRUE;
 -					useDynamicObstacle = TRUE;
 -					useDynamicPhantom = TRUE;
 -					if (linksetPtr->canBeVolume())
 -					{
 -						useMaterialVolume = TRUE;
 -						useExclusionVolume = TRUE;
 -					}
 -				}
 -				else if (linksetPtr->isPhantom())
 -				{
 -					useDynamicPhantom = TRUE;
 -					if (linksetPtr->canBeVolume())
 -					{
 -						useMaterialVolume = TRUE;
 -						useExclusionVolume = TRUE;
 -					}
 -				}
 -				else
 -				{
 -					useWalkable = TRUE;
 -					useStaticObstacle = TRUE;
 -					useDynamicObstacle = TRUE;
 -				}
 -			}
 -		}
 -	}
 -
 -	mEditLinksetUseWalkable->setEnabled(useWalkable);
 -	mEditLinksetUseStaticObstacle->setEnabled(useStaticObstacle);
 -	mEditLinksetUseDynamicObstacle->setEnabled(useDynamicObstacle);
 -	mEditLinksetUseMaterialVolume->setEnabled(useMaterialVolume);
 -	mEditLinksetUseExclusionVolume->setEnabled(useExclusionVolume);
 -	mEditLinksetUseDynamicPhantom->setEnabled(useDynamicPhantom);
 -}
 -
 -void LLFloaterPathfindingLinksets::applyEdit()
 -{
 -	LLPathfindingLinkset::ELinksetUse linksetUse = getEditLinksetUse();
 -
 -	bool showUnmodifiablePhantomWarning = isShowUnmodifiablePhantomWarning(linksetUse);
 -	bool showCannotBeVolumeWarning = isShowCannotBeVolumeWarning(linksetUse);
 -
 -	if (showUnmodifiablePhantomWarning || showCannotBeVolumeWarning)
 -	{
 -		LLPathfindingLinkset::ELinksetUse restrictedLinksetUse = LLPathfindingLinkset::getLinksetUseWithToggledPhantom(linksetUse);
 -		LLSD substitutions;
 -		substitutions["REQUESTED_TYPE"] = getLinksetUseString(linksetUse);
 -		substitutions["RESTRICTED_TYPE"] = getLinksetUseString(restrictedLinksetUse);
 -
 -		std::string notificationName;
 -		if (showUnmodifiablePhantomWarning && showCannotBeVolumeWarning)
 -		{
 -			notificationName = "PathfindingLinksets_SetLinksetUseMismatchOnRestrictedAndVolume";
 -		}
 -		else if (showUnmodifiablePhantomWarning)
 -		{
 -			notificationName = "PathfindingLinksets_SetLinksetUseMismatchOnRestricted";
 -		}
 -		else
 -		{
 -			notificationName = "PathfindingLinksets_SetLinksetUseMismatchOnVolume";
 -		}
 -		LLNotificationsUtil::add(notificationName, substitutions, LLSD(), boost::bind(&LLFloaterPathfindingLinksets::handleApplyEdit, this, _1, _2));
 -	}
 -	else
 -	{
 -		doApplyEdit();
 -	}
 -}
 -
 -void LLFloaterPathfindingLinksets::handleApplyEdit(const LLSD &pNotification, const LLSD &pResponse)
 -{
 -	if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0)
 -	{
 -		doApplyEdit();
 -	}
 -}
 -
 -void LLFloaterPathfindingLinksets::doApplyEdit()
 -{
 -	std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected();
 -	if (!selectedItems.empty())
 -	{
 -		LLPathfindingLinkset::ELinksetUse linksetUse = getEditLinksetUse();
 -		const std::string &aString = mEditA->getText();
 -		const std::string &bString = mEditB->getText();
 -		const std::string &cString = mEditC->getText();
 -		const std::string &dString = mEditD->getText();
 -		S32 aValue = static_cast<S32>(atoi(aString.c_str()));
 -		S32 bValue = static_cast<S32>(atoi(bString.c_str()));
 -		S32 cValue = static_cast<S32>(atoi(cString.c_str()));
 -		S32 dValue = static_cast<S32>(atoi(dString.c_str()));
 -
 -		LLPathfindingLinksetListPtr editListPtr(new LLPathfindingLinksetList());
 -		for (std::vector<LLScrollListItem*>::const_iterator itemIter = selectedItems.begin();
 -			itemIter != selectedItems.end(); ++itemIter)
 -		{
 -			const LLScrollListItem *listItem = *itemIter;
 -			LLUUID uuid = listItem->getUUID();
 -			const std::string &uuidString = uuid.asString();
 -			llassert(mLinksetsListPtr != NULL);
 -			LLPathfindingLinksetList::iterator linksetIter = mLinksetsListPtr->find(uuidString);
 -			llassert(linksetIter != mLinksetsListPtr->end());
 -			LLPathfindingLinksetPtr linksetPtr = linksetIter->second;
 -			editListPtr->insert(std::pair<std::string, LLPathfindingLinksetPtr>(uuidString, linksetPtr));
 -		}
 -
 -		requestSetLinksets(editListPtr, linksetUse, aValue, bValue, cValue, dValue);
 -	}
 -}
 -
 -std::string LLFloaterPathfindingLinksets::getLinksetUseString(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
 -{
 -	std::string linksetUse;
 -
 -	switch (pLinksetUse)
 -	{
 -	case LLPathfindingLinkset::kWalkable :
 -		linksetUse = getString("linkset_use_walkable");
 -		break;
 -	case LLPathfindingLinkset::kStaticObstacle :
 -		linksetUse = getString("linkset_use_static_obstacle");
 -		break;
 -	case LLPathfindingLinkset::kDynamicObstacle :
 -		linksetUse = getString("linkset_use_dynamic_obstacle");
 -		break;
 -	case LLPathfindingLinkset::kMaterialVolume :
 -		linksetUse = getString("linkset_use_material_volume");
 -		break;
 -	case LLPathfindingLinkset::kExclusionVolume :
 -		linksetUse = getString("linkset_use_exclusion_volume");
 -		break;
 -	case LLPathfindingLinkset::kDynamicPhantom :
 -		linksetUse = getString("linkset_use_dynamic_phantom");
 -		break;
 -	case LLPathfindingLinkset::kUnknown :
 -	default :
 -		linksetUse = getString("linkset_use_dynamic_obstacle");
 -		llassert(0);
 -		break;
 -	}
 -
 -	return linksetUse;
 -}
 -
 -LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::getFilterLinksetUse() const
 -{
 -	return convertToLinksetUse(mFilterByLinksetUse->getValue());
 -}
 -
 -void LLFloaterPathfindingLinksets::setFilterLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse)
 -{
 -	mFilterByLinksetUse->setValue(convertToXuiValue(pLinksetUse));
 -}
 -
 -LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::getEditLinksetUse() const
 -{
 -	return convertToLinksetUse(mEditLinksetUse->getValue());
 -}
 -
 -void LLFloaterPathfindingLinksets::setEditLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse)
 -{
 -	mEditLinksetUse->setValue(convertToXuiValue(pLinksetUse));
 -}
 -
 -LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::convertToLinksetUse(LLSD pXuiValue) const
 -{
 -	LLPathfindingLinkset::ELinksetUse linkUse;
 -
 -	switch (pXuiValue.asInteger())
 -	{
 -	case XUI_LINKSET_USE_NONE :
 -		linkUse = LLPathfindingLinkset::kUnknown;
 -		break;
 -	case XUI_LINKSET_USE_WALKABLE :
 -		linkUse = LLPathfindingLinkset::kWalkable;
 -		break;
 -	case XUI_LINKSET_USE_STATIC_OBSTACLE :
 -		linkUse = LLPathfindingLinkset::kStaticObstacle;
 -		break;
 -	case XUI_LINKSET_USE_DYNAMIC_OBSTACLE :
 -		linkUse = LLPathfindingLinkset::kDynamicObstacle;
 -		break;
 -	case XUI_LINKSET_USE_MATERIAL_VOLUME :
 -		linkUse = LLPathfindingLinkset::kMaterialVolume;
 -		break;
 -	case XUI_LINKSET_USE_EXCLUSION_VOLUME :
 -		linkUse = LLPathfindingLinkset::kExclusionVolume;
 -		break;
 -	case XUI_LINKSET_USE_DYNAMIC_PHANTOM :
 -		linkUse = LLPathfindingLinkset::kDynamicPhantom;
 -		break;
 -	default :
 -		linkUse = LLPathfindingLinkset::kUnknown;
 -		llassert(0);
 -		break;
 -	}
 -
 -	return linkUse;
 -}
 -
 -LLSD LLFloaterPathfindingLinksets::convertToXuiValue(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
 -{
 -	LLSD xuiValue;
 -
 -	switch (pLinksetUse)
 -	{
 -	case LLPathfindingLinkset::kUnknown :
 -		xuiValue = XUI_LINKSET_USE_NONE;
 -		break;
 -	case LLPathfindingLinkset::kWalkable :
 -		xuiValue = XUI_LINKSET_USE_WALKABLE;
 -		break;
 -	case LLPathfindingLinkset::kStaticObstacle :
 -		xuiValue = XUI_LINKSET_USE_STATIC_OBSTACLE;
 -		break;
 -	case LLPathfindingLinkset::kDynamicObstacle :
 -		xuiValue = XUI_LINKSET_USE_DYNAMIC_OBSTACLE;
 -		break;
 -	case LLPathfindingLinkset::kMaterialVolume :
 -		xuiValue = XUI_LINKSET_USE_MATERIAL_VOLUME;
 -		break;
 -	case LLPathfindingLinkset::kExclusionVolume :
 -		xuiValue = XUI_LINKSET_USE_EXCLUSION_VOLUME;
 -		break;
 -	case LLPathfindingLinkset::kDynamicPhantom :
 -		xuiValue = XUI_LINKSET_USE_DYNAMIC_PHANTOM;
 -		break;
 -	default :
 -		xuiValue = XUI_LINKSET_USE_NONE;
 -		llassert(0);
 -		break;
 -	}
 -
 -	return xuiValue;
 -}
 +/**  +* @file llfloaterpathfindinglinksets.cpp +* @author William Todd Stinson +* @brief "Pathfinding linksets" floater, allowing manipulation of the Havok AI pathfinding settings. +* +* $LicenseInfo:firstyear=2002&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2010, Linden Research, Inc. +*  +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +*  +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +* Lesser General Public License for more details. +*  +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA +*  +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" +#include "llfloater.h" +#include "llfloaterreg.h" +#include "llfloaterpathfindinglinksets.h" +#include "llsd.h" +#include "lluuid.h" +#include "v3math.h" +#include "lltextvalidate.h" +#include "llagent.h" +#include "lltextbase.h" +#include "lllineeditor.h" +#include "llscrolllistitem.h" +#include "llscrolllistctrl.h" +#include "llcombobox.h" +#include "llcheckboxctrl.h" +#include "llbutton.h" +#include "llresmgr.h" +#include "llviewerregion.h" +#include "llselectmgr.h" +#include "llviewermenu.h" +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "llpathfindinglinkset.h" +#include "llpathfindinglinksetlist.h" +#include "llpathfindingmanager.h" +#include "llnotificationsutil.h" +#include "llenvmanager.h" + +#include <boost/bind.hpp> +#include <boost/signals2.hpp> + +#define XUI_LINKSET_USE_NONE             0 +#define XUI_LINKSET_USE_WALKABLE         1 +#define XUI_LINKSET_USE_STATIC_OBSTACLE  2 +#define XUI_LINKSET_USE_DYNAMIC_OBSTACLE 3 +#define XUI_LINKSET_USE_MATERIAL_VOLUME  4 +#define XUI_LINKSET_USE_EXCLUSION_VOLUME 5 +#define XUI_LINKSET_USE_DYNAMIC_PHANTOM  6 + +//--------------------------------------------------------------------------- +// LLFloaterPathfindingLinksets +//--------------------------------------------------------------------------- + +BOOL LLFloaterPathfindingLinksets::postBuild() +{ +	childSetAction("apply_filters", boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this)); +	childSetAction("clear_filters", boost::bind(&LLFloaterPathfindingLinksets::onClearFiltersClicked, this)); + +	mFilterByName = findChild<LLLineEditor>("filter_by_name"); +	llassert(mFilterByName != NULL); +	mFilterByName->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this)); +	mFilterByName->setSelectAllonFocusReceived(true); +	mFilterByName->setCommitOnFocusLost(true); + +	mFilterByDescription = findChild<LLLineEditor>("filter_by_description"); +	llassert(mFilterByDescription != NULL); +	mFilterByDescription->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this)); +	mFilterByDescription->setSelectAllonFocusReceived(true); +	mFilterByDescription->setCommitOnFocusLost(true); + +	mFilterByLinksetUse = findChild<LLComboBox>("filter_by_linkset_use"); +	llassert(mFilterByLinksetUse != NULL); +	mFilterByLinksetUse->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this)); + +	mLinksetsScrollList = findChild<LLScrollListCtrl>("pathfinding_linksets"); +	llassert(mLinksetsScrollList != NULL); +	mLinksetsScrollList->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onLinksetsSelectionChange, this)); +	mLinksetsScrollList->sortByColumnIndex(0, true); + +	mLinksetsStatus = findChild<LLTextBase>("linksets_status"); +	llassert(mLinksetsStatus != NULL); + +	mRefreshListButton = findChild<LLButton>("refresh_linksets_list"); +	llassert(mRefreshListButton != NULL); +	mRefreshListButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onRefreshLinksetsClicked, this)); + +	mSelectAllButton = findChild<LLButton>("select_all_linksets"); +	llassert(mSelectAllButton != NULL); +	mSelectAllButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onSelectAllLinksetsClicked, this)); + +	mSelectNoneButton = findChild<LLButton>("select_none_linksets"); +	llassert(mSelectNoneButton != NULL); +	mSelectNoneButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onSelectNoneLinksetsClicked, this)); + +	mShowBeaconCheckBox = findChild<LLCheckBoxCtrl>("show_beacon"); +	llassert(mShowBeaconCheckBox != NULL); + +	mTakeButton = findChild<LLButton>("take_linksets"); +	llassert(mTakeButton != NULL); +	mTakeButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onTakeClicked, this)); + +	mTakeCopyButton = findChild<LLButton>("take_copy_linksets"); +	llassert(mTakeCopyButton != NULL); +	mTakeCopyButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onTakeCopyClicked, this)); + +	mReturnButton = findChild<LLButton>("return_linksets"); +	llassert(mReturnButton != NULL); +	mReturnButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onReturnClicked, this)); + +	mDeleteButton = findChild<LLButton>("delete_linksets"); +	llassert(mDeleteButton != NULL); +	mDeleteButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onDeleteClicked, this)); + +	mTeleportButton = findChild<LLButton>("teleport_me_to_linkset"); +	llassert(mTeleportButton != NULL); +	mTeleportButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onTeleportClicked, this)); + +	mEditLinksetUse = findChild<LLComboBox>("edit_linkset_use"); +	llassert(mEditLinksetUse != NULL); + +	mEditLinksetUse->clearRows(); + +	mEditLinksetUseUnset = mEditLinksetUse->addElement(buildLinksetUseScrollListElement(getString("linkset_choose_use"), XUI_LINKSET_USE_NONE)); +	llassert(mEditLinksetUseUnset != NULL); + +	mEditLinksetUseWalkable = mEditLinksetUse->addElement(buildLinksetUseScrollListElement(getLinksetUseString(LLPathfindingLinkset::kWalkable), XUI_LINKSET_USE_WALKABLE)); +	llassert(mEditLinksetUseWalkable != NULL); + +	mEditLinksetUseStaticObstacle = mEditLinksetUse->addElement(buildLinksetUseScrollListElement(getLinksetUseString(LLPathfindingLinkset::kStaticObstacle), XUI_LINKSET_USE_STATIC_OBSTACLE)); +	llassert(mEditLinksetUseStaticObstacle != NULL); + +	mEditLinksetUseDynamicObstacle = mEditLinksetUse->addElement(buildLinksetUseScrollListElement(getLinksetUseString(LLPathfindingLinkset::kDynamicObstacle), XUI_LINKSET_USE_DYNAMIC_OBSTACLE)); +	llassert(mEditLinksetUseDynamicObstacle != NULL); + +	mEditLinksetUseMaterialVolume = mEditLinksetUse->addElement(buildLinksetUseScrollListElement(getLinksetUseString(LLPathfindingLinkset::kMaterialVolume), XUI_LINKSET_USE_MATERIAL_VOLUME)); +	llassert(mEditLinksetUseMaterialVolume != NULL); + +	mEditLinksetUseExclusionVolume = mEditLinksetUse->addElement(buildLinksetUseScrollListElement(getLinksetUseString(LLPathfindingLinkset::kExclusionVolume), XUI_LINKSET_USE_EXCLUSION_VOLUME)); +	llassert(mEditLinksetUseExclusionVolume != NULL); + +	mEditLinksetUseDynamicPhantom = mEditLinksetUse->addElement(buildLinksetUseScrollListElement(getLinksetUseString(LLPathfindingLinkset::kDynamicPhantom), XUI_LINKSET_USE_DYNAMIC_PHANTOM)); +	llassert(mEditLinksetUseDynamicPhantom != NULL); + +	mEditLinksetUse->selectFirstItem(); + +	mLabelWalkabilityCoefficients = findChild<LLTextBase>("walkability_coefficients_label"); +	llassert(mLabelWalkabilityCoefficients != NULL); + +	mLabelEditA = findChild<LLTextBase>("edit_a_label"); +	llassert(mLabelEditA != NULL); + +	mEditA = findChild<LLLineEditor>("edit_a_value"); +	llassert(mEditA != NULL); +	mEditA->setPrevalidate(LLTextValidate::validateNonNegativeS32); +	mEditA->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1)); + +	mLabelEditB = findChild<LLTextBase>("edit_b_label"); +	llassert(mLabelEditB != NULL); + +	mEditB = findChild<LLLineEditor>("edit_b_value"); +	llassert(mEditB != NULL); +	mEditB->setPrevalidate(LLTextValidate::validateNonNegativeS32); +	mEditB->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1)); + +	mLabelEditC = findChild<LLTextBase>("edit_c_label"); +	llassert(mLabelEditC != NULL); + +	mEditC = findChild<LLLineEditor>("edit_c_value"); +	llassert(mEditC != NULL); +	mEditC->setPrevalidate(LLTextValidate::validateNonNegativeS32); +	mEditC->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1)); + +	mLabelEditD = findChild<LLTextBase>("edit_d_label"); +	llassert(mLabelEditD != NULL); + +	mEditD = findChild<LLLineEditor>("edit_d_value"); +	llassert(mEditD != NULL); +	mEditD->setPrevalidate(LLTextValidate::validateNonNegativeS32); +	mEditD->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1)); + +	mApplyEditsButton = findChild<LLButton>("apply_edit_values"); +	llassert(mApplyEditsButton != NULL); +	mApplyEditsButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyChangesClicked, this)); + +	return LLFloater::postBuild(); +} + +void LLFloaterPathfindingLinksets::onOpen(const LLSD& pKey) +{ +	LLFloater::onOpen(pKey); + +	requestGetLinksets(); +	selectNoneLinksets(); +	mLinksetsScrollList->setCommitOnSelectionChange(true); + +	if (!mAgentStateSlot.connected()) +	{ +		mAgentStateSlot = LLPathfindingManager::getInstance()->registerAgentStateListener(boost::bind(&LLFloaterPathfindingLinksets::onAgentStateCB, this, _1)); +	} + +	if (!mSelectionUpdateSlot.connected()) +	{ +		mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterPathfindingLinksets::updateControls, this)); +	} + +	if (!mRegionBoundarySlot.connected()) +	{ +		mRegionBoundarySlot = LLEnvManagerNew::instance().setRegionChangeCallback(boost::bind(&LLFloaterPathfindingLinksets::onRegionBoundaryCross, this)); +	} +} + +void LLFloaterPathfindingLinksets::onClose(bool pAppQuitting) +{ +	if (mRegionBoundarySlot.connected()) +	{ +		mRegionBoundarySlot.disconnect(); +	} + +	if (mSelectionUpdateSlot.connected()) +	{ +		mSelectionUpdateSlot.disconnect(); +	} + +	if (mAgentStateSlot.connected()) +	{ +		mAgentStateSlot.disconnect(); +	} + +	mLinksetsScrollList->setCommitOnSelectionChange(false); +	selectNoneLinksets(); +	if (mLinksetsSelection.notNull()) +	{ +		mLinksetsSelection.clear(); +	} + +	LLFloater::onClose(pAppQuitting); +} + +void LLFloaterPathfindingLinksets::draw() +{ +	if (mShowBeaconCheckBox->get()) +	{ +		std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected(); +		if (!selectedItems.empty()) +		{ +			int numSelectedItems = selectedItems.size(); + +			std::vector<LLViewerObject *> viewerObjects; +			viewerObjects.reserve(numSelectedItems); + +			for (std::vector<LLScrollListItem*>::const_iterator selectedItemIter = selectedItems.begin(); +				selectedItemIter != selectedItems.end(); ++selectedItemIter) +			{ +				const LLScrollListItem *selectedItem = *selectedItemIter; + +				LLViewerObject *viewerObject = gObjectList.findObject(selectedItem->getUUID()); +				if (viewerObject != NULL) +				{ +					const std::string &objectName = selectedItem->getColumn(0)->getValue().asString(); +					gObjectList.addDebugBeacon(viewerObject->getPositionAgent(), objectName, LLColor4(0.f, 0.f, 1.f, 0.8f), LLColor4(1.f, 1.f, 1.f, 1.f), 6); +				} +			} +		} +	} + +	LLFloater::draw(); +} + +void LLFloaterPathfindingLinksets::openLinksetsEditor() +{ +	LLFloaterReg::toggleInstanceOrBringToFront("pathfinding_linksets"); +} + +LLFloaterPathfindingLinksets::LLFloaterPathfindingLinksets(const LLSD& pSeed) +	: LLFloater(pSeed), +	mFilterByName(NULL), +	mFilterByDescription(NULL), +	mFilterByLinksetUse(NULL), +	mLinksetsScrollList(NULL), +	mLinksetsStatus(NULL), +	mRefreshListButton(NULL), +	mSelectAllButton(NULL), +	mSelectNoneButton(NULL), +	mShowBeaconCheckBox(NULL), +	mTakeButton(NULL), +	mTakeCopyButton(NULL), +	mReturnButton(NULL), +	mDeleteButton(NULL), +	mTeleportButton(NULL), +	mEditLinksetUse(NULL), +	mLabelWalkabilityCoefficients(NULL), +	mLabelEditA(NULL), +	mEditA(NULL), +	mLabelEditB(NULL), +	mEditB(NULL), +	mLabelEditC(NULL), +	mEditC(NULL), +	mLabelEditD(NULL), +	mEditD(NULL), +	mApplyEditsButton(NULL), +	mMessagingState(kMessagingUnknown), +	mMessagingRequestId(0U), +	mLinksetsListPtr(), +	mLinksetsSelection(), +	mAgentStateSlot(), +	mSelectionUpdateSlot() +{ +} + +LLFloaterPathfindingLinksets::~LLFloaterPathfindingLinksets() +{ +} + +LLFloaterPathfindingLinksets::EMessagingState LLFloaterPathfindingLinksets::getMessagingState() const +{ +	return mMessagingState; +} + +void LLFloaterPathfindingLinksets::setMessagingState(EMessagingState pMessagingState) +{ +	mMessagingState = pMessagingState; +	updateControls(); +} + +void LLFloaterPathfindingLinksets::requestGetLinksets() +{ +	switch (LLPathfindingManager::getInstance()->requestGetLinksets(++mMessagingRequestId, boost::bind(&LLFloaterPathfindingLinksets::handleNewLinksets, this, _1, _2, _3))) +	{ +	case LLPathfindingManager::kRequestStarted : +		setMessagingState(kMessagingGetRequestSent); +		break; +	case LLPathfindingManager::kRequestCompleted : +		clearLinksets(); +		setMessagingState(kMessagingComplete); +		break; +	case LLPathfindingManager::kRequestNotEnabled : +		clearLinksets(); +		setMessagingState(kMessagingNotEnabled); +		break; +	case LLPathfindingManager::kRequestError : +		setMessagingState(kMessagingGetError); +		break; +	default : +		setMessagingState(kMessagingGetError); +		llassert(0); +		break; +	} +} + +void LLFloaterPathfindingLinksets::requestSetLinksets(LLPathfindingLinksetListPtr pLinksetList, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) +{ +	switch (LLPathfindingManager::getInstance()->requestSetLinksets(++mMessagingRequestId, pLinksetList, pLinksetUse, pA, pB, pC, pD, boost::bind(&LLFloaterPathfindingLinksets::handleUpdateLinksets, this, _1, _2, _3))) +	{ +	case LLPathfindingManager::kRequestStarted : +		setMessagingState(kMessagingSetRequestSent); +		break; +	case LLPathfindingManager::kRequestCompleted : +		setMessagingState(kMessagingComplete); +		break; +	case LLPathfindingManager::kRequestNotEnabled : +		clearLinksets(); +		setMessagingState(kMessagingNotEnabled); +		break; +	case LLPathfindingManager::kRequestError : +		setMessagingState(kMessagingSetError); +		break; +	default : +		setMessagingState(kMessagingSetError); +		llassert(0); +		break; +	} +} + +void LLFloaterPathfindingLinksets::handleNewLinksets(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pLinksetsRequestStatus, LLPathfindingLinksetListPtr pLinksetsListPtr) +{ +	llassert(pRequestId <= mMessagingRequestId); +	if (pRequestId == mMessagingRequestId) +	{ +		mLinksetsListPtr = pLinksetsListPtr; +		updateScrollList(); + +		switch (pLinksetsRequestStatus) +		{ +		case LLPathfindingManager::kRequestCompleted : +			setMessagingState(kMessagingComplete); +			break; +		case LLPathfindingManager::kRequestError : +			setMessagingState(kMessagingGetError); +			break; +		default : +			setMessagingState(kMessagingGetError); +			llassert(0); +			break; +		} +	} +} + +void LLFloaterPathfindingLinksets::handleUpdateLinksets(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pLinksetsRequestStatus, LLPathfindingLinksetListPtr pLinksetsListPtr) +{ +	llassert(pRequestId <= mMessagingRequestId); +	if (pRequestId == mMessagingRequestId) +	{ +		if (mLinksetsListPtr == NULL) +		{ +			mLinksetsListPtr = pLinksetsListPtr; +		} +		else +		{ +			mLinksetsListPtr->update(*pLinksetsListPtr); +		} +		updateScrollList(); + +		switch (pLinksetsRequestStatus) +		{ +		case LLPathfindingManager::kRequestCompleted : +			setMessagingState(kMessagingComplete); +			break; +		case LLPathfindingManager::kRequestError : +			setMessagingState(kMessagingSetError); +			break; +		default : +			setMessagingState(kMessagingSetError); +			llassert(0); +			break; +		} +	} +} + +void LLFloaterPathfindingLinksets::onApplyAllFilters() +{ +	applyFilters(); +} + +void LLFloaterPathfindingLinksets::onClearFiltersClicked() +{ +	clearFilters(); +} + +void LLFloaterPathfindingLinksets::onLinksetsSelectionChange() +{ +	mLinksetsSelection.clear(); +	LLSelectMgr::getInstance()->deselectAll(); + +	std::vector<LLScrollListItem *> selectedItems = mLinksetsScrollList->getAllSelected(); +	if (!selectedItems.empty()) +	{ +		int numSelectedItems = selectedItems.size(); + +		std::vector<LLViewerObject *>viewerObjects; +		viewerObjects.reserve(numSelectedItems); + +		for (std::vector<LLScrollListItem *>::const_iterator selectedItemIter = selectedItems.begin(); +			selectedItemIter != selectedItems.end(); ++selectedItemIter) +		{ +			const LLScrollListItem *selectedItem = *selectedItemIter; + +			LLViewerObject *viewerObject = gObjectList.findObject(selectedItem->getUUID()); +			if (viewerObject != NULL) +			{ +				viewerObjects.push_back(viewerObject); +			} +		} + +		if (!viewerObjects.empty()) +		{ +			mLinksetsSelection = LLSelectMgr::getInstance()->selectObjectAndFamily(viewerObjects); +		} +	} + +	updateEditFieldValues(); +	updateControls(); +} + +void LLFloaterPathfindingLinksets::onRefreshLinksetsClicked() +{ +	requestGetLinksets(); +} + +void LLFloaterPathfindingLinksets::onSelectAllLinksetsClicked() +{ +	selectAllLinksets(); +} + +void LLFloaterPathfindingLinksets::onSelectNoneLinksetsClicked() +{ +	selectNoneLinksets(); +} + +void LLFloaterPathfindingLinksets::onTakeClicked() +{ +	handle_take(); +} + +void LLFloaterPathfindingLinksets::onTakeCopyClicked() +{ +	handle_take_copy(); +} + +void LLFloaterPathfindingLinksets::onReturnClicked() +{ +	handle_object_return(); +} + +void LLFloaterPathfindingLinksets::onDeleteClicked() +{ +	handle_object_delete(); +} + +void LLFloaterPathfindingLinksets::onTeleportClicked() +{ +	std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected(); +	llassert(selectedItems.size() == 1); +	if (selectedItems.size() == 1) +	{ +		std::vector<LLScrollListItem*>::const_reference selectedItemRef = selectedItems.front(); +		const LLScrollListItem *selectedItem = selectedItemRef; +		llassert(mLinksetsListPtr != NULL); +		LLPathfindingLinksetList::const_iterator linksetIter = mLinksetsListPtr->find(selectedItem->getUUID().asString()); +		const LLPathfindingLinksetPtr linksetPtr = linksetIter->second; +		const LLVector3 &linksetLocation = linksetPtr->getLocation(); + +		LLViewerRegion* region = gAgent.getRegion(); +		if (region != NULL) +		{ +			gAgent.teleportRequest(region->getHandle(), linksetLocation, true); +		} +	} +} + +void LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered(LLUICtrl *pUICtrl) +{ +	LLLineEditor *pLineEditor = static_cast<LLLineEditor *>(pUICtrl); +	llassert(pLineEditor != NULL); + +	const std::string &valueString = pLineEditor->getText(); +	S32 value = static_cast<S32>(atoi(valueString.c_str())); + +	if ((value < LLPathfindingLinkset::MIN_WALKABILITY_VALUE) || (value > LLPathfindingLinkset::MAX_WALKABILITY_VALUE)) +	{ +		value = llclamp(value, LLPathfindingLinkset::MIN_WALKABILITY_VALUE, LLPathfindingLinkset::MAX_WALKABILITY_VALUE); +		pLineEditor->setValue(LLSD(value)); +	} +} + +void LLFloaterPathfindingLinksets::onApplyChangesClicked() +{ +	applyEdit(); +} + +void LLFloaterPathfindingLinksets::onAgentStateCB(LLPathfindingManager::EAgentState pAgentState) +{ +	updateControls(); +} + +void LLFloaterPathfindingLinksets::onRegionBoundaryCross() +{ +	requestGetLinksets(); +} + +void LLFloaterPathfindingLinksets::applyFilters() +{ +	updateScrollList(); +} + +void LLFloaterPathfindingLinksets::clearFilters() +{ +	mFilterByName->clear(); +	mFilterByDescription->clear(); +	setFilterLinksetUse(LLPathfindingLinkset::kUnknown); +	updateScrollList(); +} + +void LLFloaterPathfindingLinksets::selectAllLinksets() +{ +	mLinksetsScrollList->selectAll(); +} + +void LLFloaterPathfindingLinksets::selectNoneLinksets() +{ +	mLinksetsScrollList->deselectAllItems(); +} + +void LLFloaterPathfindingLinksets::clearLinksets() +{ +	if (mLinksetsListPtr != NULL) +	{ +		mLinksetsListPtr->clear(); +	} +	updateScrollList(); +} + +void LLFloaterPathfindingLinksets::updateControls() +{ +	updateStatusMessage(); +	updateEnableStateOnListActions(); +	updateEnableStateOnEditFields(); +} + +void LLFloaterPathfindingLinksets::updateEditFieldValues() +{ +	std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected(); +	int numSelectedItems = selectedItems.size(); +	if (numSelectedItems <= 0) +	{ +		mEditLinksetUse->selectFirstItem(); +		mEditA->clear(); +		mEditB->clear(); +		mEditC->clear(); +		mEditD->clear(); +	} +	else +	{ +		LLScrollListItem *firstItem = selectedItems.front(); + +		llassert(mLinksetsListPtr != NULL); +		LLPathfindingLinksetList::const_iterator linksetIter = mLinksetsListPtr->find(firstItem->getUUID().asString()); +		const LLPathfindingLinksetPtr linksetPtr(linksetIter->second); + +		setEditLinksetUse(linksetPtr->getLinksetUse()); +		mEditA->setValue(LLSD(linksetPtr->getWalkabilityCoefficientA())); +		mEditB->setValue(LLSD(linksetPtr->getWalkabilityCoefficientB())); +		mEditC->setValue(LLSD(linksetPtr->getWalkabilityCoefficientC())); +		mEditD->setValue(LLSD(linksetPtr->getWalkabilityCoefficientD())); +		updateEnableStateOnEditLinksetUse(); +	} +} + +void LLFloaterPathfindingLinksets::updateScrollList() +{ +	std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected(); +	int numSelectedItems = selectedItems.size(); +	uuid_vec_t selectedUUIDs; +	if (numSelectedItems > 0) +	{ +		selectedUUIDs.reserve(selectedItems.size()); +		for (std::vector<LLScrollListItem*>::const_iterator itemIter = selectedItems.begin(); +			itemIter != selectedItems.end(); ++itemIter) +		{ +			const LLScrollListItem *listItem = *itemIter; +			selectedUUIDs.push_back(listItem->getUUID()); +		} +	} + +	S32 origScrollPosition = mLinksetsScrollList->getScrollPos(); +	mLinksetsScrollList->deleteAllItems(); + +	if (mLinksetsListPtr != NULL) +	{ +		std::string nameFilter = mFilterByName->getText(); +		std::string descriptionFilter = mFilterByDescription->getText(); +		LLPathfindingLinkset::ELinksetUse linksetUseFilter = getFilterLinksetUse(); +		bool isFilteringName = !nameFilter.empty(); +		bool isFilteringDescription = !descriptionFilter.empty(); +		bool isFilteringLinksetUse = (linksetUseFilter != LLPathfindingLinkset::kUnknown); + +		const LLVector3& avatarPosition = gAgent.getPositionAgent(); + +		if (isFilteringName || isFilteringDescription || isFilteringLinksetUse) +		{ +			LLStringUtil::toUpper(nameFilter); +			LLStringUtil::toUpper(descriptionFilter); +			for (LLPathfindingLinksetList::const_iterator linksetIter = mLinksetsListPtr->begin(); +				linksetIter != mLinksetsListPtr->end(); ++linksetIter) +			{ +				const LLPathfindingLinksetPtr linksetPtr(linksetIter->second); +				std::string linksetName = (linksetPtr->isTerrain() ? getString("linkset_terrain_name") : linksetPtr->getName()); +				std::string linksetDescription = linksetPtr->getDescription(); +				LLStringUtil::toUpper(linksetName); +				LLStringUtil::toUpper(linksetDescription); +				if ((!isFilteringName || (linksetName.find(nameFilter) != std::string::npos)) && +					(!isFilteringDescription || (linksetDescription.find(descriptionFilter) != std::string::npos)) && +					(!isFilteringLinksetUse || (linksetPtr->getLinksetUse() == linksetUseFilter))) +				{ +					LLSD element = buildLinksetScrollListElement(linksetPtr, avatarPosition); +					mLinksetsScrollList->addElement(element); +				} +			} +		} +		else +		{ +			for (LLPathfindingLinksetList::const_iterator linksetIter = mLinksetsListPtr->begin(); +				linksetIter != mLinksetsListPtr->end(); ++linksetIter) +			{ +				const LLPathfindingLinksetPtr linksetPtr(linksetIter->second); +				LLSD element = buildLinksetScrollListElement(linksetPtr, avatarPosition); +				mLinksetsScrollList->addElement(element); +			} +		} +	} + +	mLinksetsScrollList->selectMultiple(selectedUUIDs); +	mLinksetsScrollList->setScrollPos(origScrollPosition); +	updateEditFieldValues(); +	updateControls(); +} + +LLSD LLFloaterPathfindingLinksets::buildLinksetScrollListElement(const LLPathfindingLinksetPtr pLinksetPtr, const LLVector3 &pAvatarPosition) const +{ +	LLSD columns; + +	if (pLinksetPtr->isTerrain()) +	{ +		columns[0]["column"] = "name"; +		columns[0]["value"] = getString("linkset_terrain_name"); +		columns[0]["font"] = "SANSSERIF"; + +		columns[1]["column"] = "description"; +		columns[1]["value"] = getString("linkset_terrain_description"); +		columns[1]["font"] = "SANSSERIF"; + +		columns[2]["column"] = "land_impact"; +		columns[2]["value"] = getString("linkset_terrain_land_impact"); +		columns[2]["font"] = "SANSSERIF"; + +		columns[3]["column"] = "dist_from_you"; +		columns[3]["value"] = getString("linkset_terrain_dist_from_you"); +		columns[3]["font"] = "SANSSERIF"; +	} +	else +	{ +		columns[0]["column"] = "name"; +		columns[0]["value"] = pLinksetPtr->getName(); +		columns[0]["font"] = "SANSSERIF"; + +		columns[1]["column"] = "description"; +		columns[1]["value"] = pLinksetPtr->getDescription(); +		columns[1]["font"] = "SANSSERIF"; + +		columns[2]["column"] = "land_impact"; +		columns[2]["value"] = llformat("%1d", pLinksetPtr->getLandImpact()); +		columns[2]["font"] = "SANSSERIF"; + +		columns[3]["column"] = "dist_from_you"; +		columns[3]["value"] = llformat("%1.0f m", dist_vec(pAvatarPosition, pLinksetPtr->getLocation())); +		columns[3]["font"] = "SANSSERIF"; +	} + +	columns[4]["column"] = "linkset_use"; +	std::string linksetUse = getLinksetUseString(pLinksetPtr->getLinksetUse()); +	if (pLinksetPtr->isTerrain()) +	{ +		linksetUse += (" " + getString("linkset_is_terrain")); +	} +	else if (!pLinksetPtr->isModifiable() && pLinksetPtr->canBeVolume()) +	{ +		linksetUse += (" " + getString("linkset_is_restricted_state")); +	} +	else if (pLinksetPtr->isModifiable() && !pLinksetPtr->canBeVolume()) +	{ +		linksetUse += (" " + getString("linkset_is_non_volume_state")); +	} +	else if (!pLinksetPtr->isModifiable() && !pLinksetPtr->canBeVolume()) +	{ +		linksetUse += (" " + getString("linkset_is_restricted_non_volume_state")); +	} +	columns[4]["value"] = linksetUse; +	columns[4]["font"] = "SANSSERIF"; + +	columns[5]["column"] = "a_percent"; +	columns[5]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientA()); +	columns[5]["font"] = "SANSSERIF"; + +	columns[6]["column"] = "b_percent"; +	columns[6]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientB()); +	columns[6]["font"] = "SANSSERIF"; + +	columns[7]["column"] = "c_percent"; +	columns[7]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientC()); +	columns[7]["font"] = "SANSSERIF"; + +	columns[8]["column"] = "d_percent"; +	columns[8]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientD()); +	columns[8]["font"] = "SANSSERIF"; + +	LLSD element; +	element["id"] = pLinksetPtr->getUUID().asString(); +	element["column"] = columns; + +	return element; +} + +LLSD LLFloaterPathfindingLinksets::buildLinksetUseScrollListElement(const std::string &label, S32 value) const +{ +	LLSD columns; + +	columns[0]["column"] = "name"; +	columns[0]["relwidth"] = static_cast<LLSD::Real>(100.0f); +	columns[0]["value"] = label; +	columns[0]["font"] = "SANSSERIF"; + +	LLSD element; +	element["value"] = value; +	element["column"] = columns; + +	return element; +} + +bool LLFloaterPathfindingLinksets::isShowUnmodifiablePhantomWarning(LLPathfindingLinkset::ELinksetUse linksetUse) const +{ +	bool showWarning = false; + +	if (linksetUse != LLPathfindingLinkset::kUnknown) +	{ +		std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected(); +		if (!selectedItems.empty()) +		{ +			for (std::vector<LLScrollListItem*>::const_iterator selectedItemIter = selectedItems.begin(); +				!showWarning && (selectedItemIter != selectedItems.end()); ++selectedItemIter) +			{ +				const LLScrollListItem *selectedItem = *selectedItemIter; +				llassert(mLinksetsListPtr != NULL); +				LLPathfindingLinksetList::const_iterator linksetIter = mLinksetsListPtr->find(selectedItem->getUUID().asString()); +				llassert(linksetIter != mLinksetsListPtr->end()); +				const LLPathfindingLinksetPtr linksetPtr = linksetIter->second; +				showWarning = linksetPtr->isShowUnmodifiablePhantomWarning(linksetUse); +			} +		} +	} + +	return showWarning; +} + +bool LLFloaterPathfindingLinksets::isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse linksetUse) const +{ +	bool showWarning = false; + +	if (linksetUse != LLPathfindingLinkset::kUnknown) +	{ +		std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected(); +		if (!selectedItems.empty()) +		{ +			for (std::vector<LLScrollListItem*>::const_iterator selectedItemIter = selectedItems.begin(); +				!showWarning && (selectedItemIter != selectedItems.end()); ++selectedItemIter) +			{ +				const LLScrollListItem *selectedItem = *selectedItemIter; +				llassert(mLinksetsListPtr != NULL); +				LLPathfindingLinksetList::const_iterator linksetIter = mLinksetsListPtr->find(selectedItem->getUUID().asString()); +				llassert(linksetIter != mLinksetsListPtr->end()); +				const LLPathfindingLinksetPtr linksetPtr = linksetIter->second; +				showWarning = linksetPtr->isShowCannotBeVolumeWarning(linksetUse); +			} +		} +	} + +	return showWarning; +} + +void LLFloaterPathfindingLinksets::updateStatusMessage() +{ +	static const LLColor4 errorColor = LLUIColorTable::instance().getColor("PathfindingErrorColor"); +	static const LLColor4 warningColor = LLUIColorTable::instance().getColor("PathfindingWarningColor"); + +	std::string statusText(""); +	LLStyle::Params styleParams; + +	switch (getMessagingState()) +	{ +	case kMessagingUnknown: +		statusText = getString("linksets_messaging_initial"); +		styleParams.color = errorColor; +		break; +	case kMessagingGetRequestSent : +		statusText = getString("linksets_messaging_get_inprogress"); +		styleParams.color = warningColor; +		break; +	case kMessagingGetError : +		statusText = getString("linksets_messaging_get_error"); +		styleParams.color = errorColor; +		break; +	case kMessagingSetRequestSent : +		statusText = getString("linksets_messaging_set_inprogress"); +		styleParams.color = warningColor; +		break; +	case kMessagingSetError : +		statusText = getString("linksets_messaging_set_error"); +		styleParams.color = errorColor; +		break; +	case kMessagingComplete : +		if (mLinksetsScrollList->isEmpty()) +		{ +			statusText = getString("linksets_messaging_complete_none_found"); +		} +		else +		{ +			S32 numItems = mLinksetsScrollList->getItemCount(); +			S32 numSelectedItems = mLinksetsScrollList->getNumSelected(); + +			LLLocale locale(LLStringUtil::getLocale()); +			std::string numItemsString; +			LLResMgr::getInstance()->getIntegerString(numItemsString, numItems); + +			std::string numSelectedItemsString; +			LLResMgr::getInstance()->getIntegerString(numSelectedItemsString, numSelectedItems); + +			LLStringUtil::format_map_t string_args; +			string_args["[NUM_SELECTED]"] = numSelectedItemsString; +			string_args["[NUM_TOTAL]"] = numItemsString; +			statusText = getString("linksets_messaging_complete_available", string_args); +		} +		break; +	case kMessagingNotEnabled : +		statusText = getString("linksets_messaging_not_enabled"); +		styleParams.color = errorColor; +		break; +	default: +		statusText = getString("linksets_messaging_initial"); +		styleParams.color = errorColor; +		llassert(0); +		break; +	} + +	mLinksetsStatus->setText((LLStringExplicit)statusText, styleParams); +} + +void LLFloaterPathfindingLinksets::updateEnableStateOnListActions() +{ +	switch (getMessagingState()) +	{ +	case kMessagingUnknown: +	case kMessagingGetRequestSent : +	case kMessagingSetRequestSent : +		mRefreshListButton->setEnabled(FALSE); +		mSelectAllButton->setEnabled(FALSE); +		mSelectNoneButton->setEnabled(FALSE); +		break; +	case kMessagingGetError : +	case kMessagingSetError : +	case kMessagingNotEnabled : +		mRefreshListButton->setEnabled(TRUE); +		mSelectAllButton->setEnabled(FALSE); +		mSelectNoneButton->setEnabled(FALSE); +		break; +	case kMessagingComplete : +		{ +			int numItems = mLinksetsScrollList->getItemCount(); +			int numSelectedItems = mLinksetsScrollList->getNumSelected(); +			mRefreshListButton->setEnabled(TRUE); +			mSelectAllButton->setEnabled(numSelectedItems < numItems); +			mSelectNoneButton->setEnabled(numSelectedItems > 0); +		} +		break; +	default: +		llassert(0); +		break; +	} +} + +void LLFloaterPathfindingLinksets::updateEnableStateOnEditFields() +{ +	int numSelectedItems = mLinksetsScrollList->getNumSelected(); +	bool isEditEnabled = ((numSelectedItems > 0) && LLPathfindingManager::getInstance()->isAllowAlterPermanent()); + +	mShowBeaconCheckBox->setEnabled(numSelectedItems > 0); +	mTakeButton->setEnabled(isEditEnabled && visible_take_object()); +	mTakeCopyButton->setEnabled(isEditEnabled && enable_object_take_copy()); +	mReturnButton->setEnabled(isEditEnabled && enable_object_return()); +	mDeleteButton->setEnabled(isEditEnabled && enable_object_delete()); +	mTeleportButton->setEnabled(numSelectedItems == 1); + +	mEditLinksetUse->setEnabled(isEditEnabled); + +	mLabelWalkabilityCoefficients->setEnabled(isEditEnabled); +	mLabelEditA->setEnabled(isEditEnabled); +	mLabelEditB->setEnabled(isEditEnabled); +	mLabelEditC->setEnabled(isEditEnabled); +	mLabelEditD->setEnabled(isEditEnabled); +	mEditA->setEnabled(isEditEnabled); +	mEditB->setEnabled(isEditEnabled); +	mEditC->setEnabled(isEditEnabled); +	mEditD->setEnabled(isEditEnabled); + +	mApplyEditsButton->setEnabled(isEditEnabled && (getMessagingState() == kMessagingComplete)); +} + +void LLFloaterPathfindingLinksets::updateEnableStateOnEditLinksetUse() +{ +	BOOL useWalkable = FALSE; +	BOOL useStaticObstacle = FALSE; +	BOOL useDynamicObstacle = FALSE; +	BOOL useMaterialVolume = FALSE; +	BOOL useExclusionVolume = FALSE; +	BOOL useDynamicPhantom = FALSE; + +	std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected(); +	if (!selectedItems.empty()) +	{ +		for (std::vector<LLScrollListItem*>::const_iterator selectedItemIter = selectedItems.begin(); +			!(useWalkable && useStaticObstacle && useDynamicObstacle && useMaterialVolume && useExclusionVolume && useDynamicPhantom) && (selectedItemIter != selectedItems.end()); +			++selectedItemIter) +		{ +			const LLScrollListItem *selectedItem = *selectedItemIter; +			llassert(mLinksetsListPtr != NULL); +			LLPathfindingLinksetList::const_iterator linksetIter = mLinksetsListPtr->find(selectedItem->getUUID().asString()); +			llassert(linksetIter != mLinksetsListPtr->end()); +			const LLPathfindingLinksetPtr linksetPtr = linksetIter->second; + +			if (linksetPtr->isTerrain()) +			{ +				useWalkable = TRUE; +			} +			else +			{ +				if (linksetPtr->isModifiable()) +				{ +					useWalkable = TRUE; +					useStaticObstacle = TRUE; +					useDynamicObstacle = TRUE; +					useDynamicPhantom = TRUE; +					if (linksetPtr->canBeVolume()) +					{ +						useMaterialVolume = TRUE; +						useExclusionVolume = TRUE; +					} +				} +				else if (linksetPtr->isPhantom()) +				{ +					useDynamicPhantom = TRUE; +					if (linksetPtr->canBeVolume()) +					{ +						useMaterialVolume = TRUE; +						useExclusionVolume = TRUE; +					} +				} +				else +				{ +					useWalkable = TRUE; +					useStaticObstacle = TRUE; +					useDynamicObstacle = TRUE; +				} +			} +		} +	} + +	mEditLinksetUseWalkable->setEnabled(useWalkable); +	mEditLinksetUseStaticObstacle->setEnabled(useStaticObstacle); +	mEditLinksetUseDynamicObstacle->setEnabled(useDynamicObstacle); +	mEditLinksetUseMaterialVolume->setEnabled(useMaterialVolume); +	mEditLinksetUseExclusionVolume->setEnabled(useExclusionVolume); +	mEditLinksetUseDynamicPhantom->setEnabled(useDynamicPhantom); +} + +void LLFloaterPathfindingLinksets::applyEdit() +{ +	LLPathfindingLinkset::ELinksetUse linksetUse = getEditLinksetUse(); + +	bool showUnmodifiablePhantomWarning = isShowUnmodifiablePhantomWarning(linksetUse); +	bool showCannotBeVolumeWarning = isShowCannotBeVolumeWarning(linksetUse); + +	if (showUnmodifiablePhantomWarning || showCannotBeVolumeWarning) +	{ +		LLPathfindingLinkset::ELinksetUse restrictedLinksetUse = LLPathfindingLinkset::getLinksetUseWithToggledPhantom(linksetUse); +		LLSD substitutions; +		substitutions["REQUESTED_TYPE"] = getLinksetUseString(linksetUse); +		substitutions["RESTRICTED_TYPE"] = getLinksetUseString(restrictedLinksetUse); + +		std::string notificationName; +		if (showUnmodifiablePhantomWarning && showCannotBeVolumeWarning) +		{ +			notificationName = "PathfindingLinksets_SetLinksetUseMismatchOnRestrictedAndVolume"; +		} +		else if (showUnmodifiablePhantomWarning) +		{ +			notificationName = "PathfindingLinksets_SetLinksetUseMismatchOnRestricted"; +		} +		else +		{ +			notificationName = "PathfindingLinksets_SetLinksetUseMismatchOnVolume"; +		} +		LLNotificationsUtil::add(notificationName, substitutions, LLSD(), boost::bind(&LLFloaterPathfindingLinksets::handleApplyEdit, this, _1, _2)); +	} +	else +	{ +		doApplyEdit(); +	} +} + +void LLFloaterPathfindingLinksets::handleApplyEdit(const LLSD &pNotification, const LLSD &pResponse) +{ +	if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0) +	{ +		doApplyEdit(); +	} +} + +void LLFloaterPathfindingLinksets::doApplyEdit() +{ +	std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected(); +	if (!selectedItems.empty()) +	{ +		LLPathfindingLinkset::ELinksetUse linksetUse = getEditLinksetUse(); +		const std::string &aString = mEditA->getText(); +		const std::string &bString = mEditB->getText(); +		const std::string &cString = mEditC->getText(); +		const std::string &dString = mEditD->getText(); +		S32 aValue = static_cast<S32>(atoi(aString.c_str())); +		S32 bValue = static_cast<S32>(atoi(bString.c_str())); +		S32 cValue = static_cast<S32>(atoi(cString.c_str())); +		S32 dValue = static_cast<S32>(atoi(dString.c_str())); + +		LLPathfindingLinksetListPtr editListPtr(new LLPathfindingLinksetList()); +		for (std::vector<LLScrollListItem*>::const_iterator itemIter = selectedItems.begin(); +			itemIter != selectedItems.end(); ++itemIter) +		{ +			const LLScrollListItem *listItem = *itemIter; +			LLUUID uuid = listItem->getUUID(); +			const std::string &uuidString = uuid.asString(); +			llassert(mLinksetsListPtr != NULL); +			LLPathfindingLinksetList::iterator linksetIter = mLinksetsListPtr->find(uuidString); +			llassert(linksetIter != mLinksetsListPtr->end()); +			LLPathfindingLinksetPtr linksetPtr = linksetIter->second; +			editListPtr->insert(std::pair<std::string, LLPathfindingLinksetPtr>(uuidString, linksetPtr)); +		} + +		requestSetLinksets(editListPtr, linksetUse, aValue, bValue, cValue, dValue); +	} +} + +std::string LLFloaterPathfindingLinksets::getLinksetUseString(LLPathfindingLinkset::ELinksetUse pLinksetUse) const +{ +	std::string linksetUse; + +	switch (pLinksetUse) +	{ +	case LLPathfindingLinkset::kWalkable : +		linksetUse = getString("linkset_use_walkable"); +		break; +	case LLPathfindingLinkset::kStaticObstacle : +		linksetUse = getString("linkset_use_static_obstacle"); +		break; +	case LLPathfindingLinkset::kDynamicObstacle : +		linksetUse = getString("linkset_use_dynamic_obstacle"); +		break; +	case LLPathfindingLinkset::kMaterialVolume : +		linksetUse = getString("linkset_use_material_volume"); +		break; +	case LLPathfindingLinkset::kExclusionVolume : +		linksetUse = getString("linkset_use_exclusion_volume"); +		break; +	case LLPathfindingLinkset::kDynamicPhantom : +		linksetUse = getString("linkset_use_dynamic_phantom"); +		break; +	case LLPathfindingLinkset::kUnknown : +	default : +		linksetUse = getString("linkset_use_dynamic_obstacle"); +		llassert(0); +		break; +	} + +	return linksetUse; +} + +LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::getFilterLinksetUse() const +{ +	return convertToLinksetUse(mFilterByLinksetUse->getValue()); +} + +void LLFloaterPathfindingLinksets::setFilterLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse) +{ +	mFilterByLinksetUse->setValue(convertToXuiValue(pLinksetUse)); +} + +LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::getEditLinksetUse() const +{ +	return convertToLinksetUse(mEditLinksetUse->getValue()); +} + +void LLFloaterPathfindingLinksets::setEditLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse) +{ +	mEditLinksetUse->setValue(convertToXuiValue(pLinksetUse)); +} + +LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::convertToLinksetUse(LLSD pXuiValue) const +{ +	LLPathfindingLinkset::ELinksetUse linkUse; + +	switch (pXuiValue.asInteger()) +	{ +	case XUI_LINKSET_USE_NONE : +		linkUse = LLPathfindingLinkset::kUnknown; +		break; +	case XUI_LINKSET_USE_WALKABLE : +		linkUse = LLPathfindingLinkset::kWalkable; +		break; +	case XUI_LINKSET_USE_STATIC_OBSTACLE : +		linkUse = LLPathfindingLinkset::kStaticObstacle; +		break; +	case XUI_LINKSET_USE_DYNAMIC_OBSTACLE : +		linkUse = LLPathfindingLinkset::kDynamicObstacle; +		break; +	case XUI_LINKSET_USE_MATERIAL_VOLUME : +		linkUse = LLPathfindingLinkset::kMaterialVolume; +		break; +	case XUI_LINKSET_USE_EXCLUSION_VOLUME : +		linkUse = LLPathfindingLinkset::kExclusionVolume; +		break; +	case XUI_LINKSET_USE_DYNAMIC_PHANTOM : +		linkUse = LLPathfindingLinkset::kDynamicPhantom; +		break; +	default : +		linkUse = LLPathfindingLinkset::kUnknown; +		llassert(0); +		break; +	} + +	return linkUse; +} + +LLSD LLFloaterPathfindingLinksets::convertToXuiValue(LLPathfindingLinkset::ELinksetUse pLinksetUse) const +{ +	LLSD xuiValue; + +	switch (pLinksetUse) +	{ +	case LLPathfindingLinkset::kUnknown : +		xuiValue = XUI_LINKSET_USE_NONE; +		break; +	case LLPathfindingLinkset::kWalkable : +		xuiValue = XUI_LINKSET_USE_WALKABLE; +		break; +	case LLPathfindingLinkset::kStaticObstacle : +		xuiValue = XUI_LINKSET_USE_STATIC_OBSTACLE; +		break; +	case LLPathfindingLinkset::kDynamicObstacle : +		xuiValue = XUI_LINKSET_USE_DYNAMIC_OBSTACLE; +		break; +	case LLPathfindingLinkset::kMaterialVolume : +		xuiValue = XUI_LINKSET_USE_MATERIAL_VOLUME; +		break; +	case LLPathfindingLinkset::kExclusionVolume : +		xuiValue = XUI_LINKSET_USE_EXCLUSION_VOLUME; +		break; +	case LLPathfindingLinkset::kDynamicPhantom : +		xuiValue = XUI_LINKSET_USE_DYNAMIC_PHANTOM; +		break; +	default : +		xuiValue = XUI_LINKSET_USE_NONE; +		llassert(0); +		break; +	} + +	return xuiValue; +} diff --git a/indra/newview/llfloaterpathfindinglinksets.h b/indra/newview/llfloaterpathfindinglinksets.h index c3a243314f..0fa4d9aac9 100644 --- a/indra/newview/llfloaterpathfindinglinksets.h +++ b/indra/newview/llfloaterpathfindinglinksets.h @@ -1,184 +1,184 @@ -/** 
 - * @file llfloaterpathfindinglinksets.h
 - * @author William Todd Stinson
 - * @brief "Pathfinding linksets" floater, allowing manipulation of the Havok AI pathfinding settings.
 - *
 - * $LicenseInfo:firstyear=2002&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc.
 - * 
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - * 
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - * 
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - * 
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#ifndef LL_LLFLOATERPATHFINDINGLINKSETS_H
 -#define LL_LLFLOATERPATHFINDINGLINKSETS_H
 -
 -#include "llfloater.h"
 -#include "lluuid.h"
 -#include "llselectmgr.h"
 -#include "llpathfindinglinkset.h"
 -#include "llpathfindinglinksetlist.h"
 -#include "llpathfindingmanager.h"
 -
 -#include <boost/signals2.hpp>
 -
 -class LLSD;
 -class LLUICtrl;
 -class LLTextBase;
 -class LLScrollListCtrl;
 -class LLScrollListItem;
 -class LLLineEditor;
 -class LLComboBox;
 -class LLCheckBoxCtrl;
 -class LLButton;
 -
 -class LLFloaterPathfindingLinksets
 -:	public LLFloater
 -{
 -	friend class LLFloaterReg;
 -
 -public:
 -	typedef enum
 -	{
 -		kMessagingUnknown,
 -		kMessagingGetRequestSent,
 -		kMessagingGetError,
 -		kMessagingSetRequestSent,
 -		kMessagingSetError,
 -		kMessagingComplete,
 -		kMessagingNotEnabled
 -	} EMessagingState;
 -
 -	virtual BOOL postBuild();
 -	virtual void onOpen(const LLSD& pKey);
 -	virtual void onClose(bool pAppQuitting);
 -	virtual void draw();
 -
 -	static void openLinksetsEditor();
 -
 -protected:
 -
 -private:
 -	LLLineEditor     *mFilterByName;
 -	LLLineEditor     *mFilterByDescription;
 -	LLComboBox       *mFilterByLinksetUse;
 -	LLScrollListCtrl *mLinksetsScrollList;
 -	LLTextBase       *mLinksetsStatus;
 -	LLButton         *mRefreshListButton;
 -	LLButton         *mSelectAllButton;
 -	LLButton         *mSelectNoneButton;
 -	LLCheckBoxCtrl   *mShowBeaconCheckBox;
 -	LLButton         *mTakeButton;
 -	LLButton         *mTakeCopyButton;
 -	LLButton         *mReturnButton;
 -	LLButton         *mDeleteButton;
 -	LLButton         *mTeleportButton;
 -	LLComboBox       *mEditLinksetUse;
 -	LLScrollListItem *mEditLinksetUseUnset;
 -	LLScrollListItem *mEditLinksetUseWalkable;
 -	LLScrollListItem *mEditLinksetUseStaticObstacle;
 -	LLScrollListItem *mEditLinksetUseDynamicObstacle;
 -	LLScrollListItem *mEditLinksetUseMaterialVolume;
 -	LLScrollListItem *mEditLinksetUseExclusionVolume;
 -	LLScrollListItem *mEditLinksetUseDynamicPhantom;
 -	LLTextBase       *mLabelWalkabilityCoefficients;
 -	LLTextBase       *mLabelEditA;
 -	LLLineEditor     *mEditA;
 -	LLTextBase       *mLabelEditB;
 -	LLLineEditor     *mEditB;
 -	LLTextBase       *mLabelEditC;
 -	LLLineEditor     *mEditC;
 -	LLTextBase       *mLabelEditD;
 -	LLLineEditor     *mEditD;
 -	LLButton         *mApplyEditsButton;
 -
 -	EMessagingState                          mMessagingState;
 -	LLPathfindingManager::request_id_t       mMessagingRequestId;
 -	LLPathfindingLinksetListPtr              mLinksetsListPtr;
 -	LLObjectSelectionHandle                  mLinksetsSelection;
 -	LLPathfindingManager::agent_state_slot_t mAgentStateSlot;
 -	boost::signals2::connection              mSelectionUpdateSlot;
 -	boost::signals2::connection              mRegionBoundarySlot;
 -
 -	// Does its own instance management, so clients not allowed
 -	// to allocate or destroy.
 -	LLFloaterPathfindingLinksets(const LLSD& pSeed);
 -	virtual ~LLFloaterPathfindingLinksets();
 -
 -	EMessagingState getMessagingState() const;
 -	void            setMessagingState(EMessagingState pMessagingState);
 -
 -	void requestGetLinksets();
 -	void requestSetLinksets(LLPathfindingLinksetListPtr pLinksetList, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD);
 -	void handleNewLinksets(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pLinksetsRequestStatus, LLPathfindingLinksetListPtr pLinksetsListPtr);
 -	void handleUpdateLinksets(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pLinksetsRequestStatus, LLPathfindingLinksetListPtr pLinksetsListPtr);
 -
 -	void onApplyAllFilters();
 -	void onClearFiltersClicked();
 -	void onLinksetsSelectionChange();
 -	void onRefreshLinksetsClicked();
 -	void onSelectAllLinksetsClicked();
 -	void onSelectNoneLinksetsClicked();
 -	void onTakeClicked();
 -	void onTakeCopyClicked();
 -	void onReturnClicked();
 -	void onDeleteClicked();
 -	void onTeleportClicked();
 -	void onWalkabilityCoefficientEntered(LLUICtrl *pUICtrl);
 -	void onApplyChangesClicked();
 -	void onAgentStateCB(LLPathfindingManager::EAgentState pAgentState);
 -	void onRegionBoundaryCross();
 -
 -	void applyFilters();
 -	void clearFilters();
 -
 -	void selectAllLinksets();
 -	void selectNoneLinksets();
 -	void clearLinksets();
 -
 -	void updateControls();
 -	void updateEditFieldValues();
 -	void updateScrollList();
 -	LLSD buildLinksetScrollListElement(const LLPathfindingLinksetPtr pLinksetPtr, const LLVector3 &pAvatarPosition) const;
 -	LLSD buildLinksetUseScrollListElement(const std::string &label, S32 value) const;
 -
 -	bool isShowUnmodifiablePhantomWarning(LLPathfindingLinkset::ELinksetUse linksetUse) const;
 -	bool isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse linksetUse) const;
 -
 -	void updateStatusMessage();
 -	void updateEnableStateOnListActions();
 -	void updateEnableStateOnEditFields();
 -	void updateEnableStateOnEditLinksetUse();
 -
 -	void applyEdit();
 -	void handleApplyEdit(const LLSD &pNotification, const LLSD &pResponse);
 -	void doApplyEdit();
 -
 -	std::string getLinksetUseString(LLPathfindingLinkset::ELinksetUse pLinksetUse) const;
 -
 -	LLPathfindingLinkset::ELinksetUse getFilterLinksetUse() const;
 -	void                              setFilterLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse);
 -
 -	LLPathfindingLinkset::ELinksetUse getEditLinksetUse() const;
 -	void                              setEditLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse);
 -
 -	LLPathfindingLinkset::ELinksetUse convertToLinksetUse(LLSD pXuiValue) const;
 -	LLSD                              convertToXuiValue(LLPathfindingLinkset::ELinksetUse pLinksetUse) const;
 -};
 -
 -#endif // LL_LLFLOATERPATHFINDINGLINKSETS_H
 +/**  + * @file llfloaterpathfindinglinksets.h + * @author William Todd Stinson + * @brief "Pathfinding linksets" floater, allowing manipulation of the Havok AI pathfinding settings. + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERPATHFINDINGLINKSETS_H +#define LL_LLFLOATERPATHFINDINGLINKSETS_H + +#include "llfloater.h" +#include "lluuid.h" +#include "llselectmgr.h" +#include "llpathfindinglinkset.h" +#include "llpathfindinglinksetlist.h" +#include "llpathfindingmanager.h" + +#include <boost/signals2.hpp> + +class LLSD; +class LLUICtrl; +class LLTextBase; +class LLScrollListCtrl; +class LLScrollListItem; +class LLLineEditor; +class LLComboBox; +class LLCheckBoxCtrl; +class LLButton; + +class LLFloaterPathfindingLinksets +:	public LLFloater +{ +	friend class LLFloaterReg; + +public: +	typedef enum +	{ +		kMessagingUnknown, +		kMessagingGetRequestSent, +		kMessagingGetError, +		kMessagingSetRequestSent, +		kMessagingSetError, +		kMessagingComplete, +		kMessagingNotEnabled +	} EMessagingState; + +	virtual BOOL postBuild(); +	virtual void onOpen(const LLSD& pKey); +	virtual void onClose(bool pAppQuitting); +	virtual void draw(); + +	static void openLinksetsEditor(); + +protected: + +private: +	LLLineEditor     *mFilterByName; +	LLLineEditor     *mFilterByDescription; +	LLComboBox       *mFilterByLinksetUse; +	LLScrollListCtrl *mLinksetsScrollList; +	LLTextBase       *mLinksetsStatus; +	LLButton         *mRefreshListButton; +	LLButton         *mSelectAllButton; +	LLButton         *mSelectNoneButton; +	LLCheckBoxCtrl   *mShowBeaconCheckBox; +	LLButton         *mTakeButton; +	LLButton         *mTakeCopyButton; +	LLButton         *mReturnButton; +	LLButton         *mDeleteButton; +	LLButton         *mTeleportButton; +	LLComboBox       *mEditLinksetUse; +	LLScrollListItem *mEditLinksetUseUnset; +	LLScrollListItem *mEditLinksetUseWalkable; +	LLScrollListItem *mEditLinksetUseStaticObstacle; +	LLScrollListItem *mEditLinksetUseDynamicObstacle; +	LLScrollListItem *mEditLinksetUseMaterialVolume; +	LLScrollListItem *mEditLinksetUseExclusionVolume; +	LLScrollListItem *mEditLinksetUseDynamicPhantom; +	LLTextBase       *mLabelWalkabilityCoefficients; +	LLTextBase       *mLabelEditA; +	LLLineEditor     *mEditA; +	LLTextBase       *mLabelEditB; +	LLLineEditor     *mEditB; +	LLTextBase       *mLabelEditC; +	LLLineEditor     *mEditC; +	LLTextBase       *mLabelEditD; +	LLLineEditor     *mEditD; +	LLButton         *mApplyEditsButton; + +	EMessagingState                          mMessagingState; +	LLPathfindingManager::request_id_t       mMessagingRequestId; +	LLPathfindingLinksetListPtr              mLinksetsListPtr; +	LLObjectSelectionHandle                  mLinksetsSelection; +	LLPathfindingManager::agent_state_slot_t mAgentStateSlot; +	boost::signals2::connection              mSelectionUpdateSlot; +	boost::signals2::connection              mRegionBoundarySlot; + +	// Does its own instance management, so clients not allowed +	// to allocate or destroy. +	LLFloaterPathfindingLinksets(const LLSD& pSeed); +	virtual ~LLFloaterPathfindingLinksets(); + +	EMessagingState getMessagingState() const; +	void            setMessagingState(EMessagingState pMessagingState); + +	void requestGetLinksets(); +	void requestSetLinksets(LLPathfindingLinksetListPtr pLinksetList, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD); +	void handleNewLinksets(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pLinksetsRequestStatus, LLPathfindingLinksetListPtr pLinksetsListPtr); +	void handleUpdateLinksets(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pLinksetsRequestStatus, LLPathfindingLinksetListPtr pLinksetsListPtr); + +	void onApplyAllFilters(); +	void onClearFiltersClicked(); +	void onLinksetsSelectionChange(); +	void onRefreshLinksetsClicked(); +	void onSelectAllLinksetsClicked(); +	void onSelectNoneLinksetsClicked(); +	void onTakeClicked(); +	void onTakeCopyClicked(); +	void onReturnClicked(); +	void onDeleteClicked(); +	void onTeleportClicked(); +	void onWalkabilityCoefficientEntered(LLUICtrl *pUICtrl); +	void onApplyChangesClicked(); +	void onAgentStateCB(LLPathfindingManager::EAgentState pAgentState); +	void onRegionBoundaryCross(); + +	void applyFilters(); +	void clearFilters(); + +	void selectAllLinksets(); +	void selectNoneLinksets(); +	void clearLinksets(); + +	void updateControls(); +	void updateEditFieldValues(); +	void updateScrollList(); +	LLSD buildLinksetScrollListElement(const LLPathfindingLinksetPtr pLinksetPtr, const LLVector3 &pAvatarPosition) const; +	LLSD buildLinksetUseScrollListElement(const std::string &label, S32 value) const; + +	bool isShowUnmodifiablePhantomWarning(LLPathfindingLinkset::ELinksetUse linksetUse) const; +	bool isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse linksetUse) const; + +	void updateStatusMessage(); +	void updateEnableStateOnListActions(); +	void updateEnableStateOnEditFields(); +	void updateEnableStateOnEditLinksetUse(); + +	void applyEdit(); +	void handleApplyEdit(const LLSD &pNotification, const LLSD &pResponse); +	void doApplyEdit(); + +	std::string getLinksetUseString(LLPathfindingLinkset::ELinksetUse pLinksetUse) const; + +	LLPathfindingLinkset::ELinksetUse getFilterLinksetUse() const; +	void                              setFilterLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse); + +	LLPathfindingLinkset::ELinksetUse getEditLinksetUse() const; +	void                              setEditLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse); + +	LLPathfindingLinkset::ELinksetUse convertToLinksetUse(LLSD pXuiValue) const; +	LLSD                              convertToXuiValue(LLPathfindingLinkset::ELinksetUse pLinksetUse) const; +}; + +#endif // LL_LLFLOATERPATHFINDINGLINKSETS_H diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index d277ded636..792d852d53 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -890,12 +890,12 @@ void LLPanelVolume::onCommitIsFlexible(LLUICtrl *, void*)  void LLPanelVolume::handleResponseChangeToFlexible(const LLSD &pNotification, const LLSD &pResponse)  { -	if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0)
 -	{
 -		sendIsFlexible();
 -	}
 -	else
 -	{
 -		getChild<LLUICtrl>("Flexible1D Checkbox Ctrl")->setValue(FALSE);
 -	}
 +	if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0) +	{ +		sendIsFlexible(); +	} +	else +	{ +		getChild<LLUICtrl>("Flexible1D Checkbox Ctrl")->setValue(FALSE); +	}  } diff --git a/indra/newview/llpathfindingcharacter.cpp b/indra/newview/llpathfindingcharacter.cpp index 4600f661f8..0a3d737b73 100644 --- a/indra/newview/llpathfindingcharacter.cpp +++ b/indra/newview/llpathfindingcharacter.cpp @@ -1,103 +1,103 @@ -/** 
 - * @file llpathfindingcharacter.cpp
 - * @author William Todd Stinson
 - * @brief Definition of a pathfinding character that contains various properties required for havok pathfinding.
 - *
 - * $LicenseInfo:firstyear=2002&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc.
 - * 
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - * 
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - * 
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - * 
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#include "llviewerprecompiledheaders.h"
 -#include "llpathfindingcharacter.h"
 -#include "llsd.h"
 -#include "v3math.h"
 -#include "lluuid.h"
 -#include "llavatarname.h"
 -#include "llavatarnamecache.h"
 -
 -#define CHARACTER_NAME_FIELD        "name"
 -#define CHARACTER_DESCRIPTION_FIELD "description"
 -#define CHARACTER_OWNER_FIELD       "owner"
 -#define CHARACTER_CPU_TIME_FIELD    "cpu_time"
 -#define CHARACTER_POSITION_FIELD    "position"
 -
 -//---------------------------------------------------------------------------
 -// LLPathfindingCharacter
 -//---------------------------------------------------------------------------
 -
 -LLPathfindingCharacter::LLPathfindingCharacter(const std::string &pUUID, const LLSD& pCharacterItem)
 -	: mUUID(pUUID),
 -	mName(),
 -	mDescription(),
 -	mOwnerUUID(),
 -	mOwnerName(),
 -	mCPUTime(0U),
 -	mLocation(LLVector3::zero)
 -{
 -	llassert(pCharacterItem.has(CHARACTER_NAME_FIELD));
 -	llassert(pCharacterItem.get(CHARACTER_NAME_FIELD).isString());
 -	mName = pCharacterItem.get(CHARACTER_NAME_FIELD).asString();
 -
 -	llassert(pCharacterItem.has(CHARACTER_DESCRIPTION_FIELD));
 -	llassert(pCharacterItem.get(CHARACTER_DESCRIPTION_FIELD).isString());
 -	mDescription = pCharacterItem.get(CHARACTER_DESCRIPTION_FIELD).asString();
 -
 -	llassert(pCharacterItem.has(CHARACTER_OWNER_FIELD));
 -	llassert(pCharacterItem.get(CHARACTER_OWNER_FIELD).isUUID());
 -	mOwnerUUID = pCharacterItem.get(CHARACTER_OWNER_FIELD).asUUID();
 -	LLAvatarNameCache::get(mOwnerUUID, &mOwnerName);
 -
 -	llassert(pCharacterItem.has(CHARACTER_CPU_TIME_FIELD));
 -	llassert(pCharacterItem.get(CHARACTER_CPU_TIME_FIELD).isReal());
 -	mCPUTime = pCharacterItem.get(CHARACTER_CPU_TIME_FIELD).asReal();
 -
 -	llassert(pCharacterItem.has(CHARACTER_POSITION_FIELD));
 -	llassert(pCharacterItem.get(CHARACTER_POSITION_FIELD).isArray());
 -	mLocation.setValue(pCharacterItem.get(CHARACTER_POSITION_FIELD));
 -}
 -
 -LLPathfindingCharacter::LLPathfindingCharacter(const LLPathfindingCharacter& pOther)
 -	: mUUID(pOther.mUUID),
 -	mName(pOther.mName),
 -	mDescription(pOther.mDescription),
 -	mOwnerUUID(pOther.mOwnerUUID),
 -	mOwnerName(pOther.mOwnerName),
 -	mCPUTime(pOther.mCPUTime),
 -	mLocation(pOther.mLocation)
 -{
 -}
 -
 -LLPathfindingCharacter::~LLPathfindingCharacter()
 -{
 -}
 -
 -LLPathfindingCharacter& LLPathfindingCharacter::operator =(const LLPathfindingCharacter& pOther)
 -{
 -	mUUID = pOther.mUUID;
 -	mName = pOther.mName;
 -	mDescription = pOther.mDescription;
 -	mOwnerUUID = pOther.mOwnerUUID;
 -	mOwnerName = pOther.mOwnerName;
 -	mCPUTime = pOther.mCPUTime;
 -	mLocation = pOther.mLocation;
 -
 -	return *this;
 -}
 +/**  + * @file llpathfindingcharacter.cpp + * @author William Todd Stinson + * @brief Definition of a pathfinding character that contains various properties required for havok pathfinding. + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llpathfindingcharacter.h" +#include "llsd.h" +#include "v3math.h" +#include "lluuid.h" +#include "llavatarname.h" +#include "llavatarnamecache.h" + +#define CHARACTER_NAME_FIELD        "name" +#define CHARACTER_DESCRIPTION_FIELD "description" +#define CHARACTER_OWNER_FIELD       "owner" +#define CHARACTER_CPU_TIME_FIELD    "cpu_time" +#define CHARACTER_POSITION_FIELD    "position" + +//--------------------------------------------------------------------------- +// LLPathfindingCharacter +//--------------------------------------------------------------------------- + +LLPathfindingCharacter::LLPathfindingCharacter(const std::string &pUUID, const LLSD& pCharacterItem) +	: mUUID(pUUID), +	mName(), +	mDescription(), +	mOwnerUUID(), +	mOwnerName(), +	mCPUTime(0U), +	mLocation(LLVector3::zero) +{ +	llassert(pCharacterItem.has(CHARACTER_NAME_FIELD)); +	llassert(pCharacterItem.get(CHARACTER_NAME_FIELD).isString()); +	mName = pCharacterItem.get(CHARACTER_NAME_FIELD).asString(); + +	llassert(pCharacterItem.has(CHARACTER_DESCRIPTION_FIELD)); +	llassert(pCharacterItem.get(CHARACTER_DESCRIPTION_FIELD).isString()); +	mDescription = pCharacterItem.get(CHARACTER_DESCRIPTION_FIELD).asString(); + +	llassert(pCharacterItem.has(CHARACTER_OWNER_FIELD)); +	llassert(pCharacterItem.get(CHARACTER_OWNER_FIELD).isUUID()); +	mOwnerUUID = pCharacterItem.get(CHARACTER_OWNER_FIELD).asUUID(); +	LLAvatarNameCache::get(mOwnerUUID, &mOwnerName); + +	llassert(pCharacterItem.has(CHARACTER_CPU_TIME_FIELD)); +	llassert(pCharacterItem.get(CHARACTER_CPU_TIME_FIELD).isReal()); +	mCPUTime = pCharacterItem.get(CHARACTER_CPU_TIME_FIELD).asReal(); + +	llassert(pCharacterItem.has(CHARACTER_POSITION_FIELD)); +	llassert(pCharacterItem.get(CHARACTER_POSITION_FIELD).isArray()); +	mLocation.setValue(pCharacterItem.get(CHARACTER_POSITION_FIELD)); +} + +LLPathfindingCharacter::LLPathfindingCharacter(const LLPathfindingCharacter& pOther) +	: mUUID(pOther.mUUID), +	mName(pOther.mName), +	mDescription(pOther.mDescription), +	mOwnerUUID(pOther.mOwnerUUID), +	mOwnerName(pOther.mOwnerName), +	mCPUTime(pOther.mCPUTime), +	mLocation(pOther.mLocation) +{ +} + +LLPathfindingCharacter::~LLPathfindingCharacter() +{ +} + +LLPathfindingCharacter& LLPathfindingCharacter::operator =(const LLPathfindingCharacter& pOther) +{ +	mUUID = pOther.mUUID; +	mName = pOther.mName; +	mDescription = pOther.mDescription; +	mOwnerUUID = pOther.mOwnerUUID; +	mOwnerName = pOther.mOwnerName; +	mCPUTime = pOther.mCPUTime; +	mLocation = pOther.mLocation; + +	return *this; +} diff --git a/indra/newview/llpathfindingcharacter.h b/indra/newview/llpathfindingcharacter.h index 5be52ebc45..3e40343831 100644 --- a/indra/newview/llpathfindingcharacter.h +++ b/indra/newview/llpathfindingcharacter.h @@ -1,70 +1,70 @@ -/** 
 - * @file llpathfindingcharacter.h
 - * @author William Todd Stinson
 - * @brief Definition of a pathfinding character that contains various properties required for havok pathfinding.
 - *
 - * $LicenseInfo:firstyear=2002&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc.
 - * 
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - * 
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - * 
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - * 
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#ifndef LL_LLPATHFINDINGCHARACTER_H
 -#define LL_LLPATHFINDINGCHARACTER_H
 -
 -#include "v3math.h"
 -#include "lluuid.h"
 -#include "llavatarname.h"
 -
 -#include <boost/shared_ptr.hpp>
 -
 -class LLSD;
 -class LLPathfindingCharacter;
 -
 -typedef boost::shared_ptr<LLPathfindingCharacter> LLPathfindingCharacterPtr;
 -
 -class LLPathfindingCharacter
 -{
 -public:
 -	LLPathfindingCharacter(const std::string &pUUID, const LLSD &pCharacterItem);
 -	LLPathfindingCharacter(const LLPathfindingCharacter& pOther);
 -	virtual ~LLPathfindingCharacter();
 -
 -	LLPathfindingCharacter& operator = (const LLPathfindingCharacter& pOther);
 -
 -	inline const LLUUID&      getUUID() const        {return mUUID;};
 -	inline const std::string& getName() const        {return mName;};
 -	inline const std::string& getDescription() const {return mDescription;};
 -	inline const std::string  getOwnerName() const   {return mOwnerName.getCompleteName();};
 -	inline F32                getCPUTime() const     {return mCPUTime;};
 -	inline const LLVector3&   getLocation() const    {return mLocation;};
 -
 -protected:
 -
 -private:
 -	LLUUID       mUUID;
 -	std::string  mName;
 -	std::string  mDescription;
 -	LLUUID       mOwnerUUID;
 -	LLAvatarName mOwnerName;
 -	F32          mCPUTime;
 -	LLVector3    mLocation;
 -};
 -
 -#endif // LL_LLPATHFINDINGCHARACTER_H
 +/**  + * @file llpathfindingcharacter.h + * @author William Todd Stinson + * @brief Definition of a pathfinding character that contains various properties required for havok pathfinding. + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPATHFINDINGCHARACTER_H +#define LL_LLPATHFINDINGCHARACTER_H + +#include "v3math.h" +#include "lluuid.h" +#include "llavatarname.h" + +#include <boost/shared_ptr.hpp> + +class LLSD; +class LLPathfindingCharacter; + +typedef boost::shared_ptr<LLPathfindingCharacter> LLPathfindingCharacterPtr; + +class LLPathfindingCharacter +{ +public: +	LLPathfindingCharacter(const std::string &pUUID, const LLSD &pCharacterItem); +	LLPathfindingCharacter(const LLPathfindingCharacter& pOther); +	virtual ~LLPathfindingCharacter(); + +	LLPathfindingCharacter& operator = (const LLPathfindingCharacter& pOther); + +	inline const LLUUID&      getUUID() const        {return mUUID;}; +	inline const std::string& getName() const        {return mName;}; +	inline const std::string& getDescription() const {return mDescription;}; +	inline const std::string  getOwnerName() const   {return mOwnerName.getCompleteName();}; +	inline F32                getCPUTime() const     {return mCPUTime;}; +	inline const LLVector3&   getLocation() const    {return mLocation;}; + +protected: + +private: +	LLUUID       mUUID; +	std::string  mName; +	std::string  mDescription; +	LLUUID       mOwnerUUID; +	LLAvatarName mOwnerName; +	F32          mCPUTime; +	LLVector3    mLocation; +}; + +#endif // LL_LLPATHFINDINGCHARACTER_H diff --git a/indra/newview/llpathfindingcharacterlist.cpp b/indra/newview/llpathfindingcharacterlist.cpp index 64fddd490c..5ab4a8910f 100644 --- a/indra/newview/llpathfindingcharacterlist.cpp +++ b/indra/newview/llpathfindingcharacterlist.cpp @@ -1,63 +1,63 @@ -/** 
 - * @file llpathfindingcharacterlist.cpp
 - * @author William Todd Stinson
 - * @brief Class to implement the list of a set of pathfinding characters
 - *
 - * $LicenseInfo:firstyear=2002&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc.
 - * 
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - * 
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - * 
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - * 
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#include "llviewerprecompiledheaders.h"
 -
 -#include <string>
 -#include <map>
 -
 -#include "llsd.h"
 -#include "lluuid.h"
 -#include "llpathfindingcharacter.h"
 -#include "llpathfindingcharacterlist.h"
 -
 -//---------------------------------------------------------------------------
 -// LLPathfindingCharacterList
 -//---------------------------------------------------------------------------
 -
 -LLPathfindingCharacterList::LLPathfindingCharacterList()
 -	: LLPathfindingCharacterMap()
 -{
 -}
 -
 -LLPathfindingCharacterList::LLPathfindingCharacterList(const LLSD& pCharacterItems)
 -	: LLPathfindingCharacterMap()
 -{
 -	for (LLSD::map_const_iterator characterItemIter = pCharacterItems.beginMap();
 -		characterItemIter != pCharacterItems.endMap(); ++characterItemIter)
 -	{
 -		const std::string& uuid(characterItemIter->first);
 -		const LLSD& characterData = characterItemIter->second;
 -		LLPathfindingCharacterPtr character(new LLPathfindingCharacter(uuid, characterData));
 -		insert(std::pair<std::string, LLPathfindingCharacterPtr>(uuid, character));
 -	}
 -}
 -
 -LLPathfindingCharacterList::~LLPathfindingCharacterList()
 -{
 -	clear();
 -}
 +/**  + * @file llpathfindingcharacterlist.cpp + * @author William Todd Stinson + * @brief Class to implement the list of a set of pathfinding characters + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include <string> +#include <map> + +#include "llsd.h" +#include "lluuid.h" +#include "llpathfindingcharacter.h" +#include "llpathfindingcharacterlist.h" + +//--------------------------------------------------------------------------- +// LLPathfindingCharacterList +//--------------------------------------------------------------------------- + +LLPathfindingCharacterList::LLPathfindingCharacterList() +	: LLPathfindingCharacterMap() +{ +} + +LLPathfindingCharacterList::LLPathfindingCharacterList(const LLSD& pCharacterItems) +	: LLPathfindingCharacterMap() +{ +	for (LLSD::map_const_iterator characterItemIter = pCharacterItems.beginMap(); +		characterItemIter != pCharacterItems.endMap(); ++characterItemIter) +	{ +		const std::string& uuid(characterItemIter->first); +		const LLSD& characterData = characterItemIter->second; +		LLPathfindingCharacterPtr character(new LLPathfindingCharacter(uuid, characterData)); +		insert(std::pair<std::string, LLPathfindingCharacterPtr>(uuid, character)); +	} +} + +LLPathfindingCharacterList::~LLPathfindingCharacterList() +{ +	clear(); +} diff --git a/indra/newview/llpathfindingcharacterlist.h b/indra/newview/llpathfindingcharacterlist.h index ce6ec81615..601c89626d 100644 --- a/indra/newview/llpathfindingcharacterlist.h +++ b/indra/newview/llpathfindingcharacterlist.h @@ -1,56 +1,56 @@ -/** 
 - * @file llpathfindingcharacterlist.h
 - * @author William Todd Stinson
 - * @brief Class to implement the list of a set of pathfinding characters
 - *
 - * $LicenseInfo:firstyear=2002&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc.
 - * 
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - * 
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - * 
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - * 
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#ifndef LL_LLPATHFINDINGCHARACTERLIST_H
 -#define LL_LLPATHFINDINGCHARACTERLIST_H
 -
 -#include <string>
 -#include <map>
 -#include "llpathfindingcharacter.h"
 -
 -#include <boost/shared_ptr.hpp>
 -
 -class LLSD;
 -class LLPathfindingCharacterList;
 -
 -typedef boost::shared_ptr<LLPathfindingCharacterList> LLPathfindingCharacterListPtr;
 -typedef std::map<std::string, LLPathfindingCharacterPtr> LLPathfindingCharacterMap;
 -
 -class LLPathfindingCharacterList : public LLPathfindingCharacterMap
 -{
 -public:
 -	LLPathfindingCharacterList();
 -	LLPathfindingCharacterList(const LLSD& pCharacterItems);
 -	virtual ~LLPathfindingCharacterList();
 -
 -protected:
 -
 -private:
 -
 -};
 -
 -#endif // LL_LLPATHFINDINGCHARACTERLIST_H
 +/**  + * @file llpathfindingcharacterlist.h + * @author William Todd Stinson + * @brief Class to implement the list of a set of pathfinding characters + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPATHFINDINGCHARACTERLIST_H +#define LL_LLPATHFINDINGCHARACTERLIST_H + +#include <string> +#include <map> +#include "llpathfindingcharacter.h" + +#include <boost/shared_ptr.hpp> + +class LLSD; +class LLPathfindingCharacterList; + +typedef boost::shared_ptr<LLPathfindingCharacterList> LLPathfindingCharacterListPtr; +typedef std::map<std::string, LLPathfindingCharacterPtr> LLPathfindingCharacterMap; + +class LLPathfindingCharacterList : public LLPathfindingCharacterMap +{ +public: +	LLPathfindingCharacterList(); +	LLPathfindingCharacterList(const LLSD& pCharacterItems); +	virtual ~LLPathfindingCharacterList(); + +protected: + +private: + +}; + +#endif // LL_LLPATHFINDINGCHARACTERLIST_H diff --git a/indra/newview/llpathfindinglinkset.cpp b/indra/newview/llpathfindinglinkset.cpp index f2d95d9221..e7478870ca 100644 --- a/indra/newview/llpathfindinglinkset.cpp +++ b/indra/newview/llpathfindinglinkset.cpp @@ -1,522 +1,522 @@ -/** 
 - * @file llpathfindinglinksets.cpp
 - * @author William Todd Stinson
 - * @brief Definition of a pathfinding linkset that contains various properties required for havok pathfinding.
 - *
 - * $LicenseInfo:firstyear=2002&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc.
 - * 
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - * 
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - * 
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - * 
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#include "llviewerprecompiledheaders.h"
 -#include "llpathfindinglinkset.h"
 -#include "llsd.h"
 -#include "v3math.h"
 -#include "lluuid.h"
 -
 -#define LINKSET_NAME_FIELD                 "name"
 -#define LINKSET_DESCRIPTION_FIELD          "description"
 -#define LINKSET_LAND_IMPACT_FIELD          "landimpact"
 -#define LINKSET_MODIFIABLE_FIELD           "modifiable"
 -#ifdef DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS
 -#define DEPRECATED_LINKSET_PERMANENT_FIELD "permanent"
 -#define DEPRECATED_LINKSET_WALKABLE_FIELD  "walkable"
 -#endif // DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS
 -#define LINKSET_CATEGORY_FIELD             "navmesh_category"
 -#define LINKSET_CAN_BE_VOLUME              "can_be_volume"
 -#define LINKSET_PHANTOM_FIELD              "phantom"
 -#define LINKSET_WALKABILITY_A_FIELD        "A"
 -#define LINKSET_WALKABILITY_B_FIELD        "B"
 -#define LINKSET_WALKABILITY_C_FIELD        "C"
 -#define LINKSET_WALKABILITY_D_FIELD        "D"
 -#define LINKSET_POSITION_FIELD             "position"
 -
 -#define LINKSET_CATEGORY_VALUE_INCLUDE 0
 -#define LINKSET_CATEGORY_VALUE_EXCLUDE 1
 -#define LINKSET_CATEGORY_VALUE_IGNORE  2
 -
 -//---------------------------------------------------------------------------
 -// LLPathfindingLinkset
 -//---------------------------------------------------------------------------
 -
 -const S32 LLPathfindingLinkset::MIN_WALKABILITY_VALUE(0);
 -const S32 LLPathfindingLinkset::MAX_WALKABILITY_VALUE(100);
 -
 -LLPathfindingLinkset::LLPathfindingLinkset(const LLSD& pTerrainLinksetItem)
 -	: mUUID(),
 -	mIsTerrain(true),
 -	mName(),
 -	mDescription(),
 -	mLandImpact(0U),
 -	mLocation(LLVector3::zero),
 -#ifdef MISSING_MODIFIABLE_FIELD_WAR
 -	mHasModifiable(true),
 -#endif // MISSING_MODIFIABLE_FIELD_WAR
 -	mIsModifiable(FALSE),
 -	mCanBeVolume(FALSE),
 -	mLinksetUse(kUnknown),
 -	mWalkabilityCoefficientA(MIN_WALKABILITY_VALUE),
 -	mWalkabilityCoefficientB(MIN_WALKABILITY_VALUE),
 -	mWalkabilityCoefficientC(MIN_WALKABILITY_VALUE),
 -	mWalkabilityCoefficientD(MIN_WALKABILITY_VALUE)
 -{
 -	parsePathfindingData(pTerrainLinksetItem);
 -}
 -
 -LLPathfindingLinkset::LLPathfindingLinkset(const std::string &pUUID, const LLSD& pLinksetItem)
 -	: mUUID(pUUID),
 -	mIsTerrain(false),
 -	mName(),
 -	mDescription(),
 -	mLandImpact(0U),
 -	mLocation(LLVector3::zero),
 -#ifdef MISSING_MODIFIABLE_FIELD_WAR
 -	mHasModifiable(false),
 -#endif // MISSING_MODIFIABLE_FIELD_WAR
 -	mIsModifiable(TRUE),
 -	mCanBeVolume(TRUE),
 -	mLinksetUse(kUnknown),
 -	mWalkabilityCoefficientA(MIN_WALKABILITY_VALUE),
 -	mWalkabilityCoefficientB(MIN_WALKABILITY_VALUE),
 -	mWalkabilityCoefficientC(MIN_WALKABILITY_VALUE),
 -	mWalkabilityCoefficientD(MIN_WALKABILITY_VALUE)
 -{
 -	parseObjectData(pLinksetItem);
 -	parsePathfindingData(pLinksetItem);
 -}
 -
 -LLPathfindingLinkset::LLPathfindingLinkset(const LLPathfindingLinkset& pOther)
 -	: mUUID(pOther.mUUID),
 -	mName(pOther.mName),
 -	mDescription(pOther.mDescription),
 -	mLandImpact(pOther.mLandImpact),
 -	mLocation(pOther.mLocation),
 -#ifdef MISSING_MODIFIABLE_FIELD_WAR
 -	mHasModifiable(pOther.mHasModifiable),
 -	mIsModifiable(pOther.mHasModifiable ? pOther.mIsModifiable : TRUE),
 -#else // MISSING_MODIFIABLE_FIELD_WAR
 -	mIsModifiable(pOther.mIsModifiable),
 -#endif // MISSING_MODIFIABLE_FIELD_WAR
 -	mCanBeVolume(pOther.mCanBeVolume),
 -	mLinksetUse(pOther.mLinksetUse),
 -	mWalkabilityCoefficientA(pOther.mWalkabilityCoefficientA),
 -	mWalkabilityCoefficientB(pOther.mWalkabilityCoefficientB),
 -	mWalkabilityCoefficientC(pOther.mWalkabilityCoefficientC),
 -	mWalkabilityCoefficientD(pOther.mWalkabilityCoefficientD)
 -{
 -}
 -
 -LLPathfindingLinkset::~LLPathfindingLinkset()
 -{
 -}
 -
 -LLPathfindingLinkset& LLPathfindingLinkset::operator =(const LLPathfindingLinkset& pOther)
 -{
 -	mUUID = pOther.mUUID;
 -	mName = pOther.mName;
 -	mDescription = pOther.mDescription;
 -	mLandImpact = pOther.mLandImpact;
 -	mLocation = pOther.mLocation;
 -#ifdef MISSING_MODIFIABLE_FIELD_WAR
 -	if (pOther.mHasModifiable)
 -	{
 -		mHasModifiable = pOther.mHasModifiable;
 -		mIsModifiable = pOther.mIsModifiable;
 -	}
 -#else // MISSING_MODIFIABLE_FIELD_WAR
 -	mIsModifiable = pOther.mIsModifiable;
 -#endif // MISSING_MODIFIABLE_FIELD_WAR
 -	mCanBeVolume = pOther.mCanBeVolume;
 -	mLinksetUse = pOther.mLinksetUse;
 -	mWalkabilityCoefficientA = pOther.mWalkabilityCoefficientA;
 -	mWalkabilityCoefficientB = pOther.mWalkabilityCoefficientB;
 -	mWalkabilityCoefficientC = pOther.mWalkabilityCoefficientC;
 -	mWalkabilityCoefficientD = pOther.mWalkabilityCoefficientD;
 -
 -	return *this;
 -}
 -
 -BOOL LLPathfindingLinkset::isPhantom() const
 -{
 -	return isPhantom(getLinksetUse());
 -}
 -
 -LLPathfindingLinkset::ELinksetUse LLPathfindingLinkset::getLinksetUseWithToggledPhantom(ELinksetUse pLinksetUse)
 -{
 -	BOOL isPhantom = LLPathfindingLinkset::isPhantom(pLinksetUse);
 -	ENavMeshGenerationCategory navMeshGenerationCategory = getNavMeshGenerationCategory(pLinksetUse);
 -
 -	return getLinksetUse(!isPhantom, navMeshGenerationCategory);
 -}
 -
 -bool LLPathfindingLinkset::isShowUnmodifiablePhantomWarning(ELinksetUse pLinksetUse) const
 -{
 -	return (!isModifiable() && (isPhantom() != isPhantom(pLinksetUse)));
 -}
 -
 -bool LLPathfindingLinkset::isShowCannotBeVolumeWarning(ELinksetUse pLinksetUse) const
 -{
 -	return (!canBeVolume() && ((pLinksetUse == kMaterialVolume) || (pLinksetUse == kExclusionVolume)));
 -}
 -
 -LLSD LLPathfindingLinkset::encodeAlteredFields(ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const
 -{
 -	LLSD itemData;
 -
 -	if (!isTerrain() && (pLinksetUse != kUnknown) && (getLinksetUse() != pLinksetUse) &&
 -		(canBeVolume() || ((pLinksetUse != kMaterialVolume) && (pLinksetUse != kExclusionVolume))))
 -	{
 -		if (isModifiable())
 -		{
 -			itemData[LINKSET_PHANTOM_FIELD] = static_cast<bool>(isPhantom(pLinksetUse));
 -		}
 -
 -#ifdef DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS
 -		itemData[DEPRECATED_LINKSET_PERMANENT_FIELD] = static_cast<bool>(isPermanent(pLinksetUse));
 -		itemData[DEPRECATED_LINKSET_WALKABLE_FIELD] = static_cast<bool>(isWalkable(pLinksetUse));
 -#endif // DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS
 -		itemData[LINKSET_CATEGORY_FIELD] = convertCategoryToLLSD(getNavMeshGenerationCategory(pLinksetUse));
 -	}
 -
 -	if (mWalkabilityCoefficientA != pA)
 -	{
 -		itemData[LINKSET_WALKABILITY_A_FIELD] = llclamp(pA, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
 -	}
 -
 -	if (mWalkabilityCoefficientB != pB)
 -	{
 -		itemData[LINKSET_WALKABILITY_B_FIELD] = llclamp(pB, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
 -	}
 -
 -	if (mWalkabilityCoefficientC != pC)
 -	{
 -		itemData[LINKSET_WALKABILITY_C_FIELD] = llclamp(pC, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
 -	}
 -
 -	if (mWalkabilityCoefficientD != pD)
 -	{
 -		itemData[LINKSET_WALKABILITY_D_FIELD] = llclamp(pD, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
 -	}
 -
 -	return itemData;
 -}
 -
 -void LLPathfindingLinkset::parseObjectData(const LLSD &pLinksetItem)
 -{
 -	llassert(pLinksetItem.has(LINKSET_NAME_FIELD));
 -	llassert(pLinksetItem.get(LINKSET_NAME_FIELD).isString());
 -	mName = pLinksetItem.get(LINKSET_NAME_FIELD).asString();
 -	
 -	llassert(pLinksetItem.has(LINKSET_DESCRIPTION_FIELD));
 -	llassert(pLinksetItem.get(LINKSET_DESCRIPTION_FIELD).isString());
 -	mDescription = pLinksetItem.get(LINKSET_DESCRIPTION_FIELD).asString();
 -	
 -	llassert(pLinksetItem.has(LINKSET_LAND_IMPACT_FIELD));
 -	llassert(pLinksetItem.get(LINKSET_LAND_IMPACT_FIELD).isInteger());
 -	llassert(pLinksetItem.get(LINKSET_LAND_IMPACT_FIELD).asInteger() >= 0);
 -	mLandImpact = pLinksetItem.get(LINKSET_LAND_IMPACT_FIELD).asInteger();
 -	
 -#ifdef MISSING_MODIFIABLE_FIELD_WAR
 -	mHasModifiable = pLinksetItem.has(LINKSET_MODIFIABLE_FIELD);
 -	if (mHasModifiable)
 -	{
 -		llassert(pLinksetItem.get(LINKSET_MODIFIABLE_FIELD).isBoolean());
 -		mIsModifiable = pLinksetItem.get(LINKSET_MODIFIABLE_FIELD).asBoolean();
 -	}
 -#else // MISSING_MODIFIABLE_FIELD_WAR
 -	llassert(pLinksetItem.has(LINKSET_MODIFIABLE_FIELD));
 -	llassert(pLinksetItem.get(LINKSET_MODIFIABLE_FIELD).isBoolean());
 -	mIsModifiable = pLinksetItem.get(LINKSET_MODIFIABLE_FIELD).asBoolean();
 -#endif // MISSING_MODIFIABLE_FIELD_WAR
 -	
 -	llassert(pLinksetItem.has(LINKSET_POSITION_FIELD));
 -	llassert(pLinksetItem.get(LINKSET_POSITION_FIELD).isArray());
 -	mLocation.setValue(pLinksetItem.get(LINKSET_POSITION_FIELD));
 -}
 -
 -void LLPathfindingLinkset::parsePathfindingData(const LLSD &pLinksetItem)
 -{
 -	bool isPhantom = false;
 -	if (pLinksetItem.has(LINKSET_PHANTOM_FIELD))
 -	{
 -		llassert(pLinksetItem.get(LINKSET_PHANTOM_FIELD).isBoolean());
 -		isPhantom = pLinksetItem.get(LINKSET_PHANTOM_FIELD).asBoolean();
 -	}
 -	
 -#ifdef DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS
 -	if (pLinksetItem.has(LINKSET_CATEGORY_FIELD))
 -	{
 -		mLinksetUse = getLinksetUse(isPhantom, convertCategoryFromLLSD(pLinksetItem.get(LINKSET_CATEGORY_FIELD)));
 -	}
 -	else
 -	{
 -		llassert(pLinksetItem.has(DEPRECATED_LINKSET_PERMANENT_FIELD));
 -		llassert(pLinksetItem.get(DEPRECATED_LINKSET_PERMANENT_FIELD).isBoolean());
 -		bool isPermanent = pLinksetItem.get(DEPRECATED_LINKSET_PERMANENT_FIELD).asBoolean();
 -
 -		llassert(pLinksetItem.has(DEPRECATED_LINKSET_WALKABLE_FIELD));
 -		llassert(pLinksetItem.get(DEPRECATED_LINKSET_WALKABLE_FIELD).isBoolean());
 -		bool isWalkable = pLinksetItem.get(DEPRECATED_LINKSET_WALKABLE_FIELD).asBoolean();
 -
 -		mLinksetUse = getLinksetUse(isPhantom, isPermanent, isWalkable);
 -	}
 -#else // DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS
 -	llassert(pLinksetItem.has(LINKSET_CATEGORY_FIELD));
 -	mLinksetUse = getLinksetUse(isPhantom, convertCategoryFromLLSD(pLinksetItem.get(LINKSET_CATEGORY_FIELD)));
 -#endif // DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS
 -
 -	if (pLinksetItem.has(LINKSET_CAN_BE_VOLUME))
 -	{
 -		llassert(pLinksetItem.get(LINKSET_CAN_BE_VOLUME).isBoolean());
 -		mCanBeVolume = pLinksetItem.get(LINKSET_CAN_BE_VOLUME).asBoolean();
 -	}
 -
 -	llassert(pLinksetItem.has(LINKSET_WALKABILITY_A_FIELD));
 -	llassert(pLinksetItem.get(LINKSET_WALKABILITY_A_FIELD).isInteger());
 -	mWalkabilityCoefficientA = pLinksetItem.get(LINKSET_WALKABILITY_A_FIELD).asInteger();
 -	llassert(mWalkabilityCoefficientA >= MIN_WALKABILITY_VALUE);
 -	llassert(mWalkabilityCoefficientA <= MAX_WALKABILITY_VALUE);
 -	
 -	llassert(pLinksetItem.has(LINKSET_WALKABILITY_B_FIELD));
 -	llassert(pLinksetItem.get(LINKSET_WALKABILITY_B_FIELD).isInteger());
 -	mWalkabilityCoefficientB = pLinksetItem.get(LINKSET_WALKABILITY_B_FIELD).asInteger();
 -	llassert(mWalkabilityCoefficientB >= MIN_WALKABILITY_VALUE);
 -	llassert(mWalkabilityCoefficientB <= MAX_WALKABILITY_VALUE);
 -	
 -	llassert(pLinksetItem.has(LINKSET_WALKABILITY_C_FIELD));
 -	llassert(pLinksetItem.get(LINKSET_WALKABILITY_C_FIELD).isInteger());
 -	mWalkabilityCoefficientC = pLinksetItem.get(LINKSET_WALKABILITY_C_FIELD).asInteger();
 -	llassert(mWalkabilityCoefficientC >= MIN_WALKABILITY_VALUE);
 -	llassert(mWalkabilityCoefficientC <= MAX_WALKABILITY_VALUE);
 -	
 -	llassert(pLinksetItem.has(LINKSET_WALKABILITY_D_FIELD));
 -	llassert(pLinksetItem.get(LINKSET_WALKABILITY_D_FIELD).isInteger());
 -	mWalkabilityCoefficientD = pLinksetItem.get(LINKSET_WALKABILITY_D_FIELD).asInteger();
 -	llassert(mWalkabilityCoefficientD >= MIN_WALKABILITY_VALUE);
 -	llassert(mWalkabilityCoefficientD <= MAX_WALKABILITY_VALUE);
 -}
 -
 -#ifdef DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS
 -LLPathfindingLinkset::ELinksetUse LLPathfindingLinkset::getLinksetUse(bool pIsPhantom, bool pIsPermanent, bool pIsWalkable)
 -{
 -	return (pIsPhantom ? (pIsPermanent ? (pIsWalkable ? kMaterialVolume : kExclusionVolume) : kDynamicPhantom) :
 -		(pIsPermanent ? (pIsWalkable ? kWalkable : kStaticObstacle) : kDynamicObstacle));
 -}
 -
 -BOOL LLPathfindingLinkset::isPermanent(ELinksetUse pLinksetUse)
 -{
 -	BOOL retVal;
 -
 -	switch (pLinksetUse)
 -	{
 -	case kWalkable :
 -	case kStaticObstacle :
 -	case kMaterialVolume :
 -	case kExclusionVolume :
 -		retVal = true;
 -		break;
 -	case kDynamicObstacle :
 -	case kDynamicPhantom :
 -		retVal = false;
 -		break;
 -	case kUnknown :
 -	default :
 -		retVal = false;
 -		llassert(0);
 -		break;
 -	}
 -
 -	return retVal;
 -}
 -
 -BOOL LLPathfindingLinkset::isWalkable(ELinksetUse pLinksetUse)
 -{
 -	BOOL retVal;
 -
 -	switch (pLinksetUse)
 -	{
 -	case kWalkable :
 -	case kMaterialVolume :
 -		retVal = true;
 -		break;
 -	case kStaticObstacle :
 -	case kDynamicObstacle :
 -	case kExclusionVolume :
 -	case kDynamicPhantom :
 -		retVal = false;
 -		break;
 -	case kUnknown :
 -	default :
 -		retVal = false;
 -		llassert(0);
 -		break;
 -	}
 -
 -	return retVal;
 -}
 -#endif // DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS
 -
 -BOOL LLPathfindingLinkset::isPhantom(ELinksetUse pLinksetUse)
 -{
 -	BOOL retVal;
 -
 -	switch (pLinksetUse)
 -	{
 -	case kWalkable :
 -	case kStaticObstacle :
 -	case kDynamicObstacle :
 -		retVal = false;
 -		break;
 -	case kMaterialVolume :
 -	case kExclusionVolume :
 -	case kDynamicPhantom :
 -		retVal = true;
 -		break;
 -	case kUnknown :
 -	default :
 -		retVal = false;
 -		llassert(0);
 -		break;
 -	}
 -
 -	return retVal;
 -}
 -
 -LLPathfindingLinkset::ELinksetUse LLPathfindingLinkset::getLinksetUse(bool pIsPhantom, ENavMeshGenerationCategory pNavMeshGenerationCategory)
 -{
 -	ELinksetUse linksetUse = kUnknown;
 -
 -	if (pIsPhantom)
 -	{
 -		switch (pNavMeshGenerationCategory)
 -		{
 -		case kNavMeshGenerationIgnore :
 -			linksetUse = kDynamicPhantom;
 -			break;
 -		case kNavMeshGenerationInclude :
 -			linksetUse = kMaterialVolume;
 -			break;
 -		case kNavMeshGenerationExclude :
 -			linksetUse = kExclusionVolume;
 -			break;
 -		default :
 -			linksetUse = kUnknown;
 -			llassert(0);
 -			break;
 -		}
 -	}
 -	else
 -	{
 -		switch (pNavMeshGenerationCategory)
 -		{
 -		case kNavMeshGenerationIgnore :
 -			linksetUse = kDynamicObstacle;
 -			break;
 -		case kNavMeshGenerationInclude :
 -			linksetUse = kWalkable;
 -			break;
 -		case kNavMeshGenerationExclude :
 -			linksetUse = kStaticObstacle;
 -			break;
 -		default :
 -			linksetUse = kUnknown;
 -			llassert(0);
 -			break;
 -		}
 -	}
 -
 -	return linksetUse;
 -}
 -
 -LLPathfindingLinkset::ENavMeshGenerationCategory LLPathfindingLinkset::getNavMeshGenerationCategory(ELinksetUse pLinksetUse)
 -{
 -	ENavMeshGenerationCategory navMeshGenerationCategory;
 -	switch (pLinksetUse)
 -	{
 -	case kWalkable :
 -	case kMaterialVolume :
 -		navMeshGenerationCategory = kNavMeshGenerationInclude;
 -		break;
 -	case kStaticObstacle :
 -	case kExclusionVolume :
 -		navMeshGenerationCategory = kNavMeshGenerationExclude;
 -		break;
 -	case kDynamicObstacle :
 -	case kDynamicPhantom :
 -		navMeshGenerationCategory = kNavMeshGenerationIgnore;
 -		break;
 -	case kUnknown :
 -	default :
 -		navMeshGenerationCategory = kNavMeshGenerationIgnore;
 -		llassert(0);
 -		break;
 -	}
 -
 -	return navMeshGenerationCategory;
 -}
 -
 -LLSD LLPathfindingLinkset::convertCategoryToLLSD(ENavMeshGenerationCategory pNavMeshGenerationCategory)
 -{
 -	LLSD llsd;
 -
 -	switch (pNavMeshGenerationCategory)
 -	{
 -		case kNavMeshGenerationIgnore :
 -			llsd = static_cast<S32>(LINKSET_CATEGORY_VALUE_IGNORE);
 -			break;
 -		case kNavMeshGenerationInclude :
 -			llsd = static_cast<S32>(LINKSET_CATEGORY_VALUE_INCLUDE);
 -			break;
 -		case kNavMeshGenerationExclude :
 -			llsd = static_cast<S32>(LINKSET_CATEGORY_VALUE_EXCLUDE);
 -			break;
 -		default :
 -			llsd = static_cast<S32>(LINKSET_CATEGORY_VALUE_IGNORE);
 -			llassert(0);
 -			break;
 -	}
 -
 -	return llsd;
 -}
 -
 -LLPathfindingLinkset::ENavMeshGenerationCategory LLPathfindingLinkset::convertCategoryFromLLSD(const LLSD &llsd)
 -{
 -	ENavMeshGenerationCategory navMeshGenerationCategory;
 -
 -	llassert(llsd.isInteger());
 -	switch (llsd.asInteger())
 -	{
 -		case LINKSET_CATEGORY_VALUE_IGNORE :
 -			navMeshGenerationCategory = kNavMeshGenerationIgnore;
 -			break;
 -		case LINKSET_CATEGORY_VALUE_INCLUDE :
 -			navMeshGenerationCategory = kNavMeshGenerationInclude;
 -			break;
 -		case LINKSET_CATEGORY_VALUE_EXCLUDE :
 -			navMeshGenerationCategory = kNavMeshGenerationExclude;
 -			break;
 -		default :
 -			navMeshGenerationCategory = kNavMeshGenerationIgnore;
 -			llassert(0);
 -			break;
 -	}
 -
 -	return navMeshGenerationCategory;
 -}
 +/**  + * @file llpathfindinglinksets.cpp + * @author William Todd Stinson + * @brief Definition of a pathfinding linkset that contains various properties required for havok pathfinding. + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llpathfindinglinkset.h" +#include "llsd.h" +#include "v3math.h" +#include "lluuid.h" + +#define LINKSET_NAME_FIELD                 "name" +#define LINKSET_DESCRIPTION_FIELD          "description" +#define LINKSET_LAND_IMPACT_FIELD          "landimpact" +#define LINKSET_MODIFIABLE_FIELD           "modifiable" +#ifdef DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS +#define DEPRECATED_LINKSET_PERMANENT_FIELD "permanent" +#define DEPRECATED_LINKSET_WALKABLE_FIELD  "walkable" +#endif // DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS +#define LINKSET_CATEGORY_FIELD             "navmesh_category" +#define LINKSET_CAN_BE_VOLUME              "can_be_volume" +#define LINKSET_PHANTOM_FIELD              "phantom" +#define LINKSET_WALKABILITY_A_FIELD        "A" +#define LINKSET_WALKABILITY_B_FIELD        "B" +#define LINKSET_WALKABILITY_C_FIELD        "C" +#define LINKSET_WALKABILITY_D_FIELD        "D" +#define LINKSET_POSITION_FIELD             "position" + +#define LINKSET_CATEGORY_VALUE_INCLUDE 0 +#define LINKSET_CATEGORY_VALUE_EXCLUDE 1 +#define LINKSET_CATEGORY_VALUE_IGNORE  2 + +//--------------------------------------------------------------------------- +// LLPathfindingLinkset +//--------------------------------------------------------------------------- + +const S32 LLPathfindingLinkset::MIN_WALKABILITY_VALUE(0); +const S32 LLPathfindingLinkset::MAX_WALKABILITY_VALUE(100); + +LLPathfindingLinkset::LLPathfindingLinkset(const LLSD& pTerrainLinksetItem) +	: mUUID(), +	mIsTerrain(true), +	mName(), +	mDescription(), +	mLandImpact(0U), +	mLocation(LLVector3::zero), +#ifdef MISSING_MODIFIABLE_FIELD_WAR +	mHasModifiable(true), +#endif // MISSING_MODIFIABLE_FIELD_WAR +	mIsModifiable(FALSE), +	mCanBeVolume(FALSE), +	mLinksetUse(kUnknown), +	mWalkabilityCoefficientA(MIN_WALKABILITY_VALUE), +	mWalkabilityCoefficientB(MIN_WALKABILITY_VALUE), +	mWalkabilityCoefficientC(MIN_WALKABILITY_VALUE), +	mWalkabilityCoefficientD(MIN_WALKABILITY_VALUE) +{ +	parsePathfindingData(pTerrainLinksetItem); +} + +LLPathfindingLinkset::LLPathfindingLinkset(const std::string &pUUID, const LLSD& pLinksetItem) +	: mUUID(pUUID), +	mIsTerrain(false), +	mName(), +	mDescription(), +	mLandImpact(0U), +	mLocation(LLVector3::zero), +#ifdef MISSING_MODIFIABLE_FIELD_WAR +	mHasModifiable(false), +#endif // MISSING_MODIFIABLE_FIELD_WAR +	mIsModifiable(TRUE), +	mCanBeVolume(TRUE), +	mLinksetUse(kUnknown), +	mWalkabilityCoefficientA(MIN_WALKABILITY_VALUE), +	mWalkabilityCoefficientB(MIN_WALKABILITY_VALUE), +	mWalkabilityCoefficientC(MIN_WALKABILITY_VALUE), +	mWalkabilityCoefficientD(MIN_WALKABILITY_VALUE) +{ +	parseObjectData(pLinksetItem); +	parsePathfindingData(pLinksetItem); +} + +LLPathfindingLinkset::LLPathfindingLinkset(const LLPathfindingLinkset& pOther) +	: mUUID(pOther.mUUID), +	mName(pOther.mName), +	mDescription(pOther.mDescription), +	mLandImpact(pOther.mLandImpact), +	mLocation(pOther.mLocation), +#ifdef MISSING_MODIFIABLE_FIELD_WAR +	mHasModifiable(pOther.mHasModifiable), +	mIsModifiable(pOther.mHasModifiable ? pOther.mIsModifiable : TRUE), +#else // MISSING_MODIFIABLE_FIELD_WAR +	mIsModifiable(pOther.mIsModifiable), +#endif // MISSING_MODIFIABLE_FIELD_WAR +	mCanBeVolume(pOther.mCanBeVolume), +	mLinksetUse(pOther.mLinksetUse), +	mWalkabilityCoefficientA(pOther.mWalkabilityCoefficientA), +	mWalkabilityCoefficientB(pOther.mWalkabilityCoefficientB), +	mWalkabilityCoefficientC(pOther.mWalkabilityCoefficientC), +	mWalkabilityCoefficientD(pOther.mWalkabilityCoefficientD) +{ +} + +LLPathfindingLinkset::~LLPathfindingLinkset() +{ +} + +LLPathfindingLinkset& LLPathfindingLinkset::operator =(const LLPathfindingLinkset& pOther) +{ +	mUUID = pOther.mUUID; +	mName = pOther.mName; +	mDescription = pOther.mDescription; +	mLandImpact = pOther.mLandImpact; +	mLocation = pOther.mLocation; +#ifdef MISSING_MODIFIABLE_FIELD_WAR +	if (pOther.mHasModifiable) +	{ +		mHasModifiable = pOther.mHasModifiable; +		mIsModifiable = pOther.mIsModifiable; +	} +#else // MISSING_MODIFIABLE_FIELD_WAR +	mIsModifiable = pOther.mIsModifiable; +#endif // MISSING_MODIFIABLE_FIELD_WAR +	mCanBeVolume = pOther.mCanBeVolume; +	mLinksetUse = pOther.mLinksetUse; +	mWalkabilityCoefficientA = pOther.mWalkabilityCoefficientA; +	mWalkabilityCoefficientB = pOther.mWalkabilityCoefficientB; +	mWalkabilityCoefficientC = pOther.mWalkabilityCoefficientC; +	mWalkabilityCoefficientD = pOther.mWalkabilityCoefficientD; + +	return *this; +} + +BOOL LLPathfindingLinkset::isPhantom() const +{ +	return isPhantom(getLinksetUse()); +} + +LLPathfindingLinkset::ELinksetUse LLPathfindingLinkset::getLinksetUseWithToggledPhantom(ELinksetUse pLinksetUse) +{ +	BOOL isPhantom = LLPathfindingLinkset::isPhantom(pLinksetUse); +	ENavMeshGenerationCategory navMeshGenerationCategory = getNavMeshGenerationCategory(pLinksetUse); + +	return getLinksetUse(!isPhantom, navMeshGenerationCategory); +} + +bool LLPathfindingLinkset::isShowUnmodifiablePhantomWarning(ELinksetUse pLinksetUse) const +{ +	return (!isModifiable() && (isPhantom() != isPhantom(pLinksetUse))); +} + +bool LLPathfindingLinkset::isShowCannotBeVolumeWarning(ELinksetUse pLinksetUse) const +{ +	return (!canBeVolume() && ((pLinksetUse == kMaterialVolume) || (pLinksetUse == kExclusionVolume))); +} + +LLSD LLPathfindingLinkset::encodeAlteredFields(ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const +{ +	LLSD itemData; + +	if (!isTerrain() && (pLinksetUse != kUnknown) && (getLinksetUse() != pLinksetUse) && +		(canBeVolume() || ((pLinksetUse != kMaterialVolume) && (pLinksetUse != kExclusionVolume)))) +	{ +		if (isModifiable()) +		{ +			itemData[LINKSET_PHANTOM_FIELD] = static_cast<bool>(isPhantom(pLinksetUse)); +		} + +#ifdef DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS +		itemData[DEPRECATED_LINKSET_PERMANENT_FIELD] = static_cast<bool>(isPermanent(pLinksetUse)); +		itemData[DEPRECATED_LINKSET_WALKABLE_FIELD] = static_cast<bool>(isWalkable(pLinksetUse)); +#endif // DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS +		itemData[LINKSET_CATEGORY_FIELD] = convertCategoryToLLSD(getNavMeshGenerationCategory(pLinksetUse)); +	} + +	if (mWalkabilityCoefficientA != pA) +	{ +		itemData[LINKSET_WALKABILITY_A_FIELD] = llclamp(pA, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE); +	} + +	if (mWalkabilityCoefficientB != pB) +	{ +		itemData[LINKSET_WALKABILITY_B_FIELD] = llclamp(pB, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE); +	} + +	if (mWalkabilityCoefficientC != pC) +	{ +		itemData[LINKSET_WALKABILITY_C_FIELD] = llclamp(pC, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE); +	} + +	if (mWalkabilityCoefficientD != pD) +	{ +		itemData[LINKSET_WALKABILITY_D_FIELD] = llclamp(pD, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE); +	} + +	return itemData; +} + +void LLPathfindingLinkset::parseObjectData(const LLSD &pLinksetItem) +{ +	llassert(pLinksetItem.has(LINKSET_NAME_FIELD)); +	llassert(pLinksetItem.get(LINKSET_NAME_FIELD).isString()); +	mName = pLinksetItem.get(LINKSET_NAME_FIELD).asString(); +	 +	llassert(pLinksetItem.has(LINKSET_DESCRIPTION_FIELD)); +	llassert(pLinksetItem.get(LINKSET_DESCRIPTION_FIELD).isString()); +	mDescription = pLinksetItem.get(LINKSET_DESCRIPTION_FIELD).asString(); +	 +	llassert(pLinksetItem.has(LINKSET_LAND_IMPACT_FIELD)); +	llassert(pLinksetItem.get(LINKSET_LAND_IMPACT_FIELD).isInteger()); +	llassert(pLinksetItem.get(LINKSET_LAND_IMPACT_FIELD).asInteger() >= 0); +	mLandImpact = pLinksetItem.get(LINKSET_LAND_IMPACT_FIELD).asInteger(); +	 +#ifdef MISSING_MODIFIABLE_FIELD_WAR +	mHasModifiable = pLinksetItem.has(LINKSET_MODIFIABLE_FIELD); +	if (mHasModifiable) +	{ +		llassert(pLinksetItem.get(LINKSET_MODIFIABLE_FIELD).isBoolean()); +		mIsModifiable = pLinksetItem.get(LINKSET_MODIFIABLE_FIELD).asBoolean(); +	} +#else // MISSING_MODIFIABLE_FIELD_WAR +	llassert(pLinksetItem.has(LINKSET_MODIFIABLE_FIELD)); +	llassert(pLinksetItem.get(LINKSET_MODIFIABLE_FIELD).isBoolean()); +	mIsModifiable = pLinksetItem.get(LINKSET_MODIFIABLE_FIELD).asBoolean(); +#endif // MISSING_MODIFIABLE_FIELD_WAR +	 +	llassert(pLinksetItem.has(LINKSET_POSITION_FIELD)); +	llassert(pLinksetItem.get(LINKSET_POSITION_FIELD).isArray()); +	mLocation.setValue(pLinksetItem.get(LINKSET_POSITION_FIELD)); +} + +void LLPathfindingLinkset::parsePathfindingData(const LLSD &pLinksetItem) +{ +	bool isPhantom = false; +	if (pLinksetItem.has(LINKSET_PHANTOM_FIELD)) +	{ +		llassert(pLinksetItem.get(LINKSET_PHANTOM_FIELD).isBoolean()); +		isPhantom = pLinksetItem.get(LINKSET_PHANTOM_FIELD).asBoolean(); +	} +	 +#ifdef DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS +	if (pLinksetItem.has(LINKSET_CATEGORY_FIELD)) +	{ +		mLinksetUse = getLinksetUse(isPhantom, convertCategoryFromLLSD(pLinksetItem.get(LINKSET_CATEGORY_FIELD))); +	} +	else +	{ +		llassert(pLinksetItem.has(DEPRECATED_LINKSET_PERMANENT_FIELD)); +		llassert(pLinksetItem.get(DEPRECATED_LINKSET_PERMANENT_FIELD).isBoolean()); +		bool isPermanent = pLinksetItem.get(DEPRECATED_LINKSET_PERMANENT_FIELD).asBoolean(); + +		llassert(pLinksetItem.has(DEPRECATED_LINKSET_WALKABLE_FIELD)); +		llassert(pLinksetItem.get(DEPRECATED_LINKSET_WALKABLE_FIELD).isBoolean()); +		bool isWalkable = pLinksetItem.get(DEPRECATED_LINKSET_WALKABLE_FIELD).asBoolean(); + +		mLinksetUse = getLinksetUse(isPhantom, isPermanent, isWalkable); +	} +#else // DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS +	llassert(pLinksetItem.has(LINKSET_CATEGORY_FIELD)); +	mLinksetUse = getLinksetUse(isPhantom, convertCategoryFromLLSD(pLinksetItem.get(LINKSET_CATEGORY_FIELD))); +#endif // DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS + +	if (pLinksetItem.has(LINKSET_CAN_BE_VOLUME)) +	{ +		llassert(pLinksetItem.get(LINKSET_CAN_BE_VOLUME).isBoolean()); +		mCanBeVolume = pLinksetItem.get(LINKSET_CAN_BE_VOLUME).asBoolean(); +	} + +	llassert(pLinksetItem.has(LINKSET_WALKABILITY_A_FIELD)); +	llassert(pLinksetItem.get(LINKSET_WALKABILITY_A_FIELD).isInteger()); +	mWalkabilityCoefficientA = pLinksetItem.get(LINKSET_WALKABILITY_A_FIELD).asInteger(); +	llassert(mWalkabilityCoefficientA >= MIN_WALKABILITY_VALUE); +	llassert(mWalkabilityCoefficientA <= MAX_WALKABILITY_VALUE); +	 +	llassert(pLinksetItem.has(LINKSET_WALKABILITY_B_FIELD)); +	llassert(pLinksetItem.get(LINKSET_WALKABILITY_B_FIELD).isInteger()); +	mWalkabilityCoefficientB = pLinksetItem.get(LINKSET_WALKABILITY_B_FIELD).asInteger(); +	llassert(mWalkabilityCoefficientB >= MIN_WALKABILITY_VALUE); +	llassert(mWalkabilityCoefficientB <= MAX_WALKABILITY_VALUE); +	 +	llassert(pLinksetItem.has(LINKSET_WALKABILITY_C_FIELD)); +	llassert(pLinksetItem.get(LINKSET_WALKABILITY_C_FIELD).isInteger()); +	mWalkabilityCoefficientC = pLinksetItem.get(LINKSET_WALKABILITY_C_FIELD).asInteger(); +	llassert(mWalkabilityCoefficientC >= MIN_WALKABILITY_VALUE); +	llassert(mWalkabilityCoefficientC <= MAX_WALKABILITY_VALUE); +	 +	llassert(pLinksetItem.has(LINKSET_WALKABILITY_D_FIELD)); +	llassert(pLinksetItem.get(LINKSET_WALKABILITY_D_FIELD).isInteger()); +	mWalkabilityCoefficientD = pLinksetItem.get(LINKSET_WALKABILITY_D_FIELD).asInteger(); +	llassert(mWalkabilityCoefficientD >= MIN_WALKABILITY_VALUE); +	llassert(mWalkabilityCoefficientD <= MAX_WALKABILITY_VALUE); +} + +#ifdef DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS +LLPathfindingLinkset::ELinksetUse LLPathfindingLinkset::getLinksetUse(bool pIsPhantom, bool pIsPermanent, bool pIsWalkable) +{ +	return (pIsPhantom ? (pIsPermanent ? (pIsWalkable ? kMaterialVolume : kExclusionVolume) : kDynamicPhantom) : +		(pIsPermanent ? (pIsWalkable ? kWalkable : kStaticObstacle) : kDynamicObstacle)); +} + +BOOL LLPathfindingLinkset::isPermanent(ELinksetUse pLinksetUse) +{ +	BOOL retVal; + +	switch (pLinksetUse) +	{ +	case kWalkable : +	case kStaticObstacle : +	case kMaterialVolume : +	case kExclusionVolume : +		retVal = true; +		break; +	case kDynamicObstacle : +	case kDynamicPhantom : +		retVal = false; +		break; +	case kUnknown : +	default : +		retVal = false; +		llassert(0); +		break; +	} + +	return retVal; +} + +BOOL LLPathfindingLinkset::isWalkable(ELinksetUse pLinksetUse) +{ +	BOOL retVal; + +	switch (pLinksetUse) +	{ +	case kWalkable : +	case kMaterialVolume : +		retVal = true; +		break; +	case kStaticObstacle : +	case kDynamicObstacle : +	case kExclusionVolume : +	case kDynamicPhantom : +		retVal = false; +		break; +	case kUnknown : +	default : +		retVal = false; +		llassert(0); +		break; +	} + +	return retVal; +} +#endif // DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS + +BOOL LLPathfindingLinkset::isPhantom(ELinksetUse pLinksetUse) +{ +	BOOL retVal; + +	switch (pLinksetUse) +	{ +	case kWalkable : +	case kStaticObstacle : +	case kDynamicObstacle : +		retVal = false; +		break; +	case kMaterialVolume : +	case kExclusionVolume : +	case kDynamicPhantom : +		retVal = true; +		break; +	case kUnknown : +	default : +		retVal = false; +		llassert(0); +		break; +	} + +	return retVal; +} + +LLPathfindingLinkset::ELinksetUse LLPathfindingLinkset::getLinksetUse(bool pIsPhantom, ENavMeshGenerationCategory pNavMeshGenerationCategory) +{ +	ELinksetUse linksetUse = kUnknown; + +	if (pIsPhantom) +	{ +		switch (pNavMeshGenerationCategory) +		{ +		case kNavMeshGenerationIgnore : +			linksetUse = kDynamicPhantom; +			break; +		case kNavMeshGenerationInclude : +			linksetUse = kMaterialVolume; +			break; +		case kNavMeshGenerationExclude : +			linksetUse = kExclusionVolume; +			break; +		default : +			linksetUse = kUnknown; +			llassert(0); +			break; +		} +	} +	else +	{ +		switch (pNavMeshGenerationCategory) +		{ +		case kNavMeshGenerationIgnore : +			linksetUse = kDynamicObstacle; +			break; +		case kNavMeshGenerationInclude : +			linksetUse = kWalkable; +			break; +		case kNavMeshGenerationExclude : +			linksetUse = kStaticObstacle; +			break; +		default : +			linksetUse = kUnknown; +			llassert(0); +			break; +		} +	} + +	return linksetUse; +} + +LLPathfindingLinkset::ENavMeshGenerationCategory LLPathfindingLinkset::getNavMeshGenerationCategory(ELinksetUse pLinksetUse) +{ +	ENavMeshGenerationCategory navMeshGenerationCategory; +	switch (pLinksetUse) +	{ +	case kWalkable : +	case kMaterialVolume : +		navMeshGenerationCategory = kNavMeshGenerationInclude; +		break; +	case kStaticObstacle : +	case kExclusionVolume : +		navMeshGenerationCategory = kNavMeshGenerationExclude; +		break; +	case kDynamicObstacle : +	case kDynamicPhantom : +		navMeshGenerationCategory = kNavMeshGenerationIgnore; +		break; +	case kUnknown : +	default : +		navMeshGenerationCategory = kNavMeshGenerationIgnore; +		llassert(0); +		break; +	} + +	return navMeshGenerationCategory; +} + +LLSD LLPathfindingLinkset::convertCategoryToLLSD(ENavMeshGenerationCategory pNavMeshGenerationCategory) +{ +	LLSD llsd; + +	switch (pNavMeshGenerationCategory) +	{ +		case kNavMeshGenerationIgnore : +			llsd = static_cast<S32>(LINKSET_CATEGORY_VALUE_IGNORE); +			break; +		case kNavMeshGenerationInclude : +			llsd = static_cast<S32>(LINKSET_CATEGORY_VALUE_INCLUDE); +			break; +		case kNavMeshGenerationExclude : +			llsd = static_cast<S32>(LINKSET_CATEGORY_VALUE_EXCLUDE); +			break; +		default : +			llsd = static_cast<S32>(LINKSET_CATEGORY_VALUE_IGNORE); +			llassert(0); +			break; +	} + +	return llsd; +} + +LLPathfindingLinkset::ENavMeshGenerationCategory LLPathfindingLinkset::convertCategoryFromLLSD(const LLSD &llsd) +{ +	ENavMeshGenerationCategory navMeshGenerationCategory; + +	llassert(llsd.isInteger()); +	switch (llsd.asInteger()) +	{ +		case LINKSET_CATEGORY_VALUE_IGNORE : +			navMeshGenerationCategory = kNavMeshGenerationIgnore; +			break; +		case LINKSET_CATEGORY_VALUE_INCLUDE : +			navMeshGenerationCategory = kNavMeshGenerationInclude; +			break; +		case LINKSET_CATEGORY_VALUE_EXCLUDE : +			navMeshGenerationCategory = kNavMeshGenerationExclude; +			break; +		default : +			navMeshGenerationCategory = kNavMeshGenerationIgnore; +			llassert(0); +			break; +	} + +	return navMeshGenerationCategory; +} diff --git a/indra/newview/llpathfindinglinkset.h b/indra/newview/llpathfindinglinkset.h index d8c1c9d795..6dfac31931 100644 --- a/indra/newview/llpathfindinglinkset.h +++ b/indra/newview/llpathfindinglinkset.h @@ -1,132 +1,132 @@ -/** 
 - * @file llpathfindinglinkset.h
 - * @author William Todd Stinson
 - * @brief Definition of a pathfinding linkset that contains various properties required for havok pathfinding.
 - *
 - * $LicenseInfo:firstyear=2002&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc.
 - * 
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - * 
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - * 
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - * 
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#ifndef LL_LLPATHFINDINGLINKSET_H
 -#define LL_LLPATHFINDINGLINKSET_H
 -
 -#include "v3math.h"
 -#include "lluuid.h"
 -
 -#include <boost/shared_ptr.hpp>
 -
 -class LLSD;
 -class LLPathfindingLinkset;
 -
 -typedef boost::shared_ptr<LLPathfindingLinkset> LLPathfindingLinksetPtr;
 -
 -#define DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS
 -#define MISSING_MODIFIABLE_FIELD_WAR
 -
 -class LLPathfindingLinkset
 -{
 -public:
 -	typedef enum
 -	{
 -		kUnknown,
 -		kWalkable,
 -		kStaticObstacle,
 -		kDynamicObstacle,
 -		kMaterialVolume,
 -		kExclusionVolume,
 -		kDynamicPhantom
 -	} ELinksetUse;
 -
 -	LLPathfindingLinkset(const LLSD &pTerrainLinksetItem);
 -	LLPathfindingLinkset(const std::string &pUUID, const LLSD &pLinksetItem);
 -	LLPathfindingLinkset(const LLPathfindingLinkset& pOther);
 -	virtual ~LLPathfindingLinkset();
 -
 -	LLPathfindingLinkset& operator = (const LLPathfindingLinkset& pOther);
 -
 -	inline bool                       isTerrain() const                   {return mIsTerrain;};
 -	inline const LLUUID&              getUUID() const                     {return mUUID;};
 -	inline const std::string&         getName() const                     {return mName;};
 -	inline const std::string&         getDescription() const              {return mDescription;};
 -	inline U32                        getLandImpact() const               {return mLandImpact;};
 -	inline const LLVector3&           getLocation() const                 {return mLocation;};
 -	BOOL                              isModifiable() const                {return mIsModifiable;};
 -	BOOL                              isPhantom() const;
 -	BOOL                              canBeVolume() const                 {return mCanBeVolume;};
 -	static ELinksetUse                getLinksetUseWithToggledPhantom(ELinksetUse pLinksetUse);
 -
 -	inline ELinksetUse                getLinksetUse() const               {return mLinksetUse;};
 -
 -	inline S32                        getWalkabilityCoefficientA() const  {return mWalkabilityCoefficientA;};
 -	inline S32                        getWalkabilityCoefficientB() const  {return mWalkabilityCoefficientB;};
 -	inline S32                        getWalkabilityCoefficientC() const  {return mWalkabilityCoefficientC;};
 -	inline S32                        getWalkabilityCoefficientD() const  {return mWalkabilityCoefficientD;};
 -
 -	bool                              isShowUnmodifiablePhantomWarning(ELinksetUse pLinksetUse) const;
 -	bool                              isShowCannotBeVolumeWarning(ELinksetUse pLinksetUse) const;
 -	LLSD                              encodeAlteredFields(ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const;
 -
 -	static const S32 MIN_WALKABILITY_VALUE;
 -	static const S32 MAX_WALKABILITY_VALUE;
 -	
 -protected:
 -
 -private:
 -	typedef enum
 -	{
 -		kNavMeshGenerationIgnore,
 -		kNavMeshGenerationInclude,
 -		kNavMeshGenerationExclude
 -	} ENavMeshGenerationCategory;
 -
 -	void                              parseObjectData(const LLSD &pLinksetItem);
 -	void                              parsePathfindingData(const LLSD &pLinksetItem);
 -
 -#ifdef DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS
 -	static ELinksetUse                getLinksetUse(bool pIsPhantom, bool pIsPermanent, bool pIsWalkable);
 -	static BOOL                       isPermanent(ELinksetUse pLinksetUse);
 -	static BOOL                       isWalkable(ELinksetUse pLinksetUse);
 -#endif // DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS
 -	static BOOL                       isPhantom(ELinksetUse pLinksetUse);
 -	static ELinksetUse                getLinksetUse(bool pIsPhantom, ENavMeshGenerationCategory pNavMeshGenerationCategory);
 -	static ENavMeshGenerationCategory getNavMeshGenerationCategory(ELinksetUse pLinksetUse);
 -	static LLSD                       convertCategoryToLLSD(ENavMeshGenerationCategory pNavMeshGenerationCategory);
 -	static ENavMeshGenerationCategory convertCategoryFromLLSD(const LLSD &llsd);
 -
 -	LLUUID       mUUID;
 -	bool         mIsTerrain;
 -	std::string  mName;
 -	std::string  mDescription;
 -	U32          mLandImpact;
 -	LLVector3    mLocation;
 -#ifdef MISSING_MODIFIABLE_FIELD_WAR
 -	bool         mHasModifiable;
 -#endif // MISSING_MODIFIABLE_FIELD_WAR
 -	BOOL         mIsModifiable;
 -	BOOL         mCanBeVolume;
 -	ELinksetUse  mLinksetUse;
 -	S32          mWalkabilityCoefficientA;
 -	S32          mWalkabilityCoefficientB;
 -	S32          mWalkabilityCoefficientC;
 -	S32          mWalkabilityCoefficientD;
 -};
 -
 -#endif // LL_LLPATHFINDINGLINKSET_H
 +/**  + * @file llpathfindinglinkset.h + * @author William Todd Stinson + * @brief Definition of a pathfinding linkset that contains various properties required for havok pathfinding. + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPATHFINDINGLINKSET_H +#define LL_LLPATHFINDINGLINKSET_H + +#include "v3math.h" +#include "lluuid.h" + +#include <boost/shared_ptr.hpp> + +class LLSD; +class LLPathfindingLinkset; + +typedef boost::shared_ptr<LLPathfindingLinkset> LLPathfindingLinksetPtr; + +#define DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS +#define MISSING_MODIFIABLE_FIELD_WAR + +class LLPathfindingLinkset +{ +public: +	typedef enum +	{ +		kUnknown, +		kWalkable, +		kStaticObstacle, +		kDynamicObstacle, +		kMaterialVolume, +		kExclusionVolume, +		kDynamicPhantom +	} ELinksetUse; + +	LLPathfindingLinkset(const LLSD &pTerrainLinksetItem); +	LLPathfindingLinkset(const std::string &pUUID, const LLSD &pLinksetItem); +	LLPathfindingLinkset(const LLPathfindingLinkset& pOther); +	virtual ~LLPathfindingLinkset(); + +	LLPathfindingLinkset& operator = (const LLPathfindingLinkset& pOther); + +	inline bool                       isTerrain() const                   {return mIsTerrain;}; +	inline const LLUUID&              getUUID() const                     {return mUUID;}; +	inline const std::string&         getName() const                     {return mName;}; +	inline const std::string&         getDescription() const              {return mDescription;}; +	inline U32                        getLandImpact() const               {return mLandImpact;}; +	inline const LLVector3&           getLocation() const                 {return mLocation;}; +	BOOL                              isModifiable() const                {return mIsModifiable;}; +	BOOL                              isPhantom() const; +	BOOL                              canBeVolume() const                 {return mCanBeVolume;}; +	static ELinksetUse                getLinksetUseWithToggledPhantom(ELinksetUse pLinksetUse); + +	inline ELinksetUse                getLinksetUse() const               {return mLinksetUse;}; + +	inline S32                        getWalkabilityCoefficientA() const  {return mWalkabilityCoefficientA;}; +	inline S32                        getWalkabilityCoefficientB() const  {return mWalkabilityCoefficientB;}; +	inline S32                        getWalkabilityCoefficientC() const  {return mWalkabilityCoefficientC;}; +	inline S32                        getWalkabilityCoefficientD() const  {return mWalkabilityCoefficientD;}; + +	bool                              isShowUnmodifiablePhantomWarning(ELinksetUse pLinksetUse) const; +	bool                              isShowCannotBeVolumeWarning(ELinksetUse pLinksetUse) const; +	LLSD                              encodeAlteredFields(ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const; + +	static const S32 MIN_WALKABILITY_VALUE; +	static const S32 MAX_WALKABILITY_VALUE; +	 +protected: + +private: +	typedef enum +	{ +		kNavMeshGenerationIgnore, +		kNavMeshGenerationInclude, +		kNavMeshGenerationExclude +	} ENavMeshGenerationCategory; + +	void                              parseObjectData(const LLSD &pLinksetItem); +	void                              parsePathfindingData(const LLSD &pLinksetItem); + +#ifdef DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS +	static ELinksetUse                getLinksetUse(bool pIsPhantom, bool pIsPermanent, bool pIsWalkable); +	static BOOL                       isPermanent(ELinksetUse pLinksetUse); +	static BOOL                       isWalkable(ELinksetUse pLinksetUse); +#endif // DEPRECATED_NAVMESH_PERMANENT_WALKABLE_FLAGS +	static BOOL                       isPhantom(ELinksetUse pLinksetUse); +	static ELinksetUse                getLinksetUse(bool pIsPhantom, ENavMeshGenerationCategory pNavMeshGenerationCategory); +	static ENavMeshGenerationCategory getNavMeshGenerationCategory(ELinksetUse pLinksetUse); +	static LLSD                       convertCategoryToLLSD(ENavMeshGenerationCategory pNavMeshGenerationCategory); +	static ENavMeshGenerationCategory convertCategoryFromLLSD(const LLSD &llsd); + +	LLUUID       mUUID; +	bool         mIsTerrain; +	std::string  mName; +	std::string  mDescription; +	U32          mLandImpact; +	LLVector3    mLocation; +#ifdef MISSING_MODIFIABLE_FIELD_WAR +	bool         mHasModifiable; +#endif // MISSING_MODIFIABLE_FIELD_WAR +	BOOL         mIsModifiable; +	BOOL         mCanBeVolume; +	ELinksetUse  mLinksetUse; +	S32          mWalkabilityCoefficientA; +	S32          mWalkabilityCoefficientB; +	S32          mWalkabilityCoefficientC; +	S32          mWalkabilityCoefficientD; +}; + +#endif // LL_LLPATHFINDINGLINKSET_H diff --git a/indra/newview/llpathfindinglinksetlist.cpp b/indra/newview/llpathfindinglinksetlist.cpp index 57febbf0f2..19a99ef444 100644 --- a/indra/newview/llpathfindinglinksetlist.cpp +++ b/indra/newview/llpathfindinglinksetlist.cpp @@ -1,122 +1,122 @@ -/** 
 - * @file llpathfindinglinksetlist.cpp
 - * @author William Todd Stinson
 - * @brief Class to implement the list of a set of pathfinding linksets
 - *
 - * $LicenseInfo:firstyear=2002&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc.
 - * 
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - * 
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - * 
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - * 
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#include "llviewerprecompiledheaders.h"
 -
 -#include <string>
 -#include <map>
 -
 -#include "llsd.h"
 -#include "lluuid.h"
 -#include "llpathfindinglinkset.h"
 -#include "llpathfindinglinksetlist.h"
 -
 -//---------------------------------------------------------------------------
 -// LLPathfindingLinksetList
 -//---------------------------------------------------------------------------
 -
 -LLPathfindingLinksetList::LLPathfindingLinksetList()
 -	: LLPathfindingLinksetMap()
 -{
 -}
 -
 -LLPathfindingLinksetList::LLPathfindingLinksetList(const LLSD& pLinksetItems)
 -	: LLPathfindingLinksetMap()
 -{
 -	for (LLSD::map_const_iterator linksetItemIter = pLinksetItems.beginMap();
 -		linksetItemIter != pLinksetItems.endMap(); ++linksetItemIter)
 -	{
 -		const std::string& uuid(linksetItemIter->first);
 -		const LLSD& linksetData = linksetItemIter->second;
 -		LLPathfindingLinksetPtr linkset(new LLPathfindingLinkset(uuid, linksetData));
 -		insert(std::pair<std::string, LLPathfindingLinksetPtr>(uuid, linkset));
 -	}
 -}
 -
 -LLPathfindingLinksetList::~LLPathfindingLinksetList()
 -{
 -	clear();
 -}
 -
 -void LLPathfindingLinksetList::update(const LLPathfindingLinksetList &pUpdateLinksetList)
 -{
 -	for (LLPathfindingLinksetList::const_iterator updateLinksetIter = pUpdateLinksetList.begin();
 -		updateLinksetIter != pUpdateLinksetList.end(); ++updateLinksetIter)
 -	{
 -		const std::string &uuid = updateLinksetIter->first;
 -		const LLPathfindingLinksetPtr updateLinksetPtr = updateLinksetIter->second;
 -
 -		LLPathfindingLinksetList::iterator linksetIter = find(uuid);
 -		if (linksetIter == end())
 -		{
 -			insert(std::pair<std::string, LLPathfindingLinksetPtr>(uuid, updateLinksetPtr));
 -		}
 -		else
 -		{
 -			LLPathfindingLinksetPtr linksetPtr = linksetIter->second;
 -			*linksetPtr = *updateLinksetPtr;
 -		}
 -	}
 -}
 -
 -LLSD LLPathfindingLinksetList::encodeObjectFields(LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const
 -{
 -	LLSD listData;
 -
 -	for (LLPathfindingLinksetMap::const_iterator linksetIter = begin(); linksetIter != end(); ++linksetIter)
 -	{
 -		const LLPathfindingLinksetPtr linksetPtr = linksetIter->second;
 -		if (!linksetPtr->isTerrain())
 -		{
 -			LLSD linksetData = linksetPtr->encodeAlteredFields(pLinksetUse, pA, pB, pC, pD);
 -			if (!linksetData.isUndefined())
 -			{
 -				const std::string& uuid(linksetIter->first);
 -				listData[uuid] = linksetData;
 -			}
 -		}
 -	}
 -
 -	return listData;
 -}
 -
 -LLSD LLPathfindingLinksetList::encodeTerrainFields(LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const
 -{
 -	LLSD terrainData;
 -	
 -	for (LLPathfindingLinksetMap::const_iterator linksetIter = begin(); linksetIter != end(); ++linksetIter)
 -	{
 -		const LLPathfindingLinksetPtr linksetPtr = linksetIter->second;
 -		if (linksetPtr->isTerrain())
 -		{
 -			terrainData = linksetPtr->encodeAlteredFields(pLinksetUse, pA, pB, pC, pD);
 -			break;
 -		}
 -	}
 -	
 -	return terrainData;
 -}
 +/**  + * @file llpathfindinglinksetlist.cpp + * @author William Todd Stinson + * @brief Class to implement the list of a set of pathfinding linksets + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include <string> +#include <map> + +#include "llsd.h" +#include "lluuid.h" +#include "llpathfindinglinkset.h" +#include "llpathfindinglinksetlist.h" + +//--------------------------------------------------------------------------- +// LLPathfindingLinksetList +//--------------------------------------------------------------------------- + +LLPathfindingLinksetList::LLPathfindingLinksetList() +	: LLPathfindingLinksetMap() +{ +} + +LLPathfindingLinksetList::LLPathfindingLinksetList(const LLSD& pLinksetItems) +	: LLPathfindingLinksetMap() +{ +	for (LLSD::map_const_iterator linksetItemIter = pLinksetItems.beginMap(); +		linksetItemIter != pLinksetItems.endMap(); ++linksetItemIter) +	{ +		const std::string& uuid(linksetItemIter->first); +		const LLSD& linksetData = linksetItemIter->second; +		LLPathfindingLinksetPtr linkset(new LLPathfindingLinkset(uuid, linksetData)); +		insert(std::pair<std::string, LLPathfindingLinksetPtr>(uuid, linkset)); +	} +} + +LLPathfindingLinksetList::~LLPathfindingLinksetList() +{ +	clear(); +} + +void LLPathfindingLinksetList::update(const LLPathfindingLinksetList &pUpdateLinksetList) +{ +	for (LLPathfindingLinksetList::const_iterator updateLinksetIter = pUpdateLinksetList.begin(); +		updateLinksetIter != pUpdateLinksetList.end(); ++updateLinksetIter) +	{ +		const std::string &uuid = updateLinksetIter->first; +		const LLPathfindingLinksetPtr updateLinksetPtr = updateLinksetIter->second; + +		LLPathfindingLinksetList::iterator linksetIter = find(uuid); +		if (linksetIter == end()) +		{ +			insert(std::pair<std::string, LLPathfindingLinksetPtr>(uuid, updateLinksetPtr)); +		} +		else +		{ +			LLPathfindingLinksetPtr linksetPtr = linksetIter->second; +			*linksetPtr = *updateLinksetPtr; +		} +	} +} + +LLSD LLPathfindingLinksetList::encodeObjectFields(LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const +{ +	LLSD listData; + +	for (LLPathfindingLinksetMap::const_iterator linksetIter = begin(); linksetIter != end(); ++linksetIter) +	{ +		const LLPathfindingLinksetPtr linksetPtr = linksetIter->second; +		if (!linksetPtr->isTerrain()) +		{ +			LLSD linksetData = linksetPtr->encodeAlteredFields(pLinksetUse, pA, pB, pC, pD); +			if (!linksetData.isUndefined()) +			{ +				const std::string& uuid(linksetIter->first); +				listData[uuid] = linksetData; +			} +		} +	} + +	return listData; +} + +LLSD LLPathfindingLinksetList::encodeTerrainFields(LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const +{ +	LLSD terrainData; +	 +	for (LLPathfindingLinksetMap::const_iterator linksetIter = begin(); linksetIter != end(); ++linksetIter) +	{ +		const LLPathfindingLinksetPtr linksetPtr = linksetIter->second; +		if (linksetPtr->isTerrain()) +		{ +			terrainData = linksetPtr->encodeAlteredFields(pLinksetUse, pA, pB, pC, pD); +			break; +		} +	} +	 +	return terrainData; +} diff --git a/indra/newview/llpathfindinglinksetlist.h b/indra/newview/llpathfindinglinksetlist.h index 813c4ec46c..855b1cc451 100644 --- a/indra/newview/llpathfindinglinksetlist.h +++ b/indra/newview/llpathfindinglinksetlist.h @@ -1,61 +1,61 @@ -/** 
 - * @file llpathfindinglinksetlist.h
 - * @author William Todd Stinson
 - * @brief Class to implement the list of a set of pathfinding linksets
 - *
 - * $LicenseInfo:firstyear=2002&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc.
 - * 
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - * 
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - * 
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - * 
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#ifndef LL_LLPATHFINDINGLINKSETLIST_H
 -#define LL_LLPATHFINDINGLINKSETLIST_H
 -
 -#include <string>
 -#include <map>
 -#include "llpathfindinglinkset.h"
 -
 -#include <boost/shared_ptr.hpp>
 -
 -class LLSD;
 -class LLPathfindingLinksetList;
 -
 -typedef boost::shared_ptr<LLPathfindingLinksetList> LLPathfindingLinksetListPtr;
 -typedef std::map<std::string, LLPathfindingLinksetPtr> LLPathfindingLinksetMap;
 -
 -class LLPathfindingLinksetList : public LLPathfindingLinksetMap
 -{
 -public:
 -	LLPathfindingLinksetList();
 -	LLPathfindingLinksetList(const LLSD& pLinksetItems);
 -	virtual ~LLPathfindingLinksetList();
 -
 -	void update(const LLPathfindingLinksetList &pUpdateLinksetList);
 -
 -	LLSD encodeObjectFields(LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const;
 -	LLSD encodeTerrainFields(LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const;
 -
 -protected:
 -
 -private:
 -
 -};
 -
 -#endif // LL_LLPATHFINDINGLINKSETLIST_H
 +/**  + * @file llpathfindinglinksetlist.h + * @author William Todd Stinson + * @brief Class to implement the list of a set of pathfinding linksets + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPATHFINDINGLINKSETLIST_H +#define LL_LLPATHFINDINGLINKSETLIST_H + +#include <string> +#include <map> +#include "llpathfindinglinkset.h" + +#include <boost/shared_ptr.hpp> + +class LLSD; +class LLPathfindingLinksetList; + +typedef boost::shared_ptr<LLPathfindingLinksetList> LLPathfindingLinksetListPtr; +typedef std::map<std::string, LLPathfindingLinksetPtr> LLPathfindingLinksetMap; + +class LLPathfindingLinksetList : public LLPathfindingLinksetMap +{ +public: +	LLPathfindingLinksetList(); +	LLPathfindingLinksetList(const LLSD& pLinksetItems); +	virtual ~LLPathfindingLinksetList(); + +	void update(const LLPathfindingLinksetList &pUpdateLinksetList); + +	LLSD encodeObjectFields(LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const; +	LLSD encodeTerrainFields(LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const; + +protected: + +private: + +}; + +#endif // LL_LLPATHFINDINGLINKSETLIST_H diff --git a/indra/newview/llpathfindingnavmeshstatus.cpp b/indra/newview/llpathfindingnavmeshstatus.cpp index 0ba28e0297..31ff85c1a1 100644 --- a/indra/newview/llpathfindingnavmeshstatus.cpp +++ b/indra/newview/llpathfindingnavmeshstatus.cpp @@ -1,159 +1,159 @@ -/** 
 - * @file llpathfindingnavmeshstatus.cpp
 - * @author William Todd Stinson
 - * @brief A class for representing the navmesh status of a pathfinding region.
 - *
 - * $LicenseInfo:firstyear=2002&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc.
 - * 
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - * 
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - * 
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - * 
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#include "llviewerprecompiledheaders.h"
 -#include "llsd.h"
 -#include "lluuid.h"
 -#include "llstring.h"
 -#include "llpathfindingnavmeshstatus.h"
 -
 -#include <string>
 -
 -#define REGION_FIELD  "region_id"
 -#define DEPRECATED_STATE_FIELD "state"
 -#define STATUS_FIELD  "status"
 -#define VERSION_FIELD "version"
 -
 -const std::string LLPathfindingNavMeshStatus::sStatusPending("pending");
 -const std::string LLPathfindingNavMeshStatus::sStatusBuilding("building");
 -const std::string LLPathfindingNavMeshStatus::sStatusComplete("complete");
 -const std::string LLPathfindingNavMeshStatus::sStatusRepending("repending");
 -
 -
 -//---------------------------------------------------------------------------
 -// LLPathfindingNavMeshStatus
 -//---------------------------------------------------------------------------
 -
 -LLPathfindingNavMeshStatus::LLPathfindingNavMeshStatus()
 -	: mIsValid(false),
 -	mRegionUUID(),
 -	mVersion(0U),
 -	mStatus(kComplete)
 -{
 -}
 -
 -LLPathfindingNavMeshStatus::LLPathfindingNavMeshStatus(const LLUUID &pRegionUUID)
 -	: mIsValid(false),
 -	mRegionUUID(pRegionUUID),
 -	mVersion(0U),
 -	mStatus(kComplete)
 -{
 -}
 -
 -LLPathfindingNavMeshStatus::LLPathfindingNavMeshStatus(const LLUUID &pRegionUUID, const LLSD &pContent)
 -	: mIsValid(true),
 -	mRegionUUID(pRegionUUID),
 -	mVersion(0U),
 -	mStatus(kComplete)
 -{
 -	parseStatus(pContent);
 -}
 -
 -LLPathfindingNavMeshStatus::LLPathfindingNavMeshStatus(const LLSD &pContent)
 -	: mIsValid(true),
 -	mRegionUUID(),
 -	mVersion(0U),
 -	mStatus(kComplete)
 -{
 -	llassert(pContent.has(REGION_FIELD));
 -	llassert(pContent.get(REGION_FIELD).isUUID());
 -	mRegionUUID = pContent.get(REGION_FIELD).asUUID();
 -
 -	parseStatus(pContent);
 -}
 -
 -LLPathfindingNavMeshStatus::LLPathfindingNavMeshStatus(const LLPathfindingNavMeshStatus &pOther)
 -	: mIsValid(pOther.mIsValid),
 -	mRegionUUID(pOther.mRegionUUID),
 -	mVersion(pOther.mVersion),
 -	mStatus(pOther.mStatus)
 -{
 -}
 -
 -LLPathfindingNavMeshStatus::~LLPathfindingNavMeshStatus()
 -{
 -}
 -
 -LLPathfindingNavMeshStatus &LLPathfindingNavMeshStatus::operator =(const LLPathfindingNavMeshStatus &pOther)
 -{
 -	mIsValid = pOther.mIsValid;
 -	mRegionUUID = pOther.mRegionUUID;
 -	mVersion = pOther.mVersion;
 -	mStatus = pOther.mStatus;
 -
 -	return *this;
 -}
 -
 -void LLPathfindingNavMeshStatus::parseStatus(const LLSD &pContent)
 -{
 -	llassert(pContent.has(VERSION_FIELD));
 -	llassert(pContent.get(VERSION_FIELD).isInteger());
 -	llassert(pContent.get(VERSION_FIELD).asInteger() >= 0);
 -	mVersion = static_cast<U32>(pContent.get(VERSION_FIELD).asInteger());
 -
 -#ifdef DEPRECATED_STATE_FIELD
 -	std::string status;
 -	if (pContent.has(DEPRECATED_STATE_FIELD))
 -	{
 -		llassert(pContent.has(DEPRECATED_STATE_FIELD));
 -		llassert(pContent.get(DEPRECATED_STATE_FIELD).isString());
 -		status = pContent.get(DEPRECATED_STATE_FIELD).asString();
 -	}
 -	else
 -	{
 -		llassert(pContent.has(STATUS_FIELD));
 -		llassert(pContent.get(STATUS_FIELD).isString());
 -		status = pContent.get(STATUS_FIELD).asString();
 -	}
 -#else // DEPRECATED_STATE_FIELD
 -	llassert(pContent.has(STATUS_FIELD));
 -	llassert(pContent.get(STATUS_FIELD).isString());
 -	std::string status = pContent.get(STATUS_FIELD).asString();
 -#endif // DEPRECATED_STATE_FIELD
 -
 -	if (LLStringUtil::compareStrings(status, sStatusPending) == 0)
 -	{
 -		mStatus = kPending;
 -	}
 -	else if (LLStringUtil::compareStrings(status, sStatusBuilding) == 0)
 -	{
 -		mStatus = kBuilding;
 -	}
 -	else if (LLStringUtil::compareStrings(status, sStatusComplete) == 0)
 -	{
 -		mStatus = kComplete;
 -	}
 -	else if (LLStringUtil::compareStrings(status, sStatusRepending) == 0)
 -	{
 -		mStatus = kRepending;
 -	}
 -	else
 -	{
 -		mStatus = kComplete;
 -		llassert(0);
 -	}
 -}
 +/**  + * @file llpathfindingnavmeshstatus.cpp + * @author William Todd Stinson + * @brief A class for representing the navmesh status of a pathfinding region. + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llsd.h" +#include "lluuid.h" +#include "llstring.h" +#include "llpathfindingnavmeshstatus.h" + +#include <string> + +#define REGION_FIELD  "region_id" +#define DEPRECATED_STATE_FIELD "state" +#define STATUS_FIELD  "status" +#define VERSION_FIELD "version" + +const std::string LLPathfindingNavMeshStatus::sStatusPending("pending"); +const std::string LLPathfindingNavMeshStatus::sStatusBuilding("building"); +const std::string LLPathfindingNavMeshStatus::sStatusComplete("complete"); +const std::string LLPathfindingNavMeshStatus::sStatusRepending("repending"); + + +//--------------------------------------------------------------------------- +// LLPathfindingNavMeshStatus +//--------------------------------------------------------------------------- + +LLPathfindingNavMeshStatus::LLPathfindingNavMeshStatus() +	: mIsValid(false), +	mRegionUUID(), +	mVersion(0U), +	mStatus(kComplete) +{ +} + +LLPathfindingNavMeshStatus::LLPathfindingNavMeshStatus(const LLUUID &pRegionUUID) +	: mIsValid(false), +	mRegionUUID(pRegionUUID), +	mVersion(0U), +	mStatus(kComplete) +{ +} + +LLPathfindingNavMeshStatus::LLPathfindingNavMeshStatus(const LLUUID &pRegionUUID, const LLSD &pContent) +	: mIsValid(true), +	mRegionUUID(pRegionUUID), +	mVersion(0U), +	mStatus(kComplete) +{ +	parseStatus(pContent); +} + +LLPathfindingNavMeshStatus::LLPathfindingNavMeshStatus(const LLSD &pContent) +	: mIsValid(true), +	mRegionUUID(), +	mVersion(0U), +	mStatus(kComplete) +{ +	llassert(pContent.has(REGION_FIELD)); +	llassert(pContent.get(REGION_FIELD).isUUID()); +	mRegionUUID = pContent.get(REGION_FIELD).asUUID(); + +	parseStatus(pContent); +} + +LLPathfindingNavMeshStatus::LLPathfindingNavMeshStatus(const LLPathfindingNavMeshStatus &pOther) +	: mIsValid(pOther.mIsValid), +	mRegionUUID(pOther.mRegionUUID), +	mVersion(pOther.mVersion), +	mStatus(pOther.mStatus) +{ +} + +LLPathfindingNavMeshStatus::~LLPathfindingNavMeshStatus() +{ +} + +LLPathfindingNavMeshStatus &LLPathfindingNavMeshStatus::operator =(const LLPathfindingNavMeshStatus &pOther) +{ +	mIsValid = pOther.mIsValid; +	mRegionUUID = pOther.mRegionUUID; +	mVersion = pOther.mVersion; +	mStatus = pOther.mStatus; + +	return *this; +} + +void LLPathfindingNavMeshStatus::parseStatus(const LLSD &pContent) +{ +	llassert(pContent.has(VERSION_FIELD)); +	llassert(pContent.get(VERSION_FIELD).isInteger()); +	llassert(pContent.get(VERSION_FIELD).asInteger() >= 0); +	mVersion = static_cast<U32>(pContent.get(VERSION_FIELD).asInteger()); + +#ifdef DEPRECATED_STATE_FIELD +	std::string status; +	if (pContent.has(DEPRECATED_STATE_FIELD)) +	{ +		llassert(pContent.has(DEPRECATED_STATE_FIELD)); +		llassert(pContent.get(DEPRECATED_STATE_FIELD).isString()); +		status = pContent.get(DEPRECATED_STATE_FIELD).asString(); +	} +	else +	{ +		llassert(pContent.has(STATUS_FIELD)); +		llassert(pContent.get(STATUS_FIELD).isString()); +		status = pContent.get(STATUS_FIELD).asString(); +	} +#else // DEPRECATED_STATE_FIELD +	llassert(pContent.has(STATUS_FIELD)); +	llassert(pContent.get(STATUS_FIELD).isString()); +	std::string status = pContent.get(STATUS_FIELD).asString(); +#endif // DEPRECATED_STATE_FIELD + +	if (LLStringUtil::compareStrings(status, sStatusPending) == 0) +	{ +		mStatus = kPending; +	} +	else if (LLStringUtil::compareStrings(status, sStatusBuilding) == 0) +	{ +		mStatus = kBuilding; +	} +	else if (LLStringUtil::compareStrings(status, sStatusComplete) == 0) +	{ +		mStatus = kComplete; +	} +	else if (LLStringUtil::compareStrings(status, sStatusRepending) == 0) +	{ +		mStatus = kRepending; +	} +	else +	{ +		mStatus = kComplete; +		llassert(0); +	} +} diff --git a/indra/newview/llpathfindingnavmeshstatus.h b/indra/newview/llpathfindingnavmeshstatus.h index 7147fcdf36..6428a31c24 100644 --- a/indra/newview/llpathfindingnavmeshstatus.h +++ b/indra/newview/llpathfindingnavmeshstatus.h @@ -1,85 +1,85 @@ -/** 
 - * @file llpathfindingnavmeshstatus.h
 - * @author William Todd Stinson
 - * @brief A class for representing the navmesh status of a pathfinding region.
 - *
 - * $LicenseInfo:firstyear=2002&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc. 
 - * 
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - * 
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - * 
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - * 
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#ifndef LL_LLPATHFINDINGNAVMESHSTATUS_H
 -#define LL_LLPATHFINDINGNAVMESHSTATUS_H
 -
 -#include "lluuid.h"
 -
 -#include <string>
 -
 -// XXX stinson 03/12/2012 : This definition is in place to support an older version of the pathfinding simulator that does not have versioned information
 -#define DEPRECATED_UNVERSIONED_NAVMESH
 -
 -class LLSD;
 -
 -class LLPathfindingNavMeshStatus
 -{
 -public:
 -	typedef enum
 -	{
 -		kPending,
 -		kBuilding,
 -		kComplete,
 -		kRepending
 -	} ENavMeshStatus;
 -
 -	LLPathfindingNavMeshStatus();
 -	LLPathfindingNavMeshStatus(const LLUUID &pRegionUUID);
 -	LLPathfindingNavMeshStatus(const LLUUID &pRegionUUID, const LLSD &pContent);
 -	LLPathfindingNavMeshStatus(const LLSD &pContent);
 -	LLPathfindingNavMeshStatus(const LLPathfindingNavMeshStatus &pOther);
 -	virtual ~LLPathfindingNavMeshStatus();
 -
 -	LLPathfindingNavMeshStatus &operator =(const LLPathfindingNavMeshStatus &pOther);
 -
 -#ifdef DEPRECATED_UNVERSIONED_NAVMESH
 -	void incrementNavMeshVersionXXX() {++mVersion;};
 -#endif // DEPRECATED_UNVERSIONED_NAVMESH
 -
 -	bool           isValid() const        {return mIsValid;};
 -	const LLUUID   &getRegionUUID() const {return mRegionUUID;};
 -	U32            getVersion() const     {return mVersion;};
 -	ENavMeshStatus getStatus() const      {return mStatus;};
 -
 -protected:
 -
 -private:
 -	void           parseStatus(const LLSD &pContent);
 -
 -	bool           mIsValid;
 -	LLUUID         mRegionUUID;
 -	U32            mVersion;
 -	ENavMeshStatus mStatus;
 -
 -	static const std::string sStatusPending;
 -	static const std::string sStatusBuilding;
 -	static const std::string sStatusComplete;
 -	static const std::string sStatusRepending;
 -};
 -
 -#endif // LL_LLPATHFINDINGNAVMESHSTATUS_H
 +/**  + * @file llpathfindingnavmeshstatus.h + * @author William Todd Stinson + * @brief A class for representing the navmesh status of a pathfinding region. + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc.  + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPATHFINDINGNAVMESHSTATUS_H +#define LL_LLPATHFINDINGNAVMESHSTATUS_H + +#include "lluuid.h" + +#include <string> + +// XXX stinson 03/12/2012 : This definition is in place to support an older version of the pathfinding simulator that does not have versioned information +#define DEPRECATED_UNVERSIONED_NAVMESH + +class LLSD; + +class LLPathfindingNavMeshStatus +{ +public: +	typedef enum +	{ +		kPending, +		kBuilding, +		kComplete, +		kRepending +	} ENavMeshStatus; + +	LLPathfindingNavMeshStatus(); +	LLPathfindingNavMeshStatus(const LLUUID &pRegionUUID); +	LLPathfindingNavMeshStatus(const LLUUID &pRegionUUID, const LLSD &pContent); +	LLPathfindingNavMeshStatus(const LLSD &pContent); +	LLPathfindingNavMeshStatus(const LLPathfindingNavMeshStatus &pOther); +	virtual ~LLPathfindingNavMeshStatus(); + +	LLPathfindingNavMeshStatus &operator =(const LLPathfindingNavMeshStatus &pOther); + +#ifdef DEPRECATED_UNVERSIONED_NAVMESH +	void incrementNavMeshVersionXXX() {++mVersion;}; +#endif // DEPRECATED_UNVERSIONED_NAVMESH + +	bool           isValid() const        {return mIsValid;}; +	const LLUUID   &getRegionUUID() const {return mRegionUUID;}; +	U32            getVersion() const     {return mVersion;}; +	ENavMeshStatus getStatus() const      {return mStatus;}; + +protected: + +private: +	void           parseStatus(const LLSD &pContent); + +	bool           mIsValid; +	LLUUID         mRegionUUID; +	U32            mVersion; +	ENavMeshStatus mStatus; + +	static const std::string sStatusPending; +	static const std::string sStatusBuilding; +	static const std::string sStatusComplete; +	static const std::string sStatusRepending; +}; + +#endif // LL_LLPATHFINDINGNAVMESHSTATUS_H diff --git a/indra/newview/llpathfindingpathtool.cpp b/indra/newview/llpathfindingpathtool.cpp index 04ea400090..8825f82f29 100644 --- a/indra/newview/llpathfindingpathtool.cpp +++ b/indra/newview/llpathfindingpathtool.cpp @@ -1,429 +1,429 @@ -/** 
 - * @file llpathfindingpathtool.cpp
 - * @author William Todd Stinson
 - * @brief XXX
 - *
 - * $LicenseInfo:firstyear=2002&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc.
 - * 
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - * 
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - * 
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - * 
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#include "llviewerprecompiledheaders.h"
 -#include "llpathfindingpathtool.h"
 -#include "llsingleton.h"
 -#include "lltool.h"
 -#include "llviewerwindow.h"
 -#include "llviewercamera.h"
 -#include "llpathfindingmanager.h"
 -#include "llpathinglib.h"
 -
 -#include <boost/function.hpp>
 -#include <boost/signals2.hpp>
 -
 -#define PATH_TOOL_NAME "PathfindingPathTool"
 -
 -LLPathfindingPathTool::LLPathfindingPathTool()
 -	: LLTool(PATH_TOOL_NAME),
 -	LLSingleton<LLPathfindingPathTool>(),
 -	mFinalPathData(),
 -	mTempPathData(),
 -	mPathResult(LLPathingLib::LLPL_NO_PATH),
 -	mCharacterType(kCharacterTypeNone),
 -	mPathEventSignal(),
 -	mIsLeftMouseButtonHeld(false),
 -	mIsMiddleMouseButtonHeld(false),
 -	mIsRightMouseButtonHeld(false)
 -{
 -	if (!LLPathingLib::getInstance())
 -	{
 -		LLPathingLib::initSystem();
 -	}	
 -
 -	setCharacterWidth(1.0f);
 -	setCharacterType(mCharacterType);
 -}
 -
 -LLPathfindingPathTool::~LLPathfindingPathTool()
 -{
 -}
 -
 -BOOL LLPathfindingPathTool::handleMouseDown(S32 pX, S32 pY, MASK pMask)
 -{
 -	BOOL returnVal = FALSE;
 -
 -	if (!mIsLeftMouseButtonHeld && !mIsMiddleMouseButtonHeld && !mIsRightMouseButtonHeld && isAnyPathToolModKeys(pMask))
 -	{
 -		computeFinalPoints(pX, pY, pMask);
 -		mIsLeftMouseButtonHeld = true;
 -		setMouseCapture(TRUE);
 -		returnVal = TRUE;
 -	}
 -	mIsLeftMouseButtonHeld = true;
 -
 -	return returnVal;
 -}
 -
 -BOOL LLPathfindingPathTool::handleMouseUp(S32 pX, S32 pY, MASK pMask)
 -{
 -	BOOL returnVal = FALSE;
 -
 -	if (mIsLeftMouseButtonHeld && !mIsMiddleMouseButtonHeld && !mIsRightMouseButtonHeld && isAnyPathToolModKeys(pMask))
 -	{
 -		computeFinalPoints(pX, pY, pMask);
 -		setMouseCapture(FALSE);
 -		returnVal = TRUE;
 -	}
 -	mIsLeftMouseButtonHeld = false;
 -
 -	return returnVal;
 -}
 -
 -BOOL LLPathfindingPathTool::handleMiddleMouseDown(S32 pX, S32 pY, MASK pMask)
 -{
 -	setMouseCapture(TRUE);
 -	mIsMiddleMouseButtonHeld = true;
 -	gViewerWindow->setCursor(UI_CURSOR_TOOLNO);
 -
 -	return TRUE;
 -}
 -
 -BOOL LLPathfindingPathTool::handleMiddleMouseUp(S32 pX, S32 pY, MASK pMask)
 -{
 -	if (!mIsLeftMouseButtonHeld && mIsMiddleMouseButtonHeld && !mIsRightMouseButtonHeld)
 -	{
 -		setMouseCapture(FALSE);
 -	}
 -	mIsMiddleMouseButtonHeld = false;
 -
 -	return TRUE;
 -}
 -
 -BOOL LLPathfindingPathTool::handleRightMouseDown(S32 pX, S32 pY, MASK pMask)
 -{
 -	setMouseCapture(TRUE);
 -	mIsRightMouseButtonHeld = true;
 -	gViewerWindow->setCursor(UI_CURSOR_TOOLNO);
 -
 -	return TRUE;
 -}
 -
 -BOOL LLPathfindingPathTool::handleRightMouseUp(S32 pX, S32 pY, MASK pMask)
 -{
 -	if (!mIsLeftMouseButtonHeld && !mIsMiddleMouseButtonHeld && mIsRightMouseButtonHeld)
 -	{
 -		setMouseCapture(FALSE);
 -	}
 -	mIsRightMouseButtonHeld = false;
 -
 -	return TRUE;
 -}
 -
 -BOOL LLPathfindingPathTool::handleDoubleClick(S32 pX, S32 pY, MASK pMask)
 -{
 -	return TRUE;
 -}
 -
 -BOOL LLPathfindingPathTool::handleHover(S32 pX, S32 pY, MASK pMask)
 -{
 -	BOOL returnVal = FALSE;
 -
 -	if (!mIsMiddleMouseButtonHeld && !mIsRightMouseButtonHeld && isAnyPathToolModKeys(pMask))
 -	{
 -		gViewerWindow->setCursor(UI_CURSOR_TOOLPATHFINDING);
 -		computeTempPoints(pX, pY, pMask);
 -		returnVal = TRUE;
 -	}
 -	else
 -	{
 -		clearTemp();
 -		computeFinalPath();
 -	}
 -
 -	return returnVal;
 -}
 -
 -LLPathfindingPathTool::EPathStatus LLPathfindingPathTool::getPathStatus() const
 -{
 -	EPathStatus status = kPathStatusUnknown;
 -
 -	if (LLPathingLib::getInstance() == NULL)
 -	{
 -		status = kPathStatusNotImplemented;
 -	}
 -	else if (!LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion())
 -	{
 -		status = kPathStatusNotEnabled;
 -	}
 -	else if (!hasFinalA() && !hasFinalB())
 -	{
 -		status = kPathStatusChooseStartAndEndPoints;
 -	}
 -	else if (!hasFinalA())
 -	{
 -		status = kPathStatusChooseStartPoint;
 -	}
 -	else if (!hasFinalB())
 -	{
 -		status = kPathStatusChooseEndPoint;
 -	}
 -	else if (mPathResult == LLPathingLib::LLPL_PATH_GENERATED_OK)
 -	{
 -		status = kPathStatusHasValidPath;
 -	}
 -	else if (mPathResult == LLPathingLib::LLPL_NO_PATH)
 -	{
 -		status = kPathStatusHasInvalidPath;
 -	}
 -	else
 -	{
 -		status = kPathStatusError;
 -	}
 -
 -	return status;
 -}
 -
 -F32 LLPathfindingPathTool::getCharacterWidth() const
 -{
 -	return mFinalPathData.mCharacterWidth;
 -}
 -
 -void LLPathfindingPathTool::setCharacterWidth(F32 pCharacterWidth)
 -{
 -	mFinalPathData.mCharacterWidth = pCharacterWidth;
 -	mTempPathData.mCharacterWidth = pCharacterWidth;
 -	computeFinalPath();
 -}
 -
 -LLPathfindingPathTool::ECharacterType LLPathfindingPathTool::getCharacterType() const
 -{
 -	return mCharacterType;
 -}
 -
 -void LLPathfindingPathTool::setCharacterType(ECharacterType pCharacterType)
 -{
 -	mCharacterType = pCharacterType;
 -
 -	LLPathingLib::LLPLCharacterType characterType;
 -	switch (pCharacterType)
 -	{
 -	case kCharacterTypeNone :
 -		characterType = LLPathingLib::LLPL_CHARACTER_TYPE_NONE;
 -		break;
 -	case kCharacterTypeA :
 -		characterType = LLPathingLib::LLPL_CHARACTER_TYPE_A;
 -		break;
 -	case kCharacterTypeB :
 -		characterType = LLPathingLib::LLPL_CHARACTER_TYPE_B;
 -		break;
 -	case kCharacterTypeC :
 -		characterType = LLPathingLib::LLPL_CHARACTER_TYPE_C;
 -		break;
 -	case kCharacterTypeD :
 -		characterType = LLPathingLib::LLPL_CHARACTER_TYPE_D;
 -		break;
 -	default :
 -		characterType = LLPathingLib::LLPL_CHARACTER_TYPE_NONE;
 -		llassert(0);
 -		break;
 -	}
 -	mFinalPathData.mCharacterType = characterType;
 -	mTempPathData.mCharacterType = characterType;
 -	computeFinalPath();
 -}
 -
 -bool LLPathfindingPathTool::isRenderPath() const
 -{
 -	return (hasFinalA() || hasFinalB() || hasTempA() || hasTempB());
 -}
 -
 -void LLPathfindingPathTool::clearPath()
 -{
 -	clearFinal();
 -	clearTemp();
 -	computeFinalPath();
 -}
 -
 -LLPathfindingPathTool::path_event_slot_t LLPathfindingPathTool::registerPathEventListener(path_event_callback_t pPathEventCallback)
 -{
 -	return mPathEventSignal.connect(pPathEventCallback);
 -}
 -
 -bool LLPathfindingPathTool::isAnyPathToolModKeys(MASK pMask) const
 -{
 -	return ((pMask & (MASK_CONTROL|MASK_SHIFT)) != 0);
 -}
 -
 -bool LLPathfindingPathTool::isPointAModKeys(MASK pMask) const
 -{
 -	return ((pMask & MASK_CONTROL) != 0);
 -}
 -
 -bool LLPathfindingPathTool::isPointBModKeys(MASK pMask) const
 -{
 -	return ((pMask & MASK_SHIFT) != 0);
 -}
 -
 -void LLPathfindingPathTool::getRayPoints(S32 pX, S32 pY, LLVector3 &pRayStart, LLVector3 &pRayEnd) const
 -{
 -	LLVector3 dv = gViewerWindow->mouseDirectionGlobal(pX, pY);
 -	LLVector3 mousePos = LLViewerCamera::getInstance()->getOrigin();
 -	pRayStart = mousePos;
 -	pRayEnd = mousePos + dv * 150;
 -}
 -
 -void LLPathfindingPathTool::computeFinalPoints(S32 pX, S32 pY, MASK pMask)
 -{
 -	LLVector3 rayStart, rayEnd;
 -	getRayPoints(pX, pY, rayStart, rayEnd);
 -
 -	if (isPointAModKeys(pMask))
 -	{
 -		setFinalA(rayStart, rayEnd);
 -	}
 -	else if (isPointBModKeys(pMask))
 -	{
 -		setFinalB(rayStart, rayEnd);
 -	}
 -	computeFinalPath();
 -}
 -
 -void LLPathfindingPathTool::computeTempPoints(S32 pX, S32 pY, MASK pMask)
 -{
 -	LLVector3 rayStart, rayEnd;
 -	getRayPoints(pX, pY, rayStart, rayEnd);
 -
 -	if (isPointAModKeys(pMask))
 -	{
 -		setTempA(rayStart, rayEnd);
 -		if (hasFinalB())
 -		{
 -			setTempB(getFinalBStart(), getFinalBEnd());
 -		}
 -	}
 -	else if (isPointBModKeys(pMask))
 -	{
 -		if (hasFinalA())
 -		{
 -			setTempA(getFinalAStart(), getFinalAEnd());
 -		}
 -		setTempB(rayStart, rayEnd);
 -	}
 -	computeTempPath();
 -}
 -
 -void LLPathfindingPathTool::setFinalA(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint)
 -{
 -	mFinalPathData.mStartPointA = pStartPoint;
 -	mFinalPathData.mEndPointA = pEndPoint;
 -	mFinalPathData.mHasPointA = true;
 -}
 -
 -bool LLPathfindingPathTool::hasFinalA() const
 -{
 -	return mFinalPathData.mHasPointA;
 -}
 -
 -const LLVector3 &LLPathfindingPathTool::getFinalAStart() const
 -{
 -	return mFinalPathData.mStartPointA;
 -}
 -
 -const LLVector3 &LLPathfindingPathTool::getFinalAEnd() const
 -{
 -	return mFinalPathData.mEndPointA;
 -}
 -
 -void LLPathfindingPathTool::setTempA(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint)
 -{
 -	mTempPathData.mStartPointA = pStartPoint;
 -	mTempPathData.mEndPointA = pEndPoint;
 -	mTempPathData.mHasPointA = true;
 -}
 -
 -bool LLPathfindingPathTool::hasTempA() const
 -{
 -	return mTempPathData.mHasPointA;
 -}
 -
 -void LLPathfindingPathTool::setFinalB(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint)
 -{
 -	mFinalPathData.mStartPointB = pStartPoint;
 -	mFinalPathData.mEndPointB = pEndPoint;
 -	mFinalPathData.mHasPointB = true;
 -}
 -
 -bool LLPathfindingPathTool::hasFinalB() const
 -{
 -	return mFinalPathData.mHasPointB;
 -}
 -
 -const LLVector3 &LLPathfindingPathTool::getFinalBStart() const
 -{
 -	return mFinalPathData.mStartPointB;
 -}
 -
 -const LLVector3 &LLPathfindingPathTool::getFinalBEnd() const
 -{
 -	return mFinalPathData.mEndPointB;
 -}
 -
 -void LLPathfindingPathTool::setTempB(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint)
 -{
 -	mTempPathData.mStartPointB = pStartPoint;
 -	mTempPathData.mEndPointB = pEndPoint;
 -	mTempPathData.mHasPointB = true;
 -}
 -
 -bool LLPathfindingPathTool::hasTempB() const
 -{
 -	return mTempPathData.mHasPointB;
 -}
 -
 -void LLPathfindingPathTool::clearFinal()
 -{
 -	mFinalPathData.mHasPointA = false;
 -	mFinalPathData.mHasPointB = false;
 -}
 -
 -void LLPathfindingPathTool::clearTemp()
 -{
 -	mTempPathData.mHasPointA = false;
 -	mTempPathData.mHasPointB = false;
 -}
 -
 -void LLPathfindingPathTool::computeFinalPath()
 -{
 -	mPathResult = LLPathingLib::LLPL_NO_PATH;
 -	if (LLPathingLib::getInstance() != NULL)
 -	{
 -		mPathResult = LLPathingLib::getInstance()->generatePath(mFinalPathData);
 -	}
 -	mPathEventSignal();
 -}
 -
 -void LLPathfindingPathTool::computeTempPath()
 -{
 -	mPathResult = LLPathingLib::LLPL_NO_PATH;
 -	if (LLPathingLib::getInstance() != NULL)
 -	{
 -		mPathResult = LLPathingLib::getInstance()->generatePath(mTempPathData);
 -	}
 -	mPathEventSignal();
 -}
 +/**  + * @file llpathfindingpathtool.cpp + * @author William Todd Stinson + * @brief XXX + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llpathfindingpathtool.h" +#include "llsingleton.h" +#include "lltool.h" +#include "llviewerwindow.h" +#include "llviewercamera.h" +#include "llpathfindingmanager.h" +#include "llpathinglib.h" + +#include <boost/function.hpp> +#include <boost/signals2.hpp> + +#define PATH_TOOL_NAME "PathfindingPathTool" + +LLPathfindingPathTool::LLPathfindingPathTool() +	: LLTool(PATH_TOOL_NAME), +	LLSingleton<LLPathfindingPathTool>(), +	mFinalPathData(), +	mTempPathData(), +	mPathResult(LLPathingLib::LLPL_NO_PATH), +	mCharacterType(kCharacterTypeNone), +	mPathEventSignal(), +	mIsLeftMouseButtonHeld(false), +	mIsMiddleMouseButtonHeld(false), +	mIsRightMouseButtonHeld(false) +{ +	if (!LLPathingLib::getInstance()) +	{ +		LLPathingLib::initSystem(); +	}	 + +	setCharacterWidth(1.0f); +	setCharacterType(mCharacterType); +} + +LLPathfindingPathTool::~LLPathfindingPathTool() +{ +} + +BOOL LLPathfindingPathTool::handleMouseDown(S32 pX, S32 pY, MASK pMask) +{ +	BOOL returnVal = FALSE; + +	if (!mIsLeftMouseButtonHeld && !mIsMiddleMouseButtonHeld && !mIsRightMouseButtonHeld && isAnyPathToolModKeys(pMask)) +	{ +		computeFinalPoints(pX, pY, pMask); +		mIsLeftMouseButtonHeld = true; +		setMouseCapture(TRUE); +		returnVal = TRUE; +	} +	mIsLeftMouseButtonHeld = true; + +	return returnVal; +} + +BOOL LLPathfindingPathTool::handleMouseUp(S32 pX, S32 pY, MASK pMask) +{ +	BOOL returnVal = FALSE; + +	if (mIsLeftMouseButtonHeld && !mIsMiddleMouseButtonHeld && !mIsRightMouseButtonHeld && isAnyPathToolModKeys(pMask)) +	{ +		computeFinalPoints(pX, pY, pMask); +		setMouseCapture(FALSE); +		returnVal = TRUE; +	} +	mIsLeftMouseButtonHeld = false; + +	return returnVal; +} + +BOOL LLPathfindingPathTool::handleMiddleMouseDown(S32 pX, S32 pY, MASK pMask) +{ +	setMouseCapture(TRUE); +	mIsMiddleMouseButtonHeld = true; +	gViewerWindow->setCursor(UI_CURSOR_TOOLNO); + +	return TRUE; +} + +BOOL LLPathfindingPathTool::handleMiddleMouseUp(S32 pX, S32 pY, MASK pMask) +{ +	if (!mIsLeftMouseButtonHeld && mIsMiddleMouseButtonHeld && !mIsRightMouseButtonHeld) +	{ +		setMouseCapture(FALSE); +	} +	mIsMiddleMouseButtonHeld = false; + +	return TRUE; +} + +BOOL LLPathfindingPathTool::handleRightMouseDown(S32 pX, S32 pY, MASK pMask) +{ +	setMouseCapture(TRUE); +	mIsRightMouseButtonHeld = true; +	gViewerWindow->setCursor(UI_CURSOR_TOOLNO); + +	return TRUE; +} + +BOOL LLPathfindingPathTool::handleRightMouseUp(S32 pX, S32 pY, MASK pMask) +{ +	if (!mIsLeftMouseButtonHeld && !mIsMiddleMouseButtonHeld && mIsRightMouseButtonHeld) +	{ +		setMouseCapture(FALSE); +	} +	mIsRightMouseButtonHeld = false; + +	return TRUE; +} + +BOOL LLPathfindingPathTool::handleDoubleClick(S32 pX, S32 pY, MASK pMask) +{ +	return TRUE; +} + +BOOL LLPathfindingPathTool::handleHover(S32 pX, S32 pY, MASK pMask) +{ +	BOOL returnVal = FALSE; + +	if (!mIsMiddleMouseButtonHeld && !mIsRightMouseButtonHeld && isAnyPathToolModKeys(pMask)) +	{ +		gViewerWindow->setCursor(UI_CURSOR_TOOLPATHFINDING); +		computeTempPoints(pX, pY, pMask); +		returnVal = TRUE; +	} +	else +	{ +		clearTemp(); +		computeFinalPath(); +	} + +	return returnVal; +} + +LLPathfindingPathTool::EPathStatus LLPathfindingPathTool::getPathStatus() const +{ +	EPathStatus status = kPathStatusUnknown; + +	if (LLPathingLib::getInstance() == NULL) +	{ +		status = kPathStatusNotImplemented; +	} +	else if (!LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion()) +	{ +		status = kPathStatusNotEnabled; +	} +	else if (!hasFinalA() && !hasFinalB()) +	{ +		status = kPathStatusChooseStartAndEndPoints; +	} +	else if (!hasFinalA()) +	{ +		status = kPathStatusChooseStartPoint; +	} +	else if (!hasFinalB()) +	{ +		status = kPathStatusChooseEndPoint; +	} +	else if (mPathResult == LLPathingLib::LLPL_PATH_GENERATED_OK) +	{ +		status = kPathStatusHasValidPath; +	} +	else if (mPathResult == LLPathingLib::LLPL_NO_PATH) +	{ +		status = kPathStatusHasInvalidPath; +	} +	else +	{ +		status = kPathStatusError; +	} + +	return status; +} + +F32 LLPathfindingPathTool::getCharacterWidth() const +{ +	return mFinalPathData.mCharacterWidth; +} + +void LLPathfindingPathTool::setCharacterWidth(F32 pCharacterWidth) +{ +	mFinalPathData.mCharacterWidth = pCharacterWidth; +	mTempPathData.mCharacterWidth = pCharacterWidth; +	computeFinalPath(); +} + +LLPathfindingPathTool::ECharacterType LLPathfindingPathTool::getCharacterType() const +{ +	return mCharacterType; +} + +void LLPathfindingPathTool::setCharacterType(ECharacterType pCharacterType) +{ +	mCharacterType = pCharacterType; + +	LLPathingLib::LLPLCharacterType characterType; +	switch (pCharacterType) +	{ +	case kCharacterTypeNone : +		characterType = LLPathingLib::LLPL_CHARACTER_TYPE_NONE; +		break; +	case kCharacterTypeA : +		characterType = LLPathingLib::LLPL_CHARACTER_TYPE_A; +		break; +	case kCharacterTypeB : +		characterType = LLPathingLib::LLPL_CHARACTER_TYPE_B; +		break; +	case kCharacterTypeC : +		characterType = LLPathingLib::LLPL_CHARACTER_TYPE_C; +		break; +	case kCharacterTypeD : +		characterType = LLPathingLib::LLPL_CHARACTER_TYPE_D; +		break; +	default : +		characterType = LLPathingLib::LLPL_CHARACTER_TYPE_NONE; +		llassert(0); +		break; +	} +	mFinalPathData.mCharacterType = characterType; +	mTempPathData.mCharacterType = characterType; +	computeFinalPath(); +} + +bool LLPathfindingPathTool::isRenderPath() const +{ +	return (hasFinalA() || hasFinalB() || hasTempA() || hasTempB()); +} + +void LLPathfindingPathTool::clearPath() +{ +	clearFinal(); +	clearTemp(); +	computeFinalPath(); +} + +LLPathfindingPathTool::path_event_slot_t LLPathfindingPathTool::registerPathEventListener(path_event_callback_t pPathEventCallback) +{ +	return mPathEventSignal.connect(pPathEventCallback); +} + +bool LLPathfindingPathTool::isAnyPathToolModKeys(MASK pMask) const +{ +	return ((pMask & (MASK_CONTROL|MASK_SHIFT)) != 0); +} + +bool LLPathfindingPathTool::isPointAModKeys(MASK pMask) const +{ +	return ((pMask & MASK_CONTROL) != 0); +} + +bool LLPathfindingPathTool::isPointBModKeys(MASK pMask) const +{ +	return ((pMask & MASK_SHIFT) != 0); +} + +void LLPathfindingPathTool::getRayPoints(S32 pX, S32 pY, LLVector3 &pRayStart, LLVector3 &pRayEnd) const +{ +	LLVector3 dv = gViewerWindow->mouseDirectionGlobal(pX, pY); +	LLVector3 mousePos = LLViewerCamera::getInstance()->getOrigin(); +	pRayStart = mousePos; +	pRayEnd = mousePos + dv * 150; +} + +void LLPathfindingPathTool::computeFinalPoints(S32 pX, S32 pY, MASK pMask) +{ +	LLVector3 rayStart, rayEnd; +	getRayPoints(pX, pY, rayStart, rayEnd); + +	if (isPointAModKeys(pMask)) +	{ +		setFinalA(rayStart, rayEnd); +	} +	else if (isPointBModKeys(pMask)) +	{ +		setFinalB(rayStart, rayEnd); +	} +	computeFinalPath(); +} + +void LLPathfindingPathTool::computeTempPoints(S32 pX, S32 pY, MASK pMask) +{ +	LLVector3 rayStart, rayEnd; +	getRayPoints(pX, pY, rayStart, rayEnd); + +	if (isPointAModKeys(pMask)) +	{ +		setTempA(rayStart, rayEnd); +		if (hasFinalB()) +		{ +			setTempB(getFinalBStart(), getFinalBEnd()); +		} +	} +	else if (isPointBModKeys(pMask)) +	{ +		if (hasFinalA()) +		{ +			setTempA(getFinalAStart(), getFinalAEnd()); +		} +		setTempB(rayStart, rayEnd); +	} +	computeTempPath(); +} + +void LLPathfindingPathTool::setFinalA(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint) +{ +	mFinalPathData.mStartPointA = pStartPoint; +	mFinalPathData.mEndPointA = pEndPoint; +	mFinalPathData.mHasPointA = true; +} + +bool LLPathfindingPathTool::hasFinalA() const +{ +	return mFinalPathData.mHasPointA; +} + +const LLVector3 &LLPathfindingPathTool::getFinalAStart() const +{ +	return mFinalPathData.mStartPointA; +} + +const LLVector3 &LLPathfindingPathTool::getFinalAEnd() const +{ +	return mFinalPathData.mEndPointA; +} + +void LLPathfindingPathTool::setTempA(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint) +{ +	mTempPathData.mStartPointA = pStartPoint; +	mTempPathData.mEndPointA = pEndPoint; +	mTempPathData.mHasPointA = true; +} + +bool LLPathfindingPathTool::hasTempA() const +{ +	return mTempPathData.mHasPointA; +} + +void LLPathfindingPathTool::setFinalB(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint) +{ +	mFinalPathData.mStartPointB = pStartPoint; +	mFinalPathData.mEndPointB = pEndPoint; +	mFinalPathData.mHasPointB = true; +} + +bool LLPathfindingPathTool::hasFinalB() const +{ +	return mFinalPathData.mHasPointB; +} + +const LLVector3 &LLPathfindingPathTool::getFinalBStart() const +{ +	return mFinalPathData.mStartPointB; +} + +const LLVector3 &LLPathfindingPathTool::getFinalBEnd() const +{ +	return mFinalPathData.mEndPointB; +} + +void LLPathfindingPathTool::setTempB(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint) +{ +	mTempPathData.mStartPointB = pStartPoint; +	mTempPathData.mEndPointB = pEndPoint; +	mTempPathData.mHasPointB = true; +} + +bool LLPathfindingPathTool::hasTempB() const +{ +	return mTempPathData.mHasPointB; +} + +void LLPathfindingPathTool::clearFinal() +{ +	mFinalPathData.mHasPointA = false; +	mFinalPathData.mHasPointB = false; +} + +void LLPathfindingPathTool::clearTemp() +{ +	mTempPathData.mHasPointA = false; +	mTempPathData.mHasPointB = false; +} + +void LLPathfindingPathTool::computeFinalPath() +{ +	mPathResult = LLPathingLib::LLPL_NO_PATH; +	if (LLPathingLib::getInstance() != NULL) +	{ +		mPathResult = LLPathingLib::getInstance()->generatePath(mFinalPathData); +	} +	mPathEventSignal(); +} + +void LLPathfindingPathTool::computeTempPath() +{ +	mPathResult = LLPathingLib::LLPL_NO_PATH; +	if (LLPathingLib::getInstance() != NULL) +	{ +		mPathResult = LLPathingLib::getInstance()->generatePath(mTempPathData); +	} +	mPathEventSignal(); +} diff --git a/indra/newview/llpathfindingpathtool.h b/indra/newview/llpathfindingpathtool.h index 492304e4a4..0294111ccf 100644 --- a/indra/newview/llpathfindingpathtool.h +++ b/indra/newview/llpathfindingpathtool.h @@ -1,136 +1,136 @@ -/** 
 - * @file llpathfindingpathtool.h
 - * @author William Todd Stinson
 - * @brief XXX
 - *
 - * $LicenseInfo:firstyear=2002&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc.
 - * 
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - * 
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - * 
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - * 
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#ifndef LL_LLPATHFINDINGPATHTOOL_H
 -#define LL_LLPATHFINDINGPATHTOOL_H
 -
 -#include "llsingleton.h"
 -#include "lltool.h"
 -#include "llpathinglib.h"
 -
 -#include <boost/function.hpp>
 -#include <boost/signals2.hpp>
 -
 -class LLPathfindingPathTool : public LLTool, public LLSingleton<LLPathfindingPathTool>
 -{
 -public:
 -	typedef enum
 -	{
 -		kPathStatusUnknown,
 -		kPathStatusChooseStartAndEndPoints,
 -		kPathStatusChooseStartPoint,
 -		kPathStatusChooseEndPoint,
 -		kPathStatusHasValidPath,
 -		kPathStatusHasInvalidPath,
 -		kPathStatusNotEnabled,
 -		kPathStatusNotImplemented,
 -		kPathStatusError
 -	} EPathStatus;
 -
 -	typedef enum
 -	{
 -		kCharacterTypeNone,
 -		kCharacterTypeA,
 -		kCharacterTypeB,
 -		kCharacterTypeC,
 -		kCharacterTypeD
 -	} ECharacterType;
 -
 -	LLPathfindingPathTool();
 -	virtual ~LLPathfindingPathTool();
 -
 -	typedef boost::function<void (void)>         path_event_callback_t;
 -	typedef boost::signals2::signal<void (void)> path_event_signal_t;
 -	typedef boost::signals2::connection          path_event_slot_t;
 -
 -	virtual BOOL      handleMouseDown(S32 pX, S32 pY, MASK pMask);
 -	virtual BOOL      handleMouseUp(S32 pX, S32 pY, MASK pMask);
 -	virtual BOOL      handleMiddleMouseDown(S32 pX, S32 pY, MASK pMask);
 -	virtual BOOL      handleMiddleMouseUp(S32 pX, S32 pY, MASK pMask);
 -	virtual BOOL      handleRightMouseDown(S32 pX, S32 pY, MASK pMask);
 -	virtual BOOL      handleRightMouseUp(S32 pX, S32 pY, MASK pMask);
 -	virtual BOOL      handleDoubleClick(S32 x, S32 y, MASK mask);
 -
 -	virtual BOOL      handleHover(S32 pX, S32 pY, MASK pMask);
 -
 -	EPathStatus       getPathStatus() const;
 -
 -	F32               getCharacterWidth() const;
 -	void              setCharacterWidth(F32 pCharacterWidth);
 -
 -	ECharacterType    getCharacterType() const;
 -	void              setCharacterType(ECharacterType pCharacterType);
 -
 -	bool              isRenderPath() const;
 -	void              clearPath();
 -
 -	path_event_slot_t registerPathEventListener(path_event_callback_t pPathEventCallback);
 -
 -protected:
 -
 -private:
 -	bool              isAnyPathToolModKeys(MASK pMask) const;
 -	bool              isPointAModKeys(MASK pMask) const;
 -	bool              isPointBModKeys(MASK pMask) const;
 -
 -	void              getRayPoints(S32 pX, S32 pY, LLVector3 &pRayStart, LLVector3 &pRayEnd) const;
 -	void              computeFinalPoints(S32 pX, S32 pY, MASK pMask);
 -	void              computeTempPoints(S32 pX, S32 pY, MASK pMask);
 -
 -	void              setFinalA(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint);
 -	bool              hasFinalA() const;
 -	const LLVector3   &getFinalAStart() const;
 -	const LLVector3   &getFinalAEnd() const;
 -
 -	void              setTempA(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint);
 -	bool              hasTempA() const;
 -
 -	void              setFinalB(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint);
 -	bool              hasFinalB() const;
 -	const LLVector3   &getFinalBStart() const;
 -	const LLVector3   &getFinalBEnd() const;
 -
 -	void              setTempB(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint);
 -	bool              hasTempB() const;
 -
 -	void              clearFinal();
 -	void              clearTemp();
 -
 -	void              computeFinalPath();
 -	void              computeTempPath();
 -
 -	LLPathingLib::PathingPacket mFinalPathData;
 -	LLPathingLib::PathingPacket mTempPathData;
 -	LLPathingLib::LLPLResult    mPathResult;
 -	ECharacterType              mCharacterType;
 -	path_event_signal_t         mPathEventSignal;
 -	bool                        mIsLeftMouseButtonHeld;
 -	bool                        mIsMiddleMouseButtonHeld;
 -	bool                        mIsRightMouseButtonHeld;
 -};
 -
 -#endif // LL_LLPATHFINDINGPATHTOOL_H
 +/**  + * @file llpathfindingpathtool.h + * @author William Todd Stinson + * @brief XXX + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPATHFINDINGPATHTOOL_H +#define LL_LLPATHFINDINGPATHTOOL_H + +#include "llsingleton.h" +#include "lltool.h" +#include "llpathinglib.h" + +#include <boost/function.hpp> +#include <boost/signals2.hpp> + +class LLPathfindingPathTool : public LLTool, public LLSingleton<LLPathfindingPathTool> +{ +public: +	typedef enum +	{ +		kPathStatusUnknown, +		kPathStatusChooseStartAndEndPoints, +		kPathStatusChooseStartPoint, +		kPathStatusChooseEndPoint, +		kPathStatusHasValidPath, +		kPathStatusHasInvalidPath, +		kPathStatusNotEnabled, +		kPathStatusNotImplemented, +		kPathStatusError +	} EPathStatus; + +	typedef enum +	{ +		kCharacterTypeNone, +		kCharacterTypeA, +		kCharacterTypeB, +		kCharacterTypeC, +		kCharacterTypeD +	} ECharacterType; + +	LLPathfindingPathTool(); +	virtual ~LLPathfindingPathTool(); + +	typedef boost::function<void (void)>         path_event_callback_t; +	typedef boost::signals2::signal<void (void)> path_event_signal_t; +	typedef boost::signals2::connection          path_event_slot_t; + +	virtual BOOL      handleMouseDown(S32 pX, S32 pY, MASK pMask); +	virtual BOOL      handleMouseUp(S32 pX, S32 pY, MASK pMask); +	virtual BOOL      handleMiddleMouseDown(S32 pX, S32 pY, MASK pMask); +	virtual BOOL      handleMiddleMouseUp(S32 pX, S32 pY, MASK pMask); +	virtual BOOL      handleRightMouseDown(S32 pX, S32 pY, MASK pMask); +	virtual BOOL      handleRightMouseUp(S32 pX, S32 pY, MASK pMask); +	virtual BOOL      handleDoubleClick(S32 x, S32 y, MASK mask); + +	virtual BOOL      handleHover(S32 pX, S32 pY, MASK pMask); + +	EPathStatus       getPathStatus() const; + +	F32               getCharacterWidth() const; +	void              setCharacterWidth(F32 pCharacterWidth); + +	ECharacterType    getCharacterType() const; +	void              setCharacterType(ECharacterType pCharacterType); + +	bool              isRenderPath() const; +	void              clearPath(); + +	path_event_slot_t registerPathEventListener(path_event_callback_t pPathEventCallback); + +protected: + +private: +	bool              isAnyPathToolModKeys(MASK pMask) const; +	bool              isPointAModKeys(MASK pMask) const; +	bool              isPointBModKeys(MASK pMask) const; + +	void              getRayPoints(S32 pX, S32 pY, LLVector3 &pRayStart, LLVector3 &pRayEnd) const; +	void              computeFinalPoints(S32 pX, S32 pY, MASK pMask); +	void              computeTempPoints(S32 pX, S32 pY, MASK pMask); + +	void              setFinalA(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint); +	bool              hasFinalA() const; +	const LLVector3   &getFinalAStart() const; +	const LLVector3   &getFinalAEnd() const; + +	void              setTempA(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint); +	bool              hasTempA() const; + +	void              setFinalB(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint); +	bool              hasFinalB() const; +	const LLVector3   &getFinalBStart() const; +	const LLVector3   &getFinalBEnd() const; + +	void              setTempB(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint); +	bool              hasTempB() const; + +	void              clearFinal(); +	void              clearTemp(); + +	void              computeFinalPath(); +	void              computeTempPath(); + +	LLPathingLib::PathingPacket mFinalPathData; +	LLPathingLib::PathingPacket mTempPathData; +	LLPathingLib::LLPLResult    mPathResult; +	ECharacterType              mCharacterType; +	path_event_signal_t         mPathEventSignal; +	bool                        mIsLeftMouseButtonHeld; +	bool                        mIsMiddleMouseButtonHeld; +	bool                        mIsRightMouseButtonHeld; +}; + +#endif // LL_LLPATHFINDINGPATHTOOL_H diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 936bafb488..fbd8b3ada3 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -1,1238 +1,1238 @@ -/** 
 - * @file llworld.cpp
 - * @brief Initial test structure to organize viewer regions
 - *
 - * $LicenseInfo:firstyear=2001&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc.
 - * 
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - * 
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - * 
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - * 
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#include "llviewerprecompiledheaders.h"
 -
 -#include "llworld.h"
 -#include "llrender.h"
 -
 -#include "indra_constants.h"
 -#include "llstl.h"
 -
 -#include "llagent.h"
 -#include "llviewercontrol.h"
 -#include "lldrawpool.h"
 -#include "llglheaders.h"
 -#include "llhttpnode.h"
 -#include "llregionhandle.h"
 -#include "llsurface.h"
 -#include "lltrans.h"
 -#include "llviewercamera.h"
 -#include "llviewertexture.h"
 -#include "llviewertexturelist.h"
 -#include "llviewernetwork.h"
 -#include "llviewerobjectlist.h"
 -#include "llviewerparceloverlay.h"
 -#include "llviewerregion.h"
 -#include "llviewerstats.h"
 -#include "llvlcomposition.h"
 -#include "llvoavatar.h"
 -#include "llvocache.h"
 -#include "llvowater.h"
 -#include "message.h"
 -#include "pipeline.h"
 -#include "llappviewer.h"		// for do_disconnect()
 -
 -#include <deque>
 -#include <queue>
 -#include <map>
 -#include <cstring>
 -
 -
 -//
 -// Globals
 -//
 -U32			gAgentPauseSerialNum = 0;
 -
 -//
 -// Constants
 -//
 -const S32 MAX_NUMBER_OF_CLOUDS	= 750;
 -const S32 WORLD_PATCH_SIZE = 16;
 -
 -extern LLColor4U MAX_WATER_COLOR;
 -
 -const U32 LLWorld::mWidth = 256;
 -
 -// meters/point, therefore mWidth * mScale = meters per edge
 -const F32 LLWorld::mScale = 1.f;
 -
 -const F32 LLWorld::mWidthInMeters = mWidth * mScale;
 -
 -//
 -// Functions
 -//
 -
 -// allocate the stack
 -LLWorld::LLWorld() :
 -	mLandFarClip(DEFAULT_FAR_PLANE),
 -	mLastPacketsIn(0),
 -	mLastPacketsOut(0),
 -	mLastPacketsLost(0),
 -	mSpaceTimeUSec(0)
 -{
 -	for (S32 i = 0; i < 8; i++)
 -	{
 -		mEdgeWaterObjects[i] = NULL;
 -	}
 -
 -	LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,4);
 -	U8 *default_texture = raw->getData();
 -	*(default_texture++) = MAX_WATER_COLOR.mV[0];
 -	*(default_texture++) = MAX_WATER_COLOR.mV[1];
 -	*(default_texture++) = MAX_WATER_COLOR.mV[2];
 -	*(default_texture++) = MAX_WATER_COLOR.mV[3];
 -	
 -	mDefaultWaterTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE);
 -	gGL.getTexUnit(0)->bind(mDefaultWaterTexturep);
 -	mDefaultWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
 -
 -}
 -
 -
 -void LLWorld::destroyClass()
 -{
 -	mHoleWaterObjects.clear();
 -	gObjectList.destroy();
 -	for(region_list_t::iterator region_it = mRegionList.begin(); region_it != mRegionList.end(); )
 -	{
 -		LLViewerRegion* region_to_delete = *region_it++;
 -		removeRegion(region_to_delete->getHost());
 -	}
 -	if(LLVOCache::hasInstance())
 -	{
 -		LLVOCache::getInstance()->destroyClass() ;
 -	}
 -	LLViewerPartSim::getInstance()->destroyClass();
 -
 -	mDefaultWaterTexturep = NULL ;
 -	for (S32 i = 0; i < 8; i++)
 -	{
 -		mEdgeWaterObjects[i] = NULL;
 -	}
 -}
 -
 -
 -LLViewerRegion* LLWorld::addRegion(const U64 ®ion_handle, const LLHost &host)
 -{
 -	LLMemType mt(LLMemType::MTYPE_REGIONS);
 -	llinfos << "Add region with handle: " << region_handle << " on host " << host << llendl;
 -	LLViewerRegion *regionp = getRegionFromHandle(region_handle);
 -	if (regionp)
 -	{
 -		llinfos << "Region exists, removing it " << llendl;
 -		LLHost old_host = regionp->getHost();
 -		// region already exists!
 -		if (host == old_host && regionp->isAlive())
 -		{
 -			// This is a duplicate for the same host and it's alive, don't bother.
 -			return regionp;
 -		}
 -
 -		if (host != old_host)
 -		{
 -			llwarns << "LLWorld::addRegion exists, but old host " << old_host
 -					<< " does not match new host " << host << llendl;
 -		}
 -		if (!regionp->isAlive())
 -		{
 -			llwarns << "LLWorld::addRegion exists, but isn't alive" << llendl;
 -		}
 -
 -		// Kill the old host, and then we can continue on and add the new host.  We have to kill even if the host
 -		// matches, because all the agent state for the new camera is completely different.
 -		removeRegion(old_host);
 -	}
 -
 -	U32 iindex = 0;
 -	U32 jindex = 0;
 -	from_region_handle(region_handle, &iindex, &jindex);
 -	S32 x = (S32)(iindex/mWidth);
 -	S32 y = (S32)(jindex/mWidth);
 -	llinfos << "Adding new region (" << x << ":" << y << ")" << llendl;
 -	llinfos << "Host: " << host << llendl;
 -
 -	LLVector3d origin_global;
 -
 -	origin_global = from_region_handle(region_handle);
 -
 -	regionp = new LLViewerRegion(region_handle,
 -								    host,
 -									mWidth,
 -									WORLD_PATCH_SIZE,
 -									getRegionWidthInMeters() );
 -	if (!regionp)
 -	{
 -		llerrs << "Unable to create new region!" << llendl;
 -	}
 -
 -	mRegionList.push_back(regionp);
 -	mActiveRegionList.push_back(regionp);
 -	mCulledRegionList.push_back(regionp);
 -
 -
 -	// Find all the adjacent regions, and attach them.
 -	// Generate handles for all of the adjacent regions, and attach them in the correct way.
 -	// connect the edges
 -	F32 adj_x = 0.f;
 -	F32 adj_y = 0.f;
 -	F32 region_x = 0.f;
 -	F32 region_y = 0.f;
 -	U64 adj_handle = 0;
 -
 -	F32 width = getRegionWidthInMeters();
 -
 -	LLViewerRegion *neighborp;
 -	from_region_handle(region_handle, ®ion_x, ®ion_y);
 -
 -	// Iterate through all directions, and connect neighbors if there.
 -	S32 dir;
 -	for (dir = 0; dir < 8; dir++)
 -	{
 -		adj_x = region_x + width * gDirAxes[dir][0];
 -		adj_y = region_y + width * gDirAxes[dir][1];
 -		to_region_handle(adj_x, adj_y, &adj_handle);
 -
 -		neighborp = getRegionFromHandle(adj_handle);
 -		if (neighborp)
 -		{
 -			//llinfos << "Connecting " << region_x << ":" << region_y << " -> " << adj_x << ":" << adj_y << llendl;
 -			regionp->connectNeighbor(neighborp, dir);
 -		}
 -	}
 -
 -	updateWaterObjects();
 -
 -	return regionp;
 -}
 -
 -
 -void LLWorld::removeRegion(const LLHost &host)
 -{
 -	F32 x, y;
 -
 -	LLViewerRegion *regionp = getRegion(host);
 -	if (!regionp)
 -	{
 -		llwarns << "Trying to remove region that doesn't exist!" << llendl;
 -		return;
 -	}
 -	
 -	if (regionp == gAgent.getRegion())
 -	{
 -		for (region_list_t::iterator iter = mRegionList.begin();
 -			 iter != mRegionList.end(); ++iter)
 -		{
 -			LLViewerRegion* reg = *iter;
 -			llwarns << "RegionDump: " << reg->getName()
 -				<< " " << reg->getHost()
 -				<< " " << reg->getOriginGlobal()
 -				<< llendl;
 -		}
 -
 -		llwarns << "Agent position global " << gAgent.getPositionGlobal() 
 -			<< " agent " << gAgent.getPositionAgent()
 -			<< llendl;
 -
 -		llwarns << "Regions visited " << gAgent.getRegionsVisited() << llendl;
 -
 -		llwarns << "gFrameTimeSeconds " << gFrameTimeSeconds << llendl;
 -
 -		llwarns << "Disabling region " << regionp->getName() << " that agent is in!" << llendl;
 -		LLAppViewer::instance()->forceDisconnect(LLTrans::getString("YouHaveBeenDisconnected"));
 -
 -		regionp->saveObjectCache() ; //force to save objects here in case that the object cache is about to be destroyed.
 -		return;
 -	}
 -
 -	from_region_handle(regionp->getHandle(), &x, &y);
 -	llinfos << "Removing region " << x << ":" << y << llendl;
 -
 -	mRegionList.remove(regionp);
 -	mActiveRegionList.remove(regionp);
 -	mCulledRegionList.remove(regionp);
 -	mVisibleRegionList.remove(regionp);
 -	
 -	delete regionp;
 -
 -	updateWaterObjects();
 -
 -	//double check all objects of this region are removed.
 -	gObjectList.clearAllMapObjectsInRegion(regionp) ;
 -	//llassert_always(!gObjectList.hasMapObjectInRegion(regionp)) ;
 -}
 -
 -
 -LLViewerRegion* LLWorld::getRegion(const LLHost &host)
 -{
 -	for (region_list_t::iterator iter = mRegionList.begin();
 -		 iter != mRegionList.end(); ++iter)
 -	{
 -		LLViewerRegion* regionp = *iter;
 -		if (regionp->getHost() == host)
 -		{
 -			return regionp;
 -		}
 -	}
 -	return NULL;
 -}
 -
 -LLViewerRegion* LLWorld::getRegionFromPosAgent(const LLVector3 &pos)
 -{
 -	return getRegionFromPosGlobal(gAgent.getPosGlobalFromAgent(pos));
 -}
 -
 -LLViewerRegion* LLWorld::getRegionFromPosGlobal(const LLVector3d &pos)
 -{
 -	for (region_list_t::iterator iter = mRegionList.begin();
 -		 iter != mRegionList.end(); ++iter)
 -	{
 -		LLViewerRegion* regionp = *iter;
 -		if (regionp->pointInRegionGlobal(pos))
 -		{
 -			return regionp;
 -		}
 -	}
 -	return NULL;
 -}
 -
 -
 -LLVector3d	LLWorld::clipToVisibleRegions(const LLVector3d &start_pos, const LLVector3d &end_pos)
 -{
 -	if (positionRegionValidGlobal(end_pos))
 -	{
 -		return end_pos;
 -	}
 -
 -	LLViewerRegion* regionp = getRegionFromPosGlobal(start_pos);
 -	if (!regionp) 
 -	{
 -		return start_pos;
 -	}
 -
 -	LLVector3d delta_pos = end_pos - start_pos;
 -	LLVector3d delta_pos_abs;
 -	delta_pos_abs.setVec(delta_pos);
 -	delta_pos_abs.abs();
 -
 -	LLVector3 region_coord = regionp->getPosRegionFromGlobal(end_pos);
 -	F64 clip_factor = 1.0;
 -	F32 region_width = regionp->getWidth();
 -	if (region_coord.mV[VX] < 0.f)
 -	{
 -		if (region_coord.mV[VY] < region_coord.mV[VX])
 -		{
 -			// clip along y -
 -			clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]);
 -		}
 -		else
 -		{
 -			// clip along x -
 -			clip_factor = -(region_coord.mV[VX] / delta_pos_abs.mdV[VX]);
 -		}
 -	}
 -	else if (region_coord.mV[VX] > region_width)
 -	{
 -		if (region_coord.mV[VY] > region_coord.mV[VX])
 -		{
 -			// clip along y +
 -			clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY];
 -		}
 -		else
 -		{
 -			//clip along x +
 -			clip_factor = (region_coord.mV[VX] - region_width) / delta_pos_abs.mdV[VX];
 -		}
 -	}
 -	else if (region_coord.mV[VY] < 0.f)
 -	{
 -		// clip along y -
 -		clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]);
 -	}
 -	else if (region_coord.mV[VY] > region_width)
 -	{ 
 -		// clip along y +
 -		clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY];
 -	}
 -
 -	// clamp to within region dimensions
 -	LLVector3d final_region_pos = LLVector3d(region_coord) - (delta_pos * clip_factor);
 -	final_region_pos.mdV[VX] = llclamp(final_region_pos.mdV[VX], 0.0,
 -									   (F64)(region_width - F_ALMOST_ZERO));
 -	final_region_pos.mdV[VY] = llclamp(final_region_pos.mdV[VY], 0.0,
 -									   (F64)(region_width - F_ALMOST_ZERO));
 -	final_region_pos.mdV[VZ] = llclamp(final_region_pos.mdV[VZ], 0.0,
 -									   (F64)(LLWorld::getInstance()->getRegionMaxHeight() - F_ALMOST_ZERO));
 -	return regionp->getPosGlobalFromRegion(LLVector3(final_region_pos));
 -}
 -
 -LLViewerRegion* LLWorld::getRegionFromHandle(const U64 &handle)
 -{
 -	for (region_list_t::iterator iter = mRegionList.begin();
 -		 iter != mRegionList.end(); ++iter)
 -	{
 -		LLViewerRegion* regionp = *iter;
 -		if (regionp->getHandle() == handle)
 -		{
 -			return regionp;
 -		}
 -	}
 -	return NULL;
 -}
 -
 -
 -void LLWorld::updateAgentOffset(const LLVector3d &offset_global)
 -{
 -#if 0
 -	for (region_list_t::iterator iter = mRegionList.begin();
 -		 iter != mRegionList.end(); ++iter)
 -	{
 -		LLViewerRegion* regionp = *iter;
 -		regionp->setAgentOffset(offset_global);
 -	}
 -#endif
 -}
 -
 -
 -BOOL LLWorld::positionRegionValidGlobal(const LLVector3d &pos_global)
 -{
 -	for (region_list_t::iterator iter = mRegionList.begin();
 -		 iter != mRegionList.end(); ++iter)
 -	{
 -		LLViewerRegion* regionp = *iter;
 -		if (regionp->pointInRegionGlobal(pos_global))
 -		{
 -			return TRUE;
 -		}
 -	}
 -	return FALSE;
 -}
 -
 -
 -// Allow objects to go up to their radius underground.
 -F32 LLWorld::getMinAllowedZ(LLViewerObject* object, const LLVector3d &global_pos)
 -{
 -	F32 land_height = resolveLandHeightGlobal(global_pos);
 -	F32 radius = 0.5f * object->getScale().length();
 -	return land_height - radius;
 -}
 -
 -
 -
 -LLViewerRegion* LLWorld::resolveRegionGlobal(LLVector3 &pos_region, const LLVector3d &pos_global)
 -{
 -	LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global);
 -
 -	if (regionp)
 -	{
 -		pos_region = regionp->getPosRegionFromGlobal(pos_global);
 -		return regionp;
 -	}
 -
 -	return NULL;
 -}
 -
 -
 -LLViewerRegion* LLWorld::resolveRegionAgent(LLVector3 &pos_region, const LLVector3 &pos_agent)
 -{
 -	LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent);
 -	LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global);
 -
 -	if (regionp)
 -	{
 -		pos_region = regionp->getPosRegionFromGlobal(pos_global);
 -		return regionp;
 -	}
 -
 -	return NULL;
 -}
 -
 -
 -F32 LLWorld::resolveLandHeightAgent(const LLVector3 &pos_agent)
 -{
 -	LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent);
 -	return resolveLandHeightGlobal(pos_global);
 -}
 -
 -
 -F32 LLWorld::resolveLandHeightGlobal(const LLVector3d &pos_global)
 -{
 -	LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global);
 -	if (regionp)
 -	{
 -		return regionp->getLand().resolveHeightGlobal(pos_global);
 -	}
 -	return 0.0f;
 -}
 -
 -
 -// Takes a line defined by "point_a" and "point_b" and determines the closest (to point_a) 
 -// point where the the line intersects an object or the land surface.  Stores the results
 -// in "intersection" and "intersection_normal" and returns a scalar value that represents
 -// the normalized distance along the line from "point_a" to "intersection".
 -//
 -// Currently assumes point_a and point_b only differ in z-direction, 
 -// but it may eventually become more general.
 -F32 LLWorld::resolveStepHeightGlobal(const LLVOAvatar* avatarp, const LLVector3d &point_a, const LLVector3d &point_b, 
 -							   LLVector3d &intersection, LLVector3 &intersection_normal,
 -							   LLViewerObject **viewerObjectPtr)
 -{
 -	// initialize return value to null
 -	if (viewerObjectPtr)
 -	{
 -		*viewerObjectPtr = NULL;
 -	}
 -
 -	LLViewerRegion *regionp = getRegionFromPosGlobal(point_a);
 -	if (!regionp)
 -	{
 -		// We're outside the world 
 -		intersection = 0.5f * (point_a + point_b);
 -		intersection_normal.setVec(0.0f, 0.0f, 1.0f);
 -		return 0.5f;
 -	}
 -	
 -	// calculate the length of the segment
 -	F32 segment_length = (F32)((point_a - point_b).length());
 -	if (0.0f == segment_length)
 -	{
 -		intersection = point_a;
 -		intersection_normal.setVec(0.0f, 0.0f, 1.0f);
 -		return segment_length;
 -	}
 -
 -	// get land height	
 -	// Note: we assume that the line is parallel to z-axis here
 -	LLVector3d land_intersection = point_a;
 -	F32 normalized_land_distance;
 -
 -	land_intersection.mdV[VZ] = regionp->getLand().resolveHeightGlobal(point_a);
 -	normalized_land_distance = (F32)(point_a.mdV[VZ] - land_intersection.mdV[VZ]) / segment_length;
 -	intersection = land_intersection;
 -	intersection_normal = resolveLandNormalGlobal(land_intersection);
 -
 -	if (avatarp && !avatarp->mFootPlane.isExactlyClear())
 -	{
 -		LLVector3 foot_plane_normal(avatarp->mFootPlane.mV);
 -		LLVector3 start_pt = avatarp->getRegion()->getPosRegionFromGlobal(point_a);
 -		// added 0.05 meters to compensate for error in foot plane reported by Havok
 -		F32 norm_dist_from_plane = ((start_pt * foot_plane_normal) - avatarp->mFootPlane.mV[VW]) + 0.05f;
 -		norm_dist_from_plane = llclamp(norm_dist_from_plane / segment_length, 0.f, 1.f);
 -		if (norm_dist_from_plane < normalized_land_distance)
 -		{
 -			// collided with object before land
 -			normalized_land_distance = norm_dist_from_plane;
 -			intersection = point_a;
 -			intersection.mdV[VZ] -= norm_dist_from_plane * segment_length;
 -			intersection_normal = foot_plane_normal;
 -		}
 -		else
 -		{
 -			intersection = land_intersection;
 -			intersection_normal = resolveLandNormalGlobal(land_intersection);
 -		}
 -	}
 -
 -	return normalized_land_distance;
 -}
 -
 -
 -LLSurfacePatch * LLWorld::resolveLandPatchGlobal(const LLVector3d &pos_global)
 -{
 -	//  returns a pointer to the patch at this location
 -	LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global);
 -	if (!regionp)
 -	{
 -		return NULL;
 -	}
 -
 -	return regionp->getLand().resolvePatchGlobal(pos_global);
 -}
 -
 -
 -LLVector3 LLWorld::resolveLandNormalGlobal(const LLVector3d &pos_global)
 -{
 -	LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global);
 -	if (!regionp)
 -	{
 -		return LLVector3::z_axis;
 -	}
 -
 -	return regionp->getLand().resolveNormalGlobal(pos_global);
 -}
 -
 -
 -void LLWorld::updateVisibilities()
 -{
 -	F32 cur_far_clip = LLViewerCamera::getInstance()->getFar();
 -
 -	// Go through the culled list and check for visible regions (region is visible if land is visible)
 -	for (region_list_t::iterator iter = mCulledRegionList.begin();
 -		 iter != mCulledRegionList.end(); )
 -	{
 -		region_list_t::iterator curiter = iter++;
 -		LLViewerRegion* regionp = *curiter;
 -		
 -		LLSpatialPartition* part = regionp->getSpatialPartition(LLViewerRegion::PARTITION_TERRAIN);
 -		if (part)
 -		{
 -			LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0);
 -			if (LLViewerCamera::getInstance()->AABBInFrustum(group->mBounds[0], group->mBounds[1]))
 -			{
 -				mCulledRegionList.erase(curiter);
 -				mVisibleRegionList.push_back(regionp);
 -			}
 -		}
 -	}
 -	
 -	// Update all of the visible regions 
 -	for (region_list_t::iterator iter = mVisibleRegionList.begin();
 -		 iter != mVisibleRegionList.end(); )
 -	{
 -		region_list_t::iterator curiter = iter++;
 -		LLViewerRegion* regionp = *curiter;
 -		if (!regionp->getLand().hasZData())
 -		{
 -			continue;
 -		}
 -
 -		LLSpatialPartition* part = regionp->getSpatialPartition(LLViewerRegion::PARTITION_TERRAIN);
 -		if (part)
 -		{
 -			LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0);
 -			if (LLViewerCamera::getInstance()->AABBInFrustum(group->mBounds[0], group->mBounds[1]))
 -			{
 -				regionp->calculateCameraDistance();
 -				regionp->getLand().updatePatchVisibilities(gAgent);
 -			}
 -			else
 -			{
 -				mVisibleRegionList.erase(curiter);
 -				mCulledRegionList.push_back(regionp);
 -			}
 -		}
 -	}
 -
 -	// Sort visible regions
 -	mVisibleRegionList.sort(LLViewerRegion::CompareDistance());
 -	
 -	LLViewerCamera::getInstance()->setFar(cur_far_clip);
 -}
 -
 -void LLWorld::updateRegions(F32 max_update_time)
 -{
 -	LLMemType mt_ur(LLMemType::MTYPE_IDLE_UPDATE_REGIONS);
 -	LLTimer update_timer;
 -	BOOL did_one = FALSE;
 -	
 -	// Perform idle time updates for the regions (and associated surfaces)
 -	for (region_list_t::iterator iter = mRegionList.begin();
 -		 iter != mRegionList.end(); ++iter)
 -	{
 -		LLViewerRegion* regionp = *iter;
 -		F32 max_time = max_update_time - update_timer.getElapsedTimeF32();
 -		if (did_one && max_time <= 0.f)
 -			break;
 -		max_time = llmin(max_time, max_update_time*.1f);
 -		did_one |= regionp->idleUpdate(max_update_time);
 -	}
 -}
 -
 -void LLWorld::updateParticles()
 -{
 -	LLViewerPartSim::getInstance()->updateSimulation();
 -}
 -
 -void LLWorld::renderPropertyLines()
 -{
 -	S32 region_count = 0;
 -	S32 vertex_count = 0;
 -
 -	for (region_list_t::iterator iter = mVisibleRegionList.begin();
 -		 iter != mVisibleRegionList.end(); ++iter)
 -	{
 -		LLViewerRegion* regionp = *iter;
 -		region_count++;
 -		vertex_count += regionp->renderPropertyLines();
 -	}
 -}
 -
 -
 -void LLWorld::updateNetStats()
 -{
 -	F32 bits = 0.f;
 -	U32 packets = 0;
 -
 -	for (region_list_t::iterator iter = mActiveRegionList.begin();
 -		 iter != mActiveRegionList.end(); ++iter)
 -	{
 -		LLViewerRegion* regionp = *iter;
 -		regionp->updateNetStats();
 -		bits += regionp->mBitStat.getCurrent();
 -		packets += llfloor( regionp->mPacketsStat.getCurrent() );
 -	}
 -
 -	S32 packets_in = gMessageSystem->mPacketsIn - mLastPacketsIn;
 -	S32 packets_out = gMessageSystem->mPacketsOut - mLastPacketsOut;
 -	S32 packets_lost = gMessageSystem->mDroppedPackets - mLastPacketsLost;
 -
 -	S32 actual_in_bits = gMessageSystem->mPacketRing.getAndResetActualInBits();
 -	S32 actual_out_bits = gMessageSystem->mPacketRing.getAndResetActualOutBits();
 -	LLViewerStats::getInstance()->mActualInKBitStat.addValue(actual_in_bits/1024.f);
 -	LLViewerStats::getInstance()->mActualOutKBitStat.addValue(actual_out_bits/1024.f);
 -	LLViewerStats::getInstance()->mKBitStat.addValue(bits/1024.f);
 -	LLViewerStats::getInstance()->mPacketsInStat.addValue(packets_in);
 -	LLViewerStats::getInstance()->mPacketsOutStat.addValue(packets_out);
 -	LLViewerStats::getInstance()->mPacketsLostStat.addValue(gMessageSystem->mDroppedPackets);
 -	if (packets_in)
 -	{
 -		LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(100.f*((F32)packets_lost/(F32)packets_in));
 -	}
 -	else
 -	{
 -		LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(0.f);
 -	}
 -
 -	mLastPacketsIn = gMessageSystem->mPacketsIn;
 -	mLastPacketsOut = gMessageSystem->mPacketsOut;
 -	mLastPacketsLost = gMessageSystem->mDroppedPackets;
 -}
 -
 -
 -void LLWorld::printPacketsLost()
 -{
 -	llinfos << "Simulators:" << llendl;
 -	llinfos << "----------" << llendl;
 -
 -	LLCircuitData *cdp = NULL;
 -	for (region_list_t::iterator iter = mActiveRegionList.begin();
 -		 iter != mActiveRegionList.end(); ++iter)
 -	{
 -		LLViewerRegion* regionp = *iter;
 -		cdp = gMessageSystem->mCircuitInfo.findCircuit(regionp->getHost());
 -		if (cdp)
 -		{
 -			LLVector3d range = regionp->getCenterGlobal() - gAgent.getPositionGlobal();
 -				
 -			llinfos << regionp->getHost() << ", range: " << range.length()
 -					<< " packets lost: " << cdp->getPacketsLost() << llendl;
 -		}
 -	}
 -}
 -
 -void LLWorld::processCoarseUpdate(LLMessageSystem* msg, void** user_data)
 -{
 -	LLViewerRegion* region = LLWorld::getInstance()->getRegion(msg->getSender());
 -	if( region )
 -	{
 -		region->updateCoarseLocations(msg);
 -	}
 -}
 -
 -F32 LLWorld::getLandFarClip() const
 -{
 -	return mLandFarClip;
 -}
 -
 -void LLWorld::setLandFarClip(const F32 far_clip)
 -{
 -	static S32 const rwidth = (S32)REGION_WIDTH_U32;
 -	S32 const n1 = (llceil(mLandFarClip) - 1) / rwidth;
 -	S32 const n2 = (llceil(far_clip) - 1) / rwidth;
 -	bool need_water_objects_update = n1 != n2;
 -
 -	mLandFarClip = far_clip;
 -
 -	if (need_water_objects_update)
 -	{
 -		updateWaterObjects();
 -	}
 -}
 -
 -// Some region that we're connected to, but not the one we're in, gave us
 -// a (possibly) new water height. Update it in our local copy.
 -void LLWorld::waterHeightRegionInfo(std::string const& sim_name, F32 water_height)
 -{
 -	for (region_list_t::iterator iter = mRegionList.begin(); iter != mRegionList.end(); ++iter)
 -	{
 -		if ((*iter)->getName() == sim_name)
 -		{
 -			(*iter)->setWaterHeight(water_height);
 -			break;
 -		}
 -	}
 -}
 -
 -void LLWorld::updateWaterObjects()
 -{
 -	if (!gAgent.getRegion())
 -	{
 -		return;
 -	}
 -	if (mRegionList.empty())
 -	{
 -		llwarns << "No regions!" << llendl;
 -		return;
 -	}
 -
 -	// First, determine the min and max "box" of water objects
 -	S32 min_x = 0;
 -	S32 min_y = 0;
 -	S32 max_x = 0;
 -	S32 max_y = 0;
 -	U32 region_x, region_y;
 -
 -	S32 rwidth = 256;
 -
 -	// We only want to fill in water for stuff that's near us, say, within 256 or 512m
 -	S32 range = LLViewerCamera::getInstance()->getFar() > 256.f ? 512 : 256;
 -
 -	LLViewerRegion* regionp = gAgent.getRegion();
 -	from_region_handle(regionp->getHandle(), ®ion_x, ®ion_y);
 -
 -	min_x = (S32)region_x - range;
 -	min_y = (S32)region_y - range;
 -	max_x = (S32)region_x + range;
 -	max_y = (S32)region_y + range;
 -
 -	for (region_list_t::iterator iter = mRegionList.begin();
 -		 iter != mRegionList.end(); ++iter)
 -	{
 -		LLViewerRegion* regionp = *iter;
 -		LLVOWater* waterp = regionp->getLand().getWaterObj();
 -		if (waterp)
 -		{
 -			gObjectList.updateActive(waterp);
 -		}
 -	}
 -
 -	for (std::list<LLVOWater*>::iterator iter = mHoleWaterObjects.begin();
 -		 iter != mHoleWaterObjects.end(); ++ iter)
 -	{
 -		LLVOWater* waterp = *iter;
 -		gObjectList.killObject(waterp);
 -	}
 -	mHoleWaterObjects.clear();
 -
 -	// Now, get a list of the holes
 -	S32 x, y;
 -	F32 water_height = gAgent.getRegion()->getWaterHeight() + 256.f;
 -	for (x = min_x; x <= max_x; x += rwidth)
 -	{
 -		for (y = min_y; y <= max_y; y += rwidth)
 -		{
 -			U64 region_handle = to_region_handle(x, y);
 -			if (!getRegionFromHandle(region_handle))
 -			{
 -				LLVOWater* waterp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, gAgent.getRegion());
 -				waterp->setUseTexture(FALSE);
 -				waterp->setPositionGlobal(LLVector3d(x + rwidth/2,
 -													 y + rwidth/2,
 -													 water_height));
 -				waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, 512.f));
 -				gPipeline.createObject(waterp);
 -				mHoleWaterObjects.push_back(waterp);
 -			}
 -		}
 -	}
 -
 -	// Update edge water objects
 -	S32 wx, wy;
 -	S32 center_x, center_y;
 -	wx = (max_x - min_x) + rwidth;
 -	wy = (max_y - min_y) + rwidth;
 -	center_x = min_x + (wx >> 1);
 -	center_y = min_y + (wy >> 1);
 -
 -	S32 add_boundary[4] = {
 -		512 - (max_x - region_x),
 -		512 - (max_y - region_y),
 -		512 - (region_x - min_x),
 -		512 - (region_y - min_y) };
 -		
 -	S32 dir;
 -	for (dir = 0; dir < 8; dir++)
 -	{
 -		S32 dim[2] = { 0 };
 -		switch (gDirAxes[dir][0])
 -		{
 -		case -1: dim[0] = add_boundary[2]; break;
 -		case  0: dim[0] = wx; break;
 -		default: dim[0] = add_boundary[0]; break;
 -		}
 -		switch (gDirAxes[dir][1])
 -		{
 -		case -1: dim[1] = add_boundary[3]; break;
 -		case  0: dim[1] = wy; break;
 -		default: dim[1] = add_boundary[1]; break;
 -		}
 -
 -		// Resize and reshape the water objects
 -		const S32 water_center_x = center_x + llround((wx + dim[0]) * 0.5f * gDirAxes[dir][0]);
 -		const S32 water_center_y = center_y + llround((wy + dim[1]) * 0.5f * gDirAxes[dir][1]);
 -		
 -		LLVOWater* waterp = mEdgeWaterObjects[dir];
 -		if (!waterp || waterp->isDead())
 -		{
 -			// The edge water objects can be dead because they're attached to the region that the
 -			// agent was in when they were originally created.
 -			mEdgeWaterObjects[dir] = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_VOID_WATER,
 -																				 gAgent.getRegion());
 -			waterp = mEdgeWaterObjects[dir];
 -			waterp->setUseTexture(FALSE);
 -			waterp->setIsEdgePatch(TRUE);
 -			gPipeline.createObject(waterp);
 -		}
 -
 -		waterp->setRegion(gAgent.getRegion());
 -		LLVector3d water_pos(water_center_x, water_center_y, water_height) ;
 -		LLVector3 water_scale((F32) dim[0], (F32) dim[1], 512.f);
 -
 -		//stretch out to horizon
 -		water_scale.mV[0] += fabsf(2048.f * gDirAxes[dir][0]);
 -		water_scale.mV[1] += fabsf(2048.f * gDirAxes[dir][1]);
 -
 -		water_pos.mdV[0] += 1024.f * gDirAxes[dir][0];
 -		water_pos.mdV[1] += 1024.f * gDirAxes[dir][1];
 -
 -		waterp->setPositionGlobal(water_pos);
 -		waterp->setScale(water_scale);
 -
 -		gObjectList.updateActive(waterp);
 -	}
 -}
 -
 -
 -void LLWorld::shiftRegions(const LLVector3& offset)
 -{
 -	for (region_list_t::const_iterator i = getRegionList().begin(); i != getRegionList().end(); ++i)
 -	{
 -		LLViewerRegion* region = *i;
 -		region->updateRenderMatrix();
 -	}
 -
 -	LLViewerPartSim::getInstance()->shift(offset);
 -}
 -
 -LLViewerTexture* LLWorld::getDefaultWaterTexture()
 -{
 -	return mDefaultWaterTexturep;
 -}
 -
 -void LLWorld::setSpaceTimeUSec(const U64 space_time_usec)
 -{
 -	mSpaceTimeUSec = space_time_usec;
 -}
 -
 -U64 LLWorld::getSpaceTimeUSec() const
 -{
 -	return mSpaceTimeUSec;
 -}
 -
 -void LLWorld::requestCacheMisses()
 -{
 -	for (region_list_t::iterator iter = mRegionList.begin();
 -		 iter != mRegionList.end(); ++iter)
 -	{
 -		LLViewerRegion* regionp = *iter;
 -		regionp->requestCacheMisses();
 -	}
 -}
 -
 -void LLWorld::getInfo(LLSD& info)
 -{
 -	LLSD region_info;
 -	for (region_list_t::iterator iter = mRegionList.begin();
 -		 iter != mRegionList.end(); ++iter)
 -	{	
 -		LLViewerRegion* regionp = *iter;
 -		regionp->getInfo(region_info);
 -		info["World"].append(region_info);
 -	}
 -}
 -
 -void LLWorld::disconnectRegions()
 -{
 -	LLMessageSystem* msg = gMessageSystem;
 -	for (region_list_t::iterator iter = mRegionList.begin();
 -		 iter != mRegionList.end(); ++iter)
 -	{
 -		LLViewerRegion* regionp = *iter;
 -		if (regionp == gAgent.getRegion())
 -		{
 -			// Skip the main agent
 -			continue;
 -		}
 -
 -		llinfos << "Sending AgentQuitCopy to: " << regionp->getHost() << llendl;
 -		msg->newMessageFast(_PREHASH_AgentQuitCopy);
 -		msg->nextBlockFast(_PREHASH_AgentData);
 -		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 -		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 -		msg->nextBlockFast(_PREHASH_FuseBlock);
 -		msg->addU32Fast(_PREHASH_ViewerCircuitCode, gMessageSystem->mOurCircuitCode);
 -		msg->sendMessage(regionp->getHost());
 -	}
 -}
 -
 -static LLFastTimer::DeclareTimer FTM_ENABLE_SIMULATOR("Enable Sim");
 -
 -void process_enable_simulator(LLMessageSystem *msg, void **user_data)
 -{
 -	LLFastTimer t(FTM_ENABLE_SIMULATOR);
 -	// enable the appropriate circuit for this simulator and 
 -	// add its values into the gSimulator structure
 -	U64		handle;
 -	U32		ip_u32;
 -	U16		port;
 -
 -	msg->getU64Fast(_PREHASH_SimulatorInfo, _PREHASH_Handle, handle);
 -	msg->getIPAddrFast(_PREHASH_SimulatorInfo, _PREHASH_IP, ip_u32);
 -	msg->getIPPortFast(_PREHASH_SimulatorInfo, _PREHASH_Port, port);
 -
 -	// which simulator should we modify?
 -	LLHost sim(ip_u32, port);
 -
 -	// Viewer trusts the simulator.
 -	msg->enableCircuit(sim, TRUE);
 -	LLWorld::getInstance()->addRegion(handle, sim);
 -
 -	// give the simulator a message it can use to get ip and port
 -	llinfos << "simulator_enable() Enabling " << sim << " with code " << msg->getOurCircuitCode() << llendl;
 -	msg->newMessageFast(_PREHASH_UseCircuitCode);
 -	msg->nextBlockFast(_PREHASH_CircuitCode);
 -	msg->addU32Fast(_PREHASH_Code, msg->getOurCircuitCode());
 -	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 -	msg->addUUIDFast(_PREHASH_ID, gAgent.getID());
 -	msg->sendReliable(sim);
 -}
 -
 -class LLEstablishAgentCommunication : public LLHTTPNode
 -{
 -	LOG_CLASS(LLEstablishAgentCommunication);
 -public:
 - 	virtual void describe(Description& desc) const
 -	{
 -		desc.shortInfo("seed capability info for a region");
 -		desc.postAPI();
 -		desc.input(
 -			"{ seed-capability: ..., sim-ip: ..., sim-port }");
 -		desc.source(__FILE__, __LINE__);
 -	}
 -
 -	virtual void post(ResponsePtr response, const LLSD& context, const LLSD& input) const
 -	{
 -		if (!input["body"].has("agent-id") ||
 -			!input["body"].has("sim-ip-and-port") ||
 -			!input["body"].has("seed-capability"))
 -		{
 -			llwarns << "invalid parameters" << llendl;
 -            return;
 -		}
 -
 -		LLHost sim(input["body"]["sim-ip-and-port"].asString());
 -	
 -		LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(sim);
 -		if (!regionp)
 -		{
 -			llwarns << "Got EstablishAgentCommunication for unknown region "
 -					<< sim << llendl;
 -			return;
 -		}
 -		regionp->setSeedCapability(input["body"]["seed-capability"]);
 -	}
 -};
 -
 -// disable the circuit to this simulator
 -// Called in response to "DisableSimulator" message.
 -void process_disable_simulator(LLMessageSystem *mesgsys, void **user_data)
 -{	
 -	LLHost host = mesgsys->getSender();
 -
 -	//llinfos << "Disabling simulator with message from " << host << llendl;
 -	LLWorld::getInstance()->removeRegion(host);
 -
 -	mesgsys->disableCircuit(host);
 -}
 -
 -
 -void process_region_handshake(LLMessageSystem* msg, void** user_data)
 -{
 -	LLHost host = msg->getSender();
 -	LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(host);
 -	if (!regionp)
 -	{
 -		llwarns << "Got region handshake for unknown region "
 -			<< host << llendl;
 -		return;
 -	}
 -
 -	regionp->unpackRegionHandshake();
 -}
 -
 -
 -void send_agent_pause()
 -{
 -	// *NOTE:Mani Pausing the mainloop timeout. Otherwise a long modal event may cause
 -	// the thread monitor to timeout.
 -	LLAppViewer::instance()->pauseMainloopTimeout();
 -	
 -	// Note: used to check for LLWorld initialization before it became a singleton.
 -	// Rather than just remove this check I'm changing it to assure that the message 
 -	// system has been initialized. -MG
 -	if (!gMessageSystem)
 -	{
 -		return;
 -	}
 -	
 -	gMessageSystem->newMessageFast(_PREHASH_AgentPause);
 -	gMessageSystem->nextBlockFast(_PREHASH_AgentData);
 -	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID);
 -	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
 -
 -	gAgentPauseSerialNum++;
 -	gMessageSystem->addU32Fast(_PREHASH_SerialNum, gAgentPauseSerialNum);
 -
 -	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
 -		 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
 -	{
 -		LLViewerRegion* regionp = *iter;
 -		gMessageSystem->sendReliable(regionp->getHost());
 -	}
 -
 -	gObjectList.mWasPaused = TRUE;
 -}
 -
 -
 -void send_agent_resume()
 -{
 -	// Note: used to check for LLWorld initialization before it became a singleton.
 -	// Rather than just remove this check I'm changing it to assure that the message 
 -	// system has been initialized. -MG
 -	if (!gMessageSystem)
 -	{
 -		return;
 -	}
 -
 -	gMessageSystem->newMessageFast(_PREHASH_AgentResume);
 -	gMessageSystem->nextBlockFast(_PREHASH_AgentData);
 -	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID);
 -	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
 -
 -	gAgentPauseSerialNum++;
 -	gMessageSystem->addU32Fast(_PREHASH_SerialNum, gAgentPauseSerialNum);
 -	
 -
 -	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
 -		 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
 -	{
 -		LLViewerRegion* regionp = *iter;
 -		gMessageSystem->sendReliable(regionp->getHost());
 -	}
 -
 -	// Reset the FPS counter to avoid an invalid fps
 -	LLViewerStats::getInstance()->mFPSStat.start();
 -
 -	LLAppViewer::instance()->resumeMainloopTimeout();
 -}
 -
 -static LLVector3d unpackLocalToGlobalPosition(U32 compact_local, const LLVector3d& region_origin)
 -{
 -	LLVector3d pos_local;
 -
 -	pos_local.mdV[VZ] = (compact_local & 0xFFU) * 4;
 -	pos_local.mdV[VY] = (compact_local >> 8) & 0xFFU;
 -	pos_local.mdV[VX] = (compact_local >> 16) & 0xFFU;
 -
 -	return region_origin + pos_local;
 -}
 -
 -void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positions, const LLVector3d& relative_to, F32 radius) const
 -{
 -	F32 radius_squared = radius * radius;
 -	
 -	if(avatar_ids != NULL)
 -	{
 -		avatar_ids->clear();
 -	}
 -	if(positions != NULL)
 -	{
 -		positions->clear();
 -	}
 -	// get the list of avatars from the character list first, so distances are correct
 -	// when agent is above 1020m and other avatars are nearby
 -	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
 -		iter != LLCharacter::sInstances.end(); ++iter)
 -	{
 -		LLVOAvatar* pVOAvatar = (LLVOAvatar*) *iter;
 -		LLVector3d pos_global = pVOAvatar->getPositionGlobal();
 -		LLUUID uuid = pVOAvatar->getID();
 -		if( !pVOAvatar->isDead()
 -			&& !pVOAvatar->isSelf()
 -			&& !uuid.isNull() &&
 -			dist_vec_squared(pos_global, relative_to) <= radius_squared)
 -		{
 -			if(positions != NULL)
 -			{
 -				positions->push_back(pos_global);
 -			}
 -			if(avatar_ids !=NULL)
 -			{
 -				avatar_ids->push_back(uuid);
 -			}
 -		}
 -	}
 -	// region avatars added for situations where radius is greater than RenderFarClip
 -	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
 -		iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
 -	{
 -		LLViewerRegion* regionp = *iter;
 -		const LLVector3d& origin_global = regionp->getOriginGlobal();
 -		S32 count = regionp->mMapAvatars.count();
 -		for (S32 i = 0; i < count; i++)
 -		{
 -			LLVector3d pos_global = unpackLocalToGlobalPosition(regionp->mMapAvatars.get(i), origin_global);
 -			if(dist_vec_squared(pos_global, relative_to) <= radius_squared)
 -			{
 -				LLUUID uuid = regionp->mMapAvatarIDs.get(i);
 -				// if this avatar doesn't already exist in the list, add it
 -				if(uuid.notNull() && avatar_ids != NULL && std::find(avatar_ids->begin(), avatar_ids->end(), uuid) == avatar_ids->end())
 -				{
 -					if (positions != NULL)
 -					{
 -						positions->push_back(pos_global);
 -					}
 -					avatar_ids->push_back(uuid);
 -				}
 -			}
 -		}
 -	}
 -}
 -
 -
 -LLHTTPRegistration<LLEstablishAgentCommunication>
 -	gHTTPRegistrationEstablishAgentCommunication(
 -							"/message/EstablishAgentCommunication");
 +/**  + * @file llworld.cpp + * @brief Initial test structure to organize viewer regions + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llworld.h" +#include "llrender.h" + +#include "indra_constants.h" +#include "llstl.h" + +#include "llagent.h" +#include "llviewercontrol.h" +#include "lldrawpool.h" +#include "llglheaders.h" +#include "llhttpnode.h" +#include "llregionhandle.h" +#include "llsurface.h" +#include "lltrans.h" +#include "llviewercamera.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" +#include "llviewernetwork.h" +#include "llviewerobjectlist.h" +#include "llviewerparceloverlay.h" +#include "llviewerregion.h" +#include "llviewerstats.h" +#include "llvlcomposition.h" +#include "llvoavatar.h" +#include "llvocache.h" +#include "llvowater.h" +#include "message.h" +#include "pipeline.h" +#include "llappviewer.h"		// for do_disconnect() + +#include <deque> +#include <queue> +#include <map> +#include <cstring> + + +// +// Globals +// +U32			gAgentPauseSerialNum = 0; + +// +// Constants +// +const S32 MAX_NUMBER_OF_CLOUDS	= 750; +const S32 WORLD_PATCH_SIZE = 16; + +extern LLColor4U MAX_WATER_COLOR; + +const U32 LLWorld::mWidth = 256; + +// meters/point, therefore mWidth * mScale = meters per edge +const F32 LLWorld::mScale = 1.f; + +const F32 LLWorld::mWidthInMeters = mWidth * mScale; + +// +// Functions +// + +// allocate the stack +LLWorld::LLWorld() : +	mLandFarClip(DEFAULT_FAR_PLANE), +	mLastPacketsIn(0), +	mLastPacketsOut(0), +	mLastPacketsLost(0), +	mSpaceTimeUSec(0) +{ +	for (S32 i = 0; i < 8; i++) +	{ +		mEdgeWaterObjects[i] = NULL; +	} + +	LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,4); +	U8 *default_texture = raw->getData(); +	*(default_texture++) = MAX_WATER_COLOR.mV[0]; +	*(default_texture++) = MAX_WATER_COLOR.mV[1]; +	*(default_texture++) = MAX_WATER_COLOR.mV[2]; +	*(default_texture++) = MAX_WATER_COLOR.mV[3]; +	 +	mDefaultWaterTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); +	gGL.getTexUnit(0)->bind(mDefaultWaterTexturep); +	mDefaultWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); + +} + + +void LLWorld::destroyClass() +{ +	mHoleWaterObjects.clear(); +	gObjectList.destroy(); +	for(region_list_t::iterator region_it = mRegionList.begin(); region_it != mRegionList.end(); ) +	{ +		LLViewerRegion* region_to_delete = *region_it++; +		removeRegion(region_to_delete->getHost()); +	} +	if(LLVOCache::hasInstance()) +	{ +		LLVOCache::getInstance()->destroyClass() ; +	} +	LLViewerPartSim::getInstance()->destroyClass(); + +	mDefaultWaterTexturep = NULL ; +	for (S32 i = 0; i < 8; i++) +	{ +		mEdgeWaterObjects[i] = NULL; +	} +} + + +LLViewerRegion* LLWorld::addRegion(const U64 ®ion_handle, const LLHost &host) +{ +	LLMemType mt(LLMemType::MTYPE_REGIONS); +	llinfos << "Add region with handle: " << region_handle << " on host " << host << llendl; +	LLViewerRegion *regionp = getRegionFromHandle(region_handle); +	if (regionp) +	{ +		llinfos << "Region exists, removing it " << llendl; +		LLHost old_host = regionp->getHost(); +		// region already exists! +		if (host == old_host && regionp->isAlive()) +		{ +			// This is a duplicate for the same host and it's alive, don't bother. +			return regionp; +		} + +		if (host != old_host) +		{ +			llwarns << "LLWorld::addRegion exists, but old host " << old_host +					<< " does not match new host " << host << llendl; +		} +		if (!regionp->isAlive()) +		{ +			llwarns << "LLWorld::addRegion exists, but isn't alive" << llendl; +		} + +		// Kill the old host, and then we can continue on and add the new host.  We have to kill even if the host +		// matches, because all the agent state for the new camera is completely different. +		removeRegion(old_host); +	} + +	U32 iindex = 0; +	U32 jindex = 0; +	from_region_handle(region_handle, &iindex, &jindex); +	S32 x = (S32)(iindex/mWidth); +	S32 y = (S32)(jindex/mWidth); +	llinfos << "Adding new region (" << x << ":" << y << ")" << llendl; +	llinfos << "Host: " << host << llendl; + +	LLVector3d origin_global; + +	origin_global = from_region_handle(region_handle); + +	regionp = new LLViewerRegion(region_handle, +								    host, +									mWidth, +									WORLD_PATCH_SIZE, +									getRegionWidthInMeters() ); +	if (!regionp) +	{ +		llerrs << "Unable to create new region!" << llendl; +	} + +	mRegionList.push_back(regionp); +	mActiveRegionList.push_back(regionp); +	mCulledRegionList.push_back(regionp); + + +	// Find all the adjacent regions, and attach them. +	// Generate handles for all of the adjacent regions, and attach them in the correct way. +	// connect the edges +	F32 adj_x = 0.f; +	F32 adj_y = 0.f; +	F32 region_x = 0.f; +	F32 region_y = 0.f; +	U64 adj_handle = 0; + +	F32 width = getRegionWidthInMeters(); + +	LLViewerRegion *neighborp; +	from_region_handle(region_handle, ®ion_x, ®ion_y); + +	// Iterate through all directions, and connect neighbors if there. +	S32 dir; +	for (dir = 0; dir < 8; dir++) +	{ +		adj_x = region_x + width * gDirAxes[dir][0]; +		adj_y = region_y + width * gDirAxes[dir][1]; +		to_region_handle(adj_x, adj_y, &adj_handle); + +		neighborp = getRegionFromHandle(adj_handle); +		if (neighborp) +		{ +			//llinfos << "Connecting " << region_x << ":" << region_y << " -> " << adj_x << ":" << adj_y << llendl; +			regionp->connectNeighbor(neighborp, dir); +		} +	} + +	updateWaterObjects(); + +	return regionp; +} + + +void LLWorld::removeRegion(const LLHost &host) +{ +	F32 x, y; + +	LLViewerRegion *regionp = getRegion(host); +	if (!regionp) +	{ +		llwarns << "Trying to remove region that doesn't exist!" << llendl; +		return; +	} +	 +	if (regionp == gAgent.getRegion()) +	{ +		for (region_list_t::iterator iter = mRegionList.begin(); +			 iter != mRegionList.end(); ++iter) +		{ +			LLViewerRegion* reg = *iter; +			llwarns << "RegionDump: " << reg->getName() +				<< " " << reg->getHost() +				<< " " << reg->getOriginGlobal() +				<< llendl; +		} + +		llwarns << "Agent position global " << gAgent.getPositionGlobal()  +			<< " agent " << gAgent.getPositionAgent() +			<< llendl; + +		llwarns << "Regions visited " << gAgent.getRegionsVisited() << llendl; + +		llwarns << "gFrameTimeSeconds " << gFrameTimeSeconds << llendl; + +		llwarns << "Disabling region " << regionp->getName() << " that agent is in!" << llendl; +		LLAppViewer::instance()->forceDisconnect(LLTrans::getString("YouHaveBeenDisconnected")); + +		regionp->saveObjectCache() ; //force to save objects here in case that the object cache is about to be destroyed. +		return; +	} + +	from_region_handle(regionp->getHandle(), &x, &y); +	llinfos << "Removing region " << x << ":" << y << llendl; + +	mRegionList.remove(regionp); +	mActiveRegionList.remove(regionp); +	mCulledRegionList.remove(regionp); +	mVisibleRegionList.remove(regionp); +	 +	delete regionp; + +	updateWaterObjects(); + +	//double check all objects of this region are removed. +	gObjectList.clearAllMapObjectsInRegion(regionp) ; +	//llassert_always(!gObjectList.hasMapObjectInRegion(regionp)) ; +} + + +LLViewerRegion* LLWorld::getRegion(const LLHost &host) +{ +	for (region_list_t::iterator iter = mRegionList.begin(); +		 iter != mRegionList.end(); ++iter) +	{ +		LLViewerRegion* regionp = *iter; +		if (regionp->getHost() == host) +		{ +			return regionp; +		} +	} +	return NULL; +} + +LLViewerRegion* LLWorld::getRegionFromPosAgent(const LLVector3 &pos) +{ +	return getRegionFromPosGlobal(gAgent.getPosGlobalFromAgent(pos)); +} + +LLViewerRegion* LLWorld::getRegionFromPosGlobal(const LLVector3d &pos) +{ +	for (region_list_t::iterator iter = mRegionList.begin(); +		 iter != mRegionList.end(); ++iter) +	{ +		LLViewerRegion* regionp = *iter; +		if (regionp->pointInRegionGlobal(pos)) +		{ +			return regionp; +		} +	} +	return NULL; +} + + +LLVector3d	LLWorld::clipToVisibleRegions(const LLVector3d &start_pos, const LLVector3d &end_pos) +{ +	if (positionRegionValidGlobal(end_pos)) +	{ +		return end_pos; +	} + +	LLViewerRegion* regionp = getRegionFromPosGlobal(start_pos); +	if (!regionp)  +	{ +		return start_pos; +	} + +	LLVector3d delta_pos = end_pos - start_pos; +	LLVector3d delta_pos_abs; +	delta_pos_abs.setVec(delta_pos); +	delta_pos_abs.abs(); + +	LLVector3 region_coord = regionp->getPosRegionFromGlobal(end_pos); +	F64 clip_factor = 1.0; +	F32 region_width = regionp->getWidth(); +	if (region_coord.mV[VX] < 0.f) +	{ +		if (region_coord.mV[VY] < region_coord.mV[VX]) +		{ +			// clip along y - +			clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]); +		} +		else +		{ +			// clip along x - +			clip_factor = -(region_coord.mV[VX] / delta_pos_abs.mdV[VX]); +		} +	} +	else if (region_coord.mV[VX] > region_width) +	{ +		if (region_coord.mV[VY] > region_coord.mV[VX]) +		{ +			// clip along y + +			clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY]; +		} +		else +		{ +			//clip along x + +			clip_factor = (region_coord.mV[VX] - region_width) / delta_pos_abs.mdV[VX]; +		} +	} +	else if (region_coord.mV[VY] < 0.f) +	{ +		// clip along y - +		clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]); +	} +	else if (region_coord.mV[VY] > region_width) +	{  +		// clip along y + +		clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY]; +	} + +	// clamp to within region dimensions +	LLVector3d final_region_pos = LLVector3d(region_coord) - (delta_pos * clip_factor); +	final_region_pos.mdV[VX] = llclamp(final_region_pos.mdV[VX], 0.0, +									   (F64)(region_width - F_ALMOST_ZERO)); +	final_region_pos.mdV[VY] = llclamp(final_region_pos.mdV[VY], 0.0, +									   (F64)(region_width - F_ALMOST_ZERO)); +	final_region_pos.mdV[VZ] = llclamp(final_region_pos.mdV[VZ], 0.0, +									   (F64)(LLWorld::getInstance()->getRegionMaxHeight() - F_ALMOST_ZERO)); +	return regionp->getPosGlobalFromRegion(LLVector3(final_region_pos)); +} + +LLViewerRegion* LLWorld::getRegionFromHandle(const U64 &handle) +{ +	for (region_list_t::iterator iter = mRegionList.begin(); +		 iter != mRegionList.end(); ++iter) +	{ +		LLViewerRegion* regionp = *iter; +		if (regionp->getHandle() == handle) +		{ +			return regionp; +		} +	} +	return NULL; +} + + +void LLWorld::updateAgentOffset(const LLVector3d &offset_global) +{ +#if 0 +	for (region_list_t::iterator iter = mRegionList.begin(); +		 iter != mRegionList.end(); ++iter) +	{ +		LLViewerRegion* regionp = *iter; +		regionp->setAgentOffset(offset_global); +	} +#endif +} + + +BOOL LLWorld::positionRegionValidGlobal(const LLVector3d &pos_global) +{ +	for (region_list_t::iterator iter = mRegionList.begin(); +		 iter != mRegionList.end(); ++iter) +	{ +		LLViewerRegion* regionp = *iter; +		if (regionp->pointInRegionGlobal(pos_global)) +		{ +			return TRUE; +		} +	} +	return FALSE; +} + + +// Allow objects to go up to their radius underground. +F32 LLWorld::getMinAllowedZ(LLViewerObject* object, const LLVector3d &global_pos) +{ +	F32 land_height = resolveLandHeightGlobal(global_pos); +	F32 radius = 0.5f * object->getScale().length(); +	return land_height - radius; +} + + + +LLViewerRegion* LLWorld::resolveRegionGlobal(LLVector3 &pos_region, const LLVector3d &pos_global) +{ +	LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global); + +	if (regionp) +	{ +		pos_region = regionp->getPosRegionFromGlobal(pos_global); +		return regionp; +	} + +	return NULL; +} + + +LLViewerRegion* LLWorld::resolveRegionAgent(LLVector3 &pos_region, const LLVector3 &pos_agent) +{ +	LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent); +	LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global); + +	if (regionp) +	{ +		pos_region = regionp->getPosRegionFromGlobal(pos_global); +		return regionp; +	} + +	return NULL; +} + + +F32 LLWorld::resolveLandHeightAgent(const LLVector3 &pos_agent) +{ +	LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent); +	return resolveLandHeightGlobal(pos_global); +} + + +F32 LLWorld::resolveLandHeightGlobal(const LLVector3d &pos_global) +{ +	LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global); +	if (regionp) +	{ +		return regionp->getLand().resolveHeightGlobal(pos_global); +	} +	return 0.0f; +} + + +// Takes a line defined by "point_a" and "point_b" and determines the closest (to point_a)  +// point where the the line intersects an object or the land surface.  Stores the results +// in "intersection" and "intersection_normal" and returns a scalar value that represents +// the normalized distance along the line from "point_a" to "intersection". +// +// Currently assumes point_a and point_b only differ in z-direction,  +// but it may eventually become more general. +F32 LLWorld::resolveStepHeightGlobal(const LLVOAvatar* avatarp, const LLVector3d &point_a, const LLVector3d &point_b,  +							   LLVector3d &intersection, LLVector3 &intersection_normal, +							   LLViewerObject **viewerObjectPtr) +{ +	// initialize return value to null +	if (viewerObjectPtr) +	{ +		*viewerObjectPtr = NULL; +	} + +	LLViewerRegion *regionp = getRegionFromPosGlobal(point_a); +	if (!regionp) +	{ +		// We're outside the world  +		intersection = 0.5f * (point_a + point_b); +		intersection_normal.setVec(0.0f, 0.0f, 1.0f); +		return 0.5f; +	} +	 +	// calculate the length of the segment +	F32 segment_length = (F32)((point_a - point_b).length()); +	if (0.0f == segment_length) +	{ +		intersection = point_a; +		intersection_normal.setVec(0.0f, 0.0f, 1.0f); +		return segment_length; +	} + +	// get land height	 +	// Note: we assume that the line is parallel to z-axis here +	LLVector3d land_intersection = point_a; +	F32 normalized_land_distance; + +	land_intersection.mdV[VZ] = regionp->getLand().resolveHeightGlobal(point_a); +	normalized_land_distance = (F32)(point_a.mdV[VZ] - land_intersection.mdV[VZ]) / segment_length; +	intersection = land_intersection; +	intersection_normal = resolveLandNormalGlobal(land_intersection); + +	if (avatarp && !avatarp->mFootPlane.isExactlyClear()) +	{ +		LLVector3 foot_plane_normal(avatarp->mFootPlane.mV); +		LLVector3 start_pt = avatarp->getRegion()->getPosRegionFromGlobal(point_a); +		// added 0.05 meters to compensate for error in foot plane reported by Havok +		F32 norm_dist_from_plane = ((start_pt * foot_plane_normal) - avatarp->mFootPlane.mV[VW]) + 0.05f; +		norm_dist_from_plane = llclamp(norm_dist_from_plane / segment_length, 0.f, 1.f); +		if (norm_dist_from_plane < normalized_land_distance) +		{ +			// collided with object before land +			normalized_land_distance = norm_dist_from_plane; +			intersection = point_a; +			intersection.mdV[VZ] -= norm_dist_from_plane * segment_length; +			intersection_normal = foot_plane_normal; +		} +		else +		{ +			intersection = land_intersection; +			intersection_normal = resolveLandNormalGlobal(land_intersection); +		} +	} + +	return normalized_land_distance; +} + + +LLSurfacePatch * LLWorld::resolveLandPatchGlobal(const LLVector3d &pos_global) +{ +	//  returns a pointer to the patch at this location +	LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global); +	if (!regionp) +	{ +		return NULL; +	} + +	return regionp->getLand().resolvePatchGlobal(pos_global); +} + + +LLVector3 LLWorld::resolveLandNormalGlobal(const LLVector3d &pos_global) +{ +	LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global); +	if (!regionp) +	{ +		return LLVector3::z_axis; +	} + +	return regionp->getLand().resolveNormalGlobal(pos_global); +} + + +void LLWorld::updateVisibilities() +{ +	F32 cur_far_clip = LLViewerCamera::getInstance()->getFar(); + +	// Go through the culled list and check for visible regions (region is visible if land is visible) +	for (region_list_t::iterator iter = mCulledRegionList.begin(); +		 iter != mCulledRegionList.end(); ) +	{ +		region_list_t::iterator curiter = iter++; +		LLViewerRegion* regionp = *curiter; +		 +		LLSpatialPartition* part = regionp->getSpatialPartition(LLViewerRegion::PARTITION_TERRAIN); +		if (part) +		{ +			LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0); +			if (LLViewerCamera::getInstance()->AABBInFrustum(group->mBounds[0], group->mBounds[1])) +			{ +				mCulledRegionList.erase(curiter); +				mVisibleRegionList.push_back(regionp); +			} +		} +	} +	 +	// Update all of the visible regions  +	for (region_list_t::iterator iter = mVisibleRegionList.begin(); +		 iter != mVisibleRegionList.end(); ) +	{ +		region_list_t::iterator curiter = iter++; +		LLViewerRegion* regionp = *curiter; +		if (!regionp->getLand().hasZData()) +		{ +			continue; +		} + +		LLSpatialPartition* part = regionp->getSpatialPartition(LLViewerRegion::PARTITION_TERRAIN); +		if (part) +		{ +			LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0); +			if (LLViewerCamera::getInstance()->AABBInFrustum(group->mBounds[0], group->mBounds[1])) +			{ +				regionp->calculateCameraDistance(); +				regionp->getLand().updatePatchVisibilities(gAgent); +			} +			else +			{ +				mVisibleRegionList.erase(curiter); +				mCulledRegionList.push_back(regionp); +			} +		} +	} + +	// Sort visible regions +	mVisibleRegionList.sort(LLViewerRegion::CompareDistance()); +	 +	LLViewerCamera::getInstance()->setFar(cur_far_clip); +} + +void LLWorld::updateRegions(F32 max_update_time) +{ +	LLMemType mt_ur(LLMemType::MTYPE_IDLE_UPDATE_REGIONS); +	LLTimer update_timer; +	BOOL did_one = FALSE; +	 +	// Perform idle time updates for the regions (and associated surfaces) +	for (region_list_t::iterator iter = mRegionList.begin(); +		 iter != mRegionList.end(); ++iter) +	{ +		LLViewerRegion* regionp = *iter; +		F32 max_time = max_update_time - update_timer.getElapsedTimeF32(); +		if (did_one && max_time <= 0.f) +			break; +		max_time = llmin(max_time, max_update_time*.1f); +		did_one |= regionp->idleUpdate(max_update_time); +	} +} + +void LLWorld::updateParticles() +{ +	LLViewerPartSim::getInstance()->updateSimulation(); +} + +void LLWorld::renderPropertyLines() +{ +	S32 region_count = 0; +	S32 vertex_count = 0; + +	for (region_list_t::iterator iter = mVisibleRegionList.begin(); +		 iter != mVisibleRegionList.end(); ++iter) +	{ +		LLViewerRegion* regionp = *iter; +		region_count++; +		vertex_count += regionp->renderPropertyLines(); +	} +} + + +void LLWorld::updateNetStats() +{ +	F32 bits = 0.f; +	U32 packets = 0; + +	for (region_list_t::iterator iter = mActiveRegionList.begin(); +		 iter != mActiveRegionList.end(); ++iter) +	{ +		LLViewerRegion* regionp = *iter; +		regionp->updateNetStats(); +		bits += regionp->mBitStat.getCurrent(); +		packets += llfloor( regionp->mPacketsStat.getCurrent() ); +	} + +	S32 packets_in = gMessageSystem->mPacketsIn - mLastPacketsIn; +	S32 packets_out = gMessageSystem->mPacketsOut - mLastPacketsOut; +	S32 packets_lost = gMessageSystem->mDroppedPackets - mLastPacketsLost; + +	S32 actual_in_bits = gMessageSystem->mPacketRing.getAndResetActualInBits(); +	S32 actual_out_bits = gMessageSystem->mPacketRing.getAndResetActualOutBits(); +	LLViewerStats::getInstance()->mActualInKBitStat.addValue(actual_in_bits/1024.f); +	LLViewerStats::getInstance()->mActualOutKBitStat.addValue(actual_out_bits/1024.f); +	LLViewerStats::getInstance()->mKBitStat.addValue(bits/1024.f); +	LLViewerStats::getInstance()->mPacketsInStat.addValue(packets_in); +	LLViewerStats::getInstance()->mPacketsOutStat.addValue(packets_out); +	LLViewerStats::getInstance()->mPacketsLostStat.addValue(gMessageSystem->mDroppedPackets); +	if (packets_in) +	{ +		LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(100.f*((F32)packets_lost/(F32)packets_in)); +	} +	else +	{ +		LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(0.f); +	} + +	mLastPacketsIn = gMessageSystem->mPacketsIn; +	mLastPacketsOut = gMessageSystem->mPacketsOut; +	mLastPacketsLost = gMessageSystem->mDroppedPackets; +} + + +void LLWorld::printPacketsLost() +{ +	llinfos << "Simulators:" << llendl; +	llinfos << "----------" << llendl; + +	LLCircuitData *cdp = NULL; +	for (region_list_t::iterator iter = mActiveRegionList.begin(); +		 iter != mActiveRegionList.end(); ++iter) +	{ +		LLViewerRegion* regionp = *iter; +		cdp = gMessageSystem->mCircuitInfo.findCircuit(regionp->getHost()); +		if (cdp) +		{ +			LLVector3d range = regionp->getCenterGlobal() - gAgent.getPositionGlobal(); +				 +			llinfos << regionp->getHost() << ", range: " << range.length() +					<< " packets lost: " << cdp->getPacketsLost() << llendl; +		} +	} +} + +void LLWorld::processCoarseUpdate(LLMessageSystem* msg, void** user_data) +{ +	LLViewerRegion* region = LLWorld::getInstance()->getRegion(msg->getSender()); +	if( region ) +	{ +		region->updateCoarseLocations(msg); +	} +} + +F32 LLWorld::getLandFarClip() const +{ +	return mLandFarClip; +} + +void LLWorld::setLandFarClip(const F32 far_clip) +{ +	static S32 const rwidth = (S32)REGION_WIDTH_U32; +	S32 const n1 = (llceil(mLandFarClip) - 1) / rwidth; +	S32 const n2 = (llceil(far_clip) - 1) / rwidth; +	bool need_water_objects_update = n1 != n2; + +	mLandFarClip = far_clip; + +	if (need_water_objects_update) +	{ +		updateWaterObjects(); +	} +} + +// Some region that we're connected to, but not the one we're in, gave us +// a (possibly) new water height. Update it in our local copy. +void LLWorld::waterHeightRegionInfo(std::string const& sim_name, F32 water_height) +{ +	for (region_list_t::iterator iter = mRegionList.begin(); iter != mRegionList.end(); ++iter) +	{ +		if ((*iter)->getName() == sim_name) +		{ +			(*iter)->setWaterHeight(water_height); +			break; +		} +	} +} + +void LLWorld::updateWaterObjects() +{ +	if (!gAgent.getRegion()) +	{ +		return; +	} +	if (mRegionList.empty()) +	{ +		llwarns << "No regions!" << llendl; +		return; +	} + +	// First, determine the min and max "box" of water objects +	S32 min_x = 0; +	S32 min_y = 0; +	S32 max_x = 0; +	S32 max_y = 0; +	U32 region_x, region_y; + +	S32 rwidth = 256; + +	// We only want to fill in water for stuff that's near us, say, within 256 or 512m +	S32 range = LLViewerCamera::getInstance()->getFar() > 256.f ? 512 : 256; + +	LLViewerRegion* regionp = gAgent.getRegion(); +	from_region_handle(regionp->getHandle(), ®ion_x, ®ion_y); + +	min_x = (S32)region_x - range; +	min_y = (S32)region_y - range; +	max_x = (S32)region_x + range; +	max_y = (S32)region_y + range; + +	for (region_list_t::iterator iter = mRegionList.begin(); +		 iter != mRegionList.end(); ++iter) +	{ +		LLViewerRegion* regionp = *iter; +		LLVOWater* waterp = regionp->getLand().getWaterObj(); +		if (waterp) +		{ +			gObjectList.updateActive(waterp); +		} +	} + +	for (std::list<LLVOWater*>::iterator iter = mHoleWaterObjects.begin(); +		 iter != mHoleWaterObjects.end(); ++ iter) +	{ +		LLVOWater* waterp = *iter; +		gObjectList.killObject(waterp); +	} +	mHoleWaterObjects.clear(); + +	// Now, get a list of the holes +	S32 x, y; +	F32 water_height = gAgent.getRegion()->getWaterHeight() + 256.f; +	for (x = min_x; x <= max_x; x += rwidth) +	{ +		for (y = min_y; y <= max_y; y += rwidth) +		{ +			U64 region_handle = to_region_handle(x, y); +			if (!getRegionFromHandle(region_handle)) +			{ +				LLVOWater* waterp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, gAgent.getRegion()); +				waterp->setUseTexture(FALSE); +				waterp->setPositionGlobal(LLVector3d(x + rwidth/2, +													 y + rwidth/2, +													 water_height)); +				waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, 512.f)); +				gPipeline.createObject(waterp); +				mHoleWaterObjects.push_back(waterp); +			} +		} +	} + +	// Update edge water objects +	S32 wx, wy; +	S32 center_x, center_y; +	wx = (max_x - min_x) + rwidth; +	wy = (max_y - min_y) + rwidth; +	center_x = min_x + (wx >> 1); +	center_y = min_y + (wy >> 1); + +	S32 add_boundary[4] = { +		512 - (max_x - region_x), +		512 - (max_y - region_y), +		512 - (region_x - min_x), +		512 - (region_y - min_y) }; +		 +	S32 dir; +	for (dir = 0; dir < 8; dir++) +	{ +		S32 dim[2] = { 0 }; +		switch (gDirAxes[dir][0]) +		{ +		case -1: dim[0] = add_boundary[2]; break; +		case  0: dim[0] = wx; break; +		default: dim[0] = add_boundary[0]; break; +		} +		switch (gDirAxes[dir][1]) +		{ +		case -1: dim[1] = add_boundary[3]; break; +		case  0: dim[1] = wy; break; +		default: dim[1] = add_boundary[1]; break; +		} + +		// Resize and reshape the water objects +		const S32 water_center_x = center_x + llround((wx + dim[0]) * 0.5f * gDirAxes[dir][0]); +		const S32 water_center_y = center_y + llround((wy + dim[1]) * 0.5f * gDirAxes[dir][1]); +		 +		LLVOWater* waterp = mEdgeWaterObjects[dir]; +		if (!waterp || waterp->isDead()) +		{ +			// The edge water objects can be dead because they're attached to the region that the +			// agent was in when they were originally created. +			mEdgeWaterObjects[dir] = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_VOID_WATER, +																				 gAgent.getRegion()); +			waterp = mEdgeWaterObjects[dir]; +			waterp->setUseTexture(FALSE); +			waterp->setIsEdgePatch(TRUE); +			gPipeline.createObject(waterp); +		} + +		waterp->setRegion(gAgent.getRegion()); +		LLVector3d water_pos(water_center_x, water_center_y, water_height) ; +		LLVector3 water_scale((F32) dim[0], (F32) dim[1], 512.f); + +		//stretch out to horizon +		water_scale.mV[0] += fabsf(2048.f * gDirAxes[dir][0]); +		water_scale.mV[1] += fabsf(2048.f * gDirAxes[dir][1]); + +		water_pos.mdV[0] += 1024.f * gDirAxes[dir][0]; +		water_pos.mdV[1] += 1024.f * gDirAxes[dir][1]; + +		waterp->setPositionGlobal(water_pos); +		waterp->setScale(water_scale); + +		gObjectList.updateActive(waterp); +	} +} + + +void LLWorld::shiftRegions(const LLVector3& offset) +{ +	for (region_list_t::const_iterator i = getRegionList().begin(); i != getRegionList().end(); ++i) +	{ +		LLViewerRegion* region = *i; +		region->updateRenderMatrix(); +	} + +	LLViewerPartSim::getInstance()->shift(offset); +} + +LLViewerTexture* LLWorld::getDefaultWaterTexture() +{ +	return mDefaultWaterTexturep; +} + +void LLWorld::setSpaceTimeUSec(const U64 space_time_usec) +{ +	mSpaceTimeUSec = space_time_usec; +} + +U64 LLWorld::getSpaceTimeUSec() const +{ +	return mSpaceTimeUSec; +} + +void LLWorld::requestCacheMisses() +{ +	for (region_list_t::iterator iter = mRegionList.begin(); +		 iter != mRegionList.end(); ++iter) +	{ +		LLViewerRegion* regionp = *iter; +		regionp->requestCacheMisses(); +	} +} + +void LLWorld::getInfo(LLSD& info) +{ +	LLSD region_info; +	for (region_list_t::iterator iter = mRegionList.begin(); +		 iter != mRegionList.end(); ++iter) +	{	 +		LLViewerRegion* regionp = *iter; +		regionp->getInfo(region_info); +		info["World"].append(region_info); +	} +} + +void LLWorld::disconnectRegions() +{ +	LLMessageSystem* msg = gMessageSystem; +	for (region_list_t::iterator iter = mRegionList.begin(); +		 iter != mRegionList.end(); ++iter) +	{ +		LLViewerRegion* regionp = *iter; +		if (regionp == gAgent.getRegion()) +		{ +			// Skip the main agent +			continue; +		} + +		llinfos << "Sending AgentQuitCopy to: " << regionp->getHost() << llendl; +		msg->newMessageFast(_PREHASH_AgentQuitCopy); +		msg->nextBlockFast(_PREHASH_AgentData); +		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +		msg->nextBlockFast(_PREHASH_FuseBlock); +		msg->addU32Fast(_PREHASH_ViewerCircuitCode, gMessageSystem->mOurCircuitCode); +		msg->sendMessage(regionp->getHost()); +	} +} + +static LLFastTimer::DeclareTimer FTM_ENABLE_SIMULATOR("Enable Sim"); + +void process_enable_simulator(LLMessageSystem *msg, void **user_data) +{ +	LLFastTimer t(FTM_ENABLE_SIMULATOR); +	// enable the appropriate circuit for this simulator and  +	// add its values into the gSimulator structure +	U64		handle; +	U32		ip_u32; +	U16		port; + +	msg->getU64Fast(_PREHASH_SimulatorInfo, _PREHASH_Handle, handle); +	msg->getIPAddrFast(_PREHASH_SimulatorInfo, _PREHASH_IP, ip_u32); +	msg->getIPPortFast(_PREHASH_SimulatorInfo, _PREHASH_Port, port); + +	// which simulator should we modify? +	LLHost sim(ip_u32, port); + +	// Viewer trusts the simulator. +	msg->enableCircuit(sim, TRUE); +	LLWorld::getInstance()->addRegion(handle, sim); + +	// give the simulator a message it can use to get ip and port +	llinfos << "simulator_enable() Enabling " << sim << " with code " << msg->getOurCircuitCode() << llendl; +	msg->newMessageFast(_PREHASH_UseCircuitCode); +	msg->nextBlockFast(_PREHASH_CircuitCode); +	msg->addU32Fast(_PREHASH_Code, msg->getOurCircuitCode()); +	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +	msg->addUUIDFast(_PREHASH_ID, gAgent.getID()); +	msg->sendReliable(sim); +} + +class LLEstablishAgentCommunication : public LLHTTPNode +{ +	LOG_CLASS(LLEstablishAgentCommunication); +public: + 	virtual void describe(Description& desc) const +	{ +		desc.shortInfo("seed capability info for a region"); +		desc.postAPI(); +		desc.input( +			"{ seed-capability: ..., sim-ip: ..., sim-port }"); +		desc.source(__FILE__, __LINE__); +	} + +	virtual void post(ResponsePtr response, const LLSD& context, const LLSD& input) const +	{ +		if (!input["body"].has("agent-id") || +			!input["body"].has("sim-ip-and-port") || +			!input["body"].has("seed-capability")) +		{ +			llwarns << "invalid parameters" << llendl; +            return; +		} + +		LLHost sim(input["body"]["sim-ip-and-port"].asString()); +	 +		LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(sim); +		if (!regionp) +		{ +			llwarns << "Got EstablishAgentCommunication for unknown region " +					<< sim << llendl; +			return; +		} +		regionp->setSeedCapability(input["body"]["seed-capability"]); +	} +}; + +// disable the circuit to this simulator +// Called in response to "DisableSimulator" message. +void process_disable_simulator(LLMessageSystem *mesgsys, void **user_data) +{	 +	LLHost host = mesgsys->getSender(); + +	//llinfos << "Disabling simulator with message from " << host << llendl; +	LLWorld::getInstance()->removeRegion(host); + +	mesgsys->disableCircuit(host); +} + + +void process_region_handshake(LLMessageSystem* msg, void** user_data) +{ +	LLHost host = msg->getSender(); +	LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(host); +	if (!regionp) +	{ +		llwarns << "Got region handshake for unknown region " +			<< host << llendl; +		return; +	} + +	regionp->unpackRegionHandshake(); +} + + +void send_agent_pause() +{ +	// *NOTE:Mani Pausing the mainloop timeout. Otherwise a long modal event may cause +	// the thread monitor to timeout. +	LLAppViewer::instance()->pauseMainloopTimeout(); +	 +	// Note: used to check for LLWorld initialization before it became a singleton. +	// Rather than just remove this check I'm changing it to assure that the message  +	// system has been initialized. -MG +	if (!gMessageSystem) +	{ +		return; +	} +	 +	gMessageSystem->newMessageFast(_PREHASH_AgentPause); +	gMessageSystem->nextBlockFast(_PREHASH_AgentData); +	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID); +	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); + +	gAgentPauseSerialNum++; +	gMessageSystem->addU32Fast(_PREHASH_SerialNum, gAgentPauseSerialNum); + +	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); +		 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) +	{ +		LLViewerRegion* regionp = *iter; +		gMessageSystem->sendReliable(regionp->getHost()); +	} + +	gObjectList.mWasPaused = TRUE; +} + + +void send_agent_resume() +{ +	// Note: used to check for LLWorld initialization before it became a singleton. +	// Rather than just remove this check I'm changing it to assure that the message  +	// system has been initialized. -MG +	if (!gMessageSystem) +	{ +		return; +	} + +	gMessageSystem->newMessageFast(_PREHASH_AgentResume); +	gMessageSystem->nextBlockFast(_PREHASH_AgentData); +	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID); +	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); + +	gAgentPauseSerialNum++; +	gMessageSystem->addU32Fast(_PREHASH_SerialNum, gAgentPauseSerialNum); +	 + +	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); +		 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) +	{ +		LLViewerRegion* regionp = *iter; +		gMessageSystem->sendReliable(regionp->getHost()); +	} + +	// Reset the FPS counter to avoid an invalid fps +	LLViewerStats::getInstance()->mFPSStat.start(); + +	LLAppViewer::instance()->resumeMainloopTimeout(); +} + +static LLVector3d unpackLocalToGlobalPosition(U32 compact_local, const LLVector3d& region_origin) +{ +	LLVector3d pos_local; + +	pos_local.mdV[VZ] = (compact_local & 0xFFU) * 4; +	pos_local.mdV[VY] = (compact_local >> 8) & 0xFFU; +	pos_local.mdV[VX] = (compact_local >> 16) & 0xFFU; + +	return region_origin + pos_local; +} + +void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positions, const LLVector3d& relative_to, F32 radius) const +{ +	F32 radius_squared = radius * radius; +	 +	if(avatar_ids != NULL) +	{ +		avatar_ids->clear(); +	} +	if(positions != NULL) +	{ +		positions->clear(); +	} +	// get the list of avatars from the character list first, so distances are correct +	// when agent is above 1020m and other avatars are nearby +	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); +		iter != LLCharacter::sInstances.end(); ++iter) +	{ +		LLVOAvatar* pVOAvatar = (LLVOAvatar*) *iter; +		LLVector3d pos_global = pVOAvatar->getPositionGlobal(); +		LLUUID uuid = pVOAvatar->getID(); +		if( !pVOAvatar->isDead() +			&& !pVOAvatar->isSelf() +			&& !uuid.isNull() && +			dist_vec_squared(pos_global, relative_to) <= radius_squared) +		{ +			if(positions != NULL) +			{ +				positions->push_back(pos_global); +			} +			if(avatar_ids !=NULL) +			{ +				avatar_ids->push_back(uuid); +			} +		} +	} +	// region avatars added for situations where radius is greater than RenderFarClip +	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); +		iter != LLWorld::getInstance()->getRegionList().end(); ++iter) +	{ +		LLViewerRegion* regionp = *iter; +		const LLVector3d& origin_global = regionp->getOriginGlobal(); +		S32 count = regionp->mMapAvatars.count(); +		for (S32 i = 0; i < count; i++) +		{ +			LLVector3d pos_global = unpackLocalToGlobalPosition(regionp->mMapAvatars.get(i), origin_global); +			if(dist_vec_squared(pos_global, relative_to) <= radius_squared) +			{ +				LLUUID uuid = regionp->mMapAvatarIDs.get(i); +				// if this avatar doesn't already exist in the list, add it +				if(uuid.notNull() && avatar_ids != NULL && std::find(avatar_ids->begin(), avatar_ids->end(), uuid) == avatar_ids->end()) +				{ +					if (positions != NULL) +					{ +						positions->push_back(pos_global); +					} +					avatar_ids->push_back(uuid); +				} +			} +		} +	} +} + + +LLHTTPRegistration<LLEstablishAgentCommunication> +	gHTTPRegistrationEstablishAgentCommunication( +							"/message/EstablishAgentCommunication");  | 
