PageRenderTime 62ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 1ms

/OpenMetaverse/Modules/AvatarManager.cs

https://bitbucket.org/VirtualReality/3rdparty-addon-modules
C# | 1680 lines | 1067 code | 228 blank | 385 comment | 100 complexity | 6e424edf4b3f8570e99d14d22f505ab5 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Copyright (c) 2006-2008, openmetaverse.org
  3. * All rights reserved.
  4. *
  5. * - Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * - Redistributions of source code must retain the above copyright notice, this
  9. * list of conditions and the following disclaimer.
  10. * - Neither the name of the openmetaverse.org nor the names
  11. * of its contributors may be used to endorse or promote products derived from
  12. * this software without specific prior written permission.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  15. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  17. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  18. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  19. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  20. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  21. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  22. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  23. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  24. * POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. using System;
  27. using System.Collections.Generic;
  28. using System.Text;
  29. using OpenMetaverse.Http;
  30. using OpenMetaverse.Packets;
  31. using OpenMetaverse.Interfaces;
  32. using OpenMetaverse.Messages.Linden;
  33. using OpenMetaverse.StructuredData;
  34. namespace OpenMetaverse
  35. {
  36. #region Structs
  37. /// <summary> Information about agents display name </summary>
  38. public class AgentDisplayName
  39. {
  40. /// <summary> Agent UUID </summary>
  41. public UUID ID;
  42. /// <summary> Username </summary>
  43. public string UserName;
  44. /// <summary> Display name </summary>
  45. public string DisplayName;
  46. /// <summary> First name (legacy) </summary>
  47. public string LegacyFirstName;
  48. /// <summary> Last name (legacy) </summary>
  49. public string LegacyLastName;
  50. /// <summary> Full name (legacy) </summary>
  51. public string LegacyFullName { get { return string.Format("{0} {1}", LegacyFirstName, LegacyLastName); }}
  52. /// <summary> Is display name default display name </summary>
  53. public bool IsDefaultDisplayName;
  54. /// <summary> Cache display name until </summary>
  55. public DateTime NextUpdate;
  56. /// <summary>
  57. /// Creates AgentDisplayName object from OSD
  58. /// </summary>
  59. /// <param name="data">Incoming OSD data</param>
  60. /// <returns>AgentDisplayName object</returns>
  61. public static AgentDisplayName FromOSD(OSD data)
  62. {
  63. AgentDisplayName ret = new AgentDisplayName();
  64. OSDMap map = (OSDMap)data;
  65. ret.ID = map["id"];
  66. ret.UserName = map["username"];
  67. ret.DisplayName = map["display_name"];
  68. ret.LegacyFirstName = map["legacy_first_name"];
  69. ret.LegacyLastName = map["legacy_last_name"];
  70. ret.IsDefaultDisplayName = map["is_display_name_default"];
  71. ret.NextUpdate = map["display_name_next_update"];
  72. return ret;
  73. }
  74. /// <summary>
  75. /// Return object as OSD map
  76. /// </summary>
  77. /// <returns>OSD containing agent's display name data</returns>
  78. public OSD GetOSD()
  79. {
  80. OSDMap map = new OSDMap();
  81. map["id"] = ID;
  82. map["username"] = UserName;
  83. map["display_name"] = DisplayName;
  84. map["legacy_first_name"] = LegacyFirstName;
  85. map["legacy_last_name"] = LegacyLastName;
  86. map["is_display_name_default"] = IsDefaultDisplayName;
  87. map["display_name_next_update"] = NextUpdate;
  88. return map;
  89. }
  90. public override string ToString()
  91. {
  92. return Helpers.StructToString(this);
  93. //StringBuilder result = new StringBuilder();
  94. //result.AppendLine();
  95. //result.AppendFormat("{0, 30}: {1,-40} [{2}]" + Environment.NewLine, "ID", ID, "UUID");
  96. //result.AppendFormat("{0, 30}: {1,-40} [{2}]" + Environment.NewLine, "UserName", UserName, "string");
  97. //result.AppendFormat("{0, 30}: {1,-40} [{2}]" + Environment.NewLine, "DisplayName", DisplayName, "string");
  98. //result.AppendFormat("{0, 30}: {1,-40} [{2}]" + Environment.NewLine, "LegacyFirstName", LegacyFirstName, "string");
  99. //result.AppendFormat("{0, 30}: {1,-40} [{2}]" + Environment.NewLine, "LegaacyLastName", LegaacyLastName, "string");
  100. //result.AppendFormat("{0, 30}: {1,-40} [{2}]" + Environment.NewLine, "IsDefaultDisplayName", IsDefaultDisplayName, "bool");
  101. //result.AppendFormat("{0, 30}: {1,-40} [{2}]", "NextUpdate", NextUpdate, "DateTime");
  102. //return result.ToString();
  103. }
  104. }
  105. /// <summary>
  106. /// Holds group information for Avatars such as those you might find in a profile
  107. /// </summary>
  108. public struct AvatarGroup
  109. {
  110. /// <summary>true of Avatar accepts group notices</summary>
  111. public bool AcceptNotices;
  112. /// <summary>Groups Key</summary>
  113. public UUID GroupID;
  114. /// <summary>Texture Key for groups insignia</summary>
  115. public UUID GroupInsigniaID;
  116. /// <summary>Name of the group</summary>
  117. public string GroupName;
  118. /// <summary>Powers avatar has in the group</summary>
  119. public GroupPowers GroupPowers;
  120. /// <summary>Avatars Currently selected title</summary>
  121. public string GroupTitle;
  122. /// <summary>true of Avatar has chosen to list this in their profile</summary>
  123. public bool ListInProfile;
  124. }
  125. /// <summary>
  126. /// Contains an animation currently being played by an agent
  127. /// </summary>
  128. public struct Animation
  129. {
  130. /// <summary>The ID of the animation asset</summary>
  131. public UUID AnimationID;
  132. /// <summary>A number to indicate start order of currently playing animations</summary>
  133. /// <remarks>On Linden Grids this number is unique per region, with OpenSim it is per client</remarks>
  134. public int AnimationSequence;
  135. /// <summary></summary>
  136. public UUID AnimationSourceObjectID;
  137. }
  138. /// <summary>
  139. /// Holds group information on an individual profile pick
  140. /// </summary>
  141. public struct ProfilePick
  142. {
  143. public UUID PickID;
  144. public UUID CreatorID;
  145. public bool TopPick;
  146. public UUID ParcelID;
  147. public string Name;
  148. public string Desc;
  149. public UUID SnapshotID;
  150. public string User;
  151. public string OriginalName;
  152. public string SimName;
  153. public Vector3d PosGlobal;
  154. public int SortOrder;
  155. public bool Enabled;
  156. }
  157. public struct ClassifiedAd
  158. {
  159. public UUID ClassifiedID;
  160. public uint Catagory;
  161. public UUID ParcelID;
  162. public uint ParentEstate;
  163. public UUID SnapShotID;
  164. public Vector3d Position;
  165. public byte ClassifiedFlags;
  166. public int Price;
  167. public string Name;
  168. public string Desc;
  169. }
  170. #endregion
  171. /// <summary>
  172. /// Retrieve friend status notifications, and retrieve avatar names and
  173. /// profiles
  174. /// </summary>
  175. public class AvatarManager
  176. {
  177. const int MAX_UUIDS_PER_PACKET = 100;
  178. #region Events
  179. /// <summary>The event subscribers, null of no subscribers</summary>
  180. private EventHandler<AvatarAnimationEventArgs> m_AvatarAnimation;
  181. ///<summary>Raises the AvatarAnimation Event</summary>
  182. /// <param name="e">An AvatarAnimationEventArgs object containing
  183. /// the data sent from the simulator</param>
  184. protected virtual void OnAvatarAnimation(AvatarAnimationEventArgs e)
  185. {
  186. EventHandler<AvatarAnimationEventArgs> handler = m_AvatarAnimation;
  187. if (handler != null)
  188. handler(this, e);
  189. }
  190. /// <summary>Thread sync lock object</summary>
  191. private readonly object m_AvatarAnimationLock = new object();
  192. /// <summary>Raised when the simulator sends us data containing
  193. /// an agents animation playlist</summary>
  194. public event EventHandler<AvatarAnimationEventArgs> AvatarAnimation
  195. {
  196. add { lock (m_AvatarAnimationLock) { m_AvatarAnimation += value; } }
  197. remove { lock (m_AvatarAnimationLock) { m_AvatarAnimation -= value; } }
  198. }
  199. /// <summary>The event subscribers, null of no subscribers</summary>
  200. private EventHandler<AvatarAppearanceEventArgs> m_AvatarAppearance;
  201. ///<summary>Raises the AvatarAppearance Event</summary>
  202. /// <param name="e">A AvatarAppearanceEventArgs object containing
  203. /// the data sent from the simulator</param>
  204. protected virtual void OnAvatarAppearance(AvatarAppearanceEventArgs e)
  205. {
  206. EventHandler<AvatarAppearanceEventArgs> handler = m_AvatarAppearance;
  207. if (handler != null)
  208. handler(this, e);
  209. }
  210. /// <summary>Thread sync lock object</summary>
  211. private readonly object m_AvatarAppearanceLock = new object();
  212. /// <summary>Raised when the simulator sends us data containing
  213. /// the appearance information for an agent</summary>
  214. public event EventHandler<AvatarAppearanceEventArgs> AvatarAppearance
  215. {
  216. add { lock (m_AvatarAppearanceLock) { m_AvatarAppearance += value; } }
  217. remove { lock (m_AvatarAppearanceLock) { m_AvatarAppearance -= value; } }
  218. }
  219. /// <summary>The event subscribers, null of no subscribers</summary>
  220. private EventHandler<UUIDNameReplyEventArgs> m_UUIDNameReply;
  221. ///<summary>Raises the UUIDNameReply Event</summary>
  222. /// <param name="e">A UUIDNameReplyEventArgs object containing
  223. /// the data sent from the simulator</param>
  224. protected virtual void OnUUIDNameReply(UUIDNameReplyEventArgs e)
  225. {
  226. EventHandler<UUIDNameReplyEventArgs> handler = m_UUIDNameReply;
  227. if (handler != null)
  228. handler(this, e);
  229. }
  230. /// <summary>Thread sync lock object</summary>
  231. private readonly object m_UUIDNameReplyLock = new object();
  232. /// <summary>Raised when the simulator sends us data containing
  233. /// agent names/id values</summary>
  234. public event EventHandler<UUIDNameReplyEventArgs> UUIDNameReply
  235. {
  236. add { lock (m_UUIDNameReplyLock) { m_UUIDNameReply += value; } }
  237. remove { lock (m_UUIDNameReplyLock) { m_UUIDNameReply -= value; } }
  238. }
  239. /// <summary>The event subscribers, null of no subscribers</summary>
  240. private EventHandler<AvatarInterestsReplyEventArgs> m_AvatarInterestsReply;
  241. ///<summary>Raises the AvatarInterestsReply Event</summary>
  242. /// <param name="e">A AvatarInterestsReplyEventArgs object containing
  243. /// the data sent from the simulator</param>
  244. protected virtual void OnAvatarInterestsReply(AvatarInterestsReplyEventArgs e)
  245. {
  246. EventHandler<AvatarInterestsReplyEventArgs> handler = m_AvatarInterestsReply;
  247. if (handler != null)
  248. handler(this, e);
  249. }
  250. /// <summary>Thread sync lock object</summary>
  251. private readonly object m_AvatarInterestsReplyLock = new object();
  252. /// <summary>Raised when the simulator sends us data containing
  253. /// the interests listed in an agents profile</summary>
  254. public event EventHandler<AvatarInterestsReplyEventArgs> AvatarInterestsReply
  255. {
  256. add { lock (m_AvatarInterestsReplyLock) { m_AvatarInterestsReply += value; } }
  257. remove { lock (m_AvatarInterestsReplyLock) { m_AvatarInterestsReply -= value; } }
  258. }
  259. /// <summary>The event subscribers, null of no subscribers</summary>
  260. private EventHandler<AvatarPropertiesReplyEventArgs> m_AvatarPropertiesReply;
  261. ///<summary>Raises the AvatarPropertiesReply Event</summary>
  262. /// <param name="e">A AvatarPropertiesReplyEventArgs object containing
  263. /// the data sent from the simulator</param>
  264. protected virtual void OnAvatarPropertiesReply(AvatarPropertiesReplyEventArgs e)
  265. {
  266. EventHandler<AvatarPropertiesReplyEventArgs> handler = m_AvatarPropertiesReply;
  267. if (handler != null)
  268. handler(this, e);
  269. }
  270. /// <summary>Thread sync lock object</summary>
  271. private readonly object m_AvatarPropertiesReplyLock = new object();
  272. /// <summary>Raised when the simulator sends us data containing
  273. /// profile property information for an agent</summary>
  274. public event EventHandler<AvatarPropertiesReplyEventArgs> AvatarPropertiesReply
  275. {
  276. add { lock (m_AvatarPropertiesReplyLock) { m_AvatarPropertiesReply += value; } }
  277. remove { lock (m_AvatarPropertiesReplyLock) { m_AvatarPropertiesReply -= value; } }
  278. }
  279. /// <summary>The event subscribers, null of no subscribers</summary>
  280. private EventHandler<AvatarGroupsReplyEventArgs> m_AvatarGroupsReply;
  281. ///<summary>Raises the AvatarGroupsReply Event</summary>
  282. /// <param name="e">A AvatarGroupsReplyEventArgs object containing
  283. /// the data sent from the simulator</param>
  284. protected virtual void OnAvatarGroupsReply(AvatarGroupsReplyEventArgs e)
  285. {
  286. EventHandler<AvatarGroupsReplyEventArgs> handler = m_AvatarGroupsReply;
  287. if (handler != null)
  288. handler(this, e);
  289. }
  290. /// <summary>Thread sync lock object</summary>
  291. private readonly object m_AvatarGroupsReplyLock = new object();
  292. /// <summary>Raised when the simulator sends us data containing
  293. /// the group membership an agent is a member of</summary>
  294. public event EventHandler<AvatarGroupsReplyEventArgs> AvatarGroupsReply
  295. {
  296. add { lock (m_AvatarGroupsReplyLock) { m_AvatarGroupsReply += value; } }
  297. remove { lock (m_AvatarGroupsReplyLock) { m_AvatarGroupsReply -= value; } }
  298. }
  299. /// <summary>The event subscribers, null of no subscribers</summary>
  300. private EventHandler<AvatarPickerReplyEventArgs> m_AvatarPickerReply;
  301. ///<summary>Raises the AvatarPickerReply Event</summary>
  302. /// <param name="e">A AvatarPickerReplyEventArgs object containing
  303. /// the data sent from the simulator</param>
  304. protected virtual void OnAvatarPickerReply(AvatarPickerReplyEventArgs e)
  305. {
  306. EventHandler<AvatarPickerReplyEventArgs> handler = m_AvatarPickerReply;
  307. if (handler != null)
  308. handler(this, e);
  309. }
  310. /// <summary>Thread sync lock object</summary>
  311. private readonly object m_AvatarPickerReplyLock = new object();
  312. /// <summary>Raised when the simulator sends us data containing
  313. /// name/id pair</summary>
  314. public event EventHandler<AvatarPickerReplyEventArgs> AvatarPickerReply
  315. {
  316. add { lock (m_AvatarPickerReplyLock) { m_AvatarPickerReply += value; } }
  317. remove { lock (m_AvatarPickerReplyLock) { m_AvatarPickerReply -= value; } }
  318. }
  319. /// <summary>The event subscribers, null of no subscribers</summary>
  320. private EventHandler<ViewerEffectPointAtEventArgs> m_ViewerEffectPointAt;
  321. ///<summary>Raises the ViewerEffectPointAt Event</summary>
  322. /// <param name="e">A ViewerEffectPointAtEventArgs object containing
  323. /// the data sent from the simulator</param>
  324. protected virtual void OnViewerEffectPointAt(ViewerEffectPointAtEventArgs e)
  325. {
  326. EventHandler<ViewerEffectPointAtEventArgs> handler = m_ViewerEffectPointAt;
  327. if (handler != null)
  328. handler(this, e);
  329. }
  330. /// <summary>Thread sync lock object</summary>
  331. private readonly object m_ViewerEffectPointAtLock = new object();
  332. /// <summary>Raised when the simulator sends us data containing
  333. /// the objects and effect when an agent is pointing at</summary>
  334. public event EventHandler<ViewerEffectPointAtEventArgs> ViewerEffectPointAt
  335. {
  336. add { lock (m_ViewerEffectPointAtLock) { m_ViewerEffectPointAt += value; } }
  337. remove { lock (m_ViewerEffectPointAtLock) { m_ViewerEffectPointAt -= value; } }
  338. }
  339. /// <summary>The event subscribers, null of no subscribers</summary>
  340. private EventHandler<ViewerEffectLookAtEventArgs> m_ViewerEffectLookAt;
  341. ///<summary>Raises the ViewerEffectLookAt Event</summary>
  342. /// <param name="e">A ViewerEffectLookAtEventArgs object containing
  343. /// the data sent from the simulator</param>
  344. protected virtual void OnViewerEffectLookAt(ViewerEffectLookAtEventArgs e)
  345. {
  346. EventHandler<ViewerEffectLookAtEventArgs> handler = m_ViewerEffectLookAt;
  347. if (handler != null)
  348. handler(this, e);
  349. }
  350. /// <summary>Thread sync lock object</summary>
  351. private readonly object m_ViewerEffectLookAtLock = new object();
  352. /// <summary>Raised when the simulator sends us data containing
  353. /// the objects and effect when an agent is looking at</summary>
  354. public event EventHandler<ViewerEffectLookAtEventArgs> ViewerEffectLookAt
  355. {
  356. add { lock (m_ViewerEffectLookAtLock) { m_ViewerEffectLookAt += value; } }
  357. remove { lock (m_ViewerEffectLookAtLock) { m_ViewerEffectLookAt -= value; } }
  358. }
  359. /// <summary>The event subscribers, null of no subscribers</summary>
  360. private EventHandler<ViewerEffectEventArgs> m_ViewerEffect;
  361. ///<summary>Raises the ViewerEffect Event</summary>
  362. /// <param name="e">A ViewerEffectEventArgs object containing
  363. /// the data sent from the simulator</param>
  364. protected virtual void OnViewerEffect(ViewerEffectEventArgs e)
  365. {
  366. EventHandler<ViewerEffectEventArgs> handler = m_ViewerEffect;
  367. if (handler != null)
  368. handler(this, e);
  369. }
  370. /// <summary>Thread sync lock object</summary>
  371. private readonly object m_ViewerEffectLock = new object();
  372. /// <summary>Raised when the simulator sends us data containing
  373. /// an agents viewer effect information</summary>
  374. public event EventHandler<ViewerEffectEventArgs> ViewerEffect
  375. {
  376. add { lock (m_ViewerEffectLock) { m_ViewerEffect += value; } }
  377. remove { lock (m_ViewerEffectLock) { m_ViewerEffect -= value; } }
  378. }
  379. /// <summary>The event subscribers, null of no subscribers</summary>
  380. private EventHandler<AvatarPicksReplyEventArgs> m_AvatarPicksReply;
  381. ///<summary>Raises the AvatarPicksReply Event</summary>
  382. /// <param name="e">A AvatarPicksReplyEventArgs object containing
  383. /// the data sent from the simulator</param>
  384. protected virtual void OnAvatarPicksReply(AvatarPicksReplyEventArgs e)
  385. {
  386. EventHandler<AvatarPicksReplyEventArgs> handler = m_AvatarPicksReply;
  387. if (handler != null)
  388. handler(this, e);
  389. }
  390. /// <summary>Thread sync lock object</summary>
  391. private readonly object m_AvatarPicksReplyLock = new object();
  392. /// <summary>Raised when the simulator sends us data containing
  393. /// the top picks from an agents profile</summary>
  394. public event EventHandler<AvatarPicksReplyEventArgs> AvatarPicksReply
  395. {
  396. add { lock (m_AvatarPicksReplyLock) { m_AvatarPicksReply += value; } }
  397. remove { lock (m_AvatarPicksReplyLock) { m_AvatarPicksReply -= value; } }
  398. }
  399. /// <summary>The event subscribers, null of no subscribers</summary>
  400. private EventHandler<PickInfoReplyEventArgs> m_PickInfoReply;
  401. ///<summary>Raises the PickInfoReply Event</summary>
  402. /// <param name="e">A PickInfoReplyEventArgs object containing
  403. /// the data sent from the simulator</param>
  404. protected virtual void OnPickInfoReply(PickInfoReplyEventArgs e)
  405. {
  406. EventHandler<PickInfoReplyEventArgs> handler = m_PickInfoReply;
  407. if (handler != null)
  408. handler(this, e);
  409. }
  410. /// <summary>Thread sync lock object</summary>
  411. private readonly object m_PickInfoReplyLock = new object();
  412. /// <summary>Raised when the simulator sends us data containing
  413. /// the Pick details</summary>
  414. public event EventHandler<PickInfoReplyEventArgs> PickInfoReply
  415. {
  416. add { lock (m_PickInfoReplyLock) { m_PickInfoReply += value; } }
  417. remove { lock (m_PickInfoReplyLock) { m_PickInfoReply -= value; } }
  418. }
  419. /// <summary>The event subscribers, null of no subscribers</summary>
  420. private EventHandler<AvatarClassifiedReplyEventArgs> m_AvatarClassifiedReply;
  421. ///<summary>Raises the AvatarClassifiedReply Event</summary>
  422. /// <param name="e">A AvatarClassifiedReplyEventArgs object containing
  423. /// the data sent from the simulator</param>
  424. protected virtual void OnAvatarClassifiedReply(AvatarClassifiedReplyEventArgs e)
  425. {
  426. EventHandler<AvatarClassifiedReplyEventArgs> handler = m_AvatarClassifiedReply;
  427. if (handler != null)
  428. handler(this, e);
  429. }
  430. /// <summary>Thread sync lock object</summary>
  431. private readonly object m_AvatarClassifiedReplyLock = new object();
  432. /// <summary>Raised when the simulator sends us data containing
  433. /// the classified ads an agent has placed</summary>
  434. public event EventHandler<AvatarClassifiedReplyEventArgs> AvatarClassifiedReply
  435. {
  436. add { lock (m_AvatarClassifiedReplyLock) { m_AvatarClassifiedReply += value; } }
  437. remove { lock (m_AvatarClassifiedReplyLock) { m_AvatarClassifiedReply -= value; } }
  438. }
  439. /// <summary>The event subscribers, null of no subscribers</summary>
  440. private EventHandler<ClassifiedInfoReplyEventArgs> m_ClassifiedInfoReply;
  441. ///<summary>Raises the ClassifiedInfoReply Event</summary>
  442. /// <param name="e">A ClassifiedInfoReplyEventArgs object containing
  443. /// the data sent from the simulator</param>
  444. protected virtual void OnClassifiedInfoReply(ClassifiedInfoReplyEventArgs e)
  445. {
  446. EventHandler<ClassifiedInfoReplyEventArgs> handler = m_ClassifiedInfoReply;
  447. if (handler != null)
  448. handler(this, e);
  449. }
  450. /// <summary>Thread sync lock object</summary>
  451. private readonly object m_ClassifiedInfoReplyLock = new object();
  452. /// <summary>Raised when the simulator sends us data containing
  453. /// the details of a classified ad</summary>
  454. public event EventHandler<ClassifiedInfoReplyEventArgs> ClassifiedInfoReply
  455. {
  456. add { lock (m_ClassifiedInfoReplyLock) { m_ClassifiedInfoReply += value; } }
  457. remove { lock (m_ClassifiedInfoReplyLock) { m_ClassifiedInfoReply -= value; } }
  458. }
  459. /// <summary>The event subscribers, null of no subscribers</summary>
  460. private EventHandler<DisplayNameUpdateEventArgs> m_DisplayNameUpdate;
  461. ///<summary>Raises the DisplayNameUpdate Event</summary>
  462. /// <param name="e">A DisplayNameUpdateEventArgs object containing
  463. /// the data sent from the simulator</param>
  464. protected virtual void OnDisplayNameUpdate(DisplayNameUpdateEventArgs e)
  465. {
  466. EventHandler<DisplayNameUpdateEventArgs> handler = m_DisplayNameUpdate;
  467. if (handler != null)
  468. handler(this, e);
  469. }
  470. /// <summary>Thread sync lock object</summary>
  471. private readonly object m_DisplayNameUpdateLock = new object();
  472. /// <summary>Raised when the simulator sends us data containing
  473. /// the details of display name change</summary>
  474. public event EventHandler<DisplayNameUpdateEventArgs> DisplayNameUpdate
  475. {
  476. add { lock (m_DisplayNameUpdateLock) { m_DisplayNameUpdate += value; } }
  477. remove { lock (m_DisplayNameUpdateLock) { m_DisplayNameUpdate -= value; } }
  478. }
  479. #endregion Events
  480. #region Delegates
  481. /// <summary>
  482. /// Callback giving results when fetching display names
  483. /// </summary>
  484. /// <param name="success">If the request was successful</param>
  485. /// <param name="names">Array of display names</param>
  486. /// <param name="badIDs">Array of UUIDs that could not be fetched</param>
  487. public delegate void DisplayNamesCallback(bool success, AgentDisplayName[] names, UUID[] badIDs);
  488. #endregion Delegates
  489. private GridClient Client;
  490. /// <summary>
  491. /// Represents other avatars
  492. /// </summary>
  493. /// <param name="client"></param>
  494. public AvatarManager(GridClient client)
  495. {
  496. Client = client;
  497. // Avatar appearance callback
  498. Client.Network.RegisterCallback(PacketType.AvatarAppearance, AvatarAppearanceHandler);
  499. // Avatar profile callbacks
  500. Client.Network.RegisterCallback(PacketType.AvatarPropertiesReply, AvatarPropertiesHandler);
  501. // Client.Network.RegisterCallback(PacketType.AvatarStatisticsReply, AvatarStatisticsHandler);
  502. Client.Network.RegisterCallback(PacketType.AvatarInterestsReply, AvatarInterestsHandler);
  503. // Avatar group callback
  504. Client.Network.RegisterCallback(PacketType.AvatarGroupsReply, AvatarGroupsReplyHandler);
  505. Client.Network.RegisterEventCallback("AgentGroupDataUpdate", AvatarGroupsReplyMessageHandler);
  506. Client.Network.RegisterEventCallback("AvatarGroupsReply", AvatarGroupsReplyMessageHandler);
  507. // Viewer effect callback
  508. Client.Network.RegisterCallback(PacketType.ViewerEffect, ViewerEffectHandler);
  509. // Other callbacks
  510. Client.Network.RegisterCallback(PacketType.UUIDNameReply, UUIDNameReplyHandler);
  511. Client.Network.RegisterCallback(PacketType.AvatarPickerReply, AvatarPickerReplyHandler);
  512. Client.Network.RegisterCallback(PacketType.AvatarAnimation, AvatarAnimationHandler);
  513. // Picks callbacks
  514. Client.Network.RegisterCallback(PacketType.AvatarPicksReply, AvatarPicksReplyHandler);
  515. Client.Network.RegisterCallback(PacketType.PickInfoReply, PickInfoReplyHandler);
  516. // Classifieds callbacks
  517. Client.Network.RegisterCallback(PacketType.AvatarClassifiedReply, AvatarClassifiedReplyHandler);
  518. Client.Network.RegisterCallback(PacketType.ClassifiedInfoReply, ClassifiedInfoReplyHandler);
  519. Client.Network.RegisterEventCallback("DisplayNameUpdate", DisplayNameUpdateMessageHandler);
  520. }
  521. /// <summary>Tracks the specified avatar on your map</summary>
  522. /// <param name="preyID">Avatar ID to track</param>
  523. public void RequestTrackAgent(UUID preyID)
  524. {
  525. TrackAgentPacket p = new TrackAgentPacket();
  526. p.AgentData.AgentID = Client.Self.AgentID;
  527. p.AgentData.SessionID = Client.Self.SessionID;
  528. p.TargetData.PreyID = preyID;
  529. Client.Network.SendPacket(p);
  530. }
  531. /// <summary>
  532. /// Request a single avatar name
  533. /// </summary>
  534. /// <param name="id">The avatar key to retrieve a name for</param>
  535. public void RequestAvatarName(UUID id)
  536. {
  537. UUIDNameRequestPacket request = new UUIDNameRequestPacket();
  538. request.UUIDNameBlock = new UUIDNameRequestPacket.UUIDNameBlockBlock[1];
  539. request.UUIDNameBlock[0] = new UUIDNameRequestPacket.UUIDNameBlockBlock();
  540. request.UUIDNameBlock[0].ID = id;
  541. Client.Network.SendPacket(request);
  542. }
  543. /// <summary>
  544. /// Request a list of avatar names
  545. /// </summary>
  546. /// <param name="ids">The avatar keys to retrieve names for</param>
  547. public void RequestAvatarNames(List<UUID> ids)
  548. {
  549. int m = MAX_UUIDS_PER_PACKET;
  550. int n = ids.Count / m; // Number of full requests to make
  551. int i = 0;
  552. UUIDNameRequestPacket request;
  553. for (int j = 0; j < n; j++)
  554. {
  555. request = new UUIDNameRequestPacket();
  556. request.UUIDNameBlock = new UUIDNameRequestPacket.UUIDNameBlockBlock[m];
  557. for (; i < (j + 1) * m; i++)
  558. {
  559. request.UUIDNameBlock[i % m] = new UUIDNameRequestPacket.UUIDNameBlockBlock();
  560. request.UUIDNameBlock[i % m].ID = ids[i];
  561. }
  562. Client.Network.SendPacket(request);
  563. }
  564. // Get any remaining names after left after the full requests
  565. if (ids.Count > n * m)
  566. {
  567. request = new UUIDNameRequestPacket();
  568. request.UUIDNameBlock = new UUIDNameRequestPacket.UUIDNameBlockBlock[ids.Count - n * m];
  569. for (; i < ids.Count; i++)
  570. {
  571. request.UUIDNameBlock[i % m] = new UUIDNameRequestPacket.UUIDNameBlockBlock();
  572. request.UUIDNameBlock[i % m].ID = ids[i];
  573. }
  574. Client.Network.SendPacket(request);
  575. }
  576. }
  577. /// <summary>
  578. /// Check if Display Names functionality is available
  579. /// </summary>
  580. /// <returns>True if Display name functionality is available</returns>
  581. public bool DisplayNamesAvailable()
  582. {
  583. return (Client.Network.CurrentSim != null && Client.Network.CurrentSim.Caps != null) && Client.Network.CurrentSim.Caps.CapabilityURI("GetDisplayNames") != null;
  584. }
  585. /// <summary>
  586. /// Request retrieval of display names (max 90 names per request)
  587. /// </summary>
  588. /// <param name="ids">List of UUIDs to lookup</param>
  589. /// <param name="callback">Callback to report result of the operation</param>
  590. public void GetDisplayNames(List<UUID> ids, DisplayNamesCallback callback)
  591. {
  592. if (!DisplayNamesAvailable() || ids.Count == 0)
  593. {
  594. callback(false, null, null);
  595. }
  596. StringBuilder query = new StringBuilder();
  597. for (int i = 0; i < ids.Count && i < 90; i++)
  598. {
  599. query.AppendFormat("ids={0}", ids[i]);
  600. if (i < ids.Count - 1)
  601. {
  602. query.Append("&");
  603. }
  604. }
  605. Uri uri = new Uri(Client.Network.CurrentSim.Caps.CapabilityURI("GetDisplayNames").AbsoluteUri + "/?" + query);
  606. CapsClient cap = new CapsClient(uri);
  607. cap.OnComplete += (CapsClient client, OSD result, Exception error) =>
  608. {
  609. try
  610. {
  611. if (error != null)
  612. throw error;
  613. GetDisplayNamesMessage msg = new GetDisplayNamesMessage();
  614. msg.Deserialize((OSDMap) result);
  615. callback(true, msg.Agents, msg.BadIDs);
  616. }
  617. catch (Exception ex)
  618. {
  619. Logger.Log("Failed to call GetDisplayNames capability: ",
  620. Helpers.LogLevel.Warning, Client, ex);
  621. callback(false, null, null);
  622. }
  623. };
  624. cap.BeginGetResponse(null, String.Empty, Client.Settings.CAPS_TIMEOUT);
  625. }
  626. /// <summary>
  627. /// Start a request for Avatar Properties
  628. /// </summary>
  629. /// <param name="avatarid"></param>
  630. public void RequestAvatarProperties(UUID avatarid)
  631. {
  632. AvatarPropertiesRequestPacket aprp = new AvatarPropertiesRequestPacket();
  633. aprp.AgentData.AgentID = Client.Self.AgentID;
  634. aprp.AgentData.SessionID = Client.Self.SessionID;
  635. aprp.AgentData.AvatarID = avatarid;
  636. Client.Network.SendPacket(aprp);
  637. }
  638. /// <summary>
  639. /// Search for an avatar (first name, last name)
  640. /// </summary>
  641. /// <param name="name">The name to search for</param>
  642. /// <param name="queryID">An ID to associate with this query</param>
  643. public void RequestAvatarNameSearch(string name, UUID queryID)
  644. {
  645. AvatarPickerRequestPacket aprp = new AvatarPickerRequestPacket();
  646. aprp.AgentData.AgentID = Client.Self.AgentID;
  647. aprp.AgentData.SessionID = Client.Self.SessionID;
  648. aprp.AgentData.QueryID = queryID;
  649. aprp.Data.Name = Utils.StringToBytes(name);
  650. Client.Network.SendPacket(aprp);
  651. }
  652. /// <summary>
  653. /// Start a request for Avatar Picks
  654. /// </summary>
  655. /// <param name="avatarid">UUID of the avatar</param>
  656. public void RequestAvatarPicks(UUID avatarid)
  657. {
  658. GenericMessagePacket gmp = new GenericMessagePacket();
  659. gmp.AgentData.AgentID = Client.Self.AgentID;
  660. gmp.AgentData.SessionID = Client.Self.SessionID;
  661. gmp.AgentData.TransactionID = UUID.Zero;
  662. gmp.MethodData.Method = Utils.StringToBytes("avatarpicksrequest");
  663. gmp.MethodData.Invoice = UUID.Zero;
  664. gmp.ParamList = new GenericMessagePacket.ParamListBlock[1];
  665. gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock();
  666. gmp.ParamList[0].Parameter = Utils.StringToBytes(avatarid.ToString());
  667. Client.Network.SendPacket(gmp);
  668. }
  669. /// <summary>
  670. /// Start a request for Avatar Classifieds
  671. /// </summary>
  672. /// <param name="avatarid">UUID of the avatar</param>
  673. public void RequestAvatarClassified(UUID avatarid)
  674. {
  675. GenericMessagePacket gmp = new GenericMessagePacket();
  676. gmp.AgentData.AgentID = Client.Self.AgentID;
  677. gmp.AgentData.SessionID = Client.Self.SessionID;
  678. gmp.AgentData.TransactionID = UUID.Zero;
  679. gmp.MethodData.Method = Utils.StringToBytes("avatarclassifiedsrequest");
  680. gmp.MethodData.Invoice = UUID.Zero;
  681. gmp.ParamList = new GenericMessagePacket.ParamListBlock[1];
  682. gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock();
  683. gmp.ParamList[0].Parameter = Utils.StringToBytes(avatarid.ToString());
  684. Client.Network.SendPacket(gmp);
  685. }
  686. /// <summary>
  687. /// Start a request for details of a specific profile pick
  688. /// </summary>
  689. /// <param name="avatarid">UUID of the avatar</param>
  690. /// <param name="pickid">UUID of the profile pick</param>
  691. public void RequestPickInfo(UUID avatarid, UUID pickid)
  692. {
  693. GenericMessagePacket gmp = new GenericMessagePacket();
  694. gmp.AgentData.AgentID = Client.Self.AgentID;
  695. gmp.AgentData.SessionID = Client.Self.SessionID;
  696. gmp.AgentData.TransactionID = UUID.Zero;
  697. gmp.MethodData.Method = Utils.StringToBytes("pickinforequest");
  698. gmp.MethodData.Invoice = UUID.Zero;
  699. gmp.ParamList = new GenericMessagePacket.ParamListBlock[2];
  700. gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock();
  701. gmp.ParamList[0].Parameter = Utils.StringToBytes(avatarid.ToString());
  702. gmp.ParamList[1] = new GenericMessagePacket.ParamListBlock();
  703. gmp.ParamList[1].Parameter = Utils.StringToBytes(pickid.ToString());
  704. Client.Network.SendPacket(gmp);
  705. }
  706. /// <summary>
  707. /// Start a request for details of a specific profile classified
  708. /// </summary>
  709. /// <param name="avatarid">UUID of the avatar</param>
  710. /// <param name="classifiedid">UUID of the profile classified</param>
  711. public void RequestClassifiedInfo(UUID avatarid, UUID classifiedid)
  712. {
  713. GenericMessagePacket gmp = new GenericMessagePacket();
  714. gmp.AgentData.AgentID = Client.Self.AgentID;
  715. gmp.AgentData.SessionID = Client.Self.SessionID;
  716. gmp.AgentData.TransactionID = UUID.Zero;
  717. gmp.MethodData.Method = Utils.StringToBytes("classifiedinforequest");
  718. gmp.MethodData.Invoice = UUID.Zero;
  719. gmp.ParamList = new GenericMessagePacket.ParamListBlock[2];
  720. gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock();
  721. gmp.ParamList[0].Parameter = Utils.StringToBytes(avatarid.ToString());
  722. gmp.ParamList[1] = new GenericMessagePacket.ParamListBlock();
  723. gmp.ParamList[1].Parameter = Utils.StringToBytes(classifiedid.ToString());
  724. Client.Network.SendPacket(gmp);
  725. }
  726. #region Packet Handlers
  727. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  728. /// <param name="sender">The sender</param>
  729. /// <param name="e">The EventArgs object containing the packet data</param>
  730. protected void UUIDNameReplyHandler(object sender, PacketReceivedEventArgs e)
  731. {
  732. if (m_UUIDNameReply != null)
  733. {
  734. Packet packet = e.Packet;
  735. Dictionary<UUID, string> names = new Dictionary<UUID, string>();
  736. UUIDNameReplyPacket reply = (UUIDNameReplyPacket)packet;
  737. foreach (UUIDNameReplyPacket.UUIDNameBlockBlock block in reply.UUIDNameBlock)
  738. {
  739. names[block.ID] = Utils.BytesToString(block.FirstName) +
  740. " " + Utils.BytesToString(block.LastName);
  741. }
  742. OnUUIDNameReply(new UUIDNameReplyEventArgs(names));
  743. }
  744. }
  745. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  746. /// <param name="sender">The sender</param>
  747. /// <param name="e">The EventArgs object containing the packet data</param>
  748. protected void AvatarAnimationHandler(object sender, PacketReceivedEventArgs e)
  749. {
  750. Packet packet = e.Packet;
  751. if (m_AvatarAnimation != null)
  752. {
  753. AvatarAnimationPacket data = (AvatarAnimationPacket)packet;
  754. List<Animation> signaledAnimations = new List<Animation>(data.AnimationList.Length);
  755. for (int i = 0; i < data.AnimationList.Length; i++)
  756. {
  757. Animation animation = new Animation();
  758. animation.AnimationID = data.AnimationList[i].AnimID;
  759. animation.AnimationSequence = data.AnimationList[i].AnimSequenceID;
  760. if (i < data.AnimationSourceList.Length)
  761. {
  762. animation.AnimationSourceObjectID = data.AnimationSourceList[i].ObjectID;
  763. }
  764. signaledAnimations.Add(animation);
  765. }
  766. OnAvatarAnimation(new AvatarAnimationEventArgs(data.Sender.ID, signaledAnimations));
  767. }
  768. }
  769. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  770. /// <param name="sender">The sender</param>
  771. /// <param name="e">The EventArgs object containing the packet data</param>
  772. protected void AvatarAppearanceHandler(object sender, PacketReceivedEventArgs e)
  773. {
  774. if (m_AvatarAppearance != null || Client.Settings.AVATAR_TRACKING)
  775. {
  776. Packet packet = e.Packet;
  777. Simulator simulator = e.Simulator;
  778. AvatarAppearancePacket appearance = (AvatarAppearancePacket)packet;
  779. List<byte> visualParams = new List<byte>();
  780. foreach (AvatarAppearancePacket.VisualParamBlock block in appearance.VisualParam)
  781. {
  782. visualParams.Add(block.ParamValue);
  783. }
  784. Primitive.TextureEntry textureEntry = new Primitive.TextureEntry(appearance.ObjectData.TextureEntry, 0,
  785. appearance.ObjectData.TextureEntry.Length);
  786. Primitive.TextureEntryFace defaultTexture = textureEntry.DefaultTexture;
  787. Primitive.TextureEntryFace[] faceTextures = textureEntry.FaceTextures;
  788. Avatar av = simulator.ObjectsAvatars.Find((Avatar a) => { return a.ID == appearance.Sender.ID; });
  789. if (av != null)
  790. {
  791. av.Textures = textureEntry;
  792. av.VisualParameters = visualParams.ToArray();
  793. }
  794. OnAvatarAppearance(new AvatarAppearanceEventArgs(simulator, appearance.Sender.ID, appearance.Sender.IsTrial,
  795. defaultTexture, faceTextures, visualParams));
  796. }
  797. }
  798. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  799. /// <param name="sender">The sender</param>
  800. /// <param name="e">The EventArgs object containing the packet data</param>
  801. protected void AvatarPropertiesHandler(object sender, PacketReceivedEventArgs e)
  802. {
  803. if (m_AvatarPropertiesReply != null)
  804. {
  805. Packet packet = e.Packet;
  806. AvatarPropertiesReplyPacket reply = (AvatarPropertiesReplyPacket)packet;
  807. Avatar.AvatarProperties properties = new Avatar.AvatarProperties();
  808. properties.ProfileImage = reply.PropertiesData.ImageID;
  809. properties.FirstLifeImage = reply.PropertiesData.FLImageID;
  810. properties.Partner = reply.PropertiesData.PartnerID;
  811. properties.AboutText = Utils.BytesToString(reply.PropertiesData.AboutText);
  812. properties.FirstLifeText = Utils.BytesToString(reply.PropertiesData.FLAboutText);
  813. properties.BornOn = Utils.BytesToString(reply.PropertiesData.BornOn);
  814. //properties.CharterMember = Utils.BytesToString(reply.PropertiesData.CharterMember);
  815. uint charter = Utils.BytesToUInt(reply.PropertiesData.CharterMember);
  816. if (charter == 0)
  817. {
  818. properties.CharterMember = "Resident";
  819. }
  820. else if (charter == 2)
  821. {
  822. properties.CharterMember = "Charter";
  823. }
  824. else if (charter == 3)
  825. {
  826. properties.CharterMember = "Linden";
  827. }
  828. else
  829. {
  830. properties.CharterMember = Utils.BytesToString(reply.PropertiesData.CharterMember);
  831. }
  832. properties.Flags = (ProfileFlags)reply.PropertiesData.Flags;
  833. properties.ProfileURL = Utils.BytesToString(reply.PropertiesData.ProfileURL);
  834. OnAvatarPropertiesReply(new AvatarPropertiesReplyEventArgs(reply.AgentData.AvatarID, properties));
  835. }
  836. }
  837. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  838. /// <param name="sender">The sender</param>
  839. /// <param name="e">The EventArgs object containing the packet data</param>
  840. protected void AvatarInterestsHandler(object sender, PacketReceivedEventArgs e)
  841. {
  842. if (m_AvatarInterestsReply != null)
  843. {
  844. Packet packet = e.Packet;
  845. AvatarInterestsReplyPacket airp = (AvatarInterestsReplyPacket)packet;
  846. Avatar.Interests interests = new Avatar.Interests();
  847. interests.WantToMask = airp.PropertiesData.WantToMask;
  848. interests.WantToText = Utils.BytesToString(airp.PropertiesData.WantToText);
  849. interests.SkillsMask = airp.PropertiesData.SkillsMask;
  850. interests.SkillsText = Utils.BytesToString(airp.PropertiesData.SkillsText);
  851. interests.LanguagesText = Utils.BytesToString(airp.PropertiesData.LanguagesText);
  852. OnAvatarInterestsReply(new AvatarInterestsReplyEventArgs(airp.AgentData.AvatarID, interests));
  853. }
  854. }
  855. /// <summary>
  856. /// EQ Message fired when someone nearby changes their display name
  857. /// </summary>
  858. /// <param name="capsKey">The message key</param>
  859. /// <param name="message">the IMessage object containing the deserialized data sent from the simulator</param>
  860. /// <param name="simulator">The <see cref="Simulator"/> which originated the packet</param>
  861. protected void DisplayNameUpdateMessageHandler(string capsKey, IMessage message, Simulator simulator)
  862. {
  863. if (m_DisplayNameUpdate != null)
  864. {
  865. DisplayNameUpdateMessage msg = (DisplayNameUpdateMessage) message;
  866. OnDisplayNameUpdate(new DisplayNameUpdateEventArgs(msg.OldDisplayName, msg.DisplayName));
  867. }
  868. }
  869. /// <summary>
  870. /// Crossed region handler for message that comes across the EventQueue. Sent to an agent
  871. /// when the agent crosses a sim border into a new region.
  872. /// </summary>
  873. /// <param name="capsKey">The message key</param>
  874. /// <param name="message">the IMessage object containing the deserialized data sent from the simulator</param>
  875. /// <param name="simulator">The <see cref="Simulator"/> which originated the packet</param>
  876. protected void AvatarGroupsReplyMessageHandler(string capsKey, IMessage message, Simulator simulator)
  877. {
  878. AgentGroupDataUpdateMessage msg = (AgentGroupDataUpdateMessage)message;
  879. List<AvatarGroup> avatarGroups = new List<AvatarGroup>(msg.GroupDataBlock.Length);
  880. for (int i = 0; i < msg.GroupDataBlock.Length; i++)
  881. {
  882. AvatarGroup avatarGroup = new AvatarGroup();
  883. avatarGroup.AcceptNotices = msg.GroupDataBlock[i].AcceptNotices;
  884. avatarGroup.GroupID = msg.GroupDataBlock[i].GroupID;
  885. avatarGroup.GroupInsigniaID = msg.GroupDataBlock[i].GroupInsigniaID;
  886. avatarGroup.GroupName = msg.GroupDataBlock[i].GroupName;
  887. avatarGroup.GroupPowers = msg.GroupDataBlock[i].GroupPowers;
  888. avatarGroup.ListInProfile = msg.NewGroupDataBlock[i].ListInProfile;
  889. avatarGroups.Add(avatarGroup);
  890. }
  891. OnAvatarGroupsReply(new AvatarGroupsReplyEventArgs(msg.AgentID, avatarGroups));
  892. }
  893. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  894. /// <param name="sender">The sender</param>
  895. /// <param name="e">The EventArgs object containing the packet data</param>
  896. protected void AvatarGroupsReplyHandler(object sender, PacketReceivedEventArgs e)
  897. {
  898. if (m_AvatarGroupsReply != null)
  899. {
  900. Packet packet = e.Packet;
  901. AvatarGroupsReplyPacket groups = (AvatarGroupsReplyPacket)packet;
  902. List<AvatarGroup> avatarGroups = new List<AvatarGroup>(groups.GroupData.Length);
  903. for (int i = 0; i < groups.GroupData.Length; i++)
  904. {
  905. AvatarGroup avatarGroup = new AvatarGroup();
  906. avatarGroup.AcceptNotices = groups.GroupData[i].AcceptNotices;
  907. avatarGroup.GroupID = groups.GroupData[i].GroupID;
  908. avatarGroup.GroupInsigniaID = groups.GroupData[i].GroupInsigniaID;
  909. avatarGroup.GroupName = Utils.BytesToString(groups.GroupData[i].GroupName);
  910. avatarGroup.GroupPowers = (GroupPowers)groups.GroupData[i].GroupPowers;
  911. avatarGroup.GroupTitle = Utils.BytesToString(groups.GroupData[i].GroupTitle);
  912. avatarGroup.ListInProfile = groups.NewGroupData.ListInProfile;
  913. avatarGroups.Add(avatarGroup);
  914. }
  915. OnAvatarGroupsReply(new AvatarGroupsReplyEventArgs(groups.AgentData.AvatarID, avatarGroups));
  916. }
  917. }
  918. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  919. /// <param name="sender">The sender</param>
  920. /// <param name="e">The EventArgs object containing the packet data</param>
  921. protected void AvatarPickerReplyHandler(object sender, PacketReceivedEventArgs e)
  922. {
  923. if (m_AvatarPickerReply != null)
  924. {
  925. Packet packet = e.Packet;
  926. AvatarPickerReplyPacket reply = (AvatarPickerReplyPacket)packet;
  927. Dictionary<UUID, string> avatars = new Dictionary<UUID, string>();
  928. foreach (AvatarPickerReplyPacket.DataBlock block in reply.Data)
  929. {
  930. avatars[block.AvatarID] = Utils.BytesToString(block.FirstName) +
  931. " " + Utils.BytesToString(block.LastName);
  932. }
  933. OnAvatarPickerReply(new AvatarPickerReplyEventArgs(reply.AgentData.QueryID, avatars));
  934. }
  935. }
  936. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  937. /// <param name="sender">The sender</param>
  938. /// <param name="e">The EventArgs object containing theā€¦

Large files files are truncated, but you can click here to view the full file