svn merge -r 59163:61099 svn+ssh://svn/svn/linden/branches/release-candidate into release

master
Don Kjer 2007-05-01 21:39:25 +00:00
parent f5e9ce7e47
commit 4ecb9cb63e
128 changed files with 8195 additions and 4345 deletions

231
etc/message.xml Normal file
View File

@ -0,0 +1,231 @@
<?xml version="1.0"?>
<llsd>
<map>
<key>serverDefaults</key>
<!--
a map of server names to default message transport
-->
<map>
<key>simulator</key>
<string>template</string>
<key>userserver</key>
<string>template</string>
<key>spaceserver</key>
<string>template</string>
<key>dataserver</key>
<string>template</string>
<key>logDataserver</key>
<string>template</string>
<key>inventoryDataserver</key>
<string>template</string>
<key>rpcserver</key>
<string>template</string>
<key>mapserver</key>
<string>template</string>
</map>
<key>messages</key>
<!--
a map of individual message names that override defaults
-->
<map>
<!--
Circuit related messages
-->
<key>PacketAck</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
<key>OpenCircuit</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
<key>CloseCircuit</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
<key>StartPingCheck</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
<key>CompletePingCheck</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
<key>AddCircuitCode</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>true</boolean>
</map>
<key>UseCircuitCode</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
<key>CreateTrustedCircuit</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
<!--
Viewer to userserver messages.
-->
<key>ConnectAgentToUserserver</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
<!--
Viewer to simulator messages sent before Untrusted-senderSimulatorMessage cap received.
-->
<key>SecuredTemplateChecksumRequest</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
<key>CompleteAgentMovement</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
<key>EconomyDataRequest</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
<key>ViewerEffect</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
<!--
Viewer to simulator messages sent unreliably.
-->
<key>AgentUpdate</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
<!--
Messages created by LLThrottleGroup clients
-->
<key>ImagePacket</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
<key>LayerData</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
<key>ObjectUpdateCached</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
<key>ObjectUpdateCompressed</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
<key>ObjectUpdate</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
<key>ImprovedTerseObjectUpdate</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
<key>AvatarAnimation</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
<key>AvatarAppearance</key>
<map>
<key>builder</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
</map>
</map>
</llsd>

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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);
}

View File

@ -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';
return c_str;
std::string str;
str.resize(value.size());
memcpy(&str[0], &value[0], value.size());
return 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;
}

View File

@ -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

View File

@ -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
{

View File

@ -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;

View File

@ -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);

View File

@ -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]));

View File

@ -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);

View File

@ -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;

View File

@ -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];

View File

@ -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);

View File

@ -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

View File

@ -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)
if (!impl.isRequestPending(id))
{
impl.mAskNameQueue.push_back(id);
}
else
{
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)

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -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(

View File

@ -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,

View File

@ -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;
}

View File

@ -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.
*

View File

@ -237,7 +237,7 @@ namespace boost
}
inline void intrusive_ptr_release(LLIOPipe* p)
{
if(0 == --p->mReferenceCount)
if(p && 0 == --p->mReferenceCount)
{
delete p;
}

View File

@ -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);

View File

@ -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
}

View File

@ -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

View File

@ -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());
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -313,6 +313,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);
@ -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)
{

View File

@ -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();
/**

View File

@ -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();
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -71,7 +71,7 @@ namespace boost
}
inline void intrusive_ptr_release(LLServiceCreator* p)
{
if(0 == --p->mReferenceCount)
if(p && 0 == --p->mReferenceCount)
{
delete p;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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:
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;
virtual ~LLUseCircuitCodeResponder();
virtual void complete(const LLHost& host, const LLUUID& agent) const = 0;
};
class LLMessageSystem
{
private:
U8 mSendBuffer[MAX_BUFFER_SIZE];
S32 mSendSize;
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)
{

View File

@ -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");

View File

@ -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;

View File

@ -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;

View File

@ -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]);

View File

@ -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;

View File

@ -156,7 +156,7 @@ void LLCheckBoxCtrl::onCommit()
void LLCheckBoxCtrl::setEnabled(BOOL b)
{
LLUICtrl::setEnabled(b);
LLView::setEnabled(b);
mButton->setEnabled(b);
}

View File

@ -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();

View File

@ -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()

View File

@ -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;

View File

@ -300,7 +300,7 @@ void LLSliderCtrl::onSliderCommit( LLUICtrl* caller, void *userdata )
void LLSliderCtrl::setEnabled(BOOL b)
{
LLUICtrl::setEnabled( b );
LLView::setEnabled( b );
if( mLabelBox )
{

View File

@ -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 );
}

View File

@ -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;

View File

@ -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.";

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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

View File

@ -226,7 +226,7 @@ void LLColorSwatchCtrl::draw()
void LLColorSwatchCtrl::setEnabled( BOOL enabled )
{
mCaption->setEnabled( enabled );
LLUICtrl::setEnabled( enabled );
LLView::setEnabled( enabled );
if (!enabled)
{

View File

@ -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
class LLEventPoll::Impl : LLHTTPClient::Responder
{
public:
static Impl& start(
const std::string& pollURL, const LLHTTPNode& treeRoot)
{
Impl* i = new Impl(pollURL, treeRoot);
llinfos << "LLEventPoll::Impl::start <" << i->mCount << "> "
<< pollURL << llendl;
return *i;
}
void stop()
{
lldebugs << "LLEventPoll::Impl::stop <" << mCount << "> "
<< mPollURL << llendl;
// there should be a way to stop a LLHTTPClient request in progress
mDone = true;
mPtr = NULL;
}
static Impl& start(const std::string& pollURL);
void stop();
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;
}
Impl(const std::string& pollURL);
~Impl();
void makeRequest()
{
LLSD request;
request["ack"] = mAcknowledge;
request["done"] = mDone;
lldebugs << "LLEventPoll::Impl::makeRequest <" << mCount << "> ack = "
<< LLSDXMLStreamer(mAcknowledge) << llendl;
LLHTTPClient::post(mPollURL, request, mPtr);
}
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;
}
virtual void error(U32 status, const std::string& reason)
{
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();
}
virtual void result(const LLSD& content)
{
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"))
{
handleMessage(*i);
}
}
makeRequest();
}
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;
typedef LLHTTPClient::ResponderPtr Ptr;
Ptr mPtr;
bool mDone;
std::string mPollURL;
const LLHTTPNode& mTreeRoot;
std::string mSender;
LLSD mAcknowledge;
// these are only here for debugging so we can see which poller is which
// these are only here for debugging so we can see which poller is which
static int sCount;
int mCount;
int mCount;
};
int LLEventPoll::Impl::sCount = 0;
//static
LLEventPoll::Impl& LLEventPoll::Impl::start(
const std::string& pollURL)
{
Impl* i = new Impl(pollURL);
llinfos << "LLEventPoll::Impl::start <" << i->mCount << "> "
<< pollURL << llendl;
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;
}
LLEventPoll::LLEventPoll(const std::string& pollURL, const LLHTTPNode& treeRoot)
: impl(Impl::start(pollURL, treeRoot))
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)
{
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;
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;
if(status != 499)
{
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;
if (mDone) return;
mAcknowledge = content["id"];
LLSD events = content["events"];
if(mAcknowledge.isUndefined())
{
llwarns << "LLEventPoll::Impl: id undefined" << llendl;
}
llinfos << "LLEventPoll::Impl::completed <" << mCount << "> " << events.size() << "events (id "
<< 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"))
{
handleMessage(*i);
}
}
makeRequest();
}
LLEventPoll::LLEventPoll(const std::string& pollURL)
: impl(Impl::start(pollURL))
{ }
LLEventPoll::~LLEventPoll()

View File

@ -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.

View File

@ -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());

View File

@ -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);
}

View File

@ -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
{

View File

@ -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);
}
}
}

View File

@ -218,4 +218,3 @@ void LLFloaterInspect::draw()
LLFloater::draw();
}

View File

@ -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"));

View File

@ -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"

View File

@ -162,6 +162,7 @@ BOOL LLFloaterTOS::postBuild()
childSetValue("tos_text", LLSD(mMessage));
#endif
return TRUE;
}

View File

@ -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),
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();
setLabel(session_label);
setTitle(session_label);
mInputEditor->setMaxTextLength(1023);
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),
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);
mSessionInitialTargetIDs = ids;
}
void LLFloaterIMPanel::init()
void LLFloaterIMPanel::init(const LLString& session_label)
{
gUICtrlFactory->buildFloater(this, "floater_instant_message.xml", NULL, FALSE);
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);
}
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)
{

View File

@ -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();
};

View File

@ -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,18 @@ 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,
@ -667,6 +719,34 @@ LLFloaterIMPanel* LLIMView::createFloater(const LLUUID& session_id,
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,
LLRect(),
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);
mFloaters.insert(floater->getHandle());
return floater;
}
void LLIMView::noteOfflineUsers(LLFloaterIMPanel* floater,
const LLDynamicArray<LLUUID>& ids)
{
@ -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");

View File

@ -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;
};

View File

@ -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);

View File

@ -296,7 +296,6 @@ protected:
BOOL checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& typeToCheck);
void beginIMSession(BOOL only_online);
void modifyOutfit(BOOL append);
public:
static LLFolderBridge* sSelf;

View File

@ -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();

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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$

View File

@ -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)
{

View File

@ -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;
}

View File

@ -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();

View File

@ -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;
}

View File

@ -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);

Some files were not shown because too many files have changed in this diff Show More