summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Bell <josh@lindenlab.com>2007-03-14 23:03:50 +0000
committerJosh Bell <josh@lindenlab.com>2007-03-14 23:03:50 +0000
commit00dbacb215da8d6b6739b4bcefebee552de89a9c (patch)
treee1256e1fa3b195a1128bb152a876729c7f9a163d
parentcf405184285c25723249d5a023b28d9498cf0c3f (diff)
svn merge svn+ssh://svn.lindenlab.com/svn/linden/release@59161 svn+ssh://svn.lindenlab.com/svn/linden/branches/release-candidate@59163 --> release
-rw-r--r--doc/contributions.txt2
-rw-r--r--indra/llcommon/indra_constants.h1
-rw-r--r--indra/llcommon/llstreamtools.cpp2
-rw-r--r--indra/llcommon/lluri.cpp483
-rw-r--r--indra/llcommon/lluri.h87
-rw-r--r--indra/llinventory/llinventory.cpp60
-rw-r--r--indra/llinventory/llnotecard.cpp5
-rw-r--r--indra/llinventory/llnotecard.h15
-rw-r--r--indra/llmessage/llhttpclient.cpp26
-rw-r--r--indra/llmessage/llhttpclient.h1
-rw-r--r--indra/newview/English.lproj/InfoPlist.strings4
-rw-r--r--indra/newview/Info-SecondLife.plist2
-rw-r--r--indra/newview/llassetuploadresponders.cpp518
-rw-r--r--indra/newview/llassetuploadresponders.h69
-rw-r--r--indra/newview/llfloaterpostcard.cpp44
-rw-r--r--indra/newview/llfloaterreporter.cpp424
-rw-r--r--indra/newview/llfloaterreporter.h12
-rw-r--r--indra/newview/llfloatertos.cpp12
-rw-r--r--indra/newview/llpreviewgesture.cpp34
-rw-r--r--indra/newview/llpreviewnotecard.cpp64
-rw-r--r--indra/newview/llpreviewnotecard.h8
-rw-r--r--indra/newview/llpreviewscript.cpp482
-rw-r--r--indra/newview/llpreviewscript.h27
-rw-r--r--indra/newview/llstartup.cpp2
-rw-r--r--indra/newview/llviewermenu.cpp15
-rw-r--r--indra/newview/llviewernetwork.cpp4
-rw-r--r--indra/newview/llviewernetwork.h1
-rw-r--r--indra/newview/llviewerobject.cpp78
-rw-r--r--indra/newview/llviewerobject.h5
-rw-r--r--indra/newview/llviewerregion.cpp26
-rw-r--r--indra/newview/llviewerregion.h1
-rw-r--r--indra/newview/llviewertexteditor.cpp20
-rw-r--r--indra/newview/llviewertexteditor.h9
-rw-r--r--indra/newview/llwearable.cpp29
-rwxr-xr-xindra/newview/viewer_manifest.py15
35 files changed, 1564 insertions, 1023 deletions
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 8842a9a903..59663640e3 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -4,7 +4,7 @@ along with the issue identifier corresponding to the patches we've
received from them. To see more about these contributions, visit
http://jira.secondlife.com/ , and enter the issue identifier.
-Alissa Sabre - VWR-81, VWR-86
+Alissa Sabre - VWR-81, VWR-83
blino Nakamura - VWR-17
Drewan Keats - VWR-28
Dylan Haskell - VWR-72
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))