aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs628
1 files changed, 628 insertions, 0 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
new file mode 100644
index 0000000..b9d6719
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
@@ -0,0 +1,628 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
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
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Reflection;
32using log4net;
33using Nini.Config;
34using Nwc.XmlRpc;
35using Mono.Addins;
36using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces;
41using OpenSim.Services.Connectors.Hypergrid;
42using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
43using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
44using GridRegion = OpenSim.Services.Interfaces.GridRegion;
45
46namespace OpenSim.Region.CoreModules.Avatar.Friends
47{
48 public class HGFriendsModule : FriendsModule, ISharedRegionModule, IFriendsModule, IFriendsSimConnector
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
52 #region ISharedRegionModule
53 public override string Name
54 {
55 get { return "HGFriendsModule"; }
56 }
57
58 public override void AddRegion(Scene scene)
59 {
60 if (!m_Enabled)
61 return;
62
63 base.AddRegion(scene);
64 scene.RegisterModuleInterface<IFriendsSimConnector>(this);
65 }
66
67 #endregion
68
69 #region IFriendsSimConnector
70
71 /// <summary>
72 /// Notify the user that the friend's status changed
73 /// </summary>
74 /// <param name="userID">user to be notified</param>
75 /// <param name="friendID">friend whose status changed</param>
76 /// <param name="online">status</param>
77 /// <returns></returns>
78 public bool StatusNotify(UUID friendID, UUID userID, bool online)
79 {
80 return LocalStatusNotification(friendID, userID, online);
81 }
82
83 #endregion
84
85 protected override bool FetchFriendslist(IClientAPI client)
86 {
87 if (base.FetchFriendslist(client))
88 {
89 UUID agentID = client.AgentId;
90 // we do this only for the root agent
91 if (m_Friends[agentID].Refcount == 1)
92 {
93 // We need to preload the user management cache with the names
94 // of foreign friends, just like we do with SOPs' creators
95 foreach (FriendInfo finfo in m_Friends[agentID].Friends)
96 {
97 if (finfo.TheirFlags != -1)
98 {
99 UUID id;
100 if (!UUID.TryParse(finfo.Friend, out id))
101 {
102 string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
103 if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last, out tmp))
104 {
105 IUserManagement uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
106 uMan.AddUser(id, url + ";" + first + " " + last);
107 }
108 }
109 }
110 }
111 return true;
112 }
113 }
114 return false;
115 }
116
117 public override bool SendFriendsOnlineIfNeeded(IClientAPI client)
118 {
119 if (base.SendFriendsOnlineIfNeeded(client))
120 {
121 AgentCircuitData aCircuit = ((Scene)client.Scene).AuthenticateHandler.GetAgentCircuitData(client.AgentId);
122 if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
123 {
124 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId);
125 if (account == null) // foreign
126 {
127 FriendInfo[] friends = GetFriends(client.AgentId);
128 foreach (FriendInfo f in friends)
129 {
130 client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags);
131 }
132 }
133 }
134 }
135 return false;
136 }
137
138 protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
139 {
140 List<string> fList = new List<string>();
141 foreach (string s in friendList)
142 fList.Add(s.Substring(0, 36));
143
144 PresenceInfo[] presence = PresenceService.GetAgents(fList.ToArray());
145 foreach (PresenceInfo pi in presence)
146 {
147 UUID presenceID;
148 if (UUID.TryParse(pi.UserID, out presenceID))
149 online.Add(presenceID);
150 }
151 }
152
153 //protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
154 //{
155 // // Let's single out the UUIs
156 // List<string> localFriends = new List<string>();
157 // List<string> foreignFriends = new List<string>();
158 // string tmp = string.Empty;
159
160 // foreach (string s in friendList)
161 // {
162 // UUID id;
163 // if (UUID.TryParse(s, out id))
164 // localFriends.Add(s);
165 // else if (Util.ParseUniversalUserIdentifier(s, out id, out tmp, out tmp, out tmp, out tmp))
166 // {
167 // foreignFriends.Add(s);
168 // // add it here too, who knows maybe the foreign friends happens to be on this grid
169 // localFriends.Add(id.ToString());
170 // }
171 // }
172
173 // // OK, see who's present on this grid
174 // List<string> toBeRemoved = new List<string>();
175 // PresenceInfo[] presence = PresenceService.GetAgents(localFriends.ToArray());
176 // foreach (PresenceInfo pi in presence)
177 // {
178 // UUID presenceID;
179 // if (UUID.TryParse(pi.UserID, out presenceID))
180 // {
181 // online.Add(presenceID);
182 // foreach (string s in foreignFriends)
183 // if (s.StartsWith(pi.UserID))
184 // toBeRemoved.Add(s);
185 // }
186 // }
187
188 // foreach (string s in toBeRemoved)
189 // foreignFriends.Remove(s);
190
191 // // OK, let's send this up the stack, and leave a closure here
192 // // collecting online friends in other grids
193 // Util.FireAndForget(delegate { CollectOnlineFriendsElsewhere(userID, foreignFriends); });
194
195 //}
196
197 private void CollectOnlineFriendsElsewhere(UUID userID, List<string> foreignFriends)
198 {
199 // let's divide the friends on a per-domain basis
200 Dictionary<string, List<string>> friendsPerDomain = new Dictionary<string, List<string>>();
201 foreach (string friend in foreignFriends)
202 {
203 UUID friendID;
204 if (!UUID.TryParse(friend, out friendID))
205 {
206 // it's a foreign friend
207 string url = string.Empty, tmp = string.Empty;
208 if (Util.ParseUniversalUserIdentifier(friend, out friendID, out url, out tmp, out tmp, out tmp))
209 {
210 if (!friendsPerDomain.ContainsKey(url))
211 friendsPerDomain[url] = new List<string>();
212 friendsPerDomain[url].Add(friend);
213 }
214 }
215 }
216
217 // Now, call those worlds
218
219 foreach (KeyValuePair<string, List<string>> kvp in friendsPerDomain)
220 {
221 List<string> ids = new List<string>();
222 foreach (string f in kvp.Value)
223 ids.Add(f);
224 UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
225 List<UUID> online = uConn.GetOnlineFriends(userID, ids);
226 // Finally send the notifications to the user
227 // this whole process may take a while, so let's check at every
228 // iteration that the user is still here
229 IClientAPI client = LocateClientObject(userID);
230 if (client != null)
231 client.SendAgentOnline(online.ToArray());
232 else
233 break;
234 }
235
236 }
237
238 protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
239 {
240 // First, let's divide the friends on a per-domain basis
241 Dictionary<string, List<FriendInfo>> friendsPerDomain = new Dictionary<string, List<FriendInfo>>();
242 foreach (FriendInfo friend in friendList)
243 {
244 UUID friendID;
245 if (UUID.TryParse(friend.Friend, out friendID))
246 {
247 if (!friendsPerDomain.ContainsKey("local"))
248 friendsPerDomain["local"] = new List<FriendInfo>();
249 friendsPerDomain["local"].Add(friend);
250 }
251 else
252 {
253 // it's a foreign friend
254 string url = string.Empty, tmp = string.Empty;
255 if (Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out url, out tmp, out tmp, out tmp))
256 {
257 // Let's try our luck in the local sim. Who knows, maybe it's here
258 if (LocalStatusNotification(userID, friendID, online))
259 continue;
260
261 if (!friendsPerDomain.ContainsKey(url))
262 friendsPerDomain[url] = new List<FriendInfo>();
263 friendsPerDomain[url].Add(friend);
264 }
265 }
266 }
267
268 // For the local friends, just call the base method
269 // Let's do this first of all
270 if (friendsPerDomain.ContainsKey("local"))
271 base.StatusNotify(friendsPerDomain["local"], userID, online);
272
273 foreach (KeyValuePair<string, List<FriendInfo>> kvp in friendsPerDomain)
274 {
275 if (kvp.Key != "local")
276 {
277 // For the others, call the user agent service
278 List<string> ids = new List<string>();
279 foreach (FriendInfo f in kvp.Value)
280 ids.Add(f.Friend);
281 UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
282 List<UUID> friendsOnline = uConn.StatusNotification(ids, userID, online);
283 // need to debug this here
284 if (online)
285 {
286 IClientAPI client = LocateClientObject(userID);
287 if (client != null)
288 client.SendAgentOnline(friendsOnline.ToArray());
289 }
290 }
291 }
292 }
293
294 protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
295 {
296 first = "Unknown"; last = "User";
297 if (base.GetAgentInfo(scopeID, fid, out agentID, out first, out last))
298 return true;
299
300 // fid is not a UUID...
301 string url = string.Empty, tmp = string.Empty;
302 if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp))
303 {
304 IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
305 userMan.AddUser(agentID, url + ";" + first + " " + last);
306
307 try // our best
308 {
309 string[] parts = userMan.GetUserName(agentID).Split();
310 first = parts[0];
311 last = parts[1];
312 }
313 catch { }
314 return true;
315 }
316 return false;
317 }
318
319 protected override string GetFriendshipRequesterName(UUID agentID)
320 {
321 // For the time being we assume that HG friendship requests can only happen
322 // when avies are on the same region.
323 IClientAPI client = LocateClientObject(agentID);
324 if (client != null)
325 return client.FirstName + " " + client.LastName;
326 else
327 return base.GetFriendshipRequesterName(agentID);
328 }
329
330 protected override string FriendshipMessage(string friendID)
331 {
332 UUID id;
333 if (UUID.TryParse(friendID, out id))
334 return base.FriendshipMessage(friendID);
335
336 return "Please confirm this friendship you made while you were away.";
337 }
338
339 protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
340 {
341 foreach (FriendInfo fi in friends)
342 {
343 if (fi.Friend.StartsWith(friendID.ToString()))
344 return fi;
345 }
346 return null;
347 }
348
349
350 protected override FriendInfo[] GetFriendsFromService(IClientAPI client)
351 {
352 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId);
353 if (account1 != null)
354 return base.GetFriendsFromService(client);
355
356 FriendInfo[] finfos = new FriendInfo[0];
357 // Foreigner
358 AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
359 if (agentClientCircuit != null)
360 {
361 string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
362
363 finfos = FriendsService.GetFriends(agentUUI);
364 m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI);
365 }
366 return finfos;
367 }
368
369 protected override bool StoreRights(UUID agentID, UUID friendID, int rights)
370 {
371 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
372 UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
373 // Are they both local users?
374 if (account1 != null && account2 != null)
375 {
376 // local grid users
377 return base.StoreRights(agentID, friendID, rights);
378 }
379
380 if (account1 != null) // agent is local, friend is foreigner
381 {
382 FriendInfo[] finfos = GetFriends(agentID);
383 FriendInfo finfo = GetFriend(finfos, friendID);
384 if (finfo != null)
385 {
386 FriendsService.StoreFriend(agentID.ToString(), finfo.Friend, rights);
387 return true;
388 }
389 }
390
391 if (account2 != null) // agent is foreigner, friend is local
392 {
393 string agentUUI = GetUUI(friendID, agentID);
394 if (agentUUI != string.Empty)
395 {
396 FriendsService.StoreFriend(agentUUI, friendID.ToString(), rights);
397 return true;
398 }
399 }
400
401 return false;
402
403 }
404
405 protected override void StoreBackwards(UUID friendID, UUID agentID)
406 {
407 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
408 UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
409 // Are they both local users?
410 if (account1 != null && account2 != null)
411 {
412 // local grid users
413 m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
414 base.StoreBackwards(friendID, agentID);
415 return;
416 }
417
418 // no provision for this temporary friendship state
419 //FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
420 }
421
422 protected override void StoreFriendships(UUID agentID, UUID friendID)
423 {
424 UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
425 UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
426 // Are they both local users?
427 if (agentAccount != null && friendAccount != null)
428 {
429 // local grid users
430 m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
431 base.StoreFriendships(agentID, friendID);
432 return;
433 }
434
435 // ok, at least one of them is foreigner, let's get their data
436 IClientAPI agentClient = LocateClientObject(agentID);
437 IClientAPI friendClient = LocateClientObject(friendID);
438 AgentCircuitData agentClientCircuit = null;
439 AgentCircuitData friendClientCircuit = null;
440 string agentUUI = string.Empty;
441 string friendUUI = string.Empty;
442 string agentFriendService = string.Empty;
443 string friendFriendService = string.Empty;
444
445 if (agentClient != null)
446 {
447 agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
448 agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
449 agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
450 }
451 if (friendClient != null)
452 {
453 friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode);
454 friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit);
455 friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
456 }
457
458 m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
459 agentUUI, friendUUI, agentFriendService, friendFriendService);
460
461 // Generate a random 8-character hex number that will sign this friendship
462 string secret = UUID.Random().ToString().Substring(0, 8);
463
464 if (agentAccount != null) // agent is local, 'friend' is foreigner
465 {
466 // This may happen when the agent returned home, in which case the friend is not there
467 // We need to look for its information in the friends list itself
468 bool confirming = false;
469 if (friendUUI == string.Empty)
470 {
471 FriendInfo[] finfos = GetFriends(agentID);
472 foreach (FriendInfo finfo in finfos)
473 {
474 if (finfo.TheirFlags == -1)
475 {
476 if (finfo.Friend.StartsWith(friendID.ToString()))
477 {
478 friendUUI = finfo.Friend;
479 confirming = true;
480 }
481 }
482 }
483 }
484
485 // If it's confirming the friendship, we already have the full friendUUI with the secret
486 string theFriendUUID = confirming ? friendUUI : friendUUI + ";" + secret;
487
488 // store in the local friends service a reference to the foreign friend
489 FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1);
490 // and also the converse
491 FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1);
492
493 if (!confirming && friendClientCircuit != null)
494 {
495 // store in the foreign friends service a reference to the local agent
496 HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
497 friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
498 }
499 }
500 else if (friendAccount != null) // 'friend' is local, agent is foreigner
501 {
502 // store in the local friends service a reference to the foreign agent
503 FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1);
504 // and also the converse
505 FriendsService.StoreFriend(agentUUI + ";" + secret, friendID.ToString(), 1);
506
507 if (agentClientCircuit != null)
508 {
509 // store in the foreign friends service a reference to the local agent
510 HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
511 friendsConn.NewFriendship(agentID, friendUUI + ";" + secret);
512 }
513 }
514 else // They're both foreigners!
515 {
516 HGFriendsServicesConnector friendsConn;
517 if (agentClientCircuit != null)
518 {
519 friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
520 friendsConn.NewFriendship(agentID, friendUUI + ";" + secret);
521 }
522 if (friendClientCircuit != null)
523 {
524 friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
525 friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
526 }
527 }
528 // my brain hurts now
529 }
530
531 protected override bool DeleteFriendship(UUID agentID, UUID exfriendID)
532 {
533 UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
534 UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, exfriendID);
535 // Are they both local users?
536 if (agentAccount != null && friendAccount != null)
537 {
538 // local grid users
539 return base.DeleteFriendship(agentID, exfriendID);
540 }
541
542 // ok, at least one of them is foreigner, let's get their data
543 string agentUUI = string.Empty;
544 string friendUUI = string.Empty;
545
546 if (agentAccount != null) // agent is local, 'friend' is foreigner
547 {
548 // We need to look for its information in the friends list itself
549 FriendInfo[] finfos = GetFriends(agentID);
550 FriendInfo finfo = GetFriend(finfos, exfriendID);
551 if (finfo != null)
552 {
553 friendUUI = finfo.Friend;
554
555 // delete in the local friends service the reference to the foreign friend
556 FriendsService.Delete(agentID, friendUUI);
557 // and also the converse
558 FriendsService.Delete(friendUUI, agentID.ToString());
559
560 // notify the exfriend's service
561 Util.FireAndForget(delegate { Delete(exfriendID, agentID, friendUUI); });
562
563 m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentID, friendUUI);
564 return true;
565 }
566 }
567 else if (friendAccount != null) // agent is foreigner, 'friend' is local
568 {
569 agentUUI = GetUUI(exfriendID, agentID);
570
571 if (agentUUI != string.Empty)
572 {
573 // delete in the local friends service the reference to the foreign agent
574 FriendsService.Delete(exfriendID, agentUUI);
575 // and also the converse
576 FriendsService.Delete(agentUUI, exfriendID.ToString());
577
578 // notify the agent's service?
579 Util.FireAndForget(delegate { Delete(agentID, exfriendID, agentUUI); });
580
581 m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentUUI, exfriendID);
582 return true;
583 }
584 }
585 //else They're both foreigners! Can't handle this
586
587 return false;
588 }
589
590 private string GetUUI(UUID localUser, UUID foreignUser)
591 {
592 // Let's see if the user is here by any chance
593 FriendInfo[] finfos = GetFriends(localUser);
594 if (finfos != EMPTY_FRIENDS) // friend is here, cool
595 {
596 FriendInfo finfo = GetFriend(finfos, foreignUser);
597 if (finfo != null)
598 {
599 return finfo.Friend;
600 }
601 }
602 else // user is not currently on this sim, need to get from the service
603 {
604 finfos = FriendsService.GetFriends(localUser);
605 foreach (FriendInfo finfo in finfos)
606 {
607 if (finfo.Friend.StartsWith(foreignUser.ToString())) // found it!
608 {
609 return finfo.Friend;
610 }
611 }
612 }
613 return string.Empty;
614 }
615
616 private void Delete(UUID foreignUser, UUID localUser, string uui)
617 {
618 UUID id;
619 string url = string.Empty, secret = string.Empty, tmp = string.Empty;
620 if (Util.ParseUniversalUserIdentifier(uui, out id, out url, out tmp, out tmp, out secret))
621 {
622 m_log.DebugFormat("[HGFRIENDS MODULE]: Deleting friendship from {0}", url);
623 HGFriendsServicesConnector friendConn = new HGFriendsServicesConnector(url);
624 friendConn.DeleteFriendship(foreignUser, localUser, secret);
625 }
626 }
627 }
628}