aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/Friends
diff options
context:
space:
mode:
authorDiva Canto2011-05-23 19:45:39 -0700
committerDiva Canto2011-05-23 19:45:39 -0700
commit24f28d353427d1905ae1a46408841265379e29c3 (patch)
tree07234a5837632bbe0d1198bf282d023c9cd1fb43 /OpenSim/Region/CoreModules/Avatar/Friends
parentMore on HG Friends. Added Delete(string, string) across the board. Added secu... (diff)
downloadopensim-SC-24f28d353427d1905ae1a46408841265379e29c3.zip
opensim-SC-24f28d353427d1905ae1a46408841265379e29c3.tar.gz
opensim-SC-24f28d353427d1905ae1a46408841265379e29c3.tar.bz2
opensim-SC-24f28d353427d1905ae1a46408841265379e29c3.tar.xz
HG friends: Status notifications working. Also initial logins get the online friends in other grids.
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Friends')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs92
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs162
2 files changed, 207 insertions, 47 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index 7d94813..f82716d 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -139,7 +139,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
139 if (moduleConfig != null) 139 if (moduleConfig != null)
140 { 140 {
141 string name = moduleConfig.GetString("FriendsModule", "FriendsModule"); 141 string name = moduleConfig.GetString("FriendsModule", "FriendsModule");
142 m_log.DebugFormat("[XXX] {0} compared to {1}", name, Name);
143 if (name == Name) 142 if (name == Name)
144 { 143 {
145 InitModule(config); 144 InitModule(config);
@@ -183,7 +182,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
183 { 182 {
184 } 183 }
185 184
186 public void AddRegion(Scene scene) 185 public virtual void AddRegion(Scene scene)
187 { 186 {
188 if (!m_Enabled) 187 if (!m_Enabled)
189 return; 188 return;
@@ -302,6 +301,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
302 { 301 {
303 UUID agentID = client.AgentId; 302 UUID agentID = client.AgentId;
304 303
304 //m_log.DebugFormat("[XXX]: OnClientLogin!");
305 // Inform the friends that this user is online 305 // Inform the friends that this user is online
306 StatusChange(agentID, true); 306 StatusChange(agentID, true);
307 307
@@ -405,19 +405,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
405 } 405 }
406 406
407 if (friendList.Count > 0) 407 if (friendList.Count > 0)
408 { 408 GetOnlineFriends(userID, friendList, online);
409 PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
410 foreach (PresenceInfo pi in presence)
411 {
412 UUID presenceID;
413 if (UUID.TryParse(pi.UserID, out presenceID))
414 online.Add(presenceID);
415 }
416 }
417 409
418 return online; 410 return online;
419 } 411 }
420 412
413 protected virtual void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
414 {
415 PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
416 foreach (PresenceInfo pi in presence)
417 {
418 UUID presenceID;
419 if (UUID.TryParse(pi.UserID, out presenceID))
420 online.Add(presenceID);
421 }
422 }
423
421 /// <summary> 424 /// <summary>
422 /// Find the client for a ID 425 /// Find the client for a ID
423 /// </summary> 426 /// </summary>
@@ -472,51 +475,51 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
472 Util.FireAndForget( 475 Util.FireAndForget(
473 delegate 476 delegate
474 { 477 {
475 foreach (FriendInfo fi in friendList) 478 m_log.DebugFormat("[FRIENDS MODULE]: Notifying {0} friends", friendList.Count);
476 { 479 // Notify about this user status
477 //m_log.DebugFormat("[FRIENDS]: Notifying {0}", fi.PrincipalID); 480 StatusNotify(friendList, agentID, online);
478 // Notify about this user status
479 StatusNotify(fi, agentID, online);
480 }
481 } 481 }
482 ); 482 );
483 } 483 }
484 } 484 }
485 485
486 private void StatusNotify(FriendInfo friend, UUID userID, bool online) 486 protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
487 { 487 {
488 UUID friendID; 488 foreach (FriendInfo friend in friendList)
489 if (UUID.TryParse(friend.Friend, out friendID))
490 { 489 {
491 // Try local 490 UUID friendID;
492 if (LocalStatusNotification(userID, friendID, online)) 491 if (UUID.TryParse(friend.Friend, out friendID))
493 return;
494
495 // The friend is not here [as root]. Let's forward.
496 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
497 if (friendSessions != null && friendSessions.Length > 0)
498 { 492 {
499 PresenceInfo friendSession = null; 493 // Try local
500 foreach (PresenceInfo pinfo in friendSessions) 494 if (LocalStatusNotification(userID, friendID, online))
501 if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad 495 return;
502 {
503 friendSession = pinfo;
504 break;
505 }
506 496
507 if (friendSession != null) 497 // The friend is not here [as root]. Let's forward.
498 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
499 if (friendSessions != null && friendSessions.Length > 0)
508 { 500 {
509 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); 501 PresenceInfo friendSession = null;
510 //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName); 502 foreach (PresenceInfo pinfo in friendSessions)
511 m_FriendsSimConnector.StatusNotify(region, userID, friendID, online); 503 if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad
504 {
505 friendSession = pinfo;
506 break;
507 }
508
509 if (friendSession != null)
510 {
511 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
512 //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
513 m_FriendsSimConnector.StatusNotify(region, userID, friendID, online);
514 }
512 } 515 }
513 }
514 516
515 // Friend is not online. Ignore. 517 // Friend is not online. Ignore.
516 } 518 }
517 else 519 else
518 { 520 {
519 m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend); 521 m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend);
522 }
520 } 523 }
521 } 524 }
522 525
@@ -670,7 +673,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
670 FriendInfo[] friends = GetFriends(remoteClient.AgentId); 673 FriendInfo[] friends = GetFriends(remoteClient.AgentId);
671 if (friends.Length == 0) 674 if (friends.Length == 0)
672 { 675 {
673 m_log.DebugFormat("[XXX]: agent {0} has no friends", requester);
674 return; 676 return;
675 } 677 }
676 678
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
index c55839f..b0a7567 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
@@ -46,7 +46,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
46namespace OpenSim.Region.CoreModules.Avatar.Friends 46namespace OpenSim.Region.CoreModules.Avatar.Friends
47{ 47{
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
49 public class HGFriendsModule : FriendsModule, ISharedRegionModule, IFriendsModule 49 public class HGFriendsModule : FriendsModule, ISharedRegionModule, IFriendsModule, IFriendsSimConnector
50 { 50 {
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 52
@@ -56,6 +56,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
56 get { return "HGFriendsModule"; } 56 get { return "HGFriendsModule"; }
57 } 57 }
58 58
59 public override void AddRegion(Scene scene)
60 {
61 if (!m_Enabled)
62 return;
63
64 base.AddRegion(scene);
65 scene.RegisterModuleInterface<IFriendsSimConnector>(this);
66 }
67
68 #endregion
69
70 #region IFriendsSimConnector
71
72 /// <summary>
73 /// Notify the user that the friend's status changed
74 /// </summary>
75 /// <param name="userID">user to be notified</param>
76 /// <param name="friendID">friend whose status changed</param>
77 /// <param name="online">status</param>
78 /// <returns></returns>
79 public bool StatusNotify(UUID userID, UUID friendID, bool online)
80 {
81 return LocalStatusNotification(friendID, userID, online);
82 }
83
59 #endregion 84 #endregion
60 85
61 protected override bool FetchFriendslist(IClientAPI client) 86 protected override bool FetchFriendslist(IClientAPI client)
@@ -103,6 +128,140 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
103 return false; 128 return false;
104 } 129 }
105 130
131 protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
132 {
133 // Let's single out the UUIs
134 List<string> localFriends = new List<string>();
135 List<string> foreignFriends = new List<string>();
136 string tmp = string.Empty;
137
138 foreach (string s in friendList)
139 {
140 UUID id;
141 if (UUID.TryParse(s, out id))
142 localFriends.Add(s);
143 else if (Util.ParseUniversalUserIdentifier(s, out id, out tmp, out tmp, out tmp, out tmp))
144 {
145 foreignFriends.Add(s);
146 // add it here too, who knows maybe the foreign friends happens to be on this grid
147 localFriends.Add(id.ToString());
148 }
149 }
150
151 // OK, see who's present on this grid
152 List<string> toBeRemoved = new List<string>();
153 PresenceInfo[] presence = PresenceService.GetAgents(localFriends.ToArray());
154 foreach (PresenceInfo pi in presence)
155 {
156 UUID presenceID;
157 if (UUID.TryParse(pi.UserID, out presenceID))
158 {
159 online.Add(presenceID);
160 foreach (string s in foreignFriends)
161 if (s.StartsWith(pi.UserID))
162 toBeRemoved.Add(s);
163 }
164 }
165
166 foreach (string s in toBeRemoved)
167 foreignFriends.Remove(s);
168
169 // OK, let's send this up the stack, and leave a closure here
170 // collecting online friends in other grids
171 Util.FireAndForget(delegate { CollectOnlineFriendsElsewhere(userID, foreignFriends); });
172
173 }
174
175 private void CollectOnlineFriendsElsewhere(UUID userID, List<string> foreignFriends)
176 {
177 // let's divide the friends on a per-domain basis
178 Dictionary<string, List<string>> friendsPerDomain = new Dictionary<string, List<string>>();
179 foreach (string friend in foreignFriends)
180 {
181 UUID friendID;
182 if (!UUID.TryParse(friend, out friendID))
183 {
184 // it's a foreign friend
185 string url = string.Empty, tmp = string.Empty;
186 if (Util.ParseUniversalUserIdentifier(friend, out friendID, out url, out tmp, out tmp, out tmp))
187 {
188 if (!friendsPerDomain.ContainsKey(url))
189 friendsPerDomain[url] = new List<string>();
190 friendsPerDomain[url].Add(friend);
191 }
192 }
193 }
194
195 // Now, call those worlds
196
197 foreach (KeyValuePair<string, List<string>> kvp in friendsPerDomain)
198 {
199 List<string> ids = new List<string>();
200 foreach (string f in kvp.Value)
201 ids.Add(f);
202 UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
203 List<UUID> online = uConn.GetOnlineFriends(userID, ids);
204 // Finally send the notifications to the user
205 // this whole process may take a while, so let's check at every
206 // iteration that the user is still here
207 IClientAPI client = LocateClientObject(userID);
208 if (client != null)
209 client.SendAgentOnline(online.ToArray());
210 else
211 break;
212 }
213
214 }
215
216 protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
217 {
218 // First, let's divide the friends on a per-domain basis
219 Dictionary<string, List<FriendInfo>> friendsPerDomain = new Dictionary<string, List<FriendInfo>>();
220 foreach (FriendInfo friend in friendList)
221 {
222 UUID friendID;
223 if (UUID.TryParse(friend.Friend, out friendID))
224 {
225 if (!friendsPerDomain.ContainsKey("local"))
226 friendsPerDomain["local"] = new List<FriendInfo>();
227 friendsPerDomain["local"].Add(friend);
228 }
229 else
230 {
231 // it's a foreign friend
232 string url = string.Empty, tmp = string.Empty;
233 if (Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out url, out tmp, out tmp, out tmp))
234 {
235 // Let's try our luck in the local sim. Who knows, maybe it's here
236 if (LocalStatusNotification(userID, friendID, online))
237 continue;
238
239 if (!friendsPerDomain.ContainsKey(url))
240 friendsPerDomain[url] = new List<FriendInfo>();
241 friendsPerDomain[url].Add(friend);
242 }
243 }
244 }
245
246 // For the local friends, just call the base method
247 // Let's do this first of all
248 if (friendsPerDomain.ContainsKey("local"))
249 base.StatusNotify(friendsPerDomain["local"], userID, online);
250
251 foreach (KeyValuePair<string, List<FriendInfo>> kvp in friendsPerDomain)
252 {
253 if (kvp.Key != "local")
254 {
255 // For the others, call the user agent service
256 List<string> ids = new List<string>();
257 foreach (FriendInfo f in kvp.Value)
258 ids.Add(f.Friend);
259 UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
260 uConn.StatusNotification(ids, userID, online);
261 }
262 }
263 }
264
106 protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) 265 protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
107 { 266 {
108 first = "Unknown"; last = "User"; 267 first = "Unknown"; last = "User";
@@ -172,7 +331,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
172 { 331 {
173 string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); 332 string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
174 333
175 m_log.DebugFormat("[XXX] GetFriendsFromService to {0}", agentUUI);
176 finfos = FriendsService.GetFriends(agentUUI); 334 finfos = FriendsService.GetFriends(agentUUI);
177 m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI); 335 m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI);
178 } 336 }