diff options
Diffstat (limited to 'indra')
34 files changed, 1563 insertions, 1022 deletions
| diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index c13860033e..20499d4ad3 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -97,6 +97,7 @@ const	U32		DEFAULT_USER_SERVER_PORT		= 12036;  const	U32		DEFAULT_RPC_SERVER_PORT			= 12037;  const	U32		DEFAULT_LOG_DATA_SERVER_PORT	= 12039;  const	U32		DEFAULT_BACKBONE_PORT			= 12040; +const	U32		DEFAULT_CGI_SERVICES_PORT		= 12045;  const   U32		DEFAULT_LOCAL_ASSET_PORT		= 12041;  //const   U32		DEFAULT_BACKBONE_CAP_PORT		= 12042; // Deprecated  const   U32		DEFAULT_CAP_PROXY_PORT			= 12043; diff --git a/indra/llcommon/llstreamtools.cpp b/indra/llcommon/llstreamtools.cpp index f9038afedc..a92f1c9388 100644 --- a/indra/llcommon/llstreamtools.cpp +++ b/indra/llcommon/llstreamtools.cpp @@ -534,7 +534,7 @@ std::istream& fullread(std::istream& str, char *buf, std::streamsize requested)  std::istream& operator>>(std::istream& str, const char *tocheck)  { -	char c; +	char c = '\0';  	const char *p;  	p = tocheck;  	while (*p && !str.bad()) diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp index 1f64c3bde3..a2c651b444 100644 --- a/indra/llcommon/lluri.cpp +++ b/indra/llcommon/lluri.cpp @@ -13,273 +13,86 @@  #include "llapp.h"  #include "lluri.h"  #include "llsd.h" - +#include <iomanip> +    #include "../llmath/lluuid.h" -// uric = reserved | unreserved | escaped -// reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," -// unreserved = alphanum | mark -// mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" -// escaped = "%" hex hex -static const char* ESCAPED_CHARACTERS[256] = + +// static +std::string LLURI::escape(const std::string& str, const std::string & allowed) +{ +	std::ostringstream ostr; + +	std::string::const_iterator it = str.begin(); +	std::string::const_iterator end = str.end(); +	for(; it != end; ++it) +	{ +		std::string::value_type c = *it; +		if(allowed.find(c) == std::string::npos) +		  { +		    ostr << "%" +			 << std::uppercase << std::hex << std::setw(2) << std::setfill('0') +			 << static_cast<U32>(c); +		  } +		else +		  { +		    ostr << c; +		  } +	} +	return ostr.str(); +} + +// static +std::string LLURI::unescape(const std::string& str) +{ +	std::ostringstream ostr; +	std::string::const_iterator it = str.begin(); +	std::string::const_iterator end = str.end(); +	for(; it != end; ++it) +	{ +		if((*it) == '%') +		{ +			++it; +			if(it == end) break; +			U8 c = hex_as_nybble(*it++); +			c = c << 4; +			if (it == end) break; +			c |= hex_as_nybble(*it); +			ostr.put((char)c); +		} +		else +		{ +			ostr.put(*it); +		} +	} +	return ostr.str(); +} + +namespace  { -	"%00",		// 0 -	"%01",		// 1 -	"%02",		// 2 -	"%03",		// 3 -	"%04",		// 4 -	"%05",		// 5 -	"%06",		// 6 -	"%07",		// 7 -	"%08",		// 8 -	"%09",		// 9 -	"%0a",		// 10 -	"%0b",		// 11 -	"%0c",		// 12 -	"%0d",		// 13 -	"%0e",		// 14 -	"%0f",		// 15 -	"%10",		// 16 -	"%11",		// 17 -	"%12",		// 18 -	"%13",		// 19 -	"%14",		// 20 -	"%15",		// 21 -	"%16",		// 22 -	"%17",		// 23 -	"%18",		// 24 -	"%19",		// 25 -	"%1a",		// 26 -	"%1b",		// 27 -	"%1c",		// 28 -	"%1d",		// 29 -	"%1e",		// 30 -	"%1f",		// 31 -	"%20",		// 32 -	"!",		// 33 -	"%22",		// 34 -	"%23",		// 35 -	"$",		// 36 -	"%25",		// 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 -	"%3c",		// 60 -	"=",		// 61 -	"%3e",		// 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 -	"%5b",		// 91 -	"%5c",		// 92 -	"%5d",		// 93 -	"%5e",		// 94 -	"_",		// 95 -	"%60",		// 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 -	"%7b",		// 123 -	"%7c",		// 124 -	"%7d",		// 125 -	"~",		// 126 -	"%7f",		// 127 -	"%80",		// 128 -	"%81",		// 129 -	"%82",		// 130 -	"%83",		// 131 -	"%84",		// 132 -	"%85",		// 133 -	"%86",		// 134 -	"%87",		// 135 -	"%88",		// 136 -	"%89",		// 137 -	"%8a",		// 138 -	"%8b",		// 139 -	"%8c",		// 140 -	"%8d",		// 141 -	"%8e",		// 142 -	"%8f",		// 143 -	"%90",		// 144 -	"%91",		// 145 -	"%92",		// 146 -	"%93",		// 147 -	"%94",		// 148 -	"%95",		// 149 -	"%96",		// 150 -	"%97",		// 151 -	"%98",		// 152 -	"%99",		// 153 -	"%9a",		// 154 -	"%9b",		// 155 -	"%9c",		// 156 -	"%9d",		// 157 -	"%9e",		// 158 -	"%9f",		// 159 -	"%a0",		// 160 -	"%a1",		// 161 -	"%a2",		// 162 -	"%a3",		// 163 -	"%a4",		// 164 -	"%a5",		// 165 -	"%a6",		// 166 -	"%a7",		// 167 -	"%a8",		// 168 -	"%a9",		// 169 -	"%aa",		// 170 -	"%ab",		// 171 -	"%ac",		// 172 -	"%ad",		// 173 -	"%ae",		// 174 -	"%af",		// 175 -	"%b0",		// 176 -	"%b1",		// 177 -	"%b2",		// 178 -	"%b3",		// 179 -	"%b4",		// 180 -	"%b5",		// 181 -	"%b6",		// 182 -	"%b7",		// 183 -	"%b8",		// 184 -	"%b9",		// 185 -	"%ba",		// 186 -	"%bb",		// 187 -	"%bc",		// 188 -	"%bd",		// 189 -	"%be",		// 190 -	"%bf",		// 191 -	"%c0",		// 192 -	"%c1",		// 193 -	"%c2",		// 194 -	"%c3",		// 195 -	"%c4",		// 196 -	"%c5",		// 197 -	"%c6",		// 198 -	"%c7",		// 199 -	"%c8",		// 200 -	"%c9",		// 201 -	"%ca",		// 202 -	"%cb",		// 203 -	"%cc",		// 204 -	"%cd",		// 205 -	"%ce",		// 206 -	"%cf",		// 207 -	"%d0",		// 208 -	"%d1",		// 209 -	"%d2",		// 210 -	"%d3",		// 211 -	"%d4",		// 212 -	"%d5",		// 213 -	"%d6",		// 214 -	"%d7",		// 215 -	"%d8",		// 216 -	"%d9",		// 217 -	"%da",		// 218 -	"%db",		// 219 -	"%dc",		// 220 -	"%dd",		// 221 -	"%de",		// 222 -	"%df",		// 223 -	"%e0",		// 224 -	"%e1",		// 225 -	"%e2",		// 226 -	"%e3",		// 227 -	"%e4",		// 228 -	"%e5",		// 229 -	"%e6",		// 230 -	"%e7",		// 231 -	"%e8",		// 232 -	"%e9",		// 233 -	"%ea",		// 234 -	"%eb",		// 235 -	"%ec",		// 236 -	"%ed",		// 237 -	"%ee",		// 238 -	"%ef",		// 239 -	"%f0",		// 240 -	"%f1",		// 241 -	"%f2",		// 242 -	"%f3",		// 243 -	"%f4",		// 244 -	"%f5",		// 245 -	"%f6",		// 246 -	"%f7",		// 247 -	"%f8",		// 248 -	"%f9",		// 249 -	"%fa",		// 250 -	"%fb",		// 251 -	"%fc",		// 252 -	"%fd",		// 253 -	"%fe",		// 254 -	"%ff"		// 255 -}; +	const std::string unreserved() +	{ +		static const std::string s =    +			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" +			"0123456789" +			"-._~"; +		return s; +	} +	const std::string sub_delims() +	{ +		static const std::string s = "!$&'()*+,;="; +		return s; +	} + +	std::string escapeHostAndPort(const std::string& s) +		{ return LLURI::escape(s, unreserved() + sub_delims() +":"); } +	std::string escapePathComponent(const std::string& s) +		{ return LLURI::escape(s, unreserved() + sub_delims() + ":@"); } +	std::string escapeQueryVariable(const std::string& s) +		{ return LLURI::escape(s, unreserved() + ":@!$'()*+,"); }	 // sub_delims - "&;=" + ":@" +	std::string escapeQueryValue(const std::string& s) +		{ return LLURI::escape(s, unreserved() + ":@!$'()*+,="); }	// sub_delims - "&;" + ":@" +}  LLURI::LLURI()  { @@ -352,23 +165,23 @@ LLURI::~LLURI()  {  } - -LLURI LLURI::buildHTTP(const std::string& host_port, +// static +LLURI LLURI::buildHTTP(const std::string& prefix,  					   const LLSD& path)  {  	LLURI result;  	// TODO: deal with '/' '?' '#' in host_port -	if (host_port.find("://") != host_port.npos) +	if (prefix.find("://") != prefix.npos)  	{ -		// The scheme is part of the host_port -		result.mScheme = ""; -		result.mEscapedAuthority = escape(host_port); +		// it is a prefix +		result = LLURI(prefix);  	}  	else  	{ -		result.mScheme = "HTTP"; -		result.mEscapedAuthority = "//" + escape(host_port); +		// it is just a host and optional port +		result.mScheme = "http"; +		result.mEscapedAuthority = escapeHostAndPort(prefix);  	}  	if (path.isArray()) @@ -379,20 +192,20 @@ LLURI LLURI::buildHTTP(const std::string& host_port,  			 ++it)  		{  			lldebugs << "PATH: inserting " << it->asString() << llendl; -			result.mEscapedPath += "/" + escape(it->asString()); +			result.mEscapedPath += "/" + escapePathComponent(it->asString());  		}  	} -	result.mEscapedOpaque = result.mEscapedAuthority + +	result.mEscapedOpaque = "//" + result.mEscapedAuthority +  		result.mEscapedPath;  	return result;  }  // static -LLURI LLURI::buildHTTP(const std::string& host_port, +LLURI LLURI::buildHTTP(const std::string& prefix,  					   const LLSD& path,  					   const LLSD& query)  { -	LLURI result = buildHTTP(host_port, path); +	LLURI result = buildHTTP(prefix, path);  	// break out and escape each query component  	if (query.isMap())  	{ @@ -400,8 +213,8 @@ LLURI LLURI::buildHTTP(const std::string& host_port,  			 it != query.endMap();  			 it++)  		{ -			result.mEscapedQuery += escape(it->first) + -				(it->second.isUndefined() ? "" : "=" + it->second.asString()) + +			result.mEscapedQuery += escapeQueryVariable(it->first) + +				(it->second.isUndefined() ? "" : "=" + escapeQueryValue(it->second.asString())) +  				"&";  		}  		if (query.size() > 0) @@ -413,56 +226,62 @@ LLURI LLURI::buildHTTP(const std::string& host_port,  }  // static -LLURI LLURI::buildAgentPresenceURI(const LLUUID& agent_id, LLApp* app) +LLURI LLURI::buildHTTP(const std::string& host, +					   const U32& port, +					   const LLSD& path)  { -	std::string host = "localhost:12040"; +	return LLURI::buildHTTP(llformat("%s:%u", host.c_str(), port), path); +} -	if (app) +// static +LLURI LLURI::buildHTTP(const std::string& host, +					   const U32& port, +					   const LLSD& path, +					   const LLSD& query) +{ +	return LLURI::buildHTTP(llformat("%s:%u", host.c_str(), port), path, query); +} + + +namespace { +	LLURI buildBackboneURL(LLApp* app, +				const std::string& p1 = "", +				const std::string& p2 = "", +				const std::string& p3 = "")  	{ -		host = app->getOption("backbone-host-port").asString(); +		std::string host = "localhost:12040"; + +		if (app) +		{ +			host = app->getOption("backbone-host-port").asString(); +		} + +		LLSD path = LLSD::emptyArray(); +		if (!p1.empty())	path.append(p1); +		if (!p2.empty())	path.append(p2); +		if (!p3.empty())	path.append(p3); + +		return LLURI::buildHTTP(host, path);  	} +} -	LLSD path = LLSD::emptyArray(); -	path.append("agent"); -	path.append(agent_id); -	path.append("presence"); -	return buildHTTP(host, path); +// static +LLURI LLURI::buildAgentPresenceURI(const LLUUID& agent_id, LLApp* app) +{ +	return buildBackboneURL(app, "agent", agent_id.asString(), "presence");  }  // static  LLURI LLURI::buildBulkAgentPresenceURI(LLApp* app)  { -	std::string host = "localhost:12040"; - -	if (app) -	{ -		host = app->getOption("backbone-host-port").asString(); -	} - -	LLSD path = LLSD::emptyArray(); -	path.append("agent"); -	path.append("presence"); - -	return buildHTTP(host, path); +	return buildBackboneURL(app, "agent", "presence");  }  // static  LLURI LLURI::buildAgentSessionURI(const LLUUID& agent_id, LLApp* app)  { -	std::string host = "localhost:12040"; - -	if (app) -	{ -		host = app->getOption("backbone-host-port").asString(); -	} - -	LLSD path = LLSD::emptyArray(); -	path.append("agent"); -	path.append(agent_id); -	path.append("session"); - -	return buildHTTP(host, path); +	return buildBackboneURL(app, "agent", agent_id.asString(), "session");  }  // static @@ -635,43 +454,3 @@ LLSD LLURI::queryMap(std::string escaped_query_string)  	return result;  } -// static -std::string LLURI::escape(const std::string& str) -{ -	std::ostringstream ostr; -	std::string::const_iterator it = str.begin(); -	std::string::const_iterator end = str.end(); -	S32 c; -	for(; it != end; ++it) -	{ -		c = (S32)(*it); -		ostr << ESCAPED_CHARACTERS[c]; -	} -	return ostr.str(); -} - -// static -std::string LLURI::unescape(const std::string& str) -{ -	std::ostringstream ostr; -	std::string::const_iterator it = str.begin(); -	std::string::const_iterator end = str.end(); -	for(; it != end; ++it) -	{ -		if((*it) == '%') -		{ -			++it; -			if(it == end) break; -			U8 c = hex_as_nybble(*it++); -			c = c << 4; -			if (it == end) break; -			c |= hex_as_nybble(*it); -			ostr.put((char)c); -		} -		else -		{ -			ostr.put(*it); -		} -	} -	return ostr.str(); -} diff --git a/indra/llcommon/lluri.h b/indra/llcommon/lluri.h index 514628237d..b5c3a84173 100644 --- a/indra/llcommon/lluri.h +++ b/indra/llcommon/lluri.h @@ -26,42 +26,55 @@ class LLApp;  class LLURI  {  public: -	LLURI(); -	LLURI(const std::string& escaped_str); -		// construct from escaped string, as would be transmitted on the net +  LLURI(); +  LLURI(const std::string& escaped_str); +  // construct from escaped string, as would be transmitted on the net -	~LLURI(); +  ~LLURI(); -	static LLURI buildHTTP(const std::string& host_port, -						   const LLSD& path); -	static LLURI buildHTTP(const std::string& host_port, -						   const LLSD& path, -						   const LLSD& query); -	 -	std::string asString() const; -		// the whole URI, escaped as needed - -	// Parts of a URI -	// These functions return parts of the decoded URI.  The returned -	// strings are un-escaped as needed -	 -	// for all schemes -	std::string scheme() const;		// ex.: "http", note lack of colon -	std::string opaque() const;		// everything after the colon +  static LLURI buildHTTP(const std::string& prefix, +			 const LLSD& path); +  static LLURI buildHTTP(const std::string& prefix, +			 const LLSD& path, +			 const LLSD& query); +	// prefix is either a full URL prefix of the form "http://example.com:8080", +	// or it can be simply a host and optional port like "example.com" or  +	// "example.com:8080", in these cases, the "http://" will be added -	// for schemes that follow path like syntax (http, https, ftp) -	std::string authority() const;	// ex.: "bob@host.com:80" -	std::string hostName() const;	// ex.: "host.com" -	U16 hostPort() const;			// ex.: 80, will include implicit port -	std::string path() const;		// ex.: "/abc/def", includes leading slash -//    LLSD pathArray() const;			// above decoded into an array of strings -	std::string query() const;		// ex.: "x=34", section after "?" -    LLSD queryMap() const;			// above decoded into a map -    static LLSD queryMap(std::string escaped_query_string); +  static LLURI buildHTTP(const std::string& host, +			 const U32& port, +			 const LLSD& path); +  static LLURI buildHTTP(const std::string& host, +			 const U32& port, +			 const LLSD& path, +			 const LLSD& query); +			  +	   +  std::string asString() const; +  // the whole URI, escaped as needed +   +  // Parts of a URI +  // These functions return parts of the decoded URI.  The returned +  // strings are un-escaped as needed +   +  // for all schemes +  std::string scheme() const;		// ex.: "http", note lack of colon +  std::string opaque() const;		// everything after the colon +   +  // for schemes that follow path like syntax (http, https, ftp) +  std::string authority() const;	// ex.: "host.com:80" +  std::string hostName() const;	// ex.: "host.com" +  U16 hostPort() const;			// ex.: 80, will include implicit port +  std::string path() const;		// ex.: "/abc/def", includes leading slash +  //    LLSD pathArray() const;			// above decoded into an array of strings +  std::string query() const;		// ex.: "x=34", section after "?" +  LLSD queryMap() const;			// above decoded into a map +  static LLSD queryMap(std::string escaped_query_string); -	// Escaping Utilities -	static std::string escape(const std::string& str); -	static std::string unescape(const std::string& str); +  // Escaping Utilities +  // Escape a string by urlencoding all the characters that aren't in the allowed string. +  static std::string escape(const std::string& str, const std::string & allowed);  +  static std::string unescape(const std::string& str);  	// Functions for building specific URIs for web services  	static LLURI buildAgentPresenceURI(const LLUUID& agent_id, LLApp* app); @@ -71,11 +84,11 @@ public:  	static LLURI buildInventoryHostURI(const LLUUID& agent_id, LLApp* app);  private: -	std::string mScheme; -	std::string mEscapedOpaque; -	std::string mEscapedAuthority; -	std::string mEscapedPath; -	std::string mEscapedQuery; +  std::string mScheme; +  std::string mEscapedOpaque; +  std::string mEscapedAuthority; +  std::string mEscapedPath; +  std::string mEscapedQuery;  };  #endif // LL_LLURI_H diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index 0bc3f19cdf..c392d23d22 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -23,6 +23,24 @@  #include "llsdutil.h"  ///---------------------------------------------------------------------------- +/// exported functions +///---------------------------------------------------------------------------- + +static const std::string INV_ITEM_ID_LABEL("item_id"); +static const std::string INV_FOLDER_ID_LABEL("folder_id"); +static const std::string INV_PARENT_ID_LABEL("parent_id"); +static const std::string INV_ASSET_TYPE_LABEL("type"); +static const std::string INV_PREFERRED_TYPE_LABEL("preferred_type"); +static const std::string INV_INVENTORY_TYPE_LABEL("inv_type"); +static const std::string INV_NAME_LABEL("name"); +static const std::string INV_DESC_LABEL("desc"); +static const std::string INV_PERMISSIONS_LABEL("permissions"); +static const std::string INV_ASSET_ID_LABEL("asset_id"); +static const std::string INV_SALE_INFO_LABEL("sale_info"); +static const std::string INV_FLAGS_LABEL("flags"); +static const std::string INV_CREATION_DATE_LABEL("created_at"); + +///----------------------------------------------------------------------------  /// Local function declarations, constants, enums, and typedefs  ///---------------------------------------------------------------------------- @@ -1113,24 +1131,24 @@ bool LLInventoryItem::fromLLSD(LLSD& sd)  {  	mInventoryType = LLInventoryType::IT_NONE;  	mAssetUUID.setNull(); -	const char *w; +	std::string w; -	w = "item_id"; +	w = INV_ITEM_ID_LABEL;  	if (sd.has(w))  	{  		mUUID = sd[w];  	} -	w = "parent_id"; +	w = INV_PARENT_ID_LABEL;  	if (sd.has(w))  	{  		mParentUUID = sd[w];  	} -	w = "permissions"; +	w = INV_PERMISSIONS_LABEL;  	if (sd.has(w))  	{  		mPermissions = ll_permissions_from_sd(sd[w]);  	} -	w = "sale_info"; +	w = INV_SALE_INFO_LABEL;  	if (sd.has(w))  	{  		// Sale info used to contain next owner perm. It is now in @@ -1164,40 +1182,40 @@ bool LLInventoryItem::fromLLSD(LLSD& sd)  		LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);  		cipher.decrypt(mAssetUUID.mData, UUID_BYTES);  	} -	w = "asset_id"; +	w = INV_ASSET_ID_LABEL;  	if (sd.has(w))  	{  		mAssetUUID = sd[w];  	} -	w = "type"; +	w = INV_ASSET_TYPE_LABEL;  	if (sd.has(w))  	{  		mType = LLAssetType::lookup(sd[w].asString().c_str());  	} -	w = "inv_type"; +	w = INV_INVENTORY_TYPE_LABEL;  	if (sd.has(w))  	{  		mInventoryType = LLInventoryType::lookup(sd[w].asString().c_str());  	} -	w = "flags"; +	w = INV_FLAGS_LABEL;  	if (sd.has(w))  	{  		mFlags = ll_U32_from_sd(sd[w]);  	} -	w = "name"; +	w = INV_NAME_LABEL;  	if (sd.has(w))  	{  		mName = sd[w].asString();  		LLString::replaceNonstandardASCII(mName, ' ');  		LLString::replaceChar(mName, '|', ' ');  	} -	w = "desc"; +	w = INV_DESC_LABEL;  	if (sd.has(w))  	{  		mDescription = sd[w].asString();  		LLString::replaceNonstandardASCII(mDescription, ' ');  	} -	w = "creation_date"; +	w = INV_CREATION_DATE_LABEL;  	if (sd.has(w))  	{  		mCreationDate = sd[w]; @@ -1720,24 +1738,6 @@ bool inventory_and_asset_types_match(  	return rv;  } -///---------------------------------------------------------------------------- -/// exported functions -///---------------------------------------------------------------------------- - -static const std::string INV_ITEM_ID_LABEL("item_id"); -static const std::string INV_FOLDER_ID_LABEL("folder_id"); -static const std::string INV_PARENT_ID_LABEL("parent_id"); -static const std::string INV_ASSET_TYPE_LABEL("type"); -static const std::string INV_PREFERRED_TYPE_LABEL("preferred_type"); -static const std::string INV_INVENTORY_TYPE_LABEL("inv_type"); -static const std::string INV_NAME_LABEL("name"); -static const std::string INV_DESC_LABEL("desc"); -static const std::string INV_PERMISSIONS_LABEL("permissions"); -static const std::string INV_ASSET_ID_LABEL("asset_id"); -static const std::string INV_SALE_INFO_LABEL("sale_info"); -static const std::string INV_FLAGS_LABEL("flags"); -static const std::string INV_CREATION_DATE_LABEL("created_at"); -  LLSD ll_create_sd_from_inventory_item(LLPointer<LLInventoryItem> item)  {  	LLSD rv; diff --git a/indra/llinventory/llnotecard.cpp b/indra/llinventory/llnotecard.cpp index 79545874b4..96ee7ff800 100644 --- a/indra/llinventory/llnotecard.cpp +++ b/indra/llinventory/llnotecard.cpp @@ -7,11 +7,10 @@   */  #include "linden_common.h" -#include "llinventory.h"  #include "llnotecard.h"  #include "llstreamtools.h" -LLNotecard::LLNotecard(U32 max_text) +LLNotecard::LLNotecard(S32 max_text)  : mMaxText(max_text)  {  } @@ -179,7 +178,7 @@ bool LLNotecard::importStream(std::istream& str)  	}  	line_buf[STD_STRING_STR_LEN] = '\0'; -	U32 text_len = 0; +	S32 text_len = 0;  	if( 1 != sscanf(line_buf, "Text length %d", &text_len) )  	{  		llwarns << "Invalid Linden text length field" << llendl; diff --git a/indra/llinventory/llnotecard.h b/indra/llinventory/llnotecard.h index 5f510a674f..04fe666562 100644 --- a/indra/llinventory/llnotecard.h +++ b/indra/llinventory/llnotecard.h @@ -9,12 +9,21 @@  #ifndef LL_NOTECARD_H  #define LL_NOTECARD_H -const S32 MAX_NOTECARD_SIZE = 65536; +#include "llmemory.h" +#include "llinventory.h"  class LLNotecard  {  public: -	LLNotecard(U32 max_text); +	/** +	 * @brief anonymous enumeration to set max size. +	 */ +	enum +	{ +		MAX_SIZE = 65536 +	}; +	 +	LLNotecard(S32 max_text = LLNotecard::MAX_SIZE);  	virtual ~LLNotecard();  	bool importStream(std::istream& str); @@ -33,7 +42,7 @@ private:  	bool exportEmbeddedItemsStream(std::ostream& str);  	std::vector<LLPointer<LLInventoryItem> > mItems;  	LLString mText; -	U32 mMaxText; +	S32 mMaxText;  	S32 mVersion;  	S32 mEmbeddedVersion;  }; diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index d83308d082..f93a12b274 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -131,6 +131,27 @@ namespace  		const LLSD mSD;  	}; + +	class RawInjector : public Injector +	{ +	public: +		RawInjector(const U8* data, S32 size) : mData(data), mSize(size) {} +		virtual ~RawInjector() {} + +		const char* contentType() { return "application/octet-stream"; } + +		virtual EStatus process_impl(const LLChannelDescriptors& channels, +			buffer_ptr_t& buffer, bool& eos, LLSD& context, LLPumpIO* pump) +		{ +			LLBufferStream ostream(channels, buffer.get()); +			ostream.write((const char *)mData, mSize);  // hopefully chars are always U8s +			eos = true; +			return STATUS_DONE; +		} + +		const U8* mData; +		S32 mSize; +	};  	class FileInjector : public Injector  	{ @@ -301,6 +322,11 @@ void LLHTTPClient::post(const std::string& url, const LLSD& body, ResponderPtr r  	request(url, LLURLRequest::HTTP_POST, new LLSDInjector(body), responder);  } +void LLHTTPClient::post(const std::string& url, const U8* data, S32 size, ResponderPtr responder) +{ +	request(url, LLURLRequest::HTTP_POST, new RawInjector(data, size), responder); +} +  void LLHTTPClient::del(const std::string& url, ResponderPtr responder)  {  	request(url, LLURLRequest::HTTP_DELETE, NULL, responder); diff --git a/indra/llmessage/llhttpclient.h b/indra/llmessage/llhttpclient.h index d64662e41d..a8afea312d 100644 --- a/indra/llmessage/llhttpclient.h +++ b/indra/llmessage/llhttpclient.h @@ -54,6 +54,7 @@ public:  	static void put(const std::string& url, const LLSD& body, ResponderPtr);  		///< non-blocking  	static void post(const std::string& url, const LLSD& body, ResponderPtr); +	static void post(const std::string& url, const U8* data, S32 size, ResponderPtr responder);  	static void postFile(const std::string& url, const std::string& filename, ResponderPtr);  	static void postFile(const std::string& url, const LLUUID& uuid,  		LLAssetType::EType asset_type, ResponderPtr responder); diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings index 66ce415541..f49ffa1603 100644 --- a/indra/newview/English.lproj/InfoPlist.strings +++ b/indra/newview/English.lproj/InfoPlist.strings @@ -1,5 +1,5 @@  /* Localized versions of Info.plist keys */  CFBundleName = "Second Life"; -CFBundleShortVersionString = "Second Life version 1.13.3.3"; -CFBundleGetInfoString = "Second Life version 1.13.3.3, Copyright 2004-2006 Linden Research, Inc."; +CFBundleShortVersionString = "Second Life version 1.13.4.8"; +CFBundleGetInfoString = "Second Life version 1.13.4.8, Copyright 2004-2007 Linden Research, Inc."; diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist index 13901656b5..448c7922ff 100644 --- a/indra/newview/Info-SecondLife.plist +++ b/indra/newview/Info-SecondLife.plist @@ -32,7 +32,7 @@  		</dict>  	</array>  	<key>CFBundleVersion</key> -	<string>1.13.3.3</string> +	<string>1.13.4.8</string>  	<key>CSResourcesFileMapped</key>  	<true/>  </dict> diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index b37538f023..7c615dd159 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -1,10 +1,6 @@ -/**  - * @file llmapresponders.h - * @brief Processes responses received for asset upload requests. - * - * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc. - * $License$ - */ +// llassetuploadresponders.cpp +// Copyright 2006, Linden Research, Inc. +// Processes responses received for asset upload requests.  #include "llviewerprecompiledheaders.h" @@ -19,39 +15,71 @@  #include "llinventorymodel.h"  #include "llinventoryview.h"  #include "llpermissionsflags.h" +#include "llpreviewnotecard.h" +#include "llpreviewscript.h" +#include "llscrolllistctrl.h"  #include "lluploaddialog.h" -#include "llviewermenu.h"	// for upload_new_resource() +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "llviewermenu.h"  #include "llviewerwindow.h"  #include "viewer.h" -LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLUUID& uuid, -														   const LLSD &post_data) -	: LLHTTPClient::Responder() +void dialog_refresh_all(); + +LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data, +											   const LLUUID& vfile_id, +											   LLAssetType::EType asset_type) +	: LLHTTPClient::Responder(), +	  mPostData(post_data), +	  mVFileID(vfile_id), +	  mAssetType(asset_type) +{ +	if (!gVFS->getExists(vfile_id, asset_type)) +	{ +		llwarns << "LLAssetUploadResponder called with nonexistant vfile_id" << llendl; +		mVFileID.setNull(); +		mAssetType = LLAssetType::AT_NONE; +		return; +	} +} + +LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data, +											   const std::string& file_name) +	: LLHTTPClient::Responder(), +	  mPostData(post_data), +	  mFileName(file_name) +{ +} + +LLAssetUploadResponder::~LLAssetUploadResponder()  { -	mUUID = uuid; -	mPostData = post_data; +	if (!mFileName.empty()) +	{ +		// Delete temp file +		LLFile::remove(mFileName.c_str()); +	}  }  // virtual -void LLNewAgentInventoryResponder::error(U32 statusNum, const std::string& reason) +void LLAssetUploadResponder::error(U32 statusNum, const std::string& reason)  { -	llinfos << "LLNewAgentInventoryResponder::error " << statusNum << llendl; +	llinfos << "LLAssetUploadResponder::error " << statusNum  +			<< " reason: " << reason << llendl;  	LLStringBase<char>::format_map_t args;  	switch(statusNum)  	{  		case 400: -			args["[FILE]"] = mPostData["inventory_type"].asString(); -			args["[REASON]"] = "invalid parameters in upload request"; +			args["[FILE]"] = (mFileName.empty() ? mVFileID.asString() : mFileName); +			args["[REASON]"] = "Error in upload request.  Please contact " +				"support@lindenlab.com for help fixing this problem.";  			gViewerWindow->alertXml("CannotUploadReason", args);  			break; -		case 402: -			//(result["message"].asString() == "insufficient funds") -			LLFloaterBuyCurrency::buyCurrency("Uploading costs", gGlobalEconomy->getPriceUpload()); -			break;  		case 500:  		default: -			args["[FILE]"] = mPostData["inventory_type"].asString(); -			args["[REASON]"] = "the server is experiencing unexpected difficulties"; +			args["[FILE]"] = (mFileName.empty() ? mVFileID.asString() : mFileName); +			args["[REASON]"] = "The server is experiencing unexpected " +				"difficulties. Please try again later.";  			gViewerWindow->alertXml("CannotUploadReason", args);  			break;  	} @@ -59,139 +87,373 @@ void LLNewAgentInventoryResponder::error(U32 statusNum, const std::string& reaso  }  //virtual  -void LLNewAgentInventoryResponder::result(const LLSD& result) +void LLAssetUploadResponder::result(const LLSD& content)  { -	lldebugs << "LLNewAgentInventoryResponder::result from capabilities" << llendl; +	lldebugs << "LLAssetUploadResponder::result from capabilities" << llendl; -	if (!result["success"]) +	std::string state = content["state"]; +	if (state == "upload") +	{ +		uploadUpload(content); +	} +	else if (state == "complete") +	{ +		// rename file in VFS with new asset id +		if (mFileName.empty()) +		{ +			// rename the file in the VFS to the actual asset id +			gVFS->renameFile(mVFileID, mAssetType, content["new_asset"].asUUID(), mAssetType); +		} +		uploadComplete(content); +	} +	else +	{ +		uploadFailure(content); +	} +} + +void LLAssetUploadResponder::uploadUpload(const LLSD& content) +{ +	std::string uploader = content["uploader"]; +	if (mFileName.empty()) +	{ +		LLHTTPClient::postFile(uploader, mVFileID, mAssetType, this); +	} +	else +	{ +		LLHTTPClient::postFile(uploader, mFileName, this); +	}
 +} + +void LLAssetUploadResponder::uploadFailure(const LLSD& content) +{ +	std::string reason = content["state"]; +	// deal with money errors +	if (reason == "insufficient funds") +	{ +		LLFloaterBuyCurrency::buyCurrency("Uploading costs", gGlobalEconomy->getPriceUpload()); +	} +	else  	{  		LLStringBase<char>::format_map_t args; -		args["[FILE]"] = mPostData["inventory_type"].asString(); -		args["[REASON]"] = "the server is experiencing unexpected difficulties"; +		args["[FILE]"] = (mFileName.empty() ? mVFileID.asString() : mFileName); +		args["[REASON]"] = content["message"].asString();  		gViewerWindow->alertXml("CannotUploadReason", args); -		return;  	} +} + +void LLAssetUploadResponder::uploadComplete(const LLSD& content) +{ +} + +LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data, +														   const LLUUID& vfile_id, +														   LLAssetType::EType asset_type) +: LLAssetUploadResponder(post_data, vfile_id, asset_type) +{ +} + +LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data, const std::string& file_name) +: LLAssetUploadResponder(post_data, file_name) +{ +} + +//virtual  +void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) +{ +	lldebugs << "LLNewAgentInventoryResponder::result from capabilities" << llendl; -	std::string uploader = result["uploader"];  	LLAssetType::EType asset_type = LLAssetType::lookup(mPostData["asset_type"].asString().c_str());  	LLInventoryType::EType inventory_type = LLInventoryType::lookup(mPostData["inventory_type"].asString().c_str()); -	// request succeeded -	if (!uploader.empty()) + +	// Update money and ownership credit information +	// since it probably changed on the server +	if (asset_type == LLAssetType::AT_TEXTURE || +		asset_type == LLAssetType::AT_SOUND || +		asset_type == LLAssetType::AT_ANIMATION)  	{ -		LLHTTPClient::postFile(uploader, mUUID, asset_type, this); +		gMessageSystem->newMessageFast(_PREHASH_MoneyBalanceRequest); +		gMessageSystem->nextBlockFast(_PREHASH_AgentData); +		gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +		gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +		gMessageSystem->nextBlockFast(_PREHASH_MoneyData); +		gMessageSystem->addUUIDFast(_PREHASH_TransactionID, LLUUID::null ); +		gAgent.sendReliableMessage(); + +		LLString::format_map_t args; +		args["[AMOUNT]"] = llformat("%d",gGlobalEconomy->getPriceUpload()); +		LLNotifyBox::showXml("UploadPayment", args);  	} -	// upload succeeded -	else -	{ -		// rename the file in the VFS to the actual asset id -		gVFS->renameFile(mUUID, asset_type, result["new_asset"].asUUID(), asset_type); -		// TODO: only request for textures, sound, and animation uploads -		// Update money and ownership credit information -		// since it probably changed on the server -		if (mPostData["asset_type"].asString() == "texture" ||  -			mPostData["asset_type"].asString() == "sound" || -			mPostData["asset_type"].asString() == "animatn") +	// Actually add the upload to viewer inventory +	llinfos << "Adding " << content["new_inventory_item"].asUUID() << " " +			<< content["new_asset"].asUUID() << " to inventory." << llendl; +	if(mPostData["folder_id"].asUUID().notNull()) +	{ +		LLPermissions perm; +		U32 next_owner_perm; +		perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); +		if (mPostData["inventory_type"].asString() == "snapshot")  		{ -			gMessageSystem->newMessageFast(_PREHASH_MoneyBalanceRequest); -			gMessageSystem->nextBlockFast(_PREHASH_AgentData); -			gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -			gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -			gMessageSystem->nextBlockFast(_PREHASH_MoneyData); -			gMessageSystem->addUUIDFast(_PREHASH_TransactionID, LLUUID::null ); -			gAgent.sendReliableMessage(); - -			LLString::format_map_t args; -			args["[AMOUNT]"] = llformat("%d",gGlobalEconomy->getPriceUpload()); -			LLNotifyBox::showXml("UploadPayment", args); +			next_owner_perm = PERM_ALL;  		} -		// Actually add the upload to viewer inventory -		llinfos << "Adding " << result["new_inventory_item"].asUUID() << " " -				<< result["new_asset"].asUUID() << " to inventory." << llendl; -		if(mPostData["folder_id"].asUUID().notNull()) +		else  		{ -			LLPermissions perm; -			U32 next_owner_perm; -			perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); -			if (mPostData["inventory_type"].asString() == "snapshot") +			next_owner_perm = PERM_MOVE | PERM_TRANSFER; +		} +		perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, next_owner_perm); +		S32 creation_date_now = time_corrected(); +		LLPointer<LLViewerInventoryItem> item +			= new LLViewerInventoryItem(content["new_inventory_item"].asUUID(), +										mPostData["folder_id"].asUUID(), +										perm, +										content["new_asset"].asUUID(), +										asset_type, +										inventory_type, +										mPostData["name"].asString(), +										mPostData["description"].asString(), +										LLSaleInfo::DEFAULT, +										LLInventoryItem::II_FLAGS_NONE, +										creation_date_now); +		gInventory.updateItem(item); +		gInventory.notifyObservers(); + +		// Show the preview panel for textures and sounds to let +		// user know that the image (or snapshot) arrived intact. +		LLInventoryView* view = LLInventoryView::getActiveInventory(); +		if(view) +		{ +			LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); +			LLFocusMgr::FocusLostCallback callback = gFocusMgr.getFocusCallback(); + +			view->getPanel()->setSelection(content["new_inventory_item"].asUUID(), TAKE_FOCUS_NO); +			if((LLAssetType::AT_TEXTURE == asset_type) +				|| (LLAssetType::AT_SOUND == asset_type))  			{ -				next_owner_perm = PERM_ALL; +				view->getPanel()->openSelected();  			} -			else +			//LLInventoryView::dumpSelectionInformation((void*)view); +			// restore keyboard focus +			gFocusMgr.setKeyboardFocus(focus_ctrl, callback); +		} +	} +	else +	{ +		llwarns << "Can't find a folder to put it in" << llendl; +	} + +	// remove the "Uploading..." message +	LLUploadDialog::modalUploadFinished(); +	 +	// *FIX: This is a pretty big hack. What this does is check the +	// file picker if there are any more pending uploads. If so, +	// upload that file. +	const char* next_file = LLFilePicker::instance().getNextFile(); +	if(next_file) +	{ +		const char* name = LLFilePicker::instance().getDirname(); + +		LLString asset_name = name; +		LLString::replaceNonstandardASCII( asset_name, '?' ); +		LLString::replaceChar(asset_name, '|', '?'); +		LLString::stripNonprintable(asset_name); +		LLString::trim(asset_name); + +		char* asset_name_str = (char*)asset_name.c_str(); +		char* end_p = strrchr(asset_name_str, '.');		 // strip extension if exists +		if( !end_p ) +		{ +			 end_p = asset_name_str + strlen( asset_name_str );			/*Flawfinder: ignore*/ +		} +			 +		S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) ); + +		asset_name = asset_name.substr( 0, len ); + +		upload_new_resource(next_file, asset_name, asset_name, +							0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE); +	} +} + + +LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& post_data, +																 const LLUUID& vfile_id, +																 LLAssetType::EType asset_type) +: LLAssetUploadResponder(post_data, vfile_id, asset_type) +{ +} + +LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& post_data, +																 const std::string& file_name) +: LLAssetUploadResponder(post_data, file_name) +{ +} + +//virtual  +void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content) +{ +	llinfos << "LLUpdateAgentInventoryResponder::result from capabilities" << llendl; +	LLUUID item_id = mPostData["item_id"]; + +	LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(item_id); +	if(!item) +	{ +		llwarns << "Inventory item for " << mVFileID +			<< " is no longer in agent inventory." << llendl; +		return; +	} + +	// Update viewer inventory item +	LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); +	new_item->setAssetUUID(content["new_asset"].asUUID()); +	gInventory.updateItem(new_item); +	gInventory.notifyObservers(); + +	llinfos << "Inventory item " << item->getName() << " saved into " +		<< content["new_asset"].asString() << llendl; + +	LLInventoryType::EType inventory_type = new_item->getInventoryType(); +	switch(inventory_type) +	{ +		case LLInventoryType::IT_NOTECARD:  			{ -				next_owner_perm = PERM_MOVE | PERM_TRANSFER; + +				// Update the UI with the new asset. +				LLPreviewNotecard* nc; +				nc = (LLPreviewNotecard*)LLPreview::find(new_item->getUUID()); +				if(nc) +				{ +					// *HACK: we have to delete the asset in the VFS so +					// that the viewer will redownload it. This is only +					// really necessary if the asset had to be modified by +					// the uploader, so this can be optimized away in some +					// cases. A better design is to have a new uuid if the +					// script actually changed the asset. +					if(nc->hasEmbeddedInventory()) +					{ +						gVFS->removeFile( +							content["new_asset"].asUUID(), +							LLAssetType::AT_NOTECARD); +					} +					nc->refreshFromInventory(); +				}  			} -			perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, next_owner_perm); -			S32 creation_date_now = time_corrected(); -			LLPointer<LLViewerInventoryItem> item -				= new LLViewerInventoryItem(result["new_inventory_item"].asUUID(), -											mPostData["folder_id"].asUUID(), -											perm, -											result["new_asset"].asUUID(), -											asset_type, -											inventory_type, -											mPostData["name"].asString(), -											mPostData["description"].asString(), -											LLSaleInfo::DEFAULT, -											LLInventoryItem::II_FLAGS_NONE, -											creation_date_now); -			gInventory.updateItem(item); -			gInventory.notifyObservers(); - -			// Show the preview panel for textures and sounds to let -			// user know that the image (or snapshot) arrived intact. -			LLInventoryView* view = LLInventoryView::getActiveInventory(); -			if(view) +			break; +		case LLInventoryType::IT_LSL:  			{ -				LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); -				LLFocusMgr::FocusLostCallback callback = gFocusMgr.getFocusCallback(); - -				view->getPanel()->setSelection(result["new_inventory_item"].asUUID(), TAKE_FOCUS_NO); -				if((LLAssetType::AT_TEXTURE == asset_type) -					|| (LLAssetType::AT_SOUND == asset_type)) +				// Find our window and close it if requested. +				LLPreviewLSL* preview = (LLPreviewLSL*)LLPreview::find(item_id); +				if (preview)  				{ -					view->getPanel()->openSelected(); +					// Bytecode save completed +					if (content["compiled"]) +					{ +						preview->callbackLSLCompileSucceeded(); +					} +					else +					{ +						preview->callbackLSLCompileFailed(content["errors"]); +					}  				} -				//LLInventoryView::dumpSelectionInformation((void*)view); -				// restore keyboard focus -				gFocusMgr.setKeyboardFocus(focus_ctrl, callback);  			} -		} -		else -		{ -			llwarns << "Can't find a folder to put it in" << llendl; -		} +			break; +		case LLInventoryType::IT_WEARABLE: +		default: +			break; +	} +} -		// remove the "Uploading..." message -		LLUploadDialog::modalUploadFinished(); -		 -		// *NOTE: This is a pretty big hack. What this does is check -		// the file picker if there are any more pending uploads. If -		// so, upload that file. -		const char* next_file = LLFilePicker::instance().getNextFile(); -		if(next_file) -		{ -			const char* name = LLFilePicker::instance().getDirname(); -			LLString asset_name = name; -			LLString::replaceNonstandardASCII( asset_name, '?' ); -			LLString::replaceChar(asset_name, '|', '?'); -			LLString::stripNonprintable(asset_name); -			LLString::trim(asset_name); +LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data, +																 const LLUUID& vfile_id, +																 LLAssetType::EType asset_type) +: LLAssetUploadResponder(post_data, vfile_id, asset_type) +{ +} -			char* asset_name_str = (char*)asset_name.c_str(); -			char* end_p = strrchr(asset_name_str, '.');		 // strip extension if exists -			if( !end_p ) +LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data, +															   const std::string& file_name) +: LLAssetUploadResponder(post_data, file_name) +{ +} + +//virtual  +void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content) +{ +	llinfos << "LLUpdateTaskInventoryResponder::result from capabilities" << llendl; +	LLUUID item_id = mPostData["item_id"]; +	LLUUID task_id = mPostData["task_id"]; + +	LLViewerObject* object = gObjectList.findObject(task_id); +	if (!object) +	{ +		llwarns << "LLUpdateTaskInventoryResponder::uploadComplete task " << task_id +			<< " no longer exist." << llendl; +		return; +	} +	LLViewerInventoryItem* item = (LLViewerInventoryItem*)object->getInventoryObject(item_id); +	if (!item) +	{ +		llwarns << "LLUpdateTaskInventoryResponder::uploadComplete item " +			<< item_id << " is no longer in task " << task_id +			<< "'s inventory." << llendl; +		return; +	} +	LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); +	// Update Viewer inventory +	object->updateViewerInventoryAsset(new_item, content["new_asset"]); +	dialog_refresh_all(); +	 +	LLInventoryType::EType inventory_type = new_item->getInventoryType(); +	switch(inventory_type) +	{ +		case LLInventoryType::IT_NOTECARD:  			{ -				end_p = asset_name_str + strlen( asset_name_str );			/*Flawfinder: ignore*/ -			} -				 -			S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) ); -			asset_name = asset_name.substr( 0, len ); +				// Update the UI with the new asset. +				LLPreviewNotecard* nc; +				nc = (LLPreviewNotecard*)LLPreview::find(new_item->getUUID()); +				if(nc) +				{ +					// *HACK: we have to delete the asset in the VFS so +					// that the viewer will redownload it. This is only +					// really necessary if the asset had to be modified by +					// the uploader, so this can be optimized away in some +					// cases. A better design is to have a new uuid if the +					// script actually changed the asset. +					if(nc->hasEmbeddedInventory()) +					{ +						gVFS->removeFile( +							content["new_asset"].asUUID(), +							LLAssetType::AT_NOTECARD); +					} -			upload_new_resource(next_file, asset_name, asset_name, -								0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE); -		} +					nc->refreshFromInventory(); +				} +			} +			break; +		case LLInventoryType::IT_LSL: +			{ +				LLLiveLSLEditor* preview = LLLiveLSLEditor::find(item_id, task_id); +				if (preview) +				{ +					// Bytecode save completed +					if (content["compiled"]) +					{ +						preview->callbackLSLCompileSucceeded( +							task_id, +							item_id, +							mPostData["is_script_running"]); +					} +					else +					{ +						preview->callbackLSLCompileFailed(content["errors"]); +					} +				} +			} +			break; +		case LLInventoryType::IT_WEARABLE: +		default: +			break;  	}  } diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h index b4d5377601..ef8cd3834a 100644 --- a/indra/newview/llassetuploadresponders.h +++ b/indra/newview/llassetuploadresponders.h @@ -1,26 +1,65 @@ -/**  - * @file llmapresponders.h - * @brief Processes responses received for asset upload requests. - * - * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc. - * $License$ - */ +// llassetuploadresponders.h +// Copyright 2006, Linden Research, Inc. +// Processes responses received for asset upload requests. -#ifndef LL_LLNEWAGENTINVENTORYRESPONDER_H -#define LL_LLNEWAGENTINVENTORYRESPONDER_H +#ifndef LL_LLASSETUPLOADRESPONDER_H +#define LL_LLASSETUPLOADRESPONDER_H  #include "llhttpclient.h" -class LLNewAgentInventoryResponder : public LLHTTPClient::Responder +// Abstract class for supporting asset upload +// via capabilities +class LLAssetUploadResponder : public LLHTTPClient::Responder  {  public: -	LLNewAgentInventoryResponder(const LLUUID& uuid, const LLSD& post_data); -    void error(U32 statusNum, const std::string& reason); +	LLAssetUploadResponder(const LLSD& post_data, +							const LLUUID& vfile_id, +							LLAssetType::EType asset_type); +	LLAssetUploadResponder(const LLSD& post_data, const std::string& file_name); +	~LLAssetUploadResponder(); +    virtual void error(U32 statusNum, const std::string& reason);  	virtual void result(const LLSD& content); +	virtual void uploadUpload(const LLSD& content); +	virtual void uploadComplete(const LLSD& content); +	virtual void uploadFailure(const LLSD& content); -private: -	LLUUID mUUID; +protected:  	LLSD mPostData; +	LLUUID mVFileID; +	LLAssetType::EType mAssetType; +	std::string mFileName;  }; -#endif // LL_LLNEWAGENTINVENTORYRESPONDER_H +class LLNewAgentInventoryResponder : public LLAssetUploadResponder +{ +public: +	LLNewAgentInventoryResponder(const LLSD& post_data, +								const LLUUID& vfile_id, +								LLAssetType::EType asset_type); +	LLNewAgentInventoryResponder(const LLSD& post_data, const std::string& file_name); +	virtual void uploadComplete(const LLSD& content); +}; + +class LLUpdateAgentInventoryResponder : public LLAssetUploadResponder +{ +public: +	LLUpdateAgentInventoryResponder(const LLSD& post_data, +								const LLUUID& vfile_id, +								LLAssetType::EType asset_type); +	LLUpdateAgentInventoryResponder(const LLSD& post_data, +								const std::string& file_name); +	virtual void uploadComplete(const LLSD& content); +}; + +class LLUpdateTaskInventoryResponder : public LLAssetUploadResponder +{ +public: +	LLUpdateTaskInventoryResponder(const LLSD& post_data, +								const LLUUID& vfile_id, +								LLAssetType::EType asset_type); +	LLUpdateTaskInventoryResponder(const LLSD& post_data, +								const std::string& file_name); +	virtual void uploadComplete(const LLSD& content); +}; + +#endif // LL_LLASSETUPLOADRESPONDER_H diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp index f82978c5fc..7eaac8887c 100644 --- a/indra/newview/llfloaterpostcard.cpp +++ b/indra/newview/llfloaterpostcard.cpp @@ -39,6 +39,8 @@  #include "llvfs.h"  #include "viewer.h" +#include "llassetuploadresponders.h" +  ///----------------------------------------------------------------------------  /// Local function declarations, constants, enums, and typedefs  ///---------------------------------------------------------------------------- @@ -206,6 +208,23 @@ void LLFloaterPostcard::onClickCancel(void* data)  	}  } +class LLSendPostcardResponder : public LLAssetUploadResponder +{ +public: +	LLSendPostcardResponder(const LLSD &post_data, +							const LLUUID& vfile_id, +							LLAssetType::EType asset_type): +	    LLAssetUploadResponder(post_data, vfile_id, asset_type) +	{	 +	} +	// *TODO define custom uploadFailed here so it's not such a generic message +	void LLSendPostcardResponder::uploadComplete(const LLSD& content) +	{ +		// we don't care about what the server returns from this post, just clean up the UI +		LLUploadDialog::modalUploadFinished(); +	} +}; +  // static  void LLFloaterPostcard::onClickSend(void* data)  { @@ -230,12 +249,31 @@ void LLFloaterPostcard::onClickSend(void* data)  		if (self->mJPEGImage.notNull())  		{ -			// upload the image  			self->mTransactionID.generate();  			self->mAssetID = self->mTransactionID.makeAssetID(gAgent.getSecureSessionID());  			LLVFile::writeFile(self->mJPEGImage->getData(), self->mJPEGImage->getDataSize(), gVFS, self->mAssetID, LLAssetType::AT_IMAGE_JPEG); -			 -			gAssetStorage->storeAssetData(self->mTransactionID, LLAssetType::AT_IMAGE_JPEG, &uploadCallback, (void *)self, FALSE); + +			// upload the image +			std::string url = gAgent.getRegion()->getCapability("SendPostcard"); +			if(!url.empty()) +			{ +				llinfos << "Send Postcard via capability" << llendl; +				LLSD body = LLSD::emptyMap(); +				// the capability already encodes: agent ID, region ID +				body["pos-global"] = self->mPosTakenGlobal.getValue(); +				body["to"] = self->childGetValue("to_form").asString(); +				body["from"] = self->childGetValue("from_form").asString(); +				body["name"] = self->childGetValue("name_form").asString(); +				body["subject"] = self->childGetValue("subject_form").asString(); +				body["msg"] = self->childGetValue("msg_form").asString(); +				body["allow-publish"] = self->childGetValue("allow_publish_check").asBoolean(); +				body["mature-publish"] = self->childGetValue("mature_check").asBoolean(); +				LLHTTPClient::post(url, body, new LLSendPostcardResponder(body, self->mAssetID, LLAssetType::AT_IMAGE_JPEG)); +			}  +			else +			{ +				gAssetStorage->storeAssetData(self->mTransactionID, LLAssetType::AT_IMAGE_JPEG, &uploadCallback, (void *)self, FALSE); +			}  			LLUploadDialog::modalUploadDialog("Uploading...\n\nPostcard"); diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 84c99db8da..62f5fd21d5 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -44,6 +44,7 @@  #include "lltooldraganddrop.h"  #include "llfloatermap.h"  #include "lluiconstants.h" +#include "lluploaddialog.h"  #include "llcallingcard.h"  #include "llviewerobjectlist.h"  #include "llagent.h" @@ -61,6 +62,7 @@  #include "llvieweruictrlfactory.h"  #include "viewer.h" +#include "llassetuploadresponders.h"  const U32 INCLUDE_SCREENSHOT  = 0x01 << 0; @@ -96,7 +98,8 @@ LLFloaterReporter::LLFloaterReporter(  	mDeselectOnClose( FALSE ),  	mPicking( FALSE),   	mPosition(), -	mCopyrightWarningSeen( FALSE ) +	mCopyrightWarningSeen( FALSE ), +	mResourceDatap(new LLResourceData())  {  	if (report_type == BUG_REPORT)  	{ @@ -147,9 +150,9 @@ LLFloaterReporter::LLFloaterReporter(  	gReporterInstances.addData(report_type, this); -	// Upload a screenshot, but don't draw this floater. +	// Take a screenshot, but don't draw this floater.  	setVisible(FALSE); -	uploadScreenshot(); +	takeScreenshot();  	setVisible(TRUE);  	// Default text to be blank @@ -211,6 +214,7 @@ LLFloaterReporter::~LLFloaterReporter()  	std::for_each(mMCDList.begin(), mMCDList.end(), DeletePointer() );  	mMCDList.clear(); +	delete mResourceDatap;  	gDialogVisible = FALSE;  } @@ -344,7 +348,7 @@ void LLFloaterReporter::callbackAvatarID(const std::vector<std::string>& names,  	if ( self->mReportType != BUG_REPORT )  	{  		self->childSetText("abuser_name_edit", names[0] ); - +		  		self->mAbuserID = ids[0];  		self->refresh(); @@ -355,31 +359,59 @@ void LLFloaterReporter::callbackAvatarID(const std::vector<std::string>& names,  void LLFloaterReporter::onClickSend(void *userdata)  {  	LLFloaterReporter *self = (LLFloaterReporter *)userdata; +	 +	if (self->mPicking) +	{ +		closePickTool(self); +	} -	// only do this for abuse reports -	if ( self->mReportType != BUG_REPORT ) +	if(self->validateReport())  	{ -		if ( ! self->mCopyrightWarningSeen ) +		// only show copyright alert for abuse reports +		if ( self->mReportType != BUG_REPORT )  		{ -			LLString details_lc = self->childGetText("details_edit"); -			LLString::toLower( details_lc ); -			LLString summary_lc = self->childGetText("summary_edit"); -			LLString::toLower( summary_lc ); -			if ( details_lc.find( "copyright" ) != std::string::npos || -				summary_lc.find( "copyright" ) != std::string::npos ) +			if ( ! self->mCopyrightWarningSeen )  			{ -				gViewerWindow->alertXml("HelpReportAbuseContainsCopyright"); -				self->mCopyrightWarningSeen = TRUE; -				return; +				LLString details_lc = self->childGetText("details_edit"); +				LLString::toLower( details_lc ); +				LLString summary_lc = self->childGetText("summary_edit"); +				LLString::toLower( summary_lc ); +				if ( details_lc.find( "copyright" ) != std::string::npos || +					summary_lc.find( "copyright" ) != std::string::npos ) +				{ +					gViewerWindow->alertXml("HelpReportAbuseContainsCopyright"); +					self->mCopyrightWarningSeen = TRUE; +					return; +				};  			};  		}; -	}; -	if (self->mPicking) -	{ -		closePickTool(self); +		LLUploadDialog::modalUploadDialog("Uploading...\n\nReport"); +		// *TODO don't upload image if checkbox isn't checked +		std::string url = gAgent.getRegion()->getCapability("SendUserReport"); +		std::string sshot_url = gAgent.getRegion()->getCapability("SendUserReportWithScreenshot"); +		if(!url.empty() || !sshot_url.empty()) +		{ +			self->sendReportViaCaps(url, sshot_url, self->gatherReport()); +			self->close(); +		} +		else +		{ +			if(self->childGetValue("screen_check")) +			{ +				self->childDisable("send_btn"); +				self->childDisable("cancel_btn"); +				// the callback from uploading the image calls sendReportViaLegacy() +				self->uploadImage(); +			} +			else +			{ +				self->sendReportViaLegacy(self->gatherReport()); +				LLUploadDialog::modalUploadFinished(); +				self->close(); +			} +		}  	} -	self->sendReport();  } @@ -532,10 +564,9 @@ void LLFloaterReporter::setPickedObjectProperties(const char *object_name, const  	childSetText("owner_name", owner_name);  } -void LLFloaterReporter::sendReport() + +bool LLFloaterReporter::validateReport()  { -	LLViewerRegion *regionp = gAgent.getRegion(); -	if (!regionp) return;  	// Ensure user selected a category from the list  	LLSD category_sd = childGetValue("category_combo");  	U8 category = (U8)category_sd.asInteger(); @@ -549,7 +580,7 @@ void LLFloaterReporter::sendReport()  		{  			gViewerWindow->alertXml("HelpReportBugSelectCategory");  		} -		return; +		return false;  	}  	if ( mReportType != BUG_REPORT ) @@ -557,13 +588,13 @@ void LLFloaterReporter::sendReport()  	  if ( childGetText("abuser_name_edit").empty() )  	  {  		  gViewerWindow->alertXml("HelpReportAbuseAbuserNameEmpty"); -		  return; +		  return false;  	  };  	  if ( childGetText("abuse_location_edit").empty() )  	  {  		  gViewerWindow->alertXml("HelpReportAbuseAbuserLocationEmpty"); -		  return; +		  return false;  	  };  	}; @@ -577,7 +608,7 @@ void LLFloaterReporter::sendReport()  		{  			gViewerWindow->alertXml("HelpReportBugSummaryEmpty");  		} -		return; +		return false;  	};  	if ( childGetText("details_edit") == mDefaultSummary ) @@ -590,53 +621,19 @@ void LLFloaterReporter::sendReport()  		{  			gViewerWindow->alertXml("HelpReportBugDetailsEmpty");  		} -		return; +		return false;  	}; +	return true; +} + +LLSD LLFloaterReporter::gatherReport() +{	 +	LLViewerRegion *regionp = gAgent.getRegion(); +	if (!regionp) return LLSD(); // *TODO handle this failure case more gracefully  	// reset flag in case the next report also contains this text  	mCopyrightWarningSeen = FALSE; -	U32 check_flags = 0; -	if (childGetValue("screen_check")) -	{ -		check_flags |= INCLUDE_SCREENSHOT; -	} - -	LLMessageSystem *msg = gMessageSystem; -	msg->newMessageFast(_PREHASH_UserReport); -	msg->nextBlockFast(_PREHASH_AgentData); -	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -	msg->nextBlockFast(_PREHASH_ReportData); -	msg->addU8Fast(_PREHASH_ReportType, 	(U8) mReportType); -	msg->addU8(_PREHASH_Category, category); -	msg->addVector3Fast(_PREHASH_Position, 	mPosition); -	msg->addU8Fast(_PREHASH_CheckFlags, 	(U8) check_flags); - -	// only send a screenshot ID if we're asked too and the email is  -	// going to LL - Estate Owners cannot see the screenshot asset -	LLSD screenshot_id = LLUUID::null; -	if (childGetValue("screen_check")) -	{ -		if ( mReportType != BUG_REPORT ) -		{ -			if ( gEmailToEstateOwner == FALSE ) -			{ -				screenshot_id = childGetValue("screenshot"); -			} -		} -		else -		{ -			screenshot_id = childGetValue("screenshot"); -		}; -	}; -	msg->addUUIDFast(_PREHASH_ScreenshotID, screenshot_id); -	msg->addUUIDFast(_PREHASH_ObjectID, 	mObjectID); - -	msg->addUUID("AbuserID", mAbuserID ); -	msg->addString("AbuseRegionName", ""); -	msg->addUUID("AbuseRegionID", LLUUID::null); -  	std::ostringstream summary;  	if (!gInProductionGrid)  	{ @@ -684,7 +681,6 @@ void LLFloaterReporter::sendReport()  			<< " {" << childGetText("abuser_name_edit") << "} "					// name of abuse entered in report (chosen using LLAvatarPicker)  			<< " \"" << childGetValue("summary_edit").asString() << "\"";		// summary as entered  	}; -	msg->addStringFast(_PREHASH_Summary, summary.str().c_str());  	std::ostringstream details;  	if (mReportType != BUG_REPORT) @@ -709,7 +705,6 @@ void LLFloaterReporter::sendReport()  	};  	details << childGetValue("details_edit").asString(); -	msg->addStringFast(_PREHASH_Details, details.str() );  	char version_string[MAX_STRING];		/* Flawfinder: ignore */  	snprintf(version_string,						/* Flawfinder: ignore */ @@ -722,120 +717,204 @@ void LLFloaterReporter::sendReport()  			gSysCPU.getFamily().c_str(),  			gGLManager.mGLRenderer.c_str(),  			gGLManager.mDriverVersionVendorString.c_str()); -	msg->addString("VersionString", version_string); -	msg->sendReliable(regionp->getHost()); +	// only send a screenshot ID if we're asked to and the email is  +	// going to LL - Estate Owners cannot see the screenshot asset +	LLUUID screenshot_id = LLUUID::null; +	if (childGetValue("screen_check")) +	{ +		if ( mReportType != BUG_REPORT ) +		{ +			if ( gEmailToEstateOwner == FALSE ) +			{ +				screenshot_id = childGetValue("screenshot"); +			} +		} +		else +		{ +			screenshot_id = childGetValue("screenshot"); +		}; +	}; -	close(); +	LLSD report = LLSD::emptyMap(); +	report["report-type"] = (U8) mReportType; +	report["category"] = childGetValue("category_combo"); +	report["position"] = mPosition.getValue(); +	report["check-flags"] = (U8)0; // this is not used +	report["screenshot-id"] = screenshot_id; +	report["object-id"] = mObjectID; +	report["abuser-id"] = mAbuserID; +	report["abuse-region-name"] = ""; +	report["abuse-region-id"] = LLUUID::null; +	report["summary"] = summary.str(); +	report["version-string"] = version_string; +	report["details"] = details.str(); +	return report;  } +void LLFloaterReporter::sendReportViaLegacy(const LLSD & report) +{ +	LLViewerRegion *regionp = gAgent.getRegion(); +	if (!regionp) return; +	LLMessageSystem *msg = gMessageSystem; +	msg->newMessageFast(_PREHASH_UserReport); +	msg->nextBlockFast(_PREHASH_AgentData); +	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +	 +	msg->nextBlockFast(_PREHASH_ReportData); +	msg->addU8Fast(_PREHASH_ReportType, report["report-type"].asInteger()); +	msg->addU8(_PREHASH_Category, report["category"].asInteger()); +	msg->addVector3Fast(_PREHASH_Position, 	LLVector3(report["position"])); +	msg->addU8Fast(_PREHASH_CheckFlags, report["check-flags"].asInteger()); +	msg->addUUIDFast(_PREHASH_ScreenshotID, report["screenshot-id"].asUUID()); +	msg->addUUIDFast(_PREHASH_ObjectID, report["object-id"].asUUID()); +	msg->addUUID("AbuserID", report["abuser-id"].asUUID()); +	msg->addString("AbuseRegionName", report["abuse-region-name"].asString()); +	msg->addUUID("AbuseRegionID", report["abuse-region-id"].asUUID()); + +	msg->addStringFast(_PREHASH_Summary, report["summary"].asString().c_str()); +	msg->addString("VersionString", report["version-string"]); +	msg->addStringFast(_PREHASH_Details, report["details"] ); +	 +	msg->sendReliable(regionp->getHost()); +} -void LLFloaterReporter::uploadScreenshot() +class LLUserReportScreenshotResponder : public LLAssetUploadResponder +{ +public: +	LLUserReportScreenshotResponder(const LLSD & post_data,  +									const LLUUID & vfile_id,  +									LLAssetType::EType asset_type): +	  LLAssetUploadResponder(post_data, vfile_id, asset_type) +	{ +	} +	void uploadFailed(const LLSD& content) +	{ +		// *TODO pop up a dialog so the user knows their report screenshot didn't make it +		LLUploadDialog::modalUploadFinished(); +	} +	void uploadComplete(const LLSD& content) +	{ +		// we don't care about what the server returns from this post, just clean up the UI +		LLUploadDialog::modalUploadFinished(); +	} +}; + +class LLUserReportResponder : public LLHTTPClient::Responder +{ +public: +	LLUserReportResponder(): LLHTTPClient::Responder()  {} + +	void error(U32 status, const std::string& reason) +	{ +		// *TODO do some user messaging here +		LLUploadDialog::modalUploadFinished(); +	} +	void result(const LLSD& content) +	{ +		// we don't care about what the server returns +		LLUploadDialog::modalUploadFinished(); +	} +}; + +void LLFloaterReporter::sendReportViaCaps(std::string url, std::string sshot_url, const LLSD& report) +{ +	if(childGetValue("screen_check").asBoolean() && !sshot_url.empty()) +	{ +		// try to upload screenshot +		LLHTTPClient::post(sshot_url, report, new LLUserReportScreenshotResponder(report,  +															mResourceDatap->mAssetInfo.mUuid,  +															mResourceDatap->mAssetInfo.mType));			 +	} +	else +	{ +		// screenshot not wanted or we don't have screenshot cap +		LLHTTPClient::post(url, report, new LLUserReportResponder());			 +	} +} + +void LLFloaterReporter::takeScreenshot()  {  	const S32 IMAGE_WIDTH = 1024;  	const S32 IMAGE_HEIGHT = 768; -	LLString filename("report_screenshot.bmp"); -	if( !gViewerWindow->saveSnapshot( filename, IMAGE_WIDTH, IMAGE_HEIGHT, TRUE, FALSE ) ) +	LLPointer<LLImageRaw> raw = new LLImageRaw; +	if( !gViewerWindow->rawSnapshot(raw, IMAGE_WIDTH, IMAGE_HEIGHT, TRUE, TRUE, FALSE))  	{ +		llwarns << "Unable to take screenshot" << llendl;  		return;  	} +	LLPointer<LLImageJ2C> upload_data = LLViewerImageList::convertToUploadFile(raw); -	// Generate the temporary filename -	std::string temp_filename = gDirUtilp->getTempFilename(); - -	// try to create the upload file -	if (!LLViewerImageList::createUploadFile(filename, -										 	temp_filename, -										 	IMG_CODEC_BMP )) +	// create a resource data +	mResourceDatap->mInventoryType = LLInventoryType::IT_NONE; +	mResourceDatap->mAssetInfo.mTransactionID.generate(); +	mResourceDatap->mAssetInfo.mUuid = mResourceDatap->mAssetInfo.mTransactionID.makeAssetID(gAgent.getSecureSessionID()); +	if (BUG_REPORT == mReportType)  	{ -		llwarns << "Unable to upload report screenshot " << filename << ":\n\n" << LLImageBase::getLastError() << "\n" << llendl; -		if(LLFile::remove(temp_filename.c_str()) == -1) -		{ -			lldebugs << "unable to remove temp file" << llendl; -		} -		LLFilePicker::instance().reset(); +		mResourceDatap->mAssetInfo.mType = LLAssetType::AT_TEXTURE; +		mResourceDatap->mPreferredLocation = LLAssetType::EType(-1); +	} +	else if (COMPLAINT_REPORT == mReportType) +	{ +		mResourceDatap->mAssetInfo.mType = LLAssetType::AT_TEXTURE; +		mResourceDatap->mPreferredLocation = LLAssetType::EType(-2);  	}  	else  	{ -		// create a resource data -		LLResourceData* data = NULL; -		data = new LLResourceData; -		data->mInventoryType = LLInventoryType::IT_NONE; -		data->mAssetInfo.mTransactionID.generate(); -		data->mAssetInfo.mUuid = data->mAssetInfo.mTransactionID.makeAssetID(gAgent.getSecureSessionID()); -		if (BUG_REPORT == mReportType) -		{ -			//data->mAssetInfo.mType = LLAssetType::AT_BUG_REPORT_SCREENSHOT; -			data->mAssetInfo.mType = LLAssetType::AT_TEXTURE; -			data->mPreferredLocation = LLAssetType::EType(-1); -		} -		else if (COMPLAINT_REPORT == mReportType) -		{ -			//data->mAssetInfo.mType = LLAssetType::AT_COMPLAINT_REPORT_SCREENSHOT; -			data->mAssetInfo.mType = LLAssetType::AT_TEXTURE; -			data->mPreferredLocation = LLAssetType::EType(-2); -		} -		else -		{ -			llwarns << "Unknown LLFloaterReporter type" << llendl; -		} -		data->mAssetInfo.mCreatorID = gAgentID; -		data->mAssetInfo.setName("screenshot_name"); -		data->mAssetInfo.setDescription("screenshot_descr"); - -		llinfos << "*** Uploading: " << llendl; -		llinfos << "Type: " << LLAssetType::lookup(data->mAssetInfo.mType) << llendl; -		llinfos << "File: " << filename << llendl; -		llinfos << "Dest: " << temp_filename << llendl; -		llinfos << "Name: " << data->mAssetInfo.getName() << llendl; -		llinfos << "Desc: " << data->mAssetInfo.getDescription() << llendl; - -		gAssetStorage->storeAssetData(temp_filename.c_str(), -										data->mAssetInfo.mTransactionID, -										data->mAssetInfo.mType, -										LLFloaterReporter::uploadDoneCallback, -										(void*)data, TRUE); +		llwarns << "Unknown LLFloaterReporter type" << llendl; +	} +	mResourceDatap->mAssetInfo.mCreatorID = gAgentID; +	mResourceDatap->mAssetInfo.setName("screenshot_name"); +	mResourceDatap->mAssetInfo.setDescription("screenshot_descr"); + +	// store in VFS +	LLVFile::writeFile(upload_data->getData(),  +						upload_data->getDataSize(),  +						gVFS,  +						mResourceDatap->mAssetInfo.mUuid,  +						mResourceDatap->mAssetInfo.mType); + +	// store in the image list so it doesn't try to fetch from the server +	LLViewerImage* image_in_list = new LLViewerImage(mResourceDatap->mAssetInfo.mUuid, TRUE); +	image_in_list->createGLTexture(0, raw); +	gImageList.addImage(image_in_list);  + +	// the texture picker then uses that texture +	LLTexturePicker* texture = LLUICtrlFactory::getTexturePickerByName(this, "screenshot"); +	if (texture) +	{ +		texture->setImageAssetID(mResourceDatap->mAssetInfo.mUuid); +		texture->setDefaultImageAssetID(mResourceDatap->mAssetInfo.mUuid); +		texture->setCaption("Screenshot");  	} + +} + +void LLFloaterReporter::uploadImage() +{ +	llinfos << "*** Uploading: " << llendl; +	llinfos << "Type: " << LLAssetType::lookup(mResourceDatap->mAssetInfo.mType) << llendl; +	llinfos << "UUID: " << mResourceDatap->mAssetInfo.mUuid << llendl; +	llinfos << "Name: " << mResourceDatap->mAssetInfo.getName() << llendl; +	llinfos << "Desc: " << mResourceDatap->mAssetInfo.getDescription() << llendl; + +	gAssetStorage->storeAssetData(mResourceDatap->mAssetInfo.mTransactionID, +									mResourceDatap->mAssetInfo.mType, +									LLFloaterReporter::uploadDoneCallback, +									(void*)mResourceDatap, TRUE);  }  // static  void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data, S32 result) // StoreAssetData callback (fixed)  { -	LLResourceData* data = (LLResourceData*)user_data; +	LLUploadDialog::modalUploadFinished(); -	if(result >= 0) -	{ -		EReportType report_type = UNKNOWN_REPORT; -		if (data->mPreferredLocation == -1) -		{ -			report_type = BUG_REPORT; -		} -		else if (data->mPreferredLocation == -2) -		{ -			report_type = COMPLAINT_REPORT; -		} -		else  -		{ -			llwarns << "Unknown report type : " << data->mPreferredLocation << llendl; -		} +	LLResourceData* data = (LLResourceData*)user_data; -		LLFloaterReporter *self = getReporter(report_type); -		if (self) -		{ -			LLTexturePicker* texture = LLUICtrlFactory::getTexturePickerByName(self, "screenshot"); -			if (texture) -			{ -				texture->setImageAssetID(uuid); -				texture->setDefaultImageAssetID(uuid); -				texture->setCaption("Screenshot"); -			} -			self->mScreenID = uuid; -			llinfos << "Got screen shot " << uuid << llendl; -		} -	} -	else // 	if(result >= 0) +	if(result < 0)  	{  		LLStringBase<char>::format_map_t args;  		args["[REASON]"] = std::string(LLAssetStorage::getErrorString(result)); @@ -844,8 +923,31 @@ void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data,  		std::string err_msg("There was a problem uploading a report screenshot");  		err_msg += " due to the following reason: " + args["[REASON]"];  		llwarns << err_msg << llendl; +		return; +	} + +	EReportType report_type = UNKNOWN_REPORT; +	if (data->mPreferredLocation == -1) +	{ +		report_type = BUG_REPORT;  	} -	delete data; +	else if (data->mPreferredLocation == -2) +	{ +		report_type = COMPLAINT_REPORT; +	} +	else  +	{ +		llwarns << "Unknown report type : " << data->mPreferredLocation << llendl; +	} + +	LLFloaterReporter *self = getReporter(report_type); +	if (self) +	{ +		self->mScreenID = uuid; +		llinfos << "Got screen shot " << uuid << llendl; +		self->sendReportViaLegacy(self->gatherReport()); +	} +	self->close();  } diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h index 795ef45e53..e8483b98ef 100644 --- a/indra/newview/llfloaterreporter.h +++ b/indra/newview/llfloaterreporter.h @@ -21,6 +21,7 @@ class LLViewerObject;  class LLAgent;  class LLToolObjPicker;  class LLMeanCollisionData; +struct LLResourceData;  // these flags are used to label info requests to the server  const U32 BUG_REPORT_REQUEST 		= 0x01 << 0; @@ -51,7 +52,6 @@ enum EReportType  	CS_REQUEST_REPORT = 4  }; -  class LLFloaterReporter  :	public LLFloater  { @@ -87,11 +87,16 @@ public:  	static void processRegionInfo(LLMessageSystem* msg);  	void setPickedObjectProperties(const char *object_name, const char *owner_name); -	void uploadScreenshot();  private: +	void takeScreenshot(); +	void sendReportViaCaps(std::string url); +	void uploadImage(); +	bool validateReport();  	void setReporterID(); -	void sendReport(); +	LLSD gatherReport(); +	void sendReportViaLegacy(const LLSD & report); +	void sendReportViaCaps(std::string url, std::string sshot_url, const LLSD & report);  	void setPosBox(const LLVector3d &pos);  	void enableControls(BOOL own_avatar);  	void getObjectInfo(const LLUUID& object_id); @@ -108,6 +113,7 @@ private:  	BOOL			mCopyrightWarningSeen;  	std::list<LLMeanCollisionData*> mMCDList;  	LLString		mDefaultSummary; +	LLResourceData* mResourceDatap;  };  #endif diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp index 34f394610f..c178d0d416 100644 --- a/indra/newview/llfloatertos.cpp +++ b/indra/newview/llfloatertos.cpp @@ -163,18 +163,8 @@ BOOL LLFloaterTOS::postBuild()  		gResponsePtr = LLIamHere::build( this );  		LLHTTPClient::get( childGetValue( "real_url" ).asString(), gResponsePtr );  	}; -	#else -	LLTextEditor *Editor = LLUICtrlFactory::getTextEditorByName(this, "tos_text"); -	if (Editor) -	{ -		Editor->setHandleEditKeysDirectly( TRUE ); -		Editor->setEnabled( FALSE ); -		Editor->setReadOnlyFgColor(LLColor4::white); -		Editor->setWordWrap(TRUE); -		Editor->setFocus(TRUE); -	} -	childSetValue("tos_text", LLSD(mMessage));	  	#endif +  	return TRUE;  } diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 938976241b..862dbcf377 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -22,6 +22,7 @@  // newview  #include "llagent.h"		// todo: remove +#include "llassetuploadresponders.h"  #include "llbutton.h"  #include "llcheckboxctrl.h"  #include "llcombobox.h" @@ -38,6 +39,7 @@  #include "llviewerinventory.h"  #include "llviewerobject.h"  #include "llviewerobjectlist.h" +#include "llviewerregion.h"  #include "llviewerstats.h"  #include "llviewerwindow.h"		// busycount  #include "viewer.h"			// gVFS @@ -1101,13 +1103,31 @@ void LLPreviewGesture::saveIfNeeded()  		LLInventoryItem* item = getItem();  		if (item)  		{ -			LLLineEditor* descEditor = LLUICtrlFactory::getLineEditorByName(this, "desc"); -			LLSaveInfo* info = new LLSaveInfo(mItemUUID, mObjectUUID, descEditor->getText(), tid); - -			const BOOL temp_file = FALSE; - -			gAssetStorage->storeAssetData(tid, LLAssetType::AT_GESTURE, onSaveComplete, info, temp_file); - +			std::string agent_url = gAgent.getRegion()->getCapability("UpdateGestureAgentInventory"); +			std::string task_url = gAgent.getRegion()->getCapability("UpdateGestureTaskInventory"); +			if (mObjectUUID.isNull() && !agent_url.empty()) +			{ +				// Saving into agent inventory +				LLSD body; +				body["item_id"] = mItemUUID; +				LLHTTPClient::post(agent_url, body, +					new LLUpdateAgentInventoryResponder(body, asset_id, LLAssetType::AT_GESTURE)); +			} +			else if (!mObjectUUID.isNull() && !task_url.empty()) +			{ +				// Saving into task inventory +				LLSD body; +				body["task_id"] = mObjectUUID; +				body["item_id"] = mItemUUID; +				LLHTTPClient::post(task_url, body, +					new LLUpdateTaskInventoryResponder(body, asset_id, LLAssetType::AT_GESTURE)); +			} +			else if (gAssetStorage) +			{ +				LLLineEditor* descEditor = LLUICtrlFactory::getLineEditorByName(this, "desc"); +				LLSaveInfo* info = new LLSaveInfo(mItemUUID, mObjectUUID, descEditor->getText(), tid); +				gAssetStorage->storeAssetData(tid, LLAssetType::AT_GESTURE, onSaveComplete, info, FALSE); +			}  		}  		// If this gesture is active, then we need to update the in-memory diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index 6b8cc626ee..154ce5b07c 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -13,6 +13,7 @@  #include "llinventory.h"  #include "llagent.h" +#include "llassetuploadresponders.h"  #include "llviewerwindow.h"  #include "llbutton.h"  #include "llinventorymodel.h" @@ -219,6 +220,22 @@ const LLInventoryItem* LLPreviewNotecard::getDragItem()  	return NULL;  } +bool LLPreviewNotecard::hasEmbeddedInventory() +{ +	LLViewerTextEditor* editor = NULL; +	editor = LLViewerUICtrlFactory::getViewerTextEditorByName( +		this, +		"Notecard Editor"); +	if (!editor) return false; +	return editor->hasEmbeddedInventory(); +} + +void LLPreviewNotecard::refreshFromInventory() +{ +	lldebugs << "LLPreviewNotecard::refreshFromInventory()" << llendl; +	loadAsset(); +} +  void LLPreviewNotecard::loadAsset()  {  	// request the asset. @@ -348,7 +365,7 @@ void LLPreviewNotecard::onLoadComplete(LLVFS *vfs,  			LLInventoryItem* item = preview->getItem();  			BOOL modifiable = item && gAgent.allowOperation(PERM_MODIFY,  								item->getPermissions(), GP_OBJECT_MANIPULATE); -			previewEditor->setEnabled(modifiable); +			preview->setEnabled(modifiable);  			delete[] buffer;  			preview->mAssetStatus = PREVIEW_ASSET_LOADED;  		} @@ -453,14 +470,43 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)  		LLInventoryItem* item = getItem();  		// save it out to database  		if (item) -		{ -			 -			LLSaveNotecardInfo* info = new LLSaveNotecardInfo(this, mItemUUID, mObjectUUID, -															  tid, copyitem); -			gAssetStorage->storeAssetData(tid, LLAssetType::AT_NOTECARD, -											&onSaveComplete, -											(void*)info, -											FALSE); +		{			 +			std::string agent_url = gAgent.getRegion()->getCapability("UpdateNotecardAgentInventory"); +			std::string task_url = gAgent.getRegion()->getCapability("UpdateNotecardTaskInventory"); +			if (mObjectUUID.isNull() && !agent_url.empty()) +			{ +				// Saving into agent inventory +				mAssetStatus = PREVIEW_ASSET_LOADING; +				setEnabled(FALSE); +				LLSD body; +				body["item_id"] = mItemUUID; +				llinfos << "Saving notecard " << mItemUUID +					<< " into agent inventory via " << agent_url << llendl; +				LLHTTPClient::post(agent_url, body, +					new LLUpdateAgentInventoryResponder(body, asset_id, LLAssetType::AT_NOTECARD)); +			} +			else if (!mObjectUUID.isNull() && !task_url.empty()) +			{ +				// Saving into task inventory +				mAssetStatus = PREVIEW_ASSET_LOADING; +				setEnabled(FALSE); +				LLSD body; +				body["task_id"] = mObjectUUID; +				body["item_id"] = mItemUUID; +				llinfos << "Saving notecard " << mItemUUID << " into task " +					<< mObjectUUID << " via " << task_url << llendl; +				LLHTTPClient::post(task_url, body, +					new LLUpdateTaskInventoryResponder(body, asset_id, LLAssetType::AT_NOTECARD)); +			} +			else if (gAssetStorage) +			{ +				LLSaveNotecardInfo* info = new LLSaveNotecardInfo(this, mItemUUID, mObjectUUID, +																tid, copyitem); +				gAssetStorage->storeAssetData(tid, LLAssetType::AT_NOTECARD, +												&onSaveComplete, +												(void*)info, +												FALSE); +			}  		}  	}  	return true; diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h index 3bb3da5f54..730c56833a 100644 --- a/indra/newview/llpreviewnotecard.h +++ b/indra/newview/llpreviewnotecard.h @@ -50,6 +50,14 @@ public:  	const LLInventoryItem* getDragItem(); +	// return true if there is any embedded inventory. +	bool hasEmbeddedInventory(); + +	// After saving a notecard, the tcp based upload system will +	// change the asset, therefore, we need to re-fetch it from the +	// asset system. :( +	void refreshFromInventory(); +  protected:  	virtual void loadAsset(); diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 479f1b1812..a7d29a6591 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -11,6 +11,7 @@  #include "llpreviewscript.h"  #include "llassetstorage.h" +#include "llassetuploadresponders.h"  #include "llbutton.h"  #include "llcheckboxctrl.h"  #include "llcombobox.h" @@ -832,6 +833,33 @@ LLPreviewLSL::LLPreviewLSL(const std::string& name, const LLRect& rect,  	}  } +// virtual +void LLPreviewLSL::callbackLSLCompileSucceeded() +{ +	llinfos << "LSL Bytecode saved" << llendl; +	mScriptEd->mErrorList->addSimpleItem("Compile successful!"); +	mScriptEd->mErrorList->addSimpleItem("Save complete."); +	closeIfNeeded(); +} + +// virtual +void LLPreviewLSL::callbackLSLCompileFailed(const LLSD& compile_errors) +{ +	llinfos << "Compile failed!" << llendl; + +	const LLFontGL* err_font = gResMgr->getRes(LLFONT_OCRA); +	LLScrollListItem* item = NULL; +	for(LLSD::array_const_iterator line = compile_errors.beginArray(); +		line < compile_errors.endArray(); +		line++) +	{ +		item = new LLScrollListItem(); +		item->addColumn(line->asString(), err_font); +		mScriptEd->mErrorList->addItem(item); +	} +	mScriptEd->selectFirstError(); +	closeIfNeeded(); +}  void LLPreviewLSL::loadAsset()  { @@ -893,6 +921,17 @@ BOOL LLPreviewLSL::canClose()  	return mScriptEd->canClose();  } +void LLPreviewLSL::closeIfNeeded() +{ +	// Find our window and close it if requested. +	getWindow()->decBusyCount(); +	mPendingUploads--; +	if (mPendingUploads <= 0 && mCloseAfterSave) +	{ +		close(); +	} +} +  //override the llpreview open which attempts to load asset, load after xml ui made  void LLPreviewLSL::open()		/*Flawfinder: ignore*/  { @@ -914,152 +953,152 @@ void LLPreviewLSL::onSave(void* userdata, BOOL close_after_save)  	self->saveIfNeeded();  } -  // Save needs to compile the text in the buffer. If the compile  // succeeds, then save both assets out to the database. If the compile  // fails, go ahead and save the text anyway so that the user doesn't  // get too fucked.  void LLPreviewLSL::saveIfNeeded()  { -	// llinfos << "LLPreviewLSL::save()" << llendl; -	if(!mScriptEd->mEditor->isPristine()) +	// llinfos << "LLPreviewLSL::saveIfNeeded()" << llendl; +	if(mScriptEd->mEditor->isPristine())  	{ -		mPendingUploads = 0; -		mScriptEd->mErrorList->deleteAllItems(); -		mScriptEd->mEditor->makePristine(); - -		// We need to update the asset information -		LLTransactionID tid; -		LLAssetID uuid; -		tid.generate(); -		uuid = tid.makeAssetID(gAgent.getSecureSessionID()); -		char uuid_string[UUID_STR_LENGTH];		/*Flawfinder: ignore*/ -		uuid.toString(uuid_string); -		char filename[LL_MAX_PATH];		/*Flawfinder: ignore*/ -		snprintf(filename, LL_MAX_PATH, "%s.lsl", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/ -		FILE* fp = LLFile::fopen(filename, "wb");		/*Flawfinder: ignore*/ -		if(!fp) -		{ -			llwarns << "Unable to write to " << filename << llendl; -			LLScrollListItem* item = new LLScrollListItem(); -			item->addColumn("Error writing to local file. Is your hard drive full?", LLFontGL::sSansSerifSmall); -			mScriptEd->mErrorList->addItem(item); -			return; -		} +		return; +	} -		LLString utf8text = mScriptEd->mEditor->getText(); -		//fprintf(fp, "%s|%s\n", LLAssetType::lookup(LLAssetType::AT_LSL_TEXT), -		//uuid_string); -		//fprintf(fp,"{\n%s}\n", text.c_str()); -		fputs(utf8text.c_str(), fp); -		fclose(fp); -		fp = NULL; +	mPendingUploads = 0; +	mScriptEd->mErrorList->deleteAllItems(); +	mScriptEd->mEditor->makePristine(); -		// also write it out to the vfs for upload -		LLVFile file(gVFS, uuid, LLAssetType::AT_LSL_TEXT, LLVFile::APPEND); -		S32 size = utf8text.length() + 1; +	// save off asset into file +	LLTransactionID tid; +	tid.generate(); +	LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); +	std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id.asString()); +	std::string filename = llformat("%s.lsl", filepath.c_str()); -		file.setMaxSize(size); -		file.write((U8*)utf8text.c_str(), size); +	FILE* fp = LLFile::fopen(filename.c_str(), "wb"); +	if(!fp) +	{ +		llwarns << "Unable to write to " << filename << llendl; +		LLScrollListItem* item = new LLScrollListItem(); +		item->addColumn("Error writing to local file. Is your hard drive full?", LLFontGL::sSansSerifSmall); +		mScriptEd->mErrorList->addItem(item); +		return; +	} -		LLInventoryItem *inv_item = getItem(); +	LLString utf8text = mScriptEd->mEditor->getText(); +	fputs(utf8text.c_str(), fp); +	fclose(fp); +	fp = NULL; -		// save it out to database -		if(gAssetStorage && inv_item) +	LLInventoryItem *inv_item = getItem(); +	// save it out to asset server +	std::string url = gAgent.getRegion()->getCapability("UpdateScriptAgentInventory"); +	if(inv_item) +	{ +		getWindow()->incBusyCount(); +		mPendingUploads++; +		if (!url.empty())  		{ -			getWindow()->incBusyCount(); -			mPendingUploads++; -			LLScriptSaveInfo* info = NULL; +			uploadAssetViaCaps(url, filename, mItemUUID); +		} +		else if (gAssetStorage) +		{ +			uploadAssetLegacy(filename, mItemUUID, tid); +		} +	} +} -			LLLineEditor* descEditor = LLUICtrlFactory::getLineEditorByName(this, "desc"); +void LLPreviewLSL::uploadAssetViaCaps(const std::string& url, +									  const std::string& filename, +									  const LLUUID& item_id) +{ +	llinfos << "Update Agent Inventory via capability" << llendl; +	LLSD body; +	body["item_id"] = item_id; +	LLHTTPClient::post(url, body, new LLUpdateAgentInventoryResponder(body, filename)); +} -			info = new LLScriptSaveInfo(mItemUUID, -										descEditor->getText(), -										tid); -			gAssetStorage->storeAssetData(tid, LLAssetType::AT_LSL_TEXT, &LLPreviewLSL::onSaveComplete, info); -		} +void LLPreviewLSL::uploadAssetLegacy(const std::string& filename, +									  const LLUUID& item_id, +									  const LLTransactionID& tid) +{ +	LLLineEditor* descEditor = LLUICtrlFactory::getLineEditorByName(this, "desc"); +	LLScriptSaveInfo* info = new LLScriptSaveInfo(item_id, +								descEditor->getText(), +								tid); +	gAssetStorage->storeAssetData(filename.c_str(),	tid, +								  LLAssetType::AT_LSL_TEXT, +								  &LLPreviewLSL::onSaveComplete, +								  info); -		char dst_filename[LL_MAX_PATH];		/*Flawfinder: ignore*/ -		snprintf(dst_filename, LL_MAX_PATH, "%s.lso", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/ -		char err_filename[LL_MAX_PATH];		/*Flawfinder: ignore*/ -		snprintf(err_filename, LL_MAX_PATH, "%s.out", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/ -		LLScrollListItem* item = NULL; -		const LLFontGL* err_font = gResMgr->getRes(LLFONT_OCRA); -		if(!lscript_compile(filename, dst_filename, err_filename, gAgent.isGodlike())) -		{ -			llinfos << "Compile failed!" << llendl; -			//char command[256]; -			//sprintf(command, "type %s\n", err_filename); -			//system(command); +	LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); +	std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id.asString()); +	std::string dst_filename = llformat("%s.lso", filepath.c_str()); +	std::string err_filename = llformat("%s.out", filepath.c_str()); -			// load the error file into the error scrolllist -			if(NULL != (fp = LLFile::fopen(err_filename, "r")))		/*Flawfinder: ignore*/ +	LLScrollListItem* item = NULL; +	const LLFontGL* err_font = gResMgr->getRes(LLFONT_OCRA); +	if(!lscript_compile(filename.c_str(), +						dst_filename.c_str(), +						err_filename.c_str(), +						gAgent.isGodlike())) +	{ +		llinfos << "Compile failed!" << llendl; +		//char command[256]; +		//sprintf(command, "type %s\n", err_filename); +		//system(command); + +		// load the error file into the error scrolllist +		FILE* fp = LLFile::fopen(err_filename.c_str(), "r"); +		if(fp) +		{ +			char buffer[MAX_STRING];		/*Flawfinder: ignore*/ +			LLString line; +			while(!feof(fp))   			{ -				char buffer[MAX_STRING];		/*Flawfinder: ignore*/ -				LLString line; -				while(!feof(fp))  +				fgets(buffer, MAX_STRING, fp); +				if(feof(fp))  				{ -					 -					fgets(buffer, MAX_STRING, fp); -					if(feof(fp)) -					{ -						break; -					} -					else if(!buffer) -					{ -						continue; -					} -					else -					{ -						line.assign(buffer); -						LLString::stripNonprintable(line); -						item = new LLScrollListItem(); -						item->addColumn(line, err_font); -						mScriptEd->mErrorList->addItem(item); -					} +					break;  				} -				fclose(fp); -				mScriptEd->selectFirstError(); -			} -		} -		else -		{ -			llinfos << "Compile worked!" << llendl; -			if(gAssetStorage) -			{ -				// move the compiled file into the vfs for transport -				FILE* fp = LLFile::fopen(dst_filename, "rb");			/*Flawfinder: ignore*/ -				LLVFile file(gVFS, uuid, LLAssetType::AT_LSL_BYTECODE, LLVFile::APPEND); - -				fseek(fp, 0, SEEK_END); -				S32 size = ftell(fp); -				fseek(fp, 0, SEEK_SET); - -				file.setMaxSize(size); - -				const S32 buf_size = 65536; -				U8 copy_buf[buf_size]; -				while ((size = fread(copy_buf, 1, buf_size, fp))) +				else if(!buffer)  				{ -					file.write(copy_buf, size); +					continue; +				} +				else +				{ +					line.assign(buffer); +					LLString::stripNonprintable(line); +					item = new LLScrollListItem(); +					item->addColumn(line, err_font); +					mScriptEd->mErrorList->addItem(item);  				} -				fclose(fp); -				fp = NULL; -				getWindow()->incBusyCount(); -				mPendingUploads++; -				LLUUID* this_uuid = new LLUUID(mItemUUID); -				gAssetStorage->storeAssetData(tid, -											  LLAssetType::AT_LSL_BYTECODE, -											  &LLPreviewLSL::onSaveBytecodeComplete, -											  (void**)this_uuid);  			} +			fclose(fp); +			mScriptEd->selectFirstError();  		} - -		// get rid of any temp files left lying around -		LLFile::remove(filename); -		LLFile::remove(err_filename); -		LLFile::remove(dst_filename);  	} +	else +	{ +		llinfos << "Compile worked!" << llendl; +		if(gAssetStorage) +		{ +			getWindow()->incBusyCount(); +			mPendingUploads++; +			LLUUID* this_uuid = new LLUUID(mItemUUID); +			gAssetStorage->storeAssetData(dst_filename.c_str(), +										  tid, +										  LLAssetType::AT_LSL_BYTECODE, +										  &LLPreviewLSL::onSaveBytecodeComplete, +										  (void**)this_uuid); +		} +	} + +	// get rid of any temp files left lying around +	LLFile::remove(filename.c_str()); +	LLFile::remove(err_filename.c_str()); +	LLFile::remove(dst_filename.c_str());  } @@ -1333,6 +1372,35 @@ void LLLiveLSLEditor::loadAsset()  	loadAsset(FALSE);  } +// virtual +void LLLiveLSLEditor::callbackLSLCompileSucceeded(const LLUUID& task_id, +												  const LLUUID& item_id, +												  bool is_script_running) +{ +	lldebugs << "LSL Bytecode saved" << llendl; +	mScriptEd->mErrorList->addSimpleItem("Compile successful!"); +	mScriptEd->mErrorList->addSimpleItem("Save complete."); +	closeIfNeeded(); +} + +// virtual +void LLLiveLSLEditor::callbackLSLCompileFailed(const LLSD& compile_errors) +{ +	lldebugs << "Compile failed!" << llendl; +	const LLFontGL* err_font = gResMgr->getRes(LLFONT_OCRA); +	LLScrollListItem* item = NULL; +	for(LLSD::array_const_iterator line = compile_errors.beginArray(); +		line < compile_errors.endArray(); +		line++) +	{ +		item = new LLScrollListItem(); +		item->addColumn(line->asString(), err_font); +		mScriptEd->mErrorList->addItem(item); +	} +	mScriptEd->selectFirstError(); +	closeIfNeeded(); +} +  void LLLiveLSLEditor::loadAsset(BOOL is_new)  {  	//llinfos << "LLLiveLSLEditor::loadAsset()" << llendl; @@ -1676,18 +1744,16 @@ void LLLiveLSLEditor::saveIfNeeded()  	// set up the save on the local machine.  	mScriptEd->mEditor->makePristine();  	LLTransactionID tid; -	LLAssetID uuid;  	tid.generate(); -	uuid = tid.makeAssetID(gAgent.getSecureSessionID()); -	mItem->setAssetUUID(uuid); +	LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); +	std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id.asString()); +	std::string filename = llformat("%s.lsl", filepath.c_str()); + +	mItem->setAssetUUID(asset_id);  	mItem->setTransactionID(tid);  	// write out the data, and store it in the asset database -	char uuid_string[UUID_STR_LENGTH];		/*Flawfinder: ignore*/ -	uuid.toString(uuid_string); -	char filename[LL_MAX_PATH];		/*Flawfinder: ignore*/ -	snprintf(filename, LL_MAX_PATH, "%s.lsl", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/ -	FILE* fp = LLFile::fopen(filename, "wb");		/*Flawfinder: ignore*/ +	FILE* fp = LLFile::fopen(filename.c_str(), "wb");  	if(!fp)  	{  		llwarns << "Unable to write to " << filename << llendl; @@ -1699,63 +1765,69 @@ void LLLiveLSLEditor::saveIfNeeded()  	LLString utf8text = mScriptEd->mEditor->getText();  	fputs(utf8text.c_str(), fp);  	fclose(fp); - -	LLCheckBoxCtrl* runningCheckbox = LLUICtrlFactory::getCheckBoxByName(this, "running"); +	fp = NULL; -	// save it out to database -	if(gAssetStorage) +	// save it out to asset server +	std::string url = gAgent.getRegion()->getCapability("UpdateScriptTaskInventory"); +	getWindow()->incBusyCount(); +	mPendingUploads++; +	BOOL is_running = LLUICtrlFactory::getCheckBoxByName(this, "running")->get(); +	if (!url.empty())  	{ -		// write it out to the vfs for upload -		LLVFile file(gVFS, uuid, LLAssetType::AT_LSL_TEXT, LLVFile::APPEND); -		S32 size = utf8text.length() + 1; - -		file.setMaxSize(size); -		file.write((U8*)utf8text.c_str(), size); - -		getWindow()->incBusyCount(); -		mPendingUploads++; -		LLLiveLSLSaveData* data = new LLLiveLSLSaveData(mObjectID, -														mItem, -														runningCheckbox->get()); -		gAssetStorage->storeAssetData(tid, LLAssetType::AT_LSL_TEXT, &onSaveTextComplete, (void*)data, FALSE); +		uploadAssetViaCaps(url, filename, mObjectID, +						   mItemID, is_running);  	} - -#if LL_WINDOWS -	// This major hack was inserted because sometimes compilation -	// would fail because it couldn't open this file... I decided -	// to make a loop until open was successful. This seems to be -	// a problem specific to ntfs. -	fp = NULL; -	const U32 MAX_TRIES = 20; -	U32 tries = MAX_TRIES; -	while((!fp) && --tries) +	else if (gAssetStorage)  	{ -		ms_sleep(17); -		fp = LLFile::fopen(filename, "r");		/*Flawfinder: ignore*/ -		if(!fp) -		{ -			llwarns << "Trying to open the source file " << filename -					<< " again" << llendl; -		} -		else -		{ -			fclose(fp); -		} +		uploadAssetLegacy(filename, object, tid, is_running);  	} -	fp = NULL; -#endif +} + +void LLLiveLSLEditor::uploadAssetViaCaps(const std::string& url, +										 const std::string& filename, +										 const LLUUID& task_id, +										 const LLUUID& item_id, +										 BOOL is_running) +{ +	llinfos << "Update Task Inventory via capability" << llendl; +	LLSD body; +	body["task_id"] = task_id; +	body["item_id"] = item_id; +	body["is_script_running"] = is_running; +	LLHTTPClient::post(url, body, +		new LLUpdateTaskInventoryResponder(body, filename)); +} + +void LLLiveLSLEditor::uploadAssetLegacy(const std::string& filename, +										LLViewerObject* object, +										const LLTransactionID& tid, +										BOOL is_running) +{ +	LLLiveLSLSaveData* data = new LLLiveLSLSaveData(mObjectID, +													mItem, +													is_running); +	gAssetStorage->storeAssetData(filename.c_str(), tid, +								  LLAssetType::AT_LSL_TEXT, +								  &onSaveTextComplete, +								  (void*)data, +								  FALSE); + +	LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); +	std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id.asString()); +	std::string dst_filename = llformat("%s.lso", filepath.c_str()); +	std::string err_filename = llformat("%s.out", filepath.c_str()); -	char dst_filename[LL_MAX_PATH];		/*Flawfinder: ignore*/ -	snprintf(dst_filename, LL_MAX_PATH, "%s.lso", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/ -	char err_filename[LL_MAX_PATH];		/*Flawfinder: ignore*/ -	snprintf(err_filename, LL_MAX_PATH, "%s.out", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/  	LLScrollListItem* item = NULL;  	const LLFontGL* err_font = gResMgr->getRes(LLFONT_OCRA); -	if(!lscript_compile(filename, dst_filename, err_filename, gAgent.isGodlike())) +	FILE *fp; +	if(!lscript_compile(filename.c_str(), +						dst_filename.c_str(), +						err_filename.c_str(), +						gAgent.isGodlike()))  	{  		// load the error file into the error scrolllist  		llinfos << "Compile failed!" << llendl; -		if(NULL != (fp = LLFile::fopen(err_filename, "r")))		/*Flawfinder: ignore*/ +		if(NULL != (fp = LLFile::fopen(err_filename.c_str(), "r")))  		{  			char buffer[MAX_STRING];		/*Flawfinder: ignore*/  			LLString line; @@ -1797,33 +1869,14 @@ void LLLiveLSLEditor::saveIfNeeded()  		{  			llinfos << "LLLiveLSLEditor::saveAsset "  					<< mItem->getAssetUUID() << llendl; - -			// move the compiled file into the vfs for transport -			FILE* fp = LLFile::fopen(dst_filename, "rb");		/*Flawfinder: ignore*/ -			LLVFile file(gVFS, uuid, LLAssetType::AT_LSL_BYTECODE, LLVFile::APPEND); - -			fseek(fp, 0, SEEK_END); -			S32 size = ftell(fp); -			fseek(fp, 0, SEEK_SET); - -			file.setMaxSize(size); - -			const S32 buf_size = 65536; -			U8 copy_buf[buf_size]; -			while ((size = fread(copy_buf, 1, buf_size, fp))) -			{ -				file.write(copy_buf, size); -			} -			fclose(fp); -			fp = NULL; -  			getWindow()->incBusyCount();  			mPendingUploads++;  			LLLiveLSLSaveData* data = NULL;  			data = new LLLiveLSLSaveData(mObjectID,  										 mItem, -										 runningCheckbox->get()); -			gAssetStorage->storeAssetData(tid, +										 is_running); +			gAssetStorage->storeAssetData(dst_filename.c_str(), +										  tid,  										  LLAssetType::AT_LSL_BYTECODE,  										  &LLLiveLSLEditor::onSaveBytecodeComplete,  										  (void*)data); @@ -1832,11 +1885,12 @@ void LLLiveLSLEditor::saveIfNeeded()  	}  	// get rid of any temp files left lying around -	LLFile::remove(filename); -	LLFile::remove(err_filename); -	LLFile::remove(dst_filename); +	LLFile::remove(filename.c_str()); +	LLFile::remove(err_filename.c_str()); +	LLFile::remove(dst_filename.c_str());  	// If we successfully saved it, then we should be able to check/uncheck the running box! +	LLCheckBoxCtrl* runningCheckbox = LLUICtrlFactory::getCheckBoxByName(this, "running");  	runningCheckbox->setLabel(ENABLED_RUNNING_CHECKBOX_LABEL);  	runningCheckbox->setEnabled(TRUE);  } @@ -1912,13 +1966,10 @@ void LLLiveLSLEditor::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* use  		args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));  		gViewerWindow->alertXml("CompileQueueSaveBytecode", args);  	} -	char uuid_string[UUID_STR_LENGTH];		/*Flawfinder: ignore*/ -	data->mItem->getAssetUUID().toString(uuid_string); -	char dst_filename[LL_MAX_PATH];		/*Flawfinder: ignore*/ -	snprintf(dst_filename, LL_MAX_PATH, "%s.lso", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/ -	LLFile::remove(dst_filename); -	snprintf(dst_filename, LL_MAX_PATH, "%s.lsl", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/ -	LLFile::remove(dst_filename); + +	std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_uuid.asString()); +	std::string dst_filename = llformat("%s.lso", filepath.c_str()); +	LLFile::remove(dst_filename.c_str());  	delete data;  } @@ -1927,6 +1978,16 @@ BOOL LLLiveLSLEditor::canClose()  	return (mScriptEd->canClose());  } +void LLLiveLSLEditor::closeIfNeeded() +{ +	getWindow()->decBusyCount(); +	mPendingUploads--; +	if (mPendingUploads <= 0 && mCloseAfterSave) +	{ +		close(); +	} +} +  // static  void LLLiveLSLEditor::onLoad(void* userdata)  { @@ -1970,6 +2031,13 @@ void LLLiveLSLEditor::hide(const LLUUID& script_id, const LLUUID& object_id)  		delete instance;  	}  } +// static +LLLiveLSLEditor* LLLiveLSLEditor::find(const LLUUID& script_id, const LLUUID& object_id) +{ +	LLUUID xored_id = script_id ^ object_id; +	return sInstances.getIfThere(xored_id); +} +  // static  void LLLiveLSLEditor::processScriptRunningReply(LLMessageSystem* msg, void**) diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index 9b2beb9ce9..5b15fda222 100644 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -116,15 +116,24 @@ class LLPreviewLSL : public LLPreview  public:  	LLPreviewLSL(const std::string& name, const LLRect& rect, const std::string& title,  				 const LLUUID& item_uuid ); +	virtual void callbackLSLCompileSucceeded(); +	virtual void callbackLSLCompileFailed(const LLSD& compile_errors);  	/*virtual*/ void open();		/*Flawfinder: ignore*/  protected:  	virtual BOOL canClose(); +	void closeIfNeeded();  	virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);  	virtual void loadAsset();  	void saveIfNeeded(); +	void uploadAssetViaCaps(const std::string& url, +							const std::string& filename,  +							const LLUUID& item_id); +	void uploadAssetLegacy(const std::string& filename, +							const LLUUID& item_id, +							const LLTransactionID& tid);  	static void onLoad(void* userdata);  	static void onSave(void* userdata, BOOL close_after_save); @@ -158,17 +167,33 @@ public:  	static LLLiveLSLEditor* show(const LLUUID& item_id, const LLUUID& object_id);  	static void hide(const LLUUID& item_id, const LLUUID& object_id); +	static LLLiveLSLEditor* find(const LLUUID& item_id, const LLUUID& object_id);  	static void processScriptRunningReply(LLMessageSystem* msg, void**); -	 + +	virtual void callbackLSLCompileSucceeded(const LLUUID& task_id, +											const LLUUID& item_id, +											bool is_script_running); +	virtual void callbackLSLCompileFailed(const LLSD& compile_errors); +  protected:  	virtual BOOL canClose(); +	void closeIfNeeded();  	virtual void draw();  	virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);  	virtual void loadAsset();  	void loadAsset(BOOL is_new);  	void saveIfNeeded(); +	void uploadAssetViaCaps(const std::string& url, +							const std::string& filename,  +							const LLUUID& task_id, +							const LLUUID& item_id, +							BOOL is_running); +	void uploadAssetLegacy(const std::string& filename, +						   LLViewerObject* object, +						   const LLTransactionID& tid, +						   BOOL is_running);  	static void onLoad(void* userdata);  	static void onSave(void* userdata, BOOL close_after_save); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index e6c6576ae1..f8cc68d683 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -833,6 +833,7 @@ BOOL idle_startup()  		case USERSERVER_SHAKTI:  		case USERSERVER_DURGA:  		case USERSERVER_SOMA: +		case USERSERVER_VAAK:  		case USERSERVER_GANGA:  		case USERSERVER_UMA:  		{ @@ -2557,6 +2558,7 @@ void login_show()  	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_GANGA].mLabel,	USERSERVER_GANGA );  	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_UMA].mLabel,	USERSERVER_UMA );  	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_SOMA].mLabel,	USERSERVER_SOMA ); +	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_VAAK].mLabel,	USERSERVER_VAAK );  }  // Callback for when login screen is closed.  Option 0 = connect, option 1 = quit. diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 9ac566b02b..a638d99381 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -273,6 +273,7 @@ BOOL enable_save_as(void *);  // Edit menu  void handle_dump_group_info(void *); +void handle_dump_capabilities_info(void *);  void handle_dump_focus(void*);  void handle_region_dump_settings(void*); @@ -716,6 +717,8 @@ void init_client_menu(LLMenuGL* menu)  			&handle_region_dump_settings, NULL));  		sub->append(new LLMenuItemCallGL("Group Info to Debug Console",  			&handle_dump_group_info, NULL, NULL)); +		sub->append(new LLMenuItemCallGL("Capabilities Info to Debug Console", +			&handle_dump_capabilities_info, NULL, NULL));  		sub->createJumpKeys();  	} @@ -2451,6 +2454,14 @@ void handle_dump_group_info(void *)  	//llinfos << "insig   " << gAgent.mGroupInsigniaID << llendl;  } +void handle_dump_capabilities_info(void *) +{ +	LLViewerRegion* regionp = gAgent.getRegion(); +	if (regionp) +	{ +		regionp->logActiveCapabilities(); +	} +}  void handle_dump_focus(void *)  { @@ -5689,7 +5700,7 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty  	llinfos << "Desc: " << desc << llendl;  	lldebugs << "Folder: " << gInventory.findCategoryUUIDForType(destination_folder_type) << llendl;  	lldebugs << "Asset Type: " << LLAssetType::lookup(asset_type) << llendl; -	std::string url = gAgent.getRegion()->getCapability("NewAgentInventory"); +	std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory");  	if (!url.empty())  	{  		llinfos << "New Agent Inventory via capability" << llendl; @@ -5703,7 +5714,7 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty  		std::ostringstream llsdxml;  		LLSDSerialize::toXML(body, llsdxml);  		lldebugs << "posting body to capability: " << llsdxml.str() << llendl; -		LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(uuid, body)); +		LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, uuid, asset_type));  	}  	else  	{ diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp index 189b314e55..f62949cadf 100644 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -46,6 +46,10 @@ LLUserServerData gUserServerDomainName[USERSERVER_COUNT] =  	  "userserver.ganga.lindenlab.com",  	  "https://login.ganga.lindenlab.com/cgi-bin/login.cgi",  	  "http://ganga-secondlife.webdev.lindenlab.com/helpers/" }, +	{ "Vaak", +	  "userserver.vaak.lindenlab.com", +	  "https://login.vaak.lindenlab.com/cgi-bin/login.cgi", +	  "http://vaak-secondlife.webdev.lindenlab.com/helpers/" },  	{ "Uma",  	  "userserver.uma.lindenlab.com",  	  "https://login.uma.lindenlab.com/cgi-bin/login.cgi", diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h index d461369d02..9eb2d9fcdd 100644 --- a/indra/newview/llviewernetwork.h +++ b/indra/newview/llviewernetwork.h @@ -23,6 +23,7 @@ enum EUserServerDomain  	USERSERVER_SHAKTI,  	USERSERVER_SOMA,  	USERSERVER_GANGA, +	USERSERVER_VAAK,  	USERSERVER_UMA,  	USERSERVER_LOCAL,  	USERSERVER_OTHER, // IP address set via -user or other command line option diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 6a20aa4a95..a09ce3011f 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -2323,41 +2323,45 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data)  	LLUUID task_id;  	msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_TaskID, task_id);  	LLViewerObject* object = gObjectList.findObject(task_id); -	if(object) +	if(!object)  	{ -		msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, object->mInventorySerialNum); -		LLFilenameAndTask* ft = new LLFilenameAndTask; -		ft->mTaskID = task_id; -		msg->getStringFast(_PREHASH_InventoryData, _PREHASH_Filename, MAX_STRING, ft->mFilename); -		if(!ft->mFilename[0]) +		llwarns << "LLViewerObject::processTaskInv object " +			<< task_id << " does not exist." << llendl; +		return; +	} + +	msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, object->mInventorySerialNum); +	LLFilenameAndTask* ft = new LLFilenameAndTask; +	ft->mTaskID = task_id; +	msg->getStringFast(_PREHASH_InventoryData, _PREHASH_Filename, MAX_STRING, ft->mFilename); +	if(!ft->mFilename[0]) +	{ +		lldebugs << "Task has no inventory" << llendl; +		// mock up some inventory to make a drop target. +		if(object->mInventory)  		{ -			lldebugs << "Task has no inventory" << llendl; -			// mock up some inventory to make a drop target. -			if(object->mInventory) -			{ -				object->mInventory->clear(); // will deref and delete it -			} -			else -			{ -				object->mInventory = new InventoryObjectList(); -			} -			LLPointer<LLInventoryObject> obj; -			obj = new LLInventoryObject(object->mID, LLUUID::null, -										LLAssetType::AT_CATEGORY, -										"Contents"); -			object->mInventory->push_front(obj); -			object->doInventoryCallback(); -			delete ft; -			return; +			object->mInventory->clear(); // will deref and delete it  		} -		gXferManager->requestFile(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ft->mFilename).c_str(),  -								  ft->mFilename, LL_PATH_CACHE, -								  object->mRegionp->getHost(), -								  TRUE, -								  &LLViewerObject::processTaskInvFile, -								  (void**)ft, -								  LLXferManager::HIGH_PRIORITY); +		else +		{ +			object->mInventory = new InventoryObjectList(); +		} +		LLPointer<LLInventoryObject> obj; +		obj = new LLInventoryObject(object->mID, LLUUID::null, +									LLAssetType::AT_CATEGORY, +									"Contents"); +		object->mInventory->push_front(obj); +		object->doInventoryCallback(); +		delete ft; +		return;  	} +	gXferManager->requestFile(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ft->mFilename).c_str(),  +								ft->mFilename, LL_PATH_CACHE, +								object->mRegionp->getHost(), +								TRUE, +								&LLViewerObject::processTaskInvFile, +								(void**)ft, +								LLXferManager::HIGH_PRIORITY);  }  void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code) @@ -2582,6 +2586,18 @@ LLViewerInventoryItem* LLViewerObject::getInventoryItemByAsset(const LLUUID& ass  	return rv;  } +void LLViewerObject::updateViewerInventoryAsset( +					const LLViewerInventoryItem* item, +					const LLUUID& new_asset) +{ +	LLPointer<LLViewerInventoryItem> task_item = +		new LLViewerInventoryItem(item); +	task_item->setAssetUUID(new_asset); + +	// do the internal logic +	doUpdateInventory(task_item, TASK_INVENTORY_ITEM_KEY, false); +} +  void LLViewerObject::setPixelAreaAndAngle(LLAgent &agent)  {  	if (getVolume()) diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index d8b5a14897..80d3240904 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -363,6 +363,11 @@ public:  	LLViewerInventoryItem* getInventoryItemByAsset(const LLUUID& asset_id);  	S16 getInventorySerial() const { return mInventorySerialNum; } +	// These functions does viewer-side only object inventory modifications +	void updateViewerInventoryAsset( +		const LLViewerInventoryItem* item, +		const LLUUID& new_asset); +  	// This function will make sure that we refresh the inventory.  	void dirtyInventory();  	BOOL isInventoryDirty() { return mInventoryDirty; } diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 5235410156..262c7d8ed7 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1260,8 +1260,19 @@ void LLViewerRegion::setSeedCapability(const std::string& url)  	LLSD capabilityNames = LLSD::emptyArray();  	capabilityNames.append("MapLayer");  	capabilityNames.append("MapLayerGod"); -	capabilityNames.append("NewAgentInventory"); +	capabilityNames.append("NewFileAgentInventory");  	capabilityNames.append("EventQueueGet"); +	capabilityNames.append("UpdateGestureAgentInventory"); +	capabilityNames.append("UpdateNotecardAgentInventory"); +	capabilityNames.append("UpdateScriptAgentInventory"); +	capabilityNames.append("UpdateGestureTaskInventory"); +	capabilityNames.append("UpdateNotecardTaskInventory"); +	capabilityNames.append("UpdateScriptTaskInventory"); +	capabilityNames.append("SendPostcard"); +	capabilityNames.append("ViewerStartAuction"); +	capabilityNames.append("ParcelGodReserveForNewbie"); +	capabilityNames.append("SendUserReport"); +	capabilityNames.append("SendUserReportWithScreenshot");  	capabilityNames.append("RequestTextureDownload");  	LLHTTPClient::post(url, capabilityNames, BaseCapabilitiesComplete::build(this));  } @@ -1304,3 +1315,16 @@ std::string LLViewerRegion::getCapability(const std::string& name) const  	return iter->second;  } +void LLViewerRegion::logActiveCapabilities() const +{ +	CapabilityMap::const_iterator iter; +	for (iter = mCapabilities.begin(); iter != mCapabilities.end(); iter++) +	{ +		if (!iter->second.empty()) +		{ +			// llinfos << "Active capability is " << iter->first << llendl; +			llinfos << iter->first << " URL is " << iter->second << llendl; +		} +	} +} + diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index b3392baf81..1dc1b3af20 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -169,6 +169,7 @@ public:  	void setSeedCapability(const std::string& url);  	void setCapability(const std::string& name, const std::string& url);  	std::string getCapability(const std::string& name) const; +	void logActiveCapabilities() const;  	const LLHost	&getHost() const			{ return mHost; }  	const U64 		&getHandle() const 			{ return mHandle; } diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 7d04f04528..259fa09309 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -53,6 +53,9 @@ public:  	LLEmbeddedItems(const LLViewerTextEditor* editor);  	~LLEmbeddedItems();  	void clear(); + +	// return true if there are no embedded items. +	bool empty();  	void	bindEmbeddedChars(const LLFontGL* font);  	void	unbindEmbeddedChars(const LLFontGL* font); @@ -115,6 +118,13 @@ void LLEmbeddedItems::clear()  		removeEmbeddedItem(*nextiter);  	}  	mEmbeddedUsedChars.clear(); +	mEmbeddedIndexedChars.clear(); +} + +bool LLEmbeddedItems::empty() +{ +	removeUnusedChars(); +	return mEmbeddedUsedChars.empty();  }  // Inserts a new unique entry @@ -1367,10 +1377,11 @@ S32 LLViewerTextEditor::insertEmbeddedItem( S32 pos, LLInventoryItem* item )  bool LLViewerTextEditor::importStream(std::istream& str)  { -	LLNotecard nc(MAX_NOTECARD_SIZE); +	LLNotecard nc(LLNotecard::MAX_SIZE);  	bool success = nc.importStream(str);  	if (success)  	{ +		mEmbeddedItemList->clear();  		const std::vector<LLPointer<LLInventoryItem> >& items = nc.getItems();  		mEmbeddedItemList->addItems(items);  		// Actually set the text @@ -1396,6 +1407,11 @@ void LLViewerTextEditor::copyInventory(LLInventoryItem* item)  								 item);  } +bool LLViewerTextEditor::hasEmbeddedInventory() +{ +	return (!(mEmbeddedItemList->empty())); +} +  ////////////////////////////////////////////////////////////////////////////  BOOL LLViewerTextEditor::importBuffer( const LLString& buffer ) @@ -1406,7 +1422,7 @@ BOOL LLViewerTextEditor::importBuffer( const LLString& buffer )  BOOL LLViewerTextEditor::exportBuffer( LLString& buffer )  { -	LLNotecard nc(MAX_NOTECARD_SIZE); +	LLNotecard nc(LLNotecard::MAX_SIZE);  	std::vector<LLPointer<LLInventoryItem> > embedded_items;  	mEmbeddedItemList->getEmbeddedItemList(embedded_items); diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h index 99e971b33c..de57b68e7d 100644 --- a/indra/newview/llviewertexteditor.h +++ b/indra/newview/llviewertexteditor.h @@ -67,7 +67,14 @@ public:  		// If this starts a line, you need to prepend a newline.  	void copyInventory(LLInventoryItem* item); -	 + +	// returns true if there is embedded inventory. +	// *HACK: This is only useful because the notecard verifier may +	// change the asset if there is embedded inventory. This mechanism +	// should be changed to get a different asset id from the verifier +	// rather than checking if a re-load is necessary. Phoenix 2007-02-27 +	bool hasEmbeddedInventory(); +  protected:  	// Embedded object operations  	virtual llwchar	pasteEmbeddedItem(llwchar ext_char); diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index 522e9c9a56..9e85e293d4 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -15,11 +15,13 @@  #include "llquantize.h"  #include "llagent.h" +#include "llassetuploadresponders.h"  #include "llviewerwindow.h"  #include "llfloatercustomize.h"  #include "llinventorymodel.h"  #include "llviewerimagelist.h"  #include "llviewerinventory.h" +#include "llviewerregion.h"  #include "llvoavatar.h"  #include "llwearable.h" @@ -886,11 +888,28 @@ void LLWearable::saveNewAsset()  	// save it out to database  	if( gAssetStorage )  	{ -		LLWearableSaveData* data = new LLWearableSaveData; -		data->mType = mType; -		gAssetStorage->storeAssetData(filename, mTransactionID, getAssetType(), -										&LLWearable::onSaveNewAssetComplete, -										(void*)data); +		 /* +		std::string url = gAgent.getRegion()->getCapability("NewAgentInventory"); +		if (!url.empty()) +		{ +			llinfos << "Update Agent Inventory via capability" << llendl; +			LLSD body; +			body["folder_id"] = gInventory.findCategoryUUIDForType(getAssetType()); +			body["asset_type"] = LLAssetType::lookup(getAssetType()); +			body["inventory_type"] = LLInventoryType::lookup(LLInventoryType::IT_WEARABLE); +			body["name"] = getName(); +			body["description"] = getDescription(); +			LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, filename)); +		} +		else +		{ +		} +		 */ +		 LLWearableSaveData* data = new LLWearableSaveData; +		 data->mType = mType; +		 gAssetStorage->storeAssetData(filename, mTransactionID, getAssetType(), +                                     &LLWearable::onSaveNewAssetComplete, +                                     (void*)data);  	}  } diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 301ab310d9..2c04a34da8 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -324,12 +324,15 @@ class DarwinManifest(ViewerManifest):                  volpath = re.search('HFS\s+(.+)', hdi_output).group(1).strip()                  # Copy everything in to the mounted .dmg -                for s,d in {self.get_dst_prefix():("Second Life " + self.args['grid']).strip()+ ".app", -                                        "lsl_guide.html":"Linden Scripting Language Guide.html", -                                        "releasenotes.txt":"Release Notes.txt", -                                        "installers/darwin/mac_image_hidden":".hidden", -                                        "installers/darwin/mac_image_background.tga":"background.tga", -                                        "installers/darwin/mac_image_DS_Store":".DS_Store"}.items(): +                # TODO change name of .app once mac_updater can handle it. +                for s,d in { +                        self.get_dst_prefix():"Second Life.app", +                        "lsl_guide.html":"Linden Scripting Language Guide.html", +                        "releasenotes.txt":"Release Notes.txt", +                        "installers/darwin/mac_image_hidden":".hidden", +                        "installers/darwin/mac_image_background.tga":"background.tga", +                        "installers/darwin/mac_image_DS_Store":".DS_Store"}.items(): +                                                  print "Copying to dmg", s, d                          self.copy_action(self.src_path_of(s), os.path.join(volpath, d)) | 
