svn merge svn+ssh://svn.lindenlab.com/svn/linden/release@59161 svn+ssh://svn.lindenlab.com/svn/linden/branches/release-candidate@59163 --> release
parent
cf40518428
commit
00dbacb215
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
"%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
|
||||
};
|
||||
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
|
||||
{
|
||||
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)
|
||||
|
|
@ -412,57 +225,63 @@ LLURI LLURI::buildHTTP(const std::string& host_port,
|
|||
return result;
|
||||
}
|
||||
|
||||
// static
|
||||
LLURI LLURI::buildHTTP(const std::string& host,
|
||||
const U32& port,
|
||||
const LLSD& path)
|
||||
{
|
||||
return LLURI::buildHTTP(llformat("%s:%u", host.c_str(), port), path);
|
||||
}
|
||||
|
||||
// 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 = "")
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
LLURI LLURI::buildAgentPresenceURI(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("presence");
|
||||
|
||||
return buildHTTP(host, path);
|
||||
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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
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
|
||||
|
||||
// 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& 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);
|
||||
|
||||
// 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);
|
||||
|
||||
// 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
|
||||
|
|
|
|||
|
|
@ -22,6 +22,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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.";
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
mUUID = uuid;
|
||||
mPostData = post_data;
|
||||
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()
|
||||
{
|
||||
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 << "LLAssetUploadResponder::result from capabilities" << llendl;
|
||||
|
||||
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]"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
|
||||
args["[REASON]"] = content["message"].asString();
|
||||
gViewerWindow->alertXml("CannotUploadReason", args);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (!result["success"])
|
||||
{
|
||||
LLStringBase<char>::format_map_t args;
|
||||
args["[FILE]"] = mPostData["inventory_type"].asString();
|
||||
args["[REASON]"] = "the server is experiencing unexpected difficulties";
|
||||
gViewerWindow->alertXml("CannotUploadReason", args);
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
// 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())
|
||||
{
|
||||
// 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")
|
||||
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);
|
||||
}
|
||||
// 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())
|
||||
{
|
||||
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_ALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
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(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)
|
||||
{
|
||||
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))
|
||||
{
|
||||
view->getPanel()->openSelected();
|
||||
}
|
||||
//LLInventoryView::dumpSelectionInformation((void*)view);
|
||||
// restore keyboard focus
|
||||
gFocusMgr.setKeyboardFocus(focus_ctrl, callback);
|
||||
}
|
||||
next_owner_perm = PERM_ALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Can't find a folder to put it in" << llendl;
|
||||
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();
|
||||
|
||||
// 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)
|
||||
// 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)
|
||||
{
|
||||
const char* name = LLFilePicker::instance().getDirname();
|
||||
LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
|
||||
LLFocusMgr::FocusLostCallback callback = gFocusMgr.getFocusCallback();
|
||||
|
||||
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 )
|
||||
view->getPanel()->setSelection(content["new_inventory_item"].asUUID(), TAKE_FOCUS_NO);
|
||||
if((LLAssetType::AT_TEXTURE == asset_type)
|
||||
|| (LLAssetType::AT_SOUND == asset_type))
|
||||
{
|
||||
end_p = asset_name_str + strlen( asset_name_str ); /*Flawfinder: ignore*/
|
||||
view->getPanel()->openSelected();
|
||||
}
|
||||
|
||||
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);
|
||||
//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:
|
||||
{
|
||||
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LLInventoryType::IT_LSL:
|
||||
{
|
||||
// Find our window and close it if requested.
|
||||
LLPreviewLSL* preview = (LLPreviewLSL*)LLPreview::find(item_id);
|
||||
if (preview)
|
||||
{
|
||||
// Bytecode save completed
|
||||
if (content["compiled"])
|
||||
{
|
||||
preview->callbackLSLCompileSucceeded();
|
||||
}
|
||||
else
|
||||
{
|
||||
preview->callbackLSLCompileFailed(content["errors"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LLInventoryType::IT_WEARABLE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data,
|
||||
const LLUUID& vfile_id,
|
||||
LLAssetType::EType asset_type)
|
||||
: LLAssetUploadResponder(post_data, vfile_id, asset_type)
|
||||
{
|
||||
}
|
||||
|
||||
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:
|
||||
{
|
||||
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
// only do this for abuse reports
|
||||
if ( self->mReportType != BUG_REPORT )
|
||||
{
|
||||
if ( ! self->mCopyrightWarningSeen )
|
||||
{
|
||||
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);
|
||||
}
|
||||
self->sendReport();
|
||||
|
||||
if(self->validateReport())
|
||||
{
|
||||
// only show copyright alert for abuse reports
|
||||
if ( self->mReportType != BUG_REPORT )
|
||||
{
|
||||
if ( ! self->mCopyrightWarningSeen )
|
||||
{
|
||||
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;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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());
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterReporter::uploadScreenshot()
|
||||
{
|
||||
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 ) )
|
||||
// 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"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 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 ))
|
||||
{
|
||||
llwarns << "Unable to upload report screenshot " << filename << ":\n\n" << LLImageBase::getLastError() << "\n" << llendl;
|
||||
if(LLFile::remove(temp_filename.c_str()) == -1)
|
||||
if ( mReportType != BUG_REPORT )
|
||||
{
|
||||
lldebugs << "unable to remove temp file" << llendl;
|
||||
}
|
||||
LLFilePicker::instance().reset();
|
||||
}
|
||||
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);
|
||||
if ( gEmailToEstateOwner == FALSE )
|
||||
{
|
||||
screenshot_id = childGetValue("screenshot");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Unknown LLFloaterReporter type" << llendl;
|
||||
}
|
||||
data->mAssetInfo.mCreatorID = gAgentID;
|
||||
data->mAssetInfo.setName("screenshot_name");
|
||||
data->mAssetInfo.setDescription("screenshot_descr");
|
||||
screenshot_id = childGetValue("screenshot");
|
||||
};
|
||||
};
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
gAssetStorage->storeAssetData(temp_filename.c_str(),
|
||||
data->mAssetInfo.mTransactionID,
|
||||
data->mAssetInfo.mType,
|
||||
LLFloaterReporter::uploadDoneCallback,
|
||||
(void*)data, TRUE);
|
||||
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());
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
// 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)
|
||||
{
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
LLUploadDialog::modalUploadFinished();
|
||||
|
||||
LLResourceData* data = (LLResourceData*)user_data;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
delete data;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
LLFloaterReporter *self = getReporter(report_type);
|
||||
if (self)
|
||||
{
|
||||
self->mScreenID = uuid;
|
||||
llinfos << "Got screen shot " << uuid << llendl;
|
||||
self->sendReportViaLegacy(self->gatherReport());
|
||||
}
|
||||
self->close();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
return;
|
||||
}
|
||||
|
||||
// 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)
|
||||
mPendingUploads = 0;
|
||||
mScriptEd->mErrorList->deleteAllItems();
|
||||
mScriptEd->mEditor->makePristine();
|
||||
|
||||
// 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* 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;
|
||||
}
|
||||
|
||||
LLString utf8text = mScriptEd->mEditor->getText();
|
||||
fputs(utf8text.c_str(), fp);
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
|
||||
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())
|
||||
{
|
||||
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;
|
||||
uploadAssetViaCaps(url, filename, mItemUUID);
|
||||
}
|
||||
else if (gAssetStorage)
|
||||
{
|
||||
uploadAssetLegacy(filename, mItemUUID, tid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
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));
|
||||
}
|
||||
|
||||
// also write it out to the vfs for upload
|
||||
LLVFile file(gVFS, uuid, LLAssetType::AT_LSL_TEXT, LLVFile::APPEND);
|
||||
S32 size = utf8text.length() + 1;
|
||||
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);
|
||||
|
||||
file.setMaxSize(size);
|
||||
file.write((U8*)utf8text.c_str(), size);
|
||||
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());
|
||||
|
||||
LLInventoryItem *inv_item = getItem();
|
||||
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);
|
||||
|
||||
// save it out to database
|
||||
if(gAssetStorage && inv_item)
|
||||
// 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))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
mScriptEd->selectFirstError();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
llinfos << "Compile worked!" << llendl;
|
||||
if(gAssetStorage)
|
||||
{
|
||||
getWindow()->incBusyCount();
|
||||
mPendingUploads++;
|
||||
LLScriptSaveInfo* info = NULL;
|
||||
|
||||
LLLineEditor* descEditor = LLUICtrlFactory::getLineEditorByName(this, "desc");
|
||||
|
||||
info = new LLScriptSaveInfo(mItemUUID,
|
||||
descEditor->getText(),
|
||||
tid);
|
||||
gAssetStorage->storeAssetData(tid, LLAssetType::AT_LSL_TEXT, &LLPreviewLSL::onSaveComplete, info);
|
||||
LLUUID* this_uuid = new LLUUID(mItemUUID);
|
||||
gAssetStorage->storeAssetData(dst_filename.c_str(),
|
||||
tid,
|
||||
LLAssetType::AT_LSL_BYTECODE,
|
||||
&LLPreviewLSL::onSaveBytecodeComplete,
|
||||
(void**)this_uuid);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// load the error file into the error scrolllist
|
||||
if(NULL != (fp = LLFile::fopen(err_filename, "r"))) /*Flawfinder: ignore*/
|
||||
{
|
||||
char buffer[MAX_STRING]; /*Flawfinder: ignore*/
|
||||
LLString line;
|
||||
while(!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);
|
||||
}
|
||||
}
|
||||
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)))
|
||||
{
|
||||
file.write(copy_buf, size);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// get rid of any temp files left lying around
|
||||
LLFile::remove(filename);
|
||||
LLFile::remove(err_filename);
|
||||
LLFile::remove(dst_filename);
|
||||
}
|
||||
|
||||
// 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**)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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])
|
||||
{
|
||||
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;
|
||||
}
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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())
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue