diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | 162 |
1 files changed, 160 insertions, 2 deletions
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 | } |