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 | * - Redistributions of source code must retain the above copyright notice, this |
||
8 | * list of conditions and the following disclaimer. |
||
9 | * - Neither the name of the openmetaverse.org nor the names |
||
10 | * of its contributors may be used to endorse or promote products derived from |
||
11 | * this software without specific prior written permission. |
||
12 | * |
||
13 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||
14 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||
15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||
16 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
||
17 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
||
18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
||
19 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
||
20 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
||
21 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||
22 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
||
23 | * POSSIBILITY OF SUCH DAMAGE. |
||
24 | */ |
||
25 | |||
26 | using System; |
||
27 | using System.Text; |
||
28 | using System.Collections.Generic; |
||
29 | using OpenMetaverse.Packets; |
||
30 | |||
31 | namespace OpenMetaverse |
||
32 | { |
||
33 | /// <summary> |
||
34 | /// |
||
35 | /// </summary> |
||
36 | [Flags] |
||
37 | public enum FriendRights : int |
||
38 | { |
||
39 | /// <summary>The avatar has no rights</summary> |
||
40 | None = 0, |
||
41 | /// <summary>The avatar can see the online status of the target avatar</summary> |
||
42 | CanSeeOnline = 1, |
||
43 | /// <summary>The avatar can see the location of the target avatar on the map</summary> |
||
44 | CanSeeOnMap = 2, |
||
45 | /// <summary>The avatar can modify the ojects of the target avatar </summary> |
||
46 | CanModifyObjects = 4 |
||
47 | } |
||
48 | |||
49 | /// <summary> |
||
50 | /// This class holds information about an avatar in the friends list. There are two ways |
||
51 | /// to interface to this class. The first is through the set of boolean properties. This is the typical |
||
52 | /// way clients of this class will use it. The second interface is through two bitflag properties, |
||
53 | /// TheirFriendsRights and MyFriendsRights |
||
54 | /// </summary> |
||
55 | public class FriendInfo |
||
56 | { |
||
57 | private UUID m_id; |
||
58 | private string m_name; |
||
59 | private bool m_isOnline; |
||
60 | private bool m_canSeeMeOnline; |
||
61 | private bool m_canSeeMeOnMap; |
||
62 | private bool m_canModifyMyObjects; |
||
63 | private bool m_canSeeThemOnline; |
||
64 | private bool m_canSeeThemOnMap; |
||
65 | private bool m_canModifyTheirObjects; |
||
66 | |||
67 | #region Properties |
||
68 | |||
69 | /// <summary> |
||
70 | /// System ID of the avatar |
||
71 | /// </summary> |
||
72 | public UUID UUID { get { return m_id; } } |
||
73 | |||
74 | /// <summary> |
||
75 | /// full name of the avatar |
||
76 | /// </summary> |
||
77 | public string Name |
||
78 | { |
||
79 | get { return m_name; } |
||
80 | set { m_name = value; } |
||
81 | } |
||
82 | |||
83 | /// <summary> |
||
84 | /// True if the avatar is online |
||
85 | /// </summary> |
||
86 | public bool IsOnline |
||
87 | { |
||
88 | get { return m_isOnline; } |
||
89 | set { m_isOnline = value; } |
||
90 | } |
||
91 | |||
92 | /// <summary> |
||
93 | /// True if the friend can see if I am online |
||
94 | /// </summary> |
||
95 | public bool CanSeeMeOnline |
||
96 | { |
||
97 | get { return m_canSeeMeOnline; } |
||
98 | set |
||
99 | { |
||
100 | m_canSeeMeOnline = value; |
||
101 | |||
102 | // if I can't see them online, then I can't see them on the map |
||
103 | if (!m_canSeeMeOnline) |
||
104 | m_canSeeMeOnMap = false; |
||
105 | } |
||
106 | } |
||
107 | |||
108 | /// <summary> |
||
109 | /// True if the friend can see me on the map |
||
110 | /// </summary> |
||
111 | public bool CanSeeMeOnMap |
||
112 | { |
||
113 | get { return m_canSeeMeOnMap; } |
||
114 | set |
||
115 | { |
||
116 | // if I can't see them online, then I can't see them on the map |
||
117 | if (m_canSeeMeOnline) |
||
118 | m_canSeeMeOnMap = value; |
||
119 | } |
||
120 | } |
||
121 | |||
122 | /// <summary> |
||
123 | /// True if the freind can modify my objects |
||
124 | /// </summary> |
||
125 | public bool CanModifyMyObjects |
||
126 | { |
||
127 | get { return m_canModifyMyObjects; } |
||
128 | set { m_canModifyMyObjects = value; } |
||
129 | } |
||
130 | |||
131 | /// <summary> |
||
132 | /// True if I can see if my friend is online |
||
133 | /// </summary> |
||
134 | public bool CanSeeThemOnline { get { return m_canSeeThemOnline; } } |
||
135 | |||
136 | /// <summary> |
||
137 | /// True if I can see if my friend is on the map |
||
138 | /// </summary> |
||
139 | public bool CanSeeThemOnMap { get { return m_canSeeThemOnMap; } } |
||
140 | |||
141 | /// <summary> |
||
142 | /// True if I can modify my friend's objects |
||
143 | /// </summary> |
||
144 | public bool CanModifyTheirObjects { get { return m_canModifyTheirObjects; } } |
||
145 | |||
146 | /// <summary> |
||
147 | /// My friend's rights represented as bitmapped flags |
||
148 | /// </summary> |
||
149 | public FriendRights TheirFriendRights |
||
150 | { |
||
151 | get |
||
152 | { |
||
153 | FriendRights results = FriendRights.None; |
||
154 | if (m_canSeeMeOnline) |
||
155 | results |= FriendRights.CanSeeOnline; |
||
156 | if (m_canSeeMeOnMap) |
||
157 | results |= FriendRights.CanSeeOnMap; |
||
158 | if (m_canModifyMyObjects) |
||
159 | results |= FriendRights.CanModifyObjects; |
||
160 | |||
161 | return results; |
||
162 | } |
||
163 | set |
||
164 | { |
||
165 | m_canSeeMeOnline = (value & FriendRights.CanSeeOnline) != 0; |
||
166 | m_canSeeMeOnMap = (value & FriendRights.CanSeeOnMap) != 0; |
||
167 | m_canModifyMyObjects = (value & FriendRights.CanModifyObjects) != 0; |
||
168 | } |
||
169 | } |
||
170 | |||
171 | /// <summary> |
||
172 | /// My rights represented as bitmapped flags |
||
173 | /// </summary> |
||
174 | public FriendRights MyFriendRights |
||
175 | { |
||
176 | get |
||
177 | { |
||
178 | FriendRights results = FriendRights.None; |
||
179 | if (m_canSeeThemOnline) |
||
180 | results |= FriendRights.CanSeeOnline; |
||
181 | if (m_canSeeThemOnMap) |
||
182 | results |= FriendRights.CanSeeOnMap; |
||
183 | if (m_canModifyTheirObjects) |
||
184 | results |= FriendRights.CanModifyObjects; |
||
185 | |||
186 | return results; |
||
187 | } |
||
188 | set |
||
189 | { |
||
190 | m_canSeeThemOnline = (value & FriendRights.CanSeeOnline) != 0; |
||
191 | m_canSeeThemOnMap = (value & FriendRights.CanSeeOnMap) != 0; |
||
192 | m_canModifyTheirObjects = (value & FriendRights.CanModifyObjects) != 0; |
||
193 | } |
||
194 | } |
||
195 | |||
196 | #endregion Properties |
||
197 | |||
198 | /// <summary> |
||
199 | /// Used internally when building the initial list of friends at login time |
||
200 | /// </summary> |
||
201 | /// <param name="id">System ID of the avatar being prepesented</param> |
||
202 | /// <param name="theirRights">Rights the friend has to see you online and to modify your objects</param> |
||
203 | /// <param name="myRights">Rights you have to see your friend online and to modify their objects</param> |
||
204 | internal FriendInfo(UUID id, FriendRights theirRights, FriendRights myRights) |
||
205 | { |
||
206 | m_id = id; |
||
207 | m_canSeeMeOnline = (theirRights & FriendRights.CanSeeOnline) != 0; |
||
208 | m_canSeeMeOnMap = (theirRights & FriendRights.CanSeeOnMap) != 0; |
||
209 | m_canModifyMyObjects = (theirRights & FriendRights.CanModifyObjects) != 0; |
||
210 | |||
211 | m_canSeeThemOnline = (myRights & FriendRights.CanSeeOnline) != 0; |
||
212 | m_canSeeThemOnMap = (myRights & FriendRights.CanSeeOnMap) != 0; |
||
213 | m_canModifyTheirObjects = (myRights & FriendRights.CanModifyObjects) != 0; |
||
214 | } |
||
215 | |||
216 | /// <summary> |
||
217 | /// FriendInfo represented as a string |
||
218 | /// </summary> |
||
219 | /// <returns>A string reprentation of both my rights and my friends rights</returns> |
||
220 | public override string ToString() |
||
221 | { |
||
222 | if (!String.IsNullOrEmpty(m_name)) |
||
223 | return String.Format("{0} (Their Rights: {1}, My Rights: {2})", m_name, TheirFriendRights, |
||
224 | MyFriendRights); |
||
225 | else |
||
226 | return String.Format("{0} (Their Rights: {1}, My Rights: {2})", m_id, TheirFriendRights, |
||
227 | MyFriendRights); |
||
228 | } |
||
229 | } |
||
230 | |||
231 | /// <summary> |
||
232 | /// This class is used to add and remove avatars from your friends list and to manage their permission. |
||
233 | /// </summary> |
||
234 | public class FriendsManager |
||
235 | { |
||
236 | #region Delegates |
||
237 | |||
238 | /// <summary>The event subscribers. null if no subcribers</summary> |
||
239 | private EventHandler<FriendInfoEventArgs> m_FriendOnline; |
||
240 | |||
241 | /// <summary>Raises the FriendOnline event</summary> |
||
242 | /// <param name="e">A FriendInfoEventArgs object containing the |
||
243 | /// data returned from the data server</param> |
||
244 | protected virtual void OnFriendOnline(FriendInfoEventArgs e) |
||
245 | { |
||
246 | EventHandler<FriendInfoEventArgs> handler = m_FriendOnline; |
||
247 | if (handler != null) |
||
248 | handler(this, e); |
||
249 | } |
||
250 | |||
251 | /// <summary>Thread sync lock object</summary> |
||
252 | private readonly object m_FriendOnlineLock = new object(); |
||
253 | |||
254 | /// <summary>Raised when the simulator sends notification one of the members in our friends list comes online</summary> |
||
255 | public event EventHandler<FriendInfoEventArgs> FriendOnline |
||
256 | { |
||
257 | add { lock (m_FriendOnlineLock) { m_FriendOnline += value; } } |
||
258 | remove { lock (m_FriendOnlineLock) { m_FriendOnline -= value; } } |
||
259 | } |
||
260 | |||
261 | /// <summary>The event subscribers. null if no subcribers</summary> |
||
262 | private EventHandler<FriendInfoEventArgs> m_FriendOffline; |
||
263 | |||
264 | /// <summary>Raises the FriendOffline event</summary> |
||
265 | /// <param name="e">A FriendInfoEventArgs object containing the |
||
266 | /// data returned from the data server</param> |
||
267 | protected virtual void OnFriendOffline(FriendInfoEventArgs e) |
||
268 | { |
||
269 | EventHandler<FriendInfoEventArgs> handler = m_FriendOffline; |
||
270 | if (handler != null) |
||
271 | handler(this, e); |
||
272 | } |
||
273 | |||
274 | /// <summary>Thread sync lock object</summary> |
||
275 | private readonly object m_FriendOfflineLock = new object(); |
||
276 | |||
277 | /// <summary>Raised when the simulator sends notification one of the members in our friends list goes offline</summary> |
||
278 | public event EventHandler<FriendInfoEventArgs> FriendOffline |
||
279 | { |
||
280 | add { lock (m_FriendOfflineLock) { m_FriendOffline += value; } } |
||
281 | remove { lock (m_FriendOfflineLock) { m_FriendOffline -= value; } } |
||
282 | } |
||
283 | |||
284 | /// <summary>The event subscribers. null if no subcribers</summary> |
||
285 | private EventHandler<FriendInfoEventArgs> m_FriendRights; |
||
286 | |||
287 | /// <summary>Raises the FriendRightsUpdate event</summary> |
||
288 | /// <param name="e">A FriendInfoEventArgs object containing the |
||
289 | /// data returned from the data server</param> |
||
290 | protected virtual void OnFriendRights(FriendInfoEventArgs e) |
||
291 | { |
||
292 | EventHandler<FriendInfoEventArgs> handler = m_FriendRights; |
||
293 | if (handler != null) |
||
294 | handler(this, e); |
||
295 | } |
||
296 | |||
297 | /// <summary>Thread sync lock object</summary> |
||
298 | private readonly object m_FriendRightsLock = new object(); |
||
299 | |||
300 | /// <summary>Raised when the simulator sends notification one of the members in our friends list grants or revokes permissions</summary> |
||
301 | public event EventHandler<FriendInfoEventArgs> FriendRightsUpdate |
||
302 | { |
||
303 | add { lock (m_FriendRightsLock) { m_FriendRights += value; } } |
||
304 | remove { lock (m_FriendRightsLock) { m_FriendRights -= value; } } |
||
305 | } |
||
306 | |||
307 | /// <summary>The event subscribers. null if no subcribers</summary> |
||
308 | private EventHandler<FriendNamesEventArgs> m_FriendNames; |
||
309 | |||
310 | /// <summary>Raises the FriendNames event</summary> |
||
311 | /// <param name="e">A FriendNamesEventArgs object containing the |
||
312 | /// data returned from the data server</param> |
||
313 | protected virtual void OnFriendNames(FriendNamesEventArgs e) |
||
314 | { |
||
315 | EventHandler<FriendNamesEventArgs> handler = m_FriendNames; |
||
316 | if (handler != null) |
||
317 | handler(this, e); |
||
318 | } |
||
319 | |||
320 | /// <summary>Thread sync lock object</summary> |
||
321 | private readonly object m_FriendNamesLock = new object(); |
||
322 | |||
323 | /// <summary>Raised when the simulator sends us the names on our friends list</summary> |
||
324 | public event EventHandler<FriendNamesEventArgs> FriendNames |
||
325 | { |
||
326 | add { lock (m_FriendNamesLock) { m_FriendNames += value; } } |
||
327 | remove { lock (m_FriendNamesLock) { m_FriendNames -= value; } } |
||
328 | } |
||
329 | |||
330 | /// <summary>The event subscribers. null if no subcribers</summary> |
||
331 | private EventHandler<FriendshipOfferedEventArgs> m_FriendshipOffered; |
||
332 | |||
333 | /// <summary>Raises the FriendshipOffered event</summary> |
||
334 | /// <param name="e">A FriendshipOfferedEventArgs object containing the |
||
335 | /// data returned from the data server</param> |
||
336 | protected virtual void OnFriendshipOffered(FriendshipOfferedEventArgs e) |
||
337 | { |
||
338 | EventHandler<FriendshipOfferedEventArgs> handler = m_FriendshipOffered; |
||
339 | if (handler != null) |
||
340 | handler(this, e); |
||
341 | } |
||
342 | |||
343 | /// <summary>Thread sync lock object</summary> |
||
344 | private readonly object m_FriendshipOfferedLock = new object(); |
||
345 | |||
346 | /// <summary>Raised when the simulator sends notification another agent is offering us friendship</summary> |
||
347 | public event EventHandler<FriendshipOfferedEventArgs> FriendshipOffered |
||
348 | { |
||
349 | add { lock (m_FriendshipOfferedLock) { m_FriendshipOffered += value; } } |
||
350 | remove { lock (m_FriendshipOfferedLock) { m_FriendshipOffered -= value; } } |
||
351 | } |
||
352 | |||
353 | /// <summary>The event subscribers. null if no subcribers</summary> |
||
354 | private EventHandler<FriendshipResponseEventArgs> m_FriendshipResponse; |
||
355 | |||
356 | /// <summary>Raises the FriendshipResponse event</summary> |
||
357 | /// <param name="e">A FriendshipResponseEventArgs object containing the |
||
358 | /// data returned from the data server</param> |
||
359 | protected virtual void OnFriendshipResponse(FriendshipResponseEventArgs e) |
||
360 | { |
||
361 | EventHandler<FriendshipResponseEventArgs> handler = m_FriendshipResponse; |
||
362 | if (handler != null) |
||
363 | handler(this, e); |
||
364 | } |
||
365 | |||
366 | /// <summary>Thread sync lock object</summary> |
||
367 | private readonly object m_FriendshipResponseLock = new object(); |
||
368 | |||
369 | /// <summary>Raised when a request we sent to friend another agent is accepted or declined</summary> |
||
370 | public event EventHandler<FriendshipResponseEventArgs> FriendshipResponse |
||
371 | { |
||
372 | add { lock (m_FriendshipResponseLock) { m_FriendshipResponse += value; } } |
||
373 | remove { lock (m_FriendshipResponseLock) { m_FriendshipResponse -= value; } } |
||
374 | } |
||
375 | |||
376 | /// <summary>The event subscribers. null if no subcribers</summary> |
||
377 | private EventHandler<FriendshipTerminatedEventArgs> m_FriendshipTerminated; |
||
378 | |||
379 | /// <summary>Raises the FriendshipTerminated event</summary> |
||
380 | /// <param name="e">A FriendshipTerminatedEventArgs object containing the |
||
381 | /// data returned from the data server</param> |
||
382 | protected virtual void OnFriendshipTerminated(FriendshipTerminatedEventArgs e) |
||
383 | { |
||
384 | EventHandler<FriendshipTerminatedEventArgs> handler = m_FriendshipTerminated; |
||
385 | if (handler != null) |
||
386 | handler(this, e); |
||
387 | } |
||
388 | |||
389 | /// <summary>Thread sync lock object</summary> |
||
390 | private readonly object m_FriendshipTerminatedLock = new object(); |
||
391 | |||
392 | /// <summary>Raised when the simulator sends notification one of the members in our friends list has terminated |
||
393 | /// our friendship</summary> |
||
394 | public event EventHandler<FriendshipTerminatedEventArgs> FriendshipTerminated |
||
395 | { |
||
396 | add { lock (m_FriendshipTerminatedLock) { m_FriendshipTerminated += value; } } |
||
397 | remove { lock (m_FriendshipTerminatedLock) { m_FriendshipTerminated -= value; } } |
||
398 | } |
||
399 | |||
400 | /// <summary>The event subscribers. null if no subcribers</summary> |
||
401 | private EventHandler<FriendFoundReplyEventArgs> m_FriendFound; |
||
402 | |||
403 | /// <summary>Raises the FriendFoundReply event</summary> |
||
404 | /// <param name="e">A FriendFoundReplyEventArgs object containing the |
||
405 | /// data returned from the data server</param> |
||
406 | protected virtual void OnFriendFoundReply(FriendFoundReplyEventArgs e) |
||
407 | { |
||
408 | EventHandler<FriendFoundReplyEventArgs> handler = m_FriendFound; |
||
409 | if (handler != null) |
||
410 | handler(this, e); |
||
411 | } |
||
412 | |||
413 | /// <summary>Thread sync lock object</summary> |
||
414 | private readonly object m_FriendFoundLock = new object(); |
||
415 | |||
416 | /// <summary>Raised when the simulator sends the location of a friend we have |
||
417 | /// requested map location info for</summary> |
||
418 | public event EventHandler<FriendFoundReplyEventArgs> FriendFoundReply |
||
419 | { |
||
420 | add { lock (m_FriendFoundLock) { m_FriendFound += value; } } |
||
421 | remove { lock (m_FriendFoundLock) { m_FriendFound -= value; } } |
||
422 | } |
||
423 | |||
424 | #endregion Delegates |
||
425 | |||
426 | #region Events |
||
427 | |||
428 | #endregion Events |
||
429 | |||
430 | private GridClient Client; |
||
431 | /// <summary> |
||
432 | /// A dictionary of key/value pairs containing known friends of this avatar. |
||
433 | /// |
||
434 | /// The Key is the <seealso cref="UUID"/> of the friend, the value is a <seealso cref="FriendInfo"/> |
||
435 | /// object that contains detailed information including permissions you have and have given to the friend |
||
436 | /// </summary> |
||
437 | public InternalDictionary<UUID, FriendInfo> FriendList = new InternalDictionary<UUID, FriendInfo>(); |
||
438 | |||
439 | /// <summary> |
||
440 | /// A Dictionary of key/value pairs containing current pending frienship offers. |
||
441 | /// |
||
442 | /// The key is the <seealso cref="UUID"/> of the avatar making the request, |
||
443 | /// the value is the <seealso cref="UUID"/> of the request which is used to accept |
||
444 | /// or decline the friendship offer |
||
445 | /// </summary> |
||
446 | public InternalDictionary<UUID, UUID> FriendRequests = new InternalDictionary<UUID, UUID>(); |
||
447 | |||
448 | /// <summary> |
||
449 | /// Internal constructor |
||
450 | /// </summary> |
||
451 | /// <param name="client">A reference to the GridClient Object</param> |
||
452 | internal FriendsManager(GridClient client) |
||
453 | { |
||
454 | Client = client; |
||
455 | |||
456 | Client.Network.LoginProgress += Network_OnConnect; |
||
457 | Client.Avatars.UUIDNameReply += new EventHandler<UUIDNameReplyEventArgs>(Avatars_OnAvatarNames); |
||
458 | Client.Self.IM += Self_IM; |
||
459 | |||
460 | Client.Network.RegisterCallback(PacketType.OnlineNotification, OnlineNotificationHandler); |
||
461 | Client.Network.RegisterCallback(PacketType.OfflineNotification, OfflineNotificationHandler); |
||
462 | Client.Network.RegisterCallback(PacketType.ChangeUserRights, ChangeUserRightsHandler); |
||
463 | Client.Network.RegisterCallback(PacketType.TerminateFriendship, TerminateFriendshipHandler); |
||
464 | Client.Network.RegisterCallback(PacketType.FindAgent, OnFindAgentReplyHandler); |
||
465 | |||
466 | Client.Network.RegisterLoginResponseCallback(new NetworkManager.LoginResponseCallback(Network_OnLoginResponse), |
||
467 | new string[] { "buddy-list" }); |
||
468 | } |
||
469 | |||
470 | #region Public Methods |
||
471 | |||
472 | /// <summary> |
||
473 | /// Accept a friendship request |
||
474 | /// </summary> |
||
475 | /// <param name="fromAgentID">agentID of avatatar to form friendship with</param> |
||
476 | /// <param name="imSessionID">imSessionID of the friendship request message</param> |
||
477 | public void AcceptFriendship(UUID fromAgentID, UUID imSessionID) |
||
478 | { |
||
479 | UUID callingCardFolder = Client.Inventory.FindFolderForType(AssetType.CallingCard); |
||
480 | |||
481 | AcceptFriendshipPacket request = new AcceptFriendshipPacket(); |
||
482 | request.AgentData.AgentID = Client.Self.AgentID; |
||
483 | request.AgentData.SessionID = Client.Self.SessionID; |
||
484 | request.TransactionBlock.TransactionID = imSessionID; |
||
485 | request.FolderData = new AcceptFriendshipPacket.FolderDataBlock[1]; |
||
486 | request.FolderData[0] = new AcceptFriendshipPacket.FolderDataBlock(); |
||
487 | request.FolderData[0].FolderID = callingCardFolder; |
||
488 | |||
489 | Client.Network.SendPacket(request); |
||
490 | |||
491 | FriendInfo friend = new FriendInfo(fromAgentID, FriendRights.CanSeeOnline, |
||
492 | FriendRights.CanSeeOnline); |
||
493 | |||
494 | if (!FriendList.ContainsKey(fromAgentID)) |
||
495 | FriendList.Add(friend.UUID, friend); |
||
496 | |||
497 | if (FriendRequests.ContainsKey(fromAgentID)) |
||
498 | FriendRequests.Remove(fromAgentID); |
||
499 | |||
500 | Client.Avatars.RequestAvatarName(fromAgentID); |
||
501 | } |
||
502 | |||
503 | /// <summary> |
||
504 | /// Decline a friendship request |
||
505 | /// </summary> |
||
506 | /// <param name="fromAgentID"><seealso cref="UUID"/> of friend</param> |
||
507 | /// <param name="imSessionID">imSessionID of the friendship request message</param> |
||
508 | public void DeclineFriendship(UUID fromAgentID, UUID imSessionID) |
||
509 | { |
||
510 | DeclineFriendshipPacket request = new DeclineFriendshipPacket(); |
||
511 | request.AgentData.AgentID = Client.Self.AgentID; |
||
512 | request.AgentData.SessionID = Client.Self.SessionID; |
||
513 | request.TransactionBlock.TransactionID = imSessionID; |
||
514 | Client.Network.SendPacket(request); |
||
515 | |||
516 | if (FriendRequests.ContainsKey(fromAgentID)) |
||
517 | FriendRequests.Remove(fromAgentID); |
||
518 | } |
||
519 | |||
520 | /// <summary> |
||
521 | /// Overload: Offer friendship to an avatar. |
||
522 | /// </summary> |
||
523 | /// <param name="agentID">System ID of the avatar you are offering friendship to</param> |
||
524 | public void OfferFriendship(UUID agentID) |
||
525 | { |
||
526 | OfferFriendship(agentID, "Do ya wanna be my buddy?"); |
||
527 | } |
||
528 | |||
529 | /// <summary> |
||
530 | /// Offer friendship to an avatar. |
||
531 | /// </summary> |
||
532 | /// <param name="agentID">System ID of the avatar you are offering friendship to</param> |
||
533 | /// <param name="message">A message to send with the request</param> |
||
534 | public void OfferFriendship(UUID agentID, string message) |
||
535 | { |
||
536 | Client.Self.InstantMessage(Client.Self.Name, |
||
537 | agentID, |
||
538 | message, |
||
539 | UUID.Random(), |
||
540 | InstantMessageDialog.FriendshipOffered, |
||
541 | InstantMessageOnline.Offline, |
||
542 | Client.Self.SimPosition, |
||
543 | Client.Network.CurrentSim.ID, |
||
544 | null); |
||
545 | } |
||
546 | |||
547 | |||
548 | /// <summary> |
||
549 | /// Terminate a friendship with an avatar |
||
550 | /// </summary> |
||
551 | /// <param name="agentID">System ID of the avatar you are terminating the friendship with</param> |
||
552 | public void TerminateFriendship(UUID agentID) |
||
553 | { |
||
554 | if (FriendList.ContainsKey(agentID)) |
||
555 | { |
||
556 | TerminateFriendshipPacket request = new TerminateFriendshipPacket(); |
||
557 | request.AgentData.AgentID = Client.Self.AgentID; |
||
558 | request.AgentData.SessionID = Client.Self.SessionID; |
||
559 | request.ExBlock.OtherID = agentID; |
||
560 | |||
561 | Client.Network.SendPacket(request); |
||
562 | |||
563 | if (FriendList.ContainsKey(agentID)) |
||
564 | FriendList.Remove(agentID); |
||
565 | } |
||
566 | } |
||
567 | /// <summary>Process an incoming packet and raise the appropriate events</summary> |
||
568 | /// <param name="sender">The sender</param> |
||
569 | /// <param name="e">The EventArgs object containing the packet data</param> |
||
570 | private void TerminateFriendshipHandler(object sender, PacketReceivedEventArgs e) |
||
571 | { |
||
572 | Packet packet = e.Packet; |
||
573 | TerminateFriendshipPacket itsOver = (TerminateFriendshipPacket)packet; |
||
574 | string name = String.Empty; |
||
575 | |||
576 | if (FriendList.ContainsKey(itsOver.ExBlock.OtherID)) |
||
577 | { |
||
578 | name = FriendList[itsOver.ExBlock.OtherID].Name; |
||
579 | FriendList.Remove(itsOver.ExBlock.OtherID); |
||
580 | } |
||
581 | |||
582 | if (m_FriendshipTerminated != null) |
||
583 | { |
||
584 | OnFriendshipTerminated(new FriendshipTerminatedEventArgs(itsOver.ExBlock.OtherID, name)); |
||
585 | } |
||
586 | } |
||
587 | |||
588 | /// <summary> |
||
589 | /// Change the rights of a friend avatar. |
||
590 | /// </summary> |
||
591 | /// <param name="friendID">the <seealso cref="UUID"/> of the friend</param> |
||
592 | /// <param name="rights">the new rights to give the friend</param> |
||
593 | /// <remarks>This method will implicitly set the rights to those passed in the rights parameter.</remarks> |
||
594 | public void GrantRights(UUID friendID, FriendRights rights) |
||
595 | { |
||
596 | GrantUserRightsPacket request = new GrantUserRightsPacket(); |
||
597 | request.AgentData.AgentID = Client.Self.AgentID; |
||
598 | request.AgentData.SessionID = Client.Self.SessionID; |
||
599 | request.Rights = new GrantUserRightsPacket.RightsBlock[1]; |
||
600 | request.Rights[0] = new GrantUserRightsPacket.RightsBlock(); |
||
601 | request.Rights[0].AgentRelated = friendID; |
||
602 | request.Rights[0].RelatedRights = (int)rights; |
||
603 | |||
604 | Client.Network.SendPacket(request); |
||
605 | } |
||
606 | |||
607 | /// <summary> |
||
608 | /// Use to map a friends location on the grid. |
||
609 | /// </summary> |
||
610 | /// <param name="friendID">Friends UUID to find</param> |
||
611 | /// <remarks><seealso cref="E:OnFriendFound"/></remarks> |
||
612 | public void MapFriend(UUID friendID) |
||
613 | { |
||
614 | FindAgentPacket stalk = new FindAgentPacket(); |
||
615 | stalk.AgentBlock.Hunter = Client.Self.AgentID; |
||
616 | stalk.AgentBlock.Prey = friendID; |
||
617 | stalk.AgentBlock.SpaceIP = 0; // Will be filled in by the simulator |
||
618 | stalk.LocationBlock = new FindAgentPacket.LocationBlockBlock[1]; |
||
619 | stalk.LocationBlock[0] = new FindAgentPacket.LocationBlockBlock(); |
||
620 | stalk.LocationBlock[0].GlobalX = 0.0; // Filled in by the simulator |
||
621 | stalk.LocationBlock[0].GlobalY = 0.0; |
||
622 | |||
623 | Client.Network.SendPacket(stalk); |
||
624 | } |
||
625 | |||
626 | /// <summary> |
||
627 | /// Use to track a friends movement on the grid |
||
628 | /// </summary> |
||
629 | /// <param name="friendID">Friends Key</param> |
||
630 | public void TrackFriend(UUID friendID) |
||
631 | { |
||
632 | TrackAgentPacket stalk = new TrackAgentPacket(); |
||
633 | stalk.AgentData.AgentID = Client.Self.AgentID; |
||
634 | stalk.AgentData.SessionID = Client.Self.SessionID; |
||
635 | stalk.TargetData.PreyID = friendID; |
||
636 | |||
637 | Client.Network.SendPacket(stalk); |
||
638 | } |
||
639 | |||
640 | /// <summary> |
||
641 | /// Ask for a notification of friend's online status |
||
642 | /// </summary> |
||
643 | /// <param name="friendID">Friend's UUID</param> |
||
644 | public void RequestOnlineNotification(UUID friendID) |
||
645 | { |
||
646 | GenericMessagePacket gmp = new GenericMessagePacket(); |
||
647 | |||
648 | gmp.AgentData.AgentID = Client.Self.AgentID; |
||
649 | gmp.AgentData.SessionID = Client.Self.SessionID; |
||
650 | gmp.AgentData.TransactionID = UUID.Zero; |
||
651 | |||
652 | gmp.MethodData.Method = Utils.StringToBytes("requestonlinenotification"); |
||
653 | gmp.MethodData.Invoice = UUID.Zero; |
||
654 | gmp.ParamList = new GenericMessagePacket.ParamListBlock[1]; |
||
655 | gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock(); |
||
656 | gmp.ParamList[0].Parameter = Utils.StringToBytes(friendID.ToString()); |
||
657 | |||
658 | Client.Network.SendPacket(gmp); |
||
659 | } |
||
660 | |||
661 | #endregion |
||
662 | |||
663 | #region Internal events |
||
664 | |||
665 | private void Network_OnConnect(object sender, LoginProgressEventArgs e) |
||
666 | { |
||
667 | if (e.Status != LoginStatus.Success) |
||
668 | { |
||
669 | return; |
||
670 | } |
||
671 | |||
672 | List<UUID> names = new List<UUID>(); |
||
673 | |||
674 | if (FriendList.Count > 0) |
||
675 | { |
||
676 | FriendList.ForEach( |
||
677 | delegate(KeyValuePair<UUID, FriendInfo> kvp) |
||
678 | { |
||
679 | if (String.IsNullOrEmpty(kvp.Value.Name)) |
||
680 | names.Add(kvp.Key); |
||
681 | } |
||
682 | ); |
||
683 | |||
684 | Client.Avatars.RequestAvatarNames(names); |
||
685 | } |
||
686 | } |
||
687 | |||
688 | |||
689 | /// <summary> |
||
690 | /// This handles the asynchronous response of a RequestAvatarNames call. |
||
691 | /// </summary> |
||
692 | /// <param name="sender"></param> |
||
693 | /// <param name="e">names cooresponding to the the list of IDs sent the the RequestAvatarNames call.</param> |
||
694 | private void Avatars_OnAvatarNames(object sender, UUIDNameReplyEventArgs e) |
||
695 | { |
||
696 | Dictionary<UUID, string> newNames = new Dictionary<UUID, string>(); |
||
697 | |||
698 | foreach (KeyValuePair<UUID, string> kvp in e.Names) |
||
699 | { |
||
700 | FriendInfo friend; |
||
701 | lock (FriendList.Dictionary) |
||
702 | { |
||
703 | if (FriendList.TryGetValue(kvp.Key, out friend)) |
||
704 | { |
||
705 | if (friend.Name == null) |
||
706 | newNames.Add(kvp.Key, e.Names[kvp.Key]); |
||
707 | |||
708 | friend.Name = e.Names[kvp.Key]; |
||
709 | FriendList[kvp.Key] = friend; |
||
710 | } |
||
711 | } |
||
712 | } |
||
713 | |||
714 | if (newNames.Count > 0 && m_FriendNames != null) |
||
715 | { |
||
716 | OnFriendNames(new FriendNamesEventArgs(newNames)); |
||
717 | } |
||
718 | } |
||
719 | #endregion |
||
720 | |||
721 | #region Packet Handlers |
||
722 | |||
723 | /// <summary>Process an incoming packet and raise the appropriate events</summary> |
||
724 | /// <param name="sender">The sender</param> |
||
725 | /// <param name="e">The EventArgs object containing the packet data</param> |
||
726 | protected void OnlineNotificationHandler(object sender, PacketReceivedEventArgs e) |
||
727 | { |
||
728 | Packet packet = e.Packet; |
||
729 | if (packet.Type == PacketType.OnlineNotification) |
||
730 | { |
||
731 | OnlineNotificationPacket notification = ((OnlineNotificationPacket)packet); |
||
732 | |||
733 | foreach (OnlineNotificationPacket.AgentBlockBlock block in notification.AgentBlock) |
||
734 | { |
||
735 | FriendInfo friend; |
||
736 | lock (FriendList.Dictionary) |
||
737 | { |
||
738 | if (!FriendList.ContainsKey(block.AgentID)) |
||
739 | { |
||
740 | friend = new FriendInfo(block.AgentID, FriendRights.CanSeeOnline, |
||
741 | FriendRights.CanSeeOnline); |
||
742 | FriendList.Add(block.AgentID, friend); |
||
743 | } |
||
744 | else |
||
745 | { |
||
746 | friend = FriendList[block.AgentID]; |
||
747 | } |
||
748 | } |
||
749 | |||
750 | bool doNotify = !friend.IsOnline; |
||
751 | friend.IsOnline = true; |
||
752 | |||
753 | if (m_FriendOnline != null && doNotify) |
||
754 | { |
||
755 | OnFriendOnline(new FriendInfoEventArgs(friend)); |
||
756 | } |
||
757 | } |
||
758 | } |
||
759 | } |
||
760 | |||
761 | /// <summary>Process an incoming packet and raise the appropriate events</summary> |
||
762 | /// <param name="sender">The sender</param> |
||
763 | /// <param name="e">The EventArgs object containing the packet data</param> |
||
764 | protected void OfflineNotificationHandler(object sender, PacketReceivedEventArgs e) |
||
765 | { |
||
766 | Packet packet = e.Packet; |
||
767 | if (packet.Type == PacketType.OfflineNotification) |
||
768 | { |
||
769 | OfflineNotificationPacket notification = (OfflineNotificationPacket)packet; |
||
770 | |||
771 | foreach (OfflineNotificationPacket.AgentBlockBlock block in notification.AgentBlock) |
||
772 | { |
||
773 | FriendInfo friend = new FriendInfo(block.AgentID, FriendRights.CanSeeOnline, FriendRights.CanSeeOnline); |
||
774 | |||
775 | lock (FriendList.Dictionary) |
||
776 | { |
||
777 | if (!FriendList.Dictionary.ContainsKey(block.AgentID)) |
||
778 | FriendList.Dictionary[block.AgentID] = friend; |
||
779 | |||
780 | friend = FriendList.Dictionary[block.AgentID]; |
||
781 | } |
||
782 | |||
783 | friend.IsOnline = false; |
||
784 | |||
785 | if (m_FriendOffline != null) |
||
786 | { |
||
787 | OnFriendOffline(new FriendInfoEventArgs(friend)); |
||
788 | } |
||
789 | } |
||
790 | } |
||
791 | } |
||
792 | |||
793 | |||
794 | /// <summary>Process an incoming packet and raise the appropriate events</summary> |
||
795 | /// <param name="sender">The sender</param> |
||
796 | /// <param name="e">The EventArgs object containing the packet data</param> |
||
797 | private void ChangeUserRightsHandler(object sender, PacketReceivedEventArgs e) |
||
798 | { |
||
799 | Packet packet = e.Packet; |
||
800 | if (packet.Type == PacketType.ChangeUserRights) |
||
801 | { |
||
802 | FriendInfo friend; |
||
803 | ChangeUserRightsPacket rights = (ChangeUserRightsPacket)packet; |
||
804 | |||
805 | foreach (ChangeUserRightsPacket.RightsBlock block in rights.Rights) |
||
806 | { |
||
807 | FriendRights newRights = (FriendRights)block.RelatedRights; |
||
808 | if (FriendList.TryGetValue(block.AgentRelated, out friend)) |
||
809 | { |
||
810 | friend.TheirFriendRights = newRights; |
||
811 | if (m_FriendRights != null) |
||
812 | { |
||
813 | OnFriendRights(new FriendInfoEventArgs(friend)); |
||
814 | } |
||
815 | } |
||
816 | else if (block.AgentRelated == Client.Self.AgentID) |
||
817 | { |
||
818 | if (FriendList.TryGetValue(rights.AgentData.AgentID, out friend)) |
||
819 | { |
||
820 | friend.MyFriendRights = newRights; |
||
821 | if (m_FriendRights != null) |
||
822 | { |
||
823 | OnFriendRights(new FriendInfoEventArgs(friend)); |
||
824 | } |
||
825 | } |
||
826 | } |
||
827 | } |
||
828 | } |
||
829 | } |
||
830 | |||
831 | /// <summary>Process an incoming packet and raise the appropriate events</summary> |
||
832 | /// <param name="sender">The sender</param> |
||
833 | /// <param name="e">The EventArgs object containing the packet data</param> |
||
834 | public void OnFindAgentReplyHandler(object sender, PacketReceivedEventArgs e) |
||
835 | { |
||
836 | if (m_FriendFound != null) |
||
837 | { |
||
838 | Packet packet = e.Packet; |
||
839 | FindAgentPacket reply = (FindAgentPacket)packet; |
||
840 | |||
841 | float x, y; |
||
842 | UUID prey = reply.AgentBlock.Prey; |
||
843 | ulong regionHandle = Helpers.GlobalPosToRegionHandle((float)reply.LocationBlock[0].GlobalX, |
||
844 | (float)reply.LocationBlock[0].GlobalY, out x, out y); |
||
845 | Vector3 xyz = new Vector3(x, y, 0f); |
||
846 | |||
847 | OnFriendFoundReply(new FriendFoundReplyEventArgs(prey, regionHandle, xyz)); |
||
848 | } |
||
849 | } |
||
850 | |||
851 | #endregion |
||
852 | |||
853 | private void Self_IM(object sender, InstantMessageEventArgs e) |
||
854 | { |
||
855 | if (e.IM.Dialog == InstantMessageDialog.FriendshipOffered) |
||
856 | { |
||
857 | if (m_FriendshipOffered != null) |
||
858 | { |
||
859 | if (FriendRequests.ContainsKey(e.IM.FromAgentID)) |
||
860 | FriendRequests[e.IM.FromAgentID] = e.IM.IMSessionID; |
||
861 | else |
||
862 | FriendRequests.Add(e.IM.FromAgentID, e.IM.IMSessionID); |
||
863 | |||
864 | OnFriendshipOffered(new FriendshipOfferedEventArgs(e.IM.FromAgentID, e.IM.FromAgentName, e.IM.IMSessionID)); |
||
865 | } |
||
866 | } |
||
867 | else if (e.IM.Dialog == InstantMessageDialog.FriendshipAccepted) |
||
868 | { |
||
869 | FriendInfo friend = new FriendInfo(e.IM.FromAgentID, FriendRights.CanSeeOnline, |
||
870 | FriendRights.CanSeeOnline); |
||
871 | friend.Name = e.IM.FromAgentName; |
||
872 | lock (FriendList.Dictionary) FriendList[friend.UUID] = friend; |
||
873 | |||
874 | if (m_FriendshipResponse != null) |
||
875 | { |
||
876 | OnFriendshipResponse(new FriendshipResponseEventArgs(e.IM.FromAgentID, e.IM.FromAgentName, true)); |
||
877 | } |
||
878 | RequestOnlineNotification(e.IM.FromAgentID); |
||
879 | } |
||
880 | else if (e.IM.Dialog == InstantMessageDialog.FriendshipDeclined) |
||
881 | { |
||
882 | if (m_FriendshipResponse != null) |
||
883 | { |
||
884 | OnFriendshipResponse(new FriendshipResponseEventArgs(e.IM.FromAgentID, e.IM.FromAgentName, false)); |
||
885 | } |
||
886 | } |
||
887 | } |
||
888 | |||
889 | /// <summary> |
||
890 | /// Populate FriendList <seealso cref="InternalDictionary"/> with data from the login reply |
||
891 | /// </summary> |
||
892 | /// <param name="loginSuccess">true if login was successful</param> |
||
893 | /// <param name="redirect">true if login request is requiring a redirect</param> |
||
894 | /// <param name="message">A string containing the response to the login request</param> |
||
895 | /// <param name="reason">A string containing the reason for the request</param> |
||
896 | /// <param name="replyData">A <seealso cref="LoginResponseData"/> object containing the decoded |
||
897 | /// reply from the login server</param> |
||
898 | private void Network_OnLoginResponse(bool loginSuccess, bool redirect, string message, string reason, |
||
899 | LoginResponseData replyData) |
||
900 | { |
||
901 | int uuidLength = UUID.Zero.ToString().Length; |
||
902 | |||
903 | if (loginSuccess && replyData.BuddyList != null) |
||
904 | { |
||
905 | foreach (BuddyListEntry buddy in replyData.BuddyList) |
||
906 | { |
||
907 | UUID bubid; |
||
908 | string id = buddy.buddy_id.Length > uuidLength ? buddy.buddy_id.Substring(0, uuidLength) : buddy.buddy_id; |
||
909 | if (UUID.TryParse(id, out bubid)) |
||
910 | { |
||
911 | lock (FriendList.Dictionary) |
||
912 | { |
||
913 | if (!FriendList.ContainsKey(bubid)) |
||
914 | { |
||
915 | FriendList[bubid] = new FriendInfo(bubid, |
||
916 | (FriendRights)buddy.buddy_rights_given, |
||
917 | (FriendRights)buddy.buddy_rights_has); |
||
918 | } |
||
919 | } |
||
920 | } |
||
921 | } |
||
922 | } |
||
923 | } |
||
924 | } |
||
925 | #region EventArgs |
||
926 | |||
927 | /// <summary>Contains information on a member of our friends list</summary> |
||
928 | public class FriendInfoEventArgs : EventArgs |
||
929 | { |
||
930 | private readonly FriendInfo m_Friend; |
||
931 | |||
932 | /// <summary>Get the FriendInfo</summary> |
||
933 | public FriendInfo Friend { get { return m_Friend; } } |
||
934 | |||
935 | /// <summary> |
||
936 | /// Construct a new instance of the FriendInfoEventArgs class |
||
937 | /// </summary> |
||
938 | /// <param name="friend">The FriendInfo</param> |
||
939 | public FriendInfoEventArgs(FriendInfo friend) |
||
940 | { |
||
941 | this.m_Friend = friend; |
||
942 | } |
||
943 | } |
||
944 | |||
945 | /// <summary>Contains Friend Names</summary> |
||
946 | public class FriendNamesEventArgs : EventArgs |
||
947 | { |
||
948 | private readonly Dictionary<UUID, string> m_Names; |
||
949 | |||
950 | /// <summary>A dictionary where the Key is the ID of the Agent, |
||
951 | /// and the Value is a string containing their name</summary> |
||
952 | public Dictionary<UUID, string> Names { get { return m_Names; } } |
||
953 | |||
954 | /// <summary> |
||
955 | /// Construct a new instance of the FriendNamesEventArgs class |
||
956 | /// </summary> |
||
957 | /// <param name="names">A dictionary where the Key is the ID of the Agent, |
||
958 | /// and the Value is a string containing their name</param> |
||
959 | public FriendNamesEventArgs(Dictionary<UUID, string> names) |
||
960 | { |
||
961 | this.m_Names = names; |
||
962 | } |
||
963 | } |
||
964 | |||
965 | /// <summary>Sent when another agent requests a friendship with our agent</summary> |
||
966 | public class FriendshipOfferedEventArgs : EventArgs |
||
967 | { |
||
968 | private readonly UUID m_AgentID; |
||
969 | private readonly string m_AgentName; |
||
970 | private readonly UUID m_SessionID; |
||
971 | |||
972 | /// <summary>Get the ID of the agent requesting friendship</summary> |
||
973 | public UUID AgentID { get { return m_AgentID; } } |
||
974 | /// <summary>Get the name of the agent requesting friendship</summary> |
||
975 | public string AgentName { get { return m_AgentName; } } |
||
976 | /// <summary>Get the ID of the session, used in accepting or declining the |
||
977 | /// friendship offer</summary> |
||
978 | public UUID SessionID { get { return m_SessionID; } } |
||
979 | |||
980 | /// <summary> |
||
981 | /// Construct a new instance of the FriendshipOfferedEventArgs class |
||
982 | /// </summary> |
||
983 | /// <param name="agentID">The ID of the agent requesting friendship</param> |
||
984 | /// <param name="agentName">The name of the agent requesting friendship</param> |
||
985 | /// <param name="imSessionID">The ID of the session, used in accepting or declining the |
||
986 | /// friendship offer</param> |
||
987 | public FriendshipOfferedEventArgs(UUID agentID, string agentName, UUID imSessionID) |
||
988 | { |
||
989 | this.m_AgentID = agentID; |
||
990 | this.m_AgentName = agentName; |
||
991 | this.m_SessionID = imSessionID; |
||
992 | } |
||
993 | } |
||
994 | |||
995 | /// <summary>A response containing the results of our request to form a friendship with another agent</summary> |
||
996 | public class FriendshipResponseEventArgs : EventArgs |
||
997 | { |
||
998 | private readonly UUID m_AgentID; |
||
999 | private readonly string m_AgentName; |
||
1000 | private readonly bool m_Accepted; |
||
1001 | |||
1002 | /// <summary>Get the ID of the agent we requested a friendship with</summary> |
||
1003 | public UUID AgentID { get { return m_AgentID; } } |
||
1004 | /// <summary>Get the name of the agent we requested a friendship with</summary> |
||
1005 | public string AgentName { get { return m_AgentName; } } |
||
1006 | /// <summary>true if the agent accepted our friendship offer</summary> |
||
1007 | public bool Accepted { get { return m_Accepted; } } |
||
1008 | |||
1009 | /// <summary> |
||
1010 | /// Construct a new instance of the FriendShipResponseEventArgs class |
||
1011 | /// </summary> |
||
1012 | /// <param name="agentID">The ID of the agent we requested a friendship with</param> |
||
1013 | /// <param name="agentName">The name of the agent we requested a friendship with</param> |
||
1014 | /// <param name="accepted">true if the agent accepted our friendship offer</param> |
||
1015 | public FriendshipResponseEventArgs(UUID agentID, string agentName, bool accepted) |
||
1016 | { |
||
1017 | this.m_AgentID = agentID; |
||
1018 | this.m_AgentName = agentName; |
||
1019 | this.m_Accepted = accepted; |
||
1020 | } |
||
1021 | } |
||
1022 | |||
1023 | /// <summary>Contains data sent when a friend terminates a friendship with us</summary> |
||
1024 | public class FriendshipTerminatedEventArgs : EventArgs |
||
1025 | { |
||
1026 | private readonly UUID m_AgentID; |
||
1027 | private readonly string m_AgentName; |
||
1028 | |||
1029 | /// <summary>Get the ID of the agent that terminated the friendship with us</summary> |
||
1030 | public UUID AgentID { get { return m_AgentID; } } |
||
1031 | /// <summary>Get the name of the agent that terminated the friendship with us</summary> |
||
1032 | public string AgentName { get { return m_AgentName; } } |
||
1033 | |||
1034 | /// <summary> |
||
1035 | /// Construct a new instance of the FrindshipTerminatedEventArgs class |
||
1036 | /// </summary> |
||
1037 | /// <param name="agentID">The ID of the friend who terminated the friendship with us</param> |
||
1038 | /// <param name="agentName">The name of the friend who terminated the friendship with us</param> |
||
1039 | public FriendshipTerminatedEventArgs(UUID agentID, string agentName) |
||
1040 | { |
||
1041 | this.m_AgentID = agentID; |
||
1042 | this.m_AgentName = agentName; |
||
1043 | } |
||
1044 | } |
||
1045 | |||
1046 | /// <summary> |
||
1047 | /// Data sent in response to a <see cref="FindFriend"/> request which contains the information to allow us to map the friends location |
||
1048 | /// </summary> |
||
1049 | public class FriendFoundReplyEventArgs : EventArgs |
||
1050 | { |
||
1051 | private readonly UUID m_AgentID; |
||
1052 | private readonly ulong m_RegionHandle; |
||
1053 | private readonly Vector3 m_Location; |
||
1054 | |||
1055 | /// <summary>Get the ID of the agent we have received location information for</summary> |
||
1056 | public UUID AgentID { get { return m_AgentID; } } |
||
1057 | /// <summary>Get the region handle where our mapped friend is located</summary> |
||
1058 | public ulong RegionHandle { get { return m_RegionHandle; } } |
||
1059 | /// <summary>Get the simulator local position where our friend is located</summary> |
||
1060 | public Vector3 Location { get { return m_Location; } } |
||
1061 | |||
1062 | /// <summary> |
||
1063 | /// Construct a new instance of the FriendFoundReplyEventArgs class |
||
1064 | /// </summary> |
||
1065 | /// <param name="agentID">The ID of the agent we have requested location information for</param> |
||
1066 | /// <param name="regionHandle">The region handle where our friend is located</param> |
||
1067 | /// <param name="location">The simulator local position our friend is located</param> |
||
1068 | public FriendFoundReplyEventArgs(UUID agentID, ulong regionHandle, Vector3 location) |
||
1069 | { |
||
1070 | this.m_AgentID = agentID; |
||
1071 | this.m_RegionHandle = regionHandle; |
||
1072 | this.m_Location = location; |
||
1073 | } |
||
1074 | } |
||
1075 | #endregion |
||
1076 | } |