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
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);
00236
00237
00238
00239
00240
00241
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];
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];
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