corrade-vassal – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 1 /*
2 * Copyright (c) 2006-2014, 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  
27 using System;
28 using System.Collections.Generic;
29 using System.Text;
30 using OpenMetaverse.Http;
31 using OpenMetaverse.Packets;
32 using OpenMetaverse.Interfaces;
33 using OpenMetaverse.Messages.Linden;
34 using OpenMetaverse.StructuredData;
35  
36 namespace OpenMetaverse
37 {
38  
39 #region Structs
40 /// <summary> Information about agents display name </summary>
41 public class AgentDisplayName
42 {
43 /// <summary> Agent UUID </summary>
44 public UUID ID;
45 /// <summary> Username </summary>
46 public string UserName;
47 /// <summary> Display name </summary>
48 public string DisplayName;
49 /// <summary> First name (legacy) </summary>
50 public string LegacyFirstName;
51 /// <summary> Last name (legacy) </summary>
52 public string LegacyLastName;
53 /// <summary> Full name (legacy) </summary>
54 public string LegacyFullName { get { return string.Format("{0} {1}", LegacyFirstName, LegacyLastName); } }
55 /// <summary> Is display name default display name </summary>
56 public bool IsDefaultDisplayName;
57 /// <summary> Cache display name until </summary>
58 public DateTime NextUpdate;
59 /// <summary> Last updated timestamp </summary>
60 public DateTime Updated;
61  
62 /// <summary>
63 /// Creates AgentDisplayName object from OSD
64 /// </summary>
65 /// <param name="data">Incoming OSD data</param>
66 /// <returns>AgentDisplayName object</returns>
67 public static AgentDisplayName FromOSD(OSD data)
68 {
69 AgentDisplayName ret = new AgentDisplayName();
70  
71 OSDMap map = (OSDMap)data;
72 ret.ID = map["id"];
73 ret.UserName = map["username"];
74 ret.DisplayName = map["display_name"];
75 ret.LegacyFirstName = map["legacy_first_name"];
76 ret.LegacyLastName = map["legacy_last_name"];
77 ret.IsDefaultDisplayName = map["is_display_name_default"];
78 ret.NextUpdate = map["display_name_next_update"];
79 ret.Updated = map["last_updated"];
80  
81 return ret;
82 }
83  
84 /// <summary>
85 /// Return object as OSD map
86 /// </summary>
87 /// <returns>OSD containing agent's display name data</returns>
88 public OSD GetOSD()
89 {
90 OSDMap map = new OSDMap();
91  
92 map["id"] = ID;
93 map["username"] = UserName;
94 map["display_name"] = DisplayName;
95 map["legacy_first_name"] = LegacyFirstName;
96 map["legacy_last_name"] = LegacyLastName;
97 map["is_display_name_default"] = IsDefaultDisplayName;
98 map["display_name_next_update"] = NextUpdate;
99 map["last_updated"] = Updated;
100  
101 return map;
102 }
103  
104 public override string ToString()
105 {
106 return Helpers.StructToString(this);
107 }
108 }
109  
110 /// <summary>
111 /// Holds group information for Avatars such as those you might find in a profile
112 /// </summary>
113 public struct AvatarGroup
114 {
115 /// <summary>true of Avatar accepts group notices</summary>
116 public bool AcceptNotices;
117 /// <summary>Groups Key</summary>
118 public UUID GroupID;
119 /// <summary>Texture Key for groups insignia</summary>
120 public UUID GroupInsigniaID;
121 /// <summary>Name of the group</summary>
122 public string GroupName;
123 /// <summary>Powers avatar has in the group</summary>
124 public GroupPowers GroupPowers;
125 /// <summary>Avatars Currently selected title</summary>
126 public string GroupTitle;
127 /// <summary>true of Avatar has chosen to list this in their profile</summary>
128 public bool ListInProfile;
129 }
130  
131 /// <summary>
132 /// Contains an animation currently being played by an agent
133 /// </summary>
134 public struct Animation
135 {
136 /// <summary>The ID of the animation asset</summary>
137 public UUID AnimationID;
138 /// <summary>A number to indicate start order of currently playing animations</summary>
139 /// <remarks>On Linden Grids this number is unique per region, with OpenSim it is per client</remarks>
140 public int AnimationSequence;
141 /// <summary></summary>
142 public UUID AnimationSourceObjectID;
143 }
144  
145 /// <summary>
146 /// Holds group information on an individual profile pick
147 /// </summary>
148 public struct ProfilePick
149 {
150 public UUID PickID;
151 public UUID CreatorID;
152 public bool TopPick;
153 public UUID ParcelID;
154 public string Name;
155 public string Desc;
156 public UUID SnapshotID;
157 public string User;
158 public string OriginalName;
159 public string SimName;
160 public Vector3d PosGlobal;
161 public int SortOrder;
162 public bool Enabled;
163 }
164  
165 public struct ClassifiedAd
166 {
167 public UUID ClassifiedID;
168 public uint Catagory;
169 public UUID ParcelID;
170 public uint ParentEstate;
171 public UUID SnapShotID;
172 public Vector3d Position;
173 public byte ClassifiedFlags;
174 public int Price;
175 public string Name;
176 public string Desc;
177 }
178 #endregion
179  
180 /// <summary>
181 /// Retrieve friend status notifications, and retrieve avatar names and
182 /// profiles
183 /// </summary>
184 public class AvatarManager
185 {
186 const int MAX_UUIDS_PER_PACKET = 100;
187  
188 #region Events
189 /// <summary>The event subscribers, null of no subscribers</summary>
190 private EventHandler<AvatarAnimationEventArgs> m_AvatarAnimation;
191  
192 ///<summary>Raises the AvatarAnimation Event</summary>
193 /// <param name="e">An AvatarAnimationEventArgs object containing
194 /// the data sent from the simulator</param>
195 protected virtual void OnAvatarAnimation(AvatarAnimationEventArgs e)
196 {
197 EventHandler<AvatarAnimationEventArgs> handler = m_AvatarAnimation;
198 if (handler != null)
199 handler(this, e);
200 }
201  
202 /// <summary>Thread sync lock object</summary>
203 private readonly object m_AvatarAnimationLock = new object();
204  
205 /// <summary>Raised when the simulator sends us data containing
206 /// an agents animation playlist</summary>
207 public event EventHandler<AvatarAnimationEventArgs> AvatarAnimation
208 {
209 add { lock (m_AvatarAnimationLock) { m_AvatarAnimation += value; } }
210 remove { lock (m_AvatarAnimationLock) { m_AvatarAnimation -= value; } }
211 }
212  
213 /// <summary>The event subscribers, null of no subscribers</summary>
214 private EventHandler<AvatarAppearanceEventArgs> m_AvatarAppearance;
215  
216 ///<summary>Raises the AvatarAppearance Event</summary>
217 /// <param name="e">A AvatarAppearanceEventArgs object containing
218 /// the data sent from the simulator</param>
219 protected virtual void OnAvatarAppearance(AvatarAppearanceEventArgs e)
220 {
221 EventHandler<AvatarAppearanceEventArgs> handler = m_AvatarAppearance;
222 if (handler != null)
223 handler(this, e);
224 }
225  
226 /// <summary>Thread sync lock object</summary>
227 private readonly object m_AvatarAppearanceLock = new object();
228  
229 /// <summary>Raised when the simulator sends us data containing
230 /// the appearance information for an agent</summary>
231 public event EventHandler<AvatarAppearanceEventArgs> AvatarAppearance
232 {
233 add { lock (m_AvatarAppearanceLock) { m_AvatarAppearance += value; } }
234 remove { lock (m_AvatarAppearanceLock) { m_AvatarAppearance -= value; } }
235 }
236  
237 /// <summary>The event subscribers, null of no subscribers</summary>
238 private EventHandler<UUIDNameReplyEventArgs> m_UUIDNameReply;
239  
240 ///<summary>Raises the UUIDNameReply Event</summary>
241 /// <param name="e">A UUIDNameReplyEventArgs object containing
242 /// the data sent from the simulator</param>
243 protected virtual void OnUUIDNameReply(UUIDNameReplyEventArgs e)
244 {
245 EventHandler<UUIDNameReplyEventArgs> handler = m_UUIDNameReply;
246 if (handler != null)
247 handler(this, e);
248 }
249  
250 /// <summary>Thread sync lock object</summary>
251 private readonly object m_UUIDNameReplyLock = new object();
252  
253 /// <summary>Raised when the simulator sends us data containing
254 /// agent names/id values</summary>
255 public event EventHandler<UUIDNameReplyEventArgs> UUIDNameReply
256 {
257 add { lock (m_UUIDNameReplyLock) { m_UUIDNameReply += value; } }
258 remove { lock (m_UUIDNameReplyLock) { m_UUIDNameReply -= value; } }
259 }
260  
261 /// <summary>The event subscribers, null of no subscribers</summary>
262 private EventHandler<AvatarInterestsReplyEventArgs> m_AvatarInterestsReply;
263  
264 ///<summary>Raises the AvatarInterestsReply Event</summary>
265 /// <param name="e">A AvatarInterestsReplyEventArgs object containing
266 /// the data sent from the simulator</param>
267 protected virtual void OnAvatarInterestsReply(AvatarInterestsReplyEventArgs e)
268 {
269 EventHandler<AvatarInterestsReplyEventArgs> handler = m_AvatarInterestsReply;
270 if (handler != null)
271 handler(this, e);
272 }
273  
274 /// <summary>Thread sync lock object</summary>
275 private readonly object m_AvatarInterestsReplyLock = new object();
276  
277 /// <summary>Raised when the simulator sends us data containing
278 /// the interests listed in an agents profile</summary>
279 public event EventHandler<AvatarInterestsReplyEventArgs> AvatarInterestsReply
280 {
281 add { lock (m_AvatarInterestsReplyLock) { m_AvatarInterestsReply += value; } }
282 remove { lock (m_AvatarInterestsReplyLock) { m_AvatarInterestsReply -= value; } }
283 }
284  
285 /// <summary>The event subscribers, null of no subscribers</summary>
286 private EventHandler<AvatarPropertiesReplyEventArgs> m_AvatarPropertiesReply;
287  
288 ///<summary>Raises the AvatarPropertiesReply Event</summary>
289 /// <param name="e">A AvatarPropertiesReplyEventArgs object containing
290 /// the data sent from the simulator</param>
291 protected virtual void OnAvatarPropertiesReply(AvatarPropertiesReplyEventArgs e)
292 {
293 EventHandler<AvatarPropertiesReplyEventArgs> handler = m_AvatarPropertiesReply;
294 if (handler != null)
295 handler(this, e);
296 }
297  
298 /// <summary>Thread sync lock object</summary>
299 private readonly object m_AvatarPropertiesReplyLock = new object();
300  
301 /// <summary>Raised when the simulator sends us data containing
302 /// profile property information for an agent</summary>
303 public event EventHandler<AvatarPropertiesReplyEventArgs> AvatarPropertiesReply
304 {
305 add { lock (m_AvatarPropertiesReplyLock) { m_AvatarPropertiesReply += value; } }
306 remove { lock (m_AvatarPropertiesReplyLock) { m_AvatarPropertiesReply -= value; } }
307 }
308  
309 /// <summary>The event subscribers, null of no subscribers</summary>
310 private EventHandler<AvatarGroupsReplyEventArgs> m_AvatarGroupsReply;
311  
312 ///<summary>Raises the AvatarGroupsReply Event</summary>
313 /// <param name="e">A AvatarGroupsReplyEventArgs object containing
314 /// the data sent from the simulator</param>
315 protected virtual void OnAvatarGroupsReply(AvatarGroupsReplyEventArgs e)
316 {
317 EventHandler<AvatarGroupsReplyEventArgs> handler = m_AvatarGroupsReply;
318 if (handler != null)
319 handler(this, e);
320 }
321  
322 /// <summary>Thread sync lock object</summary>
323 private readonly object m_AvatarGroupsReplyLock = new object();
324  
325 /// <summary>Raised when the simulator sends us data containing
326 /// the group membership an agent is a member of</summary>
327 public event EventHandler<AvatarGroupsReplyEventArgs> AvatarGroupsReply
328 {
329 add { lock (m_AvatarGroupsReplyLock) { m_AvatarGroupsReply += value; } }
330 remove { lock (m_AvatarGroupsReplyLock) { m_AvatarGroupsReply -= value; } }
331 }
332  
333 /// <summary>The event subscribers, null of no subscribers</summary>
334 private EventHandler<AvatarPickerReplyEventArgs> m_AvatarPickerReply;
335  
336 ///<summary>Raises the AvatarPickerReply Event</summary>
337 /// <param name="e">A AvatarPickerReplyEventArgs object containing
338 /// the data sent from the simulator</param>
339 protected virtual void OnAvatarPickerReply(AvatarPickerReplyEventArgs e)
340 {
341 EventHandler<AvatarPickerReplyEventArgs> handler = m_AvatarPickerReply;
342 if (handler != null)
343 handler(this, e);
344 }
345  
346 /// <summary>Thread sync lock object</summary>
347 private readonly object m_AvatarPickerReplyLock = new object();
348  
349 /// <summary>Raised when the simulator sends us data containing
350 /// name/id pair</summary>
351 public event EventHandler<AvatarPickerReplyEventArgs> AvatarPickerReply
352 {
353 add { lock (m_AvatarPickerReplyLock) { m_AvatarPickerReply += value; } }
354 remove { lock (m_AvatarPickerReplyLock) { m_AvatarPickerReply -= value; } }
355 }
356  
357 /// <summary>The event subscribers, null of no subscribers</summary>
358 private EventHandler<ViewerEffectPointAtEventArgs> m_ViewerEffectPointAt;
359  
360 ///<summary>Raises the ViewerEffectPointAt Event</summary>
361 /// <param name="e">A ViewerEffectPointAtEventArgs object containing
362 /// the data sent from the simulator</param>
363 protected virtual void OnViewerEffectPointAt(ViewerEffectPointAtEventArgs e)
364 {
365 EventHandler<ViewerEffectPointAtEventArgs> handler = m_ViewerEffectPointAt;
366 if (handler != null)
367 handler(this, e);
368 }
369  
370 /// <summary>Thread sync lock object</summary>
371 private readonly object m_ViewerEffectPointAtLock = new object();
372  
373 /// <summary>Raised when the simulator sends us data containing
374 /// the objects and effect when an agent is pointing at</summary>
375 public event EventHandler<ViewerEffectPointAtEventArgs> ViewerEffectPointAt
376 {
377 add { lock (m_ViewerEffectPointAtLock) { m_ViewerEffectPointAt += value; } }
378 remove { lock (m_ViewerEffectPointAtLock) { m_ViewerEffectPointAt -= value; } }
379 }
380  
381 /// <summary>The event subscribers, null of no subscribers</summary>
382 private EventHandler<ViewerEffectLookAtEventArgs> m_ViewerEffectLookAt;
383  
384 ///<summary>Raises the ViewerEffectLookAt Event</summary>
385 /// <param name="e">A ViewerEffectLookAtEventArgs object containing
386 /// the data sent from the simulator</param>
387 protected virtual void OnViewerEffectLookAt(ViewerEffectLookAtEventArgs e)
388 {
389 EventHandler<ViewerEffectLookAtEventArgs> handler = m_ViewerEffectLookAt;
390 if (handler != null)
391 handler(this, e);
392 }
393  
394 /// <summary>Thread sync lock object</summary>
395 private readonly object m_ViewerEffectLookAtLock = new object();
396  
397 /// <summary>Raised when the simulator sends us data containing
398 /// the objects and effect when an agent is looking at</summary>
399 public event EventHandler<ViewerEffectLookAtEventArgs> ViewerEffectLookAt
400 {
401 add { lock (m_ViewerEffectLookAtLock) { m_ViewerEffectLookAt += value; } }
402 remove { lock (m_ViewerEffectLookAtLock) { m_ViewerEffectLookAt -= value; } }
403 }
404  
405 /// <summary>The event subscribers, null of no subscribers</summary>
406 private EventHandler<ViewerEffectEventArgs> m_ViewerEffect;
407  
408 ///<summary>Raises the ViewerEffect Event</summary>
409 /// <param name="e">A ViewerEffectEventArgs object containing
410 /// the data sent from the simulator</param>
411 protected virtual void OnViewerEffect(ViewerEffectEventArgs e)
412 {
413 EventHandler<ViewerEffectEventArgs> handler = m_ViewerEffect;
414 if (handler != null)
415 handler(this, e);
416 }
417  
418 /// <summary>Thread sync lock object</summary>
419 private readonly object m_ViewerEffectLock = new object();
420  
421 /// <summary>Raised when the simulator sends us data containing
422 /// an agents viewer effect information</summary>
423 public event EventHandler<ViewerEffectEventArgs> ViewerEffect
424 {
425 add { lock (m_ViewerEffectLock) { m_ViewerEffect += value; } }
426 remove { lock (m_ViewerEffectLock) { m_ViewerEffect -= value; } }
427 }
428  
429 /// <summary>The event subscribers, null of no subscribers</summary>
430 private EventHandler<AvatarPicksReplyEventArgs> m_AvatarPicksReply;
431  
432 ///<summary>Raises the AvatarPicksReply Event</summary>
433 /// <param name="e">A AvatarPicksReplyEventArgs object containing
434 /// the data sent from the simulator</param>
435 protected virtual void OnAvatarPicksReply(AvatarPicksReplyEventArgs e)
436 {
437 EventHandler<AvatarPicksReplyEventArgs> handler = m_AvatarPicksReply;
438 if (handler != null)
439 handler(this, e);
440 }
441  
442 /// <summary>Thread sync lock object</summary>
443 private readonly object m_AvatarPicksReplyLock = new object();
444  
445 /// <summary>Raised when the simulator sends us data containing
446 /// the top picks from an agents profile</summary>
447 public event EventHandler<AvatarPicksReplyEventArgs> AvatarPicksReply
448 {
449 add { lock (m_AvatarPicksReplyLock) { m_AvatarPicksReply += value; } }
450 remove { lock (m_AvatarPicksReplyLock) { m_AvatarPicksReply -= value; } }
451 }
452  
453 /// <summary>The event subscribers, null of no subscribers</summary>
454 private EventHandler<PickInfoReplyEventArgs> m_PickInfoReply;
455  
456 ///<summary>Raises the PickInfoReply Event</summary>
457 /// <param name="e">A PickInfoReplyEventArgs object containing
458 /// the data sent from the simulator</param>
459 protected virtual void OnPickInfoReply(PickInfoReplyEventArgs e)
460 {
461 EventHandler<PickInfoReplyEventArgs> handler = m_PickInfoReply;
462 if (handler != null)
463 handler(this, e);
464 }
465  
466 /// <summary>Thread sync lock object</summary>
467 private readonly object m_PickInfoReplyLock = new object();
468  
469 /// <summary>Raised when the simulator sends us data containing
470 /// the Pick details</summary>
471 public event EventHandler<PickInfoReplyEventArgs> PickInfoReply
472 {
473 add { lock (m_PickInfoReplyLock) { m_PickInfoReply += value; } }
474 remove { lock (m_PickInfoReplyLock) { m_PickInfoReply -= value; } }
475 }
476  
477 /// <summary>The event subscribers, null of no subscribers</summary>
478 private EventHandler<AvatarClassifiedReplyEventArgs> m_AvatarClassifiedReply;
479  
480 ///<summary>Raises the AvatarClassifiedReply Event</summary>
481 /// <param name="e">A AvatarClassifiedReplyEventArgs object containing
482 /// the data sent from the simulator</param>
483 protected virtual void OnAvatarClassifiedReply(AvatarClassifiedReplyEventArgs e)
484 {
485 EventHandler<AvatarClassifiedReplyEventArgs> handler = m_AvatarClassifiedReply;
486 if (handler != null)
487 handler(this, e);
488 }
489  
490 /// <summary>Thread sync lock object</summary>
491 private readonly object m_AvatarClassifiedReplyLock = new object();
492  
493 /// <summary>Raised when the simulator sends us data containing
494 /// the classified ads an agent has placed</summary>
495 public event EventHandler<AvatarClassifiedReplyEventArgs> AvatarClassifiedReply
496 {
497 add { lock (m_AvatarClassifiedReplyLock) { m_AvatarClassifiedReply += value; } }
498 remove { lock (m_AvatarClassifiedReplyLock) { m_AvatarClassifiedReply -= value; } }
499 }
500  
501 /// <summary>The event subscribers, null of no subscribers</summary>
502 private EventHandler<ClassifiedInfoReplyEventArgs> m_ClassifiedInfoReply;
503  
504 ///<summary>Raises the ClassifiedInfoReply Event</summary>
505 /// <param name="e">A ClassifiedInfoReplyEventArgs object containing
506 /// the data sent from the simulator</param>
507 protected virtual void OnClassifiedInfoReply(ClassifiedInfoReplyEventArgs e)
508 {
509 EventHandler<ClassifiedInfoReplyEventArgs> handler = m_ClassifiedInfoReply;
510 if (handler != null)
511 handler(this, e);
512 }
513  
514 /// <summary>Thread sync lock object</summary>
515 private readonly object m_ClassifiedInfoReplyLock = new object();
516  
517 /// <summary>Raised when the simulator sends us data containing
518 /// the details of a classified ad</summary>
519 public event EventHandler<ClassifiedInfoReplyEventArgs> ClassifiedInfoReply
520 {
521 add { lock (m_ClassifiedInfoReplyLock) { m_ClassifiedInfoReply += value; } }
522 remove { lock (m_ClassifiedInfoReplyLock) { m_ClassifiedInfoReply -= value; } }
523 }
524  
525 /// <summary>The event subscribers, null of no subscribers</summary>
526 private EventHandler<DisplayNameUpdateEventArgs> m_DisplayNameUpdate;
527  
528 ///<summary>Raises the DisplayNameUpdate Event</summary>
529 /// <param name="e">A DisplayNameUpdateEventArgs object containing
530 /// the data sent from the simulator</param>
531 protected virtual void OnDisplayNameUpdate(DisplayNameUpdateEventArgs e)
532 {
533 EventHandler<DisplayNameUpdateEventArgs> handler = m_DisplayNameUpdate;
534 if (handler != null)
535 handler(this, e);
536 }
537  
538 /// <summary>Thread sync lock object</summary>
539 private readonly object m_DisplayNameUpdateLock = new object();
540  
541 /// <summary>Raised when the simulator sends us data containing
542 /// the details of display name change</summary>
543 public event EventHandler<DisplayNameUpdateEventArgs> DisplayNameUpdate
544 {
545 add { lock (m_DisplayNameUpdateLock) { m_DisplayNameUpdate += value; } }
546 remove { lock (m_DisplayNameUpdateLock) { m_DisplayNameUpdate -= value; } }
547 }
548  
549 #endregion Events
550  
551 #region Delegates
552 /// <summary>
553 /// Callback giving results when fetching display names
554 /// </summary>
555 /// <param name="success">If the request was successful</param>
556 /// <param name="names">Array of display names</param>
557 /// <param name="badIDs">Array of UUIDs that could not be fetched</param>
558 public delegate void DisplayNamesCallback(bool success, AgentDisplayName[] names, UUID[] badIDs);
559 #endregion Delegates
560  
561 private GridClient Client;
562  
563 /// <summary>
564 /// Represents other avatars
565 /// </summary>
566 /// <param name="client"></param>
567 public AvatarManager(GridClient client)
568 {
569 Client = client;
570  
571 // Avatar appearance callback
572 Client.Network.RegisterCallback(PacketType.AvatarAppearance, AvatarAppearanceHandler);
573  
574 // Avatar profile callbacks
575 Client.Network.RegisterCallback(PacketType.AvatarPropertiesReply, AvatarPropertiesHandler);
576 // Client.Network.RegisterCallback(PacketType.AvatarStatisticsReply, AvatarStatisticsHandler);
577 Client.Network.RegisterCallback(PacketType.AvatarInterestsReply, AvatarInterestsHandler);
578  
579 // Avatar group callback
580 Client.Network.RegisterCallback(PacketType.AvatarGroupsReply, AvatarGroupsReplyHandler);
581 Client.Network.RegisterEventCallback("AgentGroupDataUpdate", AvatarGroupsReplyMessageHandler);
582 Client.Network.RegisterEventCallback("AvatarGroupsReply", AvatarGroupsReplyMessageHandler);
583  
584 // Viewer effect callback
585 Client.Network.RegisterCallback(PacketType.ViewerEffect, ViewerEffectHandler);
586  
587 // Other callbacks
588 Client.Network.RegisterCallback(PacketType.UUIDNameReply, UUIDNameReplyHandler);
589 Client.Network.RegisterCallback(PacketType.AvatarPickerReply, AvatarPickerReplyHandler);
590 Client.Network.RegisterCallback(PacketType.AvatarAnimation, AvatarAnimationHandler);
591  
592 // Picks callbacks
593 Client.Network.RegisterCallback(PacketType.AvatarPicksReply, AvatarPicksReplyHandler);
594 Client.Network.RegisterCallback(PacketType.PickInfoReply, PickInfoReplyHandler);
595  
596 // Classifieds callbacks
597 Client.Network.RegisterCallback(PacketType.AvatarClassifiedReply, AvatarClassifiedReplyHandler);
598 Client.Network.RegisterCallback(PacketType.ClassifiedInfoReply, ClassifiedInfoReplyHandler);
599  
600 Client.Network.RegisterEventCallback("DisplayNameUpdate", DisplayNameUpdateMessageHandler);
601 }
602  
603 /// <summary>Tracks the specified avatar on your map</summary>
604 /// <param name="preyID">Avatar ID to track</param>
605 public void RequestTrackAgent(UUID preyID)
606 {
607 TrackAgentPacket p = new TrackAgentPacket();
608 p.AgentData.AgentID = Client.Self.AgentID;
609 p.AgentData.SessionID = Client.Self.SessionID;
610 p.TargetData.PreyID = preyID;
611 Client.Network.SendPacket(p);
612 }
613  
614 /// <summary>
615 /// Request a single avatar name
616 /// </summary>
617 /// <param name="id">The avatar key to retrieve a name for</param>
618 public void RequestAvatarName(UUID id)
619 {
620 UUIDNameRequestPacket request = new UUIDNameRequestPacket();
621 request.UUIDNameBlock = new UUIDNameRequestPacket.UUIDNameBlockBlock[1];
622 request.UUIDNameBlock[0] = new UUIDNameRequestPacket.UUIDNameBlockBlock();
623 request.UUIDNameBlock[0].ID = id;
624  
625 Client.Network.SendPacket(request);
626 }
627  
628 /// <summary>
629 /// Request a list of avatar names
630 /// </summary>
631 /// <param name="ids">The avatar keys to retrieve names for</param>
632 public void RequestAvatarNames(List<UUID> ids)
633 {
634 int m = MAX_UUIDS_PER_PACKET;
635 int n = ids.Count / m; // Number of full requests to make
636 int i = 0;
637  
638 UUIDNameRequestPacket request;
639  
640 for (int j = 0; j < n; j++)
641 {
642 request = new UUIDNameRequestPacket();
643 request.UUIDNameBlock = new UUIDNameRequestPacket.UUIDNameBlockBlock[m];
644  
645 for (; i < (j + 1) * m; i++)
646 {
647 request.UUIDNameBlock[i % m] = new UUIDNameRequestPacket.UUIDNameBlockBlock();
648 request.UUIDNameBlock[i % m].ID = ids[i];
649 }
650  
651 Client.Network.SendPacket(request);
652 }
653  
654 // Get any remaining names after left after the full requests
655 if (ids.Count > n * m)
656 {
657 request = new UUIDNameRequestPacket();
658 request.UUIDNameBlock = new UUIDNameRequestPacket.UUIDNameBlockBlock[ids.Count - n * m];
659  
660 for (; i < ids.Count; i++)
661 {
662 request.UUIDNameBlock[i % m] = new UUIDNameRequestPacket.UUIDNameBlockBlock();
663 request.UUIDNameBlock[i % m].ID = ids[i];
664 }
665  
666 Client.Network.SendPacket(request);
667 }
668 }
669  
670 /// <summary>
671 /// Check if Display Names functionality is available
672 /// </summary>
673 /// <returns>True if Display name functionality is available</returns>
674 public bool DisplayNamesAvailable()
675 {
676 return (Client.Network.CurrentSim != null && Client.Network.CurrentSim.Caps != null) && Client.Network.CurrentSim.Caps.CapabilityURI("GetDisplayNames") != null;
677 }
678  
679 /// <summary>
680 /// Request retrieval of display names (max 90 names per request)
681 /// </summary>
682 /// <param name="ids">List of UUIDs to lookup</param>
683 /// <param name="callback">Callback to report result of the operation</param>
684 public void GetDisplayNames(List<UUID> ids, DisplayNamesCallback callback)
685 {
686 if (!DisplayNamesAvailable() || ids.Count == 0)
687 {
688 callback(false, null, null);
689 }
690  
691 StringBuilder query = new StringBuilder();
692 for (int i = 0; i < ids.Count && i < 90; i++)
693 {
694 query.AppendFormat("ids={0}", ids[i]);
695 if (i < ids.Count - 1)
696 {
697 query.Append("&");
698 }
699 }
700  
701 Uri uri = new Uri(Client.Network.CurrentSim.Caps.CapabilityURI("GetDisplayNames").AbsoluteUri + "/?" + query);
702  
703 CapsClient cap = new CapsClient(uri);
704 cap.OnComplete += (CapsClient client, OSD result, Exception error) =>
705 {
706 try
707 {
708 if (error != null)
709 throw error;
710 GetDisplayNamesMessage msg = new GetDisplayNamesMessage();
711 msg.Deserialize((OSDMap)result);
712 callback(true, msg.Agents, msg.BadIDs);
713 }
714 catch (Exception ex)
715 {
716 Logger.Log("Failed to call GetDisplayNames capability: ",
717 Helpers.LogLevel.Warning, Client, ex);
718 callback(false, null, null);
719 }
720 };
721 cap.BeginGetResponse(null, String.Empty, Client.Settings.CAPS_TIMEOUT);
722 }
723  
724 /// <summary>
725 /// Start a request for Avatar Properties
726 /// </summary>
727 /// <param name="avatarid"></param>
728 public void RequestAvatarProperties(UUID avatarid)
729 {
730 AvatarPropertiesRequestPacket aprp = new AvatarPropertiesRequestPacket();
731  
732 aprp.AgentData.AgentID = Client.Self.AgentID;
733 aprp.AgentData.SessionID = Client.Self.SessionID;
734 aprp.AgentData.AvatarID = avatarid;
735  
736 Client.Network.SendPacket(aprp);
737 }
738  
739 /// <summary>
740 /// Search for an avatar (first name, last name)
741 /// </summary>
742 /// <param name="name">The name to search for</param>
743 /// <param name="queryID">An ID to associate with this query</param>
744 public void RequestAvatarNameSearch(string name, UUID queryID)
745 {
746 AvatarPickerRequestPacket aprp = new AvatarPickerRequestPacket();
747  
748 aprp.AgentData.AgentID = Client.Self.AgentID;
749 aprp.AgentData.SessionID = Client.Self.SessionID;
750 aprp.AgentData.QueryID = queryID;
751 aprp.Data.Name = Utils.StringToBytes(name);
752  
753 Client.Network.SendPacket(aprp);
754 }
755  
756 /// <summary>
757 /// Start a request for Avatar Picks
758 /// </summary>
759 /// <param name="avatarid">UUID of the avatar</param>
760 public void RequestAvatarPicks(UUID avatarid)
761 {
762 GenericMessagePacket gmp = new GenericMessagePacket();
763  
764 gmp.AgentData.AgentID = Client.Self.AgentID;
765 gmp.AgentData.SessionID = Client.Self.SessionID;
766 gmp.AgentData.TransactionID = UUID.Zero;
767  
768 gmp.MethodData.Method = Utils.StringToBytes("avatarpicksrequest");
769 gmp.MethodData.Invoice = UUID.Zero;
770 gmp.ParamList = new GenericMessagePacket.ParamListBlock[1];
771 gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock();
772 gmp.ParamList[0].Parameter = Utils.StringToBytes(avatarid.ToString());
773  
774 Client.Network.SendPacket(gmp);
775 }
776  
777 /// <summary>
778 /// Start a request for Avatar Classifieds
779 /// </summary>
780 /// <param name="avatarid">UUID of the avatar</param>
781 public void RequestAvatarClassified(UUID avatarid)
782 {
783 GenericMessagePacket gmp = new GenericMessagePacket();
784  
785 gmp.AgentData.AgentID = Client.Self.AgentID;
786 gmp.AgentData.SessionID = Client.Self.SessionID;
787 gmp.AgentData.TransactionID = UUID.Zero;
788  
789 gmp.MethodData.Method = Utils.StringToBytes("avatarclassifiedsrequest");
790 gmp.MethodData.Invoice = UUID.Zero;
791 gmp.ParamList = new GenericMessagePacket.ParamListBlock[1];
792 gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock();
793 gmp.ParamList[0].Parameter = Utils.StringToBytes(avatarid.ToString());
794  
795 Client.Network.SendPacket(gmp);
796 }
797  
798 /// <summary>
799 /// Start a request for details of a specific profile pick
800 /// </summary>
801 /// <param name="avatarid">UUID of the avatar</param>
802 /// <param name="pickid">UUID of the profile pick</param>
803 public void RequestPickInfo(UUID avatarid, UUID pickid)
804 {
805 GenericMessagePacket gmp = new GenericMessagePacket();
806  
807 gmp.AgentData.AgentID = Client.Self.AgentID;
808 gmp.AgentData.SessionID = Client.Self.SessionID;
809 gmp.AgentData.TransactionID = UUID.Zero;
810  
811 gmp.MethodData.Method = Utils.StringToBytes("pickinforequest");
812 gmp.MethodData.Invoice = UUID.Zero;
813 gmp.ParamList = new GenericMessagePacket.ParamListBlock[2];
814 gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock();
815 gmp.ParamList[0].Parameter = Utils.StringToBytes(avatarid.ToString());
816 gmp.ParamList[1] = new GenericMessagePacket.ParamListBlock();
817 gmp.ParamList[1].Parameter = Utils.StringToBytes(pickid.ToString());
818  
819 Client.Network.SendPacket(gmp);
820 }
821  
822 /// <summary>
823 /// Start a request for details of a specific profile classified
824 /// </summary>
825 /// <param name="avatarid">UUID of the avatar</param>
826 /// <param name="classifiedid">UUID of the profile classified</param>
827 public void RequestClassifiedInfo(UUID avatarid, UUID classifiedid)
828 {
829 GenericMessagePacket gmp = new GenericMessagePacket();
830  
831 gmp.AgentData.AgentID = Client.Self.AgentID;
832 gmp.AgentData.SessionID = Client.Self.SessionID;
833 gmp.AgentData.TransactionID = UUID.Zero;
834  
835 gmp.MethodData.Method = Utils.StringToBytes("classifiedinforequest");
836 gmp.MethodData.Invoice = UUID.Zero;
837 gmp.ParamList = new GenericMessagePacket.ParamListBlock[2];
838 gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock();
839 gmp.ParamList[0].Parameter = Utils.StringToBytes(avatarid.ToString());
840 gmp.ParamList[1] = new GenericMessagePacket.ParamListBlock();
841 gmp.ParamList[1].Parameter = Utils.StringToBytes(classifiedid.ToString());
842  
843 Client.Network.SendPacket(gmp);
844 }
845  
846 #region Packet Handlers
847  
848 /// <summary>Process an incoming packet and raise the appropriate events</summary>
849 /// <param name="sender">The sender</param>
850 /// <param name="e">The EventArgs object containing the packet data</param>
851 protected void UUIDNameReplyHandler(object sender, PacketReceivedEventArgs e)
852 {
853 if (m_UUIDNameReply != null)
854 {
855 Packet packet = e.Packet;
856 Dictionary<UUID, string> names = new Dictionary<UUID, string>();
857 UUIDNameReplyPacket reply = (UUIDNameReplyPacket)packet;
858  
859 foreach (UUIDNameReplyPacket.UUIDNameBlockBlock block in reply.UUIDNameBlock)
860 {
861 names[block.ID] = Utils.BytesToString(block.FirstName) +
862 " " + Utils.BytesToString(block.LastName);
863 }
864  
865 OnUUIDNameReply(new UUIDNameReplyEventArgs(names));
866 }
867 }
868  
869 /// <summary>Process an incoming packet and raise the appropriate events</summary>
870 /// <param name="sender">The sender</param>
871 /// <param name="e">The EventArgs object containing the packet data</param>
872 protected void AvatarAnimationHandler(object sender, PacketReceivedEventArgs e)
873 {
874 Packet packet = e.Packet;
875  
876 AvatarAnimationPacket data = (AvatarAnimationPacket)packet;
877  
878 List<Animation> signaledAnimations = new List<Animation>(data.AnimationList.Length);
879  
880 for (int i = 0; i < data.AnimationList.Length; i++)
881 {
882 Animation animation = new Animation();
883 animation.AnimationID = data.AnimationList[i].AnimID;
884 animation.AnimationSequence = data.AnimationList[i].AnimSequenceID;
885 if (i < data.AnimationSourceList.Length)
886 {
887 animation.AnimationSourceObjectID = data.AnimationSourceList[i].ObjectID;
888 }
889  
890 signaledAnimations.Add(animation);
891 }
892  
893 Avatar avatar = e.Simulator.ObjectsAvatars.Find(avi => avi.ID == data.Sender.ID);
894 if (avatar != null)
895 {
896 avatar.Animations = signaledAnimations;
897 }
898  
899 OnAvatarAnimation(new AvatarAnimationEventArgs(data.Sender.ID, signaledAnimations));
900 }
901  
902 /// <summary>Process an incoming packet and raise the appropriate events</summary>
903 /// <param name="sender">The sender</param>
904 /// <param name="e">The EventArgs object containing the packet data</param>
905 protected void AvatarAppearanceHandler(object sender, PacketReceivedEventArgs e)
906 {
907 if (m_AvatarAppearance != null || Client.Settings.AVATAR_TRACKING)
908 {
909 Packet packet = e.Packet;
910 Simulator simulator = e.Simulator;
911  
912 AvatarAppearancePacket appearance = (AvatarAppearancePacket)packet;
913  
914 List<byte> visualParams = new List<byte>();
915 foreach (AvatarAppearancePacket.VisualParamBlock block in appearance.VisualParam)
916 {
917 visualParams.Add(block.ParamValue);
918 }
919  
920 Primitive.TextureEntry textureEntry = new Primitive.TextureEntry(appearance.ObjectData.TextureEntry, 0,
921 appearance.ObjectData.TextureEntry.Length);
922  
923 Primitive.TextureEntryFace defaultTexture = textureEntry.DefaultTexture;
924 Primitive.TextureEntryFace[] faceTextures = textureEntry.FaceTextures;
925  
926 byte appearanceVersion = 0;
927 int COFVersion = 0;
928 AppearanceFlags appearanceFlags = 0;
929  
930 if (appearance.AppearanceData != null && appearance.AppearanceData.Length > 0)
931 {
932 appearanceVersion = appearance.AppearanceData[0].AppearanceVersion;
933 COFVersion = appearance.AppearanceData[0].CofVersion;
934 appearanceFlags = (AppearanceFlags)appearance.AppearanceData[0].Flags;
935 }
936  
937 Avatar av = simulator.ObjectsAvatars.Find((Avatar a) => { return a.ID == appearance.Sender.ID; });
938 if (av != null)
939 {
940 av.Textures = textureEntry;
941 av.VisualParameters = visualParams.ToArray();
942 av.AppearanceVersion = appearanceVersion;
943 av.COFVersion = COFVersion;
944 av.AppearanceFlags = appearanceFlags;
945 }
946  
947 OnAvatarAppearance(new AvatarAppearanceEventArgs(simulator, appearance.Sender.ID, appearance.Sender.IsTrial,
948 defaultTexture, faceTextures, visualParams, appearanceVersion, COFVersion, appearanceFlags));
949 }
950 }
951  
952 /// <summary>Process an incoming packet and raise the appropriate events</summary>
953 /// <param name="sender">The sender</param>
954 /// <param name="e">The EventArgs object containing the packet data</param>
955 protected void AvatarPropertiesHandler(object sender, PacketReceivedEventArgs e)
956 {
957 if (m_AvatarPropertiesReply != null)
958 {
959 Packet packet = e.Packet;
960 AvatarPropertiesReplyPacket reply = (AvatarPropertiesReplyPacket)packet;
961 Avatar.AvatarProperties properties = new Avatar.AvatarProperties();
962  
963 properties.ProfileImage = reply.PropertiesData.ImageID;
964 properties.FirstLifeImage = reply.PropertiesData.FLImageID;
965 properties.Partner = reply.PropertiesData.PartnerID;
966 properties.AboutText = Utils.BytesToString(reply.PropertiesData.AboutText);
967 properties.FirstLifeText = Utils.BytesToString(reply.PropertiesData.FLAboutText);
968 properties.BornOn = Utils.BytesToString(reply.PropertiesData.BornOn);
969 //properties.CharterMember = Utils.BytesToString(reply.PropertiesData.CharterMember);
970 uint charter = Utils.BytesToUInt(reply.PropertiesData.CharterMember);
971 if (charter == 0)
972 {
973 properties.CharterMember = "Resident";
974 }
975 else if (charter == 2)
976 {
977 properties.CharterMember = "Charter";
978 }
979 else if (charter == 3)
980 {
981 properties.CharterMember = "Linden";
982 }
983 else
984 {
985 properties.CharterMember = Utils.BytesToString(reply.PropertiesData.CharterMember);
986 }
987 properties.Flags = (ProfileFlags)reply.PropertiesData.Flags;
988 properties.ProfileURL = Utils.BytesToString(reply.PropertiesData.ProfileURL);
989  
990 OnAvatarPropertiesReply(new AvatarPropertiesReplyEventArgs(reply.AgentData.AvatarID, properties));
991 }
992 }
993  
994 /// <summary>Process an incoming packet and raise the appropriate events</summary>
995 /// <param name="sender">The sender</param>
996 /// <param name="e">The EventArgs object containing the packet data</param>
997 protected void AvatarInterestsHandler(object sender, PacketReceivedEventArgs e)
998 {
999 if (m_AvatarInterestsReply != null)
1000 {
1001 Packet packet = e.Packet;
1002  
1003 AvatarInterestsReplyPacket airp = (AvatarInterestsReplyPacket)packet;
1004 Avatar.Interests interests = new Avatar.Interests();
1005  
1006 interests.WantToMask = airp.PropertiesData.WantToMask;
1007 interests.WantToText = Utils.BytesToString(airp.PropertiesData.WantToText);
1008 interests.SkillsMask = airp.PropertiesData.SkillsMask;
1009 interests.SkillsText = Utils.BytesToString(airp.PropertiesData.SkillsText);
1010 interests.LanguagesText = Utils.BytesToString(airp.PropertiesData.LanguagesText);
1011  
1012 OnAvatarInterestsReply(new AvatarInterestsReplyEventArgs(airp.AgentData.AvatarID, interests));
1013 }
1014 }
1015  
1016 /// <summary>
1017 /// EQ Message fired when someone nearby changes their display name
1018 /// </summary>
1019 /// <param name="capsKey">The message key</param>
1020 /// <param name="message">the IMessage object containing the deserialized data sent from the simulator</param>
1021 /// <param name="simulator">The <see cref="Simulator"/> which originated the packet</param>
1022 protected void DisplayNameUpdateMessageHandler(string capsKey, IMessage message, Simulator simulator)
1023 {
1024 if (m_DisplayNameUpdate != null)
1025 {
1026 DisplayNameUpdateMessage msg = (DisplayNameUpdateMessage)message;
1027 OnDisplayNameUpdate(new DisplayNameUpdateEventArgs(msg.OldDisplayName, msg.DisplayName));
1028 }
1029 }
1030  
1031 /// <summary>
1032 /// Crossed region handler for message that comes across the EventQueue. Sent to an agent
1033 /// when the agent crosses a sim border into a new region.
1034 /// </summary>
1035 /// <param name="capsKey">The message key</param>
1036 /// <param name="message">the IMessage object containing the deserialized data sent from the simulator</param>
1037 /// <param name="simulator">The <see cref="Simulator"/> which originated the packet</param>
1038 protected void AvatarGroupsReplyMessageHandler(string capsKey, IMessage message, Simulator simulator)
1039 {
1040 AgentGroupDataUpdateMessage msg = (AgentGroupDataUpdateMessage)message;
1041 List<AvatarGroup> avatarGroups = new List<AvatarGroup>(msg.GroupDataBlock.Length);
1042 for (int i = 0; i < msg.GroupDataBlock.Length; i++)
1043 {
1044 AvatarGroup avatarGroup = new AvatarGroup();
1045 avatarGroup.AcceptNotices = msg.GroupDataBlock[i].AcceptNotices;
1046 avatarGroup.GroupID = msg.GroupDataBlock[i].GroupID;
1047 avatarGroup.GroupInsigniaID = msg.GroupDataBlock[i].GroupInsigniaID;
1048 avatarGroup.GroupName = msg.GroupDataBlock[i].GroupName;
1049 avatarGroup.GroupPowers = msg.GroupDataBlock[i].GroupPowers;
1050 avatarGroup.ListInProfile = msg.NewGroupDataBlock[i].ListInProfile;
1051  
1052 avatarGroups.Add(avatarGroup);
1053 }
1054  
1055 OnAvatarGroupsReply(new AvatarGroupsReplyEventArgs(msg.AgentID, avatarGroups));
1056 }
1057  
1058 /// <summary>Process an incoming packet and raise the appropriate events</summary>
1059 /// <param name="sender">The sender</param>
1060 /// <param name="e">The EventArgs object containing the packet data</param>
1061 protected void AvatarGroupsReplyHandler(object sender, PacketReceivedEventArgs e)
1062 {
1063 if (m_AvatarGroupsReply != null)
1064 {
1065 Packet packet = e.Packet;
1066 AvatarGroupsReplyPacket groups = (AvatarGroupsReplyPacket)packet;
1067 List<AvatarGroup> avatarGroups = new List<AvatarGroup>(groups.GroupData.Length);
1068  
1069 for (int i = 0; i < groups.GroupData.Length; i++)
1070 {
1071 AvatarGroup avatarGroup = new AvatarGroup();
1072  
1073 avatarGroup.AcceptNotices = groups.GroupData[i].AcceptNotices;
1074 avatarGroup.GroupID = groups.GroupData[i].GroupID;
1075 avatarGroup.GroupInsigniaID = groups.GroupData[i].GroupInsigniaID;
1076 avatarGroup.GroupName = Utils.BytesToString(groups.GroupData[i].GroupName);
1077 avatarGroup.GroupPowers = (GroupPowers)groups.GroupData[i].GroupPowers;
1078 avatarGroup.GroupTitle = Utils.BytesToString(groups.GroupData[i].GroupTitle);
1079 avatarGroup.ListInProfile = groups.NewGroupData.ListInProfile;
1080  
1081 avatarGroups.Add(avatarGroup);
1082 }
1083  
1084 OnAvatarGroupsReply(new AvatarGroupsReplyEventArgs(groups.AgentData.AvatarID, avatarGroups));
1085 }
1086 }
1087  
1088 /// <summary>Process an incoming packet and raise the appropriate events</summary>
1089 /// <param name="sender">The sender</param>
1090 /// <param name="e">The EventArgs object containing the packet data</param>
1091 protected void AvatarPickerReplyHandler(object sender, PacketReceivedEventArgs e)
1092 {
1093 if (m_AvatarPickerReply != null)
1094 {
1095 Packet packet = e.Packet;
1096 AvatarPickerReplyPacket reply = (AvatarPickerReplyPacket)packet;
1097 Dictionary<UUID, string> avatars = new Dictionary<UUID, string>();
1098  
1099 foreach (AvatarPickerReplyPacket.DataBlock block in reply.Data)
1100 {
1101 avatars[block.AvatarID] = Utils.BytesToString(block.FirstName) +
1102 " " + Utils.BytesToString(block.LastName);
1103 }
1104 OnAvatarPickerReply(new AvatarPickerReplyEventArgs(reply.AgentData.QueryID, avatars));
1105 }
1106 }
1107  
1108 /// <summary>Process an incoming packet and raise the appropriate events</summary>
1109 /// <param name="sender">The sender</param>
1110 /// <param name="e">The EventArgs object containing the packet data</param>
1111 protected void ViewerEffectHandler(object sender, PacketReceivedEventArgs e)
1112 {
1113 Packet packet = e.Packet;
1114 ViewerEffectPacket effect = (ViewerEffectPacket)packet;
1115  
1116 foreach (ViewerEffectPacket.EffectBlock block in effect.Effect)
1117 {
1118 EffectType type = (EffectType)block.Type;
1119  
1120 // Each ViewerEffect type uses it's own custom binary format for additional data. Fun eh?
1121 switch (type)
1122 {
1123 case EffectType.Text:
1124 Logger.Log("Received a ViewerEffect of type " + type.ToString() + ", implement me!",
1125 Helpers.LogLevel.Warning, Client);
1126 break;
1127 case EffectType.Icon:
1128 Logger.Log("Received a ViewerEffect of type " + type.ToString() + ", implement me!",
1129 Helpers.LogLevel.Warning, Client);
1130 break;
1131 case EffectType.Connector:
1132 Logger.Log("Received a ViewerEffect of type " + type.ToString() + ", implement me!",
1133 Helpers.LogLevel.Warning, Client);
1134 break;
1135 case EffectType.FlexibleObject:
1136 Logger.Log("Received a ViewerEffect of type " + type.ToString() + ", implement me!",
1137 Helpers.LogLevel.Warning, Client);
1138 break;
1139 case EffectType.AnimalControls:
1140 Logger.Log("Received a ViewerEffect of type " + type.ToString() + ", implement me!",
1141 Helpers.LogLevel.Warning, Client);
1142 break;
1143 case EffectType.AnimationObject:
1144 Logger.Log("Received a ViewerEffect of type " + type.ToString() + ", implement me!",
1145 Helpers.LogLevel.Warning, Client);
1146 break;
1147 case EffectType.Cloth:
1148 Logger.Log("Received a ViewerEffect of type " + type.ToString() + ", implement me!",
1149 Helpers.LogLevel.Warning, Client);
1150 break;
1151 case EffectType.Glow:
1152 Logger.Log("Received a Glow ViewerEffect which is not implemented yet",
1153 Helpers.LogLevel.Warning, Client);
1154 break;
1155 case EffectType.Beam:
1156 case EffectType.Point:
1157 case EffectType.Trail:
1158 case EffectType.Sphere:
1159 case EffectType.Spiral:
1160 case EffectType.Edit:
1161 if (m_ViewerEffect != null)
1162 {
1163 if (block.TypeData.Length == 56)
1164 {
1165 UUID sourceAvatar = new UUID(block.TypeData, 0);
1166 UUID targetObject = new UUID(block.TypeData, 16);
1167 Vector3d targetPos = new Vector3d(block.TypeData, 32);
1168 OnViewerEffect(new ViewerEffectEventArgs(type, sourceAvatar, targetObject, targetPos, block.Duration, block.ID));
1169 }
1170 else
1171 {
1172 Logger.Log("Received a " + type.ToString() +
1173 " ViewerEffect with an incorrect TypeData size of " +
1174 block.TypeData.Length + " bytes", Helpers.LogLevel.Warning, Client);
1175 }
1176 }
1177 break;
1178 case EffectType.LookAt:
1179 if (m_ViewerEffectLookAt != null)
1180 {
1181 if (block.TypeData.Length == 57)
1182 {
1183 UUID sourceAvatar = new UUID(block.TypeData, 0);
1184 UUID targetObject = new UUID(block.TypeData, 16);
1185 Vector3d targetPos = new Vector3d(block.TypeData, 32);
1186 LookAtType lookAt = (LookAtType)block.TypeData[56];
1187  
1188 OnViewerEffectLookAt(new ViewerEffectLookAtEventArgs(sourceAvatar, targetObject, targetPos, lookAt,
1189 block.Duration, block.ID));
1190 }
1191 else
1192 {
1193 Logger.Log("Received a LookAt ViewerEffect with an incorrect TypeData size of " +
1194 block.TypeData.Length + " bytes", Helpers.LogLevel.Warning, Client);
1195 }
1196 }
1197 break;
1198 case EffectType.PointAt:
1199 if (m_ViewerEffectPointAt != null)
1200 {
1201 if (block.TypeData.Length == 57)
1202 {
1203 UUID sourceAvatar = new UUID(block.TypeData, 0);
1204 UUID targetObject = new UUID(block.TypeData, 16);
1205 Vector3d targetPos = new Vector3d(block.TypeData, 32);
1206 PointAtType pointAt = (PointAtType)block.TypeData[56];
1207  
1208 OnViewerEffectPointAt(new ViewerEffectPointAtEventArgs(e.Simulator, sourceAvatar, targetObject, targetPos,
1209 pointAt, block.Duration, block.ID));
1210 }
1211 else
1212 {
1213 Logger.Log("Received a PointAt ViewerEffect with an incorrect TypeData size of " +
1214 block.TypeData.Length + " bytes", Helpers.LogLevel.Warning, Client);
1215 }
1216 }
1217 break;
1218 default:
1219 Logger.Log("Received a ViewerEffect with an unknown type " + type, Helpers.LogLevel.Warning, Client);
1220 break;
1221 }
1222 }
1223 }
1224  
1225 /// <summary>Process an incoming packet and raise the appropriate events</summary>
1226 /// <param name="sender">The sender</param>
1227 /// <param name="e">The EventArgs object containing the packet data</param>
1228 protected void AvatarPicksReplyHandler(object sender, PacketReceivedEventArgs e)
1229 {
1230 if (m_AvatarPicksReply == null)
1231 {
1232 return;
1233 }
1234 Packet packet = e.Packet;
1235  
1236 AvatarPicksReplyPacket p = (AvatarPicksReplyPacket)packet;
1237 Dictionary<UUID, string> picks = new Dictionary<UUID, string>();
1238  
1239 foreach (AvatarPicksReplyPacket.DataBlock b in p.Data)
1240 {
1241 picks.Add(b.PickID, Utils.BytesToString(b.PickName));
1242 }
1243  
1244 OnAvatarPicksReply(new AvatarPicksReplyEventArgs(p.AgentData.TargetID, picks));
1245 }
1246  
1247 /// <summary>Process an incoming packet and raise the appropriate events</summary>
1248 /// <param name="sender">The sender</param>
1249 /// <param name="e">The EventArgs object containing the packet data</param>
1250 protected void PickInfoReplyHandler(object sender, PacketReceivedEventArgs e)
1251 {
1252 if (m_PickInfoReply != null)
1253 {
1254 Packet packet = e.Packet;
1255 PickInfoReplyPacket p = (PickInfoReplyPacket)packet;
1256 ProfilePick ret = new ProfilePick();
1257 ret.CreatorID = p.Data.CreatorID;
1258 ret.Desc = Utils.BytesToString(p.Data.Desc);
1259 ret.Enabled = p.Data.Enabled;
1260 ret.Name = Utils.BytesToString(p.Data.Name);
1261 ret.OriginalName = Utils.BytesToString(p.Data.OriginalName);
1262 ret.ParcelID = p.Data.ParcelID;
1263 ret.PickID = p.Data.PickID;
1264 ret.PosGlobal = p.Data.PosGlobal;
1265 ret.SimName = Utils.BytesToString(p.Data.SimName);
1266 ret.SnapshotID = p.Data.SnapshotID;
1267 ret.SortOrder = p.Data.SortOrder;
1268 ret.TopPick = p.Data.TopPick;
1269 ret.User = Utils.BytesToString(p.Data.User);
1270  
1271 OnPickInfoReply(new PickInfoReplyEventArgs(ret.PickID, ret));
1272 }
1273 }
1274  
1275 /// <summary>Process an incoming packet and raise the appropriate events</summary>
1276 /// <param name="sender">The sender</param>
1277 /// <param name="e">The EventArgs object containing the packet data</param>
1278 protected void AvatarClassifiedReplyHandler(object sender, PacketReceivedEventArgs e)
1279 {
1280 if (m_AvatarClassifiedReply != null)
1281 {
1282 Packet packet = e.Packet;
1283 AvatarClassifiedReplyPacket p = (AvatarClassifiedReplyPacket)packet;
1284 Dictionary<UUID, string> classifieds = new Dictionary<UUID, string>();
1285  
1286 foreach (AvatarClassifiedReplyPacket.DataBlock b in p.Data)
1287 {
1288 classifieds.Add(b.ClassifiedID, Utils.BytesToString(b.Name));
1289 }
1290  
1291 OnAvatarClassifiedReply(new AvatarClassifiedReplyEventArgs(p.AgentData.TargetID, classifieds));
1292 }
1293 }
1294  
1295 /// <summary>Process an incoming packet and raise the appropriate events</summary>
1296 /// <param name="sender">The sender</param>
1297 /// <param name="e">The EventArgs object containing the packet data</param>
1298 protected void ClassifiedInfoReplyHandler(object sender, PacketReceivedEventArgs e)
1299 {
1300 if (m_AvatarClassifiedReply != null)
1301 {
1302 Packet packet = e.Packet;
1303 ClassifiedInfoReplyPacket p = (ClassifiedInfoReplyPacket)packet;
1304 ClassifiedAd ret = new ClassifiedAd();
1305 ret.Desc = Utils.BytesToString(p.Data.Desc);
1306 ret.Name = Utils.BytesToString(p.Data.Name);
1307 ret.ParcelID = p.Data.ParcelID;
1308 ret.ClassifiedID = p.Data.ClassifiedID;
1309 ret.Position = p.Data.PosGlobal;
1310 ret.SnapShotID = p.Data.SnapshotID;
1311 ret.Price = p.Data.PriceForListing;
1312 ret.ParentEstate = p.Data.ParentEstate;
1313 ret.ClassifiedFlags = p.Data.ClassifiedFlags;
1314 ret.Catagory = p.Data.Category;
1315  
1316 OnClassifiedInfoReply(new ClassifiedInfoReplyEventArgs(ret.ClassifiedID, ret));
1317 }
1318 }
1319  
1320 #endregion Packet Handlers
1321 }
1322  
1323 #region EventArgs
1324  
1325 /// <summary>Provides data for the <see cref="AvatarManager.AvatarAnimation"/> event</summary>
1326 /// <remarks>The <see cref="AvatarManager.AvatarAnimation"/> event occurs when the simulator sends
1327 /// the animation playlist for an agent</remarks>
1328 /// <example>
1329 /// The following code example uses the <see cref="AvatarAnimationEventArgs.AvatarID"/> and <see cref="AvatarAnimationEventArgs.Animations"/>
1330 /// properties to display the animation playlist of an avatar on the <see cref="Console"/> window.
1331 /// <code>
1332 /// // subscribe to the event
1333 /// Client.Avatars.AvatarAnimation += Avatars_AvatarAnimation;
1334 ///
1335 /// private void Avatars_AvatarAnimation(object sender, AvatarAnimationEventArgs e)
1336 /// {
1337 /// // create a dictionary of "known" animations from the Animations class using System.Reflection
1338 /// Dictionary&lt;UUID, string&gt; systemAnimations = new Dictionary&lt;UUID, string&gt;();
1339 /// Type type = typeof(Animations);
1340 /// System.Reflection.FieldInfo[] fields = type.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
1341 /// foreach (System.Reflection.FieldInfo field in fields)
1342 /// {
1343 /// systemAnimations.Add((UUID)field.GetValue(type), field.Name);
1344 /// }
1345 ///
1346 /// // find out which animations being played are known animations and which are assets
1347 /// foreach (Animation animation in e.Animations)
1348 /// {
1349 /// if (systemAnimations.ContainsKey(animation.AnimationID))
1350 /// {
1351 /// Console.WriteLine("{0} is playing {1} ({2}) sequence {3}", e.AvatarID,
1352 /// systemAnimations[animation.AnimationID], animation.AnimationSequence);
1353 /// }
1354 /// else
1355 /// {
1356 /// Console.WriteLine("{0} is playing {1} (Asset) sequence {2}", e.AvatarID,
1357 /// animation.AnimationID, animation.AnimationSequence);
1358 /// }
1359 /// }
1360 /// }
1361 /// </code>
1362 /// </example>
1363 public class AvatarAnimationEventArgs : EventArgs
1364 {
1365 private readonly UUID m_AvatarID;
1366 private readonly List<Animation> m_Animations;
1367  
1368 /// <summary>Get the ID of the agent</summary>
1369 public UUID AvatarID { get { return m_AvatarID; } }
1370 /// <summary>Get the list of animations to start</summary>
1371 public List<Animation> Animations { get { return m_Animations; } }
1372  
1373 /// <summary>
1374 /// Construct a new instance of the AvatarAnimationEventArgs class
1375 /// </summary>
1376 /// <param name="avatarID">The ID of the agent</param>
1377 /// <param name="anims">The list of animations to start</param>
1378 public AvatarAnimationEventArgs(UUID avatarID, List<Animation> anims)
1379 {
1380 this.m_AvatarID = avatarID;
1381 this.m_Animations = anims;
1382 }
1383 }
1384  
1385 /// <summary>Provides data for the <see cref="AvatarManager.AvatarAppearance"/> event</summary>
1386 /// <remarks>The <see cref="AvatarManager.AvatarAppearance"/> event occurs when the simulator sends
1387 /// the appearance data for an avatar</remarks>
1388 /// <example>
1389 /// The following code example uses the <see cref="AvatarAppearanceEventArgs.AvatarID"/> and <see cref="AvatarAppearanceEventArgs.VisualParams"/>
1390 /// properties to display the selected shape of an avatar on the <see cref="Console"/> window.
1391 /// <code>
1392 /// // subscribe to the event
1393 /// Client.Avatars.AvatarAppearance += Avatars_AvatarAppearance;
1394 ///
1395 /// // handle the data when the event is raised
1396 /// void Avatars_AvatarAppearance(object sender, AvatarAppearanceEventArgs e)
1397 /// {
1398 /// Console.WriteLine("The Agent {0} is using a {1} shape.", e.AvatarID, (e.VisualParams[31] &gt; 0) : "male" ? "female")
1399 /// }
1400 /// </code>
1401 /// </example>
1402 public class AvatarAppearanceEventArgs : EventArgs
1403 {
1404  
1405 private readonly Simulator m_Simulator;
1406 private readonly UUID m_AvatarID;
1407 private readonly bool m_IsTrial;
1408 private readonly Primitive.TextureEntryFace m_DefaultTexture;
1409 private readonly Primitive.TextureEntryFace[] m_FaceTextures;
1410 private readonly List<byte> m_VisualParams;
1411 private readonly byte m_AppearanceVersion;
1412 private readonly int m_COFVersion;
1413 private readonly AppearanceFlags m_AppearanceFlags;
1414  
1415 /// <summary>Get the Simulator this request is from of the agent</summary>
1416 public Simulator Simulator { get { return m_Simulator; } }
1417 /// <summary>Get the ID of the agent</summary>
1418 public UUID AvatarID { get { return m_AvatarID; } }
1419 /// <summary>true if the agent is a trial account</summary>
1420 public bool IsTrial { get { return m_IsTrial; } }
1421 /// <summary>Get the default agent texture</summary>
1422 public Primitive.TextureEntryFace DefaultTexture { get { return m_DefaultTexture; } }
1423 /// <summary>Get the agents appearance layer textures</summary>
1424 public Primitive.TextureEntryFace[] FaceTextures { get { return m_FaceTextures; } }
1425 /// <summary>Get the <see cref="VisualParams"/> for the agent</summary>
1426 public List<byte> VisualParams { get { return m_VisualParams; } }
1427 /// <summary>Version of the appearance system used.
1428 /// Value greater than 0 indicates that server side baking is used</summary>
1429 public byte AppearanceVersion { get { return m_AppearanceVersion; } }
1430 /// <summary>Version of the Current Outfit Folder the appearance is based on</summary>
1431 public int COFVersion { get { return m_COFVersion; } }
1432 /// <summary>Appearance flags, introduced with server side baking, currently unused</summary>
1433 public AppearanceFlags AppearanceFlags { get { return m_AppearanceFlags; } }
1434  
1435 /// <summary>
1436 /// Construct a new instance of the AvatarAppearanceEventArgs class
1437 /// </summary>
1438 /// <param name="sim">The simulator request was from</param>
1439 /// <param name="avatarID">The ID of the agent</param>
1440 /// <param name="isTrial">true of the agent is a trial account</param>
1441 /// <param name="defaultTexture">The default agent texture</param>
1442 /// <param name="faceTextures">The agents appearance layer textures</param>
1443 /// <param name="visualParams">The <see cref="VisualParams"/> for the agent</param>
1444 public AvatarAppearanceEventArgs(Simulator sim, UUID avatarID, bool isTrial, Primitive.TextureEntryFace defaultTexture,
1445 Primitive.TextureEntryFace[] faceTextures, List<byte> visualParams,
1446 byte appearanceVersion, int COFVersion, AppearanceFlags appearanceFlags)
1447 {
1448 this.m_Simulator = sim;
1449 this.m_AvatarID = avatarID;
1450 this.m_IsTrial = isTrial;
1451 this.m_DefaultTexture = defaultTexture;
1452 this.m_FaceTextures = faceTextures;
1453 this.m_VisualParams = visualParams;
1454 this.m_AppearanceVersion = appearanceVersion;
1455 this.m_COFVersion = COFVersion;
1456 this.m_AppearanceFlags = appearanceFlags;
1457 }
1458 }
1459  
1460 /// <summary>Represents the interests from the profile of an agent</summary>
1461 public class AvatarInterestsReplyEventArgs : EventArgs
1462 {
1463 private readonly UUID m_AvatarID;
1464 private readonly Avatar.Interests m_Interests;
1465  
1466 /// <summary>Get the ID of the agent</summary>
1467 public UUID AvatarID { get { return m_AvatarID; } }
1468 public Avatar.Interests Interests { get { return m_Interests; } }
1469  
1470 public AvatarInterestsReplyEventArgs(UUID avatarID, Avatar.Interests interests)
1471 {
1472 this.m_AvatarID = avatarID;
1473 this.m_Interests = interests;
1474 }
1475 }
1476  
1477 /// <summary>The properties of an agent</summary>
1478 public class AvatarPropertiesReplyEventArgs : EventArgs
1479 {
1480 private readonly UUID m_AvatarID;
1481 private readonly Avatar.AvatarProperties m_Properties;
1482  
1483 /// <summary>Get the ID of the agent</summary>
1484 public UUID AvatarID { get { return m_AvatarID; } }
1485 public Avatar.AvatarProperties Properties { get { return m_Properties; } }
1486  
1487 public AvatarPropertiesReplyEventArgs(UUID avatarID, Avatar.AvatarProperties properties)
1488 {
1489 this.m_AvatarID = avatarID;
1490 this.m_Properties = properties;
1491 }
1492 }
1493  
1494  
1495 public class AvatarGroupsReplyEventArgs : EventArgs
1496 {
1497 private readonly UUID m_AvatarID;
1498 private readonly List<AvatarGroup> m_Groups;
1499  
1500 /// <summary>Get the ID of the agent</summary>
1501 public UUID AvatarID { get { return m_AvatarID; } }
1502 public List<AvatarGroup> Groups { get { return m_Groups; } }
1503  
1504 public AvatarGroupsReplyEventArgs(UUID avatarID, List<AvatarGroup> avatarGroups)
1505 {
1506 this.m_AvatarID = avatarID;
1507 this.m_Groups = avatarGroups;
1508 }
1509 }
1510  
1511 public class AvatarPicksReplyEventArgs : EventArgs
1512 {
1513 private readonly UUID m_AvatarID;
1514 private readonly Dictionary<UUID, string> m_Picks;
1515  
1516 /// <summary>Get the ID of the agent</summary>
1517 public UUID AvatarID { get { return m_AvatarID; } }
1518 public Dictionary<UUID, string> Picks { get { return m_Picks; } }
1519  
1520 public AvatarPicksReplyEventArgs(UUID avatarid, Dictionary<UUID, string> picks)
1521 {
1522 this.m_AvatarID = avatarid;
1523 this.m_Picks = picks;
1524 }
1525 }
1526  
1527 public class PickInfoReplyEventArgs : EventArgs
1528 {
1529 private readonly UUID m_PickID;
1530 private readonly ProfilePick m_Pick;
1531  
1532 public UUID PickID { get { return m_PickID; } }
1533 public ProfilePick Pick { get { return m_Pick; } }
1534  
1535  
1536 public PickInfoReplyEventArgs(UUID pickid, ProfilePick pick)
1537 {
1538 this.m_PickID = pickid;
1539 this.m_Pick = pick;
1540 }
1541 }
1542  
1543 public class AvatarClassifiedReplyEventArgs : EventArgs
1544 {
1545 private readonly UUID m_AvatarID;
1546 private readonly Dictionary<UUID, string> m_Classifieds;
1547  
1548 /// <summary>Get the ID of the avatar</summary>
1549 public UUID AvatarID { get { return m_AvatarID; } }
1550 public Dictionary<UUID, string> Classifieds { get { return m_Classifieds; } }
1551  
1552 public AvatarClassifiedReplyEventArgs(UUID avatarid, Dictionary<UUID, string> classifieds)
1553 {
1554 this.m_AvatarID = avatarid;
1555 this.m_Classifieds = classifieds;
1556 }
1557 }
1558  
1559 public class ClassifiedInfoReplyEventArgs : EventArgs
1560 {
1561 private readonly UUID m_ClassifiedID;
1562 private readonly ClassifiedAd m_Classified;
1563  
1564 public UUID ClassifiedID { get { return m_ClassifiedID; } }
1565 public ClassifiedAd Classified { get { return m_Classified; } }
1566  
1567  
1568 public ClassifiedInfoReplyEventArgs(UUID classifiedID, ClassifiedAd Classified)
1569 {
1570 this.m_ClassifiedID = classifiedID;
1571 this.m_Classified = Classified;
1572 }
1573 }
1574  
1575 public class UUIDNameReplyEventArgs : EventArgs
1576 {
1577 private readonly Dictionary<UUID, string> m_Names;
1578  
1579 public Dictionary<UUID, string> Names { get { return m_Names; } }
1580  
1581 public UUIDNameReplyEventArgs(Dictionary<UUID, string> names)
1582 {
1583 this.m_Names = names;
1584 }
1585 }
1586  
1587 public class AvatarPickerReplyEventArgs : EventArgs
1588 {
1589 private readonly UUID m_QueryID;
1590 private readonly Dictionary<UUID, string> m_Avatars;
1591  
1592 public UUID QueryID { get { return m_QueryID; } }
1593 public Dictionary<UUID, string> Avatars { get { return m_Avatars; } }
1594  
1595 public AvatarPickerReplyEventArgs(UUID queryID, Dictionary<UUID, string> avatars)
1596 {
1597 this.m_QueryID = queryID;
1598 this.m_Avatars = avatars;
1599 }
1600 }
1601  
1602 public class ViewerEffectEventArgs : EventArgs
1603 {
1604 private readonly EffectType m_Type;
1605 private readonly UUID m_SourceID;
1606 private readonly UUID m_TargetID;
1607 private readonly Vector3d m_TargetPosition;
1608 private readonly float m_Duration;
1609 private readonly UUID m_EffectID;
1610  
1611 public EffectType Type { get { return m_Type; } }
1612 public UUID SourceID { get { return m_SourceID; } }
1613 public UUID TargetID { get { return m_TargetID; } }
1614 public Vector3d TargetPosition { get { return m_TargetPosition; } }
1615 public float Duration { get { return m_Duration; } }
1616 public UUID EffectID { get { return m_EffectID; } }
1617  
1618 public ViewerEffectEventArgs(EffectType type, UUID sourceID, UUID targetID, Vector3d targetPos, float duration, UUID id)
1619 {
1620 this.m_Type = type;
1621 this.m_SourceID = sourceID;
1622 this.m_TargetID = targetID;
1623 this.m_TargetPosition = targetPos;
1624 this.m_Duration = duration;
1625 this.m_EffectID = id;
1626 }
1627 }
1628  
1629 public class ViewerEffectPointAtEventArgs : EventArgs
1630 {
1631 private readonly Simulator m_Simulator;
1632 private readonly UUID m_SourceID;
1633 private readonly UUID m_TargetID;
1634 private readonly Vector3d m_TargetPosition;
1635 private readonly PointAtType m_PointType;
1636 private readonly float m_Duration;
1637 private readonly UUID m_EffectID;
1638  
1639 public Simulator Simulator { get { return m_Simulator; } }
1640 public UUID SourceID { get { return m_SourceID; } }
1641 public UUID TargetID { get { return m_TargetID; } }
1642 public Vector3d TargetPosition { get { return m_TargetPosition; } }
1643 public PointAtType PointType { get { return m_PointType; } }
1644 public float Duration { get { return m_Duration; } }
1645 public UUID EffectID { get { return m_EffectID; } }
1646  
1647 public ViewerEffectPointAtEventArgs(Simulator simulator, UUID sourceID, UUID targetID, Vector3d targetPos, PointAtType pointType, float duration, UUID id)
1648 {
1649 this.m_Simulator = simulator;
1650 this.m_SourceID = sourceID;
1651 this.m_TargetID = targetID;
1652 this.m_TargetPosition = targetPos;
1653 this.m_PointType = pointType;
1654 this.m_Duration = duration;
1655 this.m_EffectID = id;
1656 }
1657 }
1658  
1659 public class ViewerEffectLookAtEventArgs : EventArgs
1660 {
1661 private readonly UUID m_SourceID;
1662 private readonly UUID m_TargetID;
1663 private readonly Vector3d m_TargetPosition;
1664 private readonly LookAtType m_LookType;
1665 private readonly float m_Duration;
1666 private readonly UUID m_EffectID;
1667  
1668  
1669 public UUID SourceID { get { return m_SourceID; } }
1670 public UUID TargetID { get { return m_TargetID; } }
1671 public Vector3d TargetPosition { get { return m_TargetPosition; } }
1672 public LookAtType LookType { get { return m_LookType; } }
1673 public float Duration { get { return m_Duration; } }
1674 public UUID EffectID { get { return m_EffectID; } }
1675  
1676 public ViewerEffectLookAtEventArgs(UUID sourceID, UUID targetID, Vector3d targetPos, LookAtType lookType, float duration, UUID id)
1677 {
1678 this.m_SourceID = sourceID;
1679 this.m_TargetID = targetID;
1680 this.m_TargetPosition = targetPos;
1681 this.m_LookType = lookType;
1682 this.m_Duration = duration;
1683 this.m_EffectID = id;
1684 }
1685 }
1686  
1687 /// <summary>
1688 /// Event args class for display name notification messages
1689 /// </summary>
1690 public class DisplayNameUpdateEventArgs : EventArgs
1691 {
1692 private string oldDisplayName;
1693 private AgentDisplayName displayName;
1694  
1695 public string OldDisplayName { get { return oldDisplayName; } }
1696 public AgentDisplayName DisplayName { get { return displayName; } }
1697  
1698 public DisplayNameUpdateEventArgs(string oldDisplayName, AgentDisplayName displayName)
1699 {
1700 this.oldDisplayName = oldDisplayName;
1701 this.displayName = displayName;
1702 }
1703 }
1704 #endregion
1705 }