llinstantmessage.cpp

Go to the documentation of this file.
00001 
00034 #include "linden_common.h"
00035 
00036 #include "lldbstrings.h"
00037 #include "llinstantmessage.h"
00038 #include "llhost.h"
00039 #include "lluuid.h"
00040 #include "llsd.h"
00041 #include "llsdserialize.h"
00042 #include "llsdutil.h"
00043 #include "llmemory.h"
00044 #include "message.h"
00045 
00046 #include "message.h"
00047 
00048 const U8 IM_ONLINE = 0;
00049 const U8 IM_OFFLINE = 1;
00050 
00051 const S32 VOTE_YES = 1;
00052 const S32 VOTE_NO = 0;
00053 const S32 VOTE_ABSTAIN = -1;
00054 
00055 const S32 VOTE_MAJORITY = 0;
00056 const S32 VOTE_SUPER_MAJORITY = 1;
00057 const S32 VOTE_UNANIMOUS = 2;
00058 
00059 const char EMPTY_BINARY_BUCKET[] = "";
00060 const S32 EMPTY_BINARY_BUCKET_SIZE = 1;
00061 const U32 NO_TIMESTAMP = 0;
00062 const char SYSTEM_FROM[] = "Second Life";
00063 const S32 IM_TTL = 1;
00064 
00065 
00069 LLIMInfo::LLIMInfo() :
00070         mParentEstateID(0),
00071         mOffline(0),
00072         mViewerThinksToIsOnline(false),
00073         mTimeStamp(0),
00074         mSource(IM_FROM_SIM),
00075         mTTL(IM_TTL)
00076 {
00077 }
00078 
00079 LLIMInfo::LLIMInfo(
00080         const LLUUID& from_id,
00081         BOOL from_group,
00082         const LLUUID& to_id,
00083         EInstantMessage im_type, 
00084         const std::string& name,
00085         const std::string& message,
00086         const LLUUID& id,
00087         U32 parent_estate_id,
00088         const LLUUID& region_id,
00089         const LLVector3& position,
00090         LLSD data,
00091         U8 offline,
00092         U32 timestamp,
00093         EIMSource source,
00094         S32 ttl) :
00095         mFromID(from_id),
00096         mFromGroup(from_group),
00097         mToID(to_id),
00098         mParentEstateID(0),
00099         mRegionID(region_id),
00100         mPosition(position),
00101         mOffline(offline),
00102         mViewerThinksToIsOnline(false),
00103         mIMType(im_type),
00104         mID(id),
00105         mTimeStamp(timestamp),
00106         mName(name),
00107         mMessage(message),
00108         mData(data),
00109         mSource(source),
00110         mTTL(ttl)
00111 {
00112 }
00113 
00114 LLIMInfo::LLIMInfo(LLMessageSystem* msg, EIMSource source, S32 ttl) :
00115         mViewerThinksToIsOnline(false),
00116         mSource(source),
00117         mTTL(ttl)
00118 {
00119         unpackMessageBlock(msg);
00120 }
00121 
00122 LLIMInfo::~LLIMInfo()
00123 {
00124 }
00125 
00126 void LLIMInfo::packInstantMessage(LLMessageSystem* msg) const
00127 {
00128         lldebugs << "LLIMInfo::packInstantMessage()" << llendl;
00129         msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
00130         packMessageBlock(msg);
00131 }
00132 
00133 void LLIMInfo::packMessageBlock(LLMessageSystem* msg) const
00134 {
00135         // Construct binary bucket
00136         std::vector<U8> bucket;
00137         if (mData.has("binary_bucket"))
00138         {
00139                 bucket = mData["binary_bucket"].asBinary();
00140         }
00141         pack_instant_message_block(
00142                 msg,
00143                 mFromID,
00144                 mFromGroup,
00145                 LLUUID::null,
00146                 mToID,
00147                 mName.c_str(),
00148                 mMessage.c_str(),
00149                 mOffline,
00150                 mIMType,
00151                 mID,
00152                 mParentEstateID,
00153                 mRegionID,
00154                 mPosition,
00155                 mTimeStamp,
00156                 &bucket[0],
00157                 bucket.size());
00158 }
00159 
00160 void pack_instant_message(
00161         LLMessageSystem* msg,
00162         const LLUUID& from_id,
00163         BOOL from_group,
00164         const LLUUID& session_id,
00165         const LLUUID& to_id,
00166         const char* name,
00167         const char* message,
00168         U8 offline,
00169         EInstantMessage dialog,
00170         const LLUUID& id,
00171         U32 parent_estate_id,
00172         const LLUUID& region_id,
00173         const LLVector3& position,
00174         U32 timestamp, 
00175         const U8* binary_bucket,
00176         S32 binary_bucket_size)
00177 {
00178         lldebugs << "pack_instant_message()" << llendl;
00179         msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
00180         pack_instant_message_block(
00181                 msg,
00182                 from_id,
00183                 from_group,
00184                 session_id,
00185                 to_id,
00186                 name,
00187                 message,
00188                 offline,
00189                 dialog,
00190                 id,
00191                 parent_estate_id,
00192                 region_id,
00193                 position,
00194                 timestamp,
00195                 binary_bucket,
00196                 binary_bucket_size);
00197 }
00198 
00199 void pack_instant_message_block(
00200         LLMessageSystem* msg,
00201         const LLUUID& from_id,
00202         BOOL from_group,
00203         const LLUUID& session_id,
00204         const LLUUID& to_id,
00205         const char* name,
00206         const char* message,
00207         U8 offline,
00208         EInstantMessage dialog,
00209         const LLUUID& id,
00210         U32 parent_estate_id,
00211         const LLUUID& region_id,
00212         const LLVector3& position,
00213         U32 timestamp,
00214         const U8* binary_bucket,
00215         S32 binary_bucket_size)
00216 {
00217         msg->nextBlockFast(_PREHASH_AgentData);
00218         msg->addUUIDFast(_PREHASH_AgentID, from_id);
00219         msg->addUUIDFast(_PREHASH_SessionID, session_id);
00220         msg->nextBlockFast(_PREHASH_MessageBlock);
00221         msg->addBOOLFast(_PREHASH_FromGroup, from_group);
00222         msg->addUUIDFast(_PREHASH_ToAgentID, to_id);
00223         msg->addU32Fast(_PREHASH_ParentEstateID, parent_estate_id);
00224         msg->addUUIDFast(_PREHASH_RegionID, region_id);
00225         msg->addVector3Fast(_PREHASH_Position, position);
00226         msg->addU8Fast(_PREHASH_Offline, offline);
00227         msg->addU8Fast(_PREHASH_Dialog, (U8) dialog);
00228         msg->addUUIDFast(_PREHASH_ID, id);
00229         msg->addU32Fast(_PREHASH_Timestamp, timestamp);
00230         msg->addStringFast(_PREHASH_FromAgentName, name);
00231         S32 bytes_left = MTUBYTES;
00232         if(message)
00233         {
00234                 char buffer[MTUBYTES];
00235                 int num_written = snprintf(buffer, MTUBYTES, "%s", message);    /* Flawfinder: ignore */
00236                 // snprintf returns number of bytes that would have been written
00237                 // had the output not being truncated. In that case, it will
00238                 // return either -1 or value >= passed in size value . So a check needs to be added
00239                 // to detect truncation, and if there is any, only account for the
00240                 // actual number of bytes written..and not what could have been
00241                 // written.
00242                 if (num_written < 0 || num_written >= MTUBYTES)
00243                 {
00244                         num_written = MTUBYTES - 1;
00245                         llwarns << "pack_instant_message_block: message truncated: " << message << llendl;
00246                 }
00247 
00248                 bytes_left -= num_written;
00249                 bytes_left = llmax(0, bytes_left);
00250                 msg->addStringFast(_PREHASH_Message, buffer);
00251         }
00252         else
00253         {
00254                 msg->addStringFast(_PREHASH_Message, NULL);
00255         }
00256         const U8* bb;
00257         if(binary_bucket)
00258         {
00259                 bb = binary_bucket;
00260                 binary_bucket_size = llmin(bytes_left, binary_bucket_size);
00261         }
00262         else
00263         {
00264                 bb = (const U8*)EMPTY_BINARY_BUCKET;
00265                 binary_bucket_size = EMPTY_BINARY_BUCKET_SIZE;
00266         }
00267         msg->addBinaryDataFast(_PREHASH_BinaryBucket, bb, binary_bucket_size);
00268 }
00269 
00270 void LLIMInfo::unpackMessageBlock(LLMessageSystem* msg)
00271 {
00272         msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, mFromID);
00273         msg->getBOOLFast(_PREHASH_MessageBlock, _PREHASH_FromGroup, mFromGroup);
00274         msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ToAgentID, mToID);
00275         msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_ParentEstateID, mParentEstateID);
00276         msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_RegionID, mRegionID);
00277         msg->getVector3Fast(_PREHASH_MessageBlock, _PREHASH_Position, mPosition);
00278         msg->getU8Fast(_PREHASH_MessageBlock, _PREHASH_Offline, mOffline);
00279         U8 dialog;
00280         msg->getU8Fast(_PREHASH_MessageBlock, _PREHASH_Dialog, dialog);
00281         mIMType = (EInstantMessage) dialog;
00282         msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ID, mID);
00283         msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_Timestamp, mTimeStamp);
00284         char name[DB_FULL_NAME_BUF_SIZE];       /*Flawfinder: ignore*/
00285         msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, DB_FULL_NAME_BUF_SIZE, name);
00286         mName.assign(name);
00287 
00288         char message[DB_IM_MSG_BUF_SIZE];       /*Flawfinder: ignore*/
00289         msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_Message, DB_IM_MSG_BUF_SIZE, message);
00290         mMessage.assign(message);
00291 
00292         S32 binary_bucket_size = llmin(
00293                 MTUBYTES,
00294                 msg->getSizeFast(
00295                         _PREHASH_MessageBlock,
00296                         _PREHASH_BinaryBucket));
00297         if(binary_bucket_size > 0)
00298         {
00299                 std::vector<U8> bucket;
00300                 bucket.resize(binary_bucket_size);
00301 
00302                 msg->getBinaryDataFast(
00303                         _PREHASH_MessageBlock,
00304                         _PREHASH_BinaryBucket,
00305                         &bucket[0],
00306                         0,
00307                         0,
00308                         binary_bucket_size);
00309                 mData["binary_bucket"] = bucket;
00310         }
00311         else
00312         {
00313                 mData.clear();
00314         }
00315 }
00316 
00317 LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info)
00318 {
00319         LLSD param_version;
00320         param_version["version"] = 1;
00321         LLSD param_message;
00322         param_message["from_id"] = im_info->mFromID;
00323         param_message["from_group"] = im_info->mFromGroup;
00324         param_message["to_id"] = im_info->mToID;
00325         param_message["from_name"] = im_info->mName;
00326         param_message["message"] = im_info->mMessage;
00327         param_message["type"] = (S32)im_info->mIMType;
00328         param_message["id"] = im_info->mID;
00329         param_message["timestamp"] = (S32)im_info->mTimeStamp;
00330         param_message["offline"] = (S32)im_info->mOffline;
00331         param_message["parent_estate_id"] = (S32)im_info->mParentEstateID;
00332         param_message["region_id"] = im_info->mRegionID;
00333         param_message["position"] = ll_sd_from_vector3(im_info->mPosition);
00334         param_message["data"] = im_info->mData;
00335         param_message["source"]= im_info->mSource;
00336         param_message["ttl"] = im_info->mTTL;
00337 
00338         LLSD param_agent;
00339         param_agent["agent_id"] = im_info->mFromID;
00340 
00341         LLSD params;
00342         params["version_params"] = param_version;
00343         params["message_params"] = param_message;
00344         params["agent_params"] = param_agent;
00345 
00346         return params;
00347 }
00348 
00349 LLPointer<LLIMInfo> llsd_to_im_info(const LLSD& im_info_sd)
00350 {
00351         LLSD param_message = im_info_sd["message_params"];
00352         LLSD param_agent = im_info_sd["agent_params"];
00353 
00354         LLPointer<LLIMInfo> im_info = new LLIMInfo(
00355                 param_message["from_id"].asUUID(),
00356                 param_message["from_group"].asBoolean(),
00357                 param_message["to_id"].asUUID(),
00358                 (EInstantMessage) param_message["type"].asInteger(),
00359                 param_message["from_name"].asString(),
00360                 param_message["message"].asString(),
00361                 param_message["id"].asUUID(),
00362                 (U32) param_message["parent_estate_id"].asInteger(),
00363                 im_info->mRegionID = param_message["region_id"].asUUID(),
00364                 ll_vector3_from_sd(param_message["position"]),
00365                 param_message["data"],
00366                 (U8) param_message["offline"].asInteger(),
00367                 (U32) param_message["timestamp"].asInteger(),
00368                 (EIMSource)param_message["source"].asInteger(),
00369                 param_message["ttl"].asInteger());
00370 
00371         return im_info;
00372 }
00373 
00374 LLPointer<LLIMInfo> LLIMInfo::clone()
00375 {
00376         return new LLIMInfo(
00377                         mFromID,
00378                         mFromGroup,
00379                         mToID,
00380                         mIMType,
00381                         mName,
00382                         mMessage,
00383                         mID,
00384                         mParentEstateID,
00385                         mRegionID,
00386                         mPosition,
00387                         mData,
00388                         mOffline,
00389                         mTimeStamp,
00390                         mSource,
00391                         mTTL);
00392 }
00393 

Generated on Thu Jul 1 06:08:44 2010 for Second Life Viewer by  doxygen 1.4.7