llinstantmessage.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:10k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llinstantmessage.cpp
  3.  * @author Phoenix
  4.  * @date 2005-08-29
  5.  * @brief Constants and functions used in IM.
  6.  *
  7.  * $LicenseInfo:firstyear=2005&license=viewergpl$
  8.  * 
  9.  * Copyright (c) 2005-2010, Linden Research, Inc.
  10.  * 
  11.  * Second Life Viewer Source Code
  12.  * The source code in this file ("Source Code") is provided by Linden Lab
  13.  * to you under the terms of the GNU General Public License, version 2.0
  14.  * ("GPL"), unless you have obtained a separate licensing agreement
  15.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  16.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  17.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  18.  * 
  19.  * There are special exceptions to the terms and conditions of the GPL as
  20.  * it is applied to this Source Code. View the full text of the exception
  21.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  22.  * online at
  23.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  24.  * 
  25.  * By copying, modifying or distributing this software, you acknowledge
  26.  * that you have read and understood your obligations described above,
  27.  * and agree to abide by those obligations.
  28.  * 
  29.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  30.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  31.  * COMPLETENESS OR PERFORMANCE.
  32.  * $/LicenseInfo$
  33.  */
  34. #include "linden_common.h"
  35. #include "lldbstrings.h"
  36. #include "llinstantmessage.h"
  37. #include "llhost.h"
  38. #include "lluuid.h"
  39. #include "llsd.h"
  40. #include "llsdserialize.h"
  41. #include "llsdutil_math.h"
  42. #include "llpointer.h"
  43. #include "message.h"
  44. #include "message.h"
  45. const U8 IM_ONLINE = 0;
  46. const U8 IM_OFFLINE = 1;
  47. const S32 VOTE_YES = 1;
  48. const S32 VOTE_NO = 0;
  49. const S32 VOTE_ABSTAIN = -1;
  50. const S32 VOTE_MAJORITY = 0;
  51. const S32 VOTE_SUPER_MAJORITY = 1;
  52. const S32 VOTE_UNANIMOUS = 2;
  53. const char EMPTY_BINARY_BUCKET[] = "";
  54. const S32 EMPTY_BINARY_BUCKET_SIZE = 1;
  55. const U32 NO_TIMESTAMP = 0;
  56. const std::string SYSTEM_FROM("Second Life");
  57. const S32 IM_TTL = 1;
  58. /**
  59.  * LLIMInfo
  60.  */
  61. LLIMInfo::LLIMInfo() :
  62. mFromGroup(FALSE),
  63. mParentEstateID(0),
  64. mOffline(0),
  65. mViewerThinksToIsOnline(false),
  66. mIMType(IM_NOTHING_SPECIAL),
  67. mTimeStamp(0),
  68. mSource(IM_FROM_SIM),
  69. mTTL(IM_TTL)
  70. {
  71. }
  72. LLIMInfo::LLIMInfo(
  73. const LLUUID& from_id,
  74. BOOL from_group,
  75. const LLUUID& to_id,
  76. EInstantMessage im_type, 
  77. const std::string& name,
  78. const std::string& message,
  79. const LLUUID& id,
  80. U32 parent_estate_id,
  81. const LLUUID& region_id,
  82. const LLVector3& position,
  83. LLSD data,
  84. U8 offline,
  85. U32 timestamp,
  86. EIMSource source,
  87. S32 ttl) :
  88. mFromID(from_id),
  89. mFromGroup(from_group),
  90. mToID(to_id),
  91. mParentEstateID(0),
  92. mRegionID(region_id),
  93. mPosition(position),
  94. mOffline(offline),
  95. mViewerThinksToIsOnline(false),
  96. mIMType(im_type),
  97. mID(id),
  98. mTimeStamp(timestamp),
  99. mName(name),
  100. mMessage(message),
  101. mData(data),
  102. mSource(source),
  103. mTTL(ttl)
  104. {
  105. }
  106. LLIMInfo::LLIMInfo(LLMessageSystem* msg, EIMSource source, S32 ttl) :
  107. mViewerThinksToIsOnline(false),
  108. mSource(source),
  109. mTTL(ttl)
  110. {
  111. unpackMessageBlock(msg);
  112. }
  113. LLIMInfo::~LLIMInfo()
  114. {
  115. }
  116. void LLIMInfo::packInstantMessage(LLMessageSystem* msg) const
  117. {
  118. lldebugs << "LLIMInfo::packInstantMessage()" << llendl;
  119. msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
  120. packMessageBlock(msg);
  121. }
  122. void LLIMInfo::packMessageBlock(LLMessageSystem* msg) const
  123. {
  124. // Construct binary bucket
  125. std::vector<U8> bucket;
  126. if (mData.has("binary_bucket"))
  127. {
  128. bucket = mData["binary_bucket"].asBinary();
  129. }
  130. pack_instant_message_block(
  131. msg,
  132. mFromID,
  133. mFromGroup,
  134. LLUUID::null,
  135. mToID,
  136. mName,
  137. mMessage,
  138. mOffline,
  139. mIMType,
  140. mID,
  141. mParentEstateID,
  142. mRegionID,
  143. mPosition,
  144. mTimeStamp,
  145. &bucket[0],
  146. bucket.size());
  147. }
  148. void pack_instant_message(
  149. LLMessageSystem* msg,
  150. const LLUUID& from_id,
  151. BOOL from_group,
  152. const LLUUID& session_id,
  153. const LLUUID& to_id,
  154. const std::string& name,
  155. const std::string& message,
  156. U8 offline,
  157. EInstantMessage dialog,
  158. const LLUUID& id,
  159. U32 parent_estate_id,
  160. const LLUUID& region_id,
  161. const LLVector3& position,
  162. U32 timestamp, 
  163. const U8* binary_bucket,
  164. S32 binary_bucket_size)
  165. {
  166. lldebugs << "pack_instant_message()" << llendl;
  167. msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
  168. pack_instant_message_block(
  169. msg,
  170. from_id,
  171. from_group,
  172. session_id,
  173. to_id,
  174. name,
  175. message,
  176. offline,
  177. dialog,
  178. id,
  179. parent_estate_id,
  180. region_id,
  181. position,
  182. timestamp,
  183. binary_bucket,
  184. binary_bucket_size);
  185. }
  186. void pack_instant_message_block(
  187. LLMessageSystem* msg,
  188. const LLUUID& from_id,
  189. BOOL from_group,
  190. const LLUUID& session_id,
  191. const LLUUID& to_id,
  192. const std::string& name,
  193. const std::string& message,
  194. U8 offline,
  195. EInstantMessage dialog,
  196. const LLUUID& id,
  197. U32 parent_estate_id,
  198. const LLUUID& region_id,
  199. const LLVector3& position,
  200. U32 timestamp,
  201. const U8* binary_bucket,
  202. S32 binary_bucket_size)
  203. {
  204. msg->nextBlockFast(_PREHASH_AgentData);
  205. msg->addUUIDFast(_PREHASH_AgentID, from_id);
  206. msg->addUUIDFast(_PREHASH_SessionID, session_id);
  207. msg->nextBlockFast(_PREHASH_MessageBlock);
  208. msg->addBOOLFast(_PREHASH_FromGroup, from_group);
  209. msg->addUUIDFast(_PREHASH_ToAgentID, to_id);
  210. msg->addU32Fast(_PREHASH_ParentEstateID, parent_estate_id);
  211. msg->addUUIDFast(_PREHASH_RegionID, region_id);
  212. msg->addVector3Fast(_PREHASH_Position, position);
  213. msg->addU8Fast(_PREHASH_Offline, offline);
  214. msg->addU8Fast(_PREHASH_Dialog, (U8) dialog);
  215. msg->addUUIDFast(_PREHASH_ID, id);
  216. msg->addU32Fast(_PREHASH_Timestamp, timestamp);
  217. msg->addStringFast(_PREHASH_FromAgentName, name);
  218. S32 bytes_left = MTUBYTES;
  219. if(!message.empty())
  220. {
  221. char buffer[MTUBYTES];
  222. int num_written = snprintf(buffer, MTUBYTES, "%s", message.c_str()); /* Flawfinder: ignore */
  223. // snprintf returns number of bytes that would have been written
  224. // had the output not being truncated. In that case, it will
  225. // return either -1 or value >= passed in size value . So a check needs to be added
  226. // to detect truncation, and if there is any, only account for the
  227. // actual number of bytes written..and not what could have been
  228. // written.
  229. if (num_written < 0 || num_written >= MTUBYTES)
  230. {
  231. num_written = MTUBYTES - 1;
  232. llwarns << "pack_instant_message_block: message truncated: " << message << llendl;
  233. }
  234. bytes_left -= num_written;
  235. bytes_left = llmax(0, bytes_left);
  236. msg->addStringFast(_PREHASH_Message, buffer);
  237. }
  238. else
  239. {
  240. msg->addStringFast(_PREHASH_Message, NULL);
  241. }
  242. const U8* bb;
  243. if(binary_bucket)
  244. {
  245. bb = binary_bucket;
  246. binary_bucket_size = llmin(bytes_left, binary_bucket_size);
  247. }
  248. else
  249. {
  250. bb = (const U8*)EMPTY_BINARY_BUCKET;
  251. binary_bucket_size = EMPTY_BINARY_BUCKET_SIZE;
  252. }
  253. msg->addBinaryDataFast(_PREHASH_BinaryBucket, bb, binary_bucket_size);
  254. }
  255. void LLIMInfo::unpackMessageBlock(LLMessageSystem* msg)
  256. {
  257. msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, mFromID);
  258. msg->getBOOLFast(_PREHASH_MessageBlock, _PREHASH_FromGroup, mFromGroup);
  259. msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ToAgentID, mToID);
  260. msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_ParentEstateID, mParentEstateID);
  261. msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_RegionID, mRegionID);
  262. msg->getVector3Fast(_PREHASH_MessageBlock, _PREHASH_Position, mPosition);
  263. msg->getU8Fast(_PREHASH_MessageBlock, _PREHASH_Offline, mOffline);
  264. U8 dialog;
  265. msg->getU8Fast(_PREHASH_MessageBlock, _PREHASH_Dialog, dialog);
  266. mIMType = (EInstantMessage) dialog;
  267. msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ID, mID);
  268. msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_Timestamp, mTimeStamp);
  269. msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, mName);
  270. msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_Message, mMessage);
  271. S32 binary_bucket_size = llmin(
  272. MTUBYTES,
  273. msg->getSizeFast(
  274. _PREHASH_MessageBlock,
  275. _PREHASH_BinaryBucket));
  276. if(binary_bucket_size > 0)
  277. {
  278. std::vector<U8> bucket;
  279. bucket.resize(binary_bucket_size);
  280. msg->getBinaryDataFast(
  281. _PREHASH_MessageBlock,
  282. _PREHASH_BinaryBucket,
  283. &bucket[0],
  284. 0,
  285. 0,
  286. binary_bucket_size);
  287. mData["binary_bucket"] = bucket;
  288. }
  289. else
  290. {
  291. mData.clear();
  292. }
  293. }
  294. LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info)
  295. {
  296. LLSD param_version;
  297. param_version["version"] = 1;
  298. LLSD param_message;
  299. param_message["from_id"] = im_info->mFromID;
  300. param_message["from_group"] = im_info->mFromGroup;
  301. param_message["to_id"] = im_info->mToID;
  302. param_message["from_name"] = im_info->mName;
  303. param_message["message"] = im_info->mMessage;
  304. param_message["type"] = (S32)im_info->mIMType;
  305. param_message["id"] = im_info->mID;
  306. param_message["timestamp"] = (S32)im_info->mTimeStamp;
  307. param_message["offline"] = (S32)im_info->mOffline;
  308. param_message["parent_estate_id"] = (S32)im_info->mParentEstateID;
  309. param_message["region_id"] = im_info->mRegionID;
  310. param_message["position"] = ll_sd_from_vector3(im_info->mPosition);
  311. param_message["data"] = im_info->mData;
  312. param_message["source"]= im_info->mSource;
  313. param_message["ttl"] = im_info->mTTL;
  314. LLSD param_agent;
  315. param_agent["agent_id"] = im_info->mFromID;
  316. LLSD params;
  317. params["version_params"] = param_version;
  318. params["message_params"] = param_message;
  319. params["agent_params"] = param_agent;
  320. return params;
  321. }
  322. LLPointer<LLIMInfo> llsd_to_im_info(const LLSD& im_info_sd)
  323. {
  324. LLSD param_message = im_info_sd["message_params"];
  325. LLSD param_agent = im_info_sd["agent_params"];
  326. LLPointer<LLIMInfo> im_info = new LLIMInfo(
  327. param_message["from_id"].asUUID(),
  328. param_message["from_group"].asBoolean(),
  329. param_message["to_id"].asUUID(),
  330. (EInstantMessage) param_message["type"].asInteger(),
  331. param_message["from_name"].asString(),
  332. param_message["message"].asString(),
  333. param_message["id"].asUUID(),
  334. (U32) param_message["parent_estate_id"].asInteger(),
  335. param_message["region_id"].asUUID(),
  336. ll_vector3_from_sd(param_message["position"]),
  337. param_message["data"],
  338. (U8) param_message["offline"].asInteger(),
  339. (U32) param_message["timestamp"].asInteger(),
  340. (EIMSource)param_message["source"].asInteger(),
  341. param_message["ttl"].asInteger());
  342. return im_info;
  343. }
  344. LLPointer<LLIMInfo> LLIMInfo::clone()
  345. {
  346. return new LLIMInfo(
  347. mFromID,
  348. mFromGroup,
  349. mToID,
  350. mIMType,
  351. mName,
  352. mMessage,
  353. mID,
  354. mParentEstateID,
  355. mRegionID,
  356. mPosition,
  357. mData,
  358. mOffline,
  359. mTimeStamp,
  360. mSource,
  361. mTTL);
  362. }