summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/bitpack.cpp148
-rw-r--r--indra/llcommon/indra_constants.h6
-rw-r--r--indra/llcommon/llbase32.h38
-rw-r--r--indra/llcommon/llsdserialize_xml.cpp13
-rw-r--r--indra/llcommon/llsdutil.cpp61
-rw-r--r--indra/llcommon/llsdutil.h11
-rw-r--r--indra/llcommon/lluri.cpp40
-rw-r--r--indra/llcommon/lluri.h13
-rw-r--r--indra/llinventory/lleconomy.cpp5
-rw-r--r--indra/llinventory/llinventory.cpp12
-rw-r--r--indra/llinventory/llparcel.cpp13
-rw-r--r--indra/llinventory/llparcel.h5
-rw-r--r--indra/llmath/llvolume.cpp4
-rw-r--r--indra/llmath/llvolume.h28
-rw-r--r--indra/llmessage/llblowfishcipher.cpp48
-rw-r--r--indra/llmessage/llcachename.cpp95
-rw-r--r--indra/llmessage/llcachename.h3
-rw-r--r--indra/llmessage/llhost.cpp2
-rw-r--r--indra/llmessage/llhttpclient.cpp30
-rw-r--r--indra/llmessage/llhttpsender.cpp70
-rw-r--r--indra/llmessage/llhttpsender.h38
-rw-r--r--indra/llmessage/llinstantmessage.cpp30
-rw-r--r--indra/llmessage/llinstantmessage.h17
-rw-r--r--indra/llmessage/lliohttpserver.cpp26
-rw-r--r--indra/llmessage/lliohttpserver.h3
-rw-r--r--indra/llmessage/lliopipe.h2
-rw-r--r--indra/llmessage/lliosocket.cpp13
-rw-r--r--indra/llmessage/llmessagebuilder.cpp18
-rw-r--r--indra/llmessage/llmessagebuilder.h70
-rw-r--r--indra/llmessage/llmessageconfig.cpp210
-rw-r--r--indra/llmessage/llmessageconfig.h31
-rw-r--r--indra/llmessage/llmessagereader.cpp35
-rw-r--r--indra/llmessage/llmessagereader.h59
-rw-r--r--indra/llmessage/llmessagetemplate.cpp146
-rw-r--r--indra/llmessage/llmessagetemplate.h356
-rw-r--r--indra/llmessage/llmsgvariabletype.h33
-rw-r--r--indra/llmessage/llpacketack.h18
-rw-r--r--indra/llmessage/llpumpio.cpp8
-rw-r--r--indra/llmessage/llpumpio.h1
-rwxr-xr-xindra/llmessage/llsdmessagebuilder.cpp281
-rwxr-xr-xindra/llmessage/llsdmessagebuilder.h98
-rwxr-xr-xindra/llmessage/llsdmessagereader.cpp264
-rwxr-xr-xindra/llmessage/llsdmessagereader.h79
-rw-r--r--indra/llmessage/llservice.h2
-rw-r--r--indra/llmessage/llservicebuilder.cpp115
-rw-r--r--indra/llmessage/llservicebuilder.h73
-rw-r--r--indra/llmessage/lltemplatemessagebuilder.cpp856
-rw-r--r--indra/llmessage/lltemplatemessagebuilder.h88
-rw-r--r--indra/llmessage/lltemplatemessagereader.cpp750
-rw-r--r--indra/llmessage/lltemplatemessagereader.h98
-rw-r--r--indra/llmessage/message.cpp3046
-rw-r--r--indra/llmessage/message.h538
-rw-r--r--indra/llmessage/message_prehash.cpp44
-rw-r--r--indra/llmessage/message_prehash.h22
-rw-r--r--indra/llmessage/net.cpp6
-rw-r--r--indra/llprimitive/llprimitive.cpp48
-rw-r--r--indra/llprimitive/llvolumemessage.cpp96
-rw-r--r--indra/llui/llcheckboxctrl.cpp2
-rw-r--r--indra/llui/llcombobox.cpp32
-rw-r--r--indra/llui/llscrolllistctrl.cpp115
-rw-r--r--indra/llui/llscrolllistctrl.h14
-rw-r--r--indra/llui/llsliderctrl.cpp2
-rw-r--r--indra/llui/llspinctrl.cpp24
-rw-r--r--indra/mac_updater/mac_updater.cpp25
-rw-r--r--indra/newview/English.lproj/InfoPlist.strings4
-rw-r--r--indra/newview/Info-SecondLife.plist2
-rw-r--r--indra/newview/gpu_table.txt7
-rw-r--r--indra/newview/llagent.cpp58
-rw-r--r--indra/newview/llagent.h7
-rw-r--r--indra/newview/llcaphttpsender.cpp30
-rw-r--r--indra/newview/llcaphttpsender.h30
-rw-r--r--indra/newview/llcolorswatch.cpp2
-rw-r--r--indra/newview/lleventpoll.cpp254
-rw-r--r--indra/newview/lleventpoll.h12
-rw-r--r--indra/newview/llfloaterauction.cpp53
-rw-r--r--indra/newview/llfloaterbump.cpp4
-rw-r--r--indra/newview/llfloaterbuyland.cpp44
-rw-r--r--indra/newview/llfloaterfriends.cpp11
-rw-r--r--indra/newview/llfloaterinspect.cpp1
-rw-r--r--indra/newview/llfloaterland.cpp4
-rw-r--r--indra/newview/llfloaterreporter.cpp1
-rw-r--r--indra/newview/llfloatertos.cpp1
-rw-r--r--indra/newview/llimpanel.cpp494
-rw-r--r--indra/newview/llimpanel.h39
-rw-r--r--indra/newview/llimview.cpp350
-rw-r--r--indra/newview/llimview.h28
-rw-r--r--indra/newview/llinventorybridge.cpp56
-rw-r--r--indra/newview/llinventorybridge.h1
-rw-r--r--indra/newview/llinventorymodel.cpp4
-rw-r--r--indra/newview/llmutelist.cpp2
-rw-r--r--indra/newview/llnamelistctrl.cpp25
-rw-r--r--indra/newview/llpanelavatar.cpp141
-rw-r--r--indra/newview/llpanelavatar.h10
-rw-r--r--indra/newview/llpanelclassified.cpp2
-rw-r--r--indra/newview/llpanelgroupgeneral.cpp14
-rw-r--r--indra/newview/llpanelpick.cpp21
-rw-r--r--indra/newview/llpanelpick.h7
-rw-r--r--indra/newview/llselectmgr.cpp9
-rw-r--r--indra/newview/llstartup.cpp105
-rw-r--r--indra/newview/llstartup.h1
-rw-r--r--indra/newview/lltexturectrl.cpp2
-rw-r--r--indra/newview/lltooldraganddrop.cpp2
-rw-r--r--indra/newview/llviewerdisplay.cpp6
-rw-r--r--indra/newview/llviewergenericmessage.cpp77
-rw-r--r--indra/newview/llviewergenericmessage.h26
-rw-r--r--indra/newview/llviewergesture.cpp74
-rw-r--r--indra/newview/llviewergesture.h2
-rw-r--r--indra/newview/llviewermenu.cpp157
-rw-r--r--indra/newview/llviewermessage.cpp266
-rw-r--r--indra/newview/llviewermessage.h13
-rw-r--r--indra/newview/llviewerparcelmgr.cpp11
-rw-r--r--indra/newview/llviewerparcelmgr.h6
-rw-r--r--indra/newview/llviewerregion.cpp34
-rw-r--r--indra/newview/llviewerwindow.cpp81
-rw-r--r--indra/newview/llvoavatar.cpp14
-rw-r--r--indra/newview/llxmlrpctransaction.cpp1
-rw-r--r--indra/test/llhttpclient_tut.cpp2
-rw-r--r--indra/test/lliohttpserver_tut.cpp29
-rw-r--r--indra/test/llmessageconfig_tut.cpp207
-rw-r--r--indra/test/llsd_new_tut.cpp77
-rwxr-xr-xindra/test/llsdmessagebuilder_tut.cpp259
-rwxr-xr-xindra/test/llsdmessagereader_tut.cpp300
-rw-r--r--indra/test/llsdtraits.h78
-rw-r--r--indra/test/llservicebuilder_tut.cpp76
-rw-r--r--indra/test/test_llmanifest.py2
-rw-r--r--indra/win_updater/updater.cpp38
126 files changed, 7922 insertions, 4229 deletions
diff --git a/indra/llcommon/bitpack.cpp b/indra/llcommon/bitpack.cpp
deleted file mode 100644
index 4acd533600..0000000000
--- a/indra/llcommon/bitpack.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-/**
- * @file bitpack.cpp
- * @brief Convert data to packed bit stream
- *
- * Copyright (c) 2000-$CurrentYear$, Linden Research, Inc.
- * $License$
- */
-
-#include "linden_common.h"
-
-#include "bitpack.h"
-
-#if 0
-#include <stdio.h>
-#include <stdlib.h>
-#include "stdtypes.h"
-
-U8 gLoad, gUnLoad;
-U32 gLoadSize, gUnLoadSize, gTotalBits;
-
-const U32 gMaxDataBits = 8;
-
-/////////////////////////////////////////////////////////////////////////////////////////
-#if 0
-void bit_pack(U8 *outbase, U32 *outptr, U8 *total_data, U32 total_dsize)
-{
- U32 max_data_bits = gMaxDataBits;
- U32 load_size = gLoadSize, total_bits = gTotalBits;
- U32 dsize;
-
- U8 data;
- U8 load = gLoad;
-
- while (total_dsize > 0)
- {
- if (total_dsize > max_data_bits)
- {
- dsize = max_data_bits;
- total_dsize -= max_data_bits;
- }
- else
- {
- dsize = total_dsize;
- total_dsize = 0;
- }
-
- data = *total_data++;
-
- data <<= (max_data_bits - dsize);
- while (dsize > 0)
- {
- if (load_size == max_data_bits)
- {
- *(outbase + (*outptr)++) = load;
- load_size = 0;
- load = 0x00;
- }
- load <<= 1;
- load |= (data >> (max_data_bits - 1));
- data <<= 1;
- load_size++;
- total_bits++;
- dsize--;
- }
- }
-
- gLoad = load;
- gLoadSize = load_size;
- gTotalBits = total_bits;
-}
-#endif
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void bit_pack_reset()
-{
- gLoad = 0x0;
- gLoadSize = 0;
- gTotalBits = 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void bit_pack_flush(U8 *outbase, U32 *outptr)
-{
- if (gLoadSize)
- {
- gTotalBits += gLoadSize;
- gLoad <<= (gMaxDataBits - gLoadSize);
- outbase[(*outptr)++] = gLoad;
- gLoadSize = 0;
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-#if 0
-void bit_unpack(U8 *total_retval, U32 total_dsize, U8 *indata, U32 *inptr)
-{
- U32 max_data_bits = gMaxDataBits;
- U32 unload_size = gUnLoadSize;
- U32 dsize;
- U8 *retval;
- U8 unload = gUnLoad;
-
- while (total_dsize > 0)
- {
- if (total_dsize > max_data_bits)
- {
- dsize = max_data_bits;
- total_dsize -= max_data_bits;
- }
- else
- {
- dsize = total_dsize;
- total_dsize = 0;
- }
-
- retval = total_data++;
- *retval = 0x00;
- while (dsize > 0)
- {
- if (unload_size == 0)
- {
- unload = indata[(*inptr)++];
- unload_size = max_data_bits;
- }
- *retval <<= 1;
- *retval |= (unload >> (max_data_bits - 1));
- unload_size--;
- unload <<= 1;
- dsize--;
- }
- }
-
- gUnLoad = unload;
- gUnLoadSize = unload_size;
-}
-#endif
-
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-void bit_unpack_reset()
-{
- gUnLoad = 0;
- gUnLoadSize = 0;
-}
-#endif
diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h
index 20499d4ad3..7f1c48a215 100644
--- a/indra/llcommon/indra_constants.h
+++ b/indra/llcommon/indra_constants.h
@@ -12,10 +12,6 @@
#include "stdtypes.h"
#include "lluuid.h"
-// Viewer object cache version, change if object update
-// format changes. JC
-const U32 INDRA_OBJECT_CACHE_VERSION = 11;
-
// At 45 Hz collisions seem stable and objects seem
// to settle down at a reasonable rate.
// JC 3/18/2003
@@ -97,11 +93,11 @@ 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;
const U32 DEFAULT_INV_DATA_SERVER_PORT = 12044;
+const U32 DEFAULT_CGI_SERVICES_PORT = 12045;
// For automatic port discovery when running multiple viewers on one host
const U32 PORT_DISCOVERY_RANGE_MIN = 13000;
diff --git a/indra/llcommon/llbase32.h b/indra/llcommon/llbase32.h
index 5fd06f9e30..6927607c8f 100644
--- a/indra/llcommon/llbase32.h
+++ b/indra/llcommon/llbase32.h
@@ -1,19 +1,19 @@
-/**
- * @file llbase32.h
- * @brief base32 encoding that returns a std::string
- * @author James Cook
- *
- * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
- * $License$
- */
-
-#ifndef LLBASE32_H
-#define LLBASE32_h
-
-class LLBase32
-{
-public:
- static std::string encode(const U8* input, size_t input_size);
-};
-
-#endif
+/**
+ * @file llbase32.h
+ * @brief base32 encoding that returns a std::string
+ * @author James Cook
+ *
+ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#ifndef LLBASE32_H
+#define LLBASE32_h
+
+class LLBase32
+{
+public:
+ static std::string encode(const U8* input, size_t input_size);
+};
+
+#endif
diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp
index 796cd9f9f4..c5ab369d0f 100644
--- a/indra/llcommon/llsdserialize_xml.cpp
+++ b/indra/llcommon/llsdserialize_xml.cpp
@@ -234,7 +234,7 @@ public:
Impl();
~Impl();
- LLSD parse(std::istream& input);
+ S32 parse(std::istream& input, LLSD& data);
void parsePart(const char *buf, int len);
@@ -336,7 +336,7 @@ static unsigned get_till_eol(std::istream& input, char *buf, unsigned bufsize)
return count;
}
-LLSD LLSDXMLParser::Impl::parse(std::istream& input)
+S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data)
{
reset();
XML_Status status;
@@ -380,11 +380,13 @@ LLSD LLSDXMLParser::Impl::parse(std::istream& input)
{
((char*) buffer)[count? count - 1 : 0] = '\0';
llinfos << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << llendl;
- return LLSD();
+ data = LLSD();
+ return -1;
}
clear_eol(input);
- return mResult;
+ data = mResult;
+ return 1;
}
void LLSDXMLParser::Impl::reset()
@@ -703,6 +705,5 @@ void LLSDXMLParser::parsePart(const char *buf, int len)
// virtual
S32 LLSDXMLParser::parse(std::istream& input, LLSD& data) const
{
- data = impl.parse(input);
- return 0;
+ return impl.parse(input, data);
}
diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp
index a6ac2fb12b..57a024ecee 100644
--- a/indra/llcommon/llsdutil.cpp
+++ b/indra/llcommon/llsdutil.cpp
@@ -21,7 +21,7 @@
# include <arpa/inet.h>
#endif
-
+#include "llsdserialize.h"
// vector3
LLSD ll_sd_from_vector3(const LLVector3& vec)
@@ -42,6 +42,27 @@ LLVector3 ll_vector3_from_sd(const LLSD& sd, S32 start_index)
return rv;
}
+// vector4
+LLSD ll_sd_from_vector4(const LLVector4& vec)
+{
+ LLSD rv;
+ rv.append((F64)vec.mV[VX]);
+ rv.append((F64)vec.mV[VY]);
+ rv.append((F64)vec.mV[VZ]);
+ rv.append((F64)vec.mV[VW]);
+ return rv;
+}
+
+LLVector4 ll_vector4_from_sd(const LLSD& sd, S32 start_index)
+{
+ LLVector4 rv;
+ rv.mV[VX] = (F32)sd[start_index].asReal();
+ rv.mV[VY] = (F32)sd[++start_index].asReal();
+ rv.mV[VZ] = (F32)sd[++start_index].asReal();
+ rv.mV[VW] = (F32)sd[++start_index].asReal();
+ return rv;
+}
+
// vector3d
LLSD ll_sd_from_vector3d(const LLVector3d& vec)
{
@@ -208,9 +229,39 @@ U32 ll_ipaddr_from_sd(const LLSD& sd)
LLSD ll_string_from_binary(const LLSD& sd)
{
std::vector<U8> value = sd.asBinary();
- char* c_str = new char[value.size() + 1];
- memcpy(c_str, &value[0], value.size());
- c_str[value.size()] = '\0';
+ std::string str;
+ str.resize(value.size());
+ memcpy(&str[0], &value[0], value.size());
+ return str;
+}
- return c_str;
+// Converts an LLSD string to an LLSD binary
+LLSD ll_binary_from_string(const LLSD& sd)
+{
+ std::vector<U8> binary_value;
+
+ LLString string_value = sd.asString();
+ const char* string_p = string_value.c_str();
+ while (*string_p)
+ {
+ binary_value.push_back(*string_p);
+ string_p++;
+ }
+
+ binary_value.push_back('\0');
+
+ return binary_value;
+}
+
+char* ll_print_sd(const LLSD& sd)
+{
+ const U32 bufferSize = 10 * 1024;
+ static char buffer[bufferSize];
+ std::ostringstream stream;
+ //stream.rdbuf()->pubsetbuf(buffer, bufferSize);
+ stream << LLSDOStreamer<LLSDXMLFormatter>(sd);
+ stream << std::ends;
+ strncpy(buffer, stream.str().c_str(), bufferSize);
+ buffer[bufferSize - 1] = '\0';
+ return buffer;
}
diff --git a/indra/llcommon/llsdutil.h b/indra/llcommon/llsdutil.h
index 44e9429d7f..860232044e 100644
--- a/indra/llcommon/llsdutil.h
+++ b/indra/llcommon/llsdutil.h
@@ -13,6 +13,7 @@
#include "llsd.h"
#include "../llmath/v3math.h"
+#include "../llmath/v4math.h"
#include "../llmath/v3dmath.h"
#include "../llmath/v2math.h"
#include "../llmath/llquaternion.h"
@@ -23,6 +24,10 @@
LLSD ll_sd_from_vector3(const LLVector3& vec);
LLVector3 ll_vector3_from_sd(const LLSD& sd, S32 start_index = 0);
+// vector4
+LLSD ll_sd_from_vector4(const LLVector4& vec);
+LLVector4 ll_vector4_from_sd(const LLSD& sd, S32 start_index = 0);
+
// vector3d (double)
LLSD ll_sd_from_vector3d(const LLVector3d& vec);
LLVector3d ll_vector3d_from_sd(const LLSD& sd, S32 start_index = 0);
@@ -54,4 +59,10 @@ U32 ll_ipaddr_from_sd(const LLSD& sd);
// Binary to string
LLSD ll_string_from_binary(const LLSD& sd);
+//String to binary
+LLSD ll_binary_from_string(const LLSD& sd);
+
+// Serializes sd to static buffer and returns pointer, useful for gdb debugging.
+char* ll_print_sd(const LLSD& sd);
+
#endif // LL_LLSDUTIL_H
diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp
index bf0d2cb21e..52270376f8 100644
--- a/indra/llcommon/lluri.cpp
+++ b/indra/llcommon/lluri.cpp
@@ -195,6 +195,19 @@ LLURI LLURI::buildHTTP(const std::string& prefix,
result.mEscapedPath += "/" + escapePathComponent(it->asString());
}
}
+ else if(path.isString())
+ {
+ result.mEscapedPath += "/" + escapePathComponent(path.asString());
+ }
+ else if(path.isUndefined())
+ {
+ // do nothing
+ }
+ else
+ {
+ llwarns << "Valid path arguments to buildHTTP are array, string, or undef, you passed type"
+ << path.type() << llendl;
+ }
result.mEscapedOpaque = "//" + result.mEscapedAuthority +
result.mEscapedPath;
return result;
@@ -265,17 +278,22 @@ namespace {
}
}
-
+#if LL_ENABLE_JANKY_DEPRECATED_WEB_SERVICE_CALLS
// static
-LLURI LLURI::buildAgentPresenceURI(const LLUUID& agent_id, LLApp* app)
+LLURI LLURI::buildBulkAgentNamesURI(LLApp* app)
{
- return buildBackboneURL(app, "agent", agent_id.asString(), "presence");
-}
+ std::string host = "localhost:12040";
-// static
-LLURI LLURI::buildBulkAgentPresenceURI(LLApp* app)
-{
- return buildBackboneURL(app, "agent", "presence");
+ if (app)
+ {
+ host = app->getOption("backbone-host-port").asString();
+ }
+
+ LLSD path = LLSD::emptyArray();
+ path.append("agent");
+ path.append("names");
+
+ return buildHTTP(host, path);
}
// static
@@ -302,7 +320,7 @@ LLURI LLURI::buildAgentSessionURI(const LLUUID& agent_id, LLApp* app)
}
// static
-LLURI LLURI::buildInventoryHostURI(const LLUUID& agent_id, LLApp* app)
+LLURI LLURI::buildAgentNameURI(const LLUUID& agent_id, LLApp* app)
{
std::string host = "localhost:12040";
@@ -314,8 +332,7 @@ LLURI LLURI::buildInventoryHostURI(const LLUUID& agent_id, LLApp* app)
LLSD path = LLSD::emptyArray();
path.append("agent");
path.append(agent_id);
- path.append("inventory");
- path.append("host");
+ path.append("name");
return buildHTTP(host, path);
}
@@ -348,6 +365,7 @@ LLURI LLURI::buildAgentLoginInfoURI(const LLUUID& agent_id, const std::string& d
return buildHTTP(dataserver, path);
}
+#endif // LL_ENABLE_JANKY_DEPRECATED_WEB_SERVICE_CALLS
std::string LLURI::asString() const
{
diff --git a/indra/llcommon/lluri.h b/indra/llcommon/lluri.h
index 865a3b21a0..f42cc102e6 100644
--- a/indra/llcommon/lluri.h
+++ b/indra/llcommon/lluri.h
@@ -77,13 +77,12 @@ public:
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);
- static LLURI buildBulkAgentPresenceURI(LLApp* app);
- static LLURI buildBulkAgentNamesURI(LLApp* app);
- static LLURI buildAgentSessionURI(const LLUUID& agent_id, LLApp* app);
- static LLURI buildAgentLoginInfoURI(const LLUUID& agent_id, const std::string& dataserver);
- static LLURI buildInventoryHostURI(const LLUUID& agent_id, LLApp* app);
- static LLURI buildAgentNameURI(const LLUUID& agent_id, LLApp* app);
+ // *NOTE: DEPRECATED. use the service builder instead.
+ //static LLURI buildBulkAgentNamesURI(LLApp* app);
+ //static LLURI buildAgentSessionURI(const LLUUID& agent_id, LLApp* app);
+ //static LLURI buildAgentLoginInfoURI(const LLUUID& agent_id, const std::string& dataserver);
+ //static LLURI buildAgentNameURI(const LLUUID& agent_id, LLApp* app);
+
private:
std::string mScheme;
std::string mEscapedOpaque;
diff --git a/indra/llinventory/lleconomy.cpp b/indra/llinventory/lleconomy.cpp
index 378ab8ced1..f7442380b0 100644
--- a/indra/llinventory/lleconomy.cpp
+++ b/indra/llinventory/lleconomy.cpp
@@ -151,6 +151,11 @@ void LLRegionEconomy::processEconomyData(LLMessageSystem *msg, void** user_data)
void LLRegionEconomy::processEconomyDataRequest(LLMessageSystem *msg, void **user_data)
{
LLRegionEconomy *this_ptr = (LLRegionEconomy*)user_data;
+ if (!this_ptr->hasData())
+ {
+ llwarns << "Dropping EconomyDataRequest, because EconomyData message "
+ << "has not been processed" << llendl;
+ }
msg->newMessageFast(_PREHASH_EconomyData);
msg->nextBlockFast(_PREHASH_Info);
diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index 94a90f2c20..6164dae22f 100644
--- a/indra/llinventory/llinventory.cpp
+++ b/indra/llinventory/llinventory.cpp
@@ -1772,7 +1772,17 @@ LLPointer<LLInventoryItem> ll_create_item_from_sd(const LLSD& sd_item)
rv->rename(sd_item[INV_NAME_LABEL].asString());
rv->setType(
LLAssetType::lookup(sd_item[INV_ASSET_TYPE_LABEL].asString().c_str()));
- rv->setAssetUUID(sd_item[INV_ASSET_ID_LABEL].asUUID());
+ if (sd_item.has("shadow_id"))
+ {
+ LLUUID asset_id = sd_item["shadow_id"];
+ LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
+ cipher.decrypt(asset_id.mData, UUID_BYTES);
+ rv->setAssetUUID(asset_id);
+ }
+ if (sd_item.has(INV_ASSET_ID_LABEL))
+ {
+ rv->setAssetUUID(sd_item[INV_ASSET_ID_LABEL].asUUID());
+ }
rv->setDescription(sd_item[INV_DESC_LABEL].asString());
rv->setSaleInfo(ll_sale_info_from_sd(sd_item[INV_SALE_INFO_LABEL]));
rv->setPermissions(ll_permissions_from_sd(sd_item[INV_PERMISSIONS_LABEL]));
diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp
index 42a9d64254..7ea83f6e5e 100644
--- a/indra/llinventory/llparcel.cpp
+++ b/indra/llinventory/llparcel.cpp
@@ -173,7 +173,6 @@ void LLParcel::init(const LLUUID &owner_id,
mRecordTransaction = FALSE;
mAuctionID = 0;
- mIsReservedForNewbie = FALSE;
mInEscrow = false;
mParcelFlags = PF_DEFAULT;
@@ -633,10 +632,6 @@ BOOL LLParcel::importStream(std::istream& input_stream)
{
LLString::convertToU32(value, mAuctionID);
}
- else if("reserved_newbie" == keyword)
- {
- LLString::convertToBOOL(value, mIsReservedForNewbie);
- }
else if ("allow_modify" == keyword)
{
LLString::convertToU32(value, setting);
@@ -1071,10 +1066,6 @@ BOOL LLParcel::exportStream(std::ostream& output_stream)
{
output_stream << "\t\t auction_id " << mAuctionID << "\n";
}
- if(mIsReservedForNewbie)
- {
- output_stream << "\t\t reserved_newbie " << mIsReservedForNewbie << "\n";
- }
output_stream << "\t\t allow_modify " << getAllowModify() << "\n";
output_stream << "\t\t allow_group_modify " << getAllowGroupModify() << "\n";
@@ -1615,7 +1606,6 @@ void LLParcel::expireSale(U32& type, U8& flags, LLUUID& from_id, LLUUID& to_id)
setSellWithObjects(FALSE);
type = TRANS_LAND_RELEASE;
mStatus = OS_NONE;
- mIsReservedForNewbie = FALSE;
flags = pack_transaction_flags(mGroupOwned, FALSE);
mAuthBuyerID.setNull();
from_id = mOwnerID;
@@ -1633,7 +1623,6 @@ void LLParcel::completeSale(U32& type, U8& flags,
flags = pack_transaction_flags(mGroupOwned, mGroupOwned);
to_id = mOwnerID;
mAuthBuyerID.setNull();
- mIsReservedForNewbie = FALSE;
// Purchased parcels are assumed to no longer be for sale.
// Otherwise someone can snipe the sale.
@@ -1666,7 +1655,6 @@ void LLParcel::clearSale()
setPreviousOwnerID(LLUUID::null);
setPreviouslyGroupOwned(FALSE);
setSellWithObjects(FALSE);
- mIsReservedForNewbie = FALSE;
}
BOOL LLParcel::isPublic() const
@@ -1700,7 +1688,6 @@ void LLParcel::clearParcel()
setUserLookAt(LLVector3::x_axis);
setLandingType(L_LANDING_POINT);
setAuctionID(0);
- setReservedForNewbie(FALSE);
setGroupID(LLUUID::null);
setPassPrice(0);
setPassHours(0.f);
diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h
index 16d3cb01e5..131bcdd55d 100644
--- a/indra/llinventory/llparcel.h
+++ b/indra/llinventory/llparcel.h
@@ -190,7 +190,6 @@ public:
void setLandingType(const ELandingType type) { mLandingType = type; }
void setAuctionID(U32 auction_id) { mAuctionID = auction_id;}
- void setReservedForNewbie(BOOL reserve) { mIsReservedForNewbie = reserve; }
void setAllParcelFlags(U32 flags) { mParcelFlags = flags; }
void setParcelFlag(U32 flag, BOOL b);
@@ -271,7 +270,6 @@ public:
BOOL getIsGroupOwned() const { return mGroupOwned; }
U32 getAuctionID() { return mAuctionID; }
- BOOL getReservedForNewbie() { return mIsReservedForNewbie; }
bool isInEscrow() const { return mInEscrow; }
BOOL isPublic() const;
@@ -518,9 +516,6 @@ protected:
// the parcel.
U32 mAuctionID;
- // This value is TRUE if the land is reserved for a newbie.
- BOOL mIsReservedForNewbie;
-
// value used to temporarily lock attempts to purchase the parcel.
bool mInEscrow;
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 00a192aca8..c5d105c9ee 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -196,7 +196,7 @@ void LLProfile::genNGon(S32 sides, F32 offset, F32 bevel, F32 ang_scale, S32 spl
t_fraction = (begin - t_first)*sides;
// Only use if it's not almost exactly on an edge.
- if (t_fraction < 0.99f)
+ if (t_fraction < 0.9999f)
{
LLVector3 new_pt = lerp(pt1, pt2, t_fraction);
F32 pt_x = new_pt.mV[VX];
@@ -247,7 +247,7 @@ void LLProfile::genNGon(S32 sides, F32 offset, F32 bevel, F32 ang_scale, S32 spl
// Find the fraction that we need to add to the end point.
t_fraction = (end - (t - t_step))*sides;
- if (t_fraction > 0.01f)
+ if (t_fraction > 0.0001f)
{
LLVector3 new_pt = lerp(pt1, pt2, t_fraction);
F32 pt_x = new_pt.mV[VX];
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index 97aeeb9589..22742e09da 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -42,12 +42,12 @@ const S32 MAX_LOD = 3;
const F32 MIN_VOLUME_PROFILE_WIDTH = 0.05f;
const F32 MIN_VOLUME_PATH_WIDTH = 0.05f;
-const F32 CUT_QUANTA = 0.005f;
-const F32 SCALE_QUANTA = 0.01f;
-const F32 SHEAR_QUANTA = 0.01f;
-const F32 TAPER_QUANTA = 0.01f;
-const F32 REV_QUANTA = 0.015f;
-
+const F32 CUT_QUANTA = 0.00002f;
+const F32 SCALE_QUANTA = 0.01f;
+const F32 SHEAR_QUANTA = 0.01f;
+const F32 TAPER_QUANTA = 0.01f;
+const F32 REV_QUANTA = 0.015f;
+const F32 HOLLOW_QUANTA = 0.00002f;
//============================================================================
@@ -165,7 +165,7 @@ public:
{
}
- LLProfileParams(U8 curve, U8 begin, U8 end, U8 hollow)
+ LLProfileParams(U8 curve, U16 begin, U16 end, U16 hollow)
{
mCurveType = curve;
F32 temp_f32 = begin * CUT_QUANTA;
@@ -180,7 +180,7 @@ public:
temp_f32 = 1.f;
}
mEnd = 1.f - temp_f32;
- temp_f32 = hollow * SCALE_QUANTA;
+ temp_f32 = hollow * HOLLOW_QUANTA;
if (temp_f32 > 1.f)
{
temp_f32 = 1.f;
@@ -210,9 +210,9 @@ public:
const U8& getCurveType () const { return mCurveType; }
void setCurveType(const U32 type) { mCurveType = type;}
- void setBegin(const F32 begin) { mBegin = (begin >= 1.0f) ? 0.0f : ((int) (begin * 1000))/1000.0f;}
- void setEnd(const F32 end) { mEnd = (end <= 0.0f) ? 1.0f : ((int) (end * 1000))/1000.0f;}
- void setHollow(const F32 hollow) { mHollow = ((int) (hollow * 1000))/1000.0f;}
+ void setBegin(const F32 begin) { mBegin = (begin >= 1.0f) ? 0.0f : ((int) (begin * 100000))/100000.0f;}
+ void setEnd(const F32 end) { mEnd = (end <= 0.0f) ? 1.0f : ((int) (end * 100000))/100000.0f;}
+ void setHollow(const F32 hollow) { mHollow = ((int) (hollow * 100000))/100000.0f;}
friend std::ostream& operator<<(std::ostream &s, const LLProfileParams &profile_params);
@@ -296,11 +296,11 @@ public:
mTaper.setVec(tx,ty);
}
- LLPathParams(U8 curve, U8 begin, U8 end, U8 scx, U8 scy, U8 shx, U8 shy, U8 twistend, U8 twistbegin, U8 radiusoffset, U8 tx, U8 ty, U8 revolutions, U8 skew)
+ LLPathParams(U8 curve, U16 begin, U16 end, U8 scx, U8 scy, U8 shx, U8 shy, U8 twistend, U8 twistbegin, U8 radiusoffset, U8 tx, U8 ty, U8 revolutions, U8 skew)
{
mCurveType = curve;
- mBegin = (F32)(begin * SCALE_QUANTA);
- mEnd = (F32)(100.f - end) * SCALE_QUANTA;
+ mBegin = (F32)(begin * CUT_QUANTA);
+ mEnd = (F32)(100.f - end) * CUT_QUANTA;
if (mEnd > 1.f)
mEnd = 1.f;
mScale.setVec((F32) (200 - scx) * SCALE_QUANTA,(F32) (200 - scy) * SCALE_QUANTA);
diff --git a/indra/llmessage/llblowfishcipher.cpp b/indra/llmessage/llblowfishcipher.cpp
index 0255a654df..d15e4fb69a 100644
--- a/indra/llmessage/llblowfishcipher.cpp
+++ b/indra/llmessage/llblowfishcipher.cpp
@@ -65,27 +65,33 @@ U32 LLBlowfishCipher::encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len)
<< " iv_len " << iv_length
<< llendl;
- int output_len = 0;
- if (!EVP_EncryptUpdate(&context,
- dst,
- &output_len,
- src,
- src_len))
- {
- llwarns << "LLBlowfishCipher::encrypt EVP_EncryptUpdate failure" << llendl;
- return 0;
- }
-
- // There may be some final data left to encrypt if the input is
- // not an exact multiple of the block size.
- int temp_len = 0;
- if (!EVP_EncryptFinal_ex(&context, (unsigned char*)(dst + output_len), &temp_len))
- {
- llwarns << "LLBlowfishCipher::encrypt EVP_EncryptFinal failure" << llendl;
- return 0;
- }
- output_len += temp_len;
- return output_len;
+ int output_len = 0;
+ int temp_len = 0;
+ if (!EVP_EncryptUpdate(&context,
+ dst,
+ &output_len,
+ src,
+ src_len))
+ {
+ llwarns << "LLBlowfishCipher::encrypt EVP_EncryptUpdate failure" << llendl;
+ goto ERROR;
+ }
+
+ // There may be some final data left to encrypt if the input is
+ // not an exact multiple of the block size.
+ if (!EVP_EncryptFinal_ex(&context, (unsigned char*)(dst + output_len), &temp_len))
+ {
+ llwarns << "LLBlowfishCipher::encrypt EVP_EncryptFinal failure" << llendl;
+ goto ERROR;
+ }
+ output_len += temp_len;
+
+ EVP_CIPHER_CTX_cleanup(&context);
+ return output_len;
+
+ERROR:
+ EVP_CIPHER_CTX_cleanup(&context);
+ return 0;
}
// virtual
diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp
index 339fdda9ef..36cd2ce188 100644
--- a/indra/llmessage/llcachename.cpp
+++ b/indra/llmessage/llcachename.cpp
@@ -32,6 +32,10 @@ const char* CN_NONE = "(none)";
const char* CN_HIPPOS = "(hippos)";
const F32 HIPPO_PROBABILITY = 0.01f;
+// We track name requests in flight for up to this long.
+// We won't re-request a name during this time
+const U32 PENDING_TIMEOUT_SECS = 5 * 60;
+
// File version number
const S32 CN_FILE_VERSION = 2;
@@ -162,8 +166,9 @@ namespace {
}
- typedef std::vector<LLUUID> AskQueue;
+ typedef std::set<LLUUID> AskQueue;
typedef std::vector<PendingReply> ReplyQueue;
+ typedef std::map<LLUUID,U32> PendingQueue;
typedef std::map<LLUUID, LLCacheNameEntry*> Cache;
typedef std::vector<LLCacheNameCallback> Observers;
};
@@ -180,6 +185,9 @@ public:
AskQueue mAskNameQueue;
AskQueue mAskGroupQueue;
// UUIDs to ask our upstream host about
+
+ PendingQueue mPendingQueue;
+ // UUIDs that have been requested but are not in cache yet.
ReplyQueue mReplyQueue;
// requests awaiting replies from us
@@ -194,6 +202,7 @@ public:
void processPendingAsks();
void processPendingReplies();
void sendRequest(const char* msg_name, const AskQueue& queue);
+ bool isRequestPending(const LLUUID& id);
// Message system callbacks.
void processUUIDRequest(LLMessageSystem* msg, bool isGroup);
@@ -436,7 +445,10 @@ BOOL LLCacheName::getName(const LLUUID& id, char* first, char* last)
: CN_WAITING);
strcpy(last, ""); /*Flawfinder: ignore*/
- impl.mAskNameQueue.push_back(id);
+ if (!impl.isRequestPending(id))
+ {
+ impl.mAskNameQueue.insert(id);
+ }
return FALSE;
}
@@ -476,8 +488,10 @@ BOOL LLCacheName::getGroupName(const LLUUID& id, char* group)
// The function signature needs to change to pass in the length
// of first and last.
strcpy(group, CN_WAITING); /*Flawfinder: ignore*/
-
- impl.mAskGroupQueue.push_back(id);
+ if (!impl.isRequestPending(id))
+ {
+ impl.mAskGroupQueue.insert(id);
+ }
return FALSE;
}
}
@@ -505,13 +519,16 @@ void LLCacheName::get(const LLUUID& id, BOOL is_group, LLCacheNameCallback callb
}
else
{
- if (!is_group)
- {
- impl.mAskNameQueue.push_back(id);
- }
- else
+ if (!impl.isRequestPending(id))
{
- impl.mAskGroupQueue.push_back(id);
+ if (!is_group)
+ {
+ impl.mAskNameQueue.insert(id);
+ }
+ else
+ {
+ impl.mAskGroupQueue.insert(id);
+ }
}
impl.mReplyQueue.push_back(PendingReply(id, callback, user_data));
}
@@ -550,6 +567,19 @@ void LLCacheName::deleteEntriesOlderThan(S32 secs)
impl.mCache.erase(curiter);
}
}
+
+ // These are pending requests that we never heard back from.
+ U32 pending_expire_time = now - PENDING_TIMEOUT_SECS;
+ for(PendingQueue::iterator p_iter = impl.mPendingQueue.begin();
+ p_iter != impl.mPendingQueue.end(); )
+ {
+ PendingQueue::iterator p_curitor = p_iter++;
+
+ if (p_curitor->second < pending_expire_time)
+ {
+ impl.mPendingQueue.erase(p_curitor);
+ }
+ }
}
@@ -579,6 +609,18 @@ void LLCacheName::dump()
}
}
+void LLCacheName::dumpStats()
+{
+ llinfos << "Queue sizes: "
+ << " Cache=" << impl.mCache.size()
+ << " AskName=" << impl.mAskNameQueue.size()
+ << " AskGroup=" << impl.mAskGroupQueue.size()
+ << " Pending=" << impl.mPendingQueue.size()
+ << " Reply=" << impl.mReplyQueue.size()
+ << " Observers=" << impl.mObservers.size()
+ << llendl;
+}
+
void LLCacheName::Impl::processPendingAsks()
{
sendRequest(_PREHASH_UUIDNameRequest, mAskNameQueue);
@@ -682,7 +724,23 @@ void LLCacheName::Impl::notifyObservers(const LLUUID& id,
}
}
+bool LLCacheName::Impl::isRequestPending(const LLUUID& id)
+{
+ U32 now = (U32)time(NULL);
+ U32 expire_time = now - PENDING_TIMEOUT_SECS;
+ PendingQueue::iterator iter = mPendingQueue.find(id);
+
+ if (iter == mPendingQueue.end()
+ || (iter->second < expire_time) )
+ {
+ mPendingQueue[id] = now;
+ return false;
+ }
+
+ return true;
+}
+
void LLCacheName::Impl::processUUIDRequest(LLMessageSystem* msg, bool isGroup)
{
// You should only get this message if the cache is at the simulator
@@ -720,13 +778,16 @@ void LLCacheName::Impl::processUUIDRequest(LLMessageSystem* msg, bool isGroup)
}
else
{
- if (isGroup)
+ if (!isRequestPending(id))
{
- mAskGroupQueue.push_back(id);
- }
- else
- {
- mAskNameQueue.push_back(id);
+ if (isGroup)
+ {
+ mAskGroupQueue.insert(id);
+ }
+ else
+ {
+ mAskNameQueue.insert(id);
+ }
}
mReplyQueue.push_back(PendingReply(id, fromHost));
@@ -750,6 +811,8 @@ void LLCacheName::Impl::processUUIDReply(LLMessageSystem* msg, bool isGroup)
mCache[id] = entry;
}
+ mPendingQueue.erase(id);
+
entry->mIsGroup = isGroup;
entry->mCreateTime = (U32)time(NULL);
if (!isGroup)
diff --git a/indra/llmessage/llcachename.h b/indra/llmessage/llcachename.h
index af49903c88..c4f88ac490 100644
--- a/indra/llmessage/llcachename.h
+++ b/indra/llmessage/llcachename.h
@@ -78,7 +78,8 @@ public:
void deleteEntriesOlderThan(S32 secs);
// Debugging
- void dump();
+ void dump(); // Dumps the contents of the cache
+ void dumpStats(); // Dumps the sizes of the cache and associated queues.
private:
class Impl;
diff --git a/indra/llmessage/llhost.cpp b/indra/llmessage/llhost.cpp
index d395188b72..6a74cfe831 100644
--- a/indra/llmessage/llhost.cpp
+++ b/indra/llmessage/llhost.cpp
@@ -28,7 +28,7 @@ LLHost LLHost::invalid(INVALID_PORT,INVALID_HOST_IP_ADDRESS);
LLHost::LLHost(const std::string& ip_and_port)
{
std::string::size_type colon_index = ip_and_port.find(":");
- if (colon_index != std::string::npos)
+ if (colon_index == std::string::npos)
{
mIP = ip_string_to_u32(ip_and_port.c_str());
mPort = 0;
diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp
index 121cbd2e68..92c309f1bc 100644
--- a/indra/llmessage/llhttpclient.cpp
+++ b/indra/llmessage/llhttpclient.cpp
@@ -18,6 +18,7 @@
#include "llvfile.h"
#include "llvfs.h"
+#include "message.h"
#include <curl/curl.h>
const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f;
@@ -92,6 +93,14 @@ namespace
if (200 <= mStatus && mStatus < 300)
{
LLSDSerialize::fromXML(content, istr);
+/*
+ const S32 parseError = -1;
+ if(LLSDSerialize::fromXML(content, istr) == parseError)
+ {
+ mStatus = 498;
+ mReason = "Client Parse Error";
+ }
+*/
}
if (mResponder.get())
@@ -232,10 +241,17 @@ static void request(const std::string& url, LLURLRequest::ERequestAction method,
}
req->setCallback(new LLHTTPClientURLAdaptor(responder));
+ if (method == LLURLRequest::HTTP_POST && gMessageSystem) {
+ req->addHeader(llformat("X-SecondLife-UDP-Listen-Port: %d",
+ gMessageSystem->mPort).c_str());
+ }
+
if (method == LLURLRequest::HTTP_PUT || method == LLURLRequest::HTTP_POST)
{
- req->addHeader(llformat("Content-Type: %s", body_injector->contentType()).c_str());
- chain.push_back(LLIOPipe::ptr_t(body_injector));
+ req->addHeader(llformat("Content-Type: %s",
+ body_injector->contentType()).c_str());
+
+ chain.push_back(LLIOPipe::ptr_t(body_injector));
}
chain.push_back(LLIOPipe::ptr_t(req));
@@ -293,6 +309,14 @@ LLSD LLHTTPClient::blockingGet(const std::string& url)
LLHTTPBuffer http_buffer;
+ // Without this timeout, blockingGet() calls have been observed to take
+ // up to 90 seconds to complete. Users of blockingGet() already must
+ // check the HTTP return code for validity, so this will not introduce
+ // new errors. A 5 second timeout will succeed > 95% of the time (and
+ // probably > 99% of the time) based on my statistics. JC
+ curl_easy_setopt(curlp, CURLOPT_NOSIGNAL, 1); // don't use SIGALRM for timeouts
+ curl_easy_setopt(curlp, CURLOPT_TIMEOUT, 5); // seconds
+
curl_easy_setopt(curlp, CURLOPT_WRITEFUNCTION, LLHTTPBuffer::curl_write);
curl_easy_setopt(curlp, CURLOPT_WRITEDATA, &http_buffer);
curl_easy_setopt(curlp, CURLOPT_URL, url.c_str());
@@ -382,7 +406,7 @@ namespace boost
void intrusive_ptr_release(LLHTTPClient::Responder* p)
{
- if(0 == --p->mReferenceCount)
+ if(p && 0 == --p->mReferenceCount)
{
delete p;
}
diff --git a/indra/llmessage/llhttpsender.cpp b/indra/llmessage/llhttpsender.cpp
new file mode 100644
index 0000000000..4152dedae5
--- /dev/null
+++ b/indra/llmessage/llhttpsender.cpp
@@ -0,0 +1,70 @@
+/**
+ * @file llhttpsender.cpp
+ * @brief Abstracts details of sending messages via HTTP.
+ *
+ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include "linden_common.h"
+
+#include "llhttpsender.h"
+
+#include <map>
+#include <sstream>
+
+#include "llhost.h"
+#include "llsd.h"
+
+namespace
+{
+ typedef std::map<LLHost, LLHTTPSender*> SenderMap;
+ static SenderMap senderMap;
+}
+
+//virtual
+LLHTTPSender::~LLHTTPSender()
+{
+}
+
+//virtual
+void LLHTTPSender::send(const LLHost& host, const char* name,
+ const LLSD& body,
+ LLHTTPClient::ResponderPtr response) const
+{
+ // Default implementation inserts sender, message and sends HTTP POST
+ std::ostringstream stream;
+ stream << "http://" << host << "/trusted-message/" << name;
+ llinfos << "LLHTTPSender::send: POST to " << stream.str() << llendl;
+ LLHTTPClient::post(stream.str(), body, response);
+}
+
+//static
+void LLHTTPSender::setSender(const LLHost& host, LLHTTPSender* sender)
+{
+ llinfos << "LLHTTPSender::setSender " << host << llendl;
+ senderMap[host] = sender;
+}
+
+//static
+const LLHTTPSender& LLHTTPSender::getSender(const LLHost& host)
+{
+ static LLHTTPSender defaultSender;
+ SenderMap::const_iterator iter = senderMap.find(host);
+ if(iter == senderMap.end())
+ {
+ return defaultSender;
+ }
+ return *(iter->second);
+}
+
+//static
+void LLHTTPSender::clearSender(const LLHost& host)
+{
+ SenderMap::iterator iter = senderMap.find(host);
+ if(iter != senderMap.end())
+ {
+ delete iter->second;
+ senderMap.erase(iter);
+ }
+}
diff --git a/indra/llmessage/llhttpsender.h b/indra/llmessage/llhttpsender.h
new file mode 100644
index 0000000000..a9f42579c2
--- /dev/null
+++ b/indra/llmessage/llhttpsender.h
@@ -0,0 +1,38 @@
+/**
+ * @file llhttpsender.h
+ * @brief Abstracts details of sending messages via HTTP.
+ *
+ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#ifndef LL_HTTP_SENDER_H
+#define LL_HTTP_SENDER_H
+
+#include "llhttpclient.h"
+
+class LLHost;
+class LLSD;
+
+class LLHTTPSender
+{
+ public:
+
+ virtual ~LLHTTPSender();
+
+ /** @brief Send message to host with body, call response when done */
+ virtual void send(const LLHost& host,
+ const char* message, const LLSD& body,
+ LLHTTPClient::ResponderPtr response) const;
+
+ /** @brief Set sender for host, takes ownership of sender. */
+ static void setSender(const LLHost& host, LLHTTPSender* sender);
+
+ /** @brief Get sender for host, retains ownership of returned sender. */
+ static const LLHTTPSender& getSender(const LLHost& host);
+
+ /** @brief Clear sender for host. */
+ static void clearSender(const LLHost& host);
+};
+
+#endif // LL_HTTP_SENDER_H
diff --git a/indra/llmessage/llinstantmessage.cpp b/indra/llmessage/llinstantmessage.cpp
index 944785c3a5..28886108ea 100644
--- a/indra/llmessage/llinstantmessage.cpp
+++ b/indra/llmessage/llinstantmessage.cpp
@@ -16,6 +16,7 @@
#include "lluuid.h"
#include "llsd.h"
#include "llsdserialize.h"
+#include "llsdutil.h"
#include "llmemory.h"
#include "message.h"
@@ -290,6 +291,35 @@ void LLIMInfo::unpackMessageBlock(LLMessageSystem* msg)
}
}
+LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info)
+{
+ LLSD param_version;
+ param_version["version"] = 1;
+ LLSD param_message;
+ param_message["from_id"] = im_info->mFromID;
+ param_message["from_group"] = im_info->mFromGroup;
+ param_message["to_id"] = im_info->mToID;
+ param_message["from_name"] = im_info->mName;
+ param_message["message"] = im_info->mMessage;
+ param_message["type"] = (S32)im_info->mIMType;
+ param_message["id"] = im_info->mID;
+ param_message["timestamp"] = (S32)im_info->mTimeStamp;
+ param_message["offline"] = (S32)im_info->mOffline;
+ param_message["parent_estate_id"] = (S32)im_info->mParentEstateID;
+ param_message["region_id"] = im_info->mRegionID;
+ param_message["position"] = ll_sd_from_vector3(im_info->mPosition);
+ if (im_info->mData) param_message["data"] = im_info->mData;
+ LLSD param_agent;
+ param_agent["agent_id"] = im_info->mFromID;
+
+ LLSD params;
+ params.append(param_version);
+ params.append(param_message);
+ params.append(param_agent);
+
+ return params;
+}
+
LLPointer<LLIMInfo> LLIMInfo::clone()
{
return new LLIMInfo(
diff --git a/indra/llmessage/llinstantmessage.h b/indra/llmessage/llinstantmessage.h
index c8138cf491..99b2734a70 100644
--- a/indra/llmessage/llinstantmessage.h
+++ b/indra/llmessage/llinstantmessage.h
@@ -74,17 +74,19 @@ enum EInstantMessage
// communicate with each other.
//
- // Start a session, or add users to a session.
+ // Add users to a session.
IM_SESSION_ADD = 13,
- // Start a session, but don't prune offline users
- IM_SESSION_OFFLINE_ADD = 14,
+ // IM sent automatically on call for help,
+ // sets up a way for each Helper reached to teleport to the
+ // helpee
+ IM_SESSION_911_SEND = 14,
// start a session with your gruop
IM_SESSION_GROUP_START = 15,
// start a session without a calling card (finder or objects)
- IM_SESSION_CARDLESS_START = 16,
+ IM_SESSION_CONFERENCE_START = 16,
// send a message to a session.
IM_SESSION_SEND = 17,
@@ -123,9 +125,9 @@ enum EInstantMessage
// Binary bucket contains the name of the session.
IM_SESSION_911_START = 29,
- // IM sent automatically on call for help,
- // sends a lure to each Helper reached
- IM_LURE_911 = 30,
+ // IM for requesting to teleport to the creator
+ // of a livehelp session (assuming they are verified first)
+ IM_TELEPORT_911 = 30,
// a message generated by a script which we don't want to
// be sent through e-mail. Similar to IM_FROM_TASK, but
@@ -266,6 +268,7 @@ public:
S32 mTTL;
};
+LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info);
void pack_instant_message(
LLMessageSystem* msgsystem,
diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp
index c1a9bc442e..869012e431 100644
--- a/indra/llmessage/lliohttpserver.cpp
+++ b/indra/llmessage/lliohttpserver.cpp
@@ -27,6 +27,8 @@
#include "llsdserialize_xml.h"
#include "llstl.h"
+#include <sstream>
+
static const char HTTP_VERSION_STR[] = "HTTP/1.0";
static const std::string CONTEXT_REQUEST("request");
static const std::string HTTP_VERB_GET("GET");
@@ -374,7 +376,7 @@ LLIOPipe::EStatus LLHTTPResponseHeader::process_impl(
class LLHTTPResponder : public LLIOPipe
{
public:
- LLHTTPResponder(const LLHTTPNode& tree);
+ LLHTTPResponder(const LLHTTPNode& tree, const LLSD& ctx);
~LLHTTPResponder();
protected:
@@ -435,6 +437,7 @@ protected:
STATE_SHORT_CIRCUIT
};
+ LLSD mBuildContext;
EState mState;
U8* mLastRead;
std::string mVerb;
@@ -443,12 +446,14 @@ protected:
std::string mQuery;
std::string mVersion;
S32 mContentLength;
+ LLSD mHeaders;
// handle the urls
const LLHTTPNode& mRootNode;
};
-LLHTTPResponder::LLHTTPResponder(const LLHTTPNode& tree) :
+LLHTTPResponder::LLHTTPResponder(const LLHTTPNode& tree, const LLSD& ctx) :
+ mBuildContext(ctx),
mState(STATE_NOTHING),
mLastRead(NULL),
mContentLength(0),
@@ -636,6 +641,11 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(
lldebugs << "Content-Length: " << value << llendl;
mContentLength = atoi(value.c_str());
}
+ else
+ {
+ LLString::trimTail(value);
+ mHeaders[name] = value;
+ }
}
}
}
@@ -701,6 +711,11 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(
chain.push_back(LLIOPipe::ptr_t(new LLIOFlush));
context[CONTEXT_REQUEST]["path"] = mPath;
context[CONTEXT_REQUEST]["query-string"] = mQuery;
+ context[CONTEXT_REQUEST]["remote-host"]
+ = mBuildContext["remote-host"];
+ context[CONTEXT_REQUEST]["remote-port"]
+ = mBuildContext["remote-port"];
+ context[CONTEXT_REQUEST]["headers"] = mHeaders;
const LLChainIOFactory* protocolHandler
= node->getProtocolHandler();
@@ -785,9 +800,10 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(
-void LLCreateHTTPPipe(LLPumpIO::chain_t& chain, const LLHTTPNode& root)
+void LLCreateHTTPPipe(LLPumpIO::chain_t& chain,
+ const LLHTTPNode& root, const LLSD& ctx)
{
- chain.push_back(LLIOPipe::ptr_t(new LLHTTPResponder(root)));
+ chain.push_back(LLIOPipe::ptr_t(new LLHTTPResponder(root, ctx)));
}
@@ -796,7 +812,7 @@ class LLHTTPResponseFactory : public LLChainIOFactory
public:
bool build(LLPumpIO::chain_t& chain, LLSD ctx) const
{
- LLCreateHTTPPipe(chain, mTree);
+ LLCreateHTTPPipe(chain, mTree, ctx);
return true;
}
diff --git a/indra/llmessage/lliohttpserver.h b/indra/llmessage/lliohttpserver.h
index 05dfdc4bf7..f11a1eccf6 100644
--- a/indra/llmessage/lliohttpserver.h
+++ b/indra/llmessage/lliohttpserver.h
@@ -31,7 +31,8 @@ LLHTTPNode& LLCreateHTTPServer(apr_pool_t* pool, LLPumpIO& pump, U16 port);
* for example), use the helper templates below.
*/
-void LLCreateHTTPPipe(LLPumpIO::chain_t& chain, const LLHTTPNode& root);
+void LLCreateHTTPPipe(LLPumpIO::chain_t& chain,
+ const LLHTTPNode& root, const LLSD& ctx);
/**< Create a pipe on the chain that handles HTTP requests.
* The requests are served by the node tree given at root.
*
diff --git a/indra/llmessage/lliopipe.h b/indra/llmessage/lliopipe.h
index 5cbe3d8743..6f7fbe652d 100644
--- a/indra/llmessage/lliopipe.h
+++ b/indra/llmessage/lliopipe.h
@@ -237,7 +237,7 @@ namespace boost
}
inline void intrusive_ptr_release(LLIOPipe* p)
{
- if(0 == --p->mReferenceCount)
+ if(p && 0 == --p->mReferenceCount)
{
delete p;
}
diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp
index 7649fef0cf..7c33153086 100644
--- a/indra/llmessage/lliosocket.cpp
+++ b/indra/llmessage/lliosocket.cpp
@@ -519,9 +519,20 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
if(llsocket)
{
PUMP_DEBUG;
+
+ apr_sockaddr_t* remote_addr;
+ apr_socket_addr_get(&remote_addr, APR_REMOTE, socket);
+
+ char* remote_host_string;
+ apr_sockaddr_ip_get(&remote_host_string, remote_addr);
+
+ LLSD context;
+ context["remote-host"] = remote_host_string;
+ context["remote-port"] = remote_addr->port;
+
LLPumpIO::chain_t chain;
chain.push_back(LLIOPipe::ptr_t(new LLIOSocketReader(llsocket)));
- if(mReactor->build(chain, LLSD()))
+ if(mReactor->build(chain, context))
{
chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(llsocket)));
pump->addChain(chain, mResponseTimeout);
diff --git a/indra/llmessage/llmessagebuilder.cpp b/indra/llmessage/llmessagebuilder.cpp
new file mode 100644
index 0000000000..d467e6d808
--- /dev/null
+++ b/indra/llmessage/llmessagebuilder.cpp
@@ -0,0 +1,18 @@
+/**
+ * @file llmessagebuilder.cpp
+ * @brief LLMessageBuilder class implementation
+ *
+ * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include "linden_common.h"
+
+#include "llmessagebuilder.h"
+
+//virtual
+LLMessageBuilder::~LLMessageBuilder()
+{
+ // even abstract base classes need a concrete destructor
+}
+
diff --git a/indra/llmessage/llmessagebuilder.h b/indra/llmessage/llmessagebuilder.h
new file mode 100644
index 0000000000..7ae09c54d5
--- /dev/null
+++ b/indra/llmessage/llmessagebuilder.h
@@ -0,0 +1,70 @@
+#ifndef LL_LLMESSAGEBUILDER_H
+#define LL_LLMESSAGEBUILDER_H
+
+#include <string>
+
+#include "stdtypes.h"
+
+class LLMsgData;
+class LLQuaternion;
+class LLSD;
+class LLUUID;
+class LLVector3;
+class LLVector3d;
+class LLVector4;
+
+class LLMessageBuilder
+{
+public:
+
+ //CLASS_LOG_TYPE(LLMessageBuilder);
+
+ virtual ~LLMessageBuilder();
+ virtual void newMessage(const char *name) = 0;
+
+ virtual void nextBlock(const char* blockname) = 0;
+ virtual BOOL removeLastBlock() = 0; // TODO: babbage: remove this horror
+
+ /** All add* methods expect pointers to canonical strings. */
+ virtual void addBinaryData(const char *varname, const void *data,
+ S32 size) = 0;
+ virtual void addBOOL(const char* varname, BOOL b) = 0;
+ virtual void addS8(const char *varname, S8 s) = 0;
+ virtual void addU8(const char *varname, U8 u) = 0;
+ virtual void addS16(const char *varname, S16 i) = 0;
+ virtual void addU16(const char *varname, U16 i) = 0;
+ virtual void addF32(const char *varname, F32 f) = 0;
+ virtual void addS32(const char *varname, S32 s) = 0;
+ virtual void addU32(const char *varname, U32 u) = 0;
+ virtual void addU64(const char *varname, U64 lu) = 0;
+ virtual void addF64(const char *varname, F64 d) = 0;
+ virtual void addVector3(const char *varname, const LLVector3& vec) = 0;
+ virtual void addVector4(const char *varname, const LLVector4& vec) = 0;
+ virtual void addVector3d(const char *varname, const LLVector3d& vec) = 0;
+ virtual void addQuat(const char *varname, const LLQuaternion& quat) = 0;
+ virtual void addUUID(const char *varname, const LLUUID& uuid) = 0;
+ virtual void addIPAddr(const char *varname, const U32 ip) = 0;
+ virtual void addIPPort(const char *varname, const U16 port) = 0;
+ virtual void addString(const char* varname, const char* s) = 0;
+ virtual void addString(const char* varname, const std::string& s) = 0;
+
+ virtual BOOL isMessageFull(const char* blockname) const = 0;
+ virtual void compressMessage(U8*& buf_ptr, U32& buffer_length) = 0;
+ virtual S32 getMessageSize() = 0;
+
+ virtual BOOL isBuilt() const = 0;
+ virtual BOOL isClear() const = 0;
+ virtual U32 buildMessage(U8* buffer, U32 buffer_size) = 0;
+ /**< Return built message size */
+ virtual void clearMessage() = 0;
+
+ // TODO: babbage: remove this horror
+ virtual void setBuilt(BOOL b) = 0;
+
+ virtual const char* getMessageName() const = 0;
+
+ virtual void copyFromMessageData(const LLMsgData& data) = 0;
+ virtual void copyFromLLSD(const LLSD& data) = 0;
+};
+
+#endif // LL_LLMESSAGEBUILDER_H
diff --git a/indra/llmessage/llmessageconfig.cpp b/indra/llmessage/llmessageconfig.cpp
new file mode 100644
index 0000000000..a2b0bc5efa
--- /dev/null
+++ b/indra/llmessage/llmessageconfig.cpp
@@ -0,0 +1,210 @@
+/**
+ * @file llmessageconfig.cpp
+ * @brief Live file handling for messaging
+ *
+ * Copyright (c) 2000-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include "linden_common.h"
+
+#include "llmessageconfig.h"
+#include "llfile.h"
+#include "lllivefile.h"
+#include "llsd.h"
+#include "llsdserialize.h"
+
+static const char messageConfigFileName[] = "message.xml";
+static const F32 messageConfigRefreshRate = 5.0; // seconds
+static std::string sServerName = "";
+static std::string sConfigDir = "";
+
+class LLMessageConfigFile : public LLLiveFile
+{
+private:
+ LLMessageConfigFile()
+ : LLLiveFile(fileName(), messageConfigRefreshRate),
+ mChanged(false)
+ { }
+
+ static std::string fileName();
+
+public:
+ static LLMessageConfigFile& instance();
+ // return the singleton configuration file
+
+protected:
+ /* virtual */ void loadFile();
+ void loadServerDefaults(const LLSD& data);
+ void loadMessages(const LLSD& data);
+
+public:
+ bool mChanged;
+
+ std::string mServerDefault;
+ LLSD mMessages;
+};
+
+std::string LLMessageConfigFile::fileName()
+{
+ std::ostringstream ostr;
+ ostr << sConfigDir//gAppSimp->getOption("configdir").asString()
+ << "/" << messageConfigFileName;
+ return ostr.str();
+}
+
+LLMessageConfigFile& LLMessageConfigFile::instance()
+{
+ static LLMessageConfigFile the_file;
+ the_file.checkAndReload();
+ return the_file;
+}
+
+// virtual
+void LLMessageConfigFile::loadFile()
+{
+ LLSD data;
+ {
+ llifstream file(filename().c_str());
+ if (file.is_open())
+ {
+ llinfos << "Loading message.xml file at " << fileName() << llendl;
+ LLSDSerialize::fromXML(data, file);
+ }
+
+ if (data.isUndefined())
+ {
+ llinfos << "LLMessageConfigFile::loadFile: file missing,"
+ " ill-formed, or simply undefined; not changing the"
+ " file" << llendl;
+ return;
+ }
+ }
+ loadServerDefaults(data);
+ loadMessages(data);
+}
+
+void LLMessageConfigFile::loadServerDefaults(const LLSD& data)
+{
+ mServerDefault = data["serverDefaults"][sServerName].asString();
+ lldebugs << "loading default " << mServerDefault << llendl;
+}
+
+void LLMessageConfigFile::loadMessages(const LLSD& data)
+{
+ mMessages = data["messages"];
+ std::ostringstream out;
+ LLSDXMLFormatter *formatter = new LLSDXMLFormatter;
+ formatter->format(mMessages, out);
+ lldebugs << "loading ... " << out.str()
+ << " LLMessageConfigFile::loadMessages loaded "
+ << mMessages.size() << " messages" << llendl;
+}
+
+
+//---------------------------------------------------------------
+// LLMessageConfig
+//---------------------------------------------------------------
+
+//static
+void LLMessageConfig::initClass(const std::string& server_name,
+ const std::string& config_dir)
+{
+ sServerName = server_name;
+ sConfigDir = config_dir;
+ (void) LLMessageConfigFile::instance();
+ llinfos << "LLMessageConfig::intiClass config file "
+ << config_dir << "/" << messageConfigFileName << llendl;
+}
+
+//static
+bool LLMessageConfig::isServerDefaultBuilderLLSD()
+{
+ if (sServerName.empty())
+ {
+ llerrs << "LLMessageConfig::isServerDefaultBuilderLLSD() before"
+ << " LLMessageConfig::initClass()" << llendl;
+ }
+ LLMessageConfigFile& file = LLMessageConfigFile::instance();
+ return (file.mServerDefault == "llsd");
+}
+
+//static
+bool LLMessageConfig::isServerDefaultBuilderTemplate()
+{
+ if (sServerName.empty())
+ {
+ llerrs << "LLMessageConfig::isServerDefaultBuilderTemplate() before"
+ << " LLMessageConfig::initClass()" << llendl;
+ }
+ LLMessageConfigFile& file = LLMessageConfigFile::instance();
+ return (file.mServerDefault == "template");
+}
+
+//static
+bool LLMessageConfig::isMessageBuiltLLSD(const std::string& msg_name)
+{
+ if (sServerName.empty())
+ {
+ llerrs << "LLMessageConfig::isMessageBuiltLLSD(name) before"
+ << " LLMessageConfig::initClass()" << llendl;
+ }
+ LLMessageConfigFile& file = LLMessageConfigFile::instance();
+ LLSD config = file.mMessages[msg_name];
+ if (!config.has("builder"))
+ {
+ return isServerDefaultBuilderLLSD();
+ }
+ return (config["builder"].asString() == "llsd");
+}
+
+//static
+bool LLMessageConfig::isMessageBuiltTemplate(const std::string& msg_name)
+{
+ if (sServerName.empty())
+ {
+ llerrs << "LLMessageConfig::isMessageBuiltTemplate(name) before"
+ << " LLMessageConfig::initClass()" << llendl;
+ }
+ LLMessageConfigFile& file = LLMessageConfigFile::instance();
+ LLSD config = file.mMessages[msg_name];
+ if (!config.has("builder"))
+ {
+ return isServerDefaultBuilderTemplate();
+ }
+ return (config["builder"].asString() == "template");
+}
+
+//static
+bool LLMessageConfig::isMessageTrusted(const std::string& msg_name)
+{
+ if (sServerName.empty())
+ {
+ llerrs << "LLMessageConfig::isMessageTrusted(name) before"
+ << " LLMessageConfig::initClass()" << llendl;
+ }
+ LLMessageConfigFile& file = LLMessageConfigFile::instance();
+ LLSD config = file.mMessages[msg_name];
+ if (!config.has("trusted-sender"))
+ {
+ return false;
+ }
+ return config["trusted-sender"].asBoolean();
+}
+
+//static
+bool LLMessageConfig::isValidUntrustedMessage(const std::string& msg_name)
+{
+ if (sServerName.empty())
+ {
+ llerrs << "LLMessageConfig::isMessageTrusted(name) before"
+ << " LLMessageConfig::initClass()" << llendl;
+ }
+ LLMessageConfigFile& file = LLMessageConfigFile::instance();
+ LLSD config = file.mMessages[msg_name];
+ if (!config.has("trusted-sender"))
+ {
+ return false;
+ }
+ return !(config["trusted-sender"].asBoolean());
+}
diff --git a/indra/llmessage/llmessageconfig.h b/indra/llmessage/llmessageconfig.h
new file mode 100644
index 0000000000..2fb6f2077e
--- /dev/null
+++ b/indra/llmessage/llmessageconfig.h
@@ -0,0 +1,31 @@
+/**
+ * @file llmessageconfig.h
+ * @brief Live file handling for messaging
+ *
+ * Copyright (c) 2000-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#ifndef LL_MESSAGECONFIG_H
+#define LL_MESSAGECONFIG_H
+
+#include <string>
+
+class LLMessageConfig
+{
+public:
+ static void initClass(const std::string& server_name,
+ const std::string& config_dir);
+ // force loading of config file during startup process
+ // so it can be used for startup features
+
+ static bool isServerDefaultBuilderLLSD();
+ static bool isServerDefaultBuilderTemplate();
+
+ // For individual messages
+ static bool isMessageBuiltLLSD(const std::string& msg_name);
+ static bool isMessageBuiltTemplate(const std::string& msg_name);
+ static bool isMessageTrusted(const std::string& msg_name);
+ static bool isValidUntrustedMessage(const std::string& msg_name);
+};
+#endif // LL_MESSAGECONFIG_H
diff --git a/indra/llmessage/llmessagereader.cpp b/indra/llmessage/llmessagereader.cpp
new file mode 100644
index 0000000000..4824480e32
--- /dev/null
+++ b/indra/llmessage/llmessagereader.cpp
@@ -0,0 +1,35 @@
+#include "llmessagereader.h"
+
+static BOOL sTimeDecodes = FALSE;
+
+static F32 sTimeDecodesSpamThreshold = 0.05f;
+
+//virtual
+LLMessageReader::~LLMessageReader()
+{
+ // even abstract base classes need a concrete destructor
+}
+
+//static
+void LLMessageReader::setTimeDecodes(BOOL b)
+{
+ sTimeDecodes = b;
+}
+
+//static
+void LLMessageReader::setTimeDecodesSpamThreshold(F32 seconds)
+{
+ sTimeDecodesSpamThreshold = seconds;
+}
+
+//static
+BOOL LLMessageReader::getTimeDecodes()
+{
+ return sTimeDecodes;
+}
+
+//static
+F32 LLMessageReader::getTimeDecodesSpamThreshold()
+{
+ return sTimeDecodesSpamThreshold;
+}
diff --git a/indra/llmessage/llmessagereader.h b/indra/llmessage/llmessagereader.h
new file mode 100644
index 0000000000..33ce9289f5
--- /dev/null
+++ b/indra/llmessage/llmessagereader.h
@@ -0,0 +1,59 @@
+#ifndef LL_LLMESSAGEREADER_H
+#define LL_LLMESSAGEREADER_H
+
+#include "stdtypes.h"
+
+class LLHost;
+class LLMessageBuilder;
+class LLMsgData;
+class LLQuaternion;
+class LLUUID;
+class LLVector3;
+class LLVector3d;
+class LLVector4;
+
+class LLMessageReader
+{
+ public:
+
+ virtual ~LLMessageReader();
+
+ /** All get* methods expect pointers to canonical strings. */
+ virtual void getBinaryData(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX) = 0;
+ virtual void getBOOL(const char *block, const char *var, BOOL &data, S32 blocknum = 0) = 0;
+ virtual void getS8(const char *block, const char *var, S8 &data, S32 blocknum = 0) = 0;
+ virtual void getU8(const char *block, const char *var, U8 &data, S32 blocknum = 0) = 0;
+ virtual void getS16(const char *block, const char *var, S16 &data, S32 blocknum = 0) = 0;
+ virtual void getU16(const char *block, const char *var, U16 &data, S32 blocknum = 0) = 0;
+ virtual void getS32(const char *block, const char *var, S32 &data, S32 blocknum = 0) = 0;
+ virtual void getF32(const char *block, const char *var, F32 &data, S32 blocknum = 0) = 0;
+ virtual void getU32(const char *block, const char *var, U32 &data, S32 blocknum = 0) = 0;
+ virtual void getU64(const char *block, const char *var, U64 &data, S32 blocknum = 0) = 0;
+ virtual void getF64(const char *block, const char *var, F64 &data, S32 blocknum = 0) = 0;
+ virtual void getVector3(const char *block, const char *var, LLVector3 &vec, S32 blocknum = 0) = 0;
+ virtual void getVector4(const char *block, const char *var, LLVector4 &vec, S32 blocknum = 0) = 0;
+ virtual void getVector3d(const char *block, const char *var, LLVector3d &vec, S32 blocknum = 0) = 0;
+ virtual void getQuat(const char *block, const char *var, LLQuaternion &q, S32 blocknum = 0) = 0;
+ virtual void getUUID(const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0) = 0;
+ virtual void getIPAddr(const char *block, const char *var, U32 &ip, S32 blocknum = 0) = 0;
+ virtual void getIPPort(const char *block, const char *var, U16 &port, S32 blocknum = 0) = 0;
+ virtual void getString(const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0) = 0;
+
+ virtual S32 getNumberOfBlocks(const char *blockname) = 0;
+ virtual S32 getSize(const char *blockname, const char *varname) = 0;
+ virtual S32 getSize(const char *blockname, S32 blocknum, const char *varname) = 0;
+
+ virtual void clearMessage() = 0;
+
+ virtual const char* getMessageName() const = 0;
+ virtual S32 getMessageSize() const = 0;
+
+ virtual void copyToBuilder(LLMessageBuilder&) const = 0;
+
+ static void setTimeDecodes(BOOL b);
+ static BOOL getTimeDecodes();
+ static void setTimeDecodesSpamThreshold(F32 seconds);
+ static F32 getTimeDecodesSpamThreshold();
+};
+
+#endif // LL_LLMESSAGEREADER_H
diff --git a/indra/llmessage/llmessagetemplate.cpp b/indra/llmessage/llmessagetemplate.cpp
new file mode 100644
index 0000000000..026843d6ec
--- /dev/null
+++ b/indra/llmessage/llmessagetemplate.cpp
@@ -0,0 +1,146 @@
+#include "linden_common.h"
+
+#include "llmessagetemplate.h"
+
+#include "message.h"
+
+void LLMsgVarData::addData(const void *data, S32 size, EMsgVariableType type, S32 data_size)
+{
+ mSize = size;
+ mDataSize = data_size;
+ if ( (type != MVT_VARIABLE) && (type != MVT_FIXED)
+ && (mType != MVT_VARIABLE) && (mType != MVT_FIXED))
+ {
+ if (mType != type)
+ {
+ llwarns << "Type mismatch in LLMsgVarData::addData for " << mName
+ << llendl;
+ }
+ }
+ if(size)
+ {
+ delete mData; // Delete it if it already exists
+ mData = new U8[size];
+ htonmemcpy(mData, data, mType, size);
+ }
+}
+
+void LLMsgData::addDataFast(char *blockname, char *varname, const void *data, S32 size, EMsgVariableType type, S32 data_size)
+{
+ // remember that if the blocknumber is > 0 then the number is appended to the name
+ char *namep = (char *)blockname;
+ LLMsgBlkData* block_data = mMemberBlocks[namep];
+ if (block_data->mBlockNumber)
+ {
+ namep += block_data->mBlockNumber;
+ block_data->addData(varname, data, size, type, data_size);
+ }
+ else
+ {
+ block_data->addData(varname, data, size, type, data_size);
+ }
+}
+
+// LLMessageVariable functions and friends
+
+std::ostream& operator<<(std::ostream& s, LLMessageVariable &msg)
+{
+ s << "\t\t" << msg.mName << " (";
+ switch (msg.mType)
+ {
+ case MVT_FIXED:
+ s << "Fixed, " << msg.mSize << " bytes total)\n";
+ break;
+ case MVT_VARIABLE:
+ s << "Variable, " << msg.mSize << " bytes of size info)\n";
+ break;
+ default:
+ s << "Unknown\n";
+ break;
+ }
+ return s;
+}
+
+// LLMessageBlock functions and friends
+
+std::ostream& operator<<(std::ostream& s, LLMessageBlock &msg)
+{
+ s << "\t" << msg.mName << " (";
+ switch (msg.mType)
+ {
+ case MBT_SINGLE:
+ s << "Fixed";
+ break;
+ case MBT_MULTIPLE:
+ s << "Multiple - " << msg.mNumber << " copies";
+ break;
+ case MBT_VARIABLE:
+ s << "Variable";
+ break;
+ default:
+ s << "Unknown";
+ break;
+ }
+ if (msg.mTotalSize != -1)
+ {
+ s << ", " << msg.mTotalSize << " bytes each, " << msg.mNumber*msg.mTotalSize << " bytes total)\n";
+ }
+ else
+ {
+ s << ")\n";
+ }
+
+
+ for (LLMessageBlock::message_variable_map_t::iterator iter = msg.mMemberVariables.begin();
+ iter != msg.mMemberVariables.end(); iter++)
+ {
+ LLMessageVariable& ci = *(iter->second);
+ s << ci;
+ }
+
+ return s;
+}
+
+// LLMessageTemplate functions and friends
+
+std::ostream& operator<<(std::ostream& s, LLMessageTemplate &msg)
+{
+ switch (msg.mFrequency)
+ {
+ case MFT_HIGH:
+ s << "========================================\n" << "Message #" << msg.mMessageNumber << "\n" << msg.mName << " (";
+ s << "High";
+ break;
+ case MFT_MEDIUM:
+ s << "========================================\n" << "Message #";
+ s << (msg.mMessageNumber & 0xFF) << "\n" << msg.mName << " (";
+ s << "Medium";
+ break;
+ case MFT_LOW:
+ s << "========================================\n" << "Message #";
+ s << (msg.mMessageNumber & 0xFFFF) << "\n" << msg.mName << " (";
+ s << "Low";
+ break;
+ default:
+ s << "Unknown";
+ break;
+ }
+
+ if (msg.mTotalSize != -1)
+ {
+ s << ", " << msg.mTotalSize << " bytes total)\n";
+ }
+ else
+ {
+ s << ")\n";
+ }
+
+ for (LLMessageTemplate::message_block_map_t::iterator iter = msg.mMemberBlocks.begin();
+ iter != msg.mMemberBlocks.end(); iter++)
+ {
+ LLMessageBlock* ci = iter->second;
+ s << *ci;
+ }
+
+ return s;
+}
diff --git a/indra/llmessage/llmessagetemplate.h b/indra/llmessage/llmessagetemplate.h
new file mode 100644
index 0000000000..8847ddc0d9
--- /dev/null
+++ b/indra/llmessage/llmessagetemplate.h
@@ -0,0 +1,356 @@
+#ifndef LL_LLMESSAGETEMPLATE_H
+#define LL_LLMESSAGETEMPLATE_H
+
+#include "lldarray.h"
+#include "message.h" // TODO: babbage: Remove...
+#include "llstl.h"
+
+class LLMsgVarData
+{
+public:
+ LLMsgVarData() : mName(NULL), mSize(-1), mDataSize(-1), mData(NULL), mType(MVT_U8)
+ {
+ }
+
+ LLMsgVarData(const char *name, EMsgVariableType type) : mSize(-1), mDataSize(-1), mData(NULL), mType(type)
+ {
+ mName = (char *)name;
+ }
+
+ ~LLMsgVarData()
+ {
+ // copy constructor just copies the mData pointer, so only delete mData explicitly
+ }
+
+ void deleteData()
+ {
+ delete[] mData;
+ mData = NULL;
+ }
+
+ void addData(const void *indata, S32 size, EMsgVariableType type, S32 data_size = -1);
+
+ char *getName() const { return mName; }
+ S32 getSize() const { return mSize; }
+ void *getData() { return (void*)mData; }
+ const void *getData() const { return (const void*)mData; }
+ S32 getDataSize() const { return mDataSize; }
+ EMsgVariableType getType() const { return mType; }
+
+protected:
+ char *mName;
+ S32 mSize;
+ S32 mDataSize;
+
+ U8 *mData;
+ EMsgVariableType mType;
+};
+
+class LLMsgBlkData
+{
+public:
+ LLMsgBlkData(const char *name, S32 blocknum) : mOffset(-1), mBlockNumber(blocknum), mTotalSize(-1)
+ {
+ mName = (char *)name;
+ }
+
+ ~LLMsgBlkData()
+ {
+ for (msg_var_data_map_t::iterator iter = mMemberVarData.begin();
+ iter != mMemberVarData.end(); iter++)
+ {
+ iter->deleteData();
+ }
+ }
+
+ void addVariable(const char *name, EMsgVariableType type)
+ {
+ LLMsgVarData tmp(name,type);
+ mMemberVarData[name] = tmp;
+ }
+
+ void addData(char *name, const void *data, S32 size, EMsgVariableType type, S32 data_size = -1)
+ {
+ LLMsgVarData* temp = &mMemberVarData[name]; // creates a new entry if one doesn't exist
+ temp->addData(data, size, type, data_size);
+ }
+
+ S32 mOffset;
+ S32 mBlockNumber;
+ typedef LLDynamicArrayIndexed<LLMsgVarData, const char *, 8> msg_var_data_map_t;
+ msg_var_data_map_t mMemberVarData;
+ char *mName;
+ S32 mTotalSize;
+};
+
+class LLMsgData
+{
+public:
+ LLMsgData(const char *name) : mTotalSize(-1)
+ {
+ mName = (char *)name;
+ }
+ ~LLMsgData()
+ {
+ for_each(mMemberBlocks.begin(), mMemberBlocks.end(), DeletePairedPointer());
+ }
+
+ void addBlock(LLMsgBlkData *blockp)
+ {
+ mMemberBlocks[blockp->mName] = blockp;
+ }
+
+ void addDataFast(char *blockname, char *varname, const void *data, S32 size, EMsgVariableType type, S32 data_size = -1);
+
+public:
+ S32 mOffset;
+ typedef std::map<char*, LLMsgBlkData*> msg_blk_data_map_t;
+ msg_blk_data_map_t mMemberBlocks;
+ char *mName;
+ S32 mTotalSize;
+};
+
+// LLMessage* classes store the template of messages
+class LLMessageVariable
+{
+public:
+ LLMessageVariable() : mName(NULL), mType(MVT_NULL), mSize(-1)
+ {
+ }
+
+ LLMessageVariable(char *name) : mType(MVT_NULL), mSize(-1)
+ {
+ mName = name;
+ }
+
+ LLMessageVariable(char *name, const EMsgVariableType type, const S32 size) : mType(type), mSize(size)
+ {
+ mName = gMessageStringTable.getString(name);
+ }
+
+ ~LLMessageVariable() {}
+
+ friend std::ostream& operator<<(std::ostream& s, LLMessageVariable &msg);
+
+ EMsgVariableType getType() const { return mType; }
+ S32 getSize() const { return mSize; }
+ char *getName() const { return mName; }
+protected:
+ char *mName;
+ EMsgVariableType mType;
+ S32 mSize;
+};
+
+
+typedef enum e_message_block_type
+{
+ MBT_NULL,
+ MBT_SINGLE,
+ MBT_MULTIPLE,
+ MBT_VARIABLE,
+ MBT_EOF
+} EMsgBlockType;
+
+class LLMessageBlock
+{
+public:
+ LLMessageBlock(char *name, EMsgBlockType type, S32 number = 1) : mType(type), mNumber(number), mTotalSize(0)
+ {
+ mName = gMessageStringTable.getString(name);
+ }
+
+ ~LLMessageBlock()
+ {
+ for_each(mMemberVariables.begin(), mMemberVariables.end(), DeletePairedPointer());
+ }
+
+ void addVariable(char *name, const EMsgVariableType type, const S32 size)
+ {
+ LLMessageVariable** varp = &mMemberVariables[name];
+ if (*varp != NULL)
+ {
+ llerrs << name << " has already been used as a variable name!" << llendl;
+ }
+ *varp = new LLMessageVariable(name, type, size);
+ if (((*varp)->getType() != MVT_VARIABLE)
+ &&(mTotalSize != -1))
+ {
+ mTotalSize += (*varp)->getSize();
+ }
+ else
+ {
+ mTotalSize = -1;
+ }
+ }
+
+ EMsgVariableType getVariableType(char *name)
+ {
+ return (mMemberVariables[name])->getType();
+ }
+
+ S32 getVariableSize(char *name)
+ {
+ return (mMemberVariables[name])->getSize();
+ }
+
+ friend std::ostream& operator<<(std::ostream& s, LLMessageBlock &msg);
+
+ typedef std::map<const char *, LLMessageVariable*> message_variable_map_t;
+ message_variable_map_t mMemberVariables;
+ char *mName;
+ EMsgBlockType mType;
+ S32 mNumber;
+ S32 mTotalSize;
+};
+
+
+enum EMsgFrequency
+{
+ MFT_NULL = 0, // value is size of message number in bytes
+ MFT_HIGH = 1,
+ MFT_MEDIUM = 2,
+ MFT_LOW = 4
+};
+
+typedef enum e_message_trust
+{
+ MT_TRUST,
+ MT_NOTRUST
+} EMsgTrust;
+
+enum EMsgEncoding
+{
+ ME_UNENCODED,
+ ME_ZEROCODED
+};
+
+class LLMessageTemplate
+{
+public:
+ LLMessageTemplate(const char *name, U32 message_number, EMsgFrequency freq)
+ :
+ //mMemberBlocks(),
+ mName(NULL),
+ mFrequency(freq),
+ mTrust(MT_NOTRUST),
+ mEncoding(ME_ZEROCODED),
+ mMessageNumber(message_number),
+ mTotalSize(0),
+ mReceiveCount(0),
+ mReceiveBytes(0),
+ mReceiveInvalid(0),
+ mDecodeTimeThisFrame(0.f),
+ mTotalDecoded(0),
+ mTotalDecodeTime(0.f),
+ mMaxDecodeTimePerMsg(0.f),
+ mBanFromTrusted(false),
+ mBanFromUntrusted(false),
+ mHandlerFunc(NULL),
+ mUserData(NULL)
+ {
+ mName = gMessageStringTable.getString(name);
+ }
+
+ ~LLMessageTemplate()
+ {
+ for_each(mMemberBlocks.begin(), mMemberBlocks.end(), DeletePairedPointer());
+ }
+
+ void addBlock(LLMessageBlock *blockp)
+ {
+ LLMessageBlock** member_blockp = &mMemberBlocks[blockp->mName];
+ if (*member_blockp != NULL)
+ {
+ llerrs << "Block " << blockp->mName
+ << "has already been used as a block name!" << llendl;
+ }
+ *member_blockp = blockp;
+ if ( (mTotalSize != -1)
+ &&(blockp->mTotalSize != -1)
+ &&( (blockp->mType == MBT_SINGLE)
+ ||(blockp->mType == MBT_MULTIPLE)))
+ {
+ mTotalSize += blockp->mNumber*blockp->mTotalSize;
+ }
+ else
+ {
+ mTotalSize = -1;
+ }
+ }
+
+ LLMessageBlock *getBlock(char *name)
+ {
+ return mMemberBlocks[name];
+ }
+
+ // Trusted messages can only be recieved on trusted circuits.
+ void setTrust(EMsgTrust t)
+ {
+ mTrust = t;
+ }
+
+ EMsgTrust getTrust(void)
+ {
+ return mTrust;
+ }
+
+ // controls for how the message should be encoded
+ void setEncoding(EMsgEncoding e)
+ {
+ mEncoding = e;
+ }
+ EMsgEncoding getEncoding()
+ {
+ return mEncoding;
+ }
+
+ void setHandlerFunc(void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data)
+ {
+ mHandlerFunc = handler_func;
+ mUserData = user_data;
+ }
+
+ BOOL callHandlerFunc(LLMessageSystem *msgsystem)
+ {
+ if (mHandlerFunc)
+ {
+ mHandlerFunc(msgsystem, mUserData);
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ bool isBanned(bool trustedSource)
+ {
+ return trustedSource ? mBanFromTrusted : mBanFromUntrusted;
+ }
+
+ friend std::ostream& operator<<(std::ostream& s, LLMessageTemplate &msg);
+
+public:
+ typedef std::map<char*, LLMessageBlock*> message_block_map_t;
+ message_block_map_t mMemberBlocks;
+ char *mName;
+ EMsgFrequency mFrequency;
+ EMsgTrust mTrust;
+ EMsgEncoding mEncoding;
+ U32 mMessageNumber;
+ S32 mTotalSize;
+ U32 mReceiveCount; // how many of this template have been received since last reset
+ U32 mReceiveBytes; // How many bytes received
+ U32 mReceiveInvalid; // How many "invalid" packets
+ F32 mDecodeTimeThisFrame; // Total seconds spent decoding this frame
+ U32 mTotalDecoded; // Total messages successfully decoded
+ F32 mTotalDecodeTime; // Total time successfully decoding messages
+ F32 mMaxDecodeTimePerMsg;
+
+ bool mBanFromTrusted;
+ bool mBanFromUntrusted;
+
+private:
+ // message handler function (this is set by each application)
+ void (*mHandlerFunc)(LLMessageSystem *msgsystem, void **user_data);
+ void **mUserData;
+};
+
+#endif // LL_LLMESSAGETEMPLATE_H
diff --git a/indra/llmessage/llmsgvariabletype.h b/indra/llmessage/llmsgvariabletype.h
new file mode 100644
index 0000000000..360d949690
--- /dev/null
+++ b/indra/llmessage/llmsgvariabletype.h
@@ -0,0 +1,33 @@
+#ifndef LL_LLMSGVARIABLETYPE_H
+#define LL_LLMSGVARIABLETYPE_H
+
+typedef enum e_message_variable_type
+{
+ MVT_NULL,
+ MVT_FIXED,
+ MVT_VARIABLE,
+ MVT_U8,
+ MVT_U16,
+ MVT_U32,
+ MVT_U64,
+ MVT_S8,
+ MVT_S16,
+ MVT_S32,
+ MVT_S64,
+ MVT_F32,
+ MVT_F64,
+ MVT_LLVector3,
+ MVT_LLVector3d,
+ MVT_LLVector4,
+ MVT_LLQuaternion,
+ MVT_LLUUID,
+ MVT_BOOL,
+ MVT_IP_ADDR,
+ MVT_IP_PORT,
+ MVT_U16Vec3,
+ MVT_U16Quat,
+ MVT_S16Array,
+ MVT_EOL
+} EMsgVariableType;
+
+#endif // LL_LLMSGVARIABLETYPE_H
diff --git a/indra/llmessage/llpacketack.h b/indra/llmessage/llpacketack.h
index 0874da6236..4c22dc2d62 100644
--- a/indra/llmessage/llpacketack.h
+++ b/indra/llmessage/llpacketack.h
@@ -44,6 +44,14 @@ public:
public:
LLReliablePacketParams()
{
+ clear();
+ };
+
+ ~LLReliablePacketParams() { };
+
+ void clear()
+ {
+ mHost.invalidate();
mRetries = 0;
mPingBasedRetry = TRUE;
mTimeout = 0.f;
@@ -52,8 +60,6 @@ public:
mMessageName = NULL;
};
- ~LLReliablePacketParams() { };
-
void set ( const LLHost &host, S32 retries, BOOL ping_based_retry,
F32 timeout,
void (*callback)(void **,S32), void **callback_data, char *name )
@@ -117,7 +123,13 @@ public:
}
};
- ~LLReliablePacket(){ delete [] mBuffer; };
+
+ ~LLReliablePacket()
+ {
+ mCallback = NULL;
+ delete [] mBuffer;
+ mBuffer = NULL;
+ };
friend class LLCircuitData;
protected:
diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp
index 1be6c21cc2..4fa3fab1c9 100644
--- a/indra/llmessage/llpumpio.cpp
+++ b/indra/llmessage/llpumpio.cpp
@@ -314,6 +314,12 @@ bool LLPumpIO::copyCurrentLinkInfo(links_t& links) const
void LLPumpIO::pump()
{
+ pump(DEFAULT_POLL_TIMEOUT);
+}
+
+//timeout is in microseconds
+void LLPumpIO::pump(const S32& poll_timeout)
+{
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
LLFastTimer t1(LLFastTimer::FTM_PUMP);
//llinfos << "LLPumpIO::pump()" << llendl;
@@ -395,7 +401,7 @@ void LLPumpIO::pump()
S32 count = 0;
S32 client_id = 0;
const apr_pollfd_t* poll_fd = NULL;
- apr_pollset_poll(mPollset, DEFAULT_POLL_TIMEOUT, &count, &poll_fd);
+ apr_pollset_poll(mPollset, poll_timeout, &count, &poll_fd);
PUMP_DEBUG;
for(S32 i = 0; i < count; ++i)
{
diff --git a/indra/llmessage/llpumpio.h b/indra/llmessage/llpumpio.h
index 50f7411298..5edfbdf8ee 100644
--- a/indra/llmessage/llpumpio.h
+++ b/indra/llmessage/llpumpio.h
@@ -227,6 +227,7 @@ public:
* chain has a file descriptor ready, <code>process()</code> will
* be called for all pipes which have requested it.
*/
+ void pump(const S32& poll_timeout);
void pump();
/**
diff --git a/indra/llmessage/llsdmessagebuilder.cpp b/indra/llmessage/llsdmessagebuilder.cpp
new file mode 100755
index 0000000000..b7deb4817f
--- /dev/null
+++ b/indra/llmessage/llsdmessagebuilder.cpp
@@ -0,0 +1,281 @@
+#include "linden_common.h"
+
+#include "llsdmessagebuilder.h"
+
+#include "llmessagetemplate.h"
+#include "llquaternion.h"
+#include "llsdutil.h"
+#include "llsdserialize.h"
+#include "u64.h"
+#include "v3dmath.h"
+#include "v3math.h"
+#include "v4math.h"
+
+LLSDMessageBuilder::LLSDMessageBuilder() :
+ mCurrentMessage(LLSD::emptyMap()),
+ mCurrentBlock(NULL),
+ mCurrentMessageName(""),
+ mCurrentBlockName(""),
+ mbSBuilt(FALSE),
+ mbSClear(TRUE)
+{
+}
+
+//virtual
+LLSDMessageBuilder::~LLSDMessageBuilder()
+{
+}
+
+
+// virtual
+void LLSDMessageBuilder::newMessage(const char *name)
+{
+ mbSBuilt = FALSE;
+ mbSClear = FALSE;
+
+ mCurrentMessage = LLSD::emptyMap();
+ mCurrentMessageName = (char *)name;
+}
+
+// virtual
+void LLSDMessageBuilder::clearMessage()
+{
+ mbSBuilt = FALSE;
+ mbSClear = TRUE;
+
+ mCurrentMessage = LLSD::emptyMap();
+ mCurrentMessageName = "";
+}
+
+// virtual
+void LLSDMessageBuilder::nextBlock(const char* blockname)
+{
+ LLSD& block = mCurrentMessage[blockname];
+ if(block.isUndefined())
+ {
+ block[0] = LLSD::emptyMap();
+ mCurrentBlock = &(block[0]);
+ }
+ else if(block.isArray())
+ {
+ block[block.size()] = LLSD::emptyMap();
+ mCurrentBlock = &(block[block.size() - 1]);
+ }
+ else
+ {
+ llerrs << "existing block not array" << llendl;
+ }
+}
+
+// TODO: Remove this horror...
+BOOL LLSDMessageBuilder::removeLastBlock()
+{
+ /* TODO: finish implementing this */
+ return FALSE;
+}
+
+void LLSDMessageBuilder::addBinaryData(const char *varname,
+ const void *data, S32 size)
+{
+ std::vector<U8> v;
+ v.resize(size);
+ memcpy(&(v[0]), reinterpret_cast<const U8*>(data), size);
+ (*mCurrentBlock)[varname] = v;
+}
+
+void LLSDMessageBuilder::addS8(const char *varname, S8 v)
+{
+ (*mCurrentBlock)[varname] = v;
+}
+
+void LLSDMessageBuilder::addU8(const char *varname, U8 v)
+{
+ (*mCurrentBlock)[varname] = v;
+}
+
+void LLSDMessageBuilder::addS16(const char *varname, S16 v)
+{
+ (*mCurrentBlock)[varname] = v;
+}
+
+void LLSDMessageBuilder::addU16(const char *varname, U16 v)
+{
+ (*mCurrentBlock)[varname] = v;
+}
+
+void LLSDMessageBuilder::addF32(const char *varname, F32 v)
+{
+ (*mCurrentBlock)[varname] = v;
+}
+
+void LLSDMessageBuilder::addS32(const char *varname, S32 v)
+{
+ (*mCurrentBlock)[varname] = v;
+}
+
+void LLSDMessageBuilder::addU32(const char *varname, U32 v)
+{
+ (*mCurrentBlock)[varname] = ll_sd_from_U32(v);
+}
+
+void LLSDMessageBuilder::addU64(const char *varname, U64 v)
+{
+ (*mCurrentBlock)[varname] = ll_sd_from_U64(v);
+}
+
+void LLSDMessageBuilder::addF64(const char *varname, F64 v)
+{
+ (*mCurrentBlock)[varname] = v;
+}
+
+void LLSDMessageBuilder::addIPAddr(const char *varname, U32 v)
+{
+ (*mCurrentBlock)[varname] = ll_sd_from_ipaddr(v);
+}
+
+void LLSDMessageBuilder::addIPPort(const char *varname, U16 v)
+{
+ (*mCurrentBlock)[varname] = v;
+}
+
+void LLSDMessageBuilder::addBOOL(const char* varname, BOOL v)
+{
+ (*mCurrentBlock)[varname] = (v == TRUE);
+}
+
+void LLSDMessageBuilder::addString(const char* varname, const char* v)
+{
+ if (v)
+ (*mCurrentBlock)[varname] = v; /* Flawfinder: ignore */
+ else
+ (*mCurrentBlock)[varname] = "";
+}
+
+void LLSDMessageBuilder::addString(const char* varname, const std::string& v)
+{
+ if (v.size())
+ (*mCurrentBlock)[varname] = v;
+ else
+ (*mCurrentBlock)[varname] = "";
+}
+
+void LLSDMessageBuilder::addVector3(const char *varname, const LLVector3& v)
+{
+ (*mCurrentBlock)[varname] = ll_sd_from_vector3(v);
+}
+
+void LLSDMessageBuilder::addVector4(const char *varname, const LLVector4& v)
+{
+ (*mCurrentBlock)[varname] = ll_sd_from_vector4(v);
+}
+
+void LLSDMessageBuilder::addVector3d(const char *varname, const LLVector3d& v)
+{
+ (*mCurrentBlock)[varname] = ll_sd_from_vector3d(v);
+}
+
+void LLSDMessageBuilder::addQuat(const char *varname, const LLQuaternion& v)
+{
+ (*mCurrentBlock)[varname] = ll_sd_from_quaternion(v);
+}
+
+void LLSDMessageBuilder::addUUID(const char *varname, const LLUUID& v)
+{
+ (*mCurrentBlock)[varname] = v;
+}
+
+void LLSDMessageBuilder::compressMessage(U8*& buf_ptr, U32& buffer_length)
+{
+}
+
+BOOL LLSDMessageBuilder::isMessageFull(const char* blockname) const
+{
+ return FALSE;
+}
+
+// make sure that all the desired data is in place and then copy the data
+// into MAX_BUFFER_SIZEd buffer
+U32 LLSDMessageBuilder::buildMessage(U8* buffer, U32 buffer_size)
+{
+ return 0;
+}
+
+void LLSDMessageBuilder::copyFromMessageData(const LLMsgData& data)
+{
+ // copy the blocks
+ // counting variables used to encode multiple block info
+ S32 block_count = 0;
+ char *block_name = NULL;
+
+ // loop through msg blocks to loop through variables, totalling up size
+ // data and filling the new (send) message
+ LLMsgData::msg_blk_data_map_t::const_iterator iter =
+ data.mMemberBlocks.begin();
+ LLMsgData::msg_blk_data_map_t::const_iterator end =
+ data.mMemberBlocks.end();
+ for(; iter != end; ++iter)
+ {
+ const LLMsgBlkData* mbci = iter->second;
+ if(!mbci) continue;
+
+ // do we need to encode a block code?
+ if (block_count == 0)
+ {
+ block_count = mbci->mBlockNumber;
+ block_name = (char *)mbci->mName;
+ }
+
+ // counting down mutliple blocks
+ block_count--;
+
+ nextBlock(block_name);
+
+ // now loop through the variables
+ LLMsgBlkData::msg_var_data_map_t::const_iterator dit = mbci->mMemberVarData.begin();
+ LLMsgBlkData::msg_var_data_map_t::const_iterator dend = mbci->mMemberVarData.end();
+
+ for(; dit != dend; ++dit)
+ {
+ //const LLMsgVarData& mvci = *dit;
+
+ // TODO: Copy mvci data in to block:
+ // (*mCurrentBlock)[varname] = v;
+ }
+ }
+}
+
+//virtual
+void LLSDMessageBuilder::copyFromLLSD(const LLSD& msg)
+{
+ mCurrentMessage = msg;
+ llinfos << LLSDXMLStreamer(mCurrentMessage) << llendl;
+}
+
+const LLSD& LLSDMessageBuilder::getMessage() const
+{
+ return mCurrentMessage;
+}
+
+//virtual
+void LLSDMessageBuilder::setBuilt(BOOL b) { mbSBuilt = b; }
+
+//virtual
+BOOL LLSDMessageBuilder::isBuilt() const {return mbSBuilt;}
+
+//virtual
+BOOL LLSDMessageBuilder::isClear() const {return mbSClear;}
+
+//virtual
+S32 LLSDMessageBuilder::getMessageSize()
+{
+ // babbage: size is unknown as message stored as LLSD.
+ // return non-zero if pending data, as send can be skipped for 0 size.
+ // return 1 to encourage senders checking size against splitting message.
+ return mCurrentMessage.size()? 1 : 0;
+}
+
+//virtual
+const char* LLSDMessageBuilder::getMessageName() const
+{
+ return mCurrentMessageName.c_str();
+}
diff --git a/indra/llmessage/llsdmessagebuilder.h b/indra/llmessage/llsdmessagebuilder.h
new file mode 100755
index 0000000000..f04194d12f
--- /dev/null
+++ b/indra/llmessage/llsdmessagebuilder.h
@@ -0,0 +1,98 @@
+#ifndef LL_LLSDMESSAGEBUILDER_H
+#define LL_LLSDMESSAGEBUILDER_H
+
+#include <map>
+
+#include "llmessagebuilder.h"
+#include "llmsgvariabletype.h"
+#include "llsd.h"
+
+class LLMessageTemplate;
+class LLMsgData;
+
+class LLSDMessageBuilder : public LLMessageBuilder
+{
+public:
+
+ //CLASS_LOG_TYPE(LLSDMessageBuilder);
+
+ LLSDMessageBuilder();
+ virtual ~LLSDMessageBuilder();
+
+ virtual void newMessage(const char *name);
+
+ virtual void nextBlock(const char* blockname);
+ virtual BOOL removeLastBlock(); // TODO: babbage: remove this horror...
+
+ /** All add* methods expect pointers to canonical varname strings. */
+ virtual void addBinaryData(const char *varname, const void *data,
+ S32 size);
+ virtual void addBOOL(const char* varname, BOOL b);
+ virtual void addS8(const char *varname, S8 s);
+ virtual void addU8(const char *varname, U8 u);
+ virtual void addS16(const char *varname, S16 i);
+ virtual void addU16(const char *varname, U16 i);
+ virtual void addF32(const char *varname, F32 f);
+ virtual void addS32(const char *varname, S32 s);
+ virtual void addU32(const char *varname, U32 u);
+ virtual void addU64(const char *varname, U64 lu);
+ virtual void addF64(const char *varname, F64 d);
+ virtual void addVector3(const char *varname, const LLVector3& vec);
+ virtual void addVector4(const char *varname, const LLVector4& vec);
+ virtual void addVector3d(const char *varname, const LLVector3d& vec);
+ virtual void addQuat(const char *varname, const LLQuaternion& quat);
+ virtual void addUUID(const char *varname, const LLUUID& uuid);
+ virtual void addIPAddr(const char *varname, const U32 ip);
+ virtual void addIPPort(const char *varname, const U16 port);
+ virtual void addString(const char* varname, const char* s);
+ virtual void addString(const char* varname, const std::string& s);
+
+ virtual BOOL isMessageFull(const char* blockname) const;
+ virtual void compressMessage(U8*& buf_ptr, U32& buffer_length);
+
+ virtual BOOL isBuilt() const;
+ virtual BOOL isClear() const;
+ virtual U32 buildMessage(U8* buffer, U32 buffer_size);
+ /**< Return built message size */
+
+ virtual void clearMessage();
+
+ // TODO: babbage: remove this horror.
+ virtual void setBuilt(BOOL b);
+
+ virtual S32 getMessageSize();
+ virtual const char* getMessageName() const;
+
+ virtual void copyFromMessageData(const LLMsgData& data);
+
+ virtual void copyFromLLSD(const LLSD& msg);
+
+ const LLSD& getMessage() const;
+private:
+
+ /* mCurrentMessage is of the following format:
+ mCurrentMessage = { 'block_name1' : [ { 'block1_field1' : 'b1f1_data',
+ 'block1_field2' : 'b1f2_data',
+ ...
+ 'block1_fieldn' : 'b1fn_data'},
+ { 'block2_field1' : 'b2f1_data',
+ 'block2_field2' : 'b2f2_data',
+ ...
+ 'block2_fieldn' : 'b2fn_data'},
+ ...
+ { 'blockm_field1' : 'bmf1_data',
+ 'blockm_field2' : 'bmf2_data',
+ ...
+ 'blockm_fieldn' : 'bmfn_data'} ],
+ 'block_name2' : ...,
+ ...
+ 'block_namem' } */
+ LLSD mCurrentMessage;
+ LLSD* mCurrentBlock;
+ std::string mCurrentMessageName;
+ std::string mCurrentBlockName;
+ BOOL mbSBuilt;
+ BOOL mbSClear;
+};
+
+#endif // LL_LLSDMESSAGEBUILDER_H
diff --git a/indra/llmessage/llsdmessagereader.cpp b/indra/llmessage/llsdmessagereader.cpp
new file mode 100755
index 0000000000..6312bee0ab
--- /dev/null
+++ b/indra/llmessage/llsdmessagereader.cpp
@@ -0,0 +1,264 @@
+#include "llsdmessagereader.h"
+#include "llsdutil.h"
+#include "llmessagebuilder.h"
+#include "llsdmessagebuilder.h"
+
+LLSDMessageReader::LLSDMessageReader()
+{
+}
+
+//virtual
+LLSDMessageReader::~LLSDMessageReader()
+{
+}
+
+
+LLSD getLLSD(const LLSD& input, const char* block, const char* var, S32 blocknum)
+{
+ if(input[block].isArray())
+ {
+ return input[block][blocknum][var];
+ }
+ return LLSD();
+}
+
+//virtual
+void LLSDMessageReader::getBinaryData(const char *block, const char *var,
+ void *datap, S32 size, S32 blocknum,
+ S32 max_size)
+{
+ std::vector<U8> data = getLLSD(mMessage, block, var, blocknum);
+ S32 data_size = (S32)data.size();
+
+ if (size && data_size != size)
+ {
+ return;
+ }
+
+ if (max_size < data_size)
+ {
+ data_size = max_size;
+ }
+
+ memcpy(datap, &(data[0]), data_size);
+}
+
+//virtual
+void LLSDMessageReader::getBOOL(const char *block, const char *var,
+ BOOL &data,
+ S32 blocknum)
+{
+ data = getLLSD(mMessage, block, var, blocknum);
+}
+
+//virtual
+void LLSDMessageReader::getS8(const char *block, const char *var, S8 &data,
+ S32 blocknum)
+{
+ data = getLLSD(mMessage, block, var, blocknum).asInteger();
+}
+
+//virtual
+void LLSDMessageReader::getU8(const char *block, const char *var, U8 &data,
+ S32 blocknum)
+{
+ data = getLLSD(mMessage, block, var, blocknum).asInteger();
+}
+
+//virtual
+void LLSDMessageReader::getS16(const char *block, const char *var, S16 &data,
+ S32 blocknum)
+{
+ data = getLLSD(mMessage, block, var, blocknum).asInteger();
+}
+
+//virtual
+void LLSDMessageReader::getU16(const char *block, const char *var, U16 &data,
+ S32 blocknum)
+{
+ data = getLLSD(mMessage, block, var, blocknum).asInteger();
+}
+
+//virtual
+void LLSDMessageReader::getS32(const char *block, const char *var, S32 &data,
+ S32 blocknum)
+{
+ data = getLLSD(mMessage, block, var, blocknum);
+}
+
+//virtual
+void LLSDMessageReader::getF32(const char *block, const char *var, F32 &data,
+ S32 blocknum)
+{
+ data = (F32)getLLSD(mMessage, block, var, blocknum).asReal();
+}
+
+//virtual
+void LLSDMessageReader::getU32(const char *block, const char *var, U32 &data,
+ S32 blocknum)
+{
+ data = ll_U32_from_sd(getLLSD(mMessage, block, var, blocknum));
+}
+
+//virtual
+void LLSDMessageReader::getU64(const char *block, const char *var,
+ U64 &data, S32 blocknum)
+{
+ data = ll_U64_from_sd(getLLSD(mMessage, block, var, blocknum));
+}
+
+//virtual
+void LLSDMessageReader::getF64(const char *block, const char *var,
+ F64 &data, S32 blocknum)
+{
+ data = getLLSD(mMessage, block, var, blocknum);
+}
+
+//virtual
+void LLSDMessageReader::getVector3(const char *block, const char *var,
+ LLVector3 &vec, S32 blocknum)
+{
+ vec = ll_vector3_from_sd(getLLSD(mMessage, block, var, blocknum));
+}
+
+//virtual
+void LLSDMessageReader::getVector4(const char *block, const char *var,
+ LLVector4 &vec, S32 blocknum)
+{
+ vec = ll_vector4_from_sd(getLLSD(mMessage, block, var, blocknum));
+}
+
+//virtual
+void LLSDMessageReader::getVector3d(const char *block, const char *var,
+ LLVector3d &vec, S32 blocknum)
+{
+ vec = ll_vector3d_from_sd(getLLSD(mMessage, block, var, blocknum));
+}
+
+//virtual
+void LLSDMessageReader::getQuat(const char *block, const char *var,
+ LLQuaternion &q, S32 blocknum)
+{
+ q = ll_quaternion_from_sd(getLLSD(mMessage, block, var, blocknum));
+}
+
+//virtual
+void LLSDMessageReader::getUUID(const char *block, const char *var,
+ LLUUID &uuid, S32 blocknum)
+{
+ uuid = getLLSD(mMessage, block, var, blocknum);
+}
+
+//virtual
+void LLSDMessageReader::getIPAddr(const char *block, const char *var,
+ U32 &ip, S32 blocknum)
+{
+ ip = ll_ipaddr_from_sd(getLLSD(mMessage, block, var, blocknum));
+}
+
+//virtual
+void LLSDMessageReader::getIPPort(const char *block, const char *var,
+ U16 &port, S32 blocknum)
+{
+ port = getLLSD(mMessage, block, var, blocknum).asInteger();
+}
+
+//virtual
+void LLSDMessageReader::getString(const char *block, const char *var,
+ S32 buffer_size, char *buffer, S32 blocknum)
+{
+ std::string data = getLLSD(mMessage, block, var, blocknum);
+
+ S32 data_size = data.size();
+ if (data_size >= buffer_size)
+ {
+ data_size = buffer_size - 1;
+ }
+ memcpy(buffer, data.data(), data_size);
+ buffer[data_size] = '\0';
+}
+
+
+//virtual
+S32 LLSDMessageReader::getNumberOfBlocks(const char *blockname)
+{
+ return mMessage[blockname].size();
+}
+
+S32 getElementSize(const LLSD& llsd)
+{
+ LLSD::Type type = llsd.type();
+ switch(type)
+ {
+ case LLSD::TypeBoolean:
+ return sizeof(bool);
+ case LLSD::TypeInteger:
+ return sizeof(S32);
+ case LLSD::TypeReal:
+ return sizeof(F64);
+ case LLSD::TypeString:
+ return llsd.asString().size();
+ case LLSD::TypeUUID:
+ return sizeof(LLUUID);
+ case LLSD::TypeDate:
+ return sizeof(LLDate);
+ case LLSD::TypeURI:
+ return sizeof(LLURI);
+ case LLSD::TypeBinary:
+ {
+ std::vector<U8> data = llsd;
+ return data.size() * sizeof(U8);
+ }
+ case LLSD::TypeMap:
+ case LLSD::TypeArray:
+ case LLSD::TypeUndefined:
+ return 0;
+ }
+ return 0;
+}
+
+//virtual
+//Mainly used to find size of binary block of data
+S32 LLSDMessageReader::getSize(const char *blockname, const char *varname)
+{
+ return getElementSize(mMessage[blockname][0][varname]);
+}
+
+
+//virtual
+S32 LLSDMessageReader::getSize(const char *blockname, S32 blocknum,
+ const char *varname)
+{
+ return getElementSize(mMessage[blockname][blocknum][varname]);
+}
+
+//virtual
+void LLSDMessageReader::clearMessage()
+{
+ mMessage = LLSD();
+}
+
+//virtual
+const char* LLSDMessageReader::getMessageName() const
+{
+ return mMessageName.c_str();
+}
+
+// virtual
+S32 LLSDMessageReader::getMessageSize() const
+{
+ return 0;
+}
+
+//virtual
+void LLSDMessageReader::copyToBuilder(LLMessageBuilder& builder) const
+{
+ builder.copyFromLLSD(mMessage);
+}
+
+void LLSDMessageReader::setMessage(const std::string& name, const LLSD& message)
+{
+ mMessageName = name;
+ // TODO: Validate
+ mMessage = message;
+}
diff --git a/indra/llmessage/llsdmessagereader.h b/indra/llmessage/llsdmessagereader.h
new file mode 100755
index 0000000000..57851941a2
--- /dev/null
+++ b/indra/llmessage/llsdmessagereader.h
@@ -0,0 +1,79 @@
+#ifndef LL_LLSDMESSAGEREADER_H
+#define LL_LLSDMESSAGEREADER_H
+
+#include "llmessagereader.h"
+#include "llsd.h"
+
+#include <map>
+
+class LLMessageTemplate;
+class LLMsgData;
+
+class LLSDMessageReader : public LLMessageReader
+{
+public:
+
+ LLSDMessageReader();
+ virtual ~LLSDMessageReader();
+
+ /** All get* methods expect pointers to canonical strings. */
+ virtual void getBinaryData(const char *block, const char *var,
+ void *datap, S32 size, S32 blocknum = 0,
+ S32 max_size = S32_MAX);
+ virtual void getBOOL(const char *block, const char *var, BOOL &data,
+ S32 blocknum = 0);
+ virtual void getS8(const char *block, const char *var, S8 &data,
+ S32 blocknum = 0);
+ virtual void getU8(const char *block, const char *var, U8 &data,
+ S32 blocknum = 0);
+ virtual void getS16(const char *block, const char *var, S16 &data,
+ S32 blocknum = 0);
+ virtual void getU16(const char *block, const char *var, U16 &data,
+ S32 blocknum = 0);
+ virtual void getS32(const char *block, const char *var, S32 &data,
+ S32 blocknum = 0);
+ virtual void getF32(const char *block, const char *var, F32 &data,
+ S32 blocknum = 0);
+ virtual void getU32(const char *block, const char *var, U32 &data,
+ S32 blocknum = 0);
+ virtual void getU64(const char *block, const char *var, U64 &data,
+ S32 blocknum = 0);
+ virtual void getF64(const char *block, const char *var, F64 &data,
+ S32 blocknum = 0);
+ virtual void getVector3(const char *block, const char *var,
+ LLVector3 &vec, S32 blocknum = 0);
+ virtual void getVector4(const char *block, const char *var,
+ LLVector4 &vec, S32 blocknum = 0);
+ virtual void getVector3d(const char *block, const char *var,
+ LLVector3d &vec, S32 blocknum = 0);
+ virtual void getQuat(const char *block, const char *var, LLQuaternion &q,
+ S32 blocknum = 0);
+ virtual void getUUID(const char *block, const char *var, LLUUID &uuid,
+ S32 blocknum = 0);
+ virtual void getIPAddr(const char *block, const char *var, U32 &ip,
+ S32 blocknum = 0);
+ virtual void getIPPort(const char *block, const char *var, U16 &port,
+ S32 blocknum = 0);
+ virtual void getString(const char *block, const char *var,
+ S32 buffer_size, char *buffer, S32 blocknum = 0);
+
+ virtual S32 getNumberOfBlocks(const char *blockname);
+ virtual S32 getSize(const char *blockname, const char *varname);
+ virtual S32 getSize(const char *blockname, S32 blocknum,
+ const char *varname);
+
+ virtual void clearMessage();
+
+ virtual const char* getMessageName() const;
+ virtual S32 getMessageSize() const;
+
+ virtual void copyToBuilder(LLMessageBuilder&) const;
+
+ void setMessage(const std::string& name, const LLSD& msg);
+
+private:
+ std::string mMessageName;
+ LLSD mMessage;
+};
+
+#endif // LL_LLSDMESSAGEREADER_H
diff --git a/indra/llmessage/llservice.h b/indra/llmessage/llservice.h
index e243e710d6..fe6fa56477 100644
--- a/indra/llmessage/llservice.h
+++ b/indra/llmessage/llservice.h
@@ -71,7 +71,7 @@ namespace boost
}
inline void intrusive_ptr_release(LLServiceCreator* p)
{
- if(0 == --p->mReferenceCount)
+ if(p && 0 == --p->mReferenceCount)
{
delete p;
}
diff --git a/indra/llmessage/llservicebuilder.cpp b/indra/llmessage/llservicebuilder.cpp
new file mode 100644
index 0000000000..fbcf38ae35
--- /dev/null
+++ b/indra/llmessage/llservicebuilder.cpp
@@ -0,0 +1,115 @@
+/**
+* @file llservicebuilder.cpp
+* @brief Implementation of the LLServiceBuilder class.
+*
+* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
+* $License$
+*/
+
+#include "llapp.h"
+#include "llfile.h"
+#include "llservicebuilder.h"
+#include "llsd.h"
+#include "llsdserialize.h"
+
+void LLServiceBuilder::loadServiceDefinitionsFromFile(
+ const std::string& service_filename)
+{
+ llifstream service_file(service_filename.c_str(), std::ios::binary);
+ if(service_file.is_open())
+ {
+ LLSD service_data;
+ LLSDSerialize::fromXML(service_data, service_file);
+ service_file.close();
+ // Load service
+ LLSD service_map = service_data["services"];
+ for(LLSD::array_iterator array_itr = service_map.beginArray();
+ array_itr != service_map.endArray();
+ ++array_itr)
+ {
+ LLSD service_llsd = (*array_itr)["service-builder"];
+ std::string service_name = (*array_itr)["name"].asString();
+ createServiceDefinition(service_name, service_llsd);
+ }
+ llinfos << "loaded config file: " << service_filename << llendl;
+ }
+ else
+ {
+ llwarns << "unable to find config file: " << service_filename << llendl;
+ }
+}
+
+void LLServiceBuilder::createServiceDefinition(
+ const std::string& service_name,
+ LLSD& service_llsd)
+{
+ if(service_llsd.isString())
+ {
+ mServiceMap[ service_name ] = service_llsd.asString();
+ }
+ else if(service_llsd.isMap())
+ {
+ for(LLSD::map_iterator map_itr = service_llsd.beginMap();
+ map_itr != service_llsd.endMap();
+ ++map_itr)
+ {
+ std::string compound_builder_name = service_name;
+ compound_builder_name.append("-");
+ compound_builder_name.append((*map_itr).first);
+ mServiceMap[ compound_builder_name ] = (*map_itr).second.asString();
+ }
+ }
+}
+
+std::string LLServiceBuilder::buildServiceURI(const std::string& service_name)
+{
+ std::ostringstream service_url;
+ // Find the service builder
+ if(mServiceMap.find(service_name) != mServiceMap.end())
+ {
+ // construct the service builder url
+ LLApp* app = LLApp::instance();
+ if(app)
+ {
+ LLSD base_url = app->getOption("services-base-url");
+ service_url << base_url.asString();
+ }
+ service_url << mServiceMap[service_name];
+ }
+ else
+ {
+ llwarns << "Cannot find service " << service_name << llendl;
+ }
+ return service_url.str();
+}
+
+std::string LLServiceBuilder::buildServiceURI(
+ const std::string& service_name,
+ const LLSD& option_map)
+{
+ std::string service_url = buildServiceURI(service_name);
+
+ // Find the Service Name
+ if(!service_url.empty() && option_map.isMap())
+ {
+ // Do brace replacements - NOT CURRENTLY RECURSIVE
+ for(LLSD::map_const_iterator option_itr = option_map.beginMap();
+ option_itr != option_map.endMap();
+ ++option_itr)
+ {
+ std::string variable_name = "{$";
+ variable_name.append((*option_itr).first);
+ variable_name.append("}");
+ std::string::size_type find_pos = service_url.find(variable_name);
+ if(find_pos != std::string::npos)
+ {
+ service_url.replace(
+ find_pos,
+ variable_name.length(),
+ (*option_itr).second.asString());
+ }
+ }
+ }
+
+ return service_url;
+}
diff --git a/indra/llmessage/llservicebuilder.h b/indra/llmessage/llservicebuilder.h
new file mode 100644
index 0000000000..2692ffe1e5
--- /dev/null
+++ b/indra/llmessage/llservicebuilder.h
@@ -0,0 +1,73 @@
+/**
+* @file llservicebuilder.h
+* @brief Declaration of the LLServiceBuilder class.
+*
+* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
+* $License$
+*/
+
+#ifndef LLSERVICEBUILDER_H
+#define LLSERVICEBUILDER_H
+
+#include <string>
+#include <map>
+#include "llerror.h"
+
+class LLSD;
+
+/**
+ * @class LLServiceBuilder
+ * @brief This class builds urls for us to use when making web service calls.
+ */
+
+class LLServiceBuilder
+{
+ LOG_CLASS(LLServiceBuilder);
+public:
+ LLServiceBuilder(void) {}
+ ~LLServiceBuilder(void) {}
+
+ /**
+ * @brief Initialize this object with the service definitions.
+ *
+ * @param service_filename The services definition files -- services.xml.
+ */
+ void loadServiceDefinitionsFromFile(const std::string& service_filename);
+
+ /**
+ * @brief Build a service url if the url needs no construction parameters.
+ *
+ * @param service_name The name of the service you want to call.
+ */
+ std::string buildServiceURI(const std::string& service_name);
+
+ /**
+ * @brief Build a service url if the url with construction parameters.
+ *
+ * The parameter substitution supports string substituition from RUSS:
+ * [[Recursive_URL_Substitution_Syntax]]
+ * @param service_name The name of the service you want to call.
+ * @param option_map The parameters in a map of name:value for the service.
+ */
+ std::string buildServiceURI(
+ const std::string& service_name,
+ const LLSD& option_map);
+
+public:
+ /**
+ * @brief Helper method which builds construction state for a service
+ *
+ * This method should probably be protected, but we need to test this
+ * method.
+ */
+ void createServiceDefinition(
+ const std::string& service_name,
+ LLSD& service_url);
+
+protected:
+ std::map<std::string, std::string> mServiceMap;
+};
+
+
+
+#endif
diff --git a/indra/llmessage/lltemplatemessagebuilder.cpp b/indra/llmessage/lltemplatemessagebuilder.cpp
new file mode 100644
index 0000000000..806f03422d
--- /dev/null
+++ b/indra/llmessage/lltemplatemessagebuilder.cpp
@@ -0,0 +1,856 @@
+#include "linden_common.h"
+
+#include "lltemplatemessagebuilder.h"
+
+#include "llmessagetemplate.h"
+#include "llquaternion.h"
+#include "u64.h"
+#include "v3dmath.h"
+#include "v3math.h"
+#include "v4math.h"
+
+LLTemplateMessageBuilder::LLTemplateMessageBuilder(message_template_name_map_t& name_template_map) :
+ mCurrentSMessageData(NULL),
+ mCurrentSMessageTemplate(NULL),
+ mCurrentSDataBlock(NULL),
+ mCurrentSMessageName(NULL),
+ mCurrentSBlockName(NULL),
+ mbSBuilt(FALSE),
+ mbSClear(TRUE),
+ mCurrentSendTotal(0),
+ mMessageTemplates(name_template_map)
+{
+}
+
+//virtual
+LLTemplateMessageBuilder::~LLTemplateMessageBuilder()
+{
+ delete mCurrentSMessageData;
+ mCurrentSMessageData = NULL;
+}
+
+
+// virtual
+void LLTemplateMessageBuilder::newMessage(const char *name)
+{
+ mbSBuilt = FALSE;
+ mbSClear = FALSE;
+
+ mCurrentSendTotal = 0;
+
+ delete mCurrentSMessageData;
+ mCurrentSMessageData = NULL;
+
+ char *namep = (char *)name;
+
+ if (mMessageTemplates.count(namep) > 0)
+ {
+ mCurrentSMessageTemplate = mMessageTemplates[namep];
+ if (mCurrentSMessageData)
+ {
+ delete mCurrentSMessageData;
+ }
+ mCurrentSMessageData = new LLMsgData(namep);
+ mCurrentSMessageName = namep;
+ mCurrentSDataBlock = NULL;
+ mCurrentSBlockName = NULL;
+
+ // add at one of each block
+ LLMessageTemplate* msg_template = mMessageTemplates[namep];
+ for (LLMessageTemplate::message_block_map_t::iterator iter = msg_template->mMemberBlocks.begin();
+ iter != msg_template->mMemberBlocks.end(); iter++)
+ {
+ LLMessageBlock* ci = iter->second;
+ LLMsgBlkData *tblockp;
+ tblockp = new LLMsgBlkData(ci->mName, 0);
+ mCurrentSMessageData->addBlock(tblockp);
+ }
+ }
+ else
+ {
+ llerrs << "newMessage - Message " << name << " not registered" << llendl;
+ }
+}
+
+// virtual
+void LLTemplateMessageBuilder::clearMessage()
+{
+ mbSBuilt = FALSE;
+ mbSClear = TRUE;
+
+ mCurrentSendTotal = 0;
+
+ mCurrentSMessageTemplate = NULL;
+
+ delete mCurrentSMessageData;
+ mCurrentSMessageData = NULL;
+
+ mCurrentSMessageName = NULL;
+ mCurrentSDataBlock = NULL;
+ mCurrentSBlockName = NULL;
+}
+
+// virtual
+void LLTemplateMessageBuilder::nextBlock(const char* blockname)
+{
+ char *bnamep = (char *)blockname;
+
+ if (!mCurrentSMessageTemplate)
+ {
+ llerrs << "newMessage not called prior to setBlock" << llendl;
+ return;
+ }
+
+ // now, does this block exist?
+ LLMessageTemplate::message_block_map_t::iterator temp_iter = mCurrentSMessageTemplate->mMemberBlocks.find(bnamep);
+ if (temp_iter == mCurrentSMessageTemplate->mMemberBlocks.end())
+ {
+ llerrs << "LLTemplateMessageBuilder::nextBlock " << bnamep
+ << " not a block in " << mCurrentSMessageTemplate->mName << llendl;
+ return;
+ }
+
+ LLMessageBlock* template_data = temp_iter->second;
+
+ // ok, have we already set this block?
+ LLMsgBlkData* block_data = mCurrentSMessageData->mMemberBlocks[bnamep];
+ if (block_data->mBlockNumber == 0)
+ {
+ // nope! set this as the current block
+ block_data->mBlockNumber = 1;
+ mCurrentSDataBlock = block_data;
+ mCurrentSBlockName = bnamep;
+
+ // add placeholders for each of the variables
+ for (LLMessageBlock::message_variable_map_t::iterator iter = template_data->mMemberVariables.begin();
+ iter != template_data->mMemberVariables.end(); iter++)
+ {
+ LLMessageVariable& ci = *(iter->second);
+ mCurrentSDataBlock->addVariable(ci.getName(), ci.getType());
+ }
+ return;
+ }
+ else
+ {
+ // already have this block. . .
+ // are we supposed to have a new one?
+
+ // if the block is type MBT_SINGLE this is bad!
+ if (template_data->mType == MBT_SINGLE)
+ {
+ llerrs << "LLTemplateMessageBuilder::nextBlock called multiple times"
+ << " for " << bnamep << " but is type MBT_SINGLE" << llendl;
+ return;
+ }
+
+
+ // if the block is type MBT_MULTIPLE then we need a known number,
+ // make sure that we're not exceeding it
+ if ( (template_data->mType == MBT_MULTIPLE)
+ &&(mCurrentSDataBlock->mBlockNumber == template_data->mNumber))
+ {
+ llerrs << "LLTemplateMessageBuilder::nextBlock called "
+ << mCurrentSDataBlock->mBlockNumber << " times for " << bnamep
+ << " exceeding " << template_data->mNumber
+ << " specified in type MBT_MULTIPLE." << llendl;
+ return;
+ }
+
+ // ok, we can make a new one
+ // modify the name to avoid name collision by adding number to end
+ S32 count = block_data->mBlockNumber;
+
+ // incrememt base name's count
+ block_data->mBlockNumber++;
+
+ if (block_data->mBlockNumber > MAX_BLOCKS)
+ {
+ llerrs << "Trying to pack too many blocks into MBT_VARIABLE type "
+ << "(limited to " << MAX_BLOCKS << ")" << llendl;
+ }
+
+ // create new name
+ // Nota Bene: if things are working correctly,
+ // mCurrentMessageData->mMemberBlocks[blockname]->mBlockNumber ==
+ // mCurrentDataBlock->mBlockNumber + 1
+
+ char *nbnamep = bnamep + count;
+
+ mCurrentSDataBlock = new LLMsgBlkData(bnamep, count);
+ mCurrentSDataBlock->mName = nbnamep;
+ mCurrentSMessageData->mMemberBlocks[nbnamep] = mCurrentSDataBlock;
+
+ // add placeholders for each of the variables
+ for (LLMessageBlock::message_variable_map_t::iterator
+ iter = template_data->mMemberVariables.begin(),
+ end = template_data->mMemberVariables.end();
+ iter != end; iter++)
+ {
+ LLMessageVariable& ci = *(iter->second);
+ mCurrentSDataBlock->addVariable(ci.getName(), ci.getType());
+ }
+ return;
+ }
+}
+
+// TODO: Remove this horror...
+BOOL LLTemplateMessageBuilder::removeLastBlock()
+{
+ if (mCurrentSBlockName)
+ {
+ if ( (mCurrentSMessageData)
+ &&(mCurrentSMessageTemplate))
+ {
+ if (mCurrentSMessageData->mMemberBlocks[mCurrentSBlockName]->mBlockNumber >= 1)
+ {
+ // At least one block for the current block name.
+
+ // Store the current block name for future reference.
+ char *block_name = mCurrentSBlockName;
+
+ // Decrement the sent total by the size of the
+ // data in the message block that we're currently building.
+
+ LLMessageBlock* template_data = mCurrentSMessageTemplate->mMemberBlocks[mCurrentSBlockName];
+
+ for (LLMessageBlock::message_variable_map_t::iterator iter = template_data->mMemberVariables.begin();
+ iter != template_data->mMemberVariables.end(); iter++)
+ {
+ LLMessageVariable& ci = *(iter->second);
+ mCurrentSendTotal -= ci.getSize();
+ }
+
+
+ // Now we want to find the block that we're blowing away.
+
+ // Get the number of blocks.
+ LLMsgBlkData* block_data = mCurrentSMessageData->mMemberBlocks[block_name];
+ S32 num_blocks = block_data->mBlockNumber;
+
+ // Use the same (suspect?) algorithm that's used to generate
+ // the names in the nextBlock method to find it.
+ char *block_getting_whacked = block_name + num_blocks - 1;
+ LLMsgBlkData* whacked_data = mCurrentSMessageData->mMemberBlocks[block_getting_whacked];
+ delete whacked_data;
+ mCurrentSMessageData->mMemberBlocks.erase(block_getting_whacked);
+
+ if (num_blocks <= 1)
+ {
+ // we just blew away the last one, so return FALSE
+ llwarns << "not blowing away the only block of message "
+ << mCurrentSMessageName
+ << ". Block: " << block_name
+ << ". Number: " << num_blocks
+ << llendl;
+ return FALSE;
+ }
+ else
+ {
+ // Decrement the counter.
+ block_data->mBlockNumber--;
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+// add data to variable in current block
+void LLTemplateMessageBuilder::addData(const char *varname, const void *data, EMsgVariableType type, S32 size)
+{
+ char *vnamep = (char *)varname;
+
+ // do we have a current message?
+ if (!mCurrentSMessageTemplate)
+ {
+ llerrs << "newMessage not called prior to addData" << llendl;
+ return;
+ }
+
+ // do we have a current block?
+ if (!mCurrentSDataBlock)
+ {
+ llerrs << "setBlock not called prior to addData" << llendl;
+ return;
+ }
+
+ // kewl, add the data if it exists
+ LLMessageVariable* var_data = mCurrentSMessageTemplate->mMemberBlocks[mCurrentSBlockName]->mMemberVariables[vnamep];
+ if (!var_data || !var_data->getName())
+ {
+ llerrs << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << llendl;
+ return;
+ }
+
+ // ok, it seems ok. . . are we the correct size?
+ if (var_data->getType() == MVT_VARIABLE)
+ {
+ // Variable 1 can only store 255 bytes, make sure our data is smaller
+ if ((var_data->getSize() == 1) &&
+ (size > 255))
+ {
+ llwarns << "Field " << varname << " is a Variable 1 but program "
+ << "attempted to stuff more than 255 bytes in "
+ << "(" << size << "). Clamping size and truncating data." << llendl;
+ size = 255;
+ char *truncate = (char *)data;
+ truncate[255] = 0;
+ }
+
+ // no correct size for MVT_VARIABLE, instead we need to tell how many bytes the size will be encoded as
+ mCurrentSDataBlock->addData(vnamep, data, size, type, var_data->getSize());
+ mCurrentSendTotal += size;
+ }
+ else
+ {
+ if (size != var_data->getSize())
+ {
+ llerrs << varname << " is type MVT_FIXED but request size " << size << " doesn't match template size "
+ << var_data->getSize() << llendl;
+ return;
+ }
+ // alright, smash it in
+ mCurrentSDataBlock->addData(vnamep, data, size, type);
+ mCurrentSendTotal += size;
+ }
+}
+
+// add data to variable in current block - fails if variable isn't MVT_FIXED
+void LLTemplateMessageBuilder::addData(const char *varname, const void *data, EMsgVariableType type)
+{
+ char *vnamep = (char *)varname;
+
+ // do we have a current message?
+ if (!mCurrentSMessageTemplate)
+ {
+ llerrs << "newMessage not called prior to addData" << llendl;
+ return;
+ }
+
+ // do we have a current block?
+ if (!mCurrentSDataBlock)
+ {
+ llerrs << "setBlock not called prior to addData" << llendl;
+ return;
+ }
+
+ // kewl, add the data if it exists
+ LLMessageVariable* var_data = mCurrentSMessageTemplate->mMemberBlocks[mCurrentSBlockName]->mMemberVariables[vnamep];
+ if (!var_data->getName())
+ {
+ llerrs << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << llendl;
+ return;
+ }
+
+ // ok, it seems ok. . . are we MVT_VARIABLE?
+ if (var_data->getType() == MVT_VARIABLE)
+ {
+ // nope
+ llerrs << vnamep << " is type MVT_VARIABLE. Call using addData(name, data, size)" << llendl;
+ return;
+ }
+ else
+ {
+ mCurrentSDataBlock->addData(vnamep, data, var_data->getSize(), type);
+ mCurrentSendTotal += var_data->getSize();
+ }
+}
+
+void LLTemplateMessageBuilder::addBinaryData(const char *varname,
+ const void *data, S32 size)
+{
+ addData(varname, data, MVT_FIXED, size);
+}
+
+void LLTemplateMessageBuilder::addS8(const char *varname, S8 s)
+{
+ addData(varname, &s, MVT_S8, sizeof(s));
+}
+
+void LLTemplateMessageBuilder::addU8(const char *varname, U8 u)
+{
+ addData(varname, &u, MVT_U8, sizeof(u));
+}
+
+void LLTemplateMessageBuilder::addS16(const char *varname, S16 i)
+{
+ addData(varname, &i, MVT_S16, sizeof(i));
+}
+
+void LLTemplateMessageBuilder::addU16(const char *varname, U16 i)
+{
+ addData(varname, &i, MVT_U16, sizeof(i));
+}
+
+void LLTemplateMessageBuilder::addF32(const char *varname, F32 f)
+{
+ addData(varname, &f, MVT_F32, sizeof(f));
+}
+
+void LLTemplateMessageBuilder::addS32(const char *varname, S32 s)
+{
+ addData(varname, &s, MVT_S32, sizeof(s));
+}
+
+void LLTemplateMessageBuilder::addU32(const char *varname, U32 u)
+{
+ addData(varname, &u, MVT_U32, sizeof(u));
+}
+
+void LLTemplateMessageBuilder::addU64(const char *varname, U64 lu)
+{
+ addData(varname, &lu, MVT_U64, sizeof(lu));
+}
+
+void LLTemplateMessageBuilder::addF64(const char *varname, F64 d)
+{
+ addData(varname, &d, MVT_F64, sizeof(d));
+}
+
+void LLTemplateMessageBuilder::addIPAddr(const char *varname, U32 u)
+{
+ addData(varname, &u, MVT_IP_ADDR, sizeof(u));
+}
+
+void LLTemplateMessageBuilder::addIPPort(const char *varname, U16 u)
+{
+ u = htons(u);
+ addData(varname, &u, MVT_IP_PORT, sizeof(u));
+}
+
+void LLTemplateMessageBuilder::addBOOL(const char* varname, BOOL b)
+{
+ // Can't just cast a BOOL (actually a U32) to a U8.
+ // In some cases the low order bits will be zero.
+ U8 temp = (b != 0);
+ addData(varname, &temp, MVT_BOOL, sizeof(temp));
+}
+
+void LLTemplateMessageBuilder::addString(const char* varname, const char* s)
+{
+ if (s)
+ addData( varname, (void *)s, MVT_VARIABLE, (S32)strlen(s) + 1); /* Flawfinder: ignore */
+ else
+ addData( varname, NULL, MVT_VARIABLE, 0);
+}
+
+void LLTemplateMessageBuilder::addString(const char* varname, const std::string& s)
+{
+ if (s.size())
+ addData( varname, (void *)s.c_str(), MVT_VARIABLE, (S32)(s.size()) + 1);
+ else
+ addData( varname, NULL, MVT_VARIABLE, 0);
+}
+
+void LLTemplateMessageBuilder::addVector3(const char *varname, const LLVector3& vec)
+{
+ addData(varname, vec.mV, MVT_LLVector3, sizeof(vec.mV));
+}
+
+void LLTemplateMessageBuilder::addVector4(const char *varname, const LLVector4& vec)
+{
+ addData(varname, vec.mV, MVT_LLVector4, sizeof(vec.mV));
+}
+
+void LLTemplateMessageBuilder::addVector3d(const char *varname, const LLVector3d& vec)
+{
+ addData(varname, vec.mdV, MVT_LLVector3d, sizeof(vec.mdV));
+}
+
+void LLTemplateMessageBuilder::addQuat(const char *varname, const LLQuaternion& quat)
+{
+ addData(varname, quat.packToVector3().mV, MVT_LLQuaternion, sizeof(LLVector3));
+}
+
+void LLTemplateMessageBuilder::addUUID(const char *varname, const LLUUID& uuid)
+{
+ addData(varname, uuid.mData, MVT_LLUUID, sizeof(uuid.mData));
+}
+
+static S32 zero_code(U8 **data, U32 *data_size)
+{
+ // Encoded send buffer needs to be slightly larger since the zero
+ // coding can potentially increase the size of the send data.
+ static U8 encodedSendBuffer[2 * MAX_BUFFER_SIZE];
+
+ S32 count = *data_size;
+
+ S32 net_gain = 0;
+ U8 num_zeroes = 0;
+
+ U8 *inptr = (U8 *)*data;
+ U8 *outptr = (U8 *)encodedSendBuffer;
+
+// skip the packet id field
+
+ for (U32 i=0;i<LL_PACKET_ID_SIZE;i++)
+ {
+ count--;
+ *outptr++ = *inptr++;
+ }
+
+// build encoded packet, keeping track of net size gain
+
+// sequential zero bytes are encoded as 0 [U8 count]
+// with 0 0 [count] representing wrap (>256 zeroes)
+
+ while (count--)
+ {
+ if (!(*inptr)) // in a zero count
+ {
+ if (num_zeroes)
+ {
+ if (++num_zeroes > 254)
+ {
+ *outptr++ = num_zeroes;
+ num_zeroes = 0;
+ }
+ net_gain--; // subseqent zeroes save one
+ }
+ else
+ {
+ *outptr++ = 0;
+ net_gain++; // starting a zero count adds one
+ num_zeroes = 1;
+ }
+ inptr++;
+ }
+ else
+ {
+ if (num_zeroes)
+ {
+ *outptr++ = num_zeroes;
+ num_zeroes = 0;
+ }
+ *outptr++ = *inptr++;
+ }
+ }
+
+ if (num_zeroes)
+ {
+ *outptr++ = num_zeroes;
+ }
+
+ if (net_gain < 0)
+ {
+ // TODO: babbage: reinstate stat collecting...
+ //mCompressedPacketsOut++;
+ //mUncompressedBytesOut += *data_size;
+
+ *data = encodedSendBuffer;
+ *data_size += net_gain;
+ encodedSendBuffer[0] |= LL_ZERO_CODE_FLAG; // set the head bit to indicate zero coding
+
+ //mCompressedBytesOut += *data_size;
+
+ }
+ //mTotalBytesOut += *data_size;
+
+ return(net_gain);
+}
+
+void LLTemplateMessageBuilder::compressMessage(U8*& buf_ptr, U32& buffer_length)
+{
+ if(ME_ZEROCODED == mCurrentSMessageTemplate->getEncoding())
+ {
+ zero_code(&buf_ptr, &buffer_length);
+ }
+}
+
+BOOL LLTemplateMessageBuilder::isMessageFull(const char* blockname) const
+{
+ if(mCurrentSendTotal > MTUBYTES)
+ {
+ return TRUE;
+ }
+ if(!blockname)
+ {
+ return FALSE;
+ }
+ char* bnamep = (char*)blockname;
+ S32 max;
+
+ LLMessageBlock* template_data = mCurrentSMessageTemplate->mMemberBlocks[bnamep];
+
+ switch(template_data->mType)
+ {
+ case MBT_SINGLE:
+ max = 1;
+ break;
+ case MBT_MULTIPLE:
+ max = template_data->mNumber;
+ break;
+ case MBT_VARIABLE:
+ default:
+ max = MAX_BLOCKS;
+ break;
+ }
+ if(mCurrentSMessageData->mMemberBlocks[bnamep]->mBlockNumber >= max)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+// make sure that all the desired data is in place and then copy the data into MAX_BUFFER_SIZEd buffer
+U32 LLTemplateMessageBuilder::buildMessage(U8* buffer, U32 buffer_size)
+{
+ // basic algorithm is to loop through the various pieces, building
+ // size and offset info if we encounter a -1 for mSize at any
+ // point that variable wasn't given data
+
+ // do we have a current message?
+ if (!mCurrentSMessageTemplate)
+ {
+ llerrs << "newMessage not called prior to buildMessage" << llendl;
+ return 0;
+ }
+
+ // zero out some useful values
+
+ // leave room for circuit counter
+ U32 result = LL_PACKET_ID_SIZE;
+
+ // encode message number and adjust total_offset
+ if (mCurrentSMessageTemplate->mFrequency == MFT_HIGH)
+ {
+// old, endian-dependant way
+// memcpy(&buffer[result], &mCurrentMessageTemplate->mMessageNumber, sizeof(U8));
+
+// new, independant way
+ buffer[result] = (U8)mCurrentSMessageTemplate->mMessageNumber;
+ result += sizeof(U8);
+ }
+ else if (mCurrentSMessageTemplate->mFrequency == MFT_MEDIUM)
+ {
+ U8 temp = 255;
+ memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/
+ result += sizeof(U8);
+
+ // mask off unsightly bits
+ temp = mCurrentSMessageTemplate->mMessageNumber & 255;
+ memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/
+ result += sizeof(U8);
+ }
+ else if (mCurrentSMessageTemplate->mFrequency == MFT_LOW)
+ {
+ U8 temp = 255;
+ U16 message_num;
+ memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/
+ result += sizeof(U8);
+ memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/
+ result += sizeof(U8);
+
+ // mask off unsightly bits
+ message_num = mCurrentSMessageTemplate->mMessageNumber & 0xFFFF;
+
+ // convert to network byte order
+ message_num = htons(message_num);
+ memcpy(&buffer[result], &message_num, sizeof(U16)); /*Flawfinder: ignore*/
+ result += sizeof(U16);
+ }
+ else
+ {
+ llerrs << "unexpected message frequency in buildMessage" << llendl;
+ return 0;
+ }
+
+ // counting variables used to encode multiple block info
+ S32 block_count = 0;
+ U8 temp_block_number;
+
+ // loop through msg blocks to loop through variables,
+ // totalling up size data and copying into buffer
+ for (LLMsgData::msg_blk_data_map_t::iterator
+ iter = mCurrentSMessageData->mMemberBlocks.begin(),
+ end = mCurrentSMessageData->mMemberBlocks.end();
+ iter != end; iter++)
+ {
+ LLMsgBlkData* mbci = iter->second;
+ // do we need to encode a block code?
+ if (block_count == 0)
+ {
+ block_count = mbci->mBlockNumber;
+
+ LLMessageBlock* template_data =
+ mCurrentSMessageTemplate->mMemberBlocks[mbci->mName];
+
+ // ok, if this is the first block of a repeating pack, set
+ // block_count and, if it's type MBT_VARIABLE encode a byte
+ // for how many there are
+ if (template_data->mType == MBT_VARIABLE)
+ {
+ // remember that mBlockNumber is a S32
+ temp_block_number = (U8)mbci->mBlockNumber;
+ if ((S32)(result + sizeof(U8)) < MAX_BUFFER_SIZE)
+ {
+ memcpy(&buffer[result], &temp_block_number, sizeof(U8));
+ result += sizeof(U8);
+ }
+ else
+ {
+ // Just reporting error is likely not enough. Need
+ // to check how to abort or error out gracefully
+ // from this function. XXXTBD
+ llerrs << "buildMessage failed. Message excedding "
+ << "sendBuffersize." << llendl;
+ }
+ }
+ else if (template_data->mType == MBT_MULTIPLE)
+ {
+ if (block_count != template_data->mNumber)
+ {
+ // nope! need to fill it in all the way!
+ llerrs << "Block " << mbci->mName
+ << " is type MBT_MULTIPLE but only has data for "
+ << block_count << " out of its "
+ << template_data->mNumber << " blocks" << llendl;
+ }
+ }
+ }
+
+ // counting down multiple blocks
+ block_count--;
+
+ // now loop through the variables
+ for (LLMsgBlkData::msg_var_data_map_t::iterator iter = mbci->mMemberVarData.begin();
+ iter != mbci->mMemberVarData.end(); iter++)
+ {
+ LLMsgVarData& mvci = *iter;
+ if (mvci.getSize() == -1)
+ {
+ // oops, this variable wasn't ever set!
+ llerrs << "The variable " << mvci.getName() << " in block "
+ << mbci->mName << " of message "
+ << mCurrentSMessageData->mName
+ << " wasn't set prior to buildMessage call" << llendl;
+ }
+ else
+ {
+ S32 data_size = mvci.getDataSize();
+ if(data_size > 0)
+ {
+ // The type is MVT_VARIABLE, which means that we
+ // need to encode a size argument. Otherwise,
+ // there is no need.
+ S32 size = mvci.getSize();
+ U8 sizeb;
+ U16 sizeh;
+ switch(data_size)
+ {
+ case 1:
+ sizeb = size;
+ htonmemcpy(&buffer[result], &sizeb, MVT_U8, 1);
+ break;
+ case 2:
+ sizeh = size;
+ htonmemcpy(&buffer[result], &sizeh, MVT_U16, 2);
+ break;
+ case 4:
+ htonmemcpy(&buffer[result], &size, MVT_S32, 4);
+ break;
+ default:
+ llerrs << "Attempting to build variable field with unknown size of " << size << llendl;
+ break;
+ }
+ result += mvci.getDataSize();
+ }
+
+ // if there is any data to pack, pack it
+ if((mvci.getData() != NULL) && mvci.getSize())
+ {
+ if(result + mvci.getSize() < buffer_size)
+ {
+ memcpy(
+ &buffer[result],
+ mvci.getData(),
+ mvci.getSize());
+ result += mvci.getSize();
+ }
+ else
+ {
+ // Just reporting error is likely not
+ // enough. Need to check how to abort or error
+ // out gracefully from this function. XXXTBD
+ llerrs << "LLMessageSystem::buildMessage failed. "
+ << "Attempted to pack "
+ << result + mvci.getSize()
+ << " bytes into a buffer with size "
+ << buffer_size << "." << llendl
+ }
+ }
+ }
+ }
+ }
+ mbSBuilt = TRUE;
+
+ return result;
+}
+
+void LLTemplateMessageBuilder::copyFromMessageData(const LLMsgData& data)
+{
+ // copy the blocks
+ // counting variables used to encode multiple block info
+ S32 block_count = 0;
+ char *block_name = NULL;
+
+ // loop through msg blocks to loop through variables, totalling up size
+ // data and filling the new (send) message
+ LLMsgData::msg_blk_data_map_t::const_iterator iter =
+ data.mMemberBlocks.begin();
+ LLMsgData::msg_blk_data_map_t::const_iterator end =
+ data.mMemberBlocks.end();
+ for(; iter != end; ++iter)
+ {
+ const LLMsgBlkData* mbci = iter->second;
+ if(!mbci) continue;
+
+ // do we need to encode a block code?
+ if (block_count == 0)
+ {
+ block_count = mbci->mBlockNumber;
+ block_name = (char *)mbci->mName;
+ }
+
+ // counting down mutliple blocks
+ block_count--;
+
+ nextBlock(block_name);
+
+ // now loop through the variables
+ LLMsgBlkData::msg_var_data_map_t::const_iterator dit = mbci->mMemberVarData.begin();
+ LLMsgBlkData::msg_var_data_map_t::const_iterator dend = mbci->mMemberVarData.end();
+
+ for(; dit != dend; ++dit)
+ {
+ const LLMsgVarData& mvci = *dit;
+ addData(mvci.getName(), mvci.getData(), mvci.getType(), mvci.getSize());
+ }
+ }
+}
+
+//virtual
+void LLTemplateMessageBuilder::copyFromLLSD(const LLSD&)
+{
+ // TODO
+}
+
+//virtual
+void LLTemplateMessageBuilder::setBuilt(BOOL b) { mbSBuilt = b; }
+
+//virtual
+BOOL LLTemplateMessageBuilder::isBuilt() const {return mbSBuilt;}
+
+//virtual
+BOOL LLTemplateMessageBuilder::isClear() const {return mbSClear;}
+
+//virtual
+S32 LLTemplateMessageBuilder::getMessageSize() {return mCurrentSendTotal;}
+
+//virtual
+const char* LLTemplateMessageBuilder::getMessageName() const
+{
+ return mCurrentSMessageName;
+}
diff --git a/indra/llmessage/lltemplatemessagebuilder.h b/indra/llmessage/lltemplatemessagebuilder.h
new file mode 100644
index 0000000000..ae533288fb
--- /dev/null
+++ b/indra/llmessage/lltemplatemessagebuilder.h
@@ -0,0 +1,88 @@
+#ifndef LL_LLTEMPLATEMESSAGEBUILDER_H
+#define LL_LLTEMPLATEMESSAGEBUILDER_H
+
+#include <map>
+
+#include "llmessagebuilder.h"
+#include "llmsgvariabletype.h"
+
+class LLMsgData;
+class LLMessageTemplate;
+class LLMsgBlkData;
+class LLMessageTemplate;
+
+class LLTemplateMessageBuilder : public LLMessageBuilder
+{
+public:
+
+ typedef std::map<const char *, LLMessageTemplate*> message_template_name_map_t;
+
+ LLTemplateMessageBuilder(message_template_name_map_t&);
+ virtual ~LLTemplateMessageBuilder();
+
+ virtual void newMessage(const char *name);
+
+ virtual void nextBlock(const char* blockname);
+ virtual BOOL removeLastBlock(); // TODO: babbage: remove this horror...
+
+ /** All add* methods expect pointers to canonical varname strings. */
+ virtual void addBinaryData(const char *varname, const void *data,
+ S32 size);
+ virtual void addBOOL(const char* varname, BOOL b);
+ virtual void addS8(const char *varname, S8 s);
+ virtual void addU8(const char *varname, U8 u);
+ virtual void addS16(const char *varname, S16 i);
+ virtual void addU16(const char *varname, U16 i);
+ virtual void addF32(const char *varname, F32 f);
+ virtual void addS32(const char *varname, S32 s);
+ virtual void addU32(const char *varname, U32 u);
+ virtual void addU64(const char *varname, U64 lu);
+ virtual void addF64(const char *varname, F64 d);
+ virtual void addVector3(const char *varname, const LLVector3& vec);
+ virtual void addVector4(const char *varname, const LLVector4& vec);
+ virtual void addVector3d(const char *varname, const LLVector3d& vec);
+ virtual void addQuat(const char *varname, const LLQuaternion& quat);
+ virtual void addUUID(const char *varname, const LLUUID& uuid);
+ virtual void addIPAddr(const char *varname, const U32 ip);
+ virtual void addIPPort(const char *varname, const U16 port);
+ virtual void addString(const char* varname, const char* s);
+ virtual void addString(const char* varname, const std::string& s);
+
+ virtual BOOL isMessageFull(const char* blockname) const;
+ virtual void compressMessage(U8*& buf_ptr, U32& buffer_length);
+
+ virtual BOOL isBuilt() const;
+ virtual BOOL isClear() const;
+ virtual U32 buildMessage(U8* buffer, U32 buffer_size);
+ /**< Return built message size */
+
+ virtual void clearMessage();
+
+ // TODO: babbage: remove this horror.
+ virtual void setBuilt(BOOL b);
+
+ virtual S32 getMessageSize();
+ virtual const char* getMessageName() const;
+
+ virtual void copyFromMessageData(const LLMsgData& data);
+ virtual void copyFromLLSD(const LLSD&);
+
+private:
+ void addData(const char *varname, const void *data,
+ EMsgVariableType type, S32 size);
+
+ void addData(const char *varname, const void *data,
+ EMsgVariableType type);
+
+ LLMsgData* mCurrentSMessageData;
+ LLMessageTemplate* mCurrentSMessageTemplate;
+ LLMsgBlkData* mCurrentSDataBlock;
+ char* mCurrentSMessageName;
+ char* mCurrentSBlockName;
+ BOOL mbSBuilt;
+ BOOL mbSClear;
+ S32 mCurrentSendTotal;
+ message_template_name_map_t& mMessageTemplates;
+};
+
+#endif // LL_LLTEMPLATEMESSAGEBUILDER_H
diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp
new file mode 100644
index 0000000000..892efb8697
--- /dev/null
+++ b/indra/llmessage/lltemplatemessagereader.cpp
@@ -0,0 +1,750 @@
+#include "lltemplatemessagereader.h"
+
+#include "llfasttimer.h"
+#include "llmessagebuilder.h"
+#include "llmessagetemplate.h"
+#include "llquaternion.h"
+#include "message.h"
+#include "u64.h"
+#include "v3dmath.h"
+#include "v3math.h"
+#include "v4math.h"
+
+LLTemplateMessageReader::LLTemplateMessageReader(message_template_number_map_t&
+ number_template_map) :
+ mReceiveSize(0),
+ mCurrentRMessageTemplate(NULL),
+ mCurrentRMessageData(NULL),
+ mMessageNumbers(number_template_map)
+{
+}
+
+//virtual
+LLTemplateMessageReader::~LLTemplateMessageReader()
+{
+ delete mCurrentRMessageData;
+ mCurrentRMessageData = NULL;
+}
+
+//virtual
+void LLTemplateMessageReader::clearMessage()
+{
+ mReceiveSize = -1;
+ mCurrentRMessageTemplate = NULL;
+ delete mCurrentRMessageData;
+ mCurrentRMessageData = NULL;
+}
+
+void LLTemplateMessageReader::getData(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum, S32 max_size)
+{
+ // is there a message ready to go?
+ if (mReceiveSize == -1)
+ {
+ llerrs << "No message waiting for decode 2!" << llendl;
+ return;
+ }
+
+ if (!mCurrentRMessageData)
+ {
+ llerrs << "Invalid mCurrentMessageData in getData!" << llendl;
+ return;
+ }
+
+ char *bnamep = (char *)blockname + blocknum; // this works because it's just a hash. The bnamep is never derefference
+ char *vnamep = (char *)varname;
+
+ LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
+
+ if (iter == mCurrentRMessageData->mMemberBlocks.end())
+ {
+ llerrs << "Block " << blockname << " #" << blocknum
+ << " not in message " << mCurrentRMessageData->mName << llendl;
+ return;
+ }
+
+ LLMsgBlkData *msg_block_data = iter->second;
+ LLMsgVarData& vardata = msg_block_data->mMemberVarData[vnamep];
+
+ if (!vardata.getName())
+ {
+ llerrs << "Variable "<< vnamep << " not in message "
+ << mCurrentRMessageData->mName<< " block " << bnamep << llendl;
+ return;
+ }
+
+ if (size && size != vardata.getSize())
+ {
+ llerrs << "Msg " << mCurrentRMessageData->mName
+ << " variable " << vnamep
+ << " is size " << vardata.getSize()
+ << " but copying into buffer of size " << size
+ << llendl;
+ return;
+ }
+
+
+ const S32 vardata_size = vardata.getSize();
+ if( max_size >= vardata_size )
+ {
+ switch( vardata_size )
+ {
+ case 1:
+ *((U8*)datap) = *((U8*)vardata.getData());
+ break;
+ case 2:
+ *((U16*)datap) = *((U16*)vardata.getData());
+ break;
+ case 4:
+ *((U32*)datap) = *((U32*)vardata.getData());
+ break;
+ case 8:
+ ((U32*)datap)[0] = ((U32*)vardata.getData())[0];
+ ((U32*)datap)[1] = ((U32*)vardata.getData())[1];
+ break;
+ default:
+ memcpy(datap, vardata.getData(), vardata_size);
+ break;
+ }
+ }
+ else
+ {
+ llwarns << "Msg " << mCurrentRMessageData->mName
+ << " variable " << vnamep
+ << " is size " << vardata.getSize()
+ << " but truncated to max size of " << max_size
+ << llendl;
+
+ memcpy(datap, vardata.getData(), max_size);
+ }
+}
+
+S32 LLTemplateMessageReader::getNumberOfBlocks(const char *blockname)
+{
+ // is there a message ready to go?
+ if (mReceiveSize == -1)
+ {
+ llerrs << "No message waiting for decode 3!" << llendl;
+ return -1;
+ }
+
+ if (!mCurrentRMessageData)
+ {
+ llerrs << "Invalid mCurrentRMessageData in getData!" << llendl;
+ return -1;
+ }
+
+ char *bnamep = (char *)blockname;
+
+ LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
+
+ if (iter == mCurrentRMessageData->mMemberBlocks.end())
+ {
+// sprintf(errmsg, "Block %s not in message %s", bnamep, mCurrentRMessageData->mName);
+// llerrs << errmsg << llendl;
+// return -1;
+ return 0;
+ }
+
+ return (iter->second)->mBlockNumber;
+}
+
+S32 LLTemplateMessageReader::getSize(const char *blockname, const char *varname)
+{
+ // is there a message ready to go?
+ if (mReceiveSize == -1)
+ {
+ llerrs << "No message waiting for decode 4!" << llendl;
+ return -1;
+ }
+
+ if (!mCurrentRMessageData)
+ {
+ llerrs << "Invalid mCurrentRMessageData in getData!" << llendl;
+ return -1;
+ }
+
+ char *bnamep = (char *)blockname;
+
+ LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
+
+ if (iter == mCurrentRMessageData->mMemberBlocks.end())
+ {
+ llerrs << "Block " << bnamep << " not in message "
+ << mCurrentRMessageData->mName << llendl;
+ return -1;
+ }
+
+ char *vnamep = (char *)varname;
+
+ LLMsgBlkData* msg_data = iter->second;
+ LLMsgVarData& vardata = msg_data->mMemberVarData[vnamep];
+
+ if (!vardata.getName())
+ {
+ llerrs << "Variable " << varname << " not in message "
+ << mCurrentRMessageData->mName << " block " << bnamep << llendl;
+ return -1;
+ }
+
+ if (mCurrentRMessageTemplate->mMemberBlocks[bnamep]->mType != MBT_SINGLE)
+ {
+ llerrs << "Block " << bnamep << " isn't type MBT_SINGLE,"
+ " use getSize with blocknum argument!" << llendl;
+ return -1;
+ }
+
+ return vardata.getSize();
+}
+
+S32 LLTemplateMessageReader::getSize(const char *blockname, S32 blocknum, const char *varname)
+{
+ // is there a message ready to go?
+ if (mReceiveSize == -1)
+ {
+ llerrs << "No message waiting for decode 5!" << llendl;
+ return -1;
+ }
+
+ if (!mCurrentRMessageData)
+ {
+ llerrs << "Invalid mCurrentRMessageData in getData!" << llendl;
+ return -1;
+ }
+
+ char *bnamep = (char *)blockname + blocknum;
+ char *vnamep = (char *)varname;
+
+ LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
+
+ if (iter == mCurrentRMessageData->mMemberBlocks.end())
+ {
+ llerrs << "Block " << bnamep << " not in message "
+ << mCurrentRMessageData->mName << llendl;
+ return -1;
+ }
+
+ LLMsgBlkData* msg_data = iter->second;
+ LLMsgVarData& vardata = msg_data->mMemberVarData[vnamep];
+
+ if (!vardata.getName())
+ {
+ llerrs << "Variable " << vnamep << " not in message "
+ << mCurrentRMessageData->mName << " block " << bnamep << llendl;
+ return -1;
+ }
+
+ return vardata.getSize();
+}
+
+void LLTemplateMessageReader::getBinaryData(const char *blockname,
+ const char *varname, void *datap,
+ S32 size, S32 blocknum,
+ S32 max_size)
+{
+ getData(blockname, varname, datap, size, blocknum, max_size);
+}
+
+void LLTemplateMessageReader::getS8(const char *block, const char *var,
+ S8 &u, S32 blocknum)
+{
+ getData(block, var, &u, sizeof(S8), blocknum);
+}
+
+void LLTemplateMessageReader::getU8(const char *block, const char *var,
+ U8 &u, S32 blocknum)
+{
+ getData(block, var, &u, sizeof(U8), blocknum);
+}
+
+void LLTemplateMessageReader::getBOOL(const char *block, const char *var,
+ BOOL &b, S32 blocknum )
+{
+ U8 value;
+ getData(block, var, &value, sizeof(U8), blocknum);
+ b = (BOOL) value;
+}
+
+void LLTemplateMessageReader::getS16(const char *block, const char *var,
+ S16 &d, S32 blocknum)
+{
+ getData(block, var, &d, sizeof(S16), blocknum);
+}
+
+void LLTemplateMessageReader::getU16(const char *block, const char *var,
+ U16 &d, S32 blocknum)
+{
+ getData(block, var, &d, sizeof(U16), blocknum);
+}
+
+void LLTemplateMessageReader::getS32(const char *block, const char *var,
+ S32 &d, S32 blocknum)
+{
+ getData(block, var, &d, sizeof(S32), blocknum);
+}
+
+void LLTemplateMessageReader::getU32(const char *block, const char *var,
+ U32 &d, S32 blocknum)
+{
+ getData(block, var, &d, sizeof(U32), blocknum);
+}
+
+void LLTemplateMessageReader::getU64(const char *block, const char *var,
+ U64 &d, S32 blocknum)
+{
+ getData(block, var, &d, sizeof(U64), blocknum);
+}
+
+void LLTemplateMessageReader::getF32(const char *block, const char *var,
+ F32 &d, S32 blocknum)
+{
+ getData(block, var, &d, sizeof(F32), blocknum);
+
+ if( !llfinite( d ) )
+ {
+ llwarns << "non-finite in getF32Fast " << block << " " << var
+ << llendl;
+ d = 0;
+ }
+}
+
+void LLTemplateMessageReader::getF64(const char *block, const char *var,
+ F64 &d, S32 blocknum)
+{
+ getData(block, var, &d, sizeof(F64), blocknum);
+
+ if( !llfinite( d ) )
+ {
+ llwarns << "non-finite in getF64Fast " << block << " " << var
+ << llendl;
+ d = 0;
+ }
+}
+
+void LLTemplateMessageReader::getVector3(const char *block, const char *var,
+ LLVector3 &v, S32 blocknum )
+{
+ getData(block, var, v.mV, sizeof(v.mV), blocknum);
+
+ if( !v.isFinite() )
+ {
+ llwarns << "non-finite in getVector3Fast " << block << " "
+ << var << llendl;
+ v.zeroVec();
+ }
+}
+
+void LLTemplateMessageReader::getVector4(const char *block, const char *var,
+ LLVector4 &v, S32 blocknum)
+{
+ getData(block, var, v.mV, sizeof(v.mV), blocknum);
+
+ if( !v.isFinite() )
+ {
+ llwarns << "non-finite in getVector4Fast " << block << " "
+ << var << llendl;
+ v.zeroVec();
+ }
+}
+
+void LLTemplateMessageReader::getVector3d(const char *block, const char *var,
+ LLVector3d &v, S32 blocknum )
+{
+ getData(block, var, v.mdV, sizeof(v.mdV), blocknum);
+
+ if( !v.isFinite() )
+ {
+ llwarns << "non-finite in getVector3dFast " << block << " "
+ << var << llendl;
+ v.zeroVec();
+ }
+
+}
+
+void LLTemplateMessageReader::getQuat(const char *block, const char *var,
+ LLQuaternion &q, S32 blocknum)
+{
+ LLVector3 vec;
+ getData(block, var, vec.mV, sizeof(vec.mV), blocknum);
+ if( vec.isFinite() )
+ {
+ q.unpackFromVector3( vec );
+ }
+ else
+ {
+ llwarns << "non-finite in getQuatFast " << block << " " << var
+ << llendl;
+ q.loadIdentity();
+ }
+}
+
+void LLTemplateMessageReader::getUUID(const char *block, const char *var,
+ LLUUID &u, S32 blocknum)
+{
+ getData(block, var, u.mData, sizeof(u.mData), blocknum);
+}
+
+inline void LLTemplateMessageReader::getIPAddr(const char *block, const char *var, U32 &u, S32 blocknum)
+{
+ getData(block, var, &u, sizeof(U32), blocknum);
+}
+
+inline void LLTemplateMessageReader::getIPPort(const char *block, const char *var, U16 &u, S32 blocknum)
+{
+ getData(block, var, &u, sizeof(U16), blocknum);
+ u = ntohs(u);
+}
+
+inline void LLTemplateMessageReader::getString(const char *block, const char *var, S32 buffer_size, char *s, S32 blocknum )
+{
+ s[0] = '\0';
+ getData(block, var, s, 0, blocknum, buffer_size);
+ s[buffer_size - 1] = '\0';
+}
+
+//virtual
+S32 LLTemplateMessageReader::getMessageSize() const
+{
+ return mReceiveSize;
+}
+
+// Returns template for the message contained in buffer
+BOOL LLTemplateMessageReader::decodeTemplate(
+ const U8* buffer, S32 buffer_size, // inputs
+ LLMessageTemplate** msg_template ) // outputs
+{
+ const U8* header = buffer + LL_PACKET_ID_SIZE;
+
+ // is there a message ready to go?
+ if (buffer_size <= 0)
+ {
+ llwarns << "No message waiting for decode!" << llendl;
+ return(FALSE);
+ }
+
+ U32 num = 0;
+
+ if (header[0] != 255)
+ {
+ // high frequency message
+ num = header[0];
+ }
+ else if ((buffer_size >= ((S32) LL_MINIMUM_VALID_PACKET_SIZE + 1)) && (header[1] != 255))
+ {
+ // medium frequency message
+ num = (255 << 8) | header[1];
+ }
+ else if ((buffer_size >= ((S32) LL_MINIMUM_VALID_PACKET_SIZE + 3)) && (header[1] == 255))
+ {
+ // low frequency message
+ U16 message_id_U16 = 0;
+ // I think this check busts the message system.
+ // it appears that if there is a NULL in the message #, it won't copy it....
+ // what was the goal?
+ //if(header[2])
+ memcpy(&message_id_U16, &header[2], 2);
+
+ // dependant on endian-ness:
+ // U32 temp = (255 << 24) | (255 << 16) | header[2];
+
+ // independant of endian-ness:
+ message_id_U16 = ntohs(message_id_U16);
+ num = 0xFFFF0000 | message_id_U16;
+ }
+ else // bogus packet received (too short)
+ {
+ llwarns << "Packet with unusable length received (too short): "
+ << buffer_size << llendl;
+ return(FALSE);
+ }
+
+ LLMessageTemplate* temp = get_ptr_in_map(mMessageNumbers,num);
+ if (temp)
+ {
+ *msg_template = temp;
+ }
+ else
+ {
+ llwarns << "Message #" << std::hex << num << std::dec
+ << " received but not registered!" << llendl;
+ gMessageSystem->callExceptionFunc(MX_UNREGISTERED_MESSAGE);
+ return(FALSE);
+ }
+
+ return(TRUE);
+}
+
+void LLTemplateMessageReader::logRanOffEndOfPacket( const LLHost& host )
+{
+ // we've run off the end of the packet!
+ llwarns << "Ran off end of packet " << mCurrentRMessageTemplate->mName
+// << " with id " << mCurrentRecvPacketID
+ << " from " << host
+ << llendl;
+ if(gMessageSystem->mVerboseLog)
+ {
+ llinfos << "MSG: -> " << host << "\tREAD PAST END:\t"
+// << mCurrentRecvPacketID << " "
+ << getMessageName() << llendl;
+ }
+ gMessageSystem->callExceptionFunc(MX_RAN_OFF_END_OF_PACKET);
+}
+
+// decode a given message
+BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender )
+{
+ llassert( mReceiveSize >= 0 );
+ llassert( mCurrentRMessageTemplate);
+ llassert( !mCurrentRMessageData );
+ delete mCurrentRMessageData; // just to make sure
+
+ S32 decode_pos = LL_PACKET_ID_SIZE + (S32)(mCurrentRMessageTemplate->mFrequency);
+
+ // create base working data set
+ mCurrentRMessageData = new LLMsgData(mCurrentRMessageTemplate->mName);
+
+ // loop through the template building the data structure as we go
+ for (LLMessageTemplate::message_block_map_t::iterator iter = mCurrentRMessageTemplate->mMemberBlocks.begin();
+ iter != mCurrentRMessageTemplate->mMemberBlocks.end(); iter++)
+ {
+ LLMessageBlock* mbci = iter->second;
+ U8 repeat_number;
+ S32 i;
+
+ // how many of this block?
+
+ if (mbci->mType == MBT_SINGLE)
+ {
+ // just one
+ repeat_number = 1;
+ }
+ else if (mbci->mType == MBT_MULTIPLE)
+ {
+ // a known number
+ repeat_number = mbci->mNumber;
+ }
+ else if (mbci->mType == MBT_VARIABLE)
+ {
+ // need to read the number from the message
+ // repeat number is a single byte
+ if (decode_pos >= mReceiveSize)
+ {
+ logRanOffEndOfPacket( sender );
+ return FALSE;
+ }
+ repeat_number = buffer[decode_pos];
+ decode_pos++;
+ }
+ else
+ {
+ llerrs << "Unknown block type" << llendl;
+ return FALSE;
+ }
+
+ LLMsgBlkData* cur_data_block = NULL;
+
+ // now loop through the block
+ for (i = 0; i < repeat_number; i++)
+ {
+ if (i)
+ {
+ // build new name to prevent collisions
+ // TODO: This should really change to a vector
+ cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number);
+ cur_data_block->mName = mbci->mName + i;
+ }
+ else
+ {
+ cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number);
+ }
+
+ // add the block to the message
+ mCurrentRMessageData->addBlock(cur_data_block);
+
+ // now read the variables
+ for (LLMessageBlock::message_variable_map_t::iterator iter = mbci->mMemberVariables.begin();
+ iter != mbci->mMemberVariables.end(); iter++)
+ {
+ LLMessageVariable& mvci = *(iter->second);
+ // ok, build out the variables
+ // add variable block
+ cur_data_block->addVariable(mvci.getName(), mvci.getType());
+
+ // what type of variable?
+ if (mvci.getType() == MVT_VARIABLE)
+ {
+ // variable, get the number of bytes to read from the template
+ S32 data_size = mvci.getSize();
+ U8 tsizeb = 0;
+ U16 tsizeh = 0;
+ U32 tsize = 0;
+
+ if ((decode_pos + data_size) > mReceiveSize)
+ {
+ logRanOffEndOfPacket( sender );
+ return FALSE;
+ }
+ switch(data_size)
+ {
+ case 1:
+ htonmemcpy(&tsizeb, &buffer[decode_pos], MVT_U8, 1);
+ tsize = tsizeb;
+ break;
+ case 2:
+ htonmemcpy(&tsizeh, &buffer[decode_pos], MVT_U16, 2);
+ tsize = tsizeh;
+ break;
+ case 4:
+ htonmemcpy(&tsizeb, &buffer[decode_pos], MVT_U32, 4);
+ break;
+ default:
+ llerrs << "Attempting to read variable field with unknown size of " << data_size << llendl;
+ break;
+
+ }
+ decode_pos += data_size;
+
+ if ((decode_pos + (S32)tsize) > mReceiveSize)
+ {
+ logRanOffEndOfPacket( sender );
+ return FALSE;
+ }
+ cur_data_block->addData(mvci.getName(), &buffer[decode_pos], tsize, mvci.getType());
+ decode_pos += tsize;
+ }
+ else
+ {
+ // fixed!
+ // so, copy data pointer and set data size to fixed size
+
+ if ((decode_pos + mvci.getSize()) > mReceiveSize)
+ {
+ logRanOffEndOfPacket( sender );
+ return FALSE;
+ }
+
+ cur_data_block->addData(mvci.getName(), &buffer[decode_pos], mvci.getSize(), mvci.getType());
+ decode_pos += mvci.getSize();
+ }
+ }
+ }
+ }
+
+ if (mCurrentRMessageData->mMemberBlocks.empty()
+ && !mCurrentRMessageTemplate->mMemberBlocks.empty())
+ {
+ lldebugs << "Empty message '" << mCurrentRMessageTemplate->mName << "' (no blocks)" << llendl;
+ return FALSE;
+ }
+
+ {
+ static LLTimer decode_timer;
+
+ if(LLMessageReader::getTimeDecodes() || gMessageSystem->getTimingCallback())
+ {
+ decode_timer.reset();
+ }
+
+ // if( mCurrentRMessageTemplate->mName == _PREHASH_AgentToNewRegion )
+ // {
+ // VTResume(); // VTune
+ // }
+
+ {
+ LLFastTimer t(LLFastTimer::FTM_PROCESS_MESSAGES);
+ if( !mCurrentRMessageTemplate->callHandlerFunc(gMessageSystem) )
+ {
+ llwarns << "Message from " << sender << " with no handler function received: " << mCurrentRMessageTemplate->mName << llendl;
+ }
+ }
+
+ // if( mCurrentRMessageTemplate->mName == _PREHASH_AgentToNewRegion )
+ // {
+ // VTPause(); // VTune
+ // }
+
+ if(LLMessageReader::getTimeDecodes() || gMessageSystem->getTimingCallback())
+ {
+ F32 decode_time = decode_timer.getElapsedTimeF32();
+
+ if (gMessageSystem->getTimingCallback())
+ {
+ (gMessageSystem->getTimingCallback())(mCurrentRMessageTemplate->mName,
+ decode_time,
+ gMessageSystem->getTimingCallbackData());
+ }
+
+ if (LLMessageReader::getTimeDecodes())
+ {
+ mCurrentRMessageTemplate->mDecodeTimeThisFrame += decode_time;
+
+ mCurrentRMessageTemplate->mTotalDecoded++;
+ mCurrentRMessageTemplate->mTotalDecodeTime += decode_time;
+
+ if( mCurrentRMessageTemplate->mMaxDecodeTimePerMsg < decode_time )
+ {
+ mCurrentRMessageTemplate->mMaxDecodeTimePerMsg = decode_time;
+ }
+
+
+ if(decode_time > LLMessageReader::getTimeDecodesSpamThreshold())
+ {
+ lldebugs << "--------- Message " << mCurrentRMessageTemplate->mName << " decode took " << decode_time << " seconds. (" <<
+ mCurrentRMessageTemplate->mMaxDecodeTimePerMsg << " max, " <<
+ (mCurrentRMessageTemplate->mTotalDecodeTime / mCurrentRMessageTemplate->mTotalDecoded) << " avg)" << llendl;
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+
+BOOL LLTemplateMessageReader::validateMessage(const U8* buffer,
+ S32 buffer_size,
+ const LLHost& sender)
+{
+ mReceiveSize = buffer_size;
+ BOOL result = decodeTemplate(buffer, buffer_size, &mCurrentRMessageTemplate );
+ if(result)
+ {
+ mCurrentRMessageTemplate->mReceiveCount++;
+ lldebugst(LLERR_MESSAGE) << "MessageRecvd:"
+ << mCurrentRMessageTemplate->mName
+ << " from " << sender << llendl;
+ }
+ return result;
+}
+
+BOOL LLTemplateMessageReader::readMessage(const U8* buffer,
+ const LLHost& sender)
+{
+ return decodeData(buffer, sender);
+}
+
+//virtual
+const char* LLTemplateMessageReader::getMessageName() const
+{
+ static char empty_string[] = "";
+ return mCurrentRMessageTemplate ? mCurrentRMessageTemplate->mName : empty_string;
+}
+
+//virtual
+bool LLTemplateMessageReader::isTrusted() const
+{
+ return mCurrentRMessageTemplate->getTrust() == MT_TRUST;
+}
+
+//virtual
+bool LLTemplateMessageReader::isBanned(bool trustedSource) const
+{
+ return mCurrentRMessageTemplate->isBanned(trustedSource);
+}
+
+//virtual
+void LLTemplateMessageReader::copyToBuilder(LLMessageBuilder& builder) const
+{
+ if(NULL == mCurrentRMessageTemplate)
+ {
+ return;
+ }
+ builder.copyFromMessageData(*mCurrentRMessageData);
+}
diff --git a/indra/llmessage/lltemplatemessagereader.h b/indra/llmessage/lltemplatemessagereader.h
new file mode 100644
index 0000000000..dd5ee393fe
--- /dev/null
+++ b/indra/llmessage/lltemplatemessagereader.h
@@ -0,0 +1,98 @@
+#ifndef LL_LLTEMPLATEMESSAGEREADER_H
+#define LL_LLTEMPLATEMESSAGEREADER_H
+
+#include "llmessagereader.h"
+
+#include <map>
+
+class LLMessageTemplate;
+class LLMsgData;
+
+class LLTemplateMessageReader : public LLMessageReader
+{
+public:
+
+ typedef std::map<U32, LLMessageTemplate*> message_template_number_map_t;
+
+ LLTemplateMessageReader(message_template_number_map_t&);
+ virtual ~LLTemplateMessageReader();
+
+ /** All get* methods expect pointers to canonical strings. */
+ virtual void getBinaryData(const char *blockname, const char *varname,
+ void *datap, S32 size, S32 blocknum = 0,
+ S32 max_size = S32_MAX);
+ virtual void getBOOL(const char *block, const char *var, BOOL &data,
+ S32 blocknum = 0);
+ virtual void getS8(const char *block, const char *var, S8 &data,
+ S32 blocknum = 0);
+ virtual void getU8(const char *block, const char *var, U8 &data,
+ S32 blocknum = 0);
+ virtual void getS16(const char *block, const char *var, S16 &data,
+ S32 blocknum = 0);
+ virtual void getU16(const char *block, const char *var, U16 &data,
+ S32 blocknum = 0);
+ virtual void getS32(const char *block, const char *var, S32 &data,
+ S32 blocknum = 0);
+ virtual void getF32(const char *block, const char *var, F32 &data,
+ S32 blocknum = 0);
+ virtual void getU32(const char *block, const char *var, U32 &data,
+ S32 blocknum = 0);
+ virtual void getU64(const char *block, const char *var, U64 &data,
+ S32 blocknum = 0);
+ virtual void getF64(const char *block, const char *var, F64 &data,
+ S32 blocknum = 0);
+ virtual void getVector3(const char *block, const char *var,
+ LLVector3 &vec, S32 blocknum = 0);
+ virtual void getVector4(const char *block, const char *var,
+ LLVector4 &vec, S32 blocknum = 0);
+ virtual void getVector3d(const char *block, const char *var,
+ LLVector3d &vec, S32 blocknum = 0);
+ virtual void getQuat(const char *block, const char *var, LLQuaternion &q,
+ S32 blocknum = 0);
+ virtual void getUUID(const char *block, const char *var, LLUUID &uuid,
+ S32 blocknum = 0);
+ virtual void getIPAddr(const char *block, const char *var, U32 &ip,
+ S32 blocknum = 0);
+ virtual void getIPPort(const char *block, const char *var, U16 &port,
+ S32 blocknum = 0);
+ virtual void getString(const char *block, const char *var,
+ S32 buffer_size, char *buffer, S32 blocknum = 0);
+
+ virtual S32 getNumberOfBlocks(const char *blockname);
+ virtual S32 getSize(const char *blockname, const char *varname);
+ virtual S32 getSize(const char *blockname, S32 blocknum,
+ const char *varname);
+
+ virtual void clearMessage();
+
+ virtual const char* getMessageName() const;
+ virtual S32 getMessageSize() const;
+
+ virtual void copyToBuilder(LLMessageBuilder&) const;
+
+ BOOL validateMessage(const U8* buffer, S32 buffer_size,
+ const LLHost& sender);
+ BOOL readMessage(const U8* buffer, const LLHost& sender);
+
+ bool isTrusted() const;
+ bool isBanned(bool trusted_source) const;
+
+private:
+
+ void getData(const char *blockname, const char *varname, void *datap,
+ S32 size = 0, S32 blocknum = 0, S32 max_size = S32_MAX);
+
+ BOOL decodeTemplate(const U8* buffer, S32 buffer_size, // inputs
+ LLMessageTemplate** msg_template ); // outputs
+
+ void logRanOffEndOfPacket( const LLHost& host );
+
+ BOOL decodeData(const U8* buffer, const LLHost& sender );
+
+ S32 mReceiveSize;
+ LLMessageTemplate* mCurrentRMessageTemplate;
+ LLMsgData* mCurrentRMessageData;
+ message_template_number_map_t& mMessageNumbers;
+};
+
+#endif // LL_LLTEMPLATEMESSAGEREADER_H
diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp
index 6fb319326b..78d12cbda9 100644
--- a/indra/llmessage/message.cpp
+++ b/indra/llmessage/message.cpp
@@ -36,9 +36,20 @@
#include "lldarray.h"
#include "lldir.h"
#include "llerror.h"
+#include "llerrorlegacy.h"
#include "llfasttimer.h"
+#include "llhttpclient.h"
+#include "llhttpsender.h"
#include "llmd5.h"
+#include "llmessagebuilder.h"
+#include "llmessageconfig.h"
+#include "llpumpio.h"
+#include "lltemplatemessagebuilder.h"
+#include "lltemplatemessagereader.h"
+#include "llmessagetemplate.h"
#include "llsd.h"
+#include "llsdmessagebuilder.h"
+#include "llsdmessagereader.h"
#include "lltransfermanager.h"
#include "lluuid.h"
#include "llxfermanager.h"
@@ -55,405 +66,6 @@
static const F32 CIRCUIT_DUMP_TIMEOUT = 30.f;
static const S32 TRUST_TIME_WINDOW = 3;
-class LLMsgVarData
-{
-public:
- LLMsgVarData() : mName(NULL), mSize(-1), mDataSize(-1), mData(NULL), mType(MVT_U8)
- {
- }
-
- LLMsgVarData(const char *name, EMsgVariableType type) : mSize(-1), mDataSize(-1), mData(NULL), mType(type)
- {
- mName = (char *)name;
- }
-
- ~LLMsgVarData()
- {
- // copy constructor just copies the mData pointer, so only delete mData explicitly
- }
-
- void deleteData()
- {
- delete[] mData;
- mData = NULL;
- }
-
- void addData(const void *indata, S32 size, EMsgVariableType type, S32 data_size = -1);
-
- char *getName() const { return mName; }
- S32 getSize() const { return mSize; }
- void *getData() { return (void*)mData; }
- S32 getDataSize() const { return mDataSize; }
- EMsgVariableType getType() const { return mType; }
-
-protected:
- char *mName;
- S32 mSize;
- S32 mDataSize;
-
- U8 *mData;
- EMsgVariableType mType;
-};
-
-
-class LLMsgBlkData
-{
-public:
- LLMsgBlkData(const char *name, S32 blocknum) : mOffset(-1), mBlockNumber(blocknum), mTotalSize(-1)
- {
- mName = (char *)name;
- }
-
- ~LLMsgBlkData()
- {
- for (msg_var_data_map_t::iterator iter = mMemberVarData.begin();
- iter != mMemberVarData.end(); iter++)
- {
- iter->deleteData();
- }
- }
-
- void addVariable(const char *name, EMsgVariableType type)
- {
- LLMsgVarData tmp(name,type);
- mMemberVarData[name] = tmp;
- }
-
- void addData(char *name, const void *data, S32 size, EMsgVariableType type, S32 data_size = -1)
- {
- LLMsgVarData* temp = &mMemberVarData[name]; // creates a new entry if one doesn't exist
- temp->addData(data, size, type, data_size);
- }
-
- S32 mOffset;
- S32 mBlockNumber;
- typedef LLDynamicArrayIndexed<LLMsgVarData, const char *, 8> msg_var_data_map_t;
- msg_var_data_map_t mMemberVarData;
- char *mName;
- S32 mTotalSize;
-};
-
-
-class LLMsgData
-{
-public:
- LLMsgData(const char *name) : mTotalSize(-1)
- {
- mName = (char *)name;
- }
- ~LLMsgData()
- {
- for_each(mMemberBlocks.begin(), mMemberBlocks.end(), DeletePairedPointer());
- }
-
- void addBlock(LLMsgBlkData *blockp)
- {
- mMemberBlocks[blockp->mName] = blockp;
- }
-
- void addDataFast(char *blockname, char *varname, const void *data, S32 size, EMsgVariableType type, S32 data_size = -1);
-
-public:
- S32 mOffset;
- typedef std::map<char*, LLMsgBlkData*> msg_blk_data_map_t;
- msg_blk_data_map_t mMemberBlocks;
- char *mName;
- S32 mTotalSize;
-};
-
-inline void LLMsgVarData::addData(const void *data, S32 size, EMsgVariableType type, S32 data_size)
-{
- mSize = size;
- mDataSize = data_size;
- if ( (type != MVT_VARIABLE) && (type != MVT_FIXED)
- && (mType != MVT_VARIABLE) && (mType != MVT_FIXED))
- {
- if (mType != type)
- {
- llwarns << "Type mismatch in addData for " << mName
- << " message: " << gMessageSystem->getCurrentSMessageName()
- << " block: " << gMessageSystem->getCurrentSBlockName()
- << llendl;
- }
- }
- if(size)
- {
- delete mData; // Delete it if it already exists
- mData = new U8[size];
- htonmemcpy(mData, data, mType, size);
- }
-}
-
-
-
-inline void LLMsgData::addDataFast(char *blockname, char *varname, const void *data, S32 size, EMsgVariableType type, S32 data_size)
-{
- // remember that if the blocknumber is > 0 then the number is appended to the name
- char *namep = (char *)blockname;
- LLMsgBlkData* block_data = mMemberBlocks[namep];
- if (block_data->mBlockNumber)
- {
- namep += block_data->mBlockNumber;
- block_data->addData(varname, data, size, type, data_size);
- }
- else
- {
- block_data->addData(varname, data, size, type, data_size);
- }
-}
-
-// LLMessage* classes store the template of messages
-
-
-class LLMessageVariable
-{
-public:
- LLMessageVariable() : mName(NULL), mType(MVT_NULL), mSize(-1)
- {
- }
-
- LLMessageVariable(char *name) : mType(MVT_NULL), mSize(-1)
- {
- mName = name;
- }
-
- LLMessageVariable(char *name, const EMsgVariableType type, const S32 size) : mType(type), mSize(size)
- {
- mName = gMessageStringTable.getString(name);
- }
-
- ~LLMessageVariable() {}
-
- friend std::ostream& operator<<(std::ostream& s, LLMessageVariable &msg);
-
- EMsgVariableType getType() const { return mType; }
- S32 getSize() const { return mSize; }
- char *getName() const { return mName; }
-protected:
- char *mName;
- EMsgVariableType mType;
- S32 mSize;
-};
-
-
-typedef enum e_message_block_type
-{
- MBT_NULL,
- MBT_SINGLE,
- MBT_MULTIPLE,
- MBT_VARIABLE,
- MBT_EOF
-} EMsgBlockType;
-
-class LLMessageBlock
-{
-public:
- LLMessageBlock(char *name, EMsgBlockType type, S32 number = 1) : mType(type), mNumber(number), mTotalSize(0)
- {
- mName = gMessageStringTable.getString(name);
- }
-
- ~LLMessageBlock()
- {
- for_each(mMemberVariables.begin(), mMemberVariables.end(), DeletePairedPointer());
- }
-
- void addVariable(char *name, const EMsgVariableType type, const S32 size)
- {
- LLMessageVariable** varp = &mMemberVariables[name];
- if (*varp != NULL)
- {
- llerrs << name << " has already been used as a variable name!" << llendl;
- }
- *varp = new LLMessageVariable(name, type, size);
- if (((*varp)->getType() != MVT_VARIABLE)
- &&(mTotalSize != -1))
- {
- mTotalSize += (*varp)->getSize();
- }
- else
- {
- mTotalSize = -1;
- }
- }
-
- EMsgVariableType getVariableType(char *name)
- {
- return (mMemberVariables[name])->getType();
- }
-
- S32 getVariableSize(char *name)
- {
- return (mMemberVariables[name])->getSize();
- }
-
- friend std::ostream& operator<<(std::ostream& s, LLMessageBlock &msg);
-
- typedef std::map<const char *, LLMessageVariable*> message_variable_map_t;
- message_variable_map_t mMemberVariables;
- char *mName;
- EMsgBlockType mType;
- S32 mNumber;
- S32 mTotalSize;
-};
-
-
-enum EMsgFrequency
-{
- MFT_NULL = 0, // value is size of message number in bytes
- MFT_HIGH = 1,
- MFT_MEDIUM = 2,
- MFT_LOW = 4
-};
-
-typedef enum e_message_trust
-{
- MT_TRUST,
- MT_NOTRUST
-} EMsgTrust;
-
-enum EMsgEncoding
-{
- ME_UNENCODED,
- ME_ZEROCODED
-};
-
-class LLMessageTemplate
-{
-public:
- LLMessageTemplate(const char *name, U32 message_number, EMsgFrequency freq)
- :
- //mMemberBlocks(),
- mName(NULL),
- mFrequency(freq),
- mTrust(MT_NOTRUST),
- mEncoding(ME_ZEROCODED),
- mMessageNumber(message_number),
- mTotalSize(0),
- mReceiveCount(0),
- mReceiveBytes(0),
- mReceiveInvalid(0),
- mDecodeTimeThisFrame(0.f),
- mTotalDecoded(0),
- mTotalDecodeTime(0.f),
- mMaxDecodeTimePerMsg(0.f),
- mBanFromTrusted(false),
- mBanFromUntrusted(false),
- mHandlerFunc(NULL),
- mUserData(NULL)
- {
- mName = gMessageStringTable.getString(name);
- }
-
- ~LLMessageTemplate()
- {
- for_each(mMemberBlocks.begin(), mMemberBlocks.end(), DeletePairedPointer());
- }
-
- void addBlock(LLMessageBlock *blockp)
- {
- LLMessageBlock** member_blockp = &mMemberBlocks[blockp->mName];
- if (*member_blockp != NULL)
- {
- llerrs << "Block " << blockp->mName
- << "has already been used as a block name!" << llendl;
- }
- *member_blockp = blockp;
- if ( (mTotalSize != -1)
- &&(blockp->mTotalSize != -1)
- &&( (blockp->mType == MBT_SINGLE)
- ||(blockp->mType == MBT_MULTIPLE)))
- {
- mTotalSize += blockp->mNumber*blockp->mTotalSize;
- }
- else
- {
- mTotalSize = -1;
- }
- }
-
- LLMessageBlock *getBlock(char *name)
- {
- return mMemberBlocks[name];
- }
-
- // Trusted messages can only be recieved on trusted circuits.
- void setTrust(EMsgTrust t)
- {
- mTrust = t;
- }
-
- EMsgTrust getTrust(void)
- {
- return mTrust;
- }
-
- // controls for how the message should be encoded
- void setEncoding(EMsgEncoding e)
- {
- mEncoding = e;
- }
- EMsgEncoding getEncoding()
- {
- return mEncoding;
- }
-
- void setHandlerFunc(void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data)
- {
- mHandlerFunc = handler_func;
- mUserData = user_data;
- }
-
- BOOL callHandlerFunc(LLMessageSystem *msgsystem)
- {
- if (mHandlerFunc)
- {
- mHandlerFunc(msgsystem, mUserData);
- return TRUE;
- }
- return FALSE;
- }
-
- bool isBanned(bool trustedSource)
- {
- return trustedSource ? mBanFromTrusted : mBanFromUntrusted;
- }
-
- friend std::ostream& operator<<(std::ostream& s, LLMessageTemplate &msg);
-
-public:
- typedef std::map<char*, LLMessageBlock*> message_block_map_t;
- message_block_map_t mMemberBlocks;
- char *mName;
- EMsgFrequency mFrequency;
- EMsgTrust mTrust;
- EMsgEncoding mEncoding;
- U32 mMessageNumber;
- S32 mTotalSize;
- U32 mReceiveCount; // how many of this template have been received since last reset
- U32 mReceiveBytes; // How many bytes received
- U32 mReceiveInvalid; // How many "invalid" packets
- F32 mDecodeTimeThisFrame; // Total seconds spent decoding this frame
- U32 mTotalDecoded; // Total messages successfully decoded
- F32 mTotalDecodeTime; // Total time successfully decoding messages
- F32 mMaxDecodeTimePerMsg;
-
- bool mBanFromTrusted;
- bool mBanFromUntrusted;
-
-private:
- // message handler function (this is set by each application)
- void (*mHandlerFunc)(LLMessageSystem *msgsystem, void **user_data);
- void **mUserData;
-};
-
-
-// static
-BOOL LLMessageSystem::mTimeDecodes = FALSE;
-
-// static, 50ms per message decode
-F32 LLMessageSystem::mTimeDecodesSpamThreshold = 0.05f;
-
// *NOTE: This needs to be moved into a seperate file so that it never gets
// included in the viewer. 30 Sep 2002 mark
// *NOTE: I don't think it's important that the messgage system tracks
@@ -468,113 +80,6 @@ public:
apr_pollfd_t mPollFD;
};
-
-// LLMessageVariable functions and friends
-
-std::ostream& operator<<(std::ostream& s, LLMessageVariable &msg)
-{
- s << "\t\t" << msg.mName << " (";
- switch (msg.mType)
- {
- case MVT_FIXED:
- s << "Fixed, " << msg.mSize << " bytes total)\n";
- break;
- case MVT_VARIABLE:
- s << "Variable, " << msg.mSize << " bytes of size info)\n";
- break;
- default:
- s << "Unknown\n";
- break;
- }
- return s;
-}
-
-// LLMessageBlock functions and friends
-
-std::ostream& operator<<(std::ostream& s, LLMessageBlock &msg)
-{
- s << "\t" << msg.mName << " (";
- switch (msg.mType)
- {
- case MBT_SINGLE:
- s << "Fixed";
- break;
- case MBT_MULTIPLE:
- s << "Multiple - " << msg.mNumber << " copies";
- break;
- case MBT_VARIABLE:
- s << "Variable";
- break;
- default:
- s << "Unknown";
- break;
- }
- if (msg.mTotalSize != -1)
- {
- s << ", " << msg.mTotalSize << " bytes each, " << msg.mNumber*msg.mTotalSize << " bytes total)\n";
- }
- else
- {
- s << ")\n";
- }
-
-
- for (LLMessageBlock::message_variable_map_t::iterator iter = msg.mMemberVariables.begin();
- iter != msg.mMemberVariables.end(); iter++)
- {
- LLMessageVariable& ci = *(iter->second);
- s << ci;
- }
-
- return s;
-}
-
-// LLMessageTemplate functions and friends
-
-std::ostream& operator<<(std::ostream& s, LLMessageTemplate &msg)
-{
- switch (msg.mFrequency)
- {
- case MFT_HIGH:
- s << "========================================\n" << "Message #" << msg.mMessageNumber << "\n" << msg.mName << " (";
- s << "High";
- break;
- case MFT_MEDIUM:
- s << "========================================\n" << "Message #";
- s << (msg.mMessageNumber & 0xFF) << "\n" << msg.mName << " (";
- s << "Medium";
- break;
- case MFT_LOW:
- s << "========================================\n" << "Message #";
- s << (msg.mMessageNumber & 0xFFFF) << "\n" << msg.mName << " (";
- s << "Low";
- break;
- default:
- s << "Unknown";
- break;
- }
-
- if (msg.mTotalSize != -1)
- {
- s << ", " << msg.mTotalSize << " bytes total)\n";
- }
- else
- {
- s << ")\n";
- }
-
- for (LLMessageTemplate::message_block_map_t::iterator iter = msg.mMemberBlocks.begin();
- iter != msg.mMemberBlocks.end(); iter++)
- {
- LLMessageBlock* ci = iter->second;
- s << *ci;
- }
-
- return s;
-}
-
-// LLMessageList functions and friends
-
// Lets support a small subset of regular expressions here
// Syntax is a string made up of:
// a - checks against alphanumeric ([A-Za-z0-9])
@@ -776,6 +281,106 @@ BOOL b_positive_integer_ok(char *token)
return TRUE;
}
+namespace
+{
+ class LLFnPtrResponder : public LLHTTPClient::Responder
+ {
+ public:
+ LLFnPtrResponder(void (*callback)(void **,S32), void **callbackData) :
+ mCallback(callback),
+ mCallbackData(callbackData)
+ {
+ }
+
+ virtual void error(U32 status, const std::string& reason)
+ {
+ // TODO: Map status in to useful error code.
+ if(NULL != mCallback) mCallback(mCallbackData, LL_ERR_TCP_TIMEOUT);
+ }
+
+ virtual void result(const LLSD& content)
+ {
+ if(NULL != mCallback) mCallback(mCallbackData, LL_ERR_NOERR);
+ }
+
+ private:
+
+ void (*mCallback)(void **,S32);
+ void **mCallbackData;
+ };
+}
+
+
+class LLTrustedMessageService : public LLHTTPNode
+{
+ virtual bool validate(const std::string& name, LLSD& context) const
+ { return true; }
+
+ virtual void post(LLHTTPNode::ResponsePtr response,
+ const LLSD& context,
+ const LLSD& input) const;
+};
+
+//virtual
+void LLTrustedMessageService::post(LLHTTPNode::ResponsePtr response,
+ const LLSD& context,
+ const LLSD& input) const
+{
+ std::string name = context["request"]["wildcard"]["message-name"];
+ std::string senderIP = context["request"]["remote-host"];
+ std::string senderPort = context["request"]["headers"]
+ ["x-secondlife-udp-listen-port"];
+
+ LLSD message_data;
+ message_data["sender"] = senderIP + ":" + senderPort;
+ message_data["body"] = input;
+
+ LLMessageSystem::dispatch(name, message_data, response);
+}
+
+class LLMessageHandlerBridge : public LLHTTPNode
+{
+ virtual bool validate(const std::string& name, LLSD& context) const
+ { return true; }
+
+ virtual void post(LLHTTPNode::ResponsePtr response, const LLSD& context,
+ const LLSD& input) const;
+};
+
+//virtual
+void LLMessageHandlerBridge::post(LLHTTPNode::ResponsePtr response,
+ const LLSD& context, const LLSD& input) const
+{
+ std::string name = context["request"]["wildcard"]["message-name"];
+
+ lldebugs << "Setting mLastSender " << input["sender"].asString() << llendl;
+ gMessageSystem->mLastSender = LLHost(input["sender"].asString());
+ gMessageSystem->mPacketsIn += 1;
+ gMessageSystem->mLLSDMessageReader->setMessage(name, input["body"]);
+ gMessageSystem->mMessageReader = gMessageSystem->mLLSDMessageReader;
+
+ if(gMessageSystem->callHandler(name.c_str(), false, gMessageSystem))
+ {
+ response->result(LLSD());
+ }
+ else
+ {
+ response->notFound();
+ }
+}
+
+LLHTTPRegistration<LLMessageHandlerBridge>
+ gHTTPRegistrationMessageWildcard("/message/<message-name>");
+
+LLHTTPRegistration<LLTrustedMessageService>
+ gHTTPRegistrationTrustedMessageWildcard("/trusted-message/<message-name>");
+
+//virtual
+LLUseCircuitCodeResponder::~LLUseCircuitCodeResponder()
+{
+ // even abstract base classes need a concrete destructor
+}
+
void LLMessageSystem::init()
{
// initialize member variables
@@ -783,25 +388,12 @@ void LLMessageSystem::init()
mbError = FALSE;
mErrorCode = 0;
- mIncomingCompressedSize = 0;
mSendReliable = FALSE;
- mbSBuilt = FALSE;
- mbSClear = TRUE;
-
mUnackedListDepth = 0;
mUnackedListSize = 0;
mDSMaxListDepth = 0;
- mCurrentRMessageData = NULL;
- mCurrentRMessageTemplate = NULL;
-
- mCurrentSMessageData = NULL;
- mCurrentSMessageTemplate = NULL;
- mCurrentSMessageName = NULL;
-
- mCurrentRecvPacketID = 0;
-
mNumberHighFreqMessages = 0;
mNumberMediumFreqMessages = 0;
mNumberLowFreqMessages = 0;
@@ -825,57 +417,26 @@ void LLMessageSystem::init()
mOurCircuitCode = 0;
+ mIncomingCompressedSize = 0;
+ mCurrentRecvPacketID = 0;
+
mMessageFileChecksum = 0;
mMessageFileVersionNumber = 0.f;
mTimingCallback = NULL;
mTimingCallbackData = NULL;
-}
-
-LLMessageSystem::LLMessageSystem()
-{
- init();
- mSystemVersionMajor = 0;
- mSystemVersionMinor = 0;
- mSystemVersionPatch = 0;
- mSystemVersionServer = 0;
- mVersionFlags = 0x0;
-
- // default to not accepting packets from not alive circuits
- mbProtected = TRUE;
-
- mSendPacketFailureCount = 0;
- mCircuitPrintFreq = 0.f; // seconds
-
- // initialize various bits of net info
- mSocket = 0;
- mPort = 0;
-
- mPollInfop = NULL;
-
- mResendDumpTime = 0;
- mMessageCountTime = 0;
- mCircuitPrintTime = 0;
- mCurrentMessageTimeSeconds = 0;
-
- // Constants for dumping output based on message processing time/count
- mNumMessageCounts = 0;
- mMaxMessageCounts = 0; // >= 0 means dump warnings
- mMaxMessageTime = 0.f;
-
- mTrueReceiveSize = 0;
-
- // Error if checking this state, subclass methods which aren't implemented are delegated
- // to properly constructed message system.
- mbError = TRUE;
+ mMessageBuilder = NULL;
+ mMessageReader = NULL;
}
// Read file and build message templates
LLMessageSystem::LLMessageSystem(const char *filename, U32 port,
S32 version_major,
S32 version_minor,
- S32 version_patch)
+ S32 version_patch) :
+ mTemplateConfirmed(FALSE),
+ mTemplateMatches(FALSE)
{
init();
@@ -894,6 +455,14 @@ LLMessageSystem::LLMessageSystem(const char *filename, U32 port,
loadTemplateFile(filename);
+ mTemplateMessageBuilder = new LLTemplateMessageBuilder(mMessageTemplates);
+ mLLSDMessageBuilder = new LLSDMessageBuilder();
+ mMessageBuilder = NULL;
+
+ mTemplateMessageReader = new LLTemplateMessageReader(mMessageNumbers);
+ mLLSDMessageReader = new LLSDMessageReader();
+ mMessageReader = NULL;
+
// initialize various bits of net info
mSocket = 0;
mPort = port;
@@ -1712,25 +1281,25 @@ LLMessageSystem::~LLMessageSystem()
end_net();
}
- delete mCurrentRMessageData;
- mCurrentRMessageData = NULL;
+ delete mMessageReader;
+ mMessageReader = NULL;
- delete mCurrentSMessageData;
- mCurrentSMessageData = NULL;
+ delete mMessageBuilder;
+ mMessageBuilder = NULL;
delete mPollInfop;
mPollInfop = NULL;
+
+ mIncomingCompressedSize = 0;
+ mCurrentRecvPacketID = 0;
}
void LLMessageSystem::clearReceiveState()
{
- mReceiveSize = -1;
mCurrentRecvPacketID = 0;
- mCurrentRMessageTemplate = NULL;
- delete mCurrentRMessageData;
- mCurrentRMessageData = NULL;
mIncomingCompressedSize = 0;
mLastSender.invalidate();
+ mMessageReader->clearMessage();
}
@@ -1757,20 +1326,23 @@ BOOL LLMessageSystem::poll(F32 seconds)
// Returns TRUE if a valid, on-circuit message has been received.
BOOL LLMessageSystem::checkMessages( S64 frame_count )
{
+ // Pump
BOOL valid_packet = FALSE;
+ mMessageReader = mTemplateMessageReader;
LLTransferTargetVFile::updateQueue();
if (!mNumMessageCounts)
{
- // This is the first message being handled after a resetReceiveCounts, we must be starting
- // the message processing loop. Reset the timers.
+ // This is the first message being handled after a resetReceiveCounts,
+ // we must be starting the message processing loop. Reset the timers.
mCurrentMessageTimeSeconds = totalTime() * SEC_PER_USEC;
mMessageCountTime = getMessageTimeSeconds();
}
// loop until either no packets or a valid packet
// i.e., burn through packets from unregistered circuits
+ S32 receive_size = 0;
do
{
clearReceiveState();
@@ -1786,16 +1358,16 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
// If you want to dump all received packets into SecondLife.log, uncomment this
//dumpPacketToLog();
- mReceiveSize = mTrueReceiveSize;
+ receive_size = mTrueReceiveSize;
mLastSender = mPacketRing.getLastSender();
- if (mReceiveSize < (S32) LL_MINIMUM_VALID_PACKET_SIZE)
+ if (receive_size < (S32) LL_MINIMUM_VALID_PACKET_SIZE)
{
// A receive size of zero is OK, that means that there are no more packets available.
// Ones that are non-zero but below the minimum packet size are worrisome.
- if (mReceiveSize > 0)
+ if (receive_size > 0)
{
- llwarns << "Invalid (too short) packet discarded " << mReceiveSize << llendl;
+ llwarns << "Invalid (too short) packet discarded " << receive_size << llendl;
callExceptionFunc(MX_PACKET_TOO_SHORT);
}
// no data in packet receive buffer
@@ -1809,18 +1381,18 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
// note if packet acks are appended.
if(buffer[0] & LL_ACK_FLAG)
{
- acks += buffer[--mReceiveSize];
- true_rcv_size = mReceiveSize;
- if(mReceiveSize >= ((S32)(acks * sizeof(TPACKETID) + LL_MINIMUM_VALID_PACKET_SIZE)))
+ acks += buffer[--receive_size];
+ true_rcv_size = receive_size;
+ if(receive_size >= ((S32)(acks * sizeof(TPACKETID) + LL_MINIMUM_VALID_PACKET_SIZE)))
{
- mReceiveSize -= acks * sizeof(TPACKETID);
+ receive_size -= acks * sizeof(TPACKETID);
}
else
{
// mal-formed packet. ignore it and continue with
// the next one
llwarns << "Malformed packet received. Packet size "
- << mReceiveSize << " with invalid no. of acks " << acks
+ << receive_size << " with invalid no. of acks " << acks
<< llendl;
valid_packet = FALSE;
continue;
@@ -1829,7 +1401,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
// process the message as normal
- mIncomingCompressedSize = zeroCodeExpand(&buffer,&mReceiveSize);
+ mIncomingCompressedSize = zeroCodeExpand(&buffer,&receive_size);
mCurrentRecvPacketID = buffer[1] + ((buffer[0] & 0x0f ) * 256);
if (sizeof(TPACKETID) == 4)
{
@@ -1953,7 +1525,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
std::ostringstream str;
str << "MSG: <- " << host;
char buffer[MAX_STRING]; /* Flawfinder: ignore*/
- snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mReceiveSize, (mIncomingCompressedSize ? mIncomingCompressedSize : mReceiveSize), mCurrentRecvPacketID); /* Flawfinder: ignore */
+ snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", receive_size, (mIncomingCompressedSize ? mIncomingCompressedSize : receive_size), mCurrentRecvPacketID); /* Flawfinder: ignore */
str << buffer << "(unknown)"
<< (recv_reliable ? " reliable" : "")
<< " resent "
@@ -1971,23 +1543,22 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
// But we don't want to acknowledge UseCircuitCode until the circuit is
// available, which is why the acknowledgement test is done above. JC
- valid_packet = decodeTemplate( buffer, mReceiveSize, &mCurrentRMessageTemplate );
- if( valid_packet )
- {
- mCurrentRMessageTemplate->mReceiveCount++;
- lldebugst(LLERR_MESSAGE) << "MessageRecvd:" << mCurrentRMessageTemplate->mName << " from " << host << llendl;
- }
+ valid_packet = mTemplateMessageReader->validateMessage(buffer,
+ receive_size,
+ host);
// UseCircuitCode is allowed in even from an invalid circuit, so that
// we can toss circuits around.
- if (valid_packet && !cdp && (mCurrentRMessageTemplate->mName != _PREHASH_UseCircuitCode) )
+ if(valid_packet && !cdp &&
+ (mTemplateMessageReader->getMessageName() != _PREHASH_UseCircuitCode))
{
logMsgFromInvalidCircuit( host, recv_reliable );
clearReceiveState();
valid_packet = FALSE;
}
- if (valid_packet && cdp && !cdp->getTrusted() && (mCurrentRMessageTemplate->getTrust() == MT_TRUST) )
+ if(valid_packet && cdp && !cdp->getTrusted() &&
+ mTemplateMessageReader->isTrusted())
{
logTrustedMsgFromUntrustedCircuit( host );
clearReceiveState();
@@ -1997,11 +1568,11 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
}
if (valid_packet
- && mCurrentRMessageTemplate->isBanned(cdp && cdp->getTrusted()))
+ && mTemplateMessageReader->isBanned(cdp && cdp->getTrusted()))
{
llwarns << "LLMessageSystem::checkMessages "
<< "received banned message "
- << mCurrentRMessageTemplate->mName
+ << mTemplateMessageReader->getMessageName()
<< " from "
<< ((cdp && cdp->getTrusted()) ? "trusted " : "untrusted ")
<< host << llendl;
@@ -2013,7 +1584,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
{
logValidMsg(cdp, host, recv_reliable, recv_resent, (BOOL)(acks>0) );
- valid_packet = decodeData( buffer, host );
+ valid_packet = mTemplateMessageReader->readMessage(buffer, host);
}
// It's possible that the circuit went away, because ANY message can disable the circuit
@@ -2026,7 +1597,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
if( 1 )
{
static char* object_update = gMessageStringTable.getString("ObjectUpdate");
- if(object_update == mCurrentRMessageTemplate->mName )
+ if(object_update == mTemplateMessageReader->getMessageName() )
{
llinfos << "ObjectUpdate:" << llendl;
U32 i;
@@ -2037,8 +1608,8 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
}
llinfos << "" << llendl;
- llinfos << " Zero Unencoded: " << mReceiveSize << llendl;
- for( i = 0; i<mReceiveSize; i++ )
+ llinfos << " Zero Unencoded: " << receive_size << llendl;
+ for( i = 0; i<receive_size; i++ )
{
llinfos << " " << i << ": " << (U32) buffer[i] << llendl;
}
@@ -2127,7 +1698,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
if (mbProtected && (!cdp))
{
llwarns << "Packet "
- << (mCurrentRMessageTemplate ? mCurrentRMessageTemplate->mName : "")
+ << mTemplateMessageReader->getMessageName()
<< " from invalid circuit " << host << llendl;
mOffCircuitPackets++;
}
@@ -2140,7 +1711,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
// Code for dumping the complete contents of a message
// delete [] zero_unexpanded_buffer;
}
- } while (!valid_packet && mReceiveSize > 0);
+ } while (!valid_packet && receive_size > 0);
F64 mt_sec = getMessageTimeSeconds();
// Check to see if we need to print debug info
@@ -2241,600 +1812,56 @@ void LLMessageSystem::processAcks()
}
}
-
-void LLMessageSystem::newMessageFast(const char *name)
-{
- mbSBuilt = FALSE;
- mbSClear = FALSE;
-
- mCurrentSendTotal = 0;
- mSendReliable = FALSE;
-
- char *namep = (char *)name;
-
- if (mMessageTemplates.count(namep) > 0)
- {
- mCurrentSMessageTemplate = mMessageTemplates[namep];
- if (mCurrentSMessageData)
- {
- delete mCurrentSMessageData;
- }
- mCurrentSMessageData = new LLMsgData(namep);
- mCurrentSMessageName = namep;
- mCurrentSDataBlock = NULL;
- mCurrentSBlockName = NULL;
-
- // add at one of each block
- LLMessageTemplate* msg_template = mMessageTemplates[namep];
- for (LLMessageTemplate::message_block_map_t::iterator iter = msg_template->mMemberBlocks.begin();
- iter != msg_template->mMemberBlocks.end(); iter++)
- {
- LLMessageBlock* ci = iter->second;
- LLMsgBlkData *tblockp;
- tblockp = new LLMsgBlkData(ci->mName, 0);
- mCurrentSMessageData->addBlock(tblockp);
- }
- }
- else
- {
- llerrs << "newMessage - Message " << name << " not registered" << llendl;
- }
-}
-
void LLMessageSystem::copyMessageRtoS()
{
- if (!mCurrentRMessageTemplate)
+ // NOTE: babbage: switch builder to match reader to avoid
+ // converting message format
+ if(mMessageReader == mTemplateMessageReader)
{
- return;
+ mMessageBuilder = mTemplateMessageBuilder;
}
- newMessageFast(mCurrentRMessageTemplate->mName);
-
- // copy the blocks
- // counting variables used to encode multiple block info
- S32 block_count = 0;
- char *block_name = NULL;
-
- // loop through msg blocks to loop through variables, totalling up size data and filling the new (send) message
- LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.begin();
- LLMsgData::msg_blk_data_map_t::iterator end = mCurrentRMessageData->mMemberBlocks.end();
- for(; iter != end; ++iter)
+ else
{
- LLMsgBlkData* mbci = iter->second;
- if(!mbci) continue;
-
- // do we need to encode a block code?
- if (block_count == 0)
- {
- block_count = mbci->mBlockNumber;
- block_name = (char *)mbci->mName;
- }
-
- // counting down mutliple blocks
- block_count--;
-
- nextBlockFast(block_name);
-
- // now loop through the variables
- LLMsgBlkData::msg_var_data_map_t::iterator dit = mbci->mMemberVarData.begin();
- LLMsgBlkData::msg_var_data_map_t::iterator dend = mbci->mMemberVarData.end();
-
- for(; dit != dend; ++dit)
- {
- LLMsgVarData& mvci = *dit;
- addDataFast(mvci.getName(), mvci.getData(), mvci.getType(), mvci.getSize());
- }
+ mMessageBuilder = mLLSDMessageBuilder;
}
+ mSendReliable = FALSE;
+ mMessageBuilder->newMessage(mMessageReader->getMessageName());
+ mMessageReader->copyToBuilder(*mMessageBuilder);
}
void LLMessageSystem::clearMessage()
{
- mbSBuilt = FALSE;
- mbSClear = TRUE;
-
- mCurrentSendTotal = 0;
mSendReliable = FALSE;
-
- mCurrentSMessageTemplate = NULL;
-
- delete mCurrentSMessageData;
- mCurrentSMessageData = NULL;
-
- mCurrentSMessageName = NULL;
- mCurrentSDataBlock = NULL;
- mCurrentSBlockName = NULL;
+ mMessageBuilder->clearMessage();
}
-
// set block to add data to within current message
void LLMessageSystem::nextBlockFast(const char *blockname)
{
- char *bnamep = (char *)blockname;
-
- if (!mCurrentSMessageTemplate)
- {
- llerrs << "newMessage not called prior to setBlock" << llendl;
- return;
- }
-
- // now, does this block exist?
- LLMessageTemplate::message_block_map_t::iterator temp_iter = mCurrentSMessageTemplate->mMemberBlocks.find(bnamep);
- if (temp_iter == mCurrentSMessageTemplate->mMemberBlocks.end())
- {
- llerrs << "LLMessageSystem::nextBlockFast " << bnamep
- << " not a block in " << mCurrentSMessageTemplate->mName << llendl;
- return;
- }
-
- LLMessageBlock* template_data = temp_iter->second;
-
- // ok, have we already set this block?
- LLMsgBlkData* block_data = mCurrentSMessageData->mMemberBlocks[bnamep];
- if (block_data->mBlockNumber == 0)
- {
- // nope! set this as the current block
- block_data->mBlockNumber = 1;
- mCurrentSDataBlock = block_data;
- mCurrentSBlockName = bnamep;
-
- // add placeholders for each of the variables
- for (LLMessageBlock::message_variable_map_t::iterator iter = template_data->mMemberVariables.begin();
- iter != template_data->mMemberVariables.end(); iter++)
- {
- LLMessageVariable& ci = *(iter->second);
- mCurrentSDataBlock->addVariable(ci.getName(), ci.getType());
- }
- return;
- }
- else
- {
- // already have this block. . .
- // are we supposed to have a new one?
-
- // if the block is type MBT_SINGLE this is bad!
- if (template_data->mType == MBT_SINGLE)
- {
- llerrs << "LLMessageSystem::nextBlockFast called multiple times"
- << " for " << bnamep << " but is type MBT_SINGLE" << llendl;
- return;
- }
-
-
- // if the block is type MBT_MULTIPLE then we need a known number, make sure that we're not exceeding it
- if ( (template_data->mType == MBT_MULTIPLE)
- &&(mCurrentSDataBlock->mBlockNumber == template_data->mNumber))
- {
- llerrs << "LLMessageSystem::nextBlockFast called "
- << mCurrentSDataBlock->mBlockNumber << " times for " << bnamep
- << " exceeding " << template_data->mNumber
- << " specified in type MBT_MULTIPLE." << llendl;
- return;
- }
-
- // ok, we can make a new one
- // modify the name to avoid name collision by adding number to end
- S32 count = block_data->mBlockNumber;
-
- // incrememt base name's count
- block_data->mBlockNumber++;
-
- if (block_data->mBlockNumber > MAX_BLOCKS)
- {
- llerrs << "Trying to pack too many blocks into MBT_VARIABLE type (limited to " << MAX_BLOCKS << ")" << llendl;
- }
-
- // create new name
- // Nota Bene: if things are working correctly, mCurrentMessageData->mMemberBlocks[blockname]->mBlockNumber == mCurrentDataBlock->mBlockNumber + 1
-
- char *nbnamep = bnamep + count;
-
- mCurrentSDataBlock = new LLMsgBlkData(bnamep, count);
- mCurrentSDataBlock->mName = nbnamep;
- mCurrentSMessageData->mMemberBlocks[nbnamep] = mCurrentSDataBlock;
-
- // add placeholders for each of the variables
- for (LLMessageBlock::message_variable_map_t::iterator
- iter = template_data->mMemberVariables.begin(),
- end = template_data->mMemberVariables.end();
- iter != end; iter++)
- {
- LLMessageVariable& ci = *(iter->second);
- mCurrentSDataBlock->addVariable(ci.getName(), ci.getType());
- }
- return;
- }
-}
-
-// add data to variable in current block
-void LLMessageSystem::addDataFast(const char *varname, const void *data, EMsgVariableType type, S32 size)
-{
- char *vnamep = (char *)varname;
-
- // do we have a current message?
- if (!mCurrentSMessageTemplate)
- {
- llerrs << "newMessage not called prior to addData" << llendl;
- return;
- }
-
- // do we have a current block?
- if (!mCurrentSDataBlock)
- {
- llerrs << "setBlock not called prior to addData" << llendl;
- return;
- }
-
- // kewl, add the data if it exists
- LLMessageVariable* var_data = mCurrentSMessageTemplate->mMemberBlocks[mCurrentSBlockName]->mMemberVariables[vnamep];
- if (!var_data || !var_data->getName())
- {
- llerrs << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << llendl;
- return;
- }
-
- // ok, it seems ok. . . are we the correct size?
- if (var_data->getType() == MVT_VARIABLE)
- {
- // Variable 1 can only store 255 bytes, make sure our data is smaller
- if ((var_data->getSize() == 1) &&
- (size > 255))
- {
- llwarns << "Field " << varname << " is a Variable 1 but program "
- << "attempted to stuff more than 255 bytes in "
- << "(" << size << "). Clamping size and truncating data." << llendl;
- size = 255;
- char *truncate = (char *)data;
- truncate[255] = 0;
- }
-
- // no correct size for MVT_VARIABLE, instead we need to tell how many bytes the size will be encoded as
- mCurrentSDataBlock->addData(vnamep, data, size, type, var_data->getSize());
- mCurrentSendTotal += size;
- }
- else
- {
- if (size != var_data->getSize())
- {
- llerrs << varname << " is type MVT_FIXED but request size " << size << " doesn't match template size "
- << var_data->getSize() << llendl;
- return;
- }
- // alright, smash it in
- mCurrentSDataBlock->addData(vnamep, data, size, type);
- mCurrentSendTotal += size;
- }
-}
-
-// add data to variable in current block - fails if variable isn't MVT_FIXED
-void LLMessageSystem::addDataFast(const char *varname, const void *data, EMsgVariableType type)
-{
- char *vnamep = (char *)varname;
-
- // do we have a current message?
- if (!mCurrentSMessageTemplate)
- {
- llerrs << "newMessage not called prior to addData" << llendl;
- return;
- }
-
- // do we have a current block?
- if (!mCurrentSDataBlock)
- {
- llerrs << "setBlock not called prior to addData" << llendl;
- return;
- }
-
- // kewl, add the data if it exists
- LLMessageVariable* var_data = mCurrentSMessageTemplate->mMemberBlocks[mCurrentSBlockName]->mMemberVariables[vnamep];
- if (!var_data->getName())
- {
- llerrs << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << llendl;
- return;
- }
-
- // ok, it seems ok. . . are we MVT_VARIABLE?
- if (var_data->getType() == MVT_VARIABLE)
- {
- // nope
- llerrs << vnamep << " is type MVT_VARIABLE. Call using addData(name, data, size)" << llendl;
- return;
- }
- else
- {
- mCurrentSDataBlock->addData(vnamep, data, var_data->getSize(), type);
- mCurrentSendTotal += var_data->getSize();
- }
+ mMessageBuilder->nextBlock(blockname);
}
BOOL LLMessageSystem::isSendFull(const char* blockname)
{
- if(!blockname)
+ char* stringTableName = NULL;
+ if(NULL != blockname)
{
- return (mCurrentSendTotal > MTUBYTES);
+ stringTableName = gMessageStringTable.getString(blockname);
}
- return isSendFullFast(gMessageStringTable.getString(blockname));
+ return isSendFullFast(stringTableName);
}
BOOL LLMessageSystem::isSendFullFast(const char* blockname)
{
- if(mCurrentSendTotal > MTUBYTES)
- {
- return TRUE;
- }
- if(!blockname)
- {
- return FALSE;
- }
- char* bnamep = (char*)blockname;
- S32 max;
-
- LLMessageBlock* template_data = mCurrentSMessageTemplate->mMemberBlocks[bnamep];
-
- switch(template_data->mType)
- {
- case MBT_SINGLE:
- max = 1;
- break;
- case MBT_MULTIPLE:
- max = template_data->mNumber;
- break;
- case MBT_VARIABLE:
- default:
- max = MAX_BLOCKS;
- break;
- }
- if(mCurrentSMessageData->mMemberBlocks[bnamep]->mBlockNumber >= max)
- {
- return TRUE;
- }
- return FALSE;
+ return mMessageBuilder->isMessageFull(blockname);
}
// blow away the last block of a message, return FALSE if that leaves no blocks or there wasn't a block to remove
-BOOL LLMessageSystem::removeLastBlock()
-{
- if (mCurrentSBlockName)
- {
- if ( (mCurrentSMessageData)
- &&(mCurrentSMessageTemplate))
- {
- if (mCurrentSMessageData->mMemberBlocks[mCurrentSBlockName]->mBlockNumber >= 1)
- {
- // At least one block for the current block name.
-
- // Store the current block name for future reference.
- char *block_name = mCurrentSBlockName;
-
- // Decrement the sent total by the size of the
- // data in the message block that we're currently building.
-
- LLMessageBlock* template_data = mCurrentSMessageTemplate->mMemberBlocks[mCurrentSBlockName];
-
- for (LLMessageBlock::message_variable_map_t::iterator iter = template_data->mMemberVariables.begin();
- iter != template_data->mMemberVariables.end(); iter++)
- {
- LLMessageVariable& ci = *(iter->second);
- mCurrentSendTotal -= ci.getSize();
- }
-
-
- // Now we want to find the block that we're blowing away.
-
- // Get the number of blocks.
- LLMsgBlkData* block_data = mCurrentSMessageData->mMemberBlocks[block_name];
- S32 num_blocks = block_data->mBlockNumber;
-
- // Use the same (suspect?) algorithm that's used to generate
- // the names in the nextBlock method to find it.
- char *block_getting_whacked = block_name + num_blocks - 1;
- LLMsgBlkData* whacked_data = mCurrentSMessageData->mMemberBlocks[block_getting_whacked];
- delete whacked_data;
- mCurrentSMessageData->mMemberBlocks.erase(block_getting_whacked);
-
- if (num_blocks <= 1)
- {
- // we just blew away the last one, so return FALSE
- return FALSE;
- }
- else
- {
- // Decrement the counter.
- block_data->mBlockNumber--;
- return TRUE;
- }
- }
- }
- }
- return FALSE;
-}
-
-// make sure that all the desired data is in place and then copy the data into mSendBuffer
-void LLMessageSystem::buildMessage()
+// TODO: Babbage: Remove this horror.
+BOOL LLMessageSystem::removeLastBlock()
{
- // basic algorithm is to loop through the various pieces, building
- // size and offset info if we encounter a -1 for mSize at any
- // point that variable wasn't given data
-
- // do we have a current message?
- if (!mCurrentSMessageTemplate)
- {
- llerrs << "newMessage not called prior to buildMessage" << llendl;
- return;
- }
-
- // zero out some useful values
-
- // leave room for circuit counter
- mSendSize = LL_PACKET_ID_SIZE;
-
- // encode message number and adjust total_offset
- if (mCurrentSMessageTemplate->mFrequency == MFT_HIGH)
- {
-// old, endian-dependant way
-// memcpy(&mSendBuffer[mSendSize], &mCurrentMessageTemplate->mMessageNumber, sizeof(U8));
-
-// new, independant way
- mSendBuffer[mSendSize] = (U8)mCurrentSMessageTemplate->mMessageNumber;
- mSendSize += sizeof(U8);
- }
- else if (mCurrentSMessageTemplate->mFrequency == MFT_MEDIUM)
- {
- U8 temp = 255;
- memcpy(&mSendBuffer[mSendSize], &temp, sizeof(U8)); /*Flawfinder: ignore*/
- mSendSize += sizeof(U8);
-
- // mask off unsightly bits
- temp = mCurrentSMessageTemplate->mMessageNumber & 255;
- memcpy(&mSendBuffer[mSendSize], &temp, sizeof(U8)); /*Flawfinder: ignore*/
- mSendSize += sizeof(U8);
- }
- else if (mCurrentSMessageTemplate->mFrequency == MFT_LOW)
- {
- U8 temp = 255;
- U16 message_num;
- memcpy(&mSendBuffer[mSendSize], &temp, sizeof(U8)); /*Flawfinder: ignore*/
- mSendSize += sizeof(U8);
- memcpy(&mSendBuffer[mSendSize], &temp, sizeof(U8)); /*Flawfinder: ignore*/
- mSendSize += sizeof(U8);
-
- // mask off unsightly bits
- message_num = mCurrentSMessageTemplate->mMessageNumber & 0xFFFF;
-
- // convert to network byte order
- message_num = htons(message_num);
- memcpy(&mSendBuffer[mSendSize], &message_num, sizeof(U16)); /*Flawfinder: ignore*/
- mSendSize += sizeof(U16);
- }
- else
- {
- llerrs << "unexpected message frequency in buildMessage" << llendl;
- return;
- }
-
- // counting variables used to encode multiple block info
- S32 block_count = 0;
- U8 temp_block_number;
-
- // loop through msg blocks to loop through variables, totalling up size data and copying into mSendBuffer
- for (LLMsgData::msg_blk_data_map_t::iterator
- iter = mCurrentSMessageData->mMemberBlocks.begin(),
- end = mCurrentSMessageData->mMemberBlocks.end();
- iter != end; iter++)
- {
- LLMsgBlkData* mbci = iter->second;
- // do we need to encode a block code?
- if (block_count == 0)
- {
- block_count = mbci->mBlockNumber;
-
- LLMessageBlock* template_data = mCurrentSMessageTemplate->mMemberBlocks[mbci->mName];
-
- // ok, if this is the first block of a repeating pack, set block_count and, if it's type MBT_VARIABLE encode a byte for how many there are
- if (template_data->mType == MBT_VARIABLE)
- {
- // remember that mBlockNumber is a S32
- temp_block_number = (U8)mbci->mBlockNumber;
- if ((S32)(mSendSize + sizeof(U8)) < MAX_BUFFER_SIZE)
- {
- memcpy(&mSendBuffer[mSendSize], &temp_block_number, sizeof(U8)); /* Flawfinder: ignore */
- mSendSize += sizeof(U8);
- }
- else
- {
- // Just reporting error is likely not enough. Need
- // to check how to abort or error out gracefully
- // from this function. XXXTBD
- llerrs << "buildMessage failed. Message excedding"
- " sendBuffersize." << llendl;
- }
- }
- else if (template_data->mType == MBT_MULTIPLE)
- {
- if (block_count != template_data->mNumber)
- {
- // nope! need to fill it in all the way!
- llerrs << "Block " << mbci->mName
- << " is type MBT_MULTIPLE but only has data for "
- << block_count << " out of its "
- << template_data->mNumber << " blocks" << llendl;
- }
- }
- }
-
- // counting down multiple blocks
- block_count--;
-
- // now loop through the variables
- for (LLMsgBlkData::msg_var_data_map_t::iterator iter = mbci->mMemberVarData.begin();
- iter != mbci->mMemberVarData.end(); iter++)
- {
- LLMsgVarData& mvci = *iter;
- if (mvci.getSize() == -1)
- {
- // oops, this variable wasn't ever set!
- llerrs << "The variable " << mvci.getName() << " in block "
- << mbci->mName << " of message "
- << mCurrentSMessageData->mName
- << " wasn't set prior to buildMessage call" << llendl;
- }
- else
- {
- S32 data_size = mvci.getDataSize();
- if(data_size > 0)
- {
- // The type is MVT_VARIABLE, which means that we
- // need to encode a size argument. Otherwise,
- // there is no need.
- S32 size = mvci.getSize();
- U8 sizeb;
- U16 sizeh;
- switch(data_size)
- {
- case 1:
- sizeb = size;
- htonmemcpy(&mSendBuffer[mSendSize], &sizeb, MVT_U8, 1);
- break;
- case 2:
- sizeh = size;
- htonmemcpy(&mSendBuffer[mSendSize], &sizeh, MVT_U16, 2);
- break;
- case 4:
- htonmemcpy(&mSendBuffer[mSendSize], &size, MVT_S32, 4);
- break;
- default:
- llerrs << "Attempting to build variable field with unknown size of " << size << llendl;
- break;
- }
- mSendSize += mvci.getDataSize();
- }
-
- // if there is any data to pack, pack it
- if((mvci.getData() != NULL) && mvci.getSize())
- {
- if(mSendSize + mvci.getSize() < (S32)sizeof(mSendBuffer))
- {
- memcpy( /* Flawfinder: ignore */
- &mSendBuffer[mSendSize],
- mvci.getData(),
- mvci.getSize());
- mSendSize += mvci.getSize();
- }
- else
- {
- // Just reporting error is likely not
- // enough. Need to check how to abort or error
- // out gracefully from this function. XXXTBD
- llerrs << "LLMessageSystem::buildMessage failed. "
- << "Attempted to pack "
- << mSendSize + mvci.getSize()
- << " bytes into a buffer with size "
- << mSendBuffer << "." << llendl
- }
- }
- }
- }
- }
- mbSBuilt = TRUE;
+ return mMessageBuilder->removeLastBlock();
}
S32 LLMessageSystem::sendReliable(const LLHost &host)
@@ -2858,7 +1885,9 @@ S32 LLMessageSystem::sendSemiReliable(const LLHost &host, void (*callback)(void
timeout = LL_SEMIRELIABLE_TIMEOUT_FACTOR * LL_AVERAGED_PING_MAX;
}
- return sendReliable(host, 0, FALSE, timeout, callback, callback_data);
+ const S32 retries = 0;
+ const BOOL ping_based_timeout = FALSE;
+ return sendReliable(host, retries, ping_based_timeout, timeout, callback, callback_data);
}
// send the message via a UDP packet
@@ -2884,7 +1913,8 @@ S32 LLMessageSystem::sendReliable( const LLHost &host,
mSendReliable = TRUE;
mReliablePacketParams.set(host, retries, ping_based_timeout, timeout,
- callback, callback_data, mCurrentSMessageName);
+ callback, callback_data,
+ const_cast<char*>(mMessageBuilder->getMessageName()));
return sendMessage(host);
}
@@ -2922,11 +1952,13 @@ S32 LLMessageSystem::flushSemiReliable(const LLHost &host, void (*callback)(void
}
S32 send_bytes = 0;
- if (mCurrentSendTotal)
+ if (mMessageBuilder->getMessageSize())
{
mSendReliable = TRUE;
// No need for ping-based retry as not going to retry
- mReliablePacketParams.set(host, 0, FALSE, timeout, callback, callback_data, mCurrentSMessageName);
+ mReliablePacketParams.set(host, 0, FALSE, timeout, callback,
+ callback_data,
+ const_cast<char*>(mMessageBuilder->getMessageName()));
send_bytes = sendMessage(host);
clearMessage();
}
@@ -2940,7 +1972,7 @@ S32 LLMessageSystem::flushSemiReliable(const LLHost &host, void (*callback)(void
S32 LLMessageSystem::flushReliable(const LLHost &host)
{
S32 send_bytes = 0;
- if (mCurrentSendTotal)
+ if (mMessageBuilder->getMessageSize())
{
send_bytes = sendReliable(host);
}
@@ -2953,13 +1985,12 @@ S32 LLMessageSystem::flushReliable(const LLHost &host)
// so should should not use llinfos.
S32 LLMessageSystem::sendMessage(const LLHost &host)
{
- if (!mbSBuilt)
+ if (! mMessageBuilder->isBuilt())
{
- buildMessage();
+ mSendSize = mMessageBuilder->buildMessage(mSendBuffer,
+ MAX_BUFFER_SIZE);
}
- mCurrentSendTotal = 0;
-
if (!(host.isOk())) // if port and ip are zero, don't bother trying to send the message
{
return 0;
@@ -2976,10 +2007,10 @@ S32 LLMessageSystem::sendMessage(const LLHost &host)
if(mVerboseLog)
{
llinfos << "MSG: -> " << host << "\tUNKNOWN CIRCUIT:\t"
- << mCurrentSMessageName << llendl;
+ << mMessageBuilder->getMessageName() << llendl;
}
llwarns << "sendMessage - Trying to send "
- << mCurrentSMessageName << " on unknown circuit "
+ << mMessageBuilder->getMessageName() << " on unknown circuit "
<< host << llendl;
return 0;
}
@@ -2998,15 +2029,41 @@ S32 LLMessageSystem::sendMessage(const LLHost &host)
if(mVerboseLog)
{
llinfos << "MSG: -> " << host << "\tDEAD CIRCUIT\t\t"
- << mCurrentSMessageName << llendl;
+ << mMessageBuilder->getMessageName() << llendl;
}
llwarns << "sendMessage - Trying to send message "
- << mCurrentSMessageName << " to dead circuit "
+ << mMessageBuilder->getMessageName() << " to dead circuit "
<< host << llendl;
return 0;
}
}
+ // NOTE: babbage: LLSD message -> HTTP, template message -> UDP
+ if(mMessageBuilder == mLLSDMessageBuilder)
+ {
+ LLSD message = mLLSDMessageBuilder->getMessage();
+
+ const LLHTTPSender& sender = LLHTTPSender::getSender(host);
+ LLHTTPClient::ResponderPtr responder = NULL;
+ if(mSendReliable)
+ {
+ responder =
+ new LLFnPtrResponder(mReliablePacketParams.mCallback,
+ mReliablePacketParams.mCallbackData);
+ }
+ else
+ {
+ llwarns << "LLMessageSystem::sendMessage: Sending unreliable " << mMessageBuilder->getMessageName() << " message via HTTP" << llendl;
+ responder = new LLFnPtrResponder(NULL, NULL);
+ }
+ sender.send(host, mLLSDMessageBuilder->getMessageName(),
+ message, responder);
+
+ mSendReliable = FALSE;
+ mReliablePacketParams.clear();
+ return 1;
+ }
+
memset(mSendBuffer,0,LL_PACKET_ID_SIZE); // zero out the packet ID field
// add the send id to the front of the message
@@ -3017,20 +2074,17 @@ S32 LLMessageSystem::sendMessage(const LLHost &host)
// Compress the message, which will usually reduce its size.
U8 * buf_ptr = (U8 *)mSendBuffer;
- S32 buffer_length = mSendSize;
- if(ME_ZEROCODED == mCurrentSMessageTemplate->getEncoding())
- {
- zeroCode(&buf_ptr, &buffer_length);
- }
+ U32 buffer_length = mSendSize;
+ mMessageBuilder->compressMessage(buf_ptr, buffer_length);
if (buffer_length > 1500)
{
- if((mCurrentSMessageName != _PREHASH_ChildAgentUpdate)
- && (mCurrentSMessageName != _PREHASH_SendXferPacket))
+ if((mMessageBuilder->getMessageName() != _PREHASH_ChildAgentUpdate)
+ && (mMessageBuilder->getMessageName() != _PREHASH_SendXferPacket))
{
llwarns << "sendMessage - Trying to send "
<< ((buffer_length > 4000) ? "EXTRA " : "")
- << "BIG message " << mCurrentSMessageName << " - "
+ << "BIG message " << mMessageBuilder->getMessageName() << " - "
<< buffer_length << llendl;
}
}
@@ -3055,7 +2109,7 @@ S32 LLMessageSystem::sendMessage(const LLHost &host)
BOOL is_ack_appended = FALSE;
std::vector<TPACKETID> acks;
if((space_left > 0) && (ack_count > 0) &&
- (mCurrentSMessageName != _PREHASH_PacketAck))
+ (mMessageBuilder->getMessageName() != _PREHASH_PacketAck))
{
buf_ptr[0] |= LL_ACK_FLAG;
S32 append_ack_count = llmin(space_left, ack_count);
@@ -3126,7 +2180,7 @@ S32 LLMessageSystem::sendMessage(const LLHost &host)
char buffer[MAX_STRING]; /* Flawfinder: ignore */
snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mSendSize, buffer_length, cdp->getPacketOutID()); /* Flawfinder: ignore */
str << buffer
- << mCurrentSMessageTemplate->mName
+ << mMessageBuilder->getMessageName()
<< (mSendReliable ? " reliable " : "");
if(is_ack_appended)
{
@@ -3137,89 +2191,19 @@ S32 LLMessageSystem::sendMessage(const LLHost &host)
llinfos << str.str() << llendl;
}
- lldebugst(LLERR_MESSAGE) << "MessageSent at: " << (S32)totalTime()
- << ", " << mCurrentSMessageTemplate->mName
- << " to " << host
- << llendl;
-
- // ok, clean up temp data
- delete mCurrentSMessageData;
- mCurrentSMessageData = NULL;
+ /*lldebugst(LLERR_MESSAGE) << "MessageSent at: " << (S32)totalTime()
+ << "," << mMessageBuilder->getMessageName()
+ << " to " << host
+ << llendl;*/
mPacketsOut++;
mBytesOut += buffer_length;
+ mSendReliable = FALSE;
+ mReliablePacketParams.clear();
return buffer_length;
}
-
-// Returns template for the message contained in buffer
-BOOL LLMessageSystem::decodeTemplate(
- const U8* buffer, S32 buffer_size, // inputs
- LLMessageTemplate** msg_template ) // outputs
-{
- const U8* header = buffer + LL_PACKET_ID_SIZE;
-
- // is there a message ready to go?
- if (buffer_size <= 0)
- {
- llwarns << "No message waiting for decode!" << llendl;
- return(FALSE);
- }
-
- U32 num = 0;
-
- if (header[0] != 255)
- {
- // high frequency message
- num = header[0];
- }
- else if ((buffer_size >= ((S32) LL_MINIMUM_VALID_PACKET_SIZE + 1)) && (header[1] != 255))
- {
- // medium frequency message
- num = (255 << 8) | header[1];
- }
- else if ((buffer_size >= ((S32) LL_MINIMUM_VALID_PACKET_SIZE + 3)) && (header[1] == 255))
- {
- // low frequency message
- U16 message_id_U16 = 0;
- // I think this check busts the message system.
- // it appears that if there is a NULL in the message #, it won't copy it....
- // what was the goal?
- //if(header[2])
- memcpy(&message_id_U16, &header[2], 2); /* Flawfinder: ignore */
-
- // dependant on endian-ness:
- // U32 temp = (255 << 24) | (255 << 16) | header[2];
-
- // independant of endian-ness:
- message_id_U16 = ntohs(message_id_U16);
- num = 0xFFFF0000 | message_id_U16;
- }
- else // bogus packet received (too short)
- {
- llwarns << "Packet with unusable length received (too short): "
- << buffer_size << llendl;
- return(FALSE);
- }
-
- LLMessageTemplate* temp = get_ptr_in_map(mMessageNumbers,num);
- if (temp)
- {
- *msg_template = temp;
- }
- else
- {
- llwarns << "Message #" << std::hex << num << std::dec
- << " received but not registered!" << llendl;
- callExceptionFunc(MX_UNREGISTERED_MESSAGE);
- return(FALSE);
- }
-
- return(TRUE);
-}
-
-
void LLMessageSystem::logMsgFromInvalidCircuit( const LLHost& host, BOOL recv_reliable )
{
if(mVerboseLog)
@@ -3227,9 +2211,9 @@ void LLMessageSystem::logMsgFromInvalidCircuit( const LLHost& host, BOOL recv_re
std::ostringstream str;
str << "MSG: <- " << host;
char buffer[MAX_STRING]; /* Flawfinder: ignore */
- snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mReceiveSize, (mIncomingCompressedSize ? mIncomingCompressedSize: mReceiveSize), mCurrentRecvPacketID); /* Flawfinder: ignore */
+ snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mMessageReader->getMessageSize(), (mIncomingCompressedSize ? mIncomingCompressedSize: mMessageReader->getMessageSize()), mCurrentRecvPacketID); /* Flawfinder: ignore */
str << buffer
- << mCurrentRMessageTemplate->mName
+ << mMessageReader->getMessageName()
<< (recv_reliable ? " reliable" : "")
<< " REJECTED";
llinfos << str.str() << llendl;
@@ -3244,8 +2228,9 @@ void LLMessageSystem::logMsgFromInvalidCircuit( const LLHost& host, BOOL recv_re
}
else
{
- mMessageCountList[mNumMessageCounts].mMessageNum = mCurrentRMessageTemplate->mMessageNumber;
- mMessageCountList[mNumMessageCounts].mMessageBytes = mReceiveSize;
+ // TODO: babbage: work out if we need these
+ // mMessageCountList[mNumMessageCounts].mMessageNum = mCurrentRMessageTemplate->mMessageNumber;
+ mMessageCountList[mNumMessageCounts].mMessageBytes = mMessageReader->getMessageSize();
mMessageCountList[mNumMessageCounts].mInvalid = TRUE;
mNumMessageCounts++;
}
@@ -3255,11 +2240,11 @@ void LLMessageSystem::logTrustedMsgFromUntrustedCircuit( const LLHost& host )
{
// RequestTrustedCircuit is how we establish trust, so don't spam
// if it's received on a trusted circuit. JC
- if (strcmp(mCurrentRMessageTemplate->mName, "RequestTrustedCircuit"))
+ if (strcmp(mMessageReader->getMessageName(), "RequestTrustedCircuit"))
{
llwarns << "Received trusted message on untrusted circuit. "
<< "Will reply with deny. "
- << "Message: " << mCurrentRMessageTemplate->mName
+ << "Message: " << mMessageReader->getMessageName()
<< " Host: " << host << llendl;
}
@@ -3271,10 +2256,11 @@ void LLMessageSystem::logTrustedMsgFromUntrustedCircuit( const LLHost& host )
}
else
{
- mMessageCountList[mNumMessageCounts].mMessageNum
- = mCurrentRMessageTemplate->mMessageNumber;
+ // TODO: babbage: work out if we need these
+ //mMessageCountList[mNumMessageCounts].mMessageNum
+ // = mCurrentRMessageTemplate->mMessageNumber;
mMessageCountList[mNumMessageCounts].mMessageBytes
- = mReceiveSize;
+ = mMessageReader->getMessageSize();
mMessageCountList[mNumMessageCounts].mInvalid = TRUE;
mNumMessageCounts++;
}
@@ -3288,8 +2274,9 @@ void LLMessageSystem::logValidMsg(LLCircuitData *cdp, const LLHost& host, BOOL r
}
else
{
- mMessageCountList[mNumMessageCounts].mMessageNum = mCurrentRMessageTemplate->mMessageNumber;
- mMessageCountList[mNumMessageCounts].mMessageBytes = mReceiveSize;
+ // TODO: babbage: work out if we need these
+ //mMessageCountList[mNumMessageCounts].mMessageNum = mCurrentRMessageTemplate->mMessageNumber;
+ mMessageCountList[mNumMessageCounts].mMessageBytes = mMessageReader->getMessageSize();
mMessageCountList[mNumMessageCounts].mInvalid = FALSE;
mNumMessageCounts++;
}
@@ -3306,9 +2293,9 @@ void LLMessageSystem::logValidMsg(LLCircuitData *cdp, const LLHost& host, BOOL r
std::ostringstream str;
str << "MSG: <- " << host;
char buffer[MAX_STRING]; /* Flawfinder: ignore */
- snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mReceiveSize, (mIncomingCompressedSize ? mIncomingCompressedSize : mReceiveSize), mCurrentRecvPacketID); /* Flawfinder: ignore */
+ snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mMessageReader->getMessageSize(), (mIncomingCompressedSize ? mIncomingCompressedSize : mMessageReader->getMessageSize()), mCurrentRecvPacketID); /* Flawfinder: ignore */
str << buffer
- << mCurrentRMessageTemplate->mName
+ << mMessageReader->getMessageName()
<< (recv_reliable ? " reliable" : "")
<< (recv_resent ? " resent" : "")
<< (recv_acks ? " acks" : "");
@@ -3316,446 +2303,19 @@ void LLMessageSystem::logValidMsg(LLCircuitData *cdp, const LLHost& host, BOOL r
}
}
-
-void LLMessageSystem::logRanOffEndOfPacket( const LLHost& host )
-{
- // we've run off the end of the packet!
- llwarns << "Ran off end of packet " << mCurrentRMessageTemplate->mName
- << " with id " << mCurrentRecvPacketID << " from " << host
- << llendl;
- if(mVerboseLog)
- {
- llinfos << "MSG: -> " << host << "\tREAD PAST END:\t"
- << mCurrentRecvPacketID << " "
- << mCurrentSMessageTemplate->mName << llendl;
- }
- callExceptionFunc(MX_RAN_OFF_END_OF_PACKET);
-}
-
-
-// decode a given message
-BOOL LLMessageSystem::decodeData(const U8* buffer, const LLHost& sender )
-{
- llassert( mReceiveSize >= 0 );
- llassert( mCurrentRMessageTemplate);
- llassert( !mCurrentRMessageData );
- delete mCurrentRMessageData; // just to make sure
-
- S32 decode_pos = LL_PACKET_ID_SIZE + (S32)(mCurrentRMessageTemplate->mFrequency);
-
- // create base working data set
- mCurrentRMessageData = new LLMsgData(mCurrentRMessageTemplate->mName);
-
- // loop through the template building the data structure as we go
- for (LLMessageTemplate::message_block_map_t::iterator iter = mCurrentRMessageTemplate->mMemberBlocks.begin();
- iter != mCurrentRMessageTemplate->mMemberBlocks.end(); iter++)
- {
- LLMessageBlock* mbci = iter->second;
- U8 repeat_number;
- S32 i;
-
- // how many of this block?
-
- if (mbci->mType == MBT_SINGLE)
- {
- // just one
- repeat_number = 1;
- }
- else if (mbci->mType == MBT_MULTIPLE)
- {
- // a known number
- repeat_number = mbci->mNumber;
- }
- else if (mbci->mType == MBT_VARIABLE)
- {
- // need to read the number from the message
- // repeat number is a single byte
- if (decode_pos >= mReceiveSize)
- {
- logRanOffEndOfPacket( sender );
- return FALSE;
- }
- repeat_number = buffer[decode_pos];
- decode_pos++;
- }
- else
- {
- llerrs << "Unknown block type" << llendl;
- return FALSE;
- }
-
- LLMsgBlkData* cur_data_block = NULL;
-
- // now loop through the block
- for (i = 0; i < repeat_number; i++)
- {
- if (i)
- {
- // build new name to prevent collisions
- // TODO: This should really change to a vector
- cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number);
- cur_data_block->mName = mbci->mName + i;
- }
- else
- {
- cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number);
- }
-
- // add the block to the message
- mCurrentRMessageData->addBlock(cur_data_block);
-
- // now read the variables
- for (LLMessageBlock::message_variable_map_t::iterator iter = mbci->mMemberVariables.begin();
- iter != mbci->mMemberVariables.end(); iter++)
- {
- LLMessageVariable& mvci = *(iter->second);
- // ok, build out the variables
- // add variable block
- cur_data_block->addVariable(mvci.getName(), mvci.getType());
-
- // what type of variable?
- if (mvci.getType() == MVT_VARIABLE)
- {
- // variable, get the number of bytes to read from the template
- S32 data_size = mvci.getSize();
- U8 tsizeb = 0;
- U16 tsizeh = 0;
- U32 tsize = 0;
-
- if ((decode_pos + data_size) > mReceiveSize)
- {
- logRanOffEndOfPacket( sender );
- return FALSE;
- }
- switch(data_size)
- {
- case 1:
- htonmemcpy(&tsizeb, &buffer[decode_pos], MVT_U8, 1);
- tsize = tsizeb;
- break;
- case 2:
- htonmemcpy(&tsizeh, &buffer[decode_pos], MVT_U16, 2);
- tsize = tsizeh;
- break;
- case 4:
- htonmemcpy(&tsizeb, &buffer[decode_pos], MVT_U32, 4);
- break;
- default:
- llerrs << "Attempting to read variable field with unknown size of " << data_size << llendl;
- break;
-
- }
- decode_pos += data_size;
-
- if ((decode_pos + (S32)tsize) > mReceiveSize)
- {
- logRanOffEndOfPacket( sender );
- return FALSE;
- }
- cur_data_block->addData(mvci.getName(), &buffer[decode_pos], tsize, mvci.getType());
- decode_pos += tsize;
- }
- else
- {
- // fixed!
- // so, copy data pointer and set data size to fixed size
-
- if ((decode_pos + mvci.getSize()) > mReceiveSize)
- {
- logRanOffEndOfPacket( sender );
- return FALSE;
- }
-
- cur_data_block->addData(mvci.getName(), &buffer[decode_pos], mvci.getSize(), mvci.getType());
- decode_pos += mvci.getSize();
- }
- }
- }
- }
-
- if (mCurrentRMessageData->mMemberBlocks.empty()
- && !mCurrentRMessageTemplate->mMemberBlocks.empty())
- {
- lldebugs << "Empty message '" << mCurrentRMessageTemplate->mName << "' (no blocks)" << llendl;
- return FALSE;
- }
-
- {
- static LLTimer decode_timer;
-
- if( mTimeDecodes || mTimingCallback )
- {
- decode_timer.reset();
- }
-
- // if( mCurrentRMessageTemplate->mName == _PREHASH_AgentToNewRegion )
- // {
- // VTResume(); // VTune
- // }
-
- {
- LLFastTimer t(LLFastTimer::FTM_PROCESS_MESSAGES);
- if( !mCurrentRMessageTemplate->callHandlerFunc(this) )
- {
- llwarns << "Message from " << sender << " with no handler function received: " << mCurrentRMessageTemplate->mName << llendl;
- }
- }
-
- // if( mCurrentRMessageTemplate->mName == _PREHASH_AgentToNewRegion )
- // {
- // VTPause(); // VTune
- // }
-
- if( mTimeDecodes || mTimingCallback )
- {
- F32 decode_time = decode_timer.getElapsedTimeF32();
-
- if (mTimingCallback)
- {
- mTimingCallback(mCurrentRMessageTemplate->mName,
- decode_time,
- mTimingCallbackData);
- }
-
- if (mTimeDecodes)
- {
- mCurrentRMessageTemplate->mDecodeTimeThisFrame += decode_time;
-
- mCurrentRMessageTemplate->mTotalDecoded++;
- mCurrentRMessageTemplate->mTotalDecodeTime += decode_time;
-
- if( mCurrentRMessageTemplate->mMaxDecodeTimePerMsg < decode_time )
- {
- mCurrentRMessageTemplate->mMaxDecodeTimePerMsg = decode_time;
- }
-
-
- if( decode_time > mTimeDecodesSpamThreshold )
- {
- lldebugs << "--------- Message " << mCurrentRMessageTemplate->mName << " decode took " << decode_time << " seconds. (" <<
- mCurrentRMessageTemplate->mMaxDecodeTimePerMsg << " max, " <<
- (mCurrentRMessageTemplate->mTotalDecodeTime / mCurrentRMessageTemplate->mTotalDecoded) << " avg)" << llendl;
- }
- }
- }
- }
- return TRUE;
-}
-
-void LLMessageSystem::getDataFast(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum, S32 max_size)
-{
- // is there a message ready to go?
- if (mReceiveSize == -1)
- {
- llerrs << "No message waiting for decode 2!" << llendl;
- return;
- }
-
- if (!mCurrentRMessageData)
- {
- llerrs << "Invalid mCurrentMessageData in getData!" << llendl;
- return;
- }
-
- char *bnamep = (char *)blockname + blocknum; // this works because it's just a hash. The bnamep is never derefference
- char *vnamep = (char *)varname;
-
- LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
-
- if (iter == mCurrentRMessageData->mMemberBlocks.end())
- {
- llerrs << "Block " << blockname << " #" << blocknum
- << " not in message " << mCurrentRMessageData->mName << llendl;
- return;
- }
-
- LLMsgBlkData *msg_block_data = iter->second;
- LLMsgVarData& vardata = msg_block_data->mMemberVarData[vnamep];
-
- if (!vardata.getName())
- {
- llerrs << "Variable "<< vnamep << " not in message "
- << mCurrentRMessageData->mName<< " block " << bnamep << llendl;
- return;
- }
-
- if (size && size != vardata.getSize())
- {
- llerrs << "Msg " << mCurrentRMessageData->mName
- << " variable " << vnamep
- << " is size " << vardata.getSize()
- << " but copying into buffer of size " << size
- << llendl;
- return;
- }
-
-
- const S32 vardata_size = vardata.getSize();
- if( max_size >= vardata_size )
- {
- switch( vardata_size )
- {
- case 1:
- *((U8*)datap) = *((U8*)vardata.getData());
- break;
- case 2:
- *((U16*)datap) = *((U16*)vardata.getData());
- break;
- case 4:
- *((U32*)datap) = *((U32*)vardata.getData());
- break;
- case 8:
- ((U32*)datap)[0] = ((U32*)vardata.getData())[0];
- ((U32*)datap)[1] = ((U32*)vardata.getData())[1];
- break;
- default:
- memcpy(datap, vardata.getData(), vardata_size); /* Flawfinder: ignore */
- break;
- }
- }
- else
- {
- llwarns << "Msg " << mCurrentRMessageData->mName
- << " variable " << vnamep
- << " is size " << vardata.getSize()
- << " but truncated to max size of " << max_size
- << llendl;
-
- memcpy(datap, vardata.getData(), max_size); /* Flawfinder: ignore */
- }
-}
-
-S32 LLMessageSystem::getNumberOfBlocksFast(const char *blockname)
-{
- // is there a message ready to go?
- if (mReceiveSize == -1)
- {
- llerrs << "No message waiting for decode 3!" << llendl;
- return -1;
- }
-
- if (!mCurrentRMessageData)
- {
- llerrs << "Invalid mCurrentRMessageData in getData!" << llendl;
- return -1;
- }
-
- char *bnamep = (char *)blockname;
-
- LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
-
- if (iter == mCurrentRMessageData->mMemberBlocks.end())
- {
-// sprintf(errmsg, "Block %s not in message %s", bnamep, mCurrentRMessageData->mName);
-// llerrs << errmsg << llendl;
-// return -1;
- return 0;
- }
-
- return (iter->second)->mBlockNumber;
-}
-
-S32 LLMessageSystem::getSizeFast(const char *blockname, const char *varname)
-{
- // is there a message ready to go?
- if (mReceiveSize == -1)
- {
- llerrs << "No message waiting for decode 4!" << llendl;
- return -1;
- }
-
- if (!mCurrentRMessageData)
- {
- llerrs << "Invalid mCurrentRMessageData in getData!" << llendl;
- return -1;
- }
-
- char *bnamep = (char *)blockname;
-
- LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
-
- if (iter == mCurrentRMessageData->mMemberBlocks.end())
- {
- llerrs << "Block " << bnamep << " not in message "
- << mCurrentRMessageData->mName << llendl;
- return -1;
- }
-
- char *vnamep = (char *)varname;
-
- LLMsgBlkData* msg_data = iter->second;
- LLMsgVarData& vardata = msg_data->mMemberVarData[vnamep];
-
- if (!vardata.getName())
- {
- llerrs << "Variable " << varname << " not in message "
- << mCurrentRMessageData->mName << " block " << bnamep << llendl;
- return -1;
- }
-
- if (mCurrentRMessageTemplate->mMemberBlocks[bnamep]->mType != MBT_SINGLE)
- {
- llerrs << "Block " << bnamep << " isn't type MBT_SINGLE,"
- " use getSize with blocknum argument!" << llendl;
- return -1;
- }
-
- return vardata.getSize();
-}
-
-
-S32 LLMessageSystem::getSizeFast(const char *blockname, S32 blocknum, const char *varname)
-{
- // is there a message ready to go?
- if (mReceiveSize == -1)
- {
- llerrs << "No message waiting for decode 5!" << llendl;
- return -1;
- }
-
- if (!mCurrentRMessageData)
- {
- llerrs << "Invalid mCurrentRMessageData in getData!" << llendl;
- return -1;
- }
-
- char *bnamep = (char *)blockname + blocknum;
- char *vnamep = (char *)varname;
-
- LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
-
- if (iter == mCurrentRMessageData->mMemberBlocks.end())
- {
- llerrs << "Block " << bnamep << " not in message "
- << mCurrentRMessageData->mName << llendl;
- return -1;
- }
-
- LLMsgBlkData* msg_data = iter->second;
- LLMsgVarData& vardata = msg_data->mMemberVarData[vnamep];
-
- if (!vardata.getName())
- {
- llerrs << "Variable " << vnamep << " not in message "
- << mCurrentRMessageData->mName << " block " << bnamep << llendl;
- return -1;
- }
-
- return vardata.getSize();
-}
-
-
void LLMessageSystem::sanityCheck()
{
- if (!mCurrentRMessageData)
- {
- llerrs << "mCurrentRMessageData is NULL" << llendl;
- }
+// TODO: babbage: reinstate
- if (!mCurrentRMessageTemplate)
- {
- llerrs << "mCurrentRMessageTemplate is NULL" << llendl;
- }
+// if (!mCurrentRMessageData)
+// {
+// llerrs << "mCurrentRMessageData is NULL" << llendl;
+// }
+
+// if (!mCurrentRMessageTemplate)
+// {
+// llerrs << "mCurrentRMessageTemplate is NULL" << llendl;
+// }
// if (!mCurrentRTemplateBlock)
// {
@@ -3767,25 +2327,25 @@ void LLMessageSystem::sanityCheck()
// llerrs << "mCurrentRDataBlock is NULL" << llendl;
// }
- if (!mCurrentSMessageData)
- {
- llerrs << "mCurrentSMessageData is NULL" << llendl;
- }
+// if (!mCurrentSMessageData)
+// {
+// llerrs << "mCurrentSMessageData is NULL" << llendl;
+// }
- if (!mCurrentSMessageTemplate)
- {
- llerrs << "mCurrentSMessageTemplate is NULL" << llendl;
- }
+// if (!mCurrentSMessageTemplate)
+// {
+// llerrs << "mCurrentSMessageTemplate is NULL" << llendl;
+// }
// if (!mCurrentSTemplateBlock)
// {
// llerrs << "mCurrentSTemplateBlock is NULL" << llendl;
// }
- if (!mCurrentSDataBlock)
- {
- llerrs << "mCurrentSDataBlock is NULL" << llendl;
- }
+// if (!mCurrentSDataBlock)
+// {
+// llerrs << "mCurrentSDataBlock is NULL" << llendl;
+// }
}
void LLMessageSystem::showCircuitInfo()
@@ -4171,7 +2731,8 @@ bool LLMessageSystem::addCircuitCode(U32 code, const LLUUID& session_id)
//}
// static
-void LLMessageSystem::processUseCircuitCode(LLMessageSystem* msg, void**)
+void LLMessageSystem::processUseCircuitCode(LLMessageSystem* msg,
+ void** user)
{
U32 circuit_code_in;
msg->getU32Fast(_PREHASH_CircuitCode, _PREHASH_Code, circuit_code_in);
@@ -4291,6 +2852,13 @@ void LLMessageSystem::processUseCircuitCode(LLMessageSystem* msg, void**)
llinfos << "Circuit code " << circuit_code_in << " from "
<< msg->getSender() << " for agent " << id << " in session "
<< session_id << llendl;
+
+ const LLUseCircuitCodeResponder* responder =
+ (const LLUseCircuitCodeResponder*) user;
+ if(responder)
+ {
+ responder->complete(msg->getSender(), id);
+ }
}
else
{
@@ -4298,7 +2866,50 @@ void LLMessageSystem::processUseCircuitCode(LLMessageSystem* msg, void**)
}
}
+static LLHTTPNode& messageRootNode()
+{
+ static LLHTTPNode root_node;
+ static bool initialized = false;
+ if (!initialized) {
+ initialized = true;
+ LLHTTPRegistrar::buildAllServices(root_node);
+ }
+
+ return root_node;
+}
+
+//static
+void LLMessageSystem::dispatch(const std::string& msg_name,
+ const LLSD& message)
+{
+ LLPointer<LLSimpleResponse> responsep = LLSimpleResponse::create();
+ dispatch(msg_name, message, responsep);
+}
+//static
+void LLMessageSystem::dispatch(const std::string& msg_name,
+ const LLSD& message,
+ LLHTTPNode::ResponsePtr responsep)
+{
+ if (msg_name.empty())
+ {
+ llwarns << "LLMessageService::dispatch called with no message name"
+ << llendl;
+ return;
+ }
+
+ std::string path = "/message/" + msg_name;
+ LLSD context;
+ const LLHTTPNode* handler = messageRootNode().traverse(path, context);
+ if (!handler)
+ {
+ llwarns << "LLMessageService::dispatch > no handler for "
+ << path << llendl;
+ return;
+ }
+
+ handler->post(responsep, context, message);
+}
static void check_for_unrecognized_messages(
const char* type,
@@ -4613,7 +3224,8 @@ BOOL start_messaging_system(
S32 version_minor,
S32 version_patch,
BOOL b_dump_prehash_file,
- const std::string& secret)
+ const std::string& secret,
+ const LLUseCircuitCodeResponder* responder)
{
gMessageSystem = new LLMessageSystem(
template_name.c_str(),
@@ -4662,7 +3274,7 @@ BOOL start_messaging_system(
//gMessageSystem->setHandlerFuncFast(_PREHASH_AssignCircuitCode, LLMessageSystem::processAssignCircuitCode);
gMessageSystem->setHandlerFuncFast(_PREHASH_AddCircuitCode, LLMessageSystem::processAddCircuitCode);
//gMessageSystem->setHandlerFuncFast(_PREHASH_AckAddCircuitCode, ack_add_circuit_code, NULL);
- gMessageSystem->setHandlerFuncFast(_PREHASH_UseCircuitCode, LLMessageSystem::processUseCircuitCode);
+ gMessageSystem->setHandlerFuncFast(_PREHASH_UseCircuitCode, LLMessageSystem::processUseCircuitCode, (void**)responder);
gMessageSystem->setHandlerFuncFast(_PREHASH_PacketAck, process_packet_ack, NULL);
gMessageSystem->setHandlerFuncFast(_PREHASH_TemplateChecksumRequest, process_template_checksum_request, NULL);
gMessageSystem->setHandlerFuncFast(_PREHASH_SecuredTemplateChecksumRequest, process_secured_template_checksum_request, NULL);
@@ -4882,13 +3494,13 @@ void LLMessageSystem::dumpReceiveCounts()
BOOL LLMessageSystem::isClear() const
{
- return mbSClear;
+ return mMessageBuilder->isClear();
}
S32 LLMessageSystem::flush(const LLHost &host)
{
- if (mCurrentSendTotal)
+ if (mMessageBuilder->getMessageSize())
{
S32 sentbytes = sendMessage(host);
clearMessage();
@@ -4905,91 +3517,22 @@ U32 LLMessageSystem::getListenPort( void ) const
return mPort;
}
-
-S32 LLMessageSystem::zeroCode(U8 **data, S32 *data_size)
+// TODO: babbage: remove this horror!
+S32 LLMessageSystem::zeroCodeAdjustCurrentSendTotal()
{
- S32 count = *data_size;
-
- S32 net_gain = 0;
- U8 num_zeroes = 0;
-
- U8 *inptr = (U8 *)*data;
- U8 *outptr = (U8 *)mEncodedSendBuffer;
-
-// skip the packet id field
-
- for (U32 i=0;i<LL_PACKET_ID_SIZE;i++)
- {
- count--;
- *outptr++ = *inptr++;
- }
-
-// build encoded packet, keeping track of net size gain
-
-// sequential zero bytes are encoded as 0 [U8 count]
-// with 0 0 [count] representing wrap (>256 zeroes)
-
- while (count--)
- {
- if (!(*inptr)) // in a zero count
- {
- if (num_zeroes)
- {
- if (++num_zeroes > 254)
- {
- *outptr++ = num_zeroes;
- num_zeroes = 0;
- }
- net_gain--; // subseqent zeroes save one
- }
- else
- {
- *outptr++ = 0;
- net_gain++; // starting a zero count adds one
- num_zeroes = 1;
- }
- inptr++;
- }
- else
- {
- if (num_zeroes)
- {
- *outptr++ = num_zeroes;
- num_zeroes = 0;
- }
- *outptr++ = *inptr++;
- }
- }
-
- if (num_zeroes)
+ if(mMessageBuilder == mLLSDMessageBuilder)
{
- *outptr++ = num_zeroes;
- }
-
- if (net_gain < 0)
- {
- mCompressedPacketsOut++;
- mUncompressedBytesOut += *data_size;
-
- *data = mEncodedSendBuffer;
- *data_size += net_gain;
- mEncodedSendBuffer[0] |= LL_ZERO_CODE_FLAG; // set the head bit to indicate zero coding
-
- mCompressedBytesOut += *data_size;
-
+ // babbage: don't compress LLSD messages, so delta is 0
+ return 0;
}
- mTotalBytesOut += *data_size;
-
- return(net_gain);
-}
-
-S32 LLMessageSystem::zeroCodeAdjustCurrentSendTotal()
-{
- if (!mbSBuilt)
+
+ if (! mMessageBuilder->isBuilt())
{
- buildMessage();
+ mSendSize = mMessageBuilder->buildMessage(mSendBuffer,
+ MAX_BUFFER_SIZE);
}
- mbSBuilt = FALSE;
+ // TODO: babbage: remove this horror
+ mMessageBuilder->setBuilt(FALSE);
S32 count = mSendSize;
@@ -5169,7 +3712,6 @@ void LLMessageSystem::setHandlerFuncFast(const char *name, void (*handler_func)(
}
}
-
bool LLMessageSystem::callHandler(const char *name,
bool trustedSource, LLMessageSystem* msg)
{
@@ -5237,27 +3779,14 @@ BOOL LLMessageSystem::isCircuitCodeKnown(U32 code) const
BOOL LLMessageSystem::isMessageFast(const char *msg)
{
- if (mCurrentRMessageTemplate)
- {
- return(msg == mCurrentRMessageTemplate->mName);
- }
- else
- {
- return FALSE;
- }
+ return(msg == mMessageReader->getMessageName());
}
char* LLMessageSystem::getMessageName()
{
- if (mCurrentRMessageTemplate)
- {
- return mCurrentRMessageTemplate->mName;
- }
- else
- {
- return NULL;
- }
+ const char* name = mMessageReader->getMessageName();
+ return name[0] == '\0'? NULL : const_cast<char*>(name);
}
const LLUUID& LLMessageSystem::getSenderID() const
@@ -5281,211 +3810,6 @@ const LLUUID& LLMessageSystem::getSenderSessionID() const
return LLUUID::null;
}
-void LLMessageSystem::addVector3Fast(const char *varname, const LLVector3& vec)
-{
- addDataFast(varname, vec.mV, MVT_LLVector3, sizeof(vec.mV));
-}
-
-void LLMessageSystem::addVector3(const char *varname, const LLVector3& vec)
-{
- addDataFast(gMessageStringTable.getString(varname), vec.mV, MVT_LLVector3, sizeof(vec.mV));
-}
-
-void LLMessageSystem::addVector4Fast(const char *varname, const LLVector4& vec)
-{
- addDataFast(varname, vec.mV, MVT_LLVector4, sizeof(vec.mV));
-}
-
-void LLMessageSystem::addVector4(const char *varname, const LLVector4& vec)
-{
- addDataFast(gMessageStringTable.getString(varname), vec.mV, MVT_LLVector4, sizeof(vec.mV));
-}
-
-
-void LLMessageSystem::addVector3dFast(const char *varname, const LLVector3d& vec)
-{
- addDataFast(varname, vec.mdV, MVT_LLVector3d, sizeof(vec.mdV));
-}
-
-void LLMessageSystem::addVector3d(const char *varname, const LLVector3d& vec)
-{
- addDataFast(gMessageStringTable.getString(varname), vec.mdV, MVT_LLVector3d, sizeof(vec.mdV));
-}
-
-
-void LLMessageSystem::addQuatFast(const char *varname, const LLQuaternion& quat)
-{
- addDataFast(varname, quat.packToVector3().mV, MVT_LLQuaternion, sizeof(LLVector3));
-}
-
-void LLMessageSystem::addQuat(const char *varname, const LLQuaternion& quat)
-{
- addDataFast(gMessageStringTable.getString(varname), quat.packToVector3().mV, MVT_LLQuaternion, sizeof(LLVector3));
-}
-
-
-void LLMessageSystem::addUUIDFast(const char *varname, const LLUUID& uuid)
-{
- addDataFast(varname, uuid.mData, MVT_LLUUID, sizeof(uuid.mData));
-}
-
-void LLMessageSystem::addUUID(const char *varname, const LLUUID& uuid)
-{
- addDataFast(gMessageStringTable.getString(varname), uuid.mData, MVT_LLUUID, sizeof(uuid.mData));
-}
-
-void LLMessageSystem::getF32Fast(const char *block, const char *var, F32 &d, S32 blocknum)
-{
- getDataFast(block, var, &d, sizeof(F32), blocknum);
-
- if( !llfinite( d ) )
- {
- llwarns << "non-finite in getF32Fast " << block << " " << var << llendl;
- d = 0;
- }
-}
-
-void LLMessageSystem::getF32(const char *block, const char *var, F32 &d, S32 blocknum)
-{
- getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &d, sizeof(F32), blocknum);
-
- if( !llfinite( d ) )
- {
- llwarns << "non-finite in getF32 " << block << " " << var << llendl;
- d = 0;
- }
-}
-
-void LLMessageSystem::getF64Fast(const char *block, const char *var, F64 &d, S32 blocknum)
-{
- getDataFast(block, var, &d, sizeof(F64), blocknum);
-
- if( !llfinite( d ) )
- {
- llwarns << "non-finite in getF64Fast " << block << " " << var << llendl;
- d = 0;
- }
-}
-
-void LLMessageSystem::getF64(const char *block, const char *var, F64 &d, S32 blocknum)
-{
- getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &d, sizeof(F64), blocknum);
-
- if( !llfinite( d ) )
- {
- llwarns << "non-finite in getF64 " << block << " " << var << llendl;
- d = 0;
- }
-}
-
-
-void LLMessageSystem::getVector3Fast(const char *block, const char *var, LLVector3 &v, S32 blocknum )
-{
- getDataFast(block, var, v.mV, sizeof(v.mV), blocknum);
-
- if( !v.isFinite() )
- {
- llwarns << "non-finite in getVector3Fast " << block << " " << var << llendl;
- v.zeroVec();
- }
-}
-
-void LLMessageSystem::getVector3(const char *block, const char *var, LLVector3 &v, S32 blocknum )
-{
- getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), v.mV, sizeof(v.mV), blocknum);
-
- if( !v.isFinite() )
- {
- llwarns << "non-finite in getVector4 " << block << " " << var << llendl;
- v.zeroVec();
- }
-}
-
-void LLMessageSystem::getVector4Fast(const char *block, const char *var, LLVector4 &v, S32 blocknum )
-{
- getDataFast(block, var, v.mV, sizeof(v.mV), blocknum);
-
- if( !v.isFinite() )
- {
- llwarns << "non-finite in getVector4Fast " << block << " " << var << llendl;
- v.zeroVec();
- }
-}
-
-void LLMessageSystem::getVector4(const char *block, const char *var, LLVector4 &v, S32 blocknum )
-{
- getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), v.mV, sizeof(v.mV), blocknum);
-
- if( !v.isFinite() )
- {
- llwarns << "non-finite in getVector3 " << block << " " << var << llendl;
- v.zeroVec();
- }
-}
-
-void LLMessageSystem::getVector3dFast(const char *block, const char *var, LLVector3d &v, S32 blocknum )
-{
- getDataFast(block, var, v.mdV, sizeof(v.mdV), blocknum);
-
- if( !v.isFinite() )
- {
- llwarns << "non-finite in getVector3dFast " << block << " " << var << llendl;
- v.zeroVec();
- }
-
-}
-
-void LLMessageSystem::getVector3d(const char *block, const char *var, LLVector3d &v, S32 blocknum )
-{
- getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), v.mdV, sizeof(v.mdV), blocknum);
-
- if( !v.isFinite() )
- {
- llwarns << "non-finite in getVector3d " << block << " " << var << llendl;
- v.zeroVec();
- }
-}
-
-void LLMessageSystem::getQuatFast(const char *block, const char *var, LLQuaternion &q, S32 blocknum )
-{
- LLVector3 vec;
- getDataFast(block, var, vec.mV, sizeof(vec.mV), blocknum);
- if( vec.isFinite() )
- {
- q.unpackFromVector3( vec );
- }
- else
- {
- llwarns << "non-finite in getQuatFast " << block << " " << var << llendl;
- q.loadIdentity();
- }
-}
-
-void LLMessageSystem::getQuat(const char *block, const char *var, LLQuaternion &q, S32 blocknum )
-{
- LLVector3 vec;
- getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), vec.mV, sizeof(vec.mV), blocknum);
- if( vec.isFinite() )
- {
- q.unpackFromVector3( vec );
- }
- else
- {
- llwarns << "non-finite in getQuat " << block << " " << var << llendl;
- q.loadIdentity();
- }
-}
-
-void LLMessageSystem::getUUIDFast(const char *block, const char *var, LLUUID &u, S32 blocknum )
-{
- getDataFast(block, var, u.mData, sizeof(u.mData), blocknum);
-}
-
-void LLMessageSystem::getUUID(const char *block, const char *var, LLUUID &u, S32 blocknum )
-{
- getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), u.mData, sizeof(u.mData), blocknum);
-}
-
bool LLMessageSystem::generateDigestForNumberAndUUIDs(
char* digest,
const U32 number,
@@ -5790,6 +4114,121 @@ void LLMessageSystem::dumpPacketToLog()
}
//static
+BOOL LLMessageSystem::isTemplateConfirmed()
+{
+ return gMessageSystem->mTemplateConfirmed;
+}
+
+//static
+BOOL LLMessageSystem::doesTemplateMatch()
+{
+ if (!isTemplateConfirmed())
+ {
+ return FALSE;
+ }
+ return gMessageSystem->mTemplateMatches;
+}
+
+//static
+void LLMessageSystem::sendMessageTemplateChecksum(const LLHost &currentHost)
+{
+ gMessageSystem->mTemplateConfirmed = FALSE;
+ gMessageSystem->mTemplateMatches = FALSE;
+ gMessageSystem->newMessageFast(_PREHASH_TemplateChecksumRequest);
+ // Don't use ping-based retry
+ gMessageSystem->sendReliable(currentHost, 40, FALSE, 3, NULL, NULL);
+}
+
+//static
+void LLMessageSystem::processMessageTemplateChecksumReply(LLMessageSystem *msg,
+ void** user_data)
+{
+ U32 remote_template_checksum = 0;
+ msg->getU32Fast(_PREHASH_DataBlock, _PREHASH_Checksum, remote_template_checksum);
+ msg->mTemplateConfirmed = TRUE;
+ if ((remote_template_checksum) != msg->mMessageFileChecksum)
+ {
+ llwarns << "out of sync message template!" << llendl;
+
+ msg->mTemplateMatches = FALSE;
+ msg->newMessageFast(_PREHASH_CloseCircuit);
+ msg->sendMessage(msg->getSender());
+ return;
+ }
+
+ msg->mTemplateMatches = TRUE;
+ llinfos << "According to " << msg->getSender()
+ << " the message template is current!"
+ << llendl;
+}
+
+//static
+void LLMessageSystem::sendSecureMessageTemplateChecksum(const LLHost& host)
+{
+ // generate an token for use during template checksum requests to
+ // prevent DOS attacks from injected bad template checksum replies.
+ LLUUID *template_tokenp = new LLUUID;
+ template_tokenp->generate();
+ lldebugs << "random token: " << *template_tokenp << llendl;
+
+ // register the handler for the reply while saving off template_token
+ gMessageSystem->setHandlerFuncFast(_PREHASH_TemplateChecksumReply,
+ LLMessageSystem::processSecureTemplateChecksumReply,
+ (void**)template_tokenp);
+
+ // send checksum request
+ gMessageSystem->mTemplateConfirmed = FALSE;
+ gMessageSystem->newMessageFast(_PREHASH_SecuredTemplateChecksumRequest);
+ gMessageSystem->nextBlockFast(_PREHASH_TokenBlock);
+ gMessageSystem->addUUIDFast(_PREHASH_Token, *template_tokenp);
+ gMessageSystem->sendReliable(host);
+}
+
+//static
+void LLMessageSystem::processSecureTemplateChecksumReply(LLMessageSystem *msg,
+ void** user_data)
+{
+ // copy the token out into the stack and delete allocated memory
+ LLUUID template_token = *((LLUUID*)user_data);
+ delete user_data;
+
+ LLUUID received_token;
+ msg->getUUID("TokenBlock", "Token", received_token);
+
+ if(received_token != template_token)
+ {
+ llwarns << "Incorrect token in template checksum reply: "
+ << received_token << llendl;
+ //return do_normal_idle;
+ return;
+ }
+
+ U32 remote_template_checksum = 0;
+ U8 major_version = 0;
+ U8 minor_version = 0;
+ U8 patch_version = 0;
+ U8 server_version = 0;
+ U32 flags = 0x0;
+ msg->getU32("DataBlock", "Checksum", remote_template_checksum);
+ msg->getU8 ("DataBlock", "MajorVersion", major_version);
+ msg->getU8 ("DataBlock", "MinorVersion", minor_version);
+ msg->getU8 ("DataBlock", "PatchVersion", patch_version);
+ msg->getU8 ("DataBlock", "ServerVersion", server_version);
+ msg->getU32("DataBlock", "Flags", flags);
+
+ msg->mTemplateConfirmed = TRUE;
+ if (remote_template_checksum != gMessageSystem->mMessageFileChecksum)
+ {
+ llinfos << "Message template out of sync" << llendl;
+ msg->mTemplateMatches = FALSE;
+ }
+ else
+ {
+ msg->mTemplateMatches = TRUE;
+ }
+}
+
+//static
U64 LLMessageSystem::getMessageTimeUsecs(const BOOL update)
{
if (gMessageSystem)
@@ -5834,3 +4273,558 @@ std::string get_shared_secret()
return g_shared_secret;
}
+typedef std::map<const char*, LLMessageBuilder*> BuilderMap;
+
+static void setBuilder(BuilderMap& map, const char* name, LLMessageBuilder* builder)
+{
+ map[gMessageStringTable.getString(name)] = builder;
+}
+
+void LLMessageSystem::newMessageFast(const char *name)
+{
+ if(LLMessageConfig::isMessageBuiltTemplate(name))
+ {
+ mMessageBuilder = mTemplateMessageBuilder;
+ }
+ else
+ {
+ mMessageBuilder = mLLSDMessageBuilder;
+ }
+ mSendReliable = FALSE;
+ mMessageBuilder->newMessage(name);
+}
+
+void LLMessageSystem::newMessage(const char *name)
+{
+ newMessageFast(gMessageStringTable.getString(name));
+}
+
+void LLMessageSystem::addBinaryDataFast(const char *varname, const void *data, S32 size)
+{
+ mMessageBuilder->addBinaryData(varname, data, size);
+}
+
+void LLMessageSystem::addBinaryData(const char *varname, const void *data, S32 size)
+{
+ mMessageBuilder->addBinaryData(gMessageStringTable.getString(varname),data, size);
+}
+
+void LLMessageSystem::addS8Fast(const char *varname, S8 v)
+{
+ mMessageBuilder->addS8(varname, v);
+}
+
+void LLMessageSystem::addS8(const char *varname, S8 v)
+{
+ mMessageBuilder->addS8(gMessageStringTable.getString(varname), v);
+}
+
+void LLMessageSystem::addU8Fast(const char *varname, U8 v)
+{
+ mMessageBuilder->addU8(varname, v);
+}
+
+void LLMessageSystem::addU8(const char *varname, U8 v)
+{
+ mMessageBuilder->addU8(gMessageStringTable.getString(varname), v);
+}
+
+void LLMessageSystem::addS16Fast(const char *varname, S16 v)
+{
+ mMessageBuilder->addS16(varname, v);
+}
+
+void LLMessageSystem::addS16(const char *varname, S16 v)
+{
+ mMessageBuilder->addS16(gMessageStringTable.getString(varname), v);
+}
+
+void LLMessageSystem::addU16Fast(const char *varname, U16 v)
+{
+ mMessageBuilder->addU16(varname, v);
+}
+
+void LLMessageSystem::addU16(const char *varname, U16 v)
+{
+ mMessageBuilder->addU16(gMessageStringTable.getString(varname), v);
+}
+
+void LLMessageSystem::addF32Fast(const char *varname, F32 v)
+{
+ mMessageBuilder->addF32(varname, v);
+}
+
+void LLMessageSystem::addF32(const char *varname, F32 v)
+{
+ mMessageBuilder->addF32(gMessageStringTable.getString(varname), v);
+}
+
+void LLMessageSystem::addS32Fast(const char *varname, S32 v)
+{
+ mMessageBuilder->addS32(varname, v);
+}
+
+void LLMessageSystem::addS32(const char *varname, S32 v)
+{
+ mMessageBuilder->addS32(gMessageStringTable.getString(varname), v);
+}
+
+void LLMessageSystem::addU32Fast(const char *varname, U32 v)
+{
+ mMessageBuilder->addU32(varname, v);
+}
+
+void LLMessageSystem::addU32(const char *varname, U32 v)
+{
+ mMessageBuilder->addU32(gMessageStringTable.getString(varname), v);
+}
+
+void LLMessageSystem::addU64Fast(const char *varname, U64 v)
+{
+ mMessageBuilder->addU64(varname, v);
+}
+
+void LLMessageSystem::addU64(const char *varname, U64 v)
+{
+ mMessageBuilder->addU64(gMessageStringTable.getString(varname), v);
+}
+
+void LLMessageSystem::addF64Fast(const char *varname, F64 v)
+{
+ mMessageBuilder->addF64(varname, v);
+}
+
+void LLMessageSystem::addF64(const char *varname, F64 v)
+{
+ mMessageBuilder->addF64(gMessageStringTable.getString(varname), v);
+}
+
+void LLMessageSystem::addIPAddrFast(const char *varname, U32 v)
+{
+ mMessageBuilder->addIPAddr(varname, v);
+}
+
+void LLMessageSystem::addIPAddr(const char *varname, U32 v)
+{
+ mMessageBuilder->addIPAddr(gMessageStringTable.getString(varname), v);
+}
+
+void LLMessageSystem::addIPPortFast(const char *varname, U16 v)
+{
+ mMessageBuilder->addIPPort(varname, v);
+}
+
+void LLMessageSystem::addIPPort(const char *varname, U16 v)
+{
+ mMessageBuilder->addIPPort(gMessageStringTable.getString(varname), v);
+}
+
+void LLMessageSystem::addBOOLFast(const char* varname, BOOL v)
+{
+ mMessageBuilder->addBOOL(varname, v);
+}
+
+void LLMessageSystem::addBOOL(const char* varname, BOOL v)
+{
+ mMessageBuilder->addBOOL(gMessageStringTable.getString(varname), v);
+}
+
+void LLMessageSystem::addStringFast(const char* varname, const char* v)
+{
+ mMessageBuilder->addString(varname, v);
+}
+
+void LLMessageSystem::addString(const char* varname, const char* v)
+{
+ mMessageBuilder->addString(gMessageStringTable.getString(varname), v);
+}
+
+void LLMessageSystem::addStringFast(const char* varname, const std::string& v)
+{
+ mMessageBuilder->addString(varname, v);
+}
+
+void LLMessageSystem::addString(const char* varname, const std::string& v)
+{
+ mMessageBuilder->addString(gMessageStringTable.getString(varname), v);
+}
+
+void LLMessageSystem::addVector3Fast(const char *varname, const LLVector3& v)
+{
+ mMessageBuilder->addVector3(varname, v);
+}
+
+void LLMessageSystem::addVector3(const char *varname, const LLVector3& v)
+{
+ mMessageBuilder->addVector3(gMessageStringTable.getString(varname), v);
+}
+
+void LLMessageSystem::addVector4Fast(const char *varname, const LLVector4& v)
+{
+ mMessageBuilder->addVector4(varname, v);
+}
+
+void LLMessageSystem::addVector4(const char *varname, const LLVector4& v)
+{
+ mMessageBuilder->addVector4(gMessageStringTable.getString(varname), v);
+}
+
+void LLMessageSystem::addVector3dFast(const char *varname, const LLVector3d& v)
+{
+ mMessageBuilder->addVector3d(varname, v);
+}
+
+void LLMessageSystem::addVector3d(const char *varname, const LLVector3d& v)
+{
+ mMessageBuilder->addVector3d(gMessageStringTable.getString(varname), v);
+}
+
+void LLMessageSystem::addQuatFast(const char *varname, const LLQuaternion& v)
+{
+ mMessageBuilder->addQuat(varname, v);
+}
+
+void LLMessageSystem::addQuat(const char *varname, const LLQuaternion& v)
+{
+ mMessageBuilder->addQuat(gMessageStringTable.getString(varname), v);
+}
+
+
+void LLMessageSystem::addUUIDFast(const char *varname, const LLUUID& v)
+{
+ mMessageBuilder->addUUID(varname, v);
+}
+
+void LLMessageSystem::addUUID(const char *varname, const LLUUID& v)
+{
+ mMessageBuilder->addUUID(gMessageStringTable.getString(varname), v);
+}
+
+S32 LLMessageSystem::getCurrentSendTotal() const
+{
+ return mMessageBuilder->getMessageSize();
+}
+
+void LLMessageSystem::getS8Fast(const char *block, const char *var, S8 &u,
+ S32 blocknum)
+{
+ mMessageReader->getS8(block, var, u, blocknum);
+}
+
+void LLMessageSystem::getS8(const char *block, const char *var, S8 &u,
+ S32 blocknum)
+{
+ getS8Fast(gMessageStringTable.getString(block),
+ gMessageStringTable.getString(var), u, blocknum);
+}
+
+void LLMessageSystem::getU8Fast(const char *block, const char *var, U8 &u,
+ S32 blocknum)
+{
+ mMessageReader->getU8(block, var, u, blocknum);
+}
+
+void LLMessageSystem::getU8(const char *block, const char *var, U8 &u,
+ S32 blocknum)
+{
+ getU8Fast(gMessageStringTable.getString(block),
+ gMessageStringTable.getString(var), u, blocknum);
+}
+
+void LLMessageSystem::getBOOLFast(const char *block, const char *var, BOOL &b,
+ S32 blocknum)
+{
+ mMessageReader->getBOOL(block, var, b, blocknum);
+}
+
+void LLMessageSystem::getBOOL(const char *block, const char *var, BOOL &b,
+ S32 blocknum)
+{
+ getBOOLFast(gMessageStringTable.getString(block),
+ gMessageStringTable.getString(var), b, blocknum);
+}
+
+void LLMessageSystem::getS16Fast(const char *block, const char *var, S16 &d,
+ S32 blocknum)
+{
+ mMessageReader->getS16(block, var, d, blocknum);
+}
+
+void LLMessageSystem::getS16(const char *block, const char *var, S16 &d,
+ S32 blocknum)
+{
+ getS16Fast(gMessageStringTable.getString(block),
+ gMessageStringTable.getString(var), d, blocknum);
+}
+
+void LLMessageSystem::getU16Fast(const char *block, const char *var, U16 &d,
+ S32 blocknum)
+{
+ mMessageReader->getU16(block, var, d, blocknum);
+}
+
+void LLMessageSystem::getU16(const char *block, const char *var, U16 &d,
+ S32 blocknum)
+{
+ getU16Fast(gMessageStringTable.getString(block),
+ gMessageStringTable.getString(var), d, blocknum);
+}
+
+void LLMessageSystem::getS32Fast(const char *block, const char *var, S32 &d,
+ S32 blocknum)
+{
+ mMessageReader->getS32(block, var, d, blocknum);
+}
+
+void LLMessageSystem::getS32(const char *block, const char *var, S32 &d,
+ S32 blocknum)
+{
+ getS32Fast(gMessageStringTable.getString(block),
+ gMessageStringTable.getString(var), d, blocknum);
+}
+
+void LLMessageSystem::getU32Fast(const char *block, const char *var, U32 &d,
+ S32 blocknum)
+{
+ mMessageReader->getU32(block, var, d, blocknum);
+}
+
+void LLMessageSystem::getU32(const char *block, const char *var, U32 &d,
+ S32 blocknum)
+{
+ getU32Fast(gMessageStringTable.getString(block),
+ gMessageStringTable.getString(var), d, blocknum);
+}
+
+void LLMessageSystem::getU64Fast(const char *block, const char *var, U64 &d,
+ S32 blocknum)
+{
+ mMessageReader->getU64(block, var, d, blocknum);
+}
+
+void LLMessageSystem::getU64(const char *block, const char *var, U64 &d,
+ S32 blocknum)
+{
+
+ getU64Fast(gMessageStringTable.getString(block),
+ gMessageStringTable.getString(var), d, blocknum);
+}
+
+void LLMessageSystem::getBinaryDataFast(const char *blockname,
+ const char *varname,
+ void *datap, S32 size,
+ S32 blocknum, S32 max_size)
+{
+ mMessageReader->getBinaryData(blockname, varname, datap, size, blocknum,
+ max_size);
+}
+
+void LLMessageSystem::getBinaryData(const char *blockname,
+ const char *varname,
+ void *datap, S32 size,
+ S32 blocknum, S32 max_size)
+{
+ getBinaryDataFast(gMessageStringTable.getString(blockname),
+ gMessageStringTable.getString(varname),
+ datap, size, blocknum, max_size);
+}
+
+void LLMessageSystem::getF32Fast(const char *block, const char *var, F32 &d,
+ S32 blocknum)
+{
+ mMessageReader->getF32(block, var, d, blocknum);
+}
+
+void LLMessageSystem::getF32(const char *block, const char *var, F32 &d,
+ S32 blocknum)
+{
+ getF32Fast(gMessageStringTable.getString(block),
+ gMessageStringTable.getString(var), d, blocknum);
+}
+
+void LLMessageSystem::getF64Fast(const char *block, const char *var, F64 &d,
+ S32 blocknum)
+{
+ mMessageReader->getF64(block, var, d, blocknum);
+}
+
+void LLMessageSystem::getF64(const char *block, const char *var, F64 &d,
+ S32 blocknum)
+{
+ getF64Fast(gMessageStringTable.getString(block),
+ gMessageStringTable.getString(var), d, blocknum);
+}
+
+
+void LLMessageSystem::getVector3Fast(const char *block, const char *var,
+ LLVector3 &v, S32 blocknum )
+{
+ mMessageReader->getVector3(block, var, v, blocknum);
+}
+
+void LLMessageSystem::getVector3(const char *block, const char *var,
+ LLVector3 &v, S32 blocknum )
+{
+ getVector3Fast(gMessageStringTable.getString(block),
+ gMessageStringTable.getString(var), v, blocknum);
+}
+
+void LLMessageSystem::getVector4Fast(const char *block, const char *var,
+ LLVector4 &v, S32 blocknum )
+{
+ mMessageReader->getVector4(block, var, v, blocknum);
+}
+
+void LLMessageSystem::getVector4(const char *block, const char *var,
+ LLVector4 &v, S32 blocknum )
+{
+ getVector4Fast(gMessageStringTable.getString(block),
+ gMessageStringTable.getString(var), v, blocknum);
+}
+
+void LLMessageSystem::getVector3dFast(const char *block, const char *var,
+ LLVector3d &v, S32 blocknum )
+{
+ mMessageReader->getVector3d(block, var, v, blocknum);
+}
+
+void LLMessageSystem::getVector3d(const char *block, const char *var,
+ LLVector3d &v, S32 blocknum )
+{
+ getVector3dFast(gMessageStringTable.getString(block),
+ gMessageStringTable.getString(var), v, blocknum);
+}
+
+void LLMessageSystem::getQuatFast(const char *block, const char *var,
+ LLQuaternion &q, S32 blocknum )
+{
+ mMessageReader->getQuat(block, var, q, blocknum);
+}
+
+void LLMessageSystem::getQuat(const char *block, const char *var,
+ LLQuaternion &q, S32 blocknum)
+{
+ getQuatFast(gMessageStringTable.getString(block),
+ gMessageStringTable.getString(var), q, blocknum);
+}
+
+void LLMessageSystem::getUUIDFast(const char *block, const char *var,
+ LLUUID &u, S32 blocknum )
+{
+ mMessageReader->getUUID(block, var, u, blocknum);
+}
+
+void LLMessageSystem::getUUID(const char *block, const char *var, LLUUID &u,
+ S32 blocknum )
+{
+ getUUIDFast(gMessageStringTable.getString(block),
+ gMessageStringTable.getString(var), u, blocknum);
+}
+
+void LLMessageSystem::getIPAddrFast(const char *block, const char *var,
+ U32 &u, S32 blocknum)
+{
+ mMessageReader->getIPAddr(block, var, u, blocknum);
+}
+
+void LLMessageSystem::getIPAddr(const char *block, const char *var, U32 &u,
+ S32 blocknum)
+{
+ getIPAddrFast(gMessageStringTable.getString(block),
+ gMessageStringTable.getString(var), u, blocknum);
+}
+
+void LLMessageSystem::getIPPortFast(const char *block, const char *var,
+ U16 &u, S32 blocknum)
+{
+ mMessageReader->getIPPort(block, var, u, blocknum);
+}
+
+void LLMessageSystem::getIPPort(const char *block, const char *var, U16 &u,
+ S32 blocknum)
+{
+ getIPPortFast(gMessageStringTable.getString(block),
+ gMessageStringTable.getString(var), u,
+ blocknum);
+}
+
+
+void LLMessageSystem::getStringFast(const char *block, const char *var,
+ S32 buffer_size, char *s, S32 blocknum)
+{
+ mMessageReader->getString(block, var, buffer_size, s, blocknum);
+}
+
+void LLMessageSystem::getString(const char *block, const char *var,
+ S32 buffer_size, char *s, S32 blocknum )
+{
+ getStringFast(gMessageStringTable.getString(block),
+ gMessageStringTable.getString(var), buffer_size, s,
+ blocknum);
+}
+
+S32 LLMessageSystem::getNumberOfBlocksFast(const char *blockname)
+{
+ return mMessageReader->getNumberOfBlocks(blockname);
+}
+
+S32 LLMessageSystem::getNumberOfBlocks(const char *blockname)
+{
+ return getNumberOfBlocksFast(gMessageStringTable.getString(blockname));
+}
+
+S32 LLMessageSystem::getSizeFast(const char *blockname, const char *varname)
+{
+ return mMessageReader->getSize(blockname, varname);
+}
+
+S32 LLMessageSystem::getSize(const char *blockname, const char *varname)
+{
+ return getSizeFast(gMessageStringTable.getString(blockname),
+ gMessageStringTable.getString(varname));
+}
+
+// size in bytes of variable length data
+S32 LLMessageSystem::getSizeFast(const char *blockname, S32 blocknum,
+ const char *varname)
+{
+ return mMessageReader->getSize(blockname, blocknum, varname);
+}
+
+S32 LLMessageSystem::getSize(const char *blockname, S32 blocknum,
+ const char *varname)
+{
+ return getSizeFast(gMessageStringTable.getString(blockname), blocknum,
+ gMessageStringTable.getString(varname));
+}
+
+S32 LLMessageSystem::getReceiveSize() const
+{
+ return mMessageReader->getMessageSize();
+}
+
+//static
+void LLMessageSystem::setTimeDecodes( BOOL b )
+{
+ LLMessageReader::setTimeDecodes(b);
+}
+
+//static
+void LLMessageSystem::setTimeDecodesSpamThreshold( F32 seconds )
+{
+ LLMessageReader::setTimeDecodesSpamThreshold(seconds);
+}
+
+// HACK! babbage: return true if message rxed via either UDP or HTTP
+// TODO: babbage: move gServicePump in to LLMessageSystem?
+bool LLMessageSystem::checkAllMessages(S64 frame_count, LLPumpIO* http_pump)
+{
+ if(checkMessages(frame_count))
+ {
+ return true;
+ }
+ U32 packetsIn = mPacketsIn;
+ http_pump->pump();
+ http_pump->callback();
+ return (mPacketsIn - packetsIn) > 0;
+}
diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h
index 3ffafcc1b8..a4a8022631 100644
--- a/indra/llmessage/message.h
+++ b/indra/llmessage/message.h
@@ -1,5 +1,5 @@
/**
- * @file message.h
+ * @FILE message.h
* @brief LLMessageSystem class header file
*
* Copyright (c) 2001-$CurrentYear$, Linden Research, Inc.
@@ -30,9 +30,11 @@
#include "lltimer.h"
#include "llpacketring.h"
#include "llhost.h"
+#include "llhttpnode.h"
#include "llpacketack.h"
#include "message_prehash.h"
#include "llstl.h"
+#include "llmsgvariabletype.h"
const U32 MESSAGE_MAX_STRINGS_LENGTH = 64;
const U32 MESSAGE_NUMBER_OF_HASH_BUCKETS = 8192;
@@ -131,39 +133,10 @@ class LLQuaternion;
class LLSD;
class LLUUID;
class LLMessageSystem;
+class LLPumpIO;
// message data pieces are used to collect the data called for by the message template
-// iterator typedefs precede each class as needed
-typedef enum e_message_variable_type
-{
- MVT_NULL,
- MVT_FIXED,
- MVT_VARIABLE,
- MVT_U8,
- MVT_U16,
- MVT_U32,
- MVT_U64,
- MVT_S8,
- MVT_S16,
- MVT_S32,
- MVT_S64,
- MVT_F32,
- MVT_F64,
- MVT_LLVector3,
- MVT_LLVector3d,
- MVT_LLVector4,
- MVT_LLQuaternion,
- MVT_LLUUID,
- MVT_BOOL,
- MVT_IP_ADDR,
- MVT_IP_PORT,
- MVT_U16Vec3,
- MVT_U16Quat,
- MVT_S16Array,
- MVT_EOL
-} EMsgVariableType;
-
// message system exceptional condition handlers.
enum EMessageException
{
@@ -180,19 +153,29 @@ class LLMsgBlkData;
class LLMessageTemplate;
class LLMessagePollInfo;
+class LLMessageBuilder;
+class LLTemplateMessageBuilder;
+class LLSDMessageBuilder;
+class LLMessageReader;
+class LLTemplateMessageReader;
+class LLSDMessageReader;
-class LLMessageSystem
+class LLUseCircuitCodeResponder
{
LOG_CLASS(LLMessageSystem);
public:
+ virtual ~LLUseCircuitCodeResponder();
+ virtual void complete(const LLHost& host, const LLUUID& agent) const = 0;
+};
+
+class LLMessageSystem
+{
+ private:
U8 mSendBuffer[MAX_BUFFER_SIZE];
- // Encoded send buffer needs to be slightly larger since the zero
- // coding can potentially increase the size of the send data.
- U8 mEncodedSendBuffer[2 * MAX_BUFFER_SIZE];
S32 mSendSize;
- S32 mCurrentSendTotal;
+ public:
LLPacketRing mPacketRing;
LLReliablePacketParams mReliablePacketParams;
@@ -271,12 +254,7 @@ public:
LLMessageSystem(const char *filename, U32 port, S32 version_major,
S32 version_minor, S32 version_patch);
-public:
- // Subclass use.
- LLMessageSystem();
-
-public:
- virtual ~LLMessageSystem();
+ ~LLMessageSystem();
BOOL isOK() const { return !mbError; }
S32 getErrorCode() const { return mErrorCode; }
@@ -294,9 +272,6 @@ public:
setHandlerFuncFast(gMessageStringTable.getString(name), handler_func, user_data);
}
- bool callHandler(const char *name, bool trustedSource,
- LLMessageSystem* msg);
-
// Set a callback function for a message system exception.
void setExceptionFunc(EMessageException exception, msg_exception_callback func, void* data = NULL);
// Call the specified exception func, and return TRUE if a
@@ -308,6 +283,14 @@ public:
// measured in seconds. JC
typedef void (*msg_timing_callback)(const char* hashed_name, F32 time, void* data);
void setTimingFunc(msg_timing_callback func, void* data = NULL);
+ msg_timing_callback getTimingCallback()
+ {
+ return mTimingCallback;
+ }
+ void* getTimingCallbackData()
+ {
+ return mTimingCallbackData;
+ }
// This method returns true if the code is in the circuit codes map.
BOOL isCircuitCodeKnown(U32 code) const;
@@ -347,42 +330,21 @@ public:
void setMySessionID(const LLUUID& session_id) { mSessionID = session_id; }
const LLUUID& getMySessionID() { return mSessionID; }
- virtual void newMessageFast(const char *name);
- void newMessage(const char *name)
- {
- newMessageFast(gMessageStringTable.getString(name));
- }
+ void newMessageFast(const char *name);
+ void newMessage(const char *name);
void copyMessageRtoS();
void clearMessage();
- virtual void nextBlockFast(const char *blockname);
+ void nextBlockFast(const char *blockname);
void nextBlock(const char *blockname)
{
nextBlockFast(gMessageStringTable.getString(blockname));
}
-private:
- void addDataFast(const char *varname, const void *data, EMsgVariableType type, S32 size); // Use only for types not in system already
- void addData(const char *varname, const void *data, EMsgVariableType type, S32 size)
- {
- addDataFast(gMessageStringTable.getString(varname), data, type, size);
- }
-
- void addDataFast(const char *varname, const void *data, EMsgVariableType type); // DEPRECATED - not typed, doesn't check storage space
- void addData(const char *varname, const void *data, EMsgVariableType type)
- {
- addDataFast(gMessageStringTable.getString(varname), data, type);
- }
public:
- void addBinaryDataFast(const char *varname, const void *data, S32 size)
- {
- addDataFast(varname, data, MVT_FIXED, size);
- }
- void addBinaryData(const char *varname, const void *data, S32 size)
- {
- addDataFast(gMessageStringTable.getString(varname), data, MVT_FIXED, size);
- }
+ void addBinaryDataFast(const char *varname, const void *data, S32 size);
+ void addBinaryData(const char *varname, const void *data, S32 size);
void addBOOLFast( const char* varname, BOOL b); // typed, checks storage space
void addBOOL( const char* varname, BOOL b); // typed, checks storage space
@@ -398,7 +360,7 @@ public:
void addF32( const char *varname, F32 f); // typed, checks storage space
void addS32Fast( const char *varname, S32 s); // typed, checks storage space
void addS32( const char *varname, S32 s); // typed, checks storage space
- virtual void addU32Fast( const char *varname, U32 u); // typed, checks storage space
+ void addU32Fast( const char *varname, U32 u); // typed, checks storage space
void addU32( const char *varname, U32 u); // typed, checks storage space
void addU64Fast( const char *varname, U64 lu); // typed, checks storage space
void addU64( const char *varname, U64 lu); // typed, checks storage space
@@ -412,7 +374,7 @@ public:
void addVector3d( const char *varname, const LLVector3d& vec); // typed, checks storage space
void addQuatFast( const char *varname, const LLQuaternion& quat); // typed, checks storage space
void addQuat( const char *varname, const LLQuaternion& quat); // typed, checks storage space
- virtual void addUUIDFast( const char *varname, const LLUUID& uuid); // typed, checks storage space
+ void addUUIDFast( const char *varname, const LLUUID& uuid); // typed, checks storage space
void addUUID( const char *varname, const LLUUID& uuid); // typed, checks storage space
void addIPAddrFast( const char *varname, const U32 ip); // typed, checks storage space
void addIPAddr( const char *varname, const U32 ip); // typed, checks storage space
@@ -423,8 +385,8 @@ public:
void addStringFast( const char* varname, const std::string& s); // typed, checks storage space
void addString( const char* varname, const std::string& s); // typed, checks storage space
+ S32 getCurrentSendTotal() const;
TPACKETID getCurrentRecvPacketID() { return mCurrentRecvPacketID; }
- S32 getCurrentSendTotal() const { return mCurrentSendTotal; }
// This method checks for current send total and returns true if
// you need to go to the next block type or need to start a new
@@ -433,16 +395,16 @@ public:
BOOL isSendFull(const char* blockname = NULL);
BOOL isSendFullFast(const char* blockname = NULL);
- BOOL removeLastBlock();
+ BOOL removeLastBlock();
- void buildMessage();
+ //void buildMessage();
S32 zeroCode(U8 **data, S32 *data_size);
S32 zeroCodeExpand(U8 **data, S32 *data_size);
S32 zeroCodeAdjustCurrentSendTotal();
// Uses ping-based retry
- virtual S32 sendReliable(const LLHost &host);
+ S32 sendReliable(const LLHost &host);
// Uses ping-based retry
S32 sendReliable(const U32 circuit) { return sendReliable(findHost(circuit)); }
@@ -471,28 +433,10 @@ public:
S32 sendMessage(const LLHost &host);
S32 sendMessage(const U32 circuit);
- BOOL decodeData(const U8 *buffer, const LLHost &host);
-
- // TODO: Consolide these functions
- // TODO: Make these private, force use of typed functions.
- // If size is not 0, an error is generated if size doesn't exactly match the size of the data.
- // At all times, the number if bytes written to *datap is <= max_size.
-private:
- void getDataFast(const char *blockname, const char *varname, void *datap, S32 size = 0, S32 blocknum = 0, S32 max_size = S32_MAX);
- void getData(const char *blockname, const char *varname, void *datap, S32 size = 0, S32 blocknum = 0, S32 max_size = S32_MAX)
- {
- getDataFast(gMessageStringTable.getString(blockname), gMessageStringTable.getString(varname), datap, size, blocknum, max_size);
- }
-public:
- void getBinaryDataFast(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX)
- {
- getDataFast(blockname, varname, datap, size, blocknum, max_size);
- }
- void getBinaryData(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX)
- {
- getDataFast(gMessageStringTable.getString(blockname), gMessageStringTable.getString(varname), datap, size, blocknum, max_size);
- }
+ // BOOL decodeData(const U8 *buffer, const LLHost &host);
+ void getBinaryDataFast(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX);
+ void getBinaryData(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX);
void getBOOLFast( const char *block, const char *var, BOOL &data, S32 blocknum = 0);
void getBOOL( const char *block, const char *var, BOOL &data, S32 blocknum = 0);
void getS8Fast( const char *block, const char *var, S8 &data, S32 blocknum = 0);
@@ -507,9 +451,9 @@ public:
void getS32( const char *block, const char *var, S32 &data, S32 blocknum = 0);
void getF32Fast( const char *block, const char *var, F32 &data, S32 blocknum = 0);
void getF32( const char *block, const char *var, F32 &data, S32 blocknum = 0);
- virtual void getU32Fast( const char *block, const char *var, U32 &data, S32 blocknum = 0);
+ void getU32Fast( const char *block, const char *var, U32 &data, S32 blocknum = 0);
void getU32( const char *block, const char *var, U32 &data, S32 blocknum = 0);
- virtual void getU64Fast( const char *block, const char *var, U64 &data, S32 blocknum = 0);
+ void getU64Fast( const char *block, const char *var, U64 &data, S32 blocknum = 0);
void getU64( const char *block, const char *var, U64 &data, S32 blocknum = 0);
void getF64Fast( const char *block, const char *var, F64 &data, S32 blocknum = 0);
void getF64( const char *block, const char *var, F64 &data, S32 blocknum = 0);
@@ -521,13 +465,13 @@ public:
void getVector3d(const char *block, const char *var, LLVector3d &vec, S32 blocknum = 0);
void getQuatFast( const char *block, const char *var, LLQuaternion &q, S32 blocknum = 0);
void getQuat( const char *block, const char *var, LLQuaternion &q, S32 blocknum = 0);
- virtual void getUUIDFast( const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0);
+ void getUUIDFast( const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0);
void getUUID( const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0);
- virtual void getIPAddrFast( const char *block, const char *var, U32 &ip, S32 blocknum = 0);
+ void getIPAddrFast( const char *block, const char *var, U32 &ip, S32 blocknum = 0);
void getIPAddr( const char *block, const char *var, U32 &ip, S32 blocknum = 0);
- virtual void getIPPortFast( const char *block, const char *var, U16 &port, S32 blocknum = 0);
+ void getIPPortFast( const char *block, const char *var, U16 &port, S32 blocknum = 0);
void getIPPort( const char *block, const char *var, U16 &port, S32 blocknum = 0);
- virtual void getStringFast( const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0);
+ void getStringFast( const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0);
void getString( const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0);
@@ -549,7 +493,7 @@ public:
void showCircuitInfo();
LLString getCircuitInfoString();
- virtual U32 getOurCircuitCode();
+ U32 getOurCircuitCode();
void enableCircuit(const LLHost &host, BOOL trusted);
void disableCircuit(const LLHost &host);
@@ -595,20 +539,12 @@ public:
void sanityCheck();
S32 getNumberOfBlocksFast(const char *blockname);
- S32 getNumberOfBlocks(const char *blockname)
- {
- return getNumberOfBlocksFast(gMessageStringTable.getString(blockname));
- }
+ S32 getNumberOfBlocks(const char *blockname);
S32 getSizeFast(const char *blockname, const char *varname);
- S32 getSize(const char *blockname, const char *varname)
- {
- return getSizeFast(gMessageStringTable.getString(blockname), gMessageStringTable.getString(varname));
- }
- S32 getSizeFast(const char *blockname, S32 blocknum, const char *varname); // size in bytes of variable length data
- S32 getSize(const char *blockname, S32 blocknum, const char *varname)
- {
- return getSizeFast(gMessageStringTable.getString(blockname), blocknum, gMessageStringTable.getString(varname));
- }
+ S32 getSize(const char *blockname, const char *varname);
+ S32 getSizeFast(const char *blockname, S32 blocknum,
+ const char *varname); // size in bytes of data
+ S32 getSize(const char *blockname, S32 blocknum, const char *varname);
void resetReceiveCounts(); // resets receive counts for all message types to 0
void dumpReceiveCounts(); // dumps receive count for each message type to llinfos
@@ -623,14 +559,14 @@ public:
void stopLogging(); // flush and close file
void summarizeLogs(std::ostream& str); // log statistics
- S32 getReceiveSize() const { return mReceiveSize; }
- S32 getReceiveCompressedSize() const { return mIncomingCompressedSize; }
+ S32 getReceiveSize() const;
+ S32 getReceiveCompressedSize() const { return mIncomingCompressedSize; }
S32 getReceiveBytes() const;
S32 getUnackedListSize() const { return mUnackedListSize; }
- const char* getCurrentSMessageName() const { return mCurrentSMessageName; }
- const char* getCurrentSBlockName() const { return mCurrentSBlockName; }
+ //const char* getCurrentSMessageName() const { return mCurrentSMessageName; }
+ //const char* getCurrentSBlockName() const { return mCurrentSBlockName; }
// friends
friend std::ostream& operator<<(std::ostream& s, LLMessageSystem &msg);
@@ -639,25 +575,41 @@ public:
void setMaxMessageCounts(const S32 num); // Max number of messages before dumping (neg to disable)
// statics
-public:
+ static BOOL isTemplateConfirmed();
+ static BOOL doesTemplateMatch();
+ static void sendMessageTemplateChecksum(const LLHost&);
+ static void processMessageTemplateChecksumReply(LLMessageSystem *msg,
+ void** user_data);
+ static void sendSecureMessageTemplateChecksum(const LLHost&);
+ static void processSecureTemplateChecksumReply(LLMessageSystem *msg,
+ void** user_data);
static U64 getMessageTimeUsecs(const BOOL update = FALSE); // Get the current message system time in microseconds
static F64 getMessageTimeSeconds(const BOOL update = FALSE); // Get the current message system time in seconds
- static void setTimeDecodes( BOOL b )
- { LLMessageSystem::mTimeDecodes = b; }
-
- static void setTimeDecodesSpamThreshold( F32 seconds )
- { LLMessageSystem::mTimeDecodesSpamThreshold = seconds; }
+ static void setTimeDecodes(BOOL b);
+ static void setTimeDecodesSpamThreshold(F32 seconds);
// message handlers internal to the message systesm
//static void processAssignCircuitCode(LLMessageSystem* msg, void**);
static void processAddCircuitCode(LLMessageSystem* msg, void**);
static void processUseCircuitCode(LLMessageSystem* msg, void**);
+ // dispatch llsd message to http node tree
+ static void dispatch(const std::string& msg_name,
+ const LLSD& message);
+ static void dispatch(const std::string& msg_name,
+ const LLSD& message,
+ LLHTTPNode::ResponsePtr responsep);
+
void setMessageBans(const LLSD& trusted, const LLSD& untrusted);
+
+ // Check UDP messages and pump http_pump to receive HTTP messages.
+ bool checkAllMessages(S64 frame_count, LLPumpIO* http_pump);
private:
// data used in those internal handlers
+ BOOL mTemplateConfirmed;
+ BOOL mTemplateMatches;
// The mCircuitCodes is a map from circuit codes to session
// ids. This allows us to verify sessions on connect.
@@ -668,7 +620,6 @@ private:
// that no one gives them a bad circuit code.
LLUUID mSessionID;
-private:
void addTemplate(LLMessageTemplate *templatep);
void clearReceiveState();
BOOL decodeTemplate( const U8* buffer, S32 buffer_size, LLMessageTemplate** msg_template );
@@ -678,7 +629,6 @@ private:
void logValidMsg(LLCircuitData *cdp, const LLHost& sender, BOOL recv_reliable, BOOL recv_resent, BOOL recv_acks );
void logRanOffEndOfPacket( const LLHost& sender );
-private:
class LLMessageCountInfo
{
public:
@@ -694,26 +644,10 @@ private:
S32 mTrueReceiveSize;
// Must be valid during decode
- S32 mReceiveSize;
- TPACKETID mCurrentRecvPacketID; // packet ID of current receive packet (for reporting)
- LLMessageTemplate *mCurrentRMessageTemplate;
- LLMsgData *mCurrentRMessageData;
- S32 mIncomingCompressedSize; // original size of compressed msg (0 if uncomp.)
- LLHost mLastSender;
-
- // send message storage
- LLMsgData *mCurrentSMessageData;
- LLMessageTemplate *mCurrentSMessageTemplate;
- LLMsgBlkData *mCurrentSDataBlock;
- char *mCurrentSMessageName;
- char *mCurrentSBlockName;
-
+
BOOL mbError;
S32 mErrorCode;
- BOOL mbSBuilt; // is send message built?
- BOOL mbSClear; // is the send message clear?
-
F64 mResendDumpTime; // The last time we dumped resends
LLMessageCountInfo mMessageCountList[MAX_MESSAGE_COUNT_NUM];
@@ -740,6 +674,22 @@ private:
void* mTimingCallbackData;
void init(); // ctor shared initialisation.
+
+ LLHost mLastSender;
+ S32 mIncomingCompressedSize; // original size of compressed msg (0 if uncomp.)
+ TPACKETID mCurrentRecvPacketID; // packet ID of current receive packet (for reporting)
+
+ LLMessageBuilder* mMessageBuilder;
+ LLTemplateMessageBuilder* mTemplateMessageBuilder;
+ LLSDMessageBuilder* mLLSDMessageBuilder;
+ LLMessageReader* mMessageReader;
+ LLTemplateMessageReader* mTemplateMessageReader;
+ LLSDMessageReader* mLLSDMessageReader;
+
+ friend class LLMessageHandlerBridge;
+
+ bool callHandler(const char *name, bool trustedSource,
+ LLMessageSystem* msg);
};
@@ -756,7 +706,8 @@ BOOL start_messaging_system(
S32 version_minor,
S32 version_patch,
BOOL b_dump_prehash_file,
- const std::string& secret);
+ const std::string& secret,
+ const LLUseCircuitCodeResponder* responder = NULL);
void end_messaging_system();
@@ -932,12 +883,9 @@ inline void *ntohmemcpy(void *s, const void *ct, EMsgVariableType type, size_t n
}
-inline const LLHost& LLMessageSystem::getSender() const
-{
- return mLastSender;
-}
+inline const LLHost& LLMessageSystem::getSender() const {return mLastSender;}
-inline U32 LLMessageSystem::getSenderIP() const
+inline U32 LLMessageSystem::getSenderIP() const
{
return mLastSender.getAddress();
}
@@ -947,291 +895,9 @@ inline U32 LLMessageSystem::getSenderPort() const
return mLastSender.getPort();
}
-inline void LLMessageSystem::addS8Fast(const char *varname, S8 s)
-{
- addDataFast(varname, &s, MVT_S8, sizeof(s));
-}
-
-inline void LLMessageSystem::addS8(const char *varname, S8 s)
-{
- addDataFast(gMessageStringTable.getString(varname), &s, MVT_S8, sizeof(s));
-}
-
-inline void LLMessageSystem::addU8Fast(const char *varname, U8 u)
-{
- addDataFast(varname, &u, MVT_U8, sizeof(u));
-}
-
-inline void LLMessageSystem::addU8(const char *varname, U8 u)
-{
- addDataFast(gMessageStringTable.getString(varname), &u, MVT_U8, sizeof(u));
-}
-
-inline void LLMessageSystem::addS16Fast(const char *varname, S16 i)
-{
- addDataFast(varname, &i, MVT_S16, sizeof(i));
-}
-
-inline void LLMessageSystem::addS16(const char *varname, S16 i)
-{
- addDataFast(gMessageStringTable.getString(varname), &i, MVT_S16, sizeof(i));
-}
-
-inline void LLMessageSystem::addU16Fast(const char *varname, U16 i)
-{
- addDataFast(varname, &i, MVT_U16, sizeof(i));
-}
-
-inline void LLMessageSystem::addU16(const char *varname, U16 i)
-{
- addDataFast(gMessageStringTable.getString(varname), &i, MVT_U16, sizeof(i));
-}
-
-inline void LLMessageSystem::addF32Fast(const char *varname, F32 f)
-{
- addDataFast(varname, &f, MVT_F32, sizeof(f));
-}
-
-inline void LLMessageSystem::addF32(const char *varname, F32 f)
-{
- addDataFast(gMessageStringTable.getString(varname), &f, MVT_F32, sizeof(f));
-}
-
-inline void LLMessageSystem::addS32Fast(const char *varname, S32 s)
-{
- addDataFast(varname, &s, MVT_S32, sizeof(s));
-}
-
-inline void LLMessageSystem::addS32(const char *varname, S32 s)
-{
- addDataFast(gMessageStringTable.getString(varname), &s, MVT_S32, sizeof(s));
-}
-
-inline void LLMessageSystem::addU32Fast(const char *varname, U32 u)
-{
- addDataFast(varname, &u, MVT_U32, sizeof(u));
-}
-
-inline void LLMessageSystem::addU32(const char *varname, U32 u)
-{
- addDataFast(gMessageStringTable.getString(varname), &u, MVT_U32, sizeof(u));
-}
-
-inline void LLMessageSystem::addU64Fast(const char *varname, U64 lu)
-{
- addDataFast(varname, &lu, MVT_U64, sizeof(lu));
-}
-
-inline void LLMessageSystem::addU64(const char *varname, U64 lu)
-{
- addDataFast(gMessageStringTable.getString(varname), &lu, MVT_U64, sizeof(lu));
-}
-
-inline void LLMessageSystem::addF64Fast(const char *varname, F64 d)
-{
- addDataFast(varname, &d, MVT_F64, sizeof(d));
-}
-
-inline void LLMessageSystem::addF64(const char *varname, F64 d)
-{
- addDataFast(gMessageStringTable.getString(varname), &d, MVT_F64, sizeof(d));
-}
-
-inline void LLMessageSystem::addIPAddrFast(const char *varname, U32 u)
-{
- addDataFast(varname, &u, MVT_IP_ADDR, sizeof(u));
-}
-
-inline void LLMessageSystem::addIPAddr(const char *varname, U32 u)
-{
- addDataFast(gMessageStringTable.getString(varname), &u, MVT_IP_ADDR, sizeof(u));
-}
-
-inline void LLMessageSystem::addIPPortFast(const char *varname, U16 u)
-{
- u = htons(u);
- addDataFast(varname, &u, MVT_IP_PORT, sizeof(u));
-}
-
-inline void LLMessageSystem::addIPPort(const char *varname, U16 u)
-{
- u = htons(u);
- addDataFast(gMessageStringTable.getString(varname), &u, MVT_IP_PORT, sizeof(u));
-}
-
-inline void LLMessageSystem::addBOOLFast(const char* varname, BOOL b)
-{
- // Can't just cast a BOOL (actually a U32) to a U8.
- // In some cases the low order bits will be zero.
- U8 temp = (b != 0);
- addDataFast(varname, &temp, MVT_BOOL, sizeof(temp));
-}
-
-inline void LLMessageSystem::addBOOL(const char* varname, BOOL b)
-{
- // Can't just cast a BOOL (actually a U32) to a U8.
- // In some cases the low order bits will be zero.
- U8 temp = (b != 0);
- addDataFast(gMessageStringTable.getString(varname), &temp, MVT_BOOL, sizeof(temp));
-}
-
-inline void LLMessageSystem::addStringFast(const char* varname, const char* s)
-{
- if (s)
- addDataFast( varname, (void *)s, MVT_VARIABLE, (S32)strlen(s) + 1); /* Flawfinder: ignore */
- else
- addDataFast( varname, NULL, MVT_VARIABLE, 0);
-}
-
-inline void LLMessageSystem::addString(const char* varname, const char* s)
-{
- if (s)
- addDataFast( gMessageStringTable.getString(varname), (void *)s, MVT_VARIABLE, (S32)strlen(s) + 1); /* Flawfinder: ignore */
- else
- addDataFast( gMessageStringTable.getString(varname), NULL, MVT_VARIABLE, 0);
-}
-
-inline void LLMessageSystem::addStringFast(const char* varname, const std::string& s)
-{
- if (s.size())
- addDataFast( varname, (void *)s.c_str(), MVT_VARIABLE, (S32)(s.size()) + 1);
- else
- addDataFast( varname, NULL, MVT_VARIABLE, 0);
-}
-
-inline void LLMessageSystem::addString(const char* varname, const std::string& s)
-{
- if (s.size())
- addDataFast( gMessageStringTable.getString(varname), (void *)s.c_str(), MVT_VARIABLE, (S32)(s.size()) + 1);
- else
- addDataFast( gMessageStringTable.getString(varname), NULL, MVT_VARIABLE, 0);
-}
-
-
//-----------------------------------------------------------------------------
-// Retrieval aliases
+// Transmission aliases
//-----------------------------------------------------------------------------
-inline void LLMessageSystem::getS8Fast(const char *block, const char *var, S8 &u, S32 blocknum)
-{
- getDataFast(block, var, &u, sizeof(S8), blocknum);
-}
-
-inline void LLMessageSystem::getS8(const char *block, const char *var, S8 &u, S32 blocknum)
-{
- getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &u, sizeof(S8), blocknum);
-}
-
-inline void LLMessageSystem::getU8Fast(const char *block, const char *var, U8 &u, S32 blocknum)
-{
- getDataFast(block, var, &u, sizeof(U8), blocknum);
-}
-
-inline void LLMessageSystem::getU8(const char *block, const char *var, U8 &u, S32 blocknum)
-{
- getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &u, sizeof(U8), blocknum);
-}
-
-inline void LLMessageSystem::getBOOLFast(const char *block, const char *var, BOOL &b, S32 blocknum )
-{
- U8 value;
- getDataFast(block, var, &value, sizeof(U8), blocknum);
- b = (BOOL) value;
-}
-
-inline void LLMessageSystem::getBOOL(const char *block, const char *var, BOOL &b, S32 blocknum )
-{
- U8 value;
- getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &value, sizeof(U8), blocknum);
- b = (BOOL) value;
-}
-
-inline void LLMessageSystem::getS16Fast(const char *block, const char *var, S16 &d, S32 blocknum)
-{
- getDataFast(block, var, &d, sizeof(S16), blocknum);
-}
-
-inline void LLMessageSystem::getS16(const char *block, const char *var, S16 &d, S32 blocknum)
-{
- getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &d, sizeof(S16), blocknum);
-}
-
-inline void LLMessageSystem::getU16Fast(const char *block, const char *var, U16 &d, S32 blocknum)
-{
- getDataFast(block, var, &d, sizeof(U16), blocknum);
-}
-
-inline void LLMessageSystem::getU16(const char *block, const char *var, U16 &d, S32 blocknum)
-{
- getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &d, sizeof(U16), blocknum);
-}
-
-inline void LLMessageSystem::getS32Fast(const char *block, const char *var, S32 &d, S32 blocknum)
-{
- getDataFast(block, var, &d, sizeof(S32), blocknum);
-}
-
-inline void LLMessageSystem::getS32(const char *block, const char *var, S32 &d, S32 blocknum)
-{
- getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &d, sizeof(S32), blocknum);
-}
-
-inline void LLMessageSystem::getU32Fast(const char *block, const char *var, U32 &d, S32 blocknum)
-{
- getDataFast(block, var, &d, sizeof(U32), blocknum);
-}
-
-inline void LLMessageSystem::getU32(const char *block, const char *var, U32 &d, S32 blocknum)
-{
- getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &d, sizeof(U32), blocknum);
-}
-
-inline void LLMessageSystem::getU64Fast(const char *block, const char *var, U64 &d, S32 blocknum)
-{
- getDataFast(block, var, &d, sizeof(U64), blocknum);
-}
-
-inline void LLMessageSystem::getU64(const char *block, const char *var, U64 &d, S32 blocknum)
-{
- getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &d, sizeof(U64), blocknum);
-}
-
-
-inline void LLMessageSystem::getIPAddrFast(const char *block, const char *var, U32 &u, S32 blocknum)
-{
- getDataFast(block, var, &u, sizeof(U32), blocknum);
-}
-
-inline void LLMessageSystem::getIPAddr(const char *block, const char *var, U32 &u, S32 blocknum)
-{
- getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &u, sizeof(U32), blocknum);
-}
-
-inline void LLMessageSystem::getIPPortFast(const char *block, const char *var, U16 &u, S32 blocknum)
-{
- getDataFast(block, var, &u, sizeof(U16), blocknum);
- u = ntohs(u);
-}
-
-inline void LLMessageSystem::getIPPort(const char *block, const char *var, U16 &u, S32 blocknum)
-{
- getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &u, sizeof(U16), blocknum);
- u = ntohs(u);
-}
-
-
-inline void LLMessageSystem::getStringFast(const char *block, const char *var, S32 buffer_size, char *s, S32 blocknum )
-{
- s[0] = '\0';
- getDataFast(block, var, s, 0, blocknum, buffer_size);
- s[buffer_size - 1] = '\0';
-}
-
-inline void LLMessageSystem::getString(const char *block, const char *var, S32 buffer_size, char *s, S32 blocknum )
-{
- s[0] = '\0';
- getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), s, 0, blocknum, buffer_size);
- s[buffer_size - 1] = '\0';
-}
inline S32 LLMessageSystem::sendMessage(const U32 circuit)
{
diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp
index c2d7c9c2a3..9d7e603690 100644
--- a/indra/llmessage/message_prehash.cpp
+++ b/indra/llmessage/message_prehash.cpp
@@ -20,7 +20,6 @@ char * _PREHASH_X;
char * _PREHASH_Y;
char * _PREHASH_Z;
char * _PREHASH_AddFlags;
-char * _PREHASH_ReservedNewbie;
char * _PREHASH_FailureInfo;
char * _PREHASH_MapData;
char * _PREHASH_AddItem;
@@ -89,7 +88,6 @@ char * _PREHASH_RelatedRights;
char * _PREHASH_RedirectGridX;
char * _PREHASH_RedirectGridY;
char * _PREHASH_TransferID;
-char * _PREHASH_Transacted;
char * _PREHASH_TexturesChanged;
char * _PREHASH_UserLookAt;
char * _PREHASH_TestBlock1;
@@ -116,7 +114,6 @@ char * _PREHASH_SetSimStatusInDatabase;
char * _PREHASH_SetSimPresenceInDatabase;
char * _PREHASH_CameraProperty;
char * _PREHASH_BrushSize;
-char * _PREHASH_StartExpungeProcess;
char * _PREHASH_SimulatorSetMap;
char * _PREHASH_RegionPresenceRequestByRegionID;
char * _PREHASH_ParcelObjectOwnersReply;
@@ -210,8 +207,8 @@ char * _PREHASH_SimName;
char * _PREHASH_UserReport;
char * _PREHASH_DownloadPriority;
char * _PREHASH_ToAgentId;
-char * _PREHASH_Mag;
char * _PREHASH_DirPopularQuery;
+char * _PREHASH_Mag;
char * _PREHASH_ParcelPropertiesRequestByID;
char * _PREHASH_ObjectLink;
char * _PREHASH_RpcScriptReplyInbound;
@@ -420,7 +417,6 @@ char * _PREHASH_TerminateFriendship;
char * _PREHASH_TaskData;
char * _PREHASH_SimWideMaxPrims;
char * _PREHASH_TotalPrims;
-char * _PREHASH_SourceFilename;
char * _PREHASH_ProfileBegin;
char * _PREHASH_MoneyDetailsRequest;
char * _PREHASH_Request;
@@ -467,7 +463,6 @@ char * _PREHASH_ParamInUse;
char * _PREHASH_GodKickUser;
char * _PREHASH_PickName;
char * _PREHASH_TaskName;
-char * _PREHASH_ParcelGodReserveForNewbie;
char * _PREHASH_SubType;
char * _PREHASH_ObjectCount;
char * _PREHASH_RegionPresenceRequestByHandle;
@@ -486,10 +481,13 @@ char * _PREHASH_UpdateParcel;
char * _PREHASH_ClearAgentSessions;
char * _PREHASH_SetAlwaysRun;
char * _PREHASH_NVPair;
+char * _PREHASH_SearchType;
char * _PREHASH_ObjectSpinStart;
char * _PREHASH_UseEstateSun;
char * _PREHASH_LogoutBlock;
+char * _PREHASH_RelayLogControl;
char * _PREHASH_RegionID;
+char * _PREHASH_AbuseRegionID;
char * _PREHASH_Creator;
char * _PREHASH_ProposalText;
char * _PREHASH_DirEventsReply;
@@ -534,7 +532,6 @@ char * _PREHASH_MaxY;
char * _PREHASH_TextureAnim;
char * _PREHASH_ReturnIDs;
char * _PREHASH_Date;
-char * _PREHASH_GestureUpdate;
char * _PREHASH_AgentWearablesUpdate;
char * _PREHASH_AgentDataUpdate;
char * _PREHASH_Hash;
@@ -556,7 +553,6 @@ char * _PREHASH_HistoryItemData;
char * _PREHASH_AgentCachedTexture;
char * _PREHASH_Subject;
char * _PREHASH_East;
-char * _PREHASH_GodExpungeUser;
char * _PREHASH_QueryReplies;
char * _PREHASH_ObjectCategory;
char * _PREHASH_Time;
@@ -783,6 +779,7 @@ char * _PREHASH_UnsubscribeLoad;
char * _PREHASH_Packet;
char * _PREHASH_UndoLand;
char * _PREHASH_SimAccess;
+char * _PREHASH_AbuserID;
char * _PREHASH_MembershipFee;
char * _PREHASH_InviteGroupResponse;
char * _PREHASH_CreateInventoryFolder;
@@ -920,6 +917,7 @@ char * _PREHASH_ImageNotInDatabase;
char * _PREHASH_StartDate;
char * _PREHASH_AnimID;
char * _PREHASH_Serial;
+char * _PREHASH_AbuseRegionName;
char * _PREHASH_ControlPort;
char * _PREHASH_ModifyLand;
char * _PREHASH_Digest;
@@ -984,11 +982,11 @@ char * _PREHASH_EventFlags;
char * _PREHASH_TallyVotes;
char * _PREHASH_Result;
char * _PREHASH_LookAt;
+char * _PREHASH_SearchOrder;
char * _PREHASH_PayButton;
char * _PREHASH_SelfCount;
char * _PREHASH_PacketCount;
char * _PREHASH_ParcelBuyPass;
-char * _PREHASH_Identified;
char * _PREHASH_OldItemID;
char * _PREHASH_RegionPort;
char * _PREHASH_PriceEnergyUnit;
@@ -1024,7 +1022,6 @@ char * _PREHASH_EconomyDataRequest;
char * _PREHASH_TeleportLureRequest;
char * _PREHASH_FolderID;
char * _PREHASH_RegionHandleRequest;
-char * _PREHASH_GestureRequest;
char * _PREHASH_ScriptDataRequest;
char * _PREHASH_GroupRoleDataRequest;
char * _PREHASH_GroupTitlesRequest;
@@ -1168,11 +1165,9 @@ char * _PREHASH_Ratio;
char * _PREHASH_JoinGroupReply;
char * _PREHASH_LiveHelpGroupReply;
char * _PREHASH_Score;
-char * _PREHASH_ExpungeData;
char * _PREHASH_Image;
char * _PREHASH_ObjectClickAction;
char * _PREHASH_Delta;
-char * _PREHASH_InitiateUpload;
char * _PREHASH_Parameter;
char * _PREHASH_Flags;
char * _PREHASH_Plane;
@@ -1208,7 +1203,6 @@ char * _PREHASH_Disconnect;
char * _PREHASH_SimPosition;
char * _PREHASH_SimWideTotalPrims;
char * _PREHASH_Index;
-char * _PREHASH_BaseFilename;
char * _PREHASH_SimFilename;
char * _PREHASH_LastOwnerID;
char * _PREHASH_GroupNoticeRequest;
@@ -1293,6 +1287,7 @@ char * _PREHASH_AssetBlock;
char * _PREHASH_AcceptNotices;
char * _PREHASH_SetGroupAcceptNotices;
char * _PREHASH_CloseCircuit;
+char * _PREHASH_LogControl;
char * _PREHASH_TeleportFinish;
char * _PREHASH_PathRevolutions;
char * _PREHASH_ClassifiedInfoReply;
@@ -1472,7 +1467,6 @@ char * _PREHASH_DirLandReply;
char * _PREHASH_SpaceLocationTeleportReply;
char * _PREHASH_MuteType;
char * _PREHASH_IMViaEMail;
-char * _PREHASH_StartExpungeProcessAck;
char * _PREHASH_RentPrice;
char * _PREHASH_GenericMessage;
char * _PREHASH_ChildAgentAlive;
@@ -1492,7 +1486,6 @@ void init_prehash_data()
_PREHASH_Y = gMessageStringTable.getString("Y");
_PREHASH_Z = gMessageStringTable.getString("Z");
_PREHASH_AddFlags = gMessageStringTable.getString("AddFlags");
- _PREHASH_ReservedNewbie = gMessageStringTable.getString("ReservedNewbie");
_PREHASH_FailureInfo = gMessageStringTable.getString("FailureInfo");
_PREHASH_MapData = gMessageStringTable.getString("MapData");
_PREHASH_AddItem = gMessageStringTable.getString("AddItem");
@@ -1561,7 +1554,6 @@ void init_prehash_data()
_PREHASH_RedirectGridX = gMessageStringTable.getString("RedirectGridX");
_PREHASH_RedirectGridY = gMessageStringTable.getString("RedirectGridY");
_PREHASH_TransferID = gMessageStringTable.getString("TransferID");
- _PREHASH_Transacted = gMessageStringTable.getString("Transacted");
_PREHASH_TexturesChanged = gMessageStringTable.getString("TexturesChanged");
_PREHASH_UserLookAt = gMessageStringTable.getString("UserLookAt");
_PREHASH_TestBlock1 = gMessageStringTable.getString("TestBlock1");
@@ -1588,7 +1580,6 @@ void init_prehash_data()
_PREHASH_SetSimPresenceInDatabase = gMessageStringTable.getString("SetSimPresenceInDatabase");
_PREHASH_CameraProperty = gMessageStringTable.getString("CameraProperty");
_PREHASH_BrushSize = gMessageStringTable.getString("BrushSize");
- _PREHASH_StartExpungeProcess = gMessageStringTable.getString("StartExpungeProcess");
_PREHASH_SimulatorSetMap = gMessageStringTable.getString("SimulatorSetMap");
_PREHASH_RegionPresenceRequestByRegionID = gMessageStringTable.getString("RegionPresenceRequestByRegionID");
_PREHASH_ParcelObjectOwnersReply = gMessageStringTable.getString("ParcelObjectOwnersReply");
@@ -1682,8 +1673,8 @@ void init_prehash_data()
_PREHASH_UserReport = gMessageStringTable.getString("UserReport");
_PREHASH_DownloadPriority = gMessageStringTable.getString("DownloadPriority");
_PREHASH_ToAgentId = gMessageStringTable.getString("ToAgentId");
- _PREHASH_Mag = gMessageStringTable.getString("Mag");
_PREHASH_DirPopularQuery = gMessageStringTable.getString("DirPopularQuery");
+ _PREHASH_Mag = gMessageStringTable.getString("Mag");
_PREHASH_ParcelPropertiesRequestByID = gMessageStringTable.getString("ParcelPropertiesRequestByID");
_PREHASH_ObjectLink = gMessageStringTable.getString("ObjectLink");
_PREHASH_RpcScriptReplyInbound = gMessageStringTable.getString("RpcScriptReplyInbound");
@@ -1892,7 +1883,6 @@ void init_prehash_data()
_PREHASH_TaskData = gMessageStringTable.getString("TaskData");
_PREHASH_SimWideMaxPrims = gMessageStringTable.getString("SimWideMaxPrims");
_PREHASH_TotalPrims = gMessageStringTable.getString("TotalPrims");
- _PREHASH_SourceFilename = gMessageStringTable.getString("SourceFilename");
_PREHASH_ProfileBegin = gMessageStringTable.getString("ProfileBegin");
_PREHASH_MoneyDetailsRequest = gMessageStringTable.getString("MoneyDetailsRequest");
_PREHASH_Request = gMessageStringTable.getString("Request");
@@ -1939,7 +1929,6 @@ void init_prehash_data()
_PREHASH_GodKickUser = gMessageStringTable.getString("GodKickUser");
_PREHASH_PickName = gMessageStringTable.getString("PickName");
_PREHASH_TaskName = gMessageStringTable.getString("TaskName");
- _PREHASH_ParcelGodReserveForNewbie = gMessageStringTable.getString("ParcelGodReserveForNewbie");
_PREHASH_SubType = gMessageStringTable.getString("SubType");
_PREHASH_ObjectCount = gMessageStringTable.getString("ObjectCount");
_PREHASH_RegionPresenceRequestByHandle = gMessageStringTable.getString("RegionPresenceRequestByHandle");
@@ -1958,10 +1947,13 @@ void init_prehash_data()
_PREHASH_ClearAgentSessions = gMessageStringTable.getString("ClearAgentSessions");
_PREHASH_SetAlwaysRun = gMessageStringTable.getString("SetAlwaysRun");
_PREHASH_NVPair = gMessageStringTable.getString("NVPair");
+ _PREHASH_SearchType = gMessageStringTable.getString("SearchType");
_PREHASH_ObjectSpinStart = gMessageStringTable.getString("ObjectSpinStart");
_PREHASH_UseEstateSun = gMessageStringTable.getString("UseEstateSun");
_PREHASH_LogoutBlock = gMessageStringTable.getString("LogoutBlock");
+ _PREHASH_RelayLogControl = gMessageStringTable.getString("RelayLogControl");
_PREHASH_RegionID = gMessageStringTable.getString("RegionID");
+ _PREHASH_AbuseRegionID = gMessageStringTable.getString("AbuseRegionID");
_PREHASH_Creator = gMessageStringTable.getString("Creator");
_PREHASH_ProposalText = gMessageStringTable.getString("ProposalText");
_PREHASH_DirEventsReply = gMessageStringTable.getString("DirEventsReply");
@@ -2006,7 +1998,6 @@ void init_prehash_data()
_PREHASH_TextureAnim = gMessageStringTable.getString("TextureAnim");
_PREHASH_ReturnIDs = gMessageStringTable.getString("ReturnIDs");
_PREHASH_Date = gMessageStringTable.getString("Date");
- _PREHASH_GestureUpdate = gMessageStringTable.getString("GestureUpdate");
_PREHASH_AgentWearablesUpdate = gMessageStringTable.getString("AgentWearablesUpdate");
_PREHASH_AgentDataUpdate = gMessageStringTable.getString("AgentDataUpdate");
_PREHASH_Hash = gMessageStringTable.getString("Hash");
@@ -2028,7 +2019,6 @@ void init_prehash_data()
_PREHASH_AgentCachedTexture = gMessageStringTable.getString("AgentCachedTexture");
_PREHASH_Subject = gMessageStringTable.getString("Subject");
_PREHASH_East = gMessageStringTable.getString("East");
- _PREHASH_GodExpungeUser = gMessageStringTable.getString("GodExpungeUser");
_PREHASH_QueryReplies = gMessageStringTable.getString("QueryReplies");
_PREHASH_ObjectCategory = gMessageStringTable.getString("ObjectCategory");
_PREHASH_Time = gMessageStringTable.getString("Time");
@@ -2255,6 +2245,7 @@ void init_prehash_data()
_PREHASH_Packet = gMessageStringTable.getString("Packet");
_PREHASH_UndoLand = gMessageStringTable.getString("UndoLand");
_PREHASH_SimAccess = gMessageStringTable.getString("SimAccess");
+ _PREHASH_AbuserID = gMessageStringTable.getString("AbuserID");
_PREHASH_MembershipFee = gMessageStringTable.getString("MembershipFee");
_PREHASH_InviteGroupResponse = gMessageStringTable.getString("InviteGroupResponse");
_PREHASH_CreateInventoryFolder = gMessageStringTable.getString("CreateInventoryFolder");
@@ -2392,6 +2383,7 @@ void init_prehash_data()
_PREHASH_StartDate = gMessageStringTable.getString("StartDate");
_PREHASH_AnimID = gMessageStringTable.getString("AnimID");
_PREHASH_Serial = gMessageStringTable.getString("Serial");
+ _PREHASH_AbuseRegionName = gMessageStringTable.getString("AbuseRegionName");
_PREHASH_ControlPort = gMessageStringTable.getString("ControlPort");
_PREHASH_ModifyLand = gMessageStringTable.getString("ModifyLand");
_PREHASH_Digest = gMessageStringTable.getString("Digest");
@@ -2456,11 +2448,11 @@ void init_prehash_data()
_PREHASH_TallyVotes = gMessageStringTable.getString("TallyVotes");
_PREHASH_Result = gMessageStringTable.getString("Result");
_PREHASH_LookAt = gMessageStringTable.getString("LookAt");
+ _PREHASH_SearchOrder = gMessageStringTable.getString("SearchOrder");
_PREHASH_PayButton = gMessageStringTable.getString("PayButton");
_PREHASH_SelfCount = gMessageStringTable.getString("SelfCount");
_PREHASH_PacketCount = gMessageStringTable.getString("PacketCount");
_PREHASH_ParcelBuyPass = gMessageStringTable.getString("ParcelBuyPass");
- _PREHASH_Identified = gMessageStringTable.getString("Identified");
_PREHASH_OldItemID = gMessageStringTable.getString("OldItemID");
_PREHASH_RegionPort = gMessageStringTable.getString("RegionPort");
_PREHASH_PriceEnergyUnit = gMessageStringTable.getString("PriceEnergyUnit");
@@ -2496,7 +2488,6 @@ void init_prehash_data()
_PREHASH_TeleportLureRequest = gMessageStringTable.getString("TeleportLureRequest");
_PREHASH_FolderID = gMessageStringTable.getString("FolderID");
_PREHASH_RegionHandleRequest = gMessageStringTable.getString("RegionHandleRequest");
- _PREHASH_GestureRequest = gMessageStringTable.getString("GestureRequest");
_PREHASH_ScriptDataRequest = gMessageStringTable.getString("ScriptDataRequest");
_PREHASH_GroupRoleDataRequest = gMessageStringTable.getString("GroupRoleDataRequest");
_PREHASH_GroupTitlesRequest = gMessageStringTable.getString("GroupTitlesRequest");
@@ -2640,11 +2631,9 @@ void init_prehash_data()
_PREHASH_JoinGroupReply = gMessageStringTable.getString("JoinGroupReply");
_PREHASH_LiveHelpGroupReply = gMessageStringTable.getString("LiveHelpGroupReply");
_PREHASH_Score = gMessageStringTable.getString("Score");
- _PREHASH_ExpungeData = gMessageStringTable.getString("ExpungeData");
_PREHASH_Image = gMessageStringTable.getString("Image");
_PREHASH_ObjectClickAction = gMessageStringTable.getString("ObjectClickAction");
_PREHASH_Delta = gMessageStringTable.getString("Delta");
- _PREHASH_InitiateUpload = gMessageStringTable.getString("InitiateUpload");
_PREHASH_Parameter = gMessageStringTable.getString("Parameter");
_PREHASH_Flags = gMessageStringTable.getString("Flags");
_PREHASH_Plane = gMessageStringTable.getString("Plane");
@@ -2680,7 +2669,6 @@ void init_prehash_data()
_PREHASH_SimPosition = gMessageStringTable.getString("SimPosition");
_PREHASH_SimWideTotalPrims = gMessageStringTable.getString("SimWideTotalPrims");
_PREHASH_Index = gMessageStringTable.getString("Index");
- _PREHASH_BaseFilename = gMessageStringTable.getString("BaseFilename");
_PREHASH_SimFilename = gMessageStringTable.getString("SimFilename");
_PREHASH_LastOwnerID = gMessageStringTable.getString("LastOwnerID");
_PREHASH_GroupNoticeRequest = gMessageStringTable.getString("GroupNoticeRequest");
@@ -2765,6 +2753,7 @@ void init_prehash_data()
_PREHASH_AcceptNotices = gMessageStringTable.getString("AcceptNotices");
_PREHASH_SetGroupAcceptNotices = gMessageStringTable.getString("SetGroupAcceptNotices");
_PREHASH_CloseCircuit = gMessageStringTable.getString("CloseCircuit");
+ _PREHASH_LogControl = gMessageStringTable.getString("LogControl");
_PREHASH_TeleportFinish = gMessageStringTable.getString("TeleportFinish");
_PREHASH_PathRevolutions = gMessageStringTable.getString("PathRevolutions");
_PREHASH_ClassifiedInfoReply = gMessageStringTable.getString("ClassifiedInfoReply");
@@ -2944,7 +2933,6 @@ void init_prehash_data()
_PREHASH_SpaceLocationTeleportReply = gMessageStringTable.getString("SpaceLocationTeleportReply");
_PREHASH_MuteType = gMessageStringTable.getString("MuteType");
_PREHASH_IMViaEMail = gMessageStringTable.getString("IMViaEMail");
- _PREHASH_StartExpungeProcessAck = gMessageStringTable.getString("StartExpungeProcessAck");
_PREHASH_RentPrice = gMessageStringTable.getString("RentPrice");
_PREHASH_GenericMessage = gMessageStringTable.getString("GenericMessage");
_PREHASH_ChildAgentAlive = gMessageStringTable.getString("ChildAgentAlive");
diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h
index 63e23237f5..19b9881dde 100644
--- a/indra/llmessage/message_prehash.h
+++ b/indra/llmessage/message_prehash.h
@@ -20,7 +20,6 @@ extern char * _PREHASH_X;
extern char * _PREHASH_Y;
extern char * _PREHASH_Z;
extern char * _PREHASH_AddFlags;
-extern char * _PREHASH_ReservedNewbie;
extern char * _PREHASH_FailureInfo;
extern char * _PREHASH_MapData;
extern char * _PREHASH_AddItem;
@@ -89,7 +88,6 @@ extern char * _PREHASH_RelatedRights;
extern char * _PREHASH_RedirectGridX;
extern char * _PREHASH_RedirectGridY;
extern char * _PREHASH_TransferID;
-extern char * _PREHASH_Transacted;
extern char * _PREHASH_TexturesChanged;
extern char * _PREHASH_UserLookAt;
extern char * _PREHASH_TestBlock1;
@@ -116,7 +114,6 @@ extern char * _PREHASH_SetSimStatusInDatabase;
extern char * _PREHASH_SetSimPresenceInDatabase;
extern char * _PREHASH_CameraProperty;
extern char * _PREHASH_BrushSize;
-extern char * _PREHASH_StartExpungeProcess;
extern char * _PREHASH_SimulatorSetMap;
extern char * _PREHASH_RegionPresenceRequestByRegionID;
extern char * _PREHASH_ParcelObjectOwnersReply;
@@ -210,8 +207,8 @@ extern char * _PREHASH_SimName;
extern char * _PREHASH_UserReport;
extern char * _PREHASH_DownloadPriority;
extern char * _PREHASH_ToAgentId;
-extern char * _PREHASH_Mag;
extern char * _PREHASH_DirPopularQuery;
+extern char * _PREHASH_Mag;
extern char * _PREHASH_ParcelPropertiesRequestByID;
extern char * _PREHASH_ObjectLink;
extern char * _PREHASH_RpcScriptReplyInbound;
@@ -420,7 +417,6 @@ extern char * _PREHASH_TerminateFriendship;
extern char * _PREHASH_TaskData;
extern char * _PREHASH_SimWideMaxPrims;
extern char * _PREHASH_TotalPrims;
-extern char * _PREHASH_SourceFilename;
extern char * _PREHASH_ProfileBegin;
extern char * _PREHASH_MoneyDetailsRequest;
extern char * _PREHASH_Request;
@@ -467,7 +463,6 @@ extern char * _PREHASH_ParamInUse;
extern char * _PREHASH_GodKickUser;
extern char * _PREHASH_PickName;
extern char * _PREHASH_TaskName;
-extern char * _PREHASH_ParcelGodReserveForNewbie;
extern char * _PREHASH_SubType;
extern char * _PREHASH_ObjectCount;
extern char * _PREHASH_RegionPresenceRequestByHandle;
@@ -486,10 +481,13 @@ extern char * _PREHASH_UpdateParcel;
extern char * _PREHASH_ClearAgentSessions;
extern char * _PREHASH_SetAlwaysRun;
extern char * _PREHASH_NVPair;
+extern char * _PREHASH_SearchType;
extern char * _PREHASH_ObjectSpinStart;
extern char * _PREHASH_UseEstateSun;
extern char * _PREHASH_LogoutBlock;
+extern char * _PREHASH_RelayLogControl;
extern char * _PREHASH_RegionID;
+extern char * _PREHASH_AbuseRegionID;
extern char * _PREHASH_Creator;
extern char * _PREHASH_ProposalText;
extern char * _PREHASH_DirEventsReply;
@@ -534,7 +532,6 @@ extern char * _PREHASH_MaxY;
extern char * _PREHASH_TextureAnim;
extern char * _PREHASH_ReturnIDs;
extern char * _PREHASH_Date;
-extern char * _PREHASH_GestureUpdate;
extern char * _PREHASH_AgentWearablesUpdate;
extern char * _PREHASH_AgentDataUpdate;
extern char * _PREHASH_Hash;
@@ -556,7 +553,6 @@ extern char * _PREHASH_HistoryItemData;
extern char * _PREHASH_AgentCachedTexture;
extern char * _PREHASH_Subject;
extern char * _PREHASH_East;
-extern char * _PREHASH_GodExpungeUser;
extern char * _PREHASH_QueryReplies;
extern char * _PREHASH_ObjectCategory;
extern char * _PREHASH_Time;
@@ -783,6 +779,7 @@ extern char * _PREHASH_UnsubscribeLoad;
extern char * _PREHASH_Packet;
extern char * _PREHASH_UndoLand;
extern char * _PREHASH_SimAccess;
+extern char * _PREHASH_AbuserID;
extern char * _PREHASH_MembershipFee;
extern char * _PREHASH_InviteGroupResponse;
extern char * _PREHASH_CreateInventoryFolder;
@@ -920,6 +917,7 @@ extern char * _PREHASH_ImageNotInDatabase;
extern char * _PREHASH_StartDate;
extern char * _PREHASH_AnimID;
extern char * _PREHASH_Serial;
+extern char * _PREHASH_AbuseRegionName;
extern char * _PREHASH_ControlPort;
extern char * _PREHASH_ModifyLand;
extern char * _PREHASH_Digest;
@@ -984,11 +982,11 @@ extern char * _PREHASH_EventFlags;
extern char * _PREHASH_TallyVotes;
extern char * _PREHASH_Result;
extern char * _PREHASH_LookAt;
+extern char * _PREHASH_SearchOrder;
extern char * _PREHASH_PayButton;
extern char * _PREHASH_SelfCount;
extern char * _PREHASH_PacketCount;
extern char * _PREHASH_ParcelBuyPass;
-extern char * _PREHASH_Identified;
extern char * _PREHASH_OldItemID;
extern char * _PREHASH_RegionPort;
extern char * _PREHASH_PriceEnergyUnit;
@@ -1024,7 +1022,6 @@ extern char * _PREHASH_EconomyDataRequest;
extern char * _PREHASH_TeleportLureRequest;
extern char * _PREHASH_FolderID;
extern char * _PREHASH_RegionHandleRequest;
-extern char * _PREHASH_GestureRequest;
extern char * _PREHASH_ScriptDataRequest;
extern char * _PREHASH_GroupRoleDataRequest;
extern char * _PREHASH_GroupTitlesRequest;
@@ -1168,11 +1165,9 @@ extern char * _PREHASH_Ratio;
extern char * _PREHASH_JoinGroupReply;
extern char * _PREHASH_LiveHelpGroupReply;
extern char * _PREHASH_Score;
-extern char * _PREHASH_ExpungeData;
extern char * _PREHASH_Image;
extern char * _PREHASH_ObjectClickAction;
extern char * _PREHASH_Delta;
-extern char * _PREHASH_InitiateUpload;
extern char * _PREHASH_Parameter;
extern char * _PREHASH_Flags;
extern char * _PREHASH_Plane;
@@ -1208,7 +1203,6 @@ extern char * _PREHASH_Disconnect;
extern char * _PREHASH_SimPosition;
extern char * _PREHASH_SimWideTotalPrims;
extern char * _PREHASH_Index;
-extern char * _PREHASH_BaseFilename;
extern char * _PREHASH_SimFilename;
extern char * _PREHASH_LastOwnerID;
extern char * _PREHASH_GroupNoticeRequest;
@@ -1293,6 +1287,7 @@ extern char * _PREHASH_AssetBlock;
extern char * _PREHASH_AcceptNotices;
extern char * _PREHASH_SetGroupAcceptNotices;
extern char * _PREHASH_CloseCircuit;
+extern char * _PREHASH_LogControl;
extern char * _PREHASH_TeleportFinish;
extern char * _PREHASH_PathRevolutions;
extern char * _PREHASH_ClassifiedInfoReply;
@@ -1472,7 +1467,6 @@ extern char * _PREHASH_DirLandReply;
extern char * _PREHASH_SpaceLocationTeleportReply;
extern char * _PREHASH_MuteType;
extern char * _PREHASH_IMViaEMail;
-extern char * _PREHASH_StartExpungeProcessAck;
extern char * _PREHASH_RentPrice;
extern char * _PREHASH_GenericMessage;
extern char * _PREHASH_ChildAgentAlive;
diff --git a/indra/llmessage/net.cpp b/indra/llmessage/net.cpp
index a78b216ccb..9e83ce1434 100644
--- a/indra/llmessage/net.cpp
+++ b/indra/llmessage/net.cpp
@@ -222,6 +222,12 @@ S32 start_net(S32& socket_out, int& nPort)
return 4;
}
}
+
+ sockaddr_in socket_address;
+ S32 socket_address_size = sizeof(socket_address);
+ getsockname(hSocket, (SOCKADDR*) &socket_address, &socket_address_size);
+ attempt_port = ntohs(socket_address.sin_port);
+
llinfos << "connected on port " << attempt_port << llendl;
nPort = attempt_port;
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index 366ecc7d6f..fa0b4747e6 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -1260,8 +1260,8 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
U8 image_ids[MAX_TES*16];
U8 colors[MAX_TES*4];
- S16 scale_s[MAX_TES];
- S16 scale_t[MAX_TES];
+ F32 scale_s[MAX_TES];
+ F32 scale_t[MAX_TES];
S16 offset_s[MAX_TES];
S16 offset_t[MAX_TES];
S16 image_rot[MAX_TES];
@@ -1296,8 +1296,8 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
colors[4*face_index + 3] = 255 - coloru.mV[3];
const LLTextureEntry* te = getTE(face_index);
- scale_s[face_index] = (S16) llround(((llclamp(te->mScaleS,-LL_MAX_SCALE_S, LL_MAX_SCALE_S)-1.0f)/(LL_MAX_SCALE_S+1.f) * (F32)0x7FFF));
- scale_t[face_index] = (S16) llround(((llclamp(te->mScaleT,-LL_MAX_SCALE_T, LL_MAX_SCALE_T)-1.0f)/(LL_MAX_SCALE_T+1.f) * (F32)0x7FFF));
+ scale_s[face_index] = (F32) te->mScaleS;
+ scale_t[face_index] = (F32) te->mScaleT;
offset_s[face_index] = (S16) llround((llclamp(te->mOffsetS,-1.0f,1.0f) * (F32)0x7FFF)) ;
offset_t[face_index] = (S16) llround((llclamp(te->mOffsetT,-1.0f,1.0f) * (F32)0x7FFF)) ;
image_rot[face_index] = (S16) llround(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * (F32)0x7FFF));
@@ -1310,9 +1310,9 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
*cur_ptr++ = 0;
cur_ptr += packTEField(cur_ptr, (U8 *)colors, 4 ,last_face_index, MVT_U8);
*cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)scale_s, 2 ,last_face_index, MVT_S16Array);
+ cur_ptr += packTEField(cur_ptr, (U8 *)scale_s, 4 ,last_face_index, MVT_F32);
*cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)scale_t, 2 ,last_face_index, MVT_S16Array);
+ cur_ptr += packTEField(cur_ptr, (U8 *)scale_t, 4 ,last_face_index, MVT_F32);
*cur_ptr++ = 0;
cur_ptr += packTEField(cur_ptr, (U8 *)offset_s, 2 ,last_face_index, MVT_S16Array);
*cur_ptr++ = 0;
@@ -1336,8 +1336,8 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
U8 image_ids[MAX_TES*16];
U8 colors[MAX_TES*4];
- S16 scale_s[MAX_TES];
- S16 scale_t[MAX_TES];
+ F32 scale_s[MAX_TES];
+ F32 scale_t[MAX_TES];
S16 offset_s[MAX_TES];
S16 offset_t[MAX_TES];
S16 image_rot[MAX_TES];
@@ -1372,8 +1372,8 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
colors[4*face_index + 3] = 255 - coloru.mV[3];
const LLTextureEntry* te = getTE(face_index);
- scale_s[face_index] = (S16) llround(((llclamp(te->mScaleS,-LL_MAX_SCALE_S, LL_MAX_SCALE_S)-1.0f)/(LL_MAX_SCALE_S+1.f) * (F32)0x7FFF));
- scale_t[face_index] = (S16) llround(((llclamp(te->mScaleT,-LL_MAX_SCALE_T, LL_MAX_SCALE_T)-1.0f)/(LL_MAX_SCALE_T+1.f) * (F32)0x7FFF));
+ scale_s[face_index] = (F32) te->mScaleS;
+ scale_t[face_index] = (F32) te->mScaleT;
offset_s[face_index] = (S16) llround((llclamp(te->mOffsetS,-1.0f,1.0f) * (F32)0x7FFF)) ;
offset_t[face_index] = (S16) llround((llclamp(te->mOffsetT,-1.0f,1.0f) * (F32)0x7FFF)) ;
image_rot[face_index] = (S16) llround(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * (F32)0x7FFF));
@@ -1387,9 +1387,9 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
*cur_ptr++ = 0;
cur_ptr += packTEField(cur_ptr, (U8 *)colors, 4 ,last_face_index, MVT_U8);
*cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)scale_s, 2 ,last_face_index, MVT_S16Array);
+ cur_ptr += packTEField(cur_ptr, (U8 *)scale_s, 4 ,last_face_index, MVT_F32);
*cur_ptr++ = 0;
- cur_ptr += packTEField(cur_ptr, (U8 *)scale_t, 2 ,last_face_index, MVT_S16Array);
+ cur_ptr += packTEField(cur_ptr, (U8 *)scale_t, 4 ,last_face_index, MVT_F32);
*cur_ptr++ = 0;
cur_ptr += packTEField(cur_ptr, (U8 *)offset_s, 2 ,last_face_index, MVT_S16Array);
*cur_ptr++ = 0;
@@ -1421,8 +1421,8 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, con
U8 image_data[MAX_TES*16];
U8 colors[MAX_TES*4];
- S16 scale_s[MAX_TES];
- S16 scale_t[MAX_TES];
+ F32 scale_s[MAX_TES];
+ F32 scale_t[MAX_TES];
S16 offset_s[MAX_TES];
S16 offset_t[MAX_TES];
S16 image_rot[MAX_TES];
@@ -1465,9 +1465,9 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, con
cur_ptr++;
cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)colors, 4, face_count, MVT_U8);
cur_ptr++;
- cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_s, 2, face_count, MVT_S16Array);
+ cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_s, 4, face_count, MVT_F32);
cur_ptr++;
- cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_t, 2, face_count, MVT_S16Array);
+ cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_t, 4, face_count, MVT_F32);
cur_ptr++;
cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_s, 2, face_count, MVT_S16Array);
cur_ptr++;
@@ -1484,9 +1484,7 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, con
for (U32 i = 0; i < face_count; i++)
{
retval |= setTETexture(i, ((LLUUID*)image_data)[i]);
- retval |= setTEScale(i,
- floor((1.0f + ((((F32)scale_s[i] / (F32)0x7FFF)) * (LL_MAX_SCALE_S+1.f))) * 100.f + 0.5f) / 100.f,
- floor((1.0f + ((((F32)scale_t[i] / (F32)0x7FFF)) * (LL_MAX_SCALE_T+1.f))) * 100.f + 0.5f) / 100.f);
+ retval |= setTEScale(i, scale_s[i], scale_t[i]);
retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF);
retval |= setTERotation(i, ((F32)image_rot[i]/ (F32)0x7FFF) * F_TWO_PI);
retval |= setTEBumpShinyFullbright(i, bump[i]);
@@ -1518,8 +1516,8 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
U8 image_data[MAX_TES*16];
U8 colors[MAX_TES*4];
- S16 scale_s[MAX_TES];
- S16 scale_t[MAX_TES];
+ F32 scale_s[MAX_TES];
+ F32 scale_t[MAX_TES];
S16 offset_s[MAX_TES];
S16 offset_t[MAX_TES];
S16 image_rot[MAX_TES];
@@ -1552,9 +1550,9 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
cur_ptr++;
cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)colors, 4, face_count, MVT_U8);
cur_ptr++;
- cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_s, 2, face_count, MVT_S16Array);
+ cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_s, 4, face_count, MVT_F32);
cur_ptr++;
- cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_t, 2, face_count, MVT_S16Array);
+ cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_t, 4, face_count, MVT_F32);
cur_ptr++;
cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_s, 2, face_count, MVT_S16Array);
cur_ptr++;
@@ -1577,9 +1575,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
for (i = 0; i < face_count; i++)
{
retval |= setTETexture(i, image_ids[i]);
- retval |= setTEScale(i,
- floor((1.0f + ((((F32)scale_s[i] / (F32)0x7FFF)) * (LL_MAX_SCALE_S+1.f))) * 100.f + 0.5f) / 100.f,
- floor((1.0f + ((((F32)scale_t[i] / (F32)0x7FFF)) * (LL_MAX_SCALE_T+1.f))) * 100.f + 0.5f) / 100.f);
+ retval |= setTEScale(i, scale_s[i], scale_t[i]);
retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF);
retval |= setTERotation(i, ((F32)image_rot[i]/ (F32)0x7FFF) * F_TWO_PI);
retval |= setTEBumpShinyFullbright(i, bump[i]);
diff --git a/indra/llprimitive/llvolumemessage.cpp b/indra/llprimitive/llvolumemessage.cpp
index a43aa19cab..60c6bae34a 100644
--- a/indra/llprimitive/llvolumemessage.cpp
+++ b/indra/llprimitive/llvolumemessage.cpp
@@ -23,23 +23,25 @@ bool LLVolumeMessage::packProfileParams(
LLMessageSystem *mesgsys)
{
// Default to cylinder
- static LLProfileParams defaultparams(LL_PCODE_PROFILE_CIRCLE, U8(0), U8(0), U8(0));
+ static LLProfileParams defaultparams(LL_PCODE_PROFILE_CIRCLE, U16(0), U16(0), U16(0));
if (!params)
params = &defaultparams;
U8 tempU8;
+ U16 tempU16;
+
tempU8 = params->getCurveType();
mesgsys->addU8Fast(_PREHASH_ProfileCurve, tempU8);
- tempU8 = (U8) llround( params->getBegin() / CUT_QUANTA);
- mesgsys->addU8Fast(_PREHASH_ProfileBegin, tempU8);
+ tempU16 = (U16) llround( params->getBegin() / CUT_QUANTA);
+ mesgsys->addU16Fast(_PREHASH_ProfileBegin, tempU16);
- tempU8 = 200 - (U8) llround(params->getEnd() / CUT_QUANTA);
- mesgsys->addU8Fast(_PREHASH_ProfileEnd, tempU8);
+ tempU16 = 50000 - (U16) llround(params->getEnd() / CUT_QUANTA);
+ mesgsys->addU16Fast(_PREHASH_ProfileEnd, tempU16);
- tempU8 = (S8) llround(params->getHollow() / SHEAR_QUANTA);
- mesgsys->addU8Fast(_PREHASH_ProfileHollow, tempU8);
+ tempU16 = (U16) llround(params->getHollow() / HOLLOW_QUANTA);
+ mesgsys->addU16Fast(_PREHASH_ProfileHollow, tempU16);
return true;
}
@@ -49,23 +51,25 @@ bool LLVolumeMessage::packProfileParams(
LLDataPacker &dp)
{
// Default to cylinder
- static LLProfileParams defaultparams(LL_PCODE_PROFILE_CIRCLE, U8(0), U8(0), U8(0));
+ static LLProfileParams defaultparams(LL_PCODE_PROFILE_CIRCLE, U16(0), U16(0), U16(0));
if (!params)
params = &defaultparams;
U8 tempU8;
+ U16 tempU16;
+
tempU8 = params->getCurveType();
dp.packU8(tempU8, "Curve");
- tempU8 = (U8) llround( params->getBegin() / CUT_QUANTA);
- dp.packU8(tempU8, "Begin");
+ tempU16 = (U16) llround( params->getBegin() / CUT_QUANTA);
+ dp.packU16(tempU16, "Begin");
- tempU8 = 200 - (U8) llround(params->getEnd() / CUT_QUANTA);
- dp.packU8(tempU8, "End");
+ tempU16 = 50000 - (U16) llround(params->getEnd() / CUT_QUANTA);
+ dp.packU16(tempU16, "End");
- tempU8 = (S8) llround(params->getHollow() / SHEAR_QUANTA);
- dp.packU8(tempU8, "Hollow");
+ tempU16 = (U16) llround(params->getHollow() / HOLLOW_QUANTA);
+ dp.packU16(tempU16, "Hollow");
return true;
}
@@ -77,13 +81,14 @@ bool LLVolumeMessage::unpackProfileParams(
{
bool ok = true;
U8 temp_u8;
+ U16 temp_u16;
F32 temp_f32;
mesgsys->getU8Fast(block_name, _PREHASH_ProfileCurve, temp_u8, block_num);
params->setCurveType(temp_u8);
- mesgsys->getU8Fast(block_name, _PREHASH_ProfileBegin, temp_u8, block_num);
- temp_f32 = temp_u8 * CUT_QUANTA;
+ mesgsys->getU16Fast(block_name, _PREHASH_ProfileBegin, temp_u16, block_num);
+ temp_f32 = temp_u16 * CUT_QUANTA;
if (temp_f32 > 1.f)
{
llwarns << "Profile begin out of range: " << temp_f32
@@ -93,8 +98,8 @@ bool LLVolumeMessage::unpackProfileParams(
}
params->setBegin(temp_f32);
- mesgsys->getU8Fast(block_name, _PREHASH_ProfileEnd, temp_u8, block_num);
- temp_f32 = temp_u8 * CUT_QUANTA;
+ mesgsys->getU16Fast(block_name, _PREHASH_ProfileEnd, temp_u16, block_num);
+ temp_f32 = temp_u16 * CUT_QUANTA;
if (temp_f32 > 1.f)
{
llwarns << "Profile end out of range: " << 1.f - temp_f32
@@ -104,8 +109,8 @@ bool LLVolumeMessage::unpackProfileParams(
}
params->setEnd(1.f - temp_f32);
- mesgsys->getU8Fast(block_name, _PREHASH_ProfileHollow, temp_u8, block_num);
- temp_f32 = temp_u8 * SCALE_QUANTA;
+ mesgsys->getU16Fast(block_name, _PREHASH_ProfileHollow, temp_u16, block_num);
+ temp_f32 = temp_u16 * HOLLOW_QUANTA;
if (temp_f32 > 1.f)
{
llwarns << "Profile hollow out of range: " << temp_f32
@@ -132,13 +137,14 @@ bool LLVolumeMessage::unpackProfileParams(
{
bool ok = true;
U8 temp_u8;
+ U16 temp_u16;
F32 temp_f32;
dp.unpackU8(temp_u8, "Curve");
params->setCurveType(temp_u8);
- dp.unpackU8(temp_u8, "Begin");
- temp_f32 = temp_u8 * CUT_QUANTA;
+ dp.unpackU16(temp_u16, "Begin");
+ temp_f32 = temp_u16 * CUT_QUANTA;
if (temp_f32 > 1.f)
{
llwarns << "Profile begin out of range: " << temp_f32 << llendl;
@@ -148,8 +154,8 @@ bool LLVolumeMessage::unpackProfileParams(
}
params->setBegin(temp_f32);
- dp.unpackU8(temp_u8, "End");
- temp_f32 = temp_u8 * CUT_QUANTA;
+ dp.unpackU16(temp_u16, "End");
+ temp_f32 = temp_u16 * CUT_QUANTA;
if (temp_f32 > 1.f)
{
llwarns << "Profile end out of range: " << 1.f - temp_f32 << llendl;
@@ -159,8 +165,8 @@ bool LLVolumeMessage::unpackProfileParams(
}
params->setEnd(1.f - temp_f32);
- dp.unpackU8(temp_u8, "Hollow");
- temp_f32 = temp_u8 * SCALE_QUANTA;
+ dp.unpackU16(temp_u16, "Hollow");
+ temp_f32 = temp_u16 * HOLLOW_QUANTA;
if (temp_f32 > 1.f)
{
llwarns << "Profile hollow out of range: " << temp_f32 << llendl;
@@ -193,11 +199,11 @@ bool LLVolumeMessage::packPathParams(
U8 curve = params->getCurveType();
mesgsys->addU8Fast(_PREHASH_PathCurve, curve);
- U8 begin = (U8) llround(params->getBegin() / SCALE_QUANTA);
- mesgsys->addU8Fast(_PREHASH_PathBegin, begin);
+ U16 begin = (U16) llround(params->getBegin() / CUT_QUANTA);
+ mesgsys->addU16Fast(_PREHASH_PathBegin, begin);
- U8 end = 100 - (U8) llround(params->getEnd() / SCALE_QUANTA);
- mesgsys->addU8Fast(_PREHASH_PathEnd, end);
+ U16 end = 50000 - (U16) llround(params->getEnd() / CUT_QUANTA);
+ mesgsys->addU16Fast(_PREHASH_PathEnd, end);
// Avoid truncation problem with direct F32->U8 cast.
// (e.g., (U8) (0.50 / 0.01) = (U8) 49.9999999 = 49 not 50.
@@ -250,11 +256,11 @@ bool LLVolumeMessage::packPathParams(
U8 curve = params->getCurveType();
dp.packU8(curve, "Curve");
- U8 begin = (U8) llround(params->getBegin() / SCALE_QUANTA);
- dp.packU8(begin, "Begin");
+ U16 begin = (U16) llround(params->getBegin() / CUT_QUANTA);
+ dp.packU16(begin, "Begin");
- U8 end = 100 - (U8) llround(params->getEnd() / SCALE_QUANTA);
- dp.packU8(end, "End");
+ U16 end = 50000 - (U16) llround(params->getEnd() / CUT_QUANTA);
+ dp.packU16(end, "End");
// Avoid truncation problem with direct F32->U8 cast.
// (e.g., (U8) (0.50 / 0.01) = (U8) 49.9999999 = 49 not 50.
@@ -305,13 +311,13 @@ bool LLVolumeMessage::unpackPathParams(
mesgsys->getU8Fast(block_name, _PREHASH_PathCurve, curve, block_num);
params->setCurveType(curve);
- U8 begin;
- mesgsys->getU8Fast(block_name, _PREHASH_PathBegin, begin, block_num);
- params->setBegin((F32)(begin * SCALE_QUANTA));
+ U16 begin;
+ mesgsys->getU16Fast(block_name, _PREHASH_PathBegin, begin, block_num);
+ params->setBegin((F32)(begin * CUT_QUANTA));
- U8 end;
- mesgsys->getU8Fast(block_name, _PREHASH_PathEnd, end, block_num);
- params->setEnd((F32)((100 - end) * SCALE_QUANTA));
+ U16 end;
+ mesgsys->getU16Fast(block_name, _PREHASH_PathEnd, end, block_num);
+ params->setEnd((F32)((50000 - end) * CUT_QUANTA));
U8 pack_scale_x, pack_scale_y;
mesgsys->getU8Fast(block_name, _PREHASH_PathScaleX, pack_scale_x, block_num);
@@ -371,14 +377,16 @@ bool LLVolumeMessage::unpackPathParams(LLPathParams* params, LLDataPacker &dp)
{
U8 value;
S8 svalue;
+ U16 temp_u16;
+
dp.unpackU8(value, "Curve");
params->setCurveType( value );
- dp.unpackU8(value, "Begin");
- params->setBegin((F32)(value * SCALE_QUANTA));
+ dp.unpackU16(temp_u16, "Begin");
+ params->setBegin((F32)(temp_u16 * CUT_QUANTA));
- dp.unpackU8(value, "End");
- params->setEnd((F32)((100 - value) * SCALE_QUANTA));
+ dp.unpackU16(temp_u16, "End");
+ params->setEnd((F32)((50000 - temp_u16) * CUT_QUANTA));
dp.unpackU8(value, "ScaleX");
F32 x = (F32) (200 - value) * SCALE_QUANTA;
diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp
index fde27132e6..215f6d40ed 100644
--- a/indra/llui/llcheckboxctrl.cpp
+++ b/indra/llui/llcheckboxctrl.cpp
@@ -156,7 +156,7 @@ void LLCheckBoxCtrl::onCommit()
void LLCheckBoxCtrl::setEnabled(BOOL b)
{
- LLUICtrl::setEnabled(b);
+ LLView::setEnabled(b);
mButton->setEnabled(b);
}
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index f13e0d54b9..f548045474 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -102,7 +102,7 @@ LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString
LLUUID arrow_image_id( LLUI::sAssetsGroup->getString("combobox_arrow.tga") );
mArrowImage = LLUI::sImageProvider->getUIImageByID(arrow_image_id);
- mArrowImageWidth = llmax(8,mArrowImage->getWidth()); // In case image hasn't loaded yet
+ mArrowImageWidth = llmax(8,mArrowImage->getWidth(0)); // In case image hasn't loaded yet
}
@@ -202,7 +202,7 @@ LLView* LLComboBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *
void LLComboBox::setEnabled(BOOL enabled)
{
- LLUICtrl::setEnabled(enabled);
+ LLView::setEnabled(enabled);
mButton->setEnabled(enabled);
}
@@ -477,14 +477,15 @@ void LLComboBox::showList()
mList->arrange( 192, llfloor((F32)window_size.mY / LLUI::sGLScaleFactor.mV[VY]) - 50 );
// Make sure that we can see the whole list
- LLRect floater_area_local;
- gFloaterView->localRectToOtherView(gFloaterView->getLocalSnapRect(), &floater_area_local, this);
+ LLRect root_view_local;
+ LLView* root_view = getRootView();
+ root_view->localRectToOtherView(root_view->getLocalRect(), &root_view_local, this);
LLRect rect = mList->getRect();
if (mListPosition == BELOW)
{
- if (rect.getHeight() <= -floater_area_local.mBottom)
+ if (rect.getHeight() <= -root_view_local.mBottom)
{
// Move rect so it hangs off the bottom of this view
rect.setLeftTopAndSize(0, 0, rect.getWidth(), rect.getHeight() );
@@ -492,44 +493,44 @@ void LLComboBox::showList()
else
{
// stack on top or bottom, depending on which has more room
- if (-floater_area_local.mBottom > floater_area_local.mTop - mRect.getHeight())
+ if (-root_view_local.mBottom > root_view_local.mTop - mRect.getHeight())
{
// Move rect so it hangs off the bottom of this view
- rect.setLeftTopAndSize(0, 0, rect.getWidth(), llmin(-floater_area_local.mBottom, rect.getHeight()));
+ rect.setLeftTopAndSize(0, 0, rect.getWidth(), llmin(-root_view_local.mBottom, rect.getHeight()));
}
else
{
// move rect so it stacks on top of this view (clipped to size of screen)
- rect.setOriginAndSize(0, mRect.getHeight(), rect.getWidth(), llmin(floater_area_local.mTop - mRect.getHeight(), rect.getHeight()));
+ rect.setOriginAndSize(0, mRect.getHeight(), rect.getWidth(), llmin(root_view_local.mTop - mRect.getHeight(), rect.getHeight()));
}
}
}
else // ABOVE
{
- if (rect.getHeight() <= floater_area_local.mTop - mRect.getHeight())
+ if (rect.getHeight() <= root_view_local.mTop - mRect.getHeight())
{
// move rect so it stacks on top of this view (clipped to size of screen)
- rect.setOriginAndSize(0, mRect.getHeight(), rect.getWidth(), llmin(floater_area_local.mTop - mRect.getHeight(), rect.getHeight()));
+ rect.setOriginAndSize(0, mRect.getHeight(), rect.getWidth(), llmin(root_view_local.mTop - mRect.getHeight(), rect.getHeight()));
}
else
{
// stack on top or bottom, depending on which has more room
- if (-floater_area_local.mBottom > floater_area_local.mTop - mRect.getHeight())
+ if (-root_view_local.mBottom > root_view_local.mTop - mRect.getHeight())
{
// Move rect so it hangs off the bottom of this view
- rect.setLeftTopAndSize(0, 0, rect.getWidth(), llmin(-floater_area_local.mBottom, rect.getHeight()));
+ rect.setLeftTopAndSize(0, 0, rect.getWidth(), llmin(-root_view_local.mBottom, rect.getHeight()));
}
else
{
// move rect so it stacks on top of this view (clipped to size of screen)
- rect.setOriginAndSize(0, mRect.getHeight(), rect.getWidth(), llmin(floater_area_local.mTop - mRect.getHeight(), rect.getHeight()));
+ rect.setOriginAndSize(0, mRect.getHeight(), rect.getWidth(), llmin(root_view_local.mTop - mRect.getHeight(), rect.getHeight()));
}
}
}
mList->setOrigin(rect.mLeft, rect.mBottom);
mList->reshape(rect.getWidth(), rect.getHeight());
- mList->translateIntoRect(floater_area_local, FALSE);
+ mList->translateIntoRect(root_view_local, FALSE);
// Make sure we didn't go off bottom of screen
S32 x, y;
@@ -656,7 +657,8 @@ void LLComboBox::onItemSelected(LLUICtrl* item, void *userdata)
void LLComboBox::onListFocusChanged(LLUICtrl* list, void* user_data)
{
LLComboBox *self = (LLComboBox *) list->getParent();
- if (!list->hasFocus())
+ // user not manipulating list or clicking on drop down button
+ if (!self->mList->hasFocus() && !self->mButton->hasMouseCapture())
{
//*HACK: store the original value explicitly somewhere, not just in label
LLString orig_selection = self->mAllowTextEntry ? self->mTextEntry->getText() : self->mButton->getLabelSelected();
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index f442855aca..146052538a 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -405,6 +405,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLString& name, const LLRect& rect,
mNumDynamicWidthColumns(0),
mTotalStaticColumnWidth(0),
mSortColumn(-1),
+ mSorted(TRUE),
mSortAscending(TRUE)
{
mItemListRect.setOriginAndSize(
@@ -623,22 +624,28 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos )
{
case ADD_TOP:
mItemList.push_front(item);
+ setSorted(FALSE);
break;
case ADD_SORTED:
- mSortColumn = 0;
- mSortAscending = TRUE;
+ if (mSortColumn == -1)
+ {
+ mSortColumn = 0;
+ mSortAscending = TRUE;
+ }
mItemList.push_back(item);
std::sort(mItemList.begin(), mItemList.end(), SortScrollListItem(mSortColumn, mSortAscending));
break;
case ADD_BOTTOM:
mItemList.push_back(item);
+ setSorted(FALSE);
break;
default:
llassert(0);
mItemList.push_back(item);
+ setSorted(FALSE);
break;
}
@@ -1094,7 +1101,7 @@ void LLScrollListCtrl::selectNextItem( BOOL extend_selection)
}
}
- if ((mCommitOnSelectionChange || mCommitOnKeyboardMovement))
+ if (mCommitOnKeyboardMovement)
{
onCommit();
}
@@ -1685,8 +1692,7 @@ BOOL LLScrollListCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
}
// always commit when mouse operation is completed inside list
- // this only needs to be done for lists that don't commit on selection change
- if (!mCommitOnSelectionChange && pointInView(x,y))
+ if (mItemListRect.pointInRect(x,y))
{
mSelectionChanged = FALSE;
onCommit();
@@ -2090,6 +2096,16 @@ void LLScrollListCtrl::commitIfChanged()
}
}
+void LLScrollListCtrl::setSorted(BOOL sorted)
+{
+ mSorted = sorted;
+}
+
+BOOL LLScrollListCtrl::isSorted()
+{
+ return mSorted;
+}
+
// Called by scrollbar
//static
void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar, void* userdata )
@@ -2102,10 +2118,11 @@ void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar, void
// First column is column 0
void LLScrollListCtrl::sortByColumn(U32 column, BOOL ascending)
{
- if (mSortColumn != column)
+ if (!mSorted || mSortColumn != column)
{
mSortColumn = column;
std::sort(mItemList.begin(), mItemList.end(), SortScrollListItem(mSortColumn, mSortAscending));
+ setSorted(TRUE);
}
// just reverse the list if changing sort order
@@ -2358,6 +2375,9 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
LLString sortname(columnname);
child->getAttributeString("sort", sortname);
+
+ BOOL sort_ascending = TRUE;
+ child->getAttributeBOOL("sort_ascending", sort_ascending);
LLString imagename;
child->getAttributeString("image", imagename);
@@ -2379,6 +2399,7 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
columns[index]["name"] = columnname;
columns[index]["sort"] = sortname;
+ columns[index]["sort_ascending"] = sort_ascending;
columns[index]["image"] = imagename;
columns[index]["label"] = labelname;
columns[index]["width"] = columnwidth;
@@ -2543,6 +2564,13 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos)
{
mDefaultColumn = 0;
}
+ // if no column name provided, just use ordinal as name
+ if (name.empty())
+ {
+ std::ostringstream new_name;
+ new_name << mColumnsIndexed.size();
+ name = new_name.str();
+ }
if (mColumns.find(name) == mColumns.end())
{
// Add column
@@ -2621,6 +2649,7 @@ void LLScrollListCtrl::onClickColumn(void *userdata)
U32 column_index = info->mIndex;
LLScrollListColumn* column = parent->mColumnsIndexed[info->mIndex];
+ bool ascending = column->mSortAscending;
if (column->mSortingColumn != column->mName)
{
if (parent->mColumns.find(column->mSortingColumn) != parent->mColumns.end())
@@ -2630,7 +2659,6 @@ void LLScrollListCtrl::onClickColumn(void *userdata)
}
}
- bool ascending = true;
if (column_index == parent->mSortColumn)
{
ascending = !parent->mSortAscending;
@@ -2715,6 +2743,7 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p
// Add any columns we don't already have
LLSD columns = value["columns"];
LLSD::array_const_iterator itor;
+ S32 col_index = 0 ;
for (itor = columns.beginArray(); itor != columns.endArray(); ++itor)
{
LLString column = (*itor)["column"].asString();
@@ -2723,21 +2752,39 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p
{
mDefaultColumn = 0;
}
- std::map<LLString, LLScrollListColumn>::iterator column_itor = mColumns.find(column);
- if (column_itor == mColumns.end())
+
+ LLScrollListColumn* columnp = NULL;
+
+ // empty columns strings index by ordinal
+ if (column.empty())
+ {
+ std::ostringstream new_name;
+ new_name << col_index;
+ column = new_name.str();
+ }
+
+ std::map<LLString, LLScrollListColumn>::iterator column_itor;
+ column_itor = mColumns.find(column);
+ if (column_itor != mColumns.end())
+ {
+ columnp = &column_itor->second;
+ }
+
+ // create new column on demand
+ if (!columnp)
{
LLSD new_column;
new_column["name"] = column;
new_column["label"] = column;
- new_column["width"] = 0;
+ new_column["width"] = (*itor)["width"];
addColumn(new_column);
- column_itor = mColumns.find(column);
+ columnp = &mColumns.find(column)->second;
new_item->setNumColumns(mColumns.size());
}
- S32 index = column_itor->second.mIndex;
- S32 width = column_itor->second.mWidth;
- LLFontGL::HAlign font_alignment = column_itor->second.mFontAlignment;
+ S32 index = columnp->mIndex;
+ S32 width = columnp->mWidth;
+ LLFontGL::HAlign font_alignment = columnp->mFontAlignment;
LLSD value = (*itor)["value"];
LLString fontname = (*itor)["font"].asString();
@@ -2770,11 +2817,13 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p
else
{
new_item->setColumn(index, new LLScrollListText(value.asString(), font, width, font_style, font_alignment));
- if (column_itor->second.mHeader && !value.asString().empty())
+ if (columnp->mHeader && !value.asString().empty())
{
- column_itor->second.mHeader->setHasResizableElement(TRUE);
+ columnp->mHeader->setHasResizableElement(TRUE);
}
}
+
+ col_index++;
}
S32 num_columns = mColumns.size();
@@ -2917,32 +2966,6 @@ LLColumnHeader::LLColumnHeader(const LLString& label, const LLRect &rect, LLScro
mAscendingText = "[LOW]...[HIGH](Ascending)";
mDescendingText = "[HIGH]...[LOW](Descending)";
- LLSD row;
- row["columns"][0]["column"] = "label";
- row["columns"][0]["value"] = mAscendingText.getString();
- row["columns"][0]["font"] = "SANSSERIF_SMALL";
- row["columns"][0]["width"] = 80;
-
- row["columns"][1]["column"] = "arrow";
- row["columns"][1]["type"] = "icon";
- row["columns"][1]["value"] = LLUI::sAssetsGroup->getString("up_arrow.tga");
- row["columns"][1]["width"] = 20;
-
- mList->addElement(row);
-
- row["columns"][0]["column"] = "label";
- row["columns"][0]["type"] = "text";
- row["columns"][0]["value"] = mDescendingText.getString();
- row["columns"][0]["font"] = "SANSSERIF_SMALL";
- row["columns"][0]["width"] = 80;
-
- row["columns"][1]["column"] = "arrow";
- row["columns"][1]["type"] = "icon";
- row["columns"][1]["value"] = LLUI::sAssetsGroup->getString("down_arrow.tga");
- row["columns"][1]["width"] = 20;
-
- mList->addElement(row);
-
mList->reshape(llmax(mList->getRect().getWidth(), 110, mRect.getWidth()), mList->getRect().getHeight());
// resize handles on left and right
@@ -2964,7 +2987,7 @@ void LLColumnHeader::draw()
{
if( getVisible() )
{
- mDrawArrow = !mColumn->mLabel.empty() && mColumn->mParentCtrl->getSortColumnName() == mColumn->mSortingColumn;
+ mDrawArrow = !mColumn->mLabel.empty() && mColumn->mParentCtrl->isSorted() && mColumn->mParentCtrl->getSortColumnName() == mColumn->mSortingColumn;
BOOL is_ascending = mColumn->mParentCtrl->getSortAscending();
mArrowImage = is_ascending ? LLUI::sImageProvider->getUIImageByID(LLUUID(LLUI::sAssetsGroup->getString("up_arrow.tga")))
@@ -3311,7 +3334,11 @@ void LLColumnHeader::setHasResizableElement(BOOL resizable)
void LLColumnHeader::enableResizeBar(BOOL enable)
{
- mResizeBar->setEnabled(enable);
+ // for now, dynamically spaced columns can't be resized
+ if (!mColumn->mDynamicWidth)
+ {
+ mResizeBar->setEnabled(enable);
+ }
}
BOOL LLColumnHeader::canResize()
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 7a0a32c87e..de9b58bd1e 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -142,6 +142,7 @@ public:
LLScrollListColumn() :
mName(""),
mSortingColumn(""),
+ mSortAscending(TRUE),
mLabel(""),
mWidth(-1),
mRelWidth(-1.0),
@@ -156,6 +157,7 @@ public:
LLScrollListColumn(LLString name, LLString label, S32 width, F32 relwidth) :
mName(name),
mSortingColumn(name),
+ mSortAscending(TRUE),
mLabel(label),
mWidth(width),
mRelWidth(relwidth),
@@ -176,6 +178,11 @@ public:
{
mSortingColumn = sd.get("sort").asString();
}
+ mSortAscending = TRUE;
+ if (sd.has("sort_ascending"))
+ {
+ mSortAscending = sd.get("sort_ascending").asBoolean();
+ }
mLabel = sd.get("label").asString();
if (sd.has("relwidth") && (F32)sd.get("relwidth").asReal() > 0)
{
@@ -210,6 +217,7 @@ public:
LLString mName;
LLString mSortingColumn;
+ BOOL mSortAscending;
LLString mLabel;
S32 mWidth;
F32 mRelWidth;
@@ -381,8 +389,10 @@ public:
// Returns FALSE if not found.
BOOL setSelectedByValue(LLSD value, BOOL selected);
- virtual BOOL isSelected(LLSD value);
+ BOOL isSorted();
+ virtual BOOL isSelected(LLSD value);
+
BOOL selectFirstItem();
BOOL selectNthItem( S32 index );
BOOL selectItemAt(S32 x, S32 y, MASK mask);
@@ -552,6 +562,7 @@ protected:
void selectItem(LLScrollListItem* itemp, BOOL single_select = TRUE);
void deselectItem(LLScrollListItem* itemp);
void commitIfChanged();
+ void setSorted(BOOL sorted);
protected:
S32 mCurIndex; // For get[First/Next]Data
@@ -615,6 +626,7 @@ protected:
S32 mSortColumn;
BOOL mSortAscending;
+ BOOL mSorted;
std::map<LLString, LLScrollListColumn> mColumns;
std::vector<LLScrollListColumn*> mColumnsIndexed;
diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp
index b3c49e81f1..8b5cd4690e 100644
--- a/indra/llui/llsliderctrl.cpp
+++ b/indra/llui/llsliderctrl.cpp
@@ -300,7 +300,7 @@ void LLSliderCtrl::onSliderCommit( LLUICtrl* caller, void *userdata )
void LLSliderCtrl::setEnabled(BOOL b)
{
- LLUICtrl::setEnabled( b );
+ LLView::setEnabled( b );
if( mLabelBox )
{
diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp
index fbd8335e6c..34363eb506 100644
--- a/indra/llui/llspinctrl.cpp
+++ b/indra/llui/llspinctrl.cpp
@@ -123,6 +123,23 @@ LLSpinCtrl::~LLSpinCtrl()
}
+F32 clamp_precision(F32 value, S32 decimal_precision)
+{
+ // pow() isn't perfect
+
+ F64 clamped_value = value;
+ for (S32 i = 0; i < decimal_precision; i++)
+ clamped_value *= 10.0;
+
+ clamped_value = llround((F32)clamped_value);
+
+ for (S32 i = 0; i < decimal_precision; i++)
+ clamped_value /= 10.0;
+
+ return (F32)clamped_value;
+}
+
+
// static
void LLSpinCtrl::onUpBtn( void *userdata )
{
@@ -131,6 +148,7 @@ void LLSpinCtrl::onUpBtn( void *userdata )
{
// use getValue()/setValue() to force reload from/to control
F32 val = (F32)self->getValue().asReal() + self->mIncrement;
+ val = clamp_precision(val, self->mPrecision);
val = llmin( val, self->mMaxValue );
if( self->mValidateCallback )
@@ -163,6 +181,7 @@ void LLSpinCtrl::onDownBtn( void *userdata )
if( self->getEnabled() )
{
F32 val = (F32)self->getValue().asReal() - self->mIncrement;
+ val = clamp_precision(val, self->mPrecision);
val = llmax( val, self->mMinValue );
if( self->mValidateCallback )
@@ -224,12 +243,13 @@ void LLSpinCtrl::clear()
}
+
void LLSpinCtrl::updateEditor()
{
LLLocale locale(LLLocale::USER_LOCALE);
// Don't display very small negative values as -0.000
- F32 displayed_value = (F32)floor(getValue().asReal() * pow(10.0, (F64)mPrecision) + 0.5) / (F32)pow(10.0, (F64)mPrecision);
+ F32 displayed_value = clamp_precision((F32)getValue().asReal(), mPrecision);
// if( S32( displayed_value * pow( 10, mPrecision ) ) == 0 )
// {
@@ -301,7 +321,7 @@ void LLSpinCtrl::setFocus(BOOL b)
void LLSpinCtrl::setEnabled(BOOL b)
{
- LLUICtrl::setEnabled( b );
+ LLView::setEnabled( b );
mEditor->setEnabled( b );
}
diff --git a/indra/mac_updater/mac_updater.cpp b/indra/mac_updater/mac_updater.cpp
index 52902ea819..4b56148f10 100644
--- a/indra/mac_updater/mac_updater.cpp
+++ b/indra/mac_updater/mac_updater.cpp
@@ -46,9 +46,8 @@ EventHandlerRef gEventHandler = NULL;
OSStatus gFailure = noErr;
Boolean gCancelled = false;
-char *gUserServer;
+char *gUpdateURL;
char *gProductName;
-char gUpdateURL[2048]; /* Flawfinder: ignore */
void *updatethreadproc(void*);
@@ -305,20 +304,13 @@ int curl_progress_callback_func(void *clientp,
int parse_args(int argc, char **argv)
{
- // Check for old-type arguments.
- if (2 == argc)
- {
- gUserServer = argv[1];
- return 0;
- }
-
int j;
for (j = 1; j < argc; j++)
{
- if ((!strcmp(argv[j], "-userserver")) && (++j < argc))
+ if ((!strcmp(argv[j], "-url")) && (++j < argc))
{
- gUserServer = argv[j];
+ gUpdateURL = argv[j];
}
else if ((!strcmp(argv[j], "-name")) && (++j < argc))
{
@@ -338,17 +330,17 @@ int main(int argc, char **argv)
//
// Process command line arguments
//
- gUserServer = NULL;
+ gUpdateURL = NULL;
gProductName = NULL;
parse_args(argc, argv);
- if (!gUserServer)
+ if (!gUpdateURL)
{
- llinfos << "Usage: mac_updater -userserver <server> [-name <product_name>] [-program <program_name>]" << llendl;
+ llinfos << "Usage: mac_updater -url <url> [-name <product_name>] [-program <program_name>]" << llendl;
exit(1);
}
else
{
- llinfos << "User server is: " << gUserServer << llendl;
+ llinfos << "Update url is: " << gUpdateURL << llendl;
if (gProductName)
{
llinfos << "Product name is: " << gProductName << llendl;
@@ -361,9 +353,6 @@ int main(int argc, char **argv)
llinfos << "Starting " << gProductName << " Updater" << llendl;
- // Build the URL to download the update
- snprintf(gUpdateURL, sizeof(gUpdateURL), "http://secondlife.com/update-macos.php?userserver=%s", gUserServer);
-
// Real UI...
OSStatus err;
IBNibRef nib = NULL;
diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings
index 784525aad4..54687b1a43 100644
--- a/indra/newview/English.lproj/InfoPlist.strings
+++ b/indra/newview/English.lproj/InfoPlist.strings
@@ -1,5 +1,5 @@
/* Localized versions of Info.plist keys */
CFBundleName = "Second Life";
-CFBundleShortVersionString = "Second Life version 1.14.0.1";
-CFBundleGetInfoString = "Second Life version 1.14.0.1, Copyright 2004-2007 Linden Research, Inc.";
+CFBundleShortVersionString = "Second Life version 1.15.0.2";
+CFBundleGetInfoString = "Second Life version 1.15.0.2, Copyright 2004-2007 Linden Research, Inc.";
diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist
index c7d430725f..0908e18a1a 100644
--- a/indra/newview/Info-SecondLife.plist
+++ b/indra/newview/Info-SecondLife.plist
@@ -32,7 +32,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
- <string>1.14.0.1</string>
+ <string>1.15.0.2</string>
<key>CSResourcesFileMapped</key>
<true/>
</dict>
diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt
index 49b199c0a4..4e6373d57e 100644
--- a/indra/newview/gpu_table.txt
+++ b/indra/newview/gpu_table.txt
@@ -22,8 +22,11 @@ ATI All-in-Wonder X1800 .*ATI.*All-in-Wonder X18.* 3
ATI All-in-Wonder X1900 .*ATI.*All-in-Wonder X19.* 3
ATI ASUS X1xxx .*ASUS X1.* 3
ATI Mobility Radeon X1xxx .*ATI.*Mobility.*X1.* 2
-ATI Mobility Radeon X3xx .*ATI.*Mobility.*X3.* 1
-ATI Mobility Radeon X6xx .*ATI.*Mobility.*X6.* 1
+// HACK: We crash on startup on some Mobility Radeon chips, with 1.15.0
+// in FMOD (!). Try defaulting them to class 0. JC
+ATI Mobility Radeon X3xx .*ATI.*Mobility.*X3.* 0
+ATI Mobility Radeon X6xx .*ATI.*Mobility.*X6.* 0
+ATI Mobility Radeon X7xx .*ATI.*Mobility.*X7.* 0
ATI Radeon OpenGL .*ATI.*Radeon OpenGL.* 3
ATI Diamond X1xxx .*ATI.*Diamond.*X1.* 3
ATI FireGL 5xxx .*ATI.*FireGL V5.* 3
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 3939c14dbb..13fa29e242 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -203,6 +203,9 @@ BOOL LLAgent::sDebugDisplayTarget = FALSE;
const F32 LLAgent::TYPING_TIMEOUT_SECS = 5.f;
+std::map<LLString, LLString> LLAgent::sTeleportErrorMessages;
+std::map<LLString, LLString> LLAgent::sTeleportProgressMessages;
+
class LLAgentFriendObserver : public LLFriendObserver
{
public:
@@ -5472,6 +5475,8 @@ bool LLAgent::teleportCore(bool is_local)
LLFloaterWorldMap::hide(NULL);
LLFloaterDirectory::hide(NULL);
+ gParcelMgr->deselectLand();
+
// Close all pie menus, deselect land, etc.
// Don't change the camera until we know teleport succeeded. JC
resetView(FALSE);
@@ -7197,4 +7202,57 @@ void LLAgent::observeFriends()
}
}
+void LLAgent::parseTeleportMessages(const LLString& xml_filename)
+{
+ LLXMLNodePtr root;
+ BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
+
+ if (!success || !root || !root->hasName( "teleport_messages" ))
+ {
+ llerrs << "Problem reading teleport string XML file: "
+ << xml_filename << llendl;
+ return;
+ }
+
+ for (LLXMLNode* message_set = root->getFirstChild();
+ message_set != NULL;
+ message_set = message_set->getNextSibling())
+ {
+ if ( !message_set->hasName("message_set") ) continue;
+
+ std::map<LLString, LLString> *teleport_msg_map = NULL;
+ LLString message_set_name;
+
+ if ( message_set->getAttributeString("name", message_set_name) )
+ {
+ //now we loop over all the string in the set and add them
+ //to the appropriate set
+ if ( message_set_name == "errors" )
+ {
+ teleport_msg_map = &sTeleportErrorMessages;
+ }
+ else if ( message_set_name == "progress" )
+ {
+ teleport_msg_map = &sTeleportProgressMessages;
+ }
+ }
+
+ if ( !teleport_msg_map ) continue;
+
+ LLString message_name;
+ for (LLXMLNode* message_node = message_set->getFirstChild();
+ message_node != NULL;
+ message_node = message_node->getNextSibling())
+ {
+ if ( message_node->hasName("message") &&
+ message_node->getAttributeString("name", message_name) )
+ {
+ (*teleport_msg_map)[message_name] =
+ message_node->getTextContents();
+ } //end if ( message exists and has a name)
+ } //end for (all message in set)
+ }//end for (all message sets in xml file)
+}
+
+
// EOF
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index d0bda5d46a..89d60709d5 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -672,6 +672,13 @@ public:
BOOL mForceMouselook;
+ static void parseTeleportMessages(const LLString& xml_filename);
+ //we should really define ERROR and PROGRESS enums here
+ //but I don't really feel like doing that, so I am just going
+ //to expose the mappings....yup
+ static std::map<LLString, LLString> sTeleportErrorMessages;
+ static std::map<LLString, LLString> sTeleportProgressMessages;
+
private:
ETeleportState mTeleportState;
LLString mTeleportMessage;
diff --git a/indra/newview/llcaphttpsender.cpp b/indra/newview/llcaphttpsender.cpp
new file mode 100644
index 0000000000..7928a5004c
--- /dev/null
+++ b/indra/newview/llcaphttpsender.cpp
@@ -0,0 +1,30 @@
+/**
+ * @file llcaphttpsender.cpp
+ * @brief Abstracts details of sending messages via UntrustedMessage cap.
+ *
+ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "linden_common.h"
+#include "llcaphttpsender.h"
+
+LLCapHTTPSender::LLCapHTTPSender(const std::string& cap) :
+ mCap(cap)
+{
+}
+
+//virtual
+void LLCapHTTPSender::send(const LLHost& host, const char* message,
+ const LLSD& body,
+ LLHTTPClient::ResponderPtr response) const
+{
+ llinfos << "LLCapHTTPSender::send: message " << message
+ << " to host " << host << llendl;
+ LLSD llsd;
+ llsd["message"] = message;
+ llsd["body"] = body;
+ LLHTTPClient::post(mCap, llsd, response);
+}
diff --git a/indra/newview/llcaphttpsender.h b/indra/newview/llcaphttpsender.h
new file mode 100644
index 0000000000..af71c66563
--- /dev/null
+++ b/indra/newview/llcaphttpsender.h
@@ -0,0 +1,30 @@
+/**
+ * @file llcaphttpsender.h
+ * @brief Abstracts details of sending messages via the
+ * UntrustedMessage capability.
+ *
+ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#ifndef LL_CAP_HTTP_SENDER_H
+#define LL_CAP_HTTP_SENDER_H
+
+#include "llhttpsender.h"
+
+class LLCapHTTPSender : public LLHTTPSender
+{
+public:
+ LLCapHTTPSender(const std::string& cap);
+
+ /** @brief Send message via UntrustedMessage capability with body,
+ call response when done */
+ virtual void send(const LLHost& host,
+ const char* message, const LLSD& body,
+ LLHTTPClient::ResponderPtr response) const;
+
+private:
+ std::string mCap;
+};
+
+#endif // LL_CAP_HTTP_SENDER_H
diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp
index 13e7fef4ec..41f8f1d714 100644
--- a/indra/newview/llcolorswatch.cpp
+++ b/indra/newview/llcolorswatch.cpp
@@ -226,7 +226,7 @@ void LLColorSwatchCtrl::draw()
void LLColorSwatchCtrl::setEnabled( BOOL enabled )
{
mCaption->setEnabled( enabled );
- LLUICtrl::setEnabled( enabled );
+ LLView::setEnabled( enabled );
if (!enabled)
{
diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp
index 2ad7eb6866..6d1c384b5a 100644
--- a/indra/newview/lleventpoll.cpp
+++ b/indra/newview/lleventpoll.cpp
@@ -1,163 +1,167 @@
-/**
+/**
* @file lleventpoll.cpp
- * @brief Implementation of the LLEventPoll class.
+ * @brief Implementation of the LLEventPoll class.
*
- * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc.
+ * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc.
* $License$
*/
#include "llviewerprecompiledheaders.h"
+#include "llagent.h"
#include "lleventpoll.h"
#include "llhttpclient.h"
-#include "llhttpnode.h"
#include "llsdserialize.h"
+#include "llviewerregion.h"
+#include "message.h"
+class LLEventPoll::Impl : LLHTTPClient::Responder
+{
+public:
+ static Impl& start(const std::string& pollURL);
+ void stop();
+
+private:
+ Impl(const std::string& pollURL);
+ ~Impl();
+
+ void makeRequest();
+ void handleMessage(const LLSD& content);
+ virtual void error(U32 status, const std::string& reason);
+ virtual void result(const LLSD& content);
+private:
+ typedef LLHTTPClient::ResponderPtr Ptr;
-class LLEventPoll::Impl : LLHTTPClient::Responder
+ Ptr mPtr;
+ bool mDone;
+
+ std::string mPollURL;
+ std::string mSender;
+
+ LLSD mAcknowledge;
+
+ // these are only here for debugging so we can see which poller is which
+ static int sCount;
+ int mCount;
+};
+
+//static
+LLEventPoll::Impl& LLEventPoll::Impl::start(
+ const std::string& pollURL)
{
-public:
- static Impl& start(
- const std::string& pollURL, const LLHTTPNode& treeRoot)
- {
- Impl* i = new Impl(pollURL, treeRoot);
- llinfos << "LLEventPoll::Impl::start <" << i->mCount << "> "
+ Impl* i = new Impl(pollURL);
+ llinfos << "LLEventPoll::Impl::start <" << i->mCount << "> "
<< pollURL << llendl;
- return *i;
- }
-
- void stop()
+ return *i;
+}
+
+void LLEventPoll::Impl::stop()
+{
+ lldebugs << "LLEventPoll::Impl::stop <" << mCount << "> "
+ << mPollURL << llendl;
+ // there should be a way to stop a LLHTTPClient request in progress
+ mDone = true;
+ mPtr = NULL;
+}
+
+int LLEventPoll::Impl::sCount = 0;
+
+LLEventPoll::Impl::Impl(const std::string& pollURL)
+ : mPtr(NULL), mDone(false),
+ mPollURL(pollURL),
+ mCount(++sCount)
+{
+ mPtr = this;
+ //extract host and port of simulator to set as sender
+ LLViewerRegion *regionp = gAgent.getRegion();
+ if (!regionp)
{
- lldebugs << "LLEventPoll::Impl::stop <" << mCount << "> "
- << mPollURL << llendl;
- // there should be a way to stop a LLHTTPClient request in progress
- mDone = true;
- mPtr = NULL;
+ llerrs << "LLEventPoll initialized before region is added." << llendl;
}
+ mSender = regionp->getHost().getIPandPort();
+ llinfos << "LLEventPoll initialized with sender " << mSender << llendl;
+ makeRequest();
+}
+
+LLEventPoll::Impl::~Impl()
+{
+ lldebugs << "LLEventPoll::Impl::~Impl <" << mCount << "> "
+ << mPollURL << llendl;
+}
+
+void LLEventPoll::Impl::makeRequest()
+{
+ LLSD request;
+ request["ack"] = mAcknowledge;
+ request["done"] = mDone;
-private:
- Impl(const std::string& pollURL, const LLHTTPNode& treeRoot)
- : mPtr(NULL), mDone(false),
- mPollURL(pollURL), mTreeRoot(treeRoot),
- mCount(++sCount)
- {
- mPtr = this;
- makeRequest();
- }
-
- ~Impl()
- {
- lldebugs << "LLEventPoll::Impl::~Impl <" << mCount << "> "
- << mPollURL << llendl;
- }
+ lldebugs << "LLEventPoll::Impl::makeRequest <" << mCount << "> ack = "
+ << LLSDXMLStreamer(mAcknowledge) << llendl;
+ LLHTTPClient::post(mPollURL, request, mPtr);
+}
+
+void LLEventPoll::Impl::handleMessage(const LLSD& content)
+{
+ std::string msg_name = content["message"];
+ LLSD message;
+ message["sender"] = mSender;
+ message["body"] = content["body"];
+ LLMessageSystem::dispatch(msg_name, message);
+}
+//virtual
+void LLEventPoll::Impl::error(U32 status, const std::string& reason)
+{
+ if (mDone) return;
- void makeRequest()
+ if(status != 499)
{
- LLSD request;
- request["ack"] = mAcknowledge;
- request["done"] = mDone;
-
- lldebugs << "LLEventPoll::Impl::makeRequest <" << mCount << "> ack = "
- << LLSDXMLStreamer(mAcknowledge) << llendl;
- LLHTTPClient::post(mPollURL, request, mPtr);
+ llwarns << "LLEventPoll::Impl::error: <" << mCount << "> got "
+ << status << ": " << reason
+ << (mDone ? " -- done" : "") << llendl;
+ stop();
+ return;
}
+
+ makeRequest();
+}
+
+//virtual
+void LLEventPoll::Impl::result(const LLSD& content)
+{
+ lldebugs << "LLEventPoll::Impl::result <" << mCount << ">"
+ << (mDone ? " -- done" : "") << llendl;
- void handleMessage(const LLSD& content)
- {
- std::string message = content["message"];
- if (message.empty())
- {
- llwarns << "LLEventPoll::Impl::handleMessage <" << mCount
- << "> empty message name" << llendl;
- return;
- }
-
- std::string path = "/message/" + message;
-
- LLSD context;
- const LLHTTPNode* handler = mTreeRoot.traverse(path, context);
- if (!handler)
- {
- llwarns << "LLEventPoll::Impl::handleMessage <" << mCount
- << "> no handler for " << path << llendl;
- return;
- }
- LLPointer<LLSimpleResponse> responsep = LLSimpleResponse::create();
- handler->post((LLHTTPNode::ResponsePtr)responsep, context, content["body"]);
-
- lldebugs << "LLEventPoll::Impl::handleMessage handled <" << mCount << "> "
- << message << ": " << *responsep << llendl;
- }
+ if (mDone) return;
+
+ mAcknowledge = content["id"];
+ LLSD events = content["events"];
- virtual void error(U32 status, const std::string& reason)
+ if(mAcknowledge.isUndefined())
{
- lldebugs << "LLEventPoll::Impl::error <" << mCount << "> got "
- << status << ": " << reason
- << (mDone ? " -- done" : "") << llendl;
-
- if (mDone) return;
-
- if (status == 404)
- {
- // the capability has been revoked
- stop();
- return;
- }
-
- makeRequest();
+ llwarns << "LLEventPoll::Impl: id undefined" << llendl;
}
+ llinfos << "LLEventPoll::Impl::completed <" << mCount << "> " << events.size() << "events (id "
+ << LLSDXMLStreamer(mAcknowledge) << ")" << llendl;
- virtual void result(const LLSD& content)
+ LLSD::array_const_iterator i = events.beginArray();
+ LLSD::array_const_iterator end = events.endArray();
+ for (; i != end; ++i)
{
- lldebugs << "LLEventPoll::Impl::result <" << mCount << ">"
- << (mDone ? " -- done" : "") << llendl;
-
- if (mDone) return;
-
- mAcknowledge = content["id"];
- LLSD events = content["events"];
-
- lldebugs << "LLEventPoll::Impl::completed <" << mCount << "> ack = "
- << LLSDXMLStreamer(mAcknowledge) << llendl;
-
- LLSD::array_const_iterator i = events.beginArray();
- LLSD::array_const_iterator end = events.endArray();
- for (; i != end; ++i)
+ if (i->has("message"))
{
- if (i->has("message"))
- {
- handleMessage(*i);
- }
+ handleMessage(*i);
}
-
- makeRequest();
}
-
-private:
- typedef LLHTTPClient::ResponderPtr Ptr;
-
- Ptr mPtr;
- bool mDone;
-
- std::string mPollURL;
- const LLHTTPNode& mTreeRoot;
- LLSD mAcknowledge;
-
- // these are only here for debugging so we can see which poller is which
- static int sCount;
- int mCount;
-};
-
-int LLEventPoll::Impl::sCount = 0;
-
+ makeRequest();
+}
-LLEventPoll::LLEventPoll(const std::string& pollURL, const LLHTTPNode& treeRoot)
- : impl(Impl::start(pollURL, treeRoot))
+LLEventPoll::LLEventPoll(const std::string& pollURL)
+ : impl(Impl::start(pollURL))
{ }
LLEventPoll::~LLEventPoll()
diff --git a/indra/newview/lleventpoll.h b/indra/newview/lleventpoll.h
index c5024b2b95..c2d798360f 100644
--- a/indra/newview/lleventpoll.h
+++ b/indra/newview/lleventpoll.h
@@ -9,20 +9,12 @@
#ifndef LL_LLEVENTPOLL_H
#define LL_LLEVENTPOLL_H
-class LLHTTPNode;
-
-
class LLEventPoll
///< implements the viewer side of server-to-viewer pushed events.
{
public:
- LLEventPoll(const std::string& pollURL, const LLHTTPNode& treeRoot);
- /**< Start polling the URL.
-
- The object will automatically responde to events
- by calling handlers in the tree.
- */
-
+ LLEventPoll(const std::string& pollURL);
+ ///< Start polling the URL.
virtual ~LLEventPoll();
///< will stop polling, cancelling any poll in progress.
diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp
index 12891bd7b2..bc2c340999 100644
--- a/indra/newview/llfloaterauction.cpp
+++ b/indra/newview/llfloaterauction.cpp
@@ -57,12 +57,6 @@ LLFloaterAuction::LLFloaterAuction() :
childSetCommitCallback("fence_check",
LLSavedSettingsGlue::setBOOL, (void*)"AuctionShowFence");
- LLComboBox* combo = LLUICtrlFactory::getComboBoxByName(this, "saletype_combo");
- if (combo)
- {
- combo->selectFirstItem();
- }
-
childSetAction("snapshot_btn", onClickSnapshot, this);
childSetAction("ok_btn", onClickOK, this);
}
@@ -196,28 +190,18 @@ void LLFloaterAuction::onClickSnapshot(void* data)
void LLFloaterAuction::onClickOK(void* data)
{
LLFloaterAuction* self = (LLFloaterAuction*)(data);
- bool is_auction = false;
- LLComboBox* combo = LLUICtrlFactory::getComboBoxByName(self, "saletype_combo");
- if (combo
- && combo->getCurrentIndex() == 0)
- {
- is_auction = true;
- }
+
if(self->mImageID.notNull())
{
LLSD parcel_name = self->childGetValue("parcel_text");
- // create the asset
- if(is_auction)
- {
- // only need the tga if it is an auction.
- LLString* name = new LLString(parcel_name.asString());
- gAssetStorage->storeAssetData(self->mTransactionID, LLAssetType::AT_IMAGE_TGA,
- &auction_tga_upload_done,
- (void*)name,
- FALSE);
- self->getWindow()->incBusyCount();
- }
+ // create the asset
+ LLString* name = new LLString(parcel_name.asString());
+ gAssetStorage->storeAssetData(self->mTransactionID, LLAssetType::AT_IMAGE_TGA,
+ &auction_tga_upload_done,
+ (void*)name,
+ FALSE);
+ self->getWindow()->incBusyCount();
LLString* j2c_name = new LLString(parcel_name.asString());
gAssetStorage->storeAssetData(self->mTransactionID, LLAssetType::AT_TEXTURE,
@@ -226,24 +210,13 @@ void LLFloaterAuction::onClickOK(void* data)
FALSE);
self->getWindow()->incBusyCount();
- if(is_auction)
- {
- LLNotifyBox::showXml("UploadingAuctionSnapshot");
- }
- else
- {
- LLNotifyBox::showXml("UploadingSnapshot");
- }
+ LLNotifyBox::showXml("UploadingAuctionSnapshot");
+
}
LLMessageSystem* msg = gMessageSystem;
- if(is_auction)
- {
- msg->newMessage("ViewerStartAuction");
- }
- else
- {
- msg->newMessage("ParcelGodReserveForNewbie");
- }
+
+ msg->newMessage("ViewerStartAuction");
+
msg->nextBlock("AgentData");
msg->addUUID("AgentID", gAgent.getID());
msg->addUUID("SessionID", gAgent.getSessionID());
diff --git a/indra/newview/llfloaterbump.cpp b/indra/newview/llfloaterbump.cpp
index 68f002f9d9..9beaa82cb9 100644
--- a/indra/newview/llfloaterbump.cpp
+++ b/indra/newview/llfloaterbump.cpp
@@ -65,7 +65,7 @@ void LLFloaterBump::show(void *contents)
LLString none_detected = sInstance->childGetText("none_detected");
LLSD row;
row["columns"][0]["value"] = none_detected;
- row["columns"][0]["font-style"] = "BOLD";
+ row["columns"][0]["font"] = "SansSerifBold";
list->addElement(row);
}
else
@@ -136,6 +136,6 @@ void LLFloaterBump::add(LLScrollListCtrl* list, LLMeanCollisionData* mcd)
LLSD row;
row["id"] = mcd->mPerp;
row["columns"][0]["value"] = text;
- row["columns"][0]["font-style"] = "BOLD";
+ row["columns"][0]["font"] = "SansSerifBold";
list->addElement(row);
}
diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp
index 1ee8cd62ab..7ed84e495a 100644
--- a/indra/newview/llfloaterbuyland.cpp
+++ b/indra/newview/llfloaterbuyland.cpp
@@ -75,7 +75,6 @@ private:
// information about the parcel
bool mParcelValid;
bool mParcelIsForSale;
- bool mParcelIsFirstLand;
bool mParcelIsGroupLand;
S32 mParcelGroupContribution;
S32 mParcelPrice;
@@ -352,7 +351,6 @@ void LLFloaterBuyLandUI::updateParcelInfo()
LLParcel* parcel = mParcel->getParcel();
mParcelValid = parcel && mRegion;
mParcelIsForSale = false;
- mParcelIsFirstLand = false;
mParcelIsGroupLand = false;
mParcelGroupContribution = 0;
mParcelPrice = 0;
@@ -386,7 +384,6 @@ void LLFloaterBuyLandUI::updateParcelInfo()
{
mParcelActualArea = parcel->getArea();
mParcelIsForSale = parcel->getForSale();
- mParcelIsFirstLand = parcel->getReservedForNewbie();
mParcelIsGroupLand = parcel->getIsGroupOwned();
mParcelPrice = mParcelIsForSale ? parcel->getSalePrice() : 0;
@@ -493,36 +490,6 @@ void LLFloaterBuyLandUI::updateParcelInfo()
}
}
- /*
- if ((mRegion->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
- && !gAgent.isGodlike())
- {
- mCannotBuyReason = llformat(
- "The region %s does not allow transfer of land.",
- mRegion->getName().c_str() );
- return;
- }
- */
-
- if (parcel->getReservedForNewbie())
- {
- if (mIsForGroup)
- {
- mCannotBuyReason = childGetText("first_time_group");
- return;
- }
-
- if (gStatusBar->getSquareMetersCommitted() > 0)
- {
- mCannotBuyReason == childGetText("first_time");
- return;
- }
-
- // *TODO: There should be a check based on the database value
- // indra.user.ever_owned_land, only that value never makes it
- // to the viewer, see SL-10728
- }
-
mCanBuy = true;
}
@@ -1143,17 +1110,6 @@ void LLFloaterBuyLandUI::refreshUI()
message += childGetText("insufficient_land_credits");
}
- else if (mAgentHasNeverOwnedLand)
- {
- if (mParcelIsFirstLand)
- {
- message += childGetText("first_purchase");
- }
- else
- {
- message += childGetText("first_time_but_not_first_land");
- }
- }
else
{
diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp
index 534aac077f..1e65ae5620 100644
--- a/indra/newview/llfloaterfriends.cpp
+++ b/indra/newview/llfloaterfriends.cpp
@@ -501,14 +501,11 @@ void LLFloaterFriends::onClickIM(void* user_data)
}
else
{
- LLUUID session_id;
- session_id.generate();
gIMView->setFloaterOpen(TRUE);
- gIMView->addSession(
- "Friends Conference",
- IM_SESSION_ADD,
- session_id,
- ids);
+ gIMView->addSession("Friends Conference",
+ IM_SESSION_CONFERENCE_START,
+ ids[0],
+ ids);
}
}
}
diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp
index 8bb73e3a9b..1548c0e5d6 100644
--- a/indra/newview/llfloaterinspect.cpp
+++ b/indra/newview/llfloaterinspect.cpp
@@ -218,4 +218,3 @@ void LLFloaterInspect::draw()
LLFloater::draw();
}
-
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 9b28211476..51a1a99d71 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -793,10 +793,6 @@ void LLPanelLandGeneral::refreshNames()
mSaleInfoForSale2->setTextArg("[BUYER]", name);
}
- else if(parcel->getReservedForNewbie())
- {
- mSaleInfoForSale2->setTextArg("[BUYER]", childGetText("new users only"));
- }
else
{
mSaleInfoForSale2->setTextArg("[BUYER]", childGetText("anyone"));
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 9a486d76ee..8968da9720 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -40,7 +40,6 @@
#include "llviewerobject.h"
#include "llviewerregion.h"
#include "llcombobox.h"
-#include "llfloaterrate.h"
#include "lltooldraganddrop.h"
#include "llfloatermap.h"
#include "lluiconstants.h"
diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp
index f7bf4de34f..b71772bd93 100644
--- a/indra/newview/llfloatertos.cpp
+++ b/indra/newview/llfloatertos.cpp
@@ -162,6 +162,7 @@ BOOL LLFloaterTOS::postBuild()
childSetValue("tos_text", LLSD(mMessage));
#endif
+
return TRUE;
}
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 9ab9a3f6bb..7c03500f85 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -55,40 +55,171 @@ const S32 MIN_HEIGHT = 130;
//
static LLString sTitleString = "Instant Message with [NAME]";
static LLString sTypingStartString = "[NAME]: ...";
+static LLString sSessionStartString = "Starting session with [NAME] please wait.";
+
+void session_starter_helper(const LLUUID& temp_session_id,
+ const LLUUID& other_participant_id,
+ EInstantMessage im_type)
+{
+ LLMessageSystem *msg = gMessageSystem;
+
+ msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+
+ msg->nextBlockFast(_PREHASH_MessageBlock);
+ msg->addBOOLFast(_PREHASH_FromGroup, FALSE);
+ msg->addUUIDFast(_PREHASH_ToAgentID, other_participant_id);
+ msg->addU8Fast(_PREHASH_Offline, IM_ONLINE);
+ msg->addU8Fast(_PREHASH_Dialog, im_type);
+ msg->addUUIDFast(_PREHASH_ID, temp_session_id);
+ msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary
+
+ std::string name;
+ gAgent.buildFullname(name);
+
+ msg->addStringFast(_PREHASH_FromAgentName, name);
+ msg->addStringFast(_PREHASH_Message, LLString::null);
+ msg->addU32Fast(_PREHASH_ParentEstateID, 0);
+ msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null);
+ msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
+}
+
+// Returns true if any messages were sent, false otherwise.
+// Is sort of equivalent to "does the server need to do anything?"
+bool send_start_session_messages(const LLUUID& temp_session_id,
+ const LLUUID& other_participant_id,
+ const LLDynamicArray<LLUUID>& ids,
+ EInstantMessage dialog)
+{
+ if ( (dialog == IM_SESSION_911_START) ||
+ (dialog == IM_SESSION_GROUP_START) ||
+ (dialog == IM_SESSION_CONFERENCE_START) )
+ {
+ S32 count = ids.size();
+ S32 bucket_size = UUID_BYTES * count;
+ U8* bucket;
+ U8* pos;
+
+ session_starter_helper(temp_session_id,
+ other_participant_id,
+ dialog);
+
+ switch(dialog)
+ {
+ case IM_SESSION_GROUP_START:
+ case IM_SESSION_911_START:
+ gMessageSystem->addBinaryDataFast(_PREHASH_BinaryBucket,
+ EMPTY_BINARY_BUCKET,
+ EMPTY_BINARY_BUCKET_SIZE);
+ break;
+ case IM_SESSION_CONFERENCE_START:
+ bucket = new U8[bucket_size];
+ pos = bucket;
+
+ // *FIX: this could suffer from endian issues
+ for(S32 i = 0; i < count; ++i)
+ {
+ memcpy(pos, &(ids.get(i)), UUID_BYTES);
+ pos += UUID_BYTES;
+ }
+ gMessageSystem->addBinaryDataFast(_PREHASH_BinaryBucket,
+ bucket,
+ bucket_size);
+ delete[] bucket;
+
+ break;
+ default:
+ break;
+ }
+ gAgent.sendReliableMessage();
+
+ return true;
+ }
+
+ return false;
+}
// Member Functions
//
-LLFloaterIMPanel::LLFloaterIMPanel(const std::string& name, const LLRect& rect,
- const std::string& session_label,
- const LLUUID& session_id,
- const LLUUID& other_participant_id,
- EInstantMessage dialog) :
+LLFloaterIMPanel::LLFloaterIMPanel(const std::string& name,
+ const LLRect& rect,
+ const std::string& session_label,
+ const LLUUID& session_id,
+ const LLUUID& other_participant_id,
+ EInstantMessage dialog) :
+ LLFloater(name, rect, session_label),
+ mInputEditor(NULL),
+ mHistoryEditor(NULL),
+ mSessionUUID(session_id),
+ mOtherParticipantUUID(other_participant_id),
+ mDialog(dialog),
+ mTyping(FALSE),
+ mOtherTyping(FALSE),
+ mTypingLineStartIndex(0),
+ mSentTypingState(TRUE),
+ mFirstKeystrokeTimer(),
+ mLastKeystrokeTimer(),
+ mSessionInitialized(FALSE),
+ mSessionInitRequested(FALSE)
+{
+ init(session_label);
+}
+
+LLFloaterIMPanel::LLFloaterIMPanel(const std::string& name,
+ const LLRect& rect,
+ const std::string& session_label,
+ const LLUUID& session_id,
+ const LLUUID& other_participant_id,
+ const LLDynamicArray<LLUUID>& ids,
+ EInstantMessage dialog) :
LLFloater(name, rect, session_label),
mInputEditor(NULL),
mHistoryEditor(NULL),
- mSessionLabel(session_label),
mSessionUUID(session_id),
mOtherParticipantUUID(other_participant_id),
- mLureID(),
mDialog(dialog),
mTyping(FALSE),
mOtherTyping(FALSE),
mTypingLineStartIndex(0),
mSentTypingState(TRUE),
mFirstKeystrokeTimer(),
- mLastKeystrokeTimer()
+ mLastKeystrokeTimer(),
+ mSessionInitialized(FALSE),
+ mSessionInitRequested(FALSE)
+{
+ init(session_label);
+
+ mSessionInitialTargetIDs = ids;
+}
+
+
+void LLFloaterIMPanel::init(const LLString& session_label)
{
- init();
+ gUICtrlFactory->buildFloater(this,
+ "floater_instant_message.xml",
+ NULL,
+ FALSE);
+
setLabel(session_label);
setTitle(session_label);
mInputEditor->setMaxTextLength(1023);
-}
+ if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
+ {
+ LLLogChat::loadHistory(session_label,
+ &chatFromLogFile,
+ (void *)this);
+ }
-void LLFloaterIMPanel::init()
-{
- gUICtrlFactory->buildFloater(this, "floater_instant_message.xml", NULL, FALSE);
+ if(IM_SESSION_911_START == mDialog)
+ {
+ LLTextBox* live_help_text =
+ LLUICtrlFactory::getTextBoxByName(this, "live_help_dialog");
+ addHistoryLine(live_help_text->getText());
+ }
}
@@ -101,6 +232,8 @@ BOOL LLFloaterIMPanel::postBuild()
requires("live_help_dialog", WIDGET_TYPE_TEXT_BOX);
requires("title_string", WIDGET_TYPE_TEXT_BOX);
requires("typing_start_string", WIDGET_TYPE_TEXT_BOX);
+ requires("session_start_string", WIDGET_TYPE_TEXT_BOX);
+ requires("teleport_btn", WIDGET_TYPE_BUTTON);
if (checkRequirements())
{
@@ -118,24 +251,19 @@ BOOL LLFloaterIMPanel::postBuild()
LLButton* close_btn = LLUICtrlFactory::getButtonByName(this, "close_btn");
close_btn->setClickedCallback(&LLFloaterIMPanel::onClickClose, this);
+ LLButton* tp_btn = LLUICtrlFactory::getButtonByName(this, "teleport_btn");
+ tp_btn->setClickedCallback(&LLFloaterIMPanel::onTeleport, this);
+ tp_btn->setVisible(FALSE);
+ tp_btn->setEnabled(FALSE);
+
mHistoryEditor = LLViewerUICtrlFactory::getViewerTextEditorByName(this, "im_history");
mHistoryEditor->setParseHTML(TRUE);
- if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
- {
- LLLogChat::loadHistory(mSessionLabel, &chatFromLogFile, (void *)this);
- }
if (IM_SESSION_GROUP_START == mDialog
|| IM_SESSION_911_START == mDialog)
{
profile_btn->setEnabled(FALSE);
- if(IM_SESSION_911_START == mDialog)
- {
- LLTextBox* live_help_text = LLUICtrlFactory::getTextBoxByName(this, "live_help_dialog");
- addHistoryLine(live_help_text->getText());
- }
}
-
LLTextBox* title = LLUICtrlFactory::getTextBoxByName(this, "title_string");
sTitleString = title->getText();
@@ -143,6 +271,11 @@ BOOL LLFloaterIMPanel::postBuild()
sTypingStartString = typing_start->getText();
+ LLTextBox* session_start = LLUICtrlFactory::getTextBoxByName(
+ this,
+ "session_start_string");
+ sSessionStartString = session_start->getText();
+
return TRUE;
}
@@ -176,12 +309,14 @@ void LLFloaterIMPanel::draw()
BOOL LLFloaterIMPanel::addParticipants(const LLDynamicArray<LLUUID>& ids)
{
- if(isAddAllowed())
+ S32 count = ids.count();
+
+ if( isAddAllowed() && (count > 0) )
{
llinfos << "LLFloaterIMPanel::addParticipants() - adding participants" << llendl;
const S32 MAX_AGENTS = 50;
- S32 count = ids.count();
if(count > MAX_AGENTS) return FALSE;
+
LLMessageSystem *msg = gMessageSystem;
msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
msg->nextBlockFast(_PREHASH_AgentData);
@@ -191,7 +326,7 @@ BOOL LLFloaterIMPanel::addParticipants(const LLDynamicArray<LLUUID>& ids)
msg->addBOOLFast(_PREHASH_FromGroup, FALSE);
msg->addUUIDFast(_PREHASH_ToAgentID, mOtherParticipantUUID);
msg->addU8Fast(_PREHASH_Offline, IM_ONLINE);
- msg->addU8Fast(_PREHASH_Dialog, mDialog);
+ msg->addU8Fast(_PREHASH_Dialog, IM_SESSION_ADD);
msg->addUUIDFast(_PREHASH_ID, mSessionUUID);
msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary
std::string name;
@@ -201,57 +336,21 @@ BOOL LLFloaterIMPanel::addParticipants(const LLDynamicArray<LLUUID>& ids)
msg->addU32Fast(_PREHASH_ParentEstateID, 0);
msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null);
msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
- if (IM_SESSION_GROUP_START == mDialog)
- {
- // *HACK: binary bucket contains session label - the server
- // will actually add agents.
- llinfos << "Group IM session name '" << mSessionLabel
- << "'" << llendl;
- msg->addStringFast(_PREHASH_BinaryBucket, mSessionLabel);
- gAgent.sendReliableMessage();
- }
- else if (IM_SESSION_911_START == mDialog)
- {
- // HACK -- we modify the name of the session going out to
- // the helpers to help them easily identify "Help"
- // sessions in their collection of IM panels.
- LLString name;
- gAgent.getName(name);
- LLString buffer = LLString("HELP ") + name;
- llinfos << "LiveHelp IM session '" << buffer << "'." << llendl;
- msg->addStringFast(_PREHASH_BinaryBucket, buffer.c_str());
-
- // automaticaly open a wormhole when this reliable message gets through
- msg->sendReliable(
- gAgent.getRegionHost(),
- 3, // retries
- TRUE, // ping-based
- 5.0f, // timeout
- send_lure_911,
- (void**)&mSessionUUID);
- }
- else
+
+ // *FIX: this could suffer from endian issues
+ S32 bucket_size = UUID_BYTES * count;
+ U8* bucket = new U8[bucket_size];
+ U8* pos = bucket;
+ for(S32 i = 0; i < count; ++i)
{
- if (mDialog != IM_SESSION_ADD
- && mDialog != IM_SESSION_OFFLINE_ADD)
- {
- llwarns << "LLFloaterIMPanel::addParticipants() - dialog type " << mDialog
- << " is not an ADD" << llendl;
- }
- // *FIX: this could suffer from endian issues
- S32 bucket_size = UUID_BYTES * count;
- U8* bucket = new U8[bucket_size];
- U8* pos = bucket;
- for(S32 i = 0; i < count; ++i)
- {
- memcpy(pos, &(ids.get(i)), UUID_BYTES); /* Flawfinder: ignore */
- pos += UUID_BYTES;
- }
- msg->addBinaryDataFast(_PREHASH_BinaryBucket, bucket, bucket_size);
- delete[] bucket;
- gAgent.sendReliableMessage();
+ memcpy(pos, &(ids.get(i)), UUID_BYTES);
+ pos += UUID_BYTES;
}
-
+ msg->addBinaryDataFast(_PREHASH_BinaryBucket,
+ bucket,
+ bucket_size);
+ delete[] bucket;
+ gAgent.sendReliableMessage();
}
else
{
@@ -260,6 +359,7 @@ BOOL LLFloaterIMPanel::addParticipants(const LLDynamicArray<LLUUID>& ids)
// successful add, because everyone that needed to get added
// was added.
}
+
return TRUE;
}
@@ -293,7 +393,7 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4
{
LLString histstr = timestring + utf8msg;
- LLLogChat::saveHistory(mSessionLabel,histstr);
+ LLLogChat::saveHistory(getTitle(),histstr);
}
}
@@ -455,11 +555,8 @@ BOOL LLFloaterIMPanel::dropCategory(LLInventoryCategory* category, BOOL drop)
BOOL LLFloaterIMPanel::isAddAllowed() const
{
- return ((IM_SESSION_ADD == mDialog)
- || (IM_SESSION_OFFLINE_ADD == mDialog)
- || (IM_SESSION_GROUP_START == mDialog)
- || (IM_SESSION_911_START == mDialog)
- || (IM_SESSION_CARDLESS_START == mDialog));
+ return ((IM_SESSION_CONFERENCE_START == mDialog)
+ || (IM_SESSION_ADD) );
}
@@ -493,72 +590,36 @@ void LLFloaterIMPanel::onClickClose( void* userdata )
}
}
-void LLFloaterIMPanel::addTeleportButton(const LLUUID& lure_id)
+void LLFloaterIMPanel::addTeleportButton()
{
- LLButton* btn = LLViewerUICtrlFactory::getButtonByName(this, "Teleport Btn");
- if (!btn)
- {
- S32 BTN_VPAD = 2;
- S32 BTN_HPAD = 2;
+ LLButton* btn =
+ LLViewerUICtrlFactory::getButtonByName(this, "teleport_btn");
- const char* teleport_label = "Teleport";
-
- const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF );
- S32 p_btn_width = 75;
- S32 c_btn_width = 60;
- S32 t_btn_width = 75;
-
- // adjust the size of the editor to make room for the new button
+ if ( !btn->getEnabled() )
+ {
+ //it's required, don't need to check for null here
+ // adjust the size of the editor to make room for the button
LLRect rect = mInputEditor->getRect();
- S32 editor_right = rect.mRight - t_btn_width;
+ S32 editor_right = rect.mRight - btn->getRect().getWidth();
rect.mRight = editor_right;
mInputEditor->reshape(rect.getWidth(), rect.getHeight(), FALSE);
mInputEditor->setRect(rect);
-
- const S32 IMPANEL_PAD = 1 + LLPANEL_BORDER_WIDTH;
- const S32 IMPANEL_INPUT_HEIGHT = 20;
-
- rect.setLeftTopAndSize(
- mRect.getWidth() - IMPANEL_PAD - p_btn_width - c_btn_width - t_btn_width - BTN_HPAD - RESIZE_HANDLE_WIDTH,
- IMPANEL_INPUT_HEIGHT + IMPANEL_PAD - BTN_VPAD,
- t_btn_width,
- BTN_HEIGHT);
-
- btn = new LLButton(
- "Teleport Btn", rect,
- "","", "",
- &LLFloaterIMPanel::onTeleport, this,
- font, teleport_label, teleport_label );
-
- btn->setFollowsBottom();
- btn->setFollowsRight();
- addChild( btn );
- }
- btn->setEnabled(TRUE);
- mLureID = lure_id;
-}
-void LLFloaterIMPanel::removeTeleportButton()
-{
- // TODO -- purge the button
- LLButton* btn = LLViewerUICtrlFactory::getButtonByName(this, "Teleport Btn");
- if (btn)
- {
- btn->setEnabled(FALSE);
+ btn->setVisible(TRUE);
+ btn->setEnabled(TRUE);
}
}
-// static
+// static
void LLFloaterIMPanel::onTeleport(void* userdata)
{
LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
if(self)
{
- send_simple_im(self->mLureID,
- "",
- IM_LURE_911,
- LLUUID::null);
- self->removeTeleportButton();
+ send_simple_im(self->mSessionUUID, //to
+ "",
+ IM_TELEPORT_911,
+ self->mSessionUUID);//session
}
}
@@ -618,6 +679,44 @@ void LLFloaterIMPanel::onClose(bool app_quitting)
destroy();
}
+void deliver_message(const std::string& utf8_text,
+ const LLUUID& im_session_id,
+ const LLUUID& other_participant_id,
+ EInstantMessage dialog)
+{
+ std::string name;
+ gAgent.buildFullname(name);
+
+ const LLRelationship* info = NULL;
+ info = LLAvatarTracker::instance().getBuddyInfo(other_participant_id);
+ U8 offline = (!info || info->isOnline()) ? IM_ONLINE : IM_OFFLINE;
+
+ // default to IM_SESSION_SEND unless it's nothing special - in
+ // which case it's probably an IM to everyone.
+ U8 new_dialog = dialog;
+
+ if ( dialog == IM_SESSION_911_START )
+ {
+ new_dialog = IM_SESSION_911_SEND;
+ }
+ else if ( dialog != IM_NOTHING_SPECIAL )
+ {
+ new_dialog = IM_SESSION_SEND;
+ }
+
+ pack_instant_message(
+ gMessageSystem,
+ gAgent.getID(),
+ FALSE,
+ gAgent.getSessionID(),
+ other_participant_id,
+ name.c_str(),
+ utf8_text.c_str(),
+ offline,
+ (EInstantMessage)new_dialog,
+ im_session_id);
+ gAgent.sendReliableMessage();
+}
void LLFloaterIMPanel::sendMsg()
{
@@ -635,50 +734,82 @@ void LLFloaterIMPanel::sendMsg()
// Truncate and convert to UTF8 for transport
std::string utf8_text = wstring_to_utf8str(text);
utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1);
- std::string name;
- gAgent.buildFullname(name);
-
- const LLRelationship* info = NULL;
- info = LLAvatarTracker::instance().getBuddyInfo(mOtherParticipantUUID);
- U8 offline = (!info || info->isOnline()) ? IM_ONLINE : IM_OFFLINE;
-
- // default to IM_SESSION_SEND unless it's nothing special - in
- // which case it's probably an IM to everyone.
- U8 dialog = (mDialog == IM_NOTHING_SPECIAL)
- ? (U8)IM_NOTHING_SPECIAL : (U8)IM_SESSION_SEND;
- pack_instant_message(
- gMessageSystem,
- gAgent.getID(),
- FALSE,
- gAgent.getSessionID(),
- mOtherParticipantUUID,
- name.c_str(),
- utf8_text.c_str(),
- offline,
- (EInstantMessage)dialog,
- mSessionUUID);
- gAgent.sendReliableMessage();
- // local echo
- if((mDialog == IM_NOTHING_SPECIAL) && (mOtherParticipantUUID.notNull()))
+ if ( !mSessionInitialized )
{
- std::string history_echo;
- gAgent.buildFullname(history_echo);
-
- // Look for IRC-style emotes here.
- char tmpstr[5]; /* Flawfinder: ignore */
- strncpy(tmpstr,utf8_text.substr(0,4).c_str(), sizeof(tmpstr) -1); /* Flawfinder: ignore */
- tmpstr[sizeof(tmpstr) -1] = '\0';
- if (!strncmp(tmpstr, "/me ", 4) || !strncmp(tmpstr, "/me'", 4))
+ //we send requests (if we need to) to initialize our session
+ if ( !mSessionInitRequested )
{
- utf8_text.replace(0,3,"");
+ mSessionInitRequested = TRUE;
+ if ( !send_start_session_messages(mSessionUUID,
+ mOtherParticipantUUID,
+ mSessionInitialTargetIDs,
+ mDialog) )
+ {
+ //we don't need to need to wait for any responses
+ //so we don't need to disable
+ mSessionInitialized = TRUE;
+ }
+ else
+ {
+ //queue up the message to send once the session is
+ //initialized
+ mQueuedMsgsForInit.append(utf8_text);
+
+ //locally echo a little "starting session" message
+ LLUIString session_start = sSessionStartString;
+
+ session_start.setArg("[NAME]", getTitle());
+ mSessionStartMsgPos =
+ mHistoryEditor->getText().length();
+
+ bool log_to_file = false;
+ addHistoryLine(session_start,
+ LLColor4::grey,
+ log_to_file);
+
+ }
}
else
{
- history_echo += ": ";
+ //queue up the message to send once the session is
+ //initialized
+ mQueuedMsgsForInit.append(utf8_text);
+ }
+ }
+
+ if ( mSessionInitialized )
+ {
+ deliver_message(utf8_text,
+ mSessionUUID,
+ mOtherParticipantUUID,
+ mDialog);
+
+ // local echo
+ if((mDialog == IM_NOTHING_SPECIAL) &&
+ (mOtherParticipantUUID.notNull()))
+ {
+ std::string history_echo;
+ gAgent.buildFullname(history_echo);
+
+ // Look for IRC-style emotes here.
+ char tmpstr[5]; /* Flawfinder: ignore */
+ strncpy(tmpstr,
+ utf8_text.substr(0,4).c_str(),
+ sizeof(tmpstr) -1); /* Flawfinder: ignore */
+ tmpstr[sizeof(tmpstr) -1] = '\0';
+ if (!strncmp(tmpstr, "/me ", 4) ||
+ !strncmp(tmpstr, "/me'", 4))
+ {
+ utf8_text.replace(0,3,"");
+ }
+ else
+ {
+ history_echo += ": ";
+ }
+ history_echo += utf8_text;
+ addHistoryLine(history_echo);
}
- history_echo += utf8_text;
- addHistoryLine(history_echo);
}
gViewerStats->incStat(LLViewerStats::ST_IM_COUNT);
@@ -691,6 +822,31 @@ void LLFloaterIMPanel::sendMsg()
mSentTypingState = TRUE;
}
+void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id)
+{
+ mSessionUUID = session_id;
+ mSessionInitialized = TRUE;
+
+ //we assume the history editor hasn't moved at all since
+ //we added the starting session message
+ //so, we count how many characters to remove
+ S32 chars_to_remove = mHistoryEditor->getText().length() -
+ mSessionStartMsgPos;
+ mHistoryEditor->removeTextFromEnd(chars_to_remove);
+
+ //and now, send the queued msg
+ LLSD::array_iterator iter;
+ for ( iter = mQueuedMsgsForInit.beginArray();
+ iter != mQueuedMsgsForInit.endArray();
+ ++iter)
+ {
+ deliver_message(iter->asString(),
+ mSessionUUID,
+ mOtherParticipantUUID,
+ mDialog);
+ }
+}
+
void LLFloaterIMPanel::setTyping(BOOL typing)
{
diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h
index 21a0cbcd41..45dda8ec79 100644
--- a/indra/newview/llimpanel.h
+++ b/indra/newview/llimpanel.h
@@ -27,10 +27,20 @@ public:
// the default. For example, if you open a session though a
// calling card, a new session id will be generated, but the
// target_id will be the agent referenced by the calling card.
- LLFloaterIMPanel(const std::string& name, const LLRect& rect,
- const std::string& session_label,
- const LLUUID& session_id, const LLUUID& target_id,
- EInstantMessage dialog);
+ LLFloaterIMPanel(const std::string& name,
+ const LLRect& rect,
+ const std::string& session_label,
+ const LLUUID& session_id,
+ const LLUUID& target_id,
+ EInstantMessage dialog);
+ LLFloaterIMPanel(const std::string& name,
+ const LLRect& rect,
+ const std::string& session_label,
+ const LLUUID& session_id,
+ const LLUUID& target_id,
+ const LLDynamicArray<LLUUID>& ids,
+ EInstantMessage dialog);
+
/*virtual*/ BOOL postBuild();
@@ -66,14 +76,14 @@ public:
static void onClickProfile( void* userdata ); // Profile button pressed
static void onClickClose( void* userdata );
- //const LLUUID& getItemUUID() const { return mItemUUID; }
const LLUUID& getSessionID() const { return mSessionUUID; }
const LLUUID& getOtherParticipantID() const { return mOtherParticipantUUID; }
// HACK -- for enabling a teleport button for helpers
static void onTeleport(void* userdata);
- void addTeleportButton(const LLUUID& lure_id);
- void removeTeleportButton();
+ void addTeleportButton();
+
+ void sessionInitReplyReceived(const LLUUID& im_session_id);
// Handle other participant in the session typing.
void processIMTyping(const LLIMInfo* im_info, BOOL typing);
@@ -81,7 +91,7 @@ public:
private:
// called by constructors
- void init();
+ void init(const LLString& session_label);
// Called by UI methods.
void sendMsg();
@@ -110,7 +120,6 @@ private:
private:
LLLineEditor* mInputEditor;
LLViewerTextEditor* mHistoryEditor;
- std::string mSessionLabel;
// The value of the mSessionUUID depends on how the IM session was started:
// one-on-one ==> random id
@@ -119,15 +128,17 @@ private:
// 911 ==> Gaurdian_Angel_Group_ID ^ gAgent.getID()
LLUUID mSessionUUID;
+ BOOL mSessionInitRequested;
+ BOOL mSessionInitialized;
+ LLSD mQueuedMsgsForInit;
+
// The value mOtherParticipantUUID depends on how the IM session was started:
// one-on-one = recipient's id
// group ==> group_id
// inventory folder ==> first target id in list
// 911 ==> sender
LLUUID mOtherParticipantUUID;
-
- // the lure ID for help IM sessions
- LLUUID mLureID;
+ LLDynamicArray<LLUUID> mSessionInitialTargetIDs;
EInstantMessage mDialog;
@@ -139,6 +150,8 @@ private:
// Where does the "User is typing..." line start?
S32 mTypingLineStartIndex;
+ //Where does the "Starting session..." line start?
+ S32 mSessionStartMsgPos;
BOOL mSentTypingState;
@@ -149,6 +162,8 @@ private:
// Timer to detect when user has stopped typing.
LLFrameTimer mLastKeystrokeTimer;
+
+ void disableWhileSessionStarting();
};
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index c093faa1ca..553c6ec6c3 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -23,6 +23,7 @@
#include "llviewerwindow.h"
#include "llresmgr.h"
#include "llfloaternewim.h"
+#include "llhttpnode.h"
#include "llimpanel.h"
#include "llresizebar.h"
#include "lltabcontainer.h"
@@ -35,7 +36,6 @@
#include "llcallingcard.h"
#include "lltoolbar.h"
-const EInstantMessage EVERYONE_DIALOG = IM_NOTHING_SPECIAL;
const EInstantMessage GROUP_DIALOG = IM_SESSION_GROUP_START;
const EInstantMessage DEFAULT_DIALOG = IM_NOTHING_SPECIAL;
@@ -50,6 +50,9 @@ LLIMView* gIMView = NULL;
static LLString sOnlyUserMessage;
static LLString sOfflineMessage;
+static std::map<std::string,LLString> sEventStringsMap;
+static std::map<std::string,LLString> sErrorStringsMap;
+static std::map<std::string,LLString> sForceCloseSessionMap;
//
// Helper Functions
//
@@ -63,7 +66,8 @@ static BOOL group_dictionary_sort( LLGroupData* a, LLGroupData* b )
// the other_participant_id is either an agent_id, a group_id, or an inventory
// folder item_id (collection of calling cards)
-static LLUUID compute_session_id(EInstantMessage dialog, const LLUUID& other_participant_id)
+static LLUUID compute_session_id(EInstantMessage dialog,
+ const LLUUID& other_participant_id)
{
LLUUID session_id;
if (IM_SESSION_GROUP_START == dialog)
@@ -71,6 +75,10 @@ static LLUUID compute_session_id(EInstantMessage dialog, const LLUUID& other_par
// slam group session_id to the group_id (other_participant_id)
session_id = other_participant_id;
}
+ else if (IM_SESSION_CONFERENCE_START == dialog)
+ {
+ session_id.generate();
+ }
else
{
LLUUID agent_id = gAgent.getID();
@@ -102,11 +110,34 @@ BOOL LLFloaterIM::postBuild()
{
requires("only_user_message", WIDGET_TYPE_TEXT_BOX);
requires("offline_message", WIDGET_TYPE_TEXT_BOX);
+ requires("generic_request_error", WIDGET_TYPE_TEXT_BOX);
+ requires("insufficient_perms_error", WIDGET_TYPE_TEXT_BOX);
+ requires("generic_request_error", WIDGET_TYPE_TEXT_BOX);
+ requires("add_session_event", WIDGET_TYPE_TEXT_BOX);
+ requires("message_session_event", WIDGET_TYPE_TEXT_BOX);
+ requires("removed_from_group", WIDGET_TYPE_TEXT_BOX);
if (checkRequirements())
{
sOnlyUserMessage = childGetText("only_user_message");
sOfflineMessage = childGetText("offline_message");
+
+ sErrorStringsMap["generic"] =
+ childGetText("generic_request_error");
+ sErrorStringsMap["unverified"] =
+ childGetText("insufficient_perms_error");
+ sErrorStringsMap["no_user_911"] =
+ childGetText("user_no_help");
+
+ sEventStringsMap["add"] = childGetText("add_session_event");;
+ sEventStringsMap["message"] =
+ childGetText("message_session_event");;
+ sEventStringsMap["teleport"] =
+ childGetText("teleport_session_event");;
+
+ sForceCloseSessionMap["removed"] =
+ childGetText("removed_from_group");
+
return TRUE;
}
return FALSE;
@@ -190,16 +221,12 @@ protected:
// static
EInstantMessage LLIMView::defaultIMTypeForAgent(const LLUUID& agent_id)
{
- EInstantMessage type = IM_SESSION_CARDLESS_START;
+ EInstantMessage type = IM_NOTHING_SPECIAL;
if(is_agent_friend(agent_id))
{
if(LLAvatarTracker::instance().isBuddyOnline(agent_id))
{
- type = IM_SESSION_ADD;
- }
- else
- {
- type = IM_SESSION_OFFLINE_ADD;
+ type = IM_SESSION_CONFERENCE_START;
}
}
return type;
@@ -327,11 +354,21 @@ void LLIMView::addMessage(
}
else
{
+ //if we have recently requsted to be dropped from a session
+ //but are still receiving messages from the session, don't make
+ //a new floater
+// if ( mSessionsDropRequested.has(session_id.asString()) )
+// {
+// return ;
+// }
+
const char* name = from;
if(session_name && (strlen(session_name)>1))
{
name = session_name;
}
+
+
floater = createFloater(new_session_id, other_participant_id, name, dialog, FALSE);
// When we get a new IM, and if you are a god, display a bit
@@ -407,18 +444,25 @@ BOOL LLIMView::isIMSessionOpen(const LLUUID& uuid)
// exists, it is brought forward. Specifying id = NULL results in an
// im session to everyone. Returns the uuid of the session.
LLUUID LLIMView::addSession(const std::string& name,
- EInstantMessage dialog,
- const LLUUID& other_participant_id)
+ EInstantMessage dialog,
+ const LLUUID& other_participant_id)
{
LLUUID session_id = compute_session_id(dialog, other_participant_id);
+
LLFloaterIMPanel* floater = findFloaterBySession(session_id);
if(!floater)
{
- floater = createFloater(session_id, other_participant_id, name, dialog, TRUE);
LLDynamicArray<LLUUID> ids;
ids.put(other_participant_id);
+
+ floater = createFloater(session_id,
+ other_participant_id,
+ name,
+ ids,
+ dialog,
+ TRUE);
+
noteOfflineUsers(floater, ids);
- floater->addParticipants(ids);
mTalkFloater->showFloater(floater);
}
else
@@ -433,30 +477,34 @@ LLUUID LLIMView::addSession(const std::string& name,
// Adds a session using the given session_id. If the session already exists
// the dialog type is assumed correct. Returns the uuid of the session.
LLUUID LLIMView::addSession(const std::string& name,
- EInstantMessage dialog,
- const LLUUID& session_id,
- const LLDynamicArray<LLUUID>& ids)
+ EInstantMessage dialog,
+ const LLUUID& other_participant_id,
+ const LLDynamicArray<LLUUID>& ids)
{
if (0 == ids.getLength())
{
return LLUUID::null;
}
- LLUUID other_participant_id = ids[0];
- LLUUID new_session_id = session_id;
- if (new_session_id.isNull())
- {
- new_session_id = compute_session_id(dialog, other_participant_id);
- }
+ LLUUID session_id = compute_session_id(dialog,
+ other_participant_id);
- LLFloaterIMPanel* floater = findFloaterBySession(new_session_id);
+ LLFloaterIMPanel* floater = findFloaterBySession(session_id);
if(!floater)
{
- // On creation, use the first element of ids as the "other_participant_id"
- floater = createFloater(new_session_id, other_participant_id, name, dialog, TRUE);
+ // On creation, use the first element of ids as the
+ // "other_participant_id"
+ floater = createFloater(session_id,
+ other_participant_id,
+ name,
+ ids,
+ dialog,
+ TRUE);
+
+ if ( !floater ) return LLUUID::null;
+
noteOfflineUsers(floater, ids);
}
- floater->addParticipants(ids);
mTalkFloater->showFloater(floater);
//mTabContainer->selectTabPanel(panel);
floater->setInputFocus(TRUE);
@@ -474,6 +522,11 @@ void LLIMView::removeSession(const LLUUID& session_id)
mTalkFloater->removeFloater(floater);
//mTabContainer->removeTabPanel(floater);
}
+
+// if ( session_id.notNull() )
+// {
+// mSessionsDropRequested[session_id.asString()] = LLSD();
+// }
}
void LLIMView::refresh()
@@ -499,8 +552,7 @@ void LLIMView::refresh()
group;
group = group_list.getNextData())
{
- mNewIMFloater->addTarget(group->mID, group->mName,
- (void*)(&GROUP_DIALOG), TRUE, FALSE);
+ mNewIMFloater->addGroup(group->mID, (void*)(&GROUP_DIALOG), TRUE, FALSE);
}
// build a set of buddies in the current buddy list.
@@ -520,13 +572,6 @@ void LLIMView::refresh()
{
mNewIMFloater->addAgent((*it).second, (void*)(&DEFAULT_DIALOG), FALSE);
}
-
- if(gAgent.isGodlike())
- {
- // XUI:translate
- mNewIMFloater->addTarget(LLUUID::null, "All Residents, All Grids",
- (void*)(&EVERYONE_DIALOG), TRUE, FALSE);
- }
mNewIMFloater->setScrollPos( old_scroll_pos );
}
@@ -600,12 +645,17 @@ void LLIMView::disconnectAllSessions()
std::set<LLViewHandle>::iterator handle_it;
for(handle_it = mFloaters.begin();
handle_it != mFloaters.end();
- ++handle_it)
+ )
{
floater = (LLFloaterIMPanel*)LLFloater::getFloaterByHandle(*handle_it);
+
+ // MUST do this BEFORE calling floater->onClose() because that may remove the item from the set, causing the subsequent increment to crash.
+ ++handle_it;
+
if (floater)
{
floater->setEnabled(FALSE);
+ floater->onClose(TRUE);
}
}
}
@@ -643,16 +693,45 @@ BOOL LLIMView::hasSession(const LLUUID& session_id)
// consistency. Returns the pointer, caller (the class instance since
// it is a private method) is not responsible for deleting the
// pointer. Add the floater to this but do not select it.
-LLFloaterIMPanel* LLIMView::createFloater(const LLUUID& session_id,
- const LLUUID& other_participant_id,
- const std::string& session_label,
- EInstantMessage dialog,
- BOOL user_initiated)
+LLFloaterIMPanel* LLIMView::createFloater(
+ const LLUUID& session_id,
+ const LLUUID& other_participant_id,
+ const std::string& session_label,
+ EInstantMessage dialog,
+ BOOL user_initiated)
+{
+ if (session_id.isNull())
+ {
+ llwarns << "Creating LLFloaterIMPanel with null session ID" << llendl;
+ }
+
+ llinfos << "LLIMView::createFloater: from " << other_participant_id
+ << " in session " << session_id << llendl;
+ LLFloaterIMPanel* floater = new LLFloaterIMPanel(session_label,
+ LLRect(),
+ session_label,
+ session_id,
+ other_participant_id,
+ dialog);
+ LLTabContainerCommon::eInsertionPoint i_pt = user_initiated ? LLTabContainerCommon::RIGHT_OF_CURRENT : LLTabContainerCommon::END;
+ mTalkFloater->addFloater(floater, FALSE, i_pt);
+ mFloaters.insert(floater->getHandle());
+ return floater;
+}
+
+LLFloaterIMPanel* LLIMView::createFloater(
+ const LLUUID& session_id,
+ const LLUUID& other_participant_id,
+ const std::string& session_label,
+ const LLDynamicArray<LLUUID>& ids,
+ EInstantMessage dialog,
+ BOOL user_initiated)
{
if (session_id.isNull())
{
llwarns << "Creating LLFloaterIMPanel with null session ID" << llendl;
}
+
llinfos << "LLIMView::createFloater: from " << other_participant_id
<< " in session " << session_id << llendl;
LLFloaterIMPanel* floater = new LLFloaterIMPanel(session_label,
@@ -660,6 +739,7 @@ LLFloaterIMPanel* LLIMView::createFloater(const LLUUID& session_id,
session_label,
session_id,
other_participant_id,
+ ids,
dialog);
LLTabContainerCommon::eInsertionPoint i_pt = user_initiated ? LLTabContainerCommon::RIGHT_OF_CURRENT : LLTabContainerCommon::END;
mTalkFloater->addFloater(floater, FALSE, i_pt);
@@ -715,3 +795,193 @@ void LLIMView::processIMTypingCore(const LLIMInfo* im_info, BOOL typing)
floater->processIMTyping(im_info, typing);
}
}
+
+void LLIMView::updateFloaterSessionID(const LLUUID& old_session_id,
+ const LLUUID& new_session_id)
+{
+ LLFloaterIMPanel* floater = findFloaterBySession(old_session_id);
+ if (floater)
+ {
+ floater->sessionInitReplyReceived(new_session_id);
+ }
+}
+
+void LLIMView::onDropRequestReplyReceived(const LLUUID& session_id)
+{
+ mSessionsDropRequested.erase(session_id.asString());
+}
+
+void onConfirmForceCloseError(S32 option, void* data)
+{
+ //only 1 option really
+ LLFloaterIMPanel* floater = ((LLFloaterIMPanel*) data);
+
+ if ( floater ) floater->onClose(FALSE);
+}
+
+class LLViewerIMSessionStartReply : public LLHTTPNode
+{
+public:
+ virtual void describe(Description& desc) const
+ {
+ desc.shortInfo("Used for receiving a reply to a request to initialize an IM session");
+ desc.postAPI();
+ desc.input(
+ "{\"client_session_id\": UUID, \"session_id\": UUID, \"success\" boolean, \"reason\": string");
+ desc.source(__FILE__, __LINE__);
+ }
+
+ virtual void post(ResponsePtr response,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+ LLSD body;
+ LLUUID temp_session_id;
+ LLUUID session_id;
+ bool success;
+
+ body = input["body"];
+ success = body["success"].asBoolean();
+ temp_session_id = body["temp_session_id"].asUUID();
+
+ if ( success )
+ {
+ session_id = body["session_id"].asUUID();
+ gIMView->updateFloaterSessionID(temp_session_id,
+ session_id);
+ }
+ else
+ {
+ //throw an error dialog and close the temp session's
+ //floater
+ LLFloaterIMPanel* floater =
+ gIMView->findFloaterBySession(temp_session_id);
+ if (floater)
+ {
+ LLString::format_map_t args;
+ args["[REASON]"] =
+ sErrorStringsMap[body["error"].asString()];
+ args["[RECIPIENT]"] = floater->getTitle();
+
+ gViewerWindow->alertXml("IMSessionStartError",
+ args,
+ onConfirmForceCloseError,
+ floater);
+
+ }
+ }
+ }
+};
+
+class LLViewerIMSessionEventReply : public LLHTTPNode
+{
+public:
+ virtual void describe(Description& desc) const
+ {
+ desc.shortInfo("Used for receiving a reply to a IM session event");
+ desc.postAPI();
+ desc.input(
+ "{\"event\": string, \"reason\": string, \"success\": boolean, \"session_id\": UUID");
+ desc.source(__FILE__, __LINE__);
+ }
+
+ virtual void post(ResponsePtr response,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+ LLUUID session_id;
+ bool success;
+
+ LLSD body = input["body"];
+ success = body["success"].asBoolean();
+ session_id = body["session_id"].asUUID();
+
+ if ( !success )
+ {
+ //throw an error dialog
+ LLFloaterIMPanel* floater =
+ gIMView->findFloaterBySession(session_id);
+ if (floater)
+ {
+ LLString::format_map_t args;
+ args["[REASON]"] =
+ sErrorStringsMap[body["error"].asString()];
+ args["[EVENT]"] =
+ sEventStringsMap[body["event"].asString()];
+ args["[RECIPIENT]"] = floater->getTitle();
+
+ gViewerWindow->alertXml("IMSessionEventError",
+ args);
+ }
+ }
+ }
+};
+
+class LLViewerForceCloseIMSession: public LLHTTPNode
+{
+public:
+ virtual void post(ResponsePtr response,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+ LLUUID session_id;
+ LLString reason;
+
+ session_id = input["body"]["session_id"].asUUID();
+ reason = input["body"]["reason"].asString();
+
+ LLFloaterIMPanel* floater =
+ gIMView ->findFloaterBySession(session_id);
+
+ if ( floater )
+ {
+ LLString::format_map_t args;
+
+ args["[NAME]"] = floater->getTitle();
+ args["[REASON]"] = sForceCloseSessionMap[reason];
+
+ gViewerWindow->alertXml("ForceCloseIMSession",
+ args,
+ onConfirmForceCloseError,
+ floater);
+ }
+ }
+};
+
+class LLViewerIMSessionDropReply : public LLHTTPNode
+{
+public:
+ virtual void post(ResponsePtr response,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+ LLUUID session_id;
+ bool success;
+
+ success = input["body"]["success"].asBoolean();
+ session_id = input["body"]["session_id"].asUUID();
+
+ if ( !success )
+ {
+ //throw an error alert?
+ }
+
+ gIMView->onDropRequestReplyReceived(session_id);
+ }
+};
+
+LLHTTPRegistration<LLViewerIMSessionStartReply>
+ gHTTPRegistrationMessageImsessionstartreply(
+ "/message/IMSessionStartReply");
+
+LLHTTPRegistration<LLViewerIMSessionEventReply>
+ gHTTPRegistrationMessageImsessioneventreply(
+ "/message/IMSessionEventReply");
+
+LLHTTPRegistration<LLViewerForceCloseIMSession>
+ gHTTPRegistrationMessageForceCloseImSession(
+ "/message/ForceCloseIMSession");
+
+LLHTTPRegistration<LLViewerIMSessionDropReply>
+ gHTTPRegistrationMessageImSessionDropReply(
+ "/message/IMSessionDropReply");
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 8732484e0e..aac6fd63ce 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -55,11 +55,11 @@ public:
EInstantMessage dialog,
const LLUUID& other_participant_id);
- // Adds a session using the given session_id. If the session already exists
+ // Adds a session using a specific group of starting agents
// the dialog type is assumed correct. Returns the uuid of the session.
LLUUID addSession(const std::string& name,
EInstantMessage dialog,
- const LLUUID& session_id,
+ const LLUUID& other_participant_id,
const LLDynamicArray<LLUUID>& ids);
// This removes the panel referenced by the uuid, and then
@@ -67,6 +67,12 @@ public:
// deleted.
void removeSession(const LLUUID& session_id);
+ //Updates a given session's session IDs. Does not open,
+ //create or do anything new. If the old session doesn't
+ //exist, then nothing happens.
+ void updateFloaterSessionID(const LLUUID& old_session_id,
+ const LLUUID& new_session_id);
+
void processIMTypingStart(const LLIMInfo* im_info);
void processIMTypingStop(const LLIMInfo* im_info);
@@ -105,13 +111,25 @@ public:
// is no matching panel.
LLFloaterIMPanel* findFloaterBySession(const LLUUID& session_id);
+ void onDropRequestReplyReceived(const LLUUID& session_id);
+
private:
// create a panel and update internal representation for
// consistency. Returns the pointer, caller (the class instance
// since it is a private method) is not responsible for deleting
// the pointer.
- LLFloaterIMPanel* createFloater(const LLUUID& session_id, const LLUUID& target_id,
- const std::string& name, EInstantMessage dialog, BOOL user_initiated = FALSE);
+ LLFloaterIMPanel* createFloater(const LLUUID& session_id,
+ const LLUUID& target_id,
+ const std::string& name,
+ EInstantMessage dialog,
+ BOOL user_initiated = FALSE);
+
+ LLFloaterIMPanel* createFloater(const LLUUID& session_id,
+ const LLUUID& target_id,
+ const std::string& name,
+ const LLDynamicArray<LLUUID>& ids,
+ EInstantMessage dialog,
+ BOOL user_initiated = FALSE);
// This simple method just iterates through all of the ids, and
// prints a simple message if they are not online. Used to help
@@ -131,6 +149,8 @@ private:
// An IM has been received that you haven't seen yet.
BOOL mIMReceived;
+
+ LLSD mSessionsDropRequested;
};
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 0338e7f02a..f90fe340b4 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -1724,7 +1724,7 @@ void LLFolderBridge::folderOptionsMenu()
if (mCallingCards || checkFolderForContentsOfType(model, is_callingcard))
{
mItems.push_back("Calling Card Separator");
- mItems.push_back("IM Contacts In Folder");
+ mItems.push_back("Conference Chat Folder");
mItems.push_back("IM All Contacts In Folder");
}
@@ -2043,58 +2043,6 @@ void LLFolderBridge::createWearable(LLUUID parent_id, EWearableType type)
LLPointer<LLInventoryCallback>(NULL));
}
-void LLFolderBridge::beginIMSession(BOOL only_online)
-{
- LLInventoryModel* model = mInventoryPanel->getModel();
- if(!model) return;
- LLViewerInventoryCategory* cat = getCategory();
- if(!cat) return;
- LLUniqueBuddyCollector is_buddy;
- LLInventoryModel::cat_array_t cat_array;
- LLInventoryModel::item_array_t item_array;
- model->collectDescendentsIf(mUUID,
- cat_array,
- item_array,
- LLInventoryModel::EXCLUDE_TRASH,
- is_buddy);
- S32 count = item_array.count();
- if(count > 0)
- {
- // create the session
- gIMView->setFloaterOpen(TRUE);
- LLDynamicArray<LLUUID> members;
- //members.put(gAgent.getID());
- S32 i;
- EInstantMessage type = IM_SESSION_ADD;
- if(only_online)
- {
- LLAvatarTracker& at = LLAvatarTracker::instance();
- LLUUID id;
- for(i = 0; i < count; ++i)
- {
- id = item_array.get(i)->getCreatorUUID();
- if(at.isBuddyOnline(id))
- {
- members.put(id);
- }
- }
- }
- else
- {
- type = IM_SESSION_OFFLINE_ADD;
- for(i = 0; i < count; ++i)
- {
- members.put(item_array.get(i)->getCreatorUUID());
- }
- }
- // the session_id is always the item_id of the inventory folder
- gIMView->addSession(cat->getName(),
- type,
- mUUID,
- members);
- }
-}
-
void LLFolderBridge::modifyOutfit(BOOL append)
{
LLInventoryModel* model = mInventoryPanel->getModel();
@@ -2689,11 +2637,13 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
items.push_back("Send Instant Message");
items.push_back("Offer Teleport...");
+ items.push_back("Conference Chat");
if (!good_card)
{
disabled_items.push_back("Send Instant Message");
disabled_items.push_back("Offer Teleport...");
+ disabled_items.push_back("Conference Chat");
}
}
hideContextEntries(menu, items, disabled_items);
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index ddfc4fe791..d91ca7fc75 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -296,7 +296,6 @@ protected:
BOOL checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& typeToCheck);
- void beginIMSession(BOOL only_online);
void modifyOutfit(BOOL append);
public:
static LLFolderBridge* sSelf;
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index b834845107..edc4ba0ca6 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1823,7 +1823,7 @@ void LLInventoryModel::buildParentChildMap()
msg->addUUIDFast(_PREHASH_ItemID, (*it));
msg->addUUIDFast(_PREHASH_FolderID, lnf);
msg->addString("NewName", NULL);
- if(msg->mCurrentSendTotal >= MTUBYTES)
+ if(msg->isSendFull(NULL))
{
start_new_message = TRUE;
gAgent.sendReliableMessage();
@@ -3182,7 +3182,7 @@ void LLInventoryFetchObserver::fetchItems(
msg->nextBlockFast(_PREHASH_InventoryData);
msg->addUUIDFast(_PREHASH_OwnerID, owner_id);
msg->addUUIDFast(_PREHASH_ItemID, (*it));
- if(msg->getCurrentSendTotal() >= MTUBYTES)
+ if(msg->isSendFull(NULL))
{
start_new_message = TRUE;
gAgent.sendReliableMessage();
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 6aca7abc11..7ba0ccad3a 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -36,7 +36,7 @@
#include "llagent.h"
#include "llfloatermute.h"
-#include "llviewermessage.h" // for gGenericDispatcher
+#include "llviewergenericmessage.h" // for gGenericDispatcher
#include "llviewerwindow.h"
#include "viewer.h"
#include "llworld.h" //for particle system banning
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index d8c2987470..bc451ecfc0 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -175,20 +175,28 @@ LLScrollListItem* LLNameListCtrl::addElement(const LLSD& value, EAddPosition pos
char first[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/
char last[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/
- LLString fullname;
- if (gCacheName->getName(item->getUUID(), first, last))
- {
- fullname.assign(first);
- fullname.append(1, ' ');
- fullname.append(last);
- }
- else // didn't work as a resident name, try looking up as a group
+ // use supplied name by default
+ LLString fullname = value["name"].asString();
+ if (value["target"].asString() == "GROUP")
{
char group_name[DB_GROUP_NAME_BUF_SIZE]; /*Flawfinder: ignore*/
gCacheName->getGroupName(item->getUUID(), group_name);
// fullname will be "nobody" if group not found
fullname = group_name;
}
+ else if (value["target"].asString() == "SPECIAL")
+ {
+ // just use supplied name
+ }
+ else // normal resident
+ {
+ if (gCacheName->getName(item->getUUID(), first, last))
+ {
+ fullname.assign(first);
+ fullname.append(1, ' ');
+ fullname.append(last);
+ }
+ }
LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex);
((LLScrollListText*)cell)->setText( fullname );
@@ -429,3 +437,4 @@ LLView* LLNameListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto
return name_list;
}
+
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 1b0c731ea9..383d2846c0 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -30,7 +30,6 @@
#include "llfloatergroupinfo.h"
#include "llfloaterworldmap.h"
#include "llfloatermute.h"
-#include "llfloaterrate.h"
#include "llfloateravatarinfo.h"
#include "lliconctrl.h"
#include "llinventoryview.h"
@@ -48,7 +47,7 @@
#include "lluiconstants.h"
#include "llvoavatar.h"
#include "llviewermenu.h" // *FIX: for is_agent_friend()
-#include "llviewermessage.h" // send_generic_message
+#include "llviewergenericmessage.h" // send_generic_message
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llviewborder.h"
@@ -258,14 +257,13 @@ void LLPanelAvatarTab::draw()
}
}
-void LLPanelAvatarTab::sendAvatarProfileRequestIfNeeded(const char* type)
+void LLPanelAvatarTab::sendAvatarProfileRequestIfNeeded(const char* method)
{
if (!mDataRequested)
{
std::vector<std::string> strings;
strings.push_back( mPanelAvatar->getAvatarID().asString() );
- strings.push_back( type );
- send_generic_message("avatarprofilerequest", strings);
+ send_generic_message(method, strings);
mDataRequested = true;
}
}
@@ -449,7 +447,7 @@ BOOL LLPanelAvatarSecondLife::postBuild(void)
childSetAction("Show on Map", LLPanelAvatar::onClickTrack, getPanelAvatar());
childSetAction("Instant Message...", LLPanelAvatar::onClickIM, getPanelAvatar());
- //childSetAction("Rate...", LLPanelAvatar::onClickRate, getPanelAvatar());
+
childSetAction("Add Friend...", LLPanelAvatar::onClickAddFriend, getPanelAvatar());
childSetAction("Pay...", LLPanelAvatar::onClickPay, getPanelAvatar());
childSetAction("Mute", LLPanelAvatar::onClickMute, getPanelAvatar() );
@@ -807,7 +805,7 @@ LLPanelAvatarNotes::LLPanelAvatarNotes(const std::string& name, const LLRect& re
void LLPanelAvatarNotes::refresh()
{
- sendAvatarProfileRequestIfNeeded("notes");
+ sendAvatarProfileRequestIfNeeded("avatarnotesrequest");
}
void LLPanelAvatarNotes::clearControls()
@@ -851,7 +849,7 @@ void LLPanelAvatarClassified::refresh()
childSetEnabled("Delete...",self && allow_delete);
childSetVisible("classified tab",!show_help);
- sendAvatarProfileRequestIfNeeded("classifieds");
+ sendAvatarProfileRequestIfNeeded("avatarclassifiedsrequest");
}
@@ -1052,7 +1050,7 @@ void LLPanelAvatarPicks::refresh()
childSetEnabled("New...",self && allow_new);
childSetEnabled("Delete...",self && allow_delete);
- sendAvatarProfileRequestIfNeeded("picks");
+ sendAvatarProfileRequestIfNeeded("avatarpicksrequest");
}
@@ -1083,6 +1081,9 @@ void LLPanelAvatarPicks::processAvatarPicksReply(LLMessageSystem* msg, void**)
// number of new panels.
deletePickPanels();
+ // The database needs to know for which user to look up picks.
+ LLUUID avatar_id = getPanelAvatar()->getAvatarID();
+
block_count = msg->getNumberOfBlocks("Data");
for (block = 0; block < block_count; block++)
{
@@ -1091,7 +1092,7 @@ void LLPanelAvatarPicks::processAvatarPicksReply(LLMessageSystem* msg, void**)
panel_pick = new LLPanelPick(FALSE);
- panel_pick->setPickID(pick_id);
+ panel_pick->setPickID(pick_id, avatar_id);
// This will request data from the server when the pick is first
// drawn.
@@ -1170,23 +1171,24 @@ void LLPanelAvatarPicks::callbackDelete(S32 option, void* data)
if(gAgent.isGodlike())
{
msg->newMessage("PickGodDelete");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID());
+ msg->addUUID("SessionID", gAgent.getSessionID());
+ msg->nextBlock("Data");
+ msg->addUUID("PickID", panel_pick->getPickID());
+ // *HACK: We need to send the pick's creator id to accomplish
+ // the delete, and we don't use the query id for anything. JC
+ msg->addUUID( "QueryID", panel_pick->getPickCreatorID() );
}
else
{
msg->newMessage("PickDelete");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID());
+ msg->addUUID("SessionID", gAgent.getSessionID());
+ msg->nextBlock("Data");
+ msg->addUUID("PickID", panel_pick->getPickID());
}
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", gAgent.getID());
- msg->addUUID("SessionID", gAgent.getSessionID());
- msg->nextBlock("Data");
- msg->addUUID("PickID", panel_pick->getPickID());
-
- //God delete receiving end expects a query ID but we dont need it, so send a null.
- //This is to resolve SL-24170 God Picks Delete results in crash.
- if(gAgent.isGodlike())
- msg->addUUID( "QueryID", LLUUID::null );
-
-
gAgent.sendReliableMessage();
if(tabs)
@@ -1219,8 +1221,7 @@ LLPanelAvatar::LLPanelAvatar(
mAvatarID( LLUUID::null ), // mAvatarID is set with 'setAvatar' or 'setAvatarID'
mHaveProperties(FALSE),
mHaveStatistics(FALSE),
- mAllowEdit(allow_edit),
- mDisableRate(FALSE)
+ mAllowEdit(allow_edit)
{
sAllPanels.push_back(this);
@@ -1435,8 +1436,6 @@ void LLPanelAvatar::setAvatarID(const LLUUID &avatar_id, const LLString &name,
childSetEnabled("drop target",FALSE);
childSetVisible("Show on Map",FALSE);
childSetEnabled("Show on Map",FALSE);
- childSetVisible("Rate...",FALSE);
- childSetEnabled("Rate...",FALSE);
childSetVisible("Add Friend...",FALSE);
childSetEnabled("Add Friend...",FALSE);
childSetVisible("Pay...",FALSE);
@@ -1475,8 +1474,6 @@ void LLPanelAvatar::setAvatarID(const LLUUID &avatar_id, const LLString &name,
{
childSetToolTip("Show on Map",childGetValue("ShowOnMapFriendOnline").asString());
}
- childSetVisible("Rate...",TRUE);
- childSetEnabled("Rate...",FALSE);
childSetVisible("Add Friend...", true);
childSetEnabled("Add Friend...", true);
childSetVisible("Pay...",TRUE);
@@ -1576,16 +1573,6 @@ void LLPanelAvatar::onClickTrack(void* userdata)
}
}
-// static
-//-----------------------------------------------------------------------------
-// onClickRate()
-//-----------------------------------------------------------------------------
-void LLPanelAvatar::onClickRate(void *userdata)
-{
- LLPanelAvatar* self = (LLPanelAvatar*) userdata;
-
- LLFloaterRate::show(self->mAvatarID);
-}
// static
void LLPanelAvatar::onClickAddFriend(void* userdata)
@@ -1627,15 +1614,6 @@ void LLPanelAvatar::onClickMute(void *userdata)
}
-void LLPanelAvatar::disableRate()
-{
- // Force off the rate button, but enable IM.
- // Note that these buttons may not exist if it is your own profile.
- childSetEnabled("Rate...",FALSE);
- mDisableRate = TRUE;
-}
-
-
// static
void LLPanelAvatar::onClickOfferTeleport(void *userdata)
{
@@ -1783,10 +1761,6 @@ void LLPanelAvatar::processAvatarPropertiesReply(LLMessageSystem *msg, void**)
self->childSetEnabled("Pay...",TRUE);
self->childSetEnabled("Mute",TRUE);
- if (!self->mDisableRate)
- {
- self->childSetEnabled("Rate...",TRUE);
- }
self->childSetEnabled("drop target",TRUE);
self->mHaveProperties = TRUE;
@@ -2015,7 +1989,7 @@ void LLPanelAvatar::processAvatarGroupsReply(LLMessageSystem *msg, void**)
// Otherwise you will write blanks back into the database.
void LLPanelAvatar::enableOKIfReady()
{
- if(mHaveProperties && mHaveStatistics && childIsVisible("OK"))
+ if(mHaveProperties && childIsVisible("OK"))
{
childSetEnabled("OK", TRUE);
}
@@ -2121,69 +2095,6 @@ void LLPanelAvatar::selectTabByName(std::string tab_name)
}
-// static
-void LLPanelAvatar::processAvatarStatisticsReply(LLMessageSystem *msg, void**)
-{
- // extract the agent id
- LLUUID agent_id;
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
-
- LLUUID avatar_id;
- msg->getUUIDFast(_PREHASH_AvatarData, _PREHASH_AvatarID, avatar_id);
-
- // look up all panels which have this avatar
- for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter)
- {
- LLPanelAvatar* self = *iter;
- if (self->mAvatarID != avatar_id)
- {
- continue;
- }
-
- self->mHaveStatistics = TRUE;
- self->enableOKIfReady();
-
- // clear out list
- LLScrollListCtrl* ratings_list = LLUICtrlFactory::getScrollListByName(self->mPanelSecondLife,"ratings");
- if (ratings_list)
- {
- ratings_list->deleteAllItems();
- }
- // build the item list
- S32 items = msg->getNumberOfBlocksFast(_PREHASH_StatisticsData);
- for (S32 i = 0; i < items; i++)
- {
- char name[MAX_STRING]; /*Flawfinder: ignore*/
- S32 positive;
- S32 negative;
- char value_string[MAX_STRING]; /*Flawfinder: ignore*/
-
- msg->getStringFast( _PREHASH_StatisticsData,
- _PREHASH_Name, MAX_STRING, name, i);
- msg->getS32( "StatisticsData", "Positive", positive, i);
- msg->getS32( "StatisticsData", "Negative", negative, i);
-
- const S32 TEXT_WIDTH = 75;
-
- LLSD row;
- row["columns"][0]["value"] = name;
- row["columns"][0]["font"] = "SANSSERIF_SMALL";
- row["columns"][0]["width"] = TEXT_WIDTH;
- row["columns"][1]["value"] = value_string;
- row["columns"][1]["font"] = "SANSSERIF_SMALL";
- row["columns"][1]["width"] = 50;
- row["columns"][2]["value"] = "";
- row["columns"][2]["font"] = "SANSSERIF_SMALL";
-
- if(ratings_list)
- {
- ratings_list->addElement( row );
- }
- }
- }
-}
-
-
void LLPanelAvatar::processAvatarNotesReply(LLMessageSystem *msg, void**)
{
// extract the agent id
diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h
index 994d23b7d3..f54da2538f 100644
--- a/indra/newview/llpanelavatar.h
+++ b/indra/newview/llpanelavatar.h
@@ -60,8 +60,9 @@ public:
// If the data for this tab has not yet been requested,
// send the request. Used by tabs that are filled in only
// when they are first displayed.
- // type is one of "notes", "classifieds", "picks"
- void sendAvatarProfileRequestIfNeeded(const char* type);
+ // type is one of "avatarnotesrequest", "avatarpicksrequest",
+ // or "avatarclassifiedsrequest"
+ void sendAvatarProfileRequestIfNeeded(const char* method);
private:
LLPanelAvatar* mPanelAvatar;
@@ -256,8 +257,6 @@ public:
void setOnlineStatus(EOnlineStatus online_status);
const LLUUID& getAvatarID() const { return mAvatarID; }
-
- void disableRate();
void resetGroupList();
@@ -279,7 +278,6 @@ public:
static void processAvatarPropertiesReply(LLMessageSystem *msg, void **);
static void processAvatarInterestsReply(LLMessageSystem *msg, void **);
static void processAvatarGroupsReply(LLMessageSystem* msg, void**);
- static void processAvatarStatisticsReply(LLMessageSystem *msg, void **);
static void processAvatarNotesReply(LLMessageSystem *msg, void **);
static void processAvatarPicksReply(LLMessageSystem *msg, void **);
static void processAvatarClassifiedReply(LLMessageSystem *msg, void **);
@@ -288,7 +286,6 @@ public:
static void onClickIM( void *userdata);
static void onClickOfferTeleport( void *userdata);
static void onClickPay( void *userdata);
- static void onClickRate( void *userdata);
static void onClickAddFriend(void* userdata);
static void onClickOK( void *userdata);
static void onClickCancel( void *userdata);
@@ -337,7 +334,6 @@ protected:
BOOL mHaveStatistics;
LLTabContainerCommon* mTab;
BOOL mAllowEdit;
- BOOL mDisableRate;
typedef std::list<LLPanelAvatar*> panel_list_t;
static panel_list_t sAllPanels;
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index 5c5e0479d4..95ed517794 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -38,7 +38,7 @@
#include "llviewerwindow.h"
#include "llworldmap.h"
#include "llfloaterworldmap.h"
-#include "llviewermessage.h" // send_generic_message
+#include "llviewergenericmessage.h" // send_generic_message
#include "llviewerwindow.h" // for window width, height
const S32 MINIMUM_PRICE_FOR_LISTING = 50; // L$
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index 9d40357544..610bfec8ae 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -146,6 +146,7 @@ BOOL LLPanelGroupGeneral::postBuild()
{
mCtrlMature->setCommitCallback(onCommitAny);
mCtrlMature->setCallbackUserData(this);
+ mCtrlMature->setVisible( gAgent.mAccess > SIM_ACCESS_PG );
}
mCtrlOpenEnrollment = (LLCheckBoxCtrl*) getChildByName("open_enrollement", recurse);
@@ -447,7 +448,17 @@ bool LLPanelGroupGeneral::apply(LLString& mesg)
if (mCtrlPublishOnWeb) gdatap->mAllowPublish = mCtrlPublishOnWeb->get();
if (mEditCharter) gdatap->mCharter = mEditCharter->getText();
if (mInsignia) gdatap->mInsigniaID = mInsignia->getImageAssetID();
- if (mCtrlMature) gdatap->mMaturePublish = mCtrlMature->get();
+ if (mCtrlMature)
+ {
+ if (gAgent.mAccess > SIM_ACCESS_PG)
+ {
+ gdatap->mMaturePublish = mCtrlMature->get();
+ }
+ else
+ {
+ gdatap->mMaturePublish = FALSE;
+ }
+ }
if (mCtrlShowInGroupList) gdatap->mShowInList = mCtrlShowInGroupList->get();
}
@@ -598,6 +609,7 @@ void LLPanelGroupGeneral::update(LLGroupChange gc)
{
mCtrlMature->set(gdatap->mMaturePublish);
mCtrlMature->setEnabled(mAllowEdit && can_change_ident);
+ mCtrlMature->setVisible( gAgent.mAccess > SIM_ACCESS_PG );
}
if (mCtrlOpenEnrollment)
{
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
index a05f7c54c6..ff2a64075c 100644
--- a/indra/newview/llpanelpick.cpp
+++ b/indra/newview/llpanelpick.cpp
@@ -28,6 +28,7 @@
#include "llviewertexteditor.h"
#include "lltexturectrl.h"
#include "lluiconstants.h"
+#include "llviewergenericmessage.h"
#include "llvieweruictrlfactory.h"
#include "llviewerparcelmgr.h"
#include "llworldmap.h"
@@ -165,9 +166,10 @@ void LLPanelPick::initNewPick()
}
-void LLPanelPick::setPickID(const LLUUID& id)
+void LLPanelPick::setPickID(const LLUUID& pick_id, const LLUUID& creator_id)
{
- mPickID = id;
+ mPickID = pick_id;
+ mCreatorID = creator_id;
}
@@ -188,15 +190,12 @@ std::string LLPanelPick::getPickName()
void LLPanelPick::sendPickInfoRequest()
{
- LLMessageSystem *msg = gMessageSystem;
-
- msg->newMessage("PickInfoRequest");
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", gAgent.getID() );
- msg->addUUID("SessionID", gAgent.getSessionID());
- msg->nextBlock("Data");
- msg->addUUID("PickID", mPickID);
- gAgent.sendReliableMessage();
+ // Must ask for a pick based on the creator id because
+ // the pick database is distributed to the inventory cluster. JC
+ std::vector<std::string> strings;
+ strings.push_back( mCreatorID.asString() );
+ strings.push_back( mPickID.asString() );
+ send_generic_message("pickinforequest", strings);
mDataRequested = TRUE;
}
diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h
index a347133be6..232bbb736a 100644
--- a/indra/newview/llpanelpick.h
+++ b/indra/newview/llpanelpick.h
@@ -39,13 +39,15 @@ public:
/*virtual*/ void draw();
- void refresh();
+ /*virtual*/ void refresh();
// Setup a new pick, including creating an id, giving a sane
// initial position, etc.
void initNewPick();
- void setPickID(const LLUUID& id);
+ // We need to know the creator id so the database knows which partition
+ // to query for the pick data.
+ void setPickID(const LLUUID& pick_id, const LLUUID& creator_id);
// Schedules the panel to request data
// from the server next time it is drawn.
@@ -53,6 +55,7 @@ public:
std::string getPickName();
const LLUUID& getPickID() const { return mPickID; }
+ const LLUUID& getPickCreatorID() const { return mCreatorID; }
void sendPickInfoRequest();
void sendPickInfoUpdate();
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index cd4d8d2f87..a02dd912e3 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -32,7 +32,6 @@
#include "lldrawable.h"
#include "llfloaterinspect.h"
#include "llfloaterproperties.h"
-#include "llfloaterrate.h"
#include "llfloaterreporter.h"
#include "llfloatertools.h"
#include "llframetimer.h"
@@ -542,7 +541,7 @@ void LLSelectMgr::deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_s
msg->addU32Fast(_PREHASH_ObjectLocalID, (objects[i])->getLocalID());
select_count++;
- if(msg->mCurrentSendTotal >= MTUBYTES || select_count >= MAX_OBJECTS_PER_PACKET)
+ if(msg->isSendFull(NULL) || select_count >= MAX_OBJECTS_PER_PACKET)
{
msg->sendReliable(regionp->getHost() );
select_count = 0;
@@ -4179,7 +4178,7 @@ void LLSelectMgr::sendListToRegions(const LLString& message_name,
// if to same simulator and message not too big
if ((current_region == last_region)
- && (gMessageSystem->mCurrentSendTotal < MTUBYTES)
+ && (! gMessageSystem->isSendFull(NULL))
&& (objects_in_this_packet < MAX_OBJECTS_PER_PACKET))
{
// add another instance of the body of the data
@@ -4214,7 +4213,7 @@ void LLSelectMgr::sendListToRegions(const LLString& message_name,
}
// flush messages
- if (gMessageSystem->mCurrentSendTotal > 0)
+ if (gMessageSystem->getCurrentSendTotal() > 0)
{
gMessageSystem->sendReliable( current_region->getHost());
packets_sent++;
@@ -6220,7 +6219,6 @@ BOOL LLObjectSelection::getOwnershipCost(S32 &cost)
}
-
//-----------------------------------------------------------------------------
// getObjectCount()
//-----------------------------------------------------------------------------
@@ -6556,3 +6554,4 @@ LLViewerObject* LLObjectSelection::getFirstMoveableObject(BOOL get_root)
return object;
}
+
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index baf6abda11..4bbdca521c 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -35,6 +35,7 @@
#include "llloginflags.h"
#include "llmd5.h"
#include "llmemorystream.h"
+#include "llmessageconfig.h"
#include "llregionhandle.h"
#include "llsd.h"
#include "llsdserialize.h"
@@ -67,7 +68,6 @@
#include "llfloatergesture.h"
#include "llfloaterland.h"
#include "llfloatertopobjects.h"
-#include "llfloaterrate.h"
#include "llfloatertos.h"
#include "llfloaterworldmap.h"
#include "llframestats.h"
@@ -108,6 +108,7 @@
#include "llviewerassetstorage.h"
#include "llviewercamera.h"
#include "llviewerdisplay.h"
+#include "llviewergenericmessage.h"
#include "llviewergesture.h"
#include "llviewerimagelist.h"
#include "llviewermenu.h"
@@ -398,6 +399,7 @@ BOOL idle_startup()
port = gSavedSettings.getU32("ConnectionPort");
}
+ LLMessageConfig::initClass("viewer", gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
if(!start_messaging_system(
message_template_path,
port,
@@ -941,16 +943,7 @@ BOOL idle_startup()
}
llinfos << "Verifying message template..." << llendl;
-
- // register with the message system so it knows we're
- // expecting this message
- LLMessageSystem* msg = gMessageSystem;
- msg->setHandlerFuncFast(_PREHASH_TemplateChecksumReply, null_message_callback, NULL);
- msg->newMessageFast(_PREHASH_SecuredTemplateChecksumRequest);
- msg->nextBlockFast(_PREHASH_TokenBlock);
- lldebugs << "random token: " << gTemplateToken << llendl;
- msg->addUUIDFast(_PREHASH_Token, gTemplateToken);
- msg->sendReliable(mt_host);
+ LLMessageSystem::sendSecureMessageTemplateChecksum(mt_host);
timeout.reset();
gStartupState++;
@@ -959,40 +952,16 @@ BOOL idle_startup()
if (STATE_MESSAGE_TEMPLATE_WAIT == gStartupState)
{
- U32 remote_template_checksum = 0;
-
- U8 major_version = 0;
- U8 minor_version = 0;
- U8 patch_version = 0;
- U8 server_version = 0;
- U32 flags = 0x0;
-
LLMessageSystem* msg = gMessageSystem;
- while (msg->checkMessages(gFrameCount))
+ while (msg->checkAllMessages(gFrameCount, gServicePump))
{
- if (msg->isMessageFast(_PREHASH_TemplateChecksumReply))
+ if (msg->isTemplateConfirmed())
{
- LLUUID token;
- msg->getUUID("TokenBlock", "Token", token);
- if(token != gTemplateToken)
- {
- llwarns << "Incorrect token in template checksum reply: "
- << token << llendl;
- return do_normal_idle;
- }
- msg->getU32("DataBlock", "Checksum", remote_template_checksum);
- msg->getU8 ("DataBlock", "MajorVersion", major_version);
- msg->getU8 ("DataBlock", "MinorVersion", minor_version);
- msg->getU8 ("DataBlock", "PatchVersion", patch_version);
- msg->getU8 ("DataBlock", "ServerVersion", server_version);
- msg->getU32("DataBlock", "Flags", flags);
-
BOOL update_available = FALSE;
BOOL mandatory = FALSE;
- if (remote_template_checksum != msg->mMessageFileChecksum)
+ if (!LLMessageSystem::doesTemplateMatch())
{
- llinfos << "Message template out of sync" << llendl;
// Mandatory update -- message template checksum doesn't match
update_available = TRUE;
mandatory = TRUE;
@@ -1012,6 +981,7 @@ BOOL idle_startup()
quit = TRUE;
}
}
+
// Bail out and clean up circuit
if (quit)
{
@@ -1022,7 +992,6 @@ BOOL idle_startup()
}
// If we get here, we've got a compatible message template
-
if (!mandatory)
{
llinfos << "Message template is current!" << llendl;
@@ -1189,7 +1158,7 @@ BOOL idle_startup()
}
// Process messages to keep from dropping circuit.
LLMessageSystem* msg = gMessageSystem;
- while (msg->checkMessages(gFrameCount))
+ while (msg->checkAllMessages(gFrameCount, gServicePump))
{
}
msg->processAcks();
@@ -1214,7 +1183,7 @@ BOOL idle_startup()
}
// Process messages to keep from dropping circuit.
LLMessageSystem* msg = gMessageSystem;
- while (msg->checkMessages(gFrameCount))
+ while (msg->checkAllMessages(gFrameCount, gServicePump))
{
}
msg->processAcks();
@@ -1920,7 +1889,7 @@ BOOL idle_startup()
++gStartupState;
}
LLMessageSystem* msg = gMessageSystem;
- while (msg->checkMessages(gFrameCount))
+ while (msg->checkAllMessages(gFrameCount, gServicePump))
{
}
msg->processAcks();
@@ -1939,8 +1908,7 @@ BOOL idle_startup()
LLMessageSystem* msg = gMessageSystem;
msg->setHandlerFuncFast(
_PREHASH_AgentMovementComplete,
- process_agent_movement_complete,
- NULL);
+ process_agent_movement_complete);
LLViewerRegion* regionp = gAgent.getRegion();
if(!gRunLocal && regionp)
{
@@ -1977,9 +1945,9 @@ BOOL idle_startup()
if (STATE_AGENT_WAIT == gStartupState)
{
LLMessageSystem* msg = gMessageSystem;
- while (msg->checkMessages(gFrameCount))
+ while (msg->checkAllMessages(gFrameCount, gServicePump))
{
- if (msg->isMessageFast(_PREHASH_AgentMovementComplete))
+ if (gAgentMovementCompleted)
{
gStartupState++;
// Sometimes we have more than one message in the
@@ -2887,7 +2855,21 @@ void update_dialog_callback(S32 option, void *userdata)
}
return;
}
-
+
+ LLSD query_map = LLSD::emptyMap();
+ // *TODO place os string in a global constant
+#if LL_WINDOWS
+ query_map["os"] = "win";
+#elif LL_DARWIN
+ query_map["os"] = "mac";
+#elif LL_LINUX
+ query_map["os"] = "lnx";
+#endif
+ query_map["userserver"] = gUserServerName;
+ query_map["channel"] = gChannelName;
+ // *TODO constantize this guy
+ LLURI update_url = LLURI::buildHTTP("secondlife.com", 80, "update.php", query_map);
+
#if LL_WINDOWS
char ip[MAX_STRING]; /* Flawfinder: ignore */
@@ -2919,9 +2901,6 @@ void update_dialog_callback(S32 option, void *userdata)
}
u32_to_ip_string(gUserServer.getAddress(), ip);
- std::ostringstream params;
- params << "-userserver " << gUserServerName;
-
// if a sim name was passed in via command line parameter (typically through a SLURL)
if ( LLURLSimString::sInstance.mSimString.length() )
{
@@ -2929,6 +2908,8 @@ void update_dialog_callback(S32 option, void *userdata)
gSavedSettings.setString( "NextLoginLocation", LLURLSimString::sInstance.mSimString );
};
+ std::ostringstream params;
+ params << "-url \"" << update_url.asString() << "\"";
if (gHideLinks)
{
// Figure out the program name.
@@ -2949,7 +2930,8 @@ void update_dialog_callback(S32 option, void *userdata)
program_name = "SecondLife";
}
- params << " -silent -name \"" << gSecondLife << "\" -program \"" << program_name << "\"";
+ params << " -silent -name \"" << gSecondLife << "\"";
+ params << " -program \"" << program_name << "\"";
}
llinfos << "Calling updater: " << update_exe_path << " " << params.str() << llendl;
@@ -2967,12 +2949,12 @@ void update_dialog_callback(S32 option, void *userdata)
// record the location to start at next time
gSavedSettings.setString( "NextLoginLocation", LLURLSimString::sInstance.mSimString );
};
-
+
update_exe_path = "'";
update_exe_path += gDirUtilp->getAppRODataDir();
- update_exe_path += "/AutoUpdater.app/Contents/MacOS/AutoUpdater' -userserver ";
- update_exe_path += gUserServerName;
- update_exe_path += " -name \"";
+ update_exe_path += "/AutoUpdater.app/Contents/MacOS/AutoUpdater' -url \"";
+ update_exe_path += update_url.asString();
+ update_exe_path += "\" -name \"";
update_exe_path += gSecondLife;
update_exe_path += "\" &";
@@ -3100,8 +3082,9 @@ void register_viewer_callbacks(LLMessageSystem* msg)
LLPanelAvatar::processAvatarInterestsReply);
msg->setHandlerFunc("AvatarGroupsReply",
LLPanelAvatar::processAvatarGroupsReply);
- msg->setHandlerFuncFast(_PREHASH_AvatarStatisticsReply,
- LLPanelAvatar::processAvatarStatisticsReply);
+ // ratings deprecated
+ //msg->setHandlerFuncFast(_PREHASH_AvatarStatisticsReply,
+ // LLPanelAvatar::processAvatarStatisticsReply);
msg->setHandlerFunc("AvatarNotesReply",
LLPanelAvatar::processAvatarNotesReply);
msg->setHandlerFunc("AvatarPicksReply",
@@ -3120,8 +3103,9 @@ void register_viewer_callbacks(LLMessageSystem* msg)
msg->setHandlerFuncFast(_PREHASH_GroupProfileReply,
LLGroupMgr::processGroupPropertiesReply);
- msg->setHandlerFuncFast(_PREHASH_ReputationIndividualReply,
- LLFloaterRate::processReputationIndividualReply);
+ // ratings deprecated
+ // msg->setHandlerFuncFast(_PREHASH_ReputationIndividualReply,
+ // LLFloaterRate::processReputationIndividualReply);
msg->setHandlerFuncFast(_PREHASH_AgentWearablesUpdate,
LLAgent::processAgentInitialWearablesUpdate );
@@ -3129,9 +3113,6 @@ void register_viewer_callbacks(LLMessageSystem* msg)
msg->setHandlerFunc("ScriptControlChange",
LLAgent::processScriptControlChange );
- msg->setHandlerFuncFast(_PREHASH_GestureUpdate,
- LLViewerGestureList::processGestureUpdate);
-
msg->setHandlerFuncFast(_PREHASH_ViewerEffect, LLHUDManager::processViewerEffect);
msg->setHandlerFuncFast(_PREHASH_GrantGodlikePowers, process_grant_godlike_powers);
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index e5952f4f5b..7d64640fb0 100644
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -61,6 +61,7 @@ enum EStartupState{
// exorted symbol
extern S32 gStartupState;
+extern BOOL gAgentMovementCompleted;
extern bool gQuickTimeInitialized;
extern LLPointer<LLImageGL> gStartImageGL;
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index c732394b4e..bc5efa20aa 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -1012,7 +1012,7 @@ void LLTextureCtrl::setEnabled( BOOL enabled )
mCaption->setEnabled( enabled );
- LLUICtrl::setEnabled( enabled );
+ LLView::setEnabled( enabled );
}
void LLTextureCtrl::setValid(BOOL valid )
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index b4aee4e2e1..64ec8f0b2f 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -1219,6 +1219,7 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
return FALSE;
}
}
+std::cout << "ASSET ID: " << new_item->getAssetUUID() << "\n";
hit_obj->updateInventory(new_item, TASK_INVENTORY_ASSET_KEY, true);
}
else if(!item->getPermissions().allowOperationBy(PERM_TRANSFER,
@@ -1232,6 +1233,7 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
// *FIX: may want to make sure agent can paint hit_obj.
// make sure the object has the texture in it's inventory.
+std::cout << "ASSET ID: " << new_item->getAssetUUID() << "\n";
hit_obj->updateInventory(new_item, TASK_INVENTORY_ASSET_KEY, true);
}
return TRUE;
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index ee878c1dc0..cbb37e5fe4 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -253,7 +253,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield)
gViewerWindow->setShowProgress(TRUE);
gViewerWindow->setProgressPercent(0);
gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED );
- gAgent.setTeleportMessage("Requesting Teleport...");
+ gAgent.setTeleportMessage(
+ LLAgent::sTeleportProgressMessages["requesting"]);
break;
case LLAgent::TELEPORT_REQUESTED:
@@ -274,7 +275,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield)
gViewerWindow->setProgressCancelButtonVisible(FALSE, "Cancel");
gViewerWindow->setProgressPercent(75.f);
gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING );
- gAgent.setTeleportMessage("Arriving...");
+ gAgent.setTeleportMessage(
+ LLAgent::sTeleportProgressMessages["arriving"]);
gImageList.mForceResetTextureStats = TRUE;
break;
diff --git a/indra/newview/llviewergenericmessage.cpp b/indra/newview/llviewergenericmessage.cpp
new file mode 100644
index 0000000000..d155d11570
--- /dev/null
+++ b/indra/newview/llviewergenericmessage.cpp
@@ -0,0 +1,77 @@
+/**
+ * @file llviewergenericmessage.cpp
+ * @brief Handle processing of "generic messages" which contain short lists of strings.
+ * @author James Cook
+ *
+ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llviewergenericmessage.h"
+
+#include "lldispatcher.h"
+#include "lluuid.h"
+#include "message.h"
+
+#include "llagent.h"
+
+
+LLDispatcher gGenericDispatcher;
+
+
+void send_generic_message(const char* method,
+ const std::vector<std::string>& strings,
+ const LLUUID& invoice)
+{
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessage("GenericMessage");
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
+ msg->nextBlock("MethodData");
+ msg->addString("Method", method);
+ msg->addUUID("Invoice", invoice);
+ if(strings.empty())
+ {
+ msg->nextBlock("ParamList");
+ msg->addString("Parameter", NULL);
+ }
+ else
+ {
+ std::vector<std::string>::const_iterator it = strings.begin();
+ std::vector<std::string>::const_iterator end = strings.end();
+ for(; it != end; ++it)
+ {
+ msg->nextBlock("ParamList");
+ msg->addString("Parameter", (*it).c_str());
+ }
+ }
+ gAgent.sendReliableMessage();
+}
+
+
+
+void process_generic_message(LLMessageSystem* msg, void**)
+{
+ LLUUID agent_id;
+ msg->getUUID("AgentData", "AgentID", agent_id);
+ if (agent_id != gAgent.getID())
+ {
+ llwarns << "GenericMessage for wrong agent" << llendl;
+ return;
+ }
+
+ std::string request;
+ LLUUID invoice;
+ LLDispatcher::sparam_t strings;
+ LLDispatcher::unpackMessage(msg, request, invoice, strings);
+
+ if(!gGenericDispatcher.dispatch(request, invoice, strings))
+ {
+ llwarns << "GenericMessage " << request << " failed to dispatch"
+ << llendl;
+ }
+}
diff --git a/indra/newview/llviewergenericmessage.h b/indra/newview/llviewergenericmessage.h
new file mode 100644
index 0000000000..547421648c
--- /dev/null
+++ b/indra/newview/llviewergenericmessage.h
@@ -0,0 +1,26 @@
+/**
+ * @file llviewergenericmessage.h
+ * @brief Handle processing of "generic messages" which contain short lists of strings.
+ * @author James Cook
+ *
+ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#ifndef LLVIEWERGENERICMESSAGE_H
+#define LLVIEWERGENERICMESSAGE_H
+
+class LLUUID;
+class LLDispatcher;
+
+
+void send_generic_message(const char* method,
+ const std::vector<std::string>& strings,
+ const LLUUID& invoice = LLUUID::null);
+
+void process_generic_message(LLMessageSystem* msg, void**);
+
+
+extern LLDispatcher gGenericDispatcher;
+
+#endif
diff --git a/indra/newview/llviewergesture.cpp b/indra/newview/llviewergesture.cpp
index 69bee4431f..f5ef19cc33 100644
--- a/indra/newview/llviewergesture.cpp
+++ b/indra/newview/llviewergesture.cpp
@@ -123,69 +123,6 @@ LLViewerGestureList::LLViewerGestureList()
mIsLoaded = FALSE;
}
-void LLViewerGestureList::saveToServer()
-{
- U8 *buffer = new U8[getMaxSerialSize()];
-
- U8 *end = serialize(buffer);
-
- if (end - buffer > getMaxSerialSize())
- {
- llerrs << "Wrote off end of buffer, serial size computation is wrong" << llendl;
- }
-
- //U64 xfer_id = gXferManager->registerXfer(buffer, end - buffer);
- // write to a file because mem<->mem xfer isn't implemented
- LLUUID random_uuid;
- char filename[LL_MAX_PATH]; /* Flawfinder: ignore */
- random_uuid.generate();
- random_uuid.toString(filename);
- strcat(filename,".tmp"); /* Flawfinder: ignore */
-
- char filename_and_path[LL_MAX_PATH]; /* Flawfinder: ignore */
- snprintf(filename_and_path, LL_MAX_PATH, "%s%s%s", /* Flawfinder: ignore */
- gDirUtilp->getTempDir().c_str(),
- gDirUtilp->getDirDelimiter().c_str(),
- filename);
-
- FILE* fp = LLFile::fopen(filename_and_path, "wb"); /* Flawfinder: ignore */
-
- if (fp)
- {
- fwrite(buffer, end - buffer, 1, fp);
- fclose(fp);
-
- gMessageSystem->newMessageFast(_PREHASH_GestureUpdate);
- gMessageSystem->nextBlockFast(_PREHASH_AgentBlock);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addStringFast(_PREHASH_Filename, filename);
- gMessageSystem->addBOOLFast(_PREHASH_ToViewer, FALSE);
- gMessageSystem->sendReliable(gUserServer);
- }
-
- delete[] buffer;
-}
-
-/*
-void LLViewerGestureList::requestFromServer()
-{
- gMessageSystem->newMessageFast(_PREHASH_GestureRequest);
- gMessageSystem->nextBlockFast(_PREHASH_AgentBlock);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, agent_get_id());
- gMessageSystem->addU8("Reset", 0);
- gMessageSystem->sendReliable(gUserServer);
-}
-
-void LLViewerGestureList::requestResetFromServer( BOOL is_male )
-{
- gMessageSystem->newMessageFast(_PREHASH_GestureRequest);
- gMessageSystem->nextBlockFast(_PREHASH_AgentBlock);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, agent_get_id());
- gMessageSystem->addU8("Reset", is_male ? 1 : 2);
- gMessageSystem->sendReliable(gUserServer);
- mIsLoaded = FALSE;
-}
-*/
// helper for deserialize that creates the right LLGesture subclass
LLGesture *LLViewerGestureList::create_gesture(U8 **buffer, S32 max_size)
@@ -247,14 +184,3 @@ void LLViewerGestureList::xferCallback(void *data, S32 size, void** /*user_data*
llwarns << "Unable to load gesture list!" << llendl;
}
}
-
-// static
-void LLViewerGestureList::processGestureUpdate(LLMessageSystem *msg, void** /*user_data*/)
-{
- char remote_filename[MAX_STRING]; /* Flawfinder: ignore */
- msg->getStringFast(_PREHASH_AgentBlock, _PREHASH_Filename, MAX_STRING, remote_filename);
-
-
- gXferManager->requestFile(remote_filename, LL_PATH_CACHE, msg->getSender(), TRUE, xferCallback, NULL,
- LLXferManager::HIGH_PRIORITY);
-}
diff --git a/indra/newview/llviewergesture.h b/indra/newview/llviewergesture.h
index ced12a7c34..6eca0d1eca 100644
--- a/indra/newview/llviewergesture.h
+++ b/indra/newview/llviewergesture.h
@@ -45,7 +45,6 @@ class LLViewerGestureList : public LLGestureList
public:
LLViewerGestureList();
- void saveToServer();
//void requestFromServer();
BOOL getIsLoaded() { return mIsLoaded; }
@@ -57,7 +56,6 @@ public:
BOOL matchPrefix(const std::string& in_str, std::string* out_str);
static void xferCallback(void *data, S32 size, void** /*user_data*/, S32 status);
- static void processGestureUpdate(LLMessageSystem *msg, void** /*user_data*/);
protected:
LLGesture *create_gesture(U8 **buffer, S32 max_size);
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index e9d2218d55..2ac1c30ae5 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -95,7 +95,6 @@
#include "llfloateropenobject.h"
#include "llfloaterpermissionsmgr.h"
#include "llfloaterpreference.h"
-#include "llfloaterrate.h"
#include "llfloaterregioninfo.h"
#include "llfloaterreporter.h"
#include "llfloaterscriptdebug.h"
@@ -155,6 +154,7 @@
#include "lluuid.h"
#include "llvelocitybar.h"
#include "llviewercamera.h"
+#include "llviewergenericmessage.h"
#include "llviewergesture.h"
#include "llviewerimagelist.h"
#include "llviewerinventory.h"
@@ -377,8 +377,6 @@ void handle_force_parcel_owner_to_me(void*);
void handle_force_parcel_to_content(void*);
void handle_claim_public_land(void*);
-void handle_god_expunge_user(void*);
-
void handle_god_request_havok(void *);
void handle_god_request_avatar_geometry(void *); // Hack for easy testing of new avatar geometry
void reload_personal_settings_overrides(void *);
@@ -1381,8 +1379,6 @@ void init_server_menu(LLMenuGL* menu)
&handle_force_parcel_to_content,
&enable_god_customer_service, NULL,
'C', MASK_SHIFT | MASK_ALT | MASK_CONTROL));
- //sub->append(new LLMenuItemCallGL("Toggle First Land bit",
- // &handle_toggle_parcel_newbie));
sub->appendSeparator();
sub->append(new LLMenuItemCallGL("Claim Public Land",
&handle_claim_public_land, &enable_god_customer_service));
@@ -1435,33 +1431,6 @@ void cleanup_menus()
// Object pie menu
//-----------------------------------------------------------------------------
-class LLObjectRateCreator : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- LLFloaterRate::show(LLFloaterRate::RS_CREATOR);
- return true;
- }
-};
-
-class LLObjectRateOwner : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- // Don't allow rating of group owned objects.
- LLSelectNode* node = gSelectMgr->getSelection()->getFirstRootNode();
- if (!node) return true;
- if (node->mPermissions->isGroupOwned())
- {
- gViewerWindow->alertXml("CantRateOwnedByGroup");
- return true;
- }
-
- LLFloaterRate::show(LLFloaterRate::RS_OWNER);
- return true;
- }
-};
-
class LLObjectReportAbuse : public view_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
@@ -1471,59 +1440,6 @@ class LLObjectReportAbuse : public view_listener_t
}
};
-// Enable only when you didn't create it, and the creator
-// is not the owner.
-class LLObjectEnableRateCreator : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- LLUUID creator_id;
- LLUUID owner_id;
- LLString dummy;
- BOOL identical_creator = gSelectMgr->selectGetCreator(creator_id, dummy);
-
- BOOL new_value;
- if (!identical_creator)
- {
- new_value = FALSE;
- }
- else
- {
- new_value = (creator_id != gAgent.getID());
- }
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
- }
-};
-
-// Enabled if object owner isn't the agent.
-class LLObjectEnableRateOwner : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- LLUUID owner_id;
- LLString dummy;
- BOOL identical_owner = gSelectMgr->selectGetOwner(owner_id, dummy);
-
- BOOL new_value;
- if (!identical_owner)
- {
- new_value = FALSE;
- }
- else if (owner_id.isNull())
- {
- new_value = FALSE;
- }
- else
- {
- new_value = (owner_id != gAgent.getID());
- }
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
- }
-};
-
-
// Enabled it you clicked an object
class LLObjectEnableReportAbuse : public view_listener_t
{
@@ -2247,20 +2163,6 @@ void login_done(S32 which, void *user)
}
-
-class LLAvatarRate : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() );
- if( avatar )
- {
- LLFloaterRate::show( avatar->getID() );
- }
- return true;
- }
-};
-
void callback_leave_group(S32 option, void *userdata)
{
if (option == 0)
@@ -3397,40 +3299,6 @@ void handle_claim_public_land(void*)
gAgent.sendReliableMessage();
}
-//void handle_toggle_parcel_newbie(void*)
-//{
-// gParcelMgr->toggleParcelGodReserveForNewbie();
-//}
-
-void on_expunge_user(S32 option, const LLString& text, void*)
-{
- if(option == -1) return;
- llinfos << "on_expunge_user(" << option << "," << text << ")" << llendl;
- LLMessageSystem* msg = gMessageSystem;
- LLUUID user_id;
- if(user_id.set(text))
- {
- msg->newMessage("GodExpungeUser");
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", gAgent.getID());
- msg->addUUID("SessionID", gAgent.getSessionID());
- msg->nextBlock("ExpungeData");
- msg->addUUID("AgentID", user_id);
- msg->sendReliable(gUserServer);
- }
- else
- {
- gViewerWindow->alertXml("InvalidUUID");
- }
-}
-
-void handle_god_expunge_user(void*)
-{
- gViewerWindow->alertXmlEditText("ExpungeUser", LLString::format_map_t(),
- NULL, NULL,
- on_expunge_user, NULL);
-}
-
void handle_god_request_havok(void *)
{
if (gAgent.isGodlike())
@@ -6433,14 +6301,7 @@ class LLShowFloater : public view_listener_t
{
if (gParcelMgr->selectionEmpty())
{
- if (gLastHitPosGlobal.isExactlyZero())
- {
- gParcelMgr->selectParcelAt(gAgent.getPositionGlobal());
- }
- else
- {
- gParcelMgr->selectParcelAt( gLastHitPosGlobal );
- }
+ gParcelMgr->selectParcelAt(gAgent.getPositionGlobal());
}
LLFloaterLand::show();
@@ -6449,14 +6310,7 @@ class LLShowFloater : public view_listener_t
{
if (gParcelMgr->selectionEmpty())
{
- if (gLastHitPosGlobal.isExactlyZero())
- {
- gParcelMgr->selectParcelAt(gAgent.getPositionGlobal());
- }
- else
- {
- gParcelMgr->selectParcelAt( gLastHitPosGlobal );
- }
+ gParcelMgr->selectParcelAt(gAgent.getPositionGlobal());
}
gParcelMgr->startBuyLand();
@@ -8709,7 +8563,6 @@ void initialize_menu_actions()
// Avatar pie menu
(new LLObjectMute())->registerListener(gMenuHolder, "Avatar.Mute");
- (new LLAvatarRate())->registerListener(gMenuHolder, "Avatar.Rate");
(new LLAvatarAddFriend())->registerListener(gMenuHolder, "Avatar.AddFriend");
(new LLAvatarFreeze())->registerListener(gMenuHolder, "Avatar.Freeze");
(new LLAvatarDebug())->registerListener(gMenuHolder, "Avatar.Debug");
@@ -8731,9 +8584,7 @@ void initialize_menu_actions()
(new LLObjectDelete())->registerListener(gMenuHolder, "Object.Delete");
(new LLObjectAttachToAvatar())->registerListener(gMenuHolder, "Object.AttachToAvatar");
(new LLObjectReturn())->registerListener(gMenuHolder, "Object.Return");
- (new LLObjectRateOwner())->registerListener(gMenuHolder, "Object.RateOwner");
(new LLObjectReportAbuse())->registerListener(gMenuHolder, "Object.ReportAbuse");
- (new LLObjectRateCreator())->registerListener(gMenuHolder, "Object.RateCreator");
(new LLObjectMute())->registerListener(gMenuHolder, "Object.Mute");
(new LLObjectBuy())->registerListener(gMenuHolder, "Object.Buy");
(new LLObjectEdit())->registerListener(gMenuHolder, "Object.Edit");
@@ -8745,9 +8596,7 @@ void initialize_menu_actions()
(new LLObjectEnableDelete())->registerListener(gMenuHolder, "Object.EnableDelete");
(new LLObjectEnableWear())->registerListener(gMenuHolder, "Object.EnableWear");
(new LLObjectEnableReturn())->registerListener(gMenuHolder, "Object.EnableReturn");
- (new LLObjectEnableRateOwner())->registerListener(gMenuHolder, "Object.EnableRateOwner");
(new LLObjectEnableReportAbuse())->registerListener(gMenuHolder, "Object.EnableReportAbuse");
- (new LLObjectEnableRateCreator())->registerListener(gMenuHolder, "Object.EnableRateCreator");
(new LLObjectEnableMute())->registerListener(gMenuHolder, "Object.EnableMute");
(new LLObjectEnableBuy())->registerListener(gMenuHolder, "Object.EnableBuy");
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index cc1beefec5..316de37ce1 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -87,6 +87,7 @@
#include "llui.h" // for make_ui_sound
#include "lluploaddialog.h"
#include "llviewercamera.h"
+#include "llviewergenericmessage.h"
#include "llviewerinventory.h"
#include "llviewermenu.h"
#include "llviewerobject.h"
@@ -123,8 +124,6 @@ extern BOOL gDebugClicks;
extern void bad_network_handler();
-LLDispatcher gGenericDispatcher;
-
// function prototypes
void open_offer(const std::vector<LLUUID>& items);
void friendship_offer_callback(S32 option, void* user_data);
@@ -1540,26 +1539,90 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
break;
}
case IM_GROUP_VOTE:
+ {
+ LLUUID *userdata = new LLUUID(session_id);
+ args["[NAME]"] = name;
+ args["[MESSAGE]"] = message;
+ LLNotifyBox::showXml("GroupVote", args,
+ &group_vote_callback, userdata);
+ }
+ break;
+
+ case IM_GROUP_ELECTION_DEPRECATED:
+ {
+ llwarns << "Received IM: IM_GROUP_ELECTION_DEPRECATED" << llendl;
+ }
+ break;
+
+ case IM_SESSION_911_SEND:
+ {
+ //this is just the same code as IM_SESSION_SEND for a bit
+ //I was too lazy to make this a function....sorry - jwolk
+ if (!is_linden && is_busy)
{
- LLUUID *userdata = new LLUUID(session_id);
- args["[NAME]"] = name;
- args["[MESSAGE]"] = message;
- LLNotifyBox::showXml("GroupVote", args,
- &group_vote_callback, userdata);
+ return;
+ }
+
+ // standard message, not from system
+ char saved[MAX_STRING]; /* Flawfinder: ignore */
+ saved[0] = '\0';
+ if(offline == IM_OFFLINE)
+ {
+ char time_buf[TIME_STR_LENGTH]; /* Flawfinder: ignore */
+ snprintf(saved, /* Flawfinder: ignore */
+ MAX_STRING,
+ "(Saved %s) ",
+ formatted_time(timestamp, time_buf));
+ }
+
+ snprintf(buffer, /* Flawfinder: ignore */
+ sizeof(buffer),
+ "%s%s%s%s",
+ name,
+ separator_string,
+ saved,
+ (message+message_offset));
+
+ BOOL is_this_agent = FALSE;
+ if(from_id == gAgentID)
+ {
+ from_id = LLUUID::null;
+ is_this_agent = TRUE;
}
- break;
- case IM_GROUP_ELECTION_DEPRECATED:
+ gIMView->addMessage(
+ session_id,
+ from_id,
+ name,
+ buffer,
+ (char*)binary_bucket,
+ IM_SESSION_ADD,
+ parent_estate_id,
+ region_id,
+ position);
+
+ snprintf(buffer, sizeof(buffer), "IM: %s%s%s%s", name, separator_string, saved, (message+message_offset)); /* Flawfinder: ignore */
+ chat.mText = buffer;
+ LLFloaterChat::addChat(chat, TRUE, is_this_agent);
+
+ //ok, now we want to add a teleport button if we are receving
+ //a message from not ourself
+ LLFloaterIMPanel* panel =
+ gIMView->findFloaterBySession(session_id);
+
+ if (panel && !is_this_agent )
{
- llwarns << "Received IM: IM_GROUP_ELECTION_DEPRECATED" << llendl;
+ //don't add a teleport button for yourself
+ panel->addTeleportButton();
}
break;
+ }
case IM_SESSION_SEND:
+ {
+ if (!is_linden && is_busy)
{
- if (!is_linden && is_busy)
- {
- return;
- }
+ return;
+ }
// System messages, specifically "Foo Bar has left this session"
// are not shown unless you actually have that session open.
@@ -1571,40 +1634,40 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
return;
}
- // standard message, not from system
- char saved[MAX_STRING]; /* Flawfinder: ignore */
- saved[0] = '\0';
- if(offline == IM_OFFLINE)
- {
- char time_buf[TIME_STR_LENGTH]; /* Flawfinder: ignore */
- snprintf(saved, /* Flawfinder: ignore */
- MAX_STRING,
- "(Saved %s) ",
- formatted_time(timestamp, time_buf));
- }
- snprintf(buffer, sizeof(buffer), "%s%s%s%s", name, separator_string, saved, (message+message_offset)); /* Flawfinder: ignore */
- BOOL is_this_agent = FALSE;
- if(from_id == gAgentID)
- {
- from_id = LLUUID::null;
- is_this_agent = TRUE;
- }
- gIMView->addMessage(
- session_id,
- from_id,
- name,
- buffer,
- (char*)binary_bucket,
- IM_SESSION_ADD,
- parent_estate_id,
- region_id,
- position);
-
- snprintf(buffer, sizeof(buffer), "IM: %s%s%s%s", name, separator_string, saved, (message+message_offset)); /* Flawfinder: ignore */
- chat.mText = buffer;
- LLFloaterChat::addChat(chat, TRUE, is_this_agent);
+ // standard message, not from system
+ char saved[MAX_STRING]; /* Flawfinder: ignore */
+ saved[0] = '\0';
+ if(offline == IM_OFFLINE)
+ {
+ char time_buf[TIME_STR_LENGTH]; /* Flawfinder: ignore */
+ snprintf(saved, /* Flawfinder: ignore */
+ MAX_STRING,
+ "(Saved %s) ",
+ formatted_time(timestamp, time_buf));
}
- break;
+ snprintf(buffer, sizeof(buffer), "%s%s%s%s", name, separator_string, saved, (message+message_offset)); /* Flawfinder: ignore */
+ BOOL is_this_agent = FALSE;
+ if(from_id == gAgentID)
+ {
+ from_id = LLUUID::null;
+ is_this_agent = TRUE;
+ }
+ gIMView->addMessage(
+ session_id,
+ from_id,
+ name,
+ buffer,
+ (char*)binary_bucket,
+ IM_SESSION_ADD,
+ parent_estate_id,
+ region_id,
+ position);
+
+ snprintf(buffer, sizeof(buffer), "IM: %s%s%s%s", name, separator_string, saved, (message+message_offset)); /* Flawfinder: ignore */
+ chat.mText = buffer;
+ LLFloaterChat::addChat(chat, TRUE, is_this_agent);
+ }
+ break;
case IM_FROM_TASK:
if (is_busy && !is_owned_by_me)
@@ -1675,21 +1738,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
}
break;
- case IM_LURE_911:
- {
- // HACK -- the from_id is the im_session_id
- LLFloaterIMPanel* panel = gIMView->findFloaterBySession(session_id);
- if (panel)
- {
- panel->addTeleportButton(from_id);
- }
- else
- {
- llinfos << "LLFloaterIMPanel not found for " << session_id << " from " << from_id << llendl;
- }
- }
- break;
-
case IM_GOTO_URL:
{
char* url = new char[binary_bucket_size];
@@ -2299,7 +2347,18 @@ void process_teleport_progress(LLMessageSystem* msg, void**)
char buffer[MAX_STRING]; /* Flawfinder: ignore */
msg->getString("Info", "Message", MAX_STRING, buffer);
lldebugs << "teleport progress: " << buffer << llendl;
- gAgent.setTeleportMessage(buffer);
+
+ //Sorta hacky...default to using simulator raw messages
+ //if we don't find the coresponding mapping in our progress mappings
+ LLString message = buffer;
+
+ if (LLAgent::sTeleportProgressMessages.find(buffer) !=
+ LLAgent::sTeleportProgressMessages.end() )
+ {
+ message = LLAgent::sTeleportProgressMessages[buffer];
+ }
+
+ gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages[message]);
}
class LLFetchInWelcomeArea : public LLInventoryFetchDescendentsObserver
@@ -2456,7 +2515,7 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
send_complete_agent_movement(sim_host);
gAgent.setTeleportState( LLAgent::TELEPORT_MOVING );
- gAgent.setTeleportMessage("Contacting New Region...");
+ gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages["contacting"]);
regionp->setSeedCapability(std::string(seedCap));
@@ -2492,6 +2551,8 @@ void process_avatar_init_complete(LLMessageSystem* msg, void**)
void process_agent_movement_complete(LLMessageSystem* msg, void**)
{
+ gAgentMovementCompleted = TRUE;
+
LLUUID agent_id;
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
LLUUID session_id;
@@ -4295,7 +4356,7 @@ void process_teleport_failed(LLMessageSystem *msg, void**)
msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, STD_STRING_BUF_SIZE, reason);
LLStringBase<char>::format_map_t args;
- args["[REASON]"] = reason;
+ args["[REASON]"] = LLAgent::sTeleportErrorMessages[reason];
gViewerWindow->alertXml("CouldNotTeleportReason", args);
if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
@@ -4449,25 +4510,6 @@ void handle_lure_callback_godlike(S32 option, void* userdata)
handle_lure_callback(option, LLString::null, userdata);
}
-void send_lure_911(void** user_data, S32 result)
-{
- LLUUID im_session_id(*((LLUUID*)user_data));
- LLString name;
- gAgent.getName(name);
- LLString text = name + " needs help"; // this text is ignored for 911 lures
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_StartLure);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_Info);
- msg->addU8Fast(_PREHASH_LureType, (U8)IM_LURE_911);
- msg->addStringFast(_PREHASH_Message, text.c_str());
- msg->nextBlockFast(_PREHASH_TargetData);
- msg->addUUIDFast(_PREHASH_TargetID, im_session_id);
- gAgent.sendReliableMessage();
-}
-
void handle_lure(const LLUUID& invitee)
{
LLDynamicArray<LLUUID> ids;
@@ -4985,59 +5027,6 @@ void onCovenantLoadComplete(LLVFS *vfs,
LLFloaterBuyLand::updateCovenantText(covenant_text, asset_uuid);
}
-void send_generic_message(const char* method,
- const std::vector<std::string>& strings,
- const LLUUID& invoice)
-{
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessage("GenericMessage");
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
- msg->nextBlock("MethodData");
- msg->addString("Method", method);
- msg->addUUID("Invoice", invoice);
- if(strings.empty())
- {
- msg->nextBlock("ParamList");
- msg->addString("Parameter", NULL);
- }
- else
- {
- std::vector<std::string>::const_iterator it = strings.begin();
- std::vector<std::string>::const_iterator end = strings.end();
- for(; it != end; ++it)
- {
- msg->nextBlock("ParamList");
- msg->addString("Parameter", (*it).c_str());
- }
- }
- gAgent.sendReliableMessage();
-}
-
-
-void process_generic_message(LLMessageSystem* msg, void**)
-{
- LLUUID agent_id;
- msg->getUUID("AgentData", "AgentID", agent_id);
- if (agent_id != gAgent.getID())
- {
- llwarns << "GenericMessage for wrong agent" << llendl;
- return;
- }
-
- std::string request;
- LLUUID invoice;
- LLDispatcher::sparam_t strings;
- LLDispatcher::unpackMessage(msg, request, invoice, strings);
-
- if(!gGenericDispatcher.dispatch(request, invoice, strings))
- {
- llwarns << "GenericMessage " << request << " failed to dispatch"
- << llendl;
- }
-}
void process_feature_disabled_message(LLMessageSystem* msg, void**)
{
@@ -5062,3 +5051,6 @@ void invalid_message_callback(LLMessageSystem* msg,
{
bad_network_handler();
}
+
+// Please do not add more message handlers here. This file is huge.
+// Put them in a file related to the functionality you are implementing. JC
diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h
index c7d22656c7..04fb668aba 100644
--- a/indra/newview/llviewermessage.h
+++ b/indra/newview/llviewermessage.h
@@ -9,12 +9,10 @@
#ifndef LL_LLVIEWERMESSAGE_H
#define LL_LLVIEWERMESSAGE_H
-//#include "linked_lists.h"
#include "llinstantmessage.h"
#include "lltransactiontypes.h"
#include "lluuid.h"
#include "stdenums.h"
-#include "message.h"
//
// Forward declarations
@@ -23,6 +21,7 @@ class LLColor4;
class LLViewerObject;
class LLInventoryObject;
class LLInventoryItem;
+class LLMessageSystem;
class LLViewerRegion;
//
@@ -169,8 +168,6 @@ void process_decline_callingcard(LLMessageSystem* msg, void**);
// Message system exception prototypes
void invalid_message_callback(LLMessageSystem*, void*, EMessageException);
-void send_lure_911(void** user_data, S32 result);
-
void process_initiate_download(LLMessageSystem* msg, void**);
void inventory_offer_callback(S32 option, void* user_data);
@@ -189,15 +186,7 @@ struct LLOfferInfo
LLHost mHost;
};
-void send_generic_message(const char* method,
- const std::vector<std::string>& strings,
- const LLUUID& invoice = LLUUID::null);
-
-void process_generic_message(LLMessageSystem* msg, void**);
-
void process_feature_disabled_message(LLMessageSystem* msg, void**);
-extern LLDispatcher gGenericDispatcher;
-
#endif
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index c3f2b2d2f6..5af3d532a6 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -1347,7 +1347,6 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
LLUUID owner_id;
BOOL is_group_owned;
U32 auction_id = 0;
- BOOL is_reserved = FALSE;
S32 claim_price_per_meter = 0;
S32 rent_price_per_meter = 0;
S32 claim_date = 0;
@@ -1424,7 +1423,6 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
msg->getUUIDFast(_PREHASH_ParcelData, _PREHASH_OwnerID, owner_id);
msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_IsGroupOwned, is_group_owned);
msg->getU32Fast(_PREHASH_ParcelData, _PREHASH_AuctionID, auction_id);
- msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_ReservedNewbie, is_reserved);
msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_ClaimDate, claim_date);
msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_ClaimPrice, claim_price_per_meter);
msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_RentPrice, rent_price_per_meter);
@@ -1461,7 +1459,6 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
parcel->setAABBMax(aabb_max);
parcel->setAuctionID(auction_id);
- parcel->setReservedForNewbie(is_reserved);
parcel->setOwnershipStatus((LLParcel::EOwnershipStatus)status);
parcel->setSimWideMaxPrimCapacity(sw_max_prims);
@@ -2214,16 +2211,10 @@ bool LLViewerParcelMgr::canAgentBuyParcel(LLParcel* parcel, bool forGroup) const
bool isOwner
= parcelOwner == (forGroup ? gAgent.getGroupID() : gAgent.getID());
- bool isAvailable
- = parcel->getReservedForNewbie()
- ? (!forGroup && gStatusBar->getSquareMetersCommitted() == 0)
- : true;
- // *TODO: should be based on never_owned_land, see SL-10728
-
bool isAuthorized
= (authorizeBuyer.isNull() || (gAgent.getID() == authorizeBuyer));
- return isForSale && !isOwner && isAuthorized && isAvailable && isEmpowered;
+ return isForSale && !isOwner && isAuthorized && isEmpowered;
}
diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h
index ae772aebf1..ae288d70ec 100644
--- a/indra/newview/llviewerparcelmgr.h
+++ b/indra/newview/llviewerparcelmgr.h
@@ -203,12 +203,6 @@ public:
// make the selected parcel a content parcel.
void sendParcelGodForceToContent();
- // Take the selected parcel, and toggle it's 'reserved for newbie'
- // status.
- // *NOTE: There is no longer a newbie toggle. It is a linden sale
- // for newbie now.
- //void toggleParcelGodReserveForNewbie();
-
// Pack information about this parcel and send it to the region
// containing the southwest corner of the selection.
// If want_reply_to_update, simulator will send back a ParcelProperties
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index cc93ea8bdc..303e83d672 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -15,7 +15,6 @@
#include "llhttpclient.h"
#include "llregionflags.h"
#include "llregionhandle.h"
-#include "llsdmessagesystem.h"
#include "llsurface.h"
#include "message.h"
//#include "vmath.h"
@@ -24,6 +23,7 @@
#include "llagent.h"
#include "llcallingcard.h"
+#include "llcaphttpsender.h"
#include "lldir.h"
#include "lleventpoll.h"
#include "llfloatergodtools.h"
@@ -38,6 +38,12 @@
#include "llvocache.h"
#include "llvoclouds.h"
#include "llworld.h"
+#include "viewer.h"
+
+// Viewer object cache version, change if object update
+// format changes. JC
+const U32 INDRA_OBJECT_CACHE_VERSION = 12;
+
extern BOOL gNoRender;
@@ -142,6 +148,7 @@ LLViewerRegion::~LLViewerRegion()
delete mParcelOverlay;
delete mLandp;
delete mEventPoll;
+ LLHTTPSender::clearSender(mHost);
saveCache();
}
@@ -1278,35 +1285,34 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
capabilityNames.append("SendUserReport");
capabilityNames.append("SendUserReportWithScreenshot");
capabilityNames.append("RequestTextureDownload");
+ capabilityNames.append("UntrustedSimulatorMessage");
+
LLHTTPClient::post(url, capabilityNames, BaseCapabilitiesComplete::build(this));
}
static
LLEventPoll* createViewerEventPoll(const std::string& url)
{
- static LLHTTPNode eventRoot;
- static bool eventRootServicesAdded = false;
- if (!eventRootServicesAdded)
- {
- LLSDMessageSystem::useServices();
- LLHTTPRegistrar::buildAllServices(eventRoot);
- eventRootServicesAdded = true;
- }
-
- return new LLEventPoll(url, eventRoot);
+ return new LLEventPoll(url);
}
void LLViewerRegion::setCapability(const std::string& name, const std::string& url)
{
- mCapabilities[name] = url;
-
- if (name == "EventQueueGet")
+ if(name == "EventQueueGet")
{
delete mEventPoll;
mEventPoll = NULL;
mEventPoll = createViewerEventPoll(url);
}
+ else if(name == "UntrustedSimulatorMessage")
+ {
+ LLHTTPSender::setSender(mHost, new LLCapHTTPSender(url));
+ }
+ else
+ {
+ mCapabilities[name] = url;
+ }
}
std::string LLViewerRegion::getCapability(const std::string& name) const
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index f11f9fb1be..1b3c0193f4 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -610,22 +610,19 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask
// Topmost view gets a chance before the hierarchy
LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
+ BOOL mouse_over_top_ctrl = FALSE;
if (top_ctrl)
{
S32 local_x, local_y;
top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
if (top_ctrl->pointInView(local_x, local_y))
{
+ mouse_over_top_ctrl = TRUE;
if(top_ctrl->handleMouseDown(local_x, local_y, mask))
{
return TRUE;
}
}
- else if (top_ctrl->hasFocus())
- {
- // always defocus top view if we click off of it
- top_ctrl->setFocus(FALSE);
- }
}
// Give the UI views a chance to process the click
@@ -636,6 +633,11 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask
llinfos << "Left Mouse Down" << LLView::sMouseHandlerMessage << llendl;
LLView::sMouseHandlerMessage = "";
}
+ if (top_ctrl && top_ctrl->hasFocus() && !mouse_over_top_ctrl)
+ {
+ // always defocus top view if we click off of it
+ top_ctrl->setFocus(FALSE);
+ }
return TRUE;
}
else if (LLView::sDebugMouseHandling)
@@ -643,6 +645,12 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask
llinfos << "Left Mouse Down not handled by view" << llendl;
}
+ if (top_ctrl && top_ctrl->hasFocus() && !mouse_over_top_ctrl)
+ {
+ // always defocus top view if we click off of it
+ top_ctrl->setFocus(FALSE);
+ }
+
if (gDisconnected)
{
return FALSE;
@@ -699,24 +707,19 @@ BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK ma
// Check for hit on UI.
LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
+ BOOL mouse_over_top_ctrl = FALSE;
if (top_ctrl)
{
S32 local_x, local_y;
top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
if (top_ctrl->pointInView(local_x, local_y))
{
+ mouse_over_top_ctrl = TRUE;
if(top_ctrl->handleDoubleClick(local_x, local_y, mask))
{
return TRUE;
}
}
- else
- {
- if (top_ctrl->hasFocus())
- {
- top_ctrl->setFocus(FALSE);
- }
- }
}
if (mRootView->handleDoubleClick(x, y, mask))
@@ -726,6 +729,11 @@ BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK ma
llinfos << "Left Mouse Down" << LLView::sMouseHandlerMessage << llendl;
LLView::sMouseHandlerMessage = "";
}
+ if (top_ctrl && top_ctrl->hasFocus() && !mouse_over_top_ctrl)
+ {
+ // always defocus top view if we click off of it
+ top_ctrl->setFocus(FALSE);
+ }
return TRUE;
}
else if (LLView::sDebugMouseHandling)
@@ -733,7 +741,13 @@ BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK ma
llinfos << "Left Mouse Down not handled by view" << llendl;
}
- // Why is this here? JC 9/3/2002
+ if (top_ctrl && top_ctrl->hasFocus() && !mouse_over_top_ctrl)
+ {
+ // always defocus top view if we click off of it
+ top_ctrl->setFocus(FALSE);
+ }
+
+ // Why is this here? JC 9/3/2002
if (gNoRender)
{
return TRUE;
@@ -903,24 +917,19 @@ BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK
}
LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
+ BOOL mouse_over_top_ctrl = FALSE;
if (top_ctrl)
{
S32 local_x, local_y;
top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
if (top_ctrl->pointInView(local_x, local_y))
{
+ mouse_over_top_ctrl = TRUE;
if(top_ctrl->handleRightMouseDown(local_x, local_y, mask))
{
return TRUE;
}
}
- else
- {
- if (top_ctrl->hasFocus())
- {
- top_ctrl->setFocus(FALSE);
- }
- }
}
if( mRootView->handleRightMouseDown(x, y, mask) )
@@ -930,6 +939,11 @@ BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK
llinfos << "Right Mouse Down" << LLView::sMouseHandlerMessage << llendl;
LLView::sMouseHandlerMessage = "";
}
+ if (top_ctrl && top_ctrl->hasFocus() && !mouse_over_top_ctrl)
+ {
+ // always defocus top view if we click off of it
+ top_ctrl->setFocus(FALSE);
+ }
return TRUE;
}
else if (LLView::sDebugMouseHandling)
@@ -937,6 +951,12 @@ BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK
llinfos << "Right Mouse Down not handled by view" << llendl;
}
+ if (top_ctrl && top_ctrl->hasFocus() && !mouse_over_top_ctrl)
+ {
+ // always defocus top view if we click off of it
+ top_ctrl->setFocus(FALSE);
+ }
+
if (gToolMgr)
{
if(gToolMgr->getCurrentTool()->handleRightMouseDown( x, y, mask ) )
@@ -1464,8 +1484,27 @@ LLViewerWindow::LLViewerWindow(
// stuff like AGP if we think that it'll crash the viewer.
//
gFeatureManagerp->initGraphicsFeatureMasks();
+
+ // The ATI Mobility Radeon with 1.15.0 causes crashes in FMOD on startup for
+ // unknown reasons, but only if you have an old settings.ini file.
+ // In this case, force the graphics settings back to recommended, but only
+ // do it once. JC
+ std::string gpu_string = gFeatureManagerp->getGPUString();
+ LLString::toLower(gpu_string);
+ bool upgrade_to_1_15 = (gSavedSettings.getString("LastRunVersion") != "1.15.0");
+ bool mobility_radeon = (gpu_string.find("mobility radeon") != std::string::npos);
+ bool mobility_radeon_upgrade_hack = upgrade_to_1_15 && mobility_radeon;
+ if (mobility_radeon_upgrade_hack)
+ {
+ llinfos << "1.15.0 update on Mobility Radeon" << llendl;
+ llinfos << "Forcing recommended graphics settings" << llendl;
+ llinfos << "Forcing audio off" << llendl;
+ gUseAudio = FALSE;
+ }
+
if (gFeatureManagerp->isSafe()
- || (gSavedSettings.getS32("LastFeatureVersion") != gFeatureManagerp->getVersion()))
+ || (gSavedSettings.getS32("LastFeatureVersion") != gFeatureManagerp->getVersion())
+ || mobility_radeon_upgrade_hack)
{
gFeatureManagerp->applyRecommendedFeatures();
}
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index e74c286e43..2b821bed9f 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -3060,6 +3060,13 @@ void LLVOAvatar::updateCharacter(LLAgent &agent)
return;
}
+ // For fading out the names above heads, only let the timer
+ // run if we're visible.
+ if (mDrawable.notNull() && !mDrawable->isVisible())
+ {
+ mTimeVisible.reset();
+ }
+
if (!mIsSelf && !isVisible())
{
return;
@@ -3090,13 +3097,6 @@ void LLVOAvatar::updateCharacter(LLAgent &agent)
getOffObject();
}
- // For fading out the names above heads, only let the timer
- // run if we're visible.
- if (mDrawable.notNull() && !mDrawable->isVisible())
- {
- mTimeVisible.reset();
- }
-
//--------------------------------------------------------------------
// create local variables in world coords for region position values
//--------------------------------------------------------------------
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index c00a202f91..cf57ae3cd0 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -219,6 +219,7 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)
curl_easy_setopt(mCurl, CURLOPT_ERRORBUFFER, &mCurlErrorBuffer);
curl_easy_setopt(mCurl, CURLOPT_CAINFO, gDirUtilp->getCAFile().c_str());
curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYPEER, gVerifySSLCert);
+ curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYHOST, gVerifySSLCert? 2 : 0);
/* Setting the DNS cache timeout to -1 disables it completely.
This might help with bug #503 */
diff --git a/indra/test/llhttpclient_tut.cpp b/indra/test/llhttpclient_tut.cpp
index 865af98761..b169499543 100644
--- a/indra/test/llhttpclient_tut.cpp
+++ b/indra/test/llhttpclient_tut.cpp
@@ -216,7 +216,7 @@ namespace tut
template<> template<>
void HTTPClientTestObject::test<1>()
{
- LLHTTPClient::get("http://www.google.com/", newResult());
+ LLHTTPClient::get("http://www.secondlife.com/", newResult());
runThePump();
ensureStatusOK();
ensure("result object wasn't destroyed", mResultDeleted);
diff --git a/indra/test/lliohttpserver_tut.cpp b/indra/test/lliohttpserver_tut.cpp
index 1284a1fc0d..2f64cc81d7 100644
--- a/indra/test/lliohttpserver_tut.cpp
+++ b/indra/test/lliohttpserver_tut.cpp
@@ -97,7 +97,7 @@ namespace tut
LLSD context;
chain.push_back(LLIOPipe::ptr_t(injector));
- LLCreateHTTPPipe(chain, mRoot);
+ LLCreateHTTPPipe(chain, mRoot, LLSD());
chain.push_back(LLIOPipe::ptr_t(extractor));
pump->addChain(chain, DEFAULT_CHAIN_EXPIRY_SECS);
@@ -278,6 +278,33 @@ namespace tut
);
}
+ template<> template<>
+ void HTTPServiceTestObject::test<7>()
+ {
+ // test large request
+ std::stringstream stream;
+
+ //U32 size = 36 * 1024 * 1024;
+ //U32 size = 36 * 1024;
+ //std::vector<char> data(size);
+ //memset(&(data[0]), '1', size);
+ //data[size - 1] = '\0';
+
+
+ //std::string result = httpPOST("web/echo", &(data[0]));
+
+ stream << "<llsd><array>";
+ for(U32 i = 0; i < 1000000; ++i)
+ {
+ stream << "<integer>42</integer>";
+ }
+ stream << "</array></llsd>";
+ llinfos << "HTTPServiceTestObject::test<7>"
+ << stream.str().length() << llendl;
+ std::string result = httpPOST("web/echo", stream.str());
+ ensure_starts_with("large echo status", result, "HTTP/1.0 200 OK\r\n");
+ }
+
/* TO DO:
test generation of not found and method not allowed errors
*/
diff --git a/indra/test/llmessageconfig_tut.cpp b/indra/test/llmessageconfig_tut.cpp
new file mode 100644
index 0000000000..c9a62e5230
--- /dev/null
+++ b/indra/test/llmessageconfig_tut.cpp
@@ -0,0 +1,207 @@
+/**
+ * @file llmessageconfig_tut.cpp
+ * @date March 2007
+ * @brief LLMessageConfig unit tests
+ *
+ * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include <tut/tut.h>
+#include "lltut.h"
+#include "llmessageconfig.h"
+#include "llsdserialize.h"
+#include "llfile.h"
+#include "lltimer.h"
+#include "llframetimer.h"
+
+namespace tut
+{
+ ///var/tmp/babbage/dev/message-liberation/etc
+ static const char file_name[] = "/tmp/message.xml";
+ static const F32 refreshRate = 6.0*1000.0; // milliseconds
+
+ struct LLMessageConfigTestData {
+
+ LLSD getCurrentConfig()
+ {
+ LLSD data;
+ // store aside the current config to overwrite the test ones
+ // when the test finishes
+ llifstream in_file(file_name);
+ if (in_file.is_open())
+ {
+ LLSDSerialize::fromXML(data, in_file);
+ }
+ return data;
+ }
+
+ void writeConfigFile(const LLSD& config)
+ {
+ LLMessageConfig::initClass("simulator", "/tmp");
+ llofstream file(file_name);
+ if (file.is_open())
+ {
+ LLSDSerialize::toPrettyXML(config, file);
+ }
+ file.close();
+ ms_sleep(refreshRate);
+ LLFrameTimer::updateFrameTime();
+ }
+ };
+
+ typedef test_group<LLMessageConfigTestData> LLMessageConfigTestGroup;
+ typedef LLMessageConfigTestGroup::object LLMessageConfigTestObject;
+ LLMessageConfigTestGroup llMessageConfigTestGroup("LLMessageConfig");
+
+ template<> template<>
+ void LLMessageConfigTestObject::test<1>()
+ // tests server defaults
+ {
+ LLSD config_backup = getCurrentConfig();
+ LLSD config;
+ config["serverDefaults"]["simulator"] = "template";
+ writeConfigFile(config);
+ ensure_equals("Ensure server default is not llsd",
+ LLMessageConfig::isServerDefaultBuilderLLSD(),
+ false);
+ ensure_equals("Ensure server default is template",
+ LLMessageConfig::isServerDefaultBuilderTemplate(),
+ true);
+ writeConfigFile(config_backup);
+ }
+
+ template<> template<>
+ void LLMessageConfigTestObject::test<2>()
+ // tests message builders
+ {
+ LLSD config_backup = getCurrentConfig();
+ LLSD config;
+ config["serverDefaults"]["simulator"] = "template";
+ config["messages"]["msg1"]["builder"] = "template";
+ config["messages"]["msg2"]["builder"] = "llsd";
+ writeConfigFile(config);
+ ensure_equals("Ensure msg template builder not llsd",
+ LLMessageConfig::isMessageBuiltLLSD("msg1"),
+ false);
+ ensure_equals("Ensure msg template builder",
+ LLMessageConfig::isMessageBuiltTemplate("msg1"),
+ true);
+ ensure_equals("Ensure msg llsd builder",
+ LLMessageConfig::isMessageBuiltLLSD("msg2"),
+ true);
+ ensure_equals("Ensure msg llsd builder not template",
+ LLMessageConfig::isMessageBuiltTemplate("msg2"),
+ false);
+ writeConfigFile(config_backup);
+ }
+
+ template<> template<>
+ void LLMessageConfigTestObject::test<4>()
+ // tests message builder defaults
+ {
+ LLSD config_backup = getCurrentConfig();
+ LLSD config;
+ config["serverDefaults"]["simulator"] = "llsd";
+ config["messages"]["msg1"]["trusted-sender"] = true;
+ writeConfigFile(config);
+ ensure_equals("Ensure missing message defaults to server builder, not template",
+ LLMessageConfig::isMessageBuiltTemplate("Test"),
+ false);
+ ensure_equals("Ensure missing message default to server builder llsd",
+ LLMessageConfig::isMessageBuiltLLSD("Test"),
+ true);
+ ensure_equals("Ensure missing builder defaults to server builder, not template",
+ LLMessageConfig::isMessageBuiltTemplate("msg1"),
+ false);
+ ensure_equals("Ensure missing builder default to server builder llsd",
+ LLMessageConfig::isMessageBuiltLLSD("msg1"),
+ true);
+
+ ensure_equals("Ensure server default is not llsd",
+ LLMessageConfig::isServerDefaultBuilderLLSD(),
+ true);
+ ensure_equals("Ensure server default is template",
+ LLMessageConfig::isServerDefaultBuilderTemplate(),
+ false);
+
+ writeConfigFile(config_backup);
+ }
+
+ template<> template<>
+ void LLMessageConfigTestObject::test<3>()
+ // tests trusted/untrusted senders
+ {
+ LLSD config_backup = getCurrentConfig();
+ LLSD config;
+ config["serverDefaults"]["simulator"] = "template";
+ config["messages"]["msg1"]["builder"] = "llsd";
+ config["messages"]["msg1"]["trusted-sender"] = false;
+ config["messages"]["msg2"]["builder"] = "llsd";
+ config["messages"]["msg2"]["trusted-sender"] = true;
+ writeConfigFile(config);
+ ensure_equals("Ensure untrusted is not trusted",
+ LLMessageConfig::isMessageTrusted("msg1"),
+ false);
+ ensure_equals("Ensure untrusted is untrusted",
+ LLMessageConfig::isValidUntrustedMessage("msg1"),
+ true);
+ ensure_equals("Ensure trusted is trusted",
+ LLMessageConfig::isMessageTrusted("msg2"),
+ true);
+ ensure_equals("Ensure trusted is not untrusted",
+ LLMessageConfig::isValidUntrustedMessage("msg2"),
+ false);
+ writeConfigFile(config_backup);
+ }
+
+ template<> template<>
+ void LLMessageConfigTestObject::test<5>()
+ // tests trusted/untrusted without flag, only builder
+ {
+ LLSD config_backup = getCurrentConfig();
+ LLSD config;
+ config["serverDefaults"]["simulator"] = "template";
+ config["messages"]["msg1"]["builder"] = "llsd";
+ writeConfigFile(config);
+ ensure_equals("Ensure missing trusted is not trusted",
+ LLMessageConfig::isMessageTrusted("msg1"),
+ false);
+ ensure_equals("Ensure missing trusted is not untrusted",
+ LLMessageConfig::isValidUntrustedMessage("msg1"),
+ false);
+ writeConfigFile(config_backup);
+ }
+
+ template<> template<>
+ void LLMessageConfigTestObject::test<6>()
+ // tests message builder defaults
+ {
+ LLSD config_backup = getCurrentConfig();
+ LLSD config;
+ config["serverDefaults"]["simulator"] = "template";
+ config["messages"]["msg1"]["trusted-sender"] = true;
+ writeConfigFile(config);
+ ensure_equals("Ensure missing message defaults to server builder, not template",
+ LLMessageConfig::isMessageBuiltTemplate("Test"),
+ true);
+ ensure_equals("Ensure missing message default to server builder llsd",
+ LLMessageConfig::isMessageBuiltLLSD("Test"),
+ false);
+ ensure_equals("Ensure missing builder defaults to server builder, not template",
+ LLMessageConfig::isMessageBuiltTemplate("msg1"),
+ true);
+ ensure_equals("Ensure missing builder default to server builder llsd",
+ LLMessageConfig::isMessageBuiltLLSD("msg1"),
+ false);
+
+ ensure_equals("Ensure server default is not llsd",
+ LLMessageConfig::isServerDefaultBuilderLLSD(),
+ false);
+ ensure_equals("Ensure server default is template",
+ LLMessageConfig::isServerDefaultBuilderTemplate(),
+ true);
+
+ writeConfigFile(config_backup);
+ }
+}
diff --git a/indra/test/llsd_new_tut.cpp b/indra/test/llsd_new_tut.cpp
index 2354698239..0ceb4302ff 100644
--- a/indra/test/llsd_new_tut.cpp
+++ b/indra/test/llsd_new_tut.cpp
@@ -12,82 +12,11 @@
#include "linden_common.h"
#include "lltut.h"
-#include "llsd.h"
+#include "llsdtraits.h"
#include "llstring.h"
namespace tut
{
- template<class T>
- class SDTraits
- {
- protected:
- typedef T (LLSD::*Getter)() const;
-
- LLSD::Type type;
- Getter getter;
-
- public:
- SDTraits();
-
- T get(const LLSD& actual)
- {
- return (actual.*getter)();
- }
-
- bool checkType(const LLSD& actual)
- {
- return actual.type() == type;
- }
- };
-
- template<>
- SDTraits<LLSD::Boolean>::SDTraits()
- : type(LLSD::TypeBoolean), getter(&LLSD::asBoolean)
- { }
-
- template<>
- SDTraits<LLSD::Integer>::SDTraits()
- : type(LLSD::TypeInteger), getter(&LLSD::asInteger)
- { }
-
- template<>
- SDTraits<LLSD::Real>::SDTraits()
- : type(LLSD::TypeReal), getter(&LLSD::asReal)
- { }
-
- template<>
- SDTraits<LLSD::UUID>::SDTraits()
- : type(LLSD::TypeUUID), getter(&LLSD::asUUID)
- { }
-
- template<>
- SDTraits<LLSD::String>::SDTraits()
- : type(LLSD::TypeString), getter(&LLSD::asString)
- { }
-
- template<>
- class SDTraits<LLString> : public SDTraits<LLSD::String>
- { };
-
- template<>
- class SDTraits<const char*> : public SDTraits<LLSD::String>
- { };
-
- template<>
- SDTraits<LLSD::Date>::SDTraits()
- : type(LLSD::TypeDate), getter(&LLSD::asDate)
- { }
-
- template<>
- SDTraits<LLSD::URI>::SDTraits()
- : type(LLSD::TypeURI), getter(&LLSD::asURI)
- { }
-
- template<>
- SDTraits<LLSD::Binary>::SDTraits()
- : type(LLSD::TypeBinary), getter(&LLSD::asBinary)
- { }
-
class SDCleanupCheck
{
private:
@@ -126,7 +55,7 @@ namespace tut
static void ensureTypeAndValue(const char* msg, const LLSD& actual,
T expectedValue)
{
- SDTraits<T> traits;
+ LLSDTraits<T> traits;
std::string s(msg);
@@ -334,7 +263,7 @@ namespace tut
}
LLSD u(str);
- SDTraits<T> traits;
+ LLSDTraits<T> traits;
ensure_equals(msg + " value", traits.get(u), vExpected);
}
diff --git a/indra/test/llsdmessagebuilder_tut.cpp b/indra/test/llsdmessagebuilder_tut.cpp
new file mode 100755
index 0000000000..b153292abc
--- /dev/null
+++ b/indra/test/llsdmessagebuilder_tut.cpp
@@ -0,0 +1,259 @@
+/**
+ * @file llsdmessagebuilder_tut.cpp
+ * @date February 2006
+ * @brief LLSDMessageBuilder unit tests
+ *
+ * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include <tut/tut.h>
+#include "lltut.h"
+
+#include "llsdmessagebuilder.h"
+#include "llsdmessagereader.h"
+#include "llsdtraits.h"
+#include "llquaternion.h"
+#include "u64.h"
+#include "v3dmath.h"
+#include "v3math.h"
+#include "v4math.h"
+
+namespace tut
+{
+ struct LLSDMessageBuilderTestData {
+ static LLSDMessageBuilder defaultBuilder()
+ {
+ LLSDMessageBuilder builder;
+ builder.newMessage("name");
+ builder.nextBlock("block");
+ return builder;
+ }
+
+ static LLSDMessageReader setReader(const LLSDMessageBuilder& builder)
+ {
+ LLSDMessageReader reader;
+ reader.setMessage("name", builder.getMessage());
+ return reader;
+ }
+ };
+
+ typedef test_group<LLSDMessageBuilderTestData> LLSDMessageBuilderTestGroup;
+ typedef LLSDMessageBuilderTestGroup::object LLSDMessageBuilderTestObject;
+ LLSDMessageBuilderTestGroup llsdMessageBuilderTestGroup("LLSDMessageBuilder");
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<1>()
+ // construction and test of undefined
+ {
+ LLSDMessageBuilder builder = defaultBuilder();
+ LLSDMessageReader reader = setReader(builder);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<2>()
+ // BOOL
+ {
+ BOOL outValue, inValue = TRUE;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addBOOL("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getBOOL("block", "var", outValue);
+ ensure_equals("Ensure BOOL", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<3>()
+ // U8
+ {
+ U8 outValue, inValue = 2;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addU8("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getU8("block", "var", outValue);
+ ensure_equals("Ensure U8", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<4>()
+ // S16
+ {
+ S16 outValue, inValue = 90;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addS16("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getS16("block", "var", outValue);
+ ensure_equals("Ensure S16", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<5>()
+ // U16
+ {
+ U16 outValue, inValue = 3;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addU16("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getU16("block", "var", outValue);
+ ensure_equals("Ensure U16", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<6>()
+ // S32
+ {
+ S32 outValue, inValue = 44;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addS32("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getS32("block", "var", outValue);
+ ensure_equals("Ensure S32", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<7>()
+ // F32
+ {
+ F32 outValue, inValue = 121.44;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addF32("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getF32("block", "var", outValue);
+ ensure_equals("Ensure F32", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<8>()
+ // U32
+ {
+ U32 outValue, inValue = 88;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addU32("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getU32("block", "var", outValue);
+ ensure_equals("Ensure U32", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<9>()
+ // U64
+ {
+ U64 outValue, inValue = 121;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addU64("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getU64("block", "var", outValue);
+ ensure_equals("Ensure U64", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<10>()
+ // F64
+ {
+ F64 outValue, inValue = 3232143.33;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addF64("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getF64("block", "var", outValue);
+ ensure_equals("Ensure F64", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<11>()
+ // Vector3
+ {
+ LLVector3 outValue, inValue = LLVector3(1,2,3);
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addVector3("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getVector3("block", "var", outValue);
+ ensure_equals("Ensure Vector3", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<12>()
+ // Vector4
+ {
+ LLVector4 outValue, inValue = LLVector4(1,2,3,4);
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addVector4("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getVector4("block", "var", outValue);
+ ensure_equals("Ensure Vector4", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<13>()
+ // Vector3d
+ {
+ LLVector3d outValue, inValue = LLVector3d(1,2,3);
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addVector3d("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getVector3d("block", "var", outValue);
+ ensure_equals("Ensure Vector3d", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<14>()
+ // Quaternion
+ {
+ LLQuaternion outValue, inValue = LLQuaternion(1,2,3,4);
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addQuat("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getQuat("block", "var", outValue);
+ ensure_equals("Ensure Quaternion", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<15>()
+ // UUID
+ {
+ LLUUID outValue, inValue;
+ inValue.generate();
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addUUID("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getUUID("block", "var", outValue);
+ ensure_equals("Ensure UUID", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<16>()
+ // IPAddr
+ {
+ U32 outValue, inValue = 12344556;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addIPAddr("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getIPAddr("block", "var", outValue);
+ ensure_equals("Ensure IPAddr", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<17>()
+ // IPPort
+ {
+ U16 outValue, inValue = 80;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addIPPort("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getIPPort("block", "var", outValue);
+ ensure_equals("Ensure IPPort", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<18>()
+ {
+ std::string outValue, inValue = "testing";
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addString("var", inValue.c_str());
+ LLSDMessageReader reader = setReader(builder);
+ char buffer[MAX_STRING];
+ reader.getString("block", "var", MAX_STRING, buffer);
+ outValue = buffer;
+ ensure_equals("Ensure String", inValue, outValue);
+ }
+}
+
diff --git a/indra/test/llsdmessagereader_tut.cpp b/indra/test/llsdmessagereader_tut.cpp
new file mode 100755
index 0000000000..31810ae00e
--- /dev/null
+++ b/indra/test/llsdmessagereader_tut.cpp
@@ -0,0 +1,300 @@
+/**
+ * @file llsdmessagereader_tut.cpp
+ * @date February 2006
+ * @brief LLSDMessageReader unit tests
+ *
+ * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include <tut/tut.h>
+#include "lltut.h"
+
+#include "llsdmessagereader.h"
+#include "llsdutil.h"
+
+namespace tut
+{
+ struct LLSDMessageReaderTestData {
+ static void ensureMessageName(const std::string& msg_name,
+ const LLSD& msg_data,
+ const std::string& expected_name)
+ {
+ LLSDMessageReader msg;
+ msg.setMessage(msg_name, msg_data);
+ ensure_equals("Ensure name", std::string(msg.getMessageName()),
+ expected_name);
+ }
+
+ static void ensureNumberOfBlocks(const LLSD& msg_data,
+ const std::string& block,
+ S32 expected_number)
+ {
+ LLSDMessageReader msg;
+ msg.setMessage("fakename", msg_data);
+ ensure_equals("Ensure number of blocks", msg.getNumberOfBlocks(block.c_str()),
+ expected_number);
+ }
+
+ static void ensureMessageSize(const LLSD& msg_data,
+ S32 expected_size)
+ {
+ LLSDMessageReader msg;
+ msg.setMessage("fakename", msg_data);
+ ensure_equals( "Ensure size", msg.getMessageSize(), expected_size);
+ }
+
+ static void ensureBool(const LLSD& msg_data,
+ const std::string& block,
+ const std::string& var,
+ S32 blocknum,
+ BOOL expected)
+ {
+ LLSDMessageReader msg;
+ msg.setMessage("fakename", msg_data);
+ BOOL test_data;
+ msg.getBOOL(block.c_str(), var.c_str(), test_data, blocknum);
+ ensure_equals( "Ensure bool field", test_data, expected);
+ }
+ };
+
+ typedef test_group<LLSDMessageReaderTestData> LLSDMessageReaderTestGroup;
+ typedef LLSDMessageReaderTestGroup::object LLSDMessageReaderTestObject;
+ LLSDMessageReaderTestGroup llsdMessageReaderTestGroup("LLSDMessageReader");
+
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<1>()
+ // construction and test of empty LLSD
+ {
+ LLSD message = LLSD::emptyMap();
+
+ ensureMessageName("", message, "");
+ ensureNumberOfBlocks(message, "Fakeblock", 0);
+ ensureMessageSize(message, 0);
+ }
+
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<2>()
+ // construction and test of simple message with one block
+ {
+ LLSD message = LLSD::emptyMap();
+ message["block1"] = LLSD::emptyArray();
+ message["block1"][0] = LLSD::emptyMap();
+ message["block1"][0]["Field1"] = 0;
+
+ ensureMessageName("name2", message, "name2");
+ ensureNumberOfBlocks(message, "block1", 1);
+ ensureMessageSize(message, 0);
+ }
+
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<3>()
+ // multiple blocks
+ {
+ LLSD message = LLSD::emptyMap();
+ message["block1"] = LLSD::emptyArray();
+ BOOL bool_true = TRUE;
+ BOOL bool_false = FALSE;
+ message["block1"][0] = LLSD::emptyMap();
+ message["block1"][0]["BoolField1"] = bool_true;
+ message["block1"][1] = LLSD::emptyMap();
+ message["block1"][1]["BoolField1"] = bool_false;
+ message["block1"][1]["BoolField2"] = bool_true;
+
+ ensureMessageName("name3", message, "name3");
+ ensureBool(message, "block1", "BoolField1", 0, TRUE);
+ ensureBool(message, "block1", "BoolField1", 1, FALSE);
+ ensureBool(message, "block1", "BoolField2", 1, TRUE);
+ ensureNumberOfBlocks(message, "block1", 2);
+ ensureMessageSize(message, 0);
+ }
+
+ template<typename T>
+ LLSDMessageReader testType(const T& value)
+ {
+ LLSD message = LLSD::emptyMap();
+ message["block"][0]["var"] = value;
+ LLSDMessageReader msg;
+ msg.setMessage("fakename", message);
+ return msg;
+ }
+
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<4>()
+ // S8
+ {
+ S8 outValue, inValue = -3;
+ LLSDMessageReader msg = testType(inValue);
+ msg.getS8("block", "var", outValue);
+ ensure_equals("Ensure S8", outValue, inValue);
+ }
+ template<> template<>
+ void
+ LLSDMessageReaderTestObject::test<5>()
+ // U8
+ {
+ U8 outValue, inValue = 2;
+ LLSDMessageReader msg = testType(inValue);
+ msg.getU8("block", "var", outValue);
+ ensure_equals("Ensure U8", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<6>()
+ // S16
+ {
+ S16 outValue, inValue = 90;
+ LLSDMessageReader msg = testType(inValue);
+ msg.getS16("block", "var", outValue);
+ ensure_equals("Ensure S16", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<7>()
+ // U16
+ {
+ U16 outValue, inValue = 3;
+ LLSDMessageReader msg = testType(inValue);
+ msg.getU16("block", "var", outValue);
+ ensure_equals("Ensure S16", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<8>()
+ // S32
+ {
+ S32 outValue, inValue = 44;
+ LLSDMessageReader msg = testType(inValue);
+ msg.getS32("block", "var", outValue);
+ ensure_equals("Ensure S32", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<9>()
+ // F32
+ {
+ F32 outValue, inValue = 121.44;
+ LLSDMessageReader msg = testType(inValue);
+ msg.getF32("block", "var", outValue);
+ ensure_equals("Ensure F32", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<10>()
+ // U32
+ {
+ U32 outValue, inValue = 88;
+ LLSD sdValue = ll_sd_from_U32(inValue);
+ LLSDMessageReader msg = testType(sdValue);
+ msg.getU32("block", "var", outValue);
+ ensure_equals("Ensure U32", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<11>()
+ // U64
+ {
+ U64 outValue, inValue = 121;
+ LLSD sdValue = ll_sd_from_U64(inValue);
+ LLSDMessageReader msg = testType(sdValue);
+ msg.getU64("block", "var", outValue);
+ ensure_equals("Ensure U64", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<12>()
+ // F64
+ {
+ F64 outValue, inValue = 3232143.33;
+ LLSDMessageReader msg = testType(inValue);
+ msg.getF64("block", "var", outValue);
+ ensure_equals("Ensure F64", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<13>()
+ // String
+ {
+ std::string outValue, inValue = "testing";
+ LLSDMessageReader msg = testType<std::string>(inValue.c_str());
+
+ char buffer[MAX_STRING];
+ msg.getString("block", "var", MAX_STRING, buffer);
+ outValue = buffer;
+ ensure_equals("Ensure String", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<14>()
+ // Vector3
+ {
+ LLVector3 outValue, inValue = LLVector3(1,2,3);
+ LLSD sdValue = ll_sd_from_vector3(inValue);
+ LLSDMessageReader msg = testType(sdValue);
+ msg.getVector3("block", "var", outValue);
+ ensure_equals("Ensure Vector3", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<15>()
+ // Vector4
+ {
+ LLVector4 outValue, inValue = LLVector4(1,2,3,4);
+ LLSD sdValue = ll_sd_from_vector4(inValue);
+ LLSDMessageReader msg = testType(sdValue);
+ msg.getVector4("block", "var", outValue);
+ ensure_equals("Ensure Vector4", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<16>()
+ // Vector3d
+ {
+ LLVector3d outValue, inValue = LLVector3d(1,2,3);
+ LLSD sdValue = ll_sd_from_vector3d(inValue);
+ LLSDMessageReader msg = testType(sdValue);
+ msg.getVector3d("block", "var", outValue);
+ ensure_equals("Ensure Vector3d", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<17>()
+ // Quaternion
+ {
+ LLQuaternion outValue, inValue = LLQuaternion(1,2,3,4);
+ LLSD sdValue = ll_sd_from_quaternion(inValue);
+ LLSDMessageReader msg = testType(sdValue);
+ msg.getQuat("block", "var", outValue);
+ ensure_equals("Ensure Quaternion", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<18>()
+ // UUID
+ {
+ LLUUID outValue, inValue;
+ inValue.generate();
+ LLSDMessageReader msg = testType(inValue);
+ msg.getUUID("block", "var", outValue);
+ ensure_equals("Ensure UUID", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<19>()
+ // IPAddr
+ {
+ U32 outValue, inValue = 12344556;
+ LLSD sdValue = ll_sd_from_ipaddr(inValue);
+ LLSDMessageReader msg = testType(sdValue);
+ msg.getIPAddr("block", "var", outValue);
+ ensure_equals("Ensure IPAddr", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<20>()
+ // IPPort
+ {
+ U16 outValue, inValue = 80;
+ LLSDMessageReader msg = testType(inValue);
+ msg.getIPPort("block", "var", outValue);
+ ensure_equals("Ensure IPPort", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<21>()
+ // Binary
+ {
+ std::vector<U8> outValue(2), inValue(2);
+ inValue[0] = 0;
+ inValue[1] = 1;
+
+ LLSDMessageReader msg = testType(inValue);
+ msg.getBinaryData("block", "var", &(outValue[0]), inValue.size());
+ ensure_equals("Ensure Binary", outValue, inValue);
+ }
+}
+
diff --git a/indra/test/llsdtraits.h b/indra/test/llsdtraits.h
new file mode 100644
index 0000000000..2e6a96a425
--- /dev/null
+++ b/indra/test/llsdtraits.h
@@ -0,0 +1,78 @@
+#ifndef LLSDTRAITS_H
+#define LLSDTRAITS_H
+
+#include "llsd.h"
+#include "llstring.h"
+
+template<class T>
+class LLSDTraits
+{
+ protected:
+ typedef T (LLSD::*Getter)() const;
+
+ LLSD::Type type;
+ Getter getter;
+
+ public:
+ LLSDTraits();
+
+ T get(const LLSD& actual)
+ {
+ return (actual.*getter)();
+ }
+
+ bool checkType(const LLSD& actual)
+ {
+ return actual.type() == type;
+ }
+};
+
+template<> inline
+LLSDTraits<LLSD::Boolean>::LLSDTraits()
+ : type(LLSD::TypeBoolean), getter(&LLSD::asBoolean)
+{ }
+
+template<> inline
+LLSDTraits<LLSD::Integer>::LLSDTraits()
+ : type(LLSD::TypeInteger), getter(&LLSD::asInteger)
+{ }
+
+template<> inline
+LLSDTraits<LLSD::Real>::LLSDTraits()
+ : type(LLSD::TypeReal), getter(&LLSD::asReal)
+{ }
+
+template<> inline
+LLSDTraits<LLSD::UUID>::LLSDTraits()
+ : type(LLSD::TypeUUID), getter(&LLSD::asUUID)
+{ }
+
+template<> inline
+LLSDTraits<LLSD::String>::LLSDTraits()
+ : type(LLSD::TypeString), getter(&LLSD::asString)
+{ }
+
+template<>
+class LLSDTraits<LLString> : public LLSDTraits<LLSD::String>
+{ };
+
+template<>
+class LLSDTraits<const char*> : public LLSDTraits<LLSD::String>
+{ };
+
+template<> inline
+LLSDTraits<LLSD::Date>::LLSDTraits()
+ : type(LLSD::TypeDate), getter(&LLSD::asDate)
+{ }
+
+template<> inline
+LLSDTraits<LLSD::URI>::LLSDTraits()
+ : type(LLSD::TypeURI), getter(&LLSD::asURI)
+{ }
+
+template<> inline
+LLSDTraits<LLSD::Binary>::LLSDTraits()
+ : type(LLSD::TypeBinary), getter(&LLSD::asBinary)
+{ }
+
+#endif // LLSDTRAITS_H
diff --git a/indra/test/llservicebuilder_tut.cpp b/indra/test/llservicebuilder_tut.cpp
new file mode 100644
index 0000000000..b4a814ebb9
--- /dev/null
+++ b/indra/test/llservicebuilder_tut.cpp
@@ -0,0 +1,76 @@
+/**
+* @file llservicebuilder_tut.cpp
+* @brief LLServiceBuilder unit tests
+* @date March 2007
+*
+* Copyright (c) 2006-$CurrentYear$, Linden Research, Inc.
+* $License$
+*/
+
+#include <tut/tut.h>
+#include "lltut.h"
+
+#include "llsd.h"
+#include "llservicebuilder.h"
+
+namespace tut
+{
+
+ struct ServiceBuilderTestData {
+ LLServiceBuilder mServiceBuilder;
+ };
+
+ typedef test_group<ServiceBuilderTestData> ServiceBuilderTestGroup;
+ typedef ServiceBuilderTestGroup::object ServiceBuilderTestObject;
+
+ ServiceBuilderTestGroup serviceBuilderTestGroup("ServiceBuilder");
+
+ template<> template<>
+ void ServiceBuilderTestObject::test<1>()
+ {
+ //Simple service build and reply with no mapping
+ LLSD test_block;
+ test_block["service-builder"] = "/agent/name";
+ mServiceBuilder.createServiceDefinition("ServiceBuilderTest", test_block["service-builder"]);
+ std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilderTest");
+ ensure_equals("Basic URL Creation", test_url , "/agent/name");
+ }
+
+ template<> template<>
+ void ServiceBuilderTestObject::test<2>()
+ {
+ //Simple replace test
+ LLSD test_block;
+ test_block["service-builder"] = "/agent/{$agent-id}/name";
+ mServiceBuilder.createServiceDefinition("ServiceBuilderTest", test_block["service-builder"]);
+ LLSD data_map;
+ data_map["agent-id"] = "257c631f-a0c5-4f29-8a9f-9031feaae6c6";
+ std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilderTest", data_map);
+ ensure_equals("Replacement URL Creation", test_url , "/agent/257c631f-a0c5-4f29-8a9f-9031feaae6c6/name");
+ }
+
+ template<> template<>
+ void ServiceBuilderTestObject::test<3>()
+ {
+ //Incorrect service test
+ LLSD test_block;
+ test_block["service-builder"] = "/agent/{$agent-id}/name";
+ mServiceBuilder.createServiceDefinition("ServiceBuilderTest", test_block["service-builder"]);
+ std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilder");
+ ensure_equals("Replacement URL Creation for Non-existant Service", test_url , "");
+ }
+
+ template<> template<>
+ void ServiceBuilderTestObject::test<4>()
+ {
+ //Incorrect service test
+ LLSD test_block;
+ test_block["service-builder"] = "/agent/{$agent-id}/name";
+ mServiceBuilder.createServiceDefinition("ServiceBuilderTest", test_block["service-builder"]);
+ LLSD data_map;
+ data_map["agent_id"] = "257c631f-a0c5-4f29-8a9f-9031feaae6c6";
+ std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilderTest", data_map);
+ ensure_equals("Replacement URL Creation for Non-existant Service", test_url , "/agent/{$agent-id}/name");
+ }
+}
+
diff --git a/indra/test/test_llmanifest.py b/indra/test/test_llmanifest.py
index cc464237a2..f4fc2820eb 100644
--- a/indra/test/test_llmanifest.py
+++ b/indra/test/test_llmanifest.py
@@ -87,7 +87,7 @@ class TestLLManifest(unittest.TestCase):
def testruncommand(self):
self.assertEqual("Hello\n", self.m.run_command("echo Hello"))
def tmp_test():
- self.m.run_command("fff_garbage")
+ self.m.run_command("test_command_that_should_not_be_found")
self.assertRaises(RuntimeError, tmp_test)
def testpathof(self):
diff --git a/indra/win_updater/updater.cpp b/indra/win_updater/updater.cpp
index 96ffd5f66a..c139d2f55c 100644
--- a/indra/win_updater/updater.cpp
+++ b/indra/win_updater/updater.cpp
@@ -7,7 +7,7 @@
*/
//
-// Usage: updater -userserver <server> [-name <window_title>] [-program <program_name>] [-silent]
+// Usage: updater -url <url> [-name <window_title>] [-program <program_name>] [-silent]
//
#include <windows.h>
@@ -23,7 +23,7 @@
int gTotalBytesRead = 0;
HWND gWindow = NULL;
WCHAR gProgress[256];
-char* gUserServer;
+char* gUpdateURL;
char* gProgramName;
char* gProductName;
bool gIsSilent;
@@ -254,28 +254,20 @@ LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
}
#define win_class_name L"FullScreen"
-#define UPDATE_URIBASE L"http://secondlife.com/update.php?userserver="
int parse_args(int argc, char **argv)
{
- // Check for old-type arguments.
- if (2 == argc)
- {
- gUserServer = argv[1];
- return 0;
- }
-
int j;
for (j = 1; j < argc; j++)
{
- if ((!strcmp(argv[j], "-userserver")) && (++j < argc))
+ if ((!strcmp(argv[j], "-name")) && (++j < argc))
{
- gUserServer = argv[j];
+ gProductName = argv[j];
}
- else if ((!strcmp(argv[j], "-name")) && (++j < argc))
+ else if ((!strcmp(argv[j], "-url")) && (++j < argc))
{
- gProductName = argv[j];
+ gUpdateURL = argv[j];
}
else if ((!strcmp(argv[j], "-program")) && (++j < argc))
{
@@ -288,7 +280,7 @@ int parse_args(int argc, char **argv)
}
// If nothing was set, let the caller know.
- if (!gUserServer && !gProductName && !gProgramName && !gIsSilent)
+ if (!gProductName && !gProgramName && !gIsSilent && !gUpdateURL)
{
return 1;
}
@@ -339,7 +331,7 @@ WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nSho
}
}
- gUserServer = NULL;
+ gUpdateURL = NULL;
gProgramName = NULL;
gProductName = NULL;
gIsSilent = false;
@@ -373,7 +365,6 @@ WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nSho
DEVMODE dev_mode = { 0 };
char update_exec_path[MAX_PATH]; /* Flawfinder: ignore */
char *ptr;
- WCHAR update_uri[4096];
const int WINDOW_WIDTH = 250;
const int WINDOW_HEIGHT = 100;
@@ -408,15 +399,15 @@ WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nSho
if (parse_args_result)
{
MessageBox(gWindow,
- L"Usage: updater -userserver <server> [-name <window_title>] [-program <program_name>] [-silent]",
+ L"Usage: updater -url <url> [-name <window_title>] [-program <program_name>] [-silent]",
L"Usage", MB_OK);
return parse_args_result;
}
// Did we get a userserver to work with?
- if (!gUserServer)
+ if (!gUpdateURL)
{
- MessageBox(gWindow, L"Please specify the IP address of the userserver on the command line",
+ MessageBox(gWindow, L"Please specify the download url from the command line",
L"Error", MB_OK);
return 1;
}
@@ -440,10 +431,9 @@ WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nSho
*(ptr + 2) = 'x';
*(ptr + 3) = 'e';
*(ptr + 4) = 0;
- wcscpy(update_uri, UPDATE_URIBASE); /* Flawfinder: ignore */
- WCHAR wcmdline[2048];
- mbstowcs(wcmdline, gUserServer, 2048);
- wcscat(update_uri, wcmdline); /* Flawfinder: ignore */
+
+ WCHAR update_uri[4096];
+ mbstowcs(update_uri, gUpdateURL, 4096);
int success;
int cancelled;