diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | 92 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | 162 |
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; | |||
46 | namespace OpenSim.Region.CoreModules.Avatar.Friends | 46 | namespace 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 | } |