corrade-vassal – Blame information for rev 1
?pathlinks?
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<UUID, string> systemAnimations = new Dictionary<UUID, string>(); |
||
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] > 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 | } |