diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | 212 |
1 files changed, 151 insertions, 61 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index abffb94..c55839f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | |||
@@ -72,8 +72,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
72 | UUID id; | 72 | UUID id; |
73 | if (!UUID.TryParse(finfo.Friend, out id)) | 73 | if (!UUID.TryParse(finfo.Friend, out id)) |
74 | { | 74 | { |
75 | string url = string.Empty, first = string.Empty, last = string.Empty; | 75 | string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty; |
76 | if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last)) | 76 | if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last, out tmp)) |
77 | { | 77 | { |
78 | IUserManagement uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>(); | 78 | IUserManagement uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>(); |
79 | uMan.AddUser(id, url + ";" + first + " " + last); | 79 | uMan.AddUser(id, url + ";" + first + " " + last); |
@@ -103,22 +103,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
103 | return false; | 103 | return false; |
104 | } | 104 | } |
105 | 105 | ||
106 | protected override FriendInfo[] GetFriendsFromService(IClientAPI client) | ||
107 | { | ||
108 | UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId); | ||
109 | if (account1 != null) | ||
110 | return base.GetFriendsFromService(client); | ||
111 | |||
112 | // Foreigner | ||
113 | AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); | ||
114 | string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); | ||
115 | |||
116 | FriendInfo[] finfos = FriendsService.GetFriends(agentUUI); | ||
117 | m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI); | ||
118 | return finfos; | ||
119 | } | ||
120 | |||
121 | |||
122 | protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) | 106 | protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) |
123 | { | 107 | { |
124 | first = "Unknown"; last = "User"; | 108 | first = "Unknown"; last = "User"; |
@@ -126,8 +110,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
126 | return true; | 110 | return true; |
127 | 111 | ||
128 | // fid is not a UUID... | 112 | // fid is not a UUID... |
129 | string url = string.Empty; | 113 | string url = string.Empty, tmp = string.Empty; |
130 | if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last)) | 114 | if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp)) |
131 | { | 115 | { |
132 | IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>(); | 116 | IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>(); |
133 | userMan.AddUser(agentID, url + ";" + first + " " + last); | 117 | userMan.AddUser(agentID, url + ";" + first + " " + last); |
@@ -164,7 +148,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
164 | return "Please confirm this friendship you made while you were away."; | 148 | return "Please confirm this friendship you made while you were away."; |
165 | } | 149 | } |
166 | 150 | ||
167 | protected override bool SimpleStore(UUID agentID, UUID friendID, int rights) | 151 | protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID) |
152 | { | ||
153 | foreach (FriendInfo fi in friends) | ||
154 | { | ||
155 | if (fi.Friend.StartsWith(friendID.ToString())) | ||
156 | return fi; | ||
157 | } | ||
158 | return null; | ||
159 | } | ||
160 | |||
161 | |||
162 | protected override FriendInfo[] GetFriendsFromService(IClientAPI client) | ||
163 | { | ||
164 | UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId); | ||
165 | if (account1 != null) | ||
166 | return base.GetFriendsFromService(client); | ||
167 | |||
168 | FriendInfo[] finfos = new FriendInfo[0]; | ||
169 | // Foreigner | ||
170 | AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); | ||
171 | if (agentClientCircuit != null) | ||
172 | { | ||
173 | string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); | ||
174 | |||
175 | m_log.DebugFormat("[XXX] GetFriendsFromService to {0}", agentUUI); | ||
176 | finfos = FriendsService.GetFriends(agentUUI); | ||
177 | m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI); | ||
178 | } | ||
179 | return finfos; | ||
180 | } | ||
181 | |||
182 | protected override bool StoreRights(UUID agentID, UUID friendID, int rights) | ||
168 | { | 183 | { |
169 | UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID); | 184 | UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID); |
170 | UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID); | 185 | UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID); |
@@ -172,30 +187,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
172 | if (account1 != null && account2 != null) | 187 | if (account1 != null && account2 != null) |
173 | { | 188 | { |
174 | // local grid users | 189 | // local grid users |
175 | return base.SimpleStore(agentID, friendID, rights); | 190 | return base.StoreRights(agentID, friendID, rights); |
176 | } | 191 | } |
177 | 192 | ||
178 | if (account1 != null) | 193 | if (account1 != null) // agent is local, friend is foreigner |
179 | { | 194 | { |
180 | FriendInfo[] finfos = GetFriends(agentID); | 195 | FriendInfo[] finfos = GetFriends(agentID); |
181 | if (finfos.Length > 0) | 196 | FriendInfo finfo = GetFriend(finfos, friendID); |
197 | if (finfo != null) | ||
182 | { | 198 | { |
183 | FriendInfo finfo = GetFriend(finfos, friendID); | ||
184 | FriendsService.StoreFriend(agentID.ToString(), finfo.Friend, rights); | 199 | FriendsService.StoreFriend(agentID.ToString(), finfo.Friend, rights); |
185 | return true; | 200 | return true; |
186 | } | 201 | } |
187 | } | 202 | } |
188 | if (account2 != null) | 203 | |
204 | if (account2 != null) // agent is foreigner, friend is local | ||
189 | { | 205 | { |
190 | IClientAPI client = LocateClientObject(agentID); | 206 | string agentUUI = GetUUI(friendID, agentID); |
191 | if (client != null) | 207 | if (agentUUI != string.Empty) |
192 | { | 208 | { |
193 | AgentCircuitData acircuit = m_Scenes[0].AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); | 209 | FriendsService.StoreFriend(agentUUI, friendID.ToString(), rights); |
194 | if (acircuit != null) | 210 | return true; |
195 | { | ||
196 | FriendsService.StoreFriend(Util.ProduceUserUniversalIdentifier(acircuit), friendID.ToString(), rights); | ||
197 | return true; | ||
198 | } | ||
199 | } | 211 | } |
200 | } | 212 | } |
201 | 213 | ||
@@ -233,7 +245,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
233 | return; | 245 | return; |
234 | } | 246 | } |
235 | 247 | ||
236 | |||
237 | // ok, at least one of them is foreigner, let's get their data | 248 | // ok, at least one of them is foreigner, let's get their data |
238 | IClientAPI agentClient = LocateClientObject(agentID); | 249 | IClientAPI agentClient = LocateClientObject(agentID); |
239 | IClientAPI friendClient = LocateClientObject(friendID); | 250 | IClientAPI friendClient = LocateClientObject(friendID); |
@@ -257,13 +268,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
257 | friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); | 268 | friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); |
258 | } | 269 | } |
259 | 270 | ||
260 | m_log.DebugFormat("[XXX] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}", | 271 | m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}", |
261 | agentUUI, friendUUI, agentFriendService, friendFriendService); | 272 | agentUUI, friendUUI, agentFriendService, friendFriendService); |
262 | 273 | ||
274 | // Generate a random 8-character hex number that will sign this friendship | ||
275 | string secret = UUID.Random().ToString().Substring(0, 8); | ||
276 | |||
263 | if (agentAccount != null) // agent is local, 'friend' is foreigner | 277 | if (agentAccount != null) // agent is local, 'friend' is foreigner |
264 | { | 278 | { |
265 | // This may happen when the agent returned home, in which case the friend is not there | 279 | // This may happen when the agent returned home, in which case the friend is not there |
266 | // We need to llok for its information in the friends list itself | 280 | // We need to look for its information in the friends list itself |
281 | bool confirming = false; | ||
267 | if (friendUUI == string.Empty) | 282 | if (friendUUI == string.Empty) |
268 | { | 283 | { |
269 | FriendInfo[] finfos = GetFriends(agentID); | 284 | FriendInfo[] finfos = GetFriends(agentID); |
@@ -272,35 +287,41 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
272 | if (finfo.TheirFlags == -1) | 287 | if (finfo.TheirFlags == -1) |
273 | { | 288 | { |
274 | if (finfo.Friend.StartsWith(friendID.ToString())) | 289 | if (finfo.Friend.StartsWith(friendID.ToString())) |
290 | { | ||
275 | friendUUI = finfo.Friend; | 291 | friendUUI = finfo.Friend; |
292 | confirming = true; | ||
293 | } | ||
276 | } | 294 | } |
277 | } | 295 | } |
278 | } | 296 | } |
279 | 297 | ||
298 | // If it's confirming the friendship, we already have the full friendUUI with the secret | ||
299 | string theFriendUUID = confirming ? friendUUI : friendUUI + ";" + secret; | ||
300 | |||
280 | // store in the local friends service a reference to the foreign friend | 301 | // store in the local friends service a reference to the foreign friend |
281 | FriendsService.StoreFriend(agentID.ToString(), friendUUI, 1); | 302 | FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1); |
282 | // and also the converse | 303 | // and also the converse |
283 | FriendsService.StoreFriend(friendUUI, agentID.ToString(), 1); | 304 | FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1); |
284 | 305 | ||
285 | if (friendClientCircuit != null) | 306 | if (!confirming && friendClientCircuit != null) |
286 | { | 307 | { |
287 | // store in the foreign friends service a reference to the local agent | 308 | // store in the foreign friends service a reference to the local agent |
288 | HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID); | 309 | HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID); |
289 | friendsConn.NewFriendship(friendID, agentUUI); | 310 | friendsConn.NewFriendship(friendID, agentUUI + ";" + secret); |
290 | } | 311 | } |
291 | } | 312 | } |
292 | else if (friendAccount != null) // 'friend' is local, agent is foreigner | 313 | else if (friendAccount != null) // 'friend' is local, agent is foreigner |
293 | { | 314 | { |
294 | // store in the local friends service a reference to the foreign agent | 315 | // store in the local friends service a reference to the foreign agent |
295 | FriendsService.StoreFriend(friendID.ToString(), agentUUI, 1); | 316 | FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1); |
296 | // and also the converse | 317 | // and also the converse |
297 | FriendsService.StoreFriend(agentUUI, friendID.ToString(), 1); | 318 | FriendsService.StoreFriend(agentUUI + ";" + secret, friendID.ToString(), 1); |
298 | 319 | ||
299 | if (agentClientCircuit != null) | 320 | if (agentClientCircuit != null) |
300 | { | 321 | { |
301 | // store in the foreign friends service a reference to the local agent | 322 | // store in the foreign friends service a reference to the local agent |
302 | HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID); | 323 | HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID); |
303 | friendsConn.NewFriendship(agentID, friendUUI); | 324 | friendsConn.NewFriendship(agentID, friendUUI + ";" + secret); |
304 | } | 325 | } |
305 | } | 326 | } |
306 | else // They're both foreigners! | 327 | else // They're both foreigners! |
@@ -309,43 +330,112 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
309 | if (agentClientCircuit != null) | 330 | if (agentClientCircuit != null) |
310 | { | 331 | { |
311 | friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID); | 332 | friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID); |
312 | friendsConn.NewFriendship(agentID, friendUUI); | 333 | friendsConn.NewFriendship(agentID, friendUUI + ";" + secret); |
313 | } | 334 | } |
314 | if (friendClientCircuit != null) | 335 | if (friendClientCircuit != null) |
315 | { | 336 | { |
316 | friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID); | 337 | friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID); |
317 | friendsConn.NewFriendship(friendID, agentUUI); | 338 | friendsConn.NewFriendship(friendID, agentUUI + ";" + secret); |
318 | } | 339 | } |
319 | } | 340 | } |
320 | // my brain hurts now | 341 | // my brain hurts now |
321 | } | 342 | } |
322 | 343 | ||
323 | protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID) | 344 | protected override bool DeleteFriendship(UUID agentID, UUID exfriendID) |
324 | { | 345 | { |
325 | foreach (FriendInfo fi in friends) | 346 | UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID); |
347 | UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, exfriendID); | ||
348 | // Are they both local users? | ||
349 | if (agentAccount != null && friendAccount != null) | ||
326 | { | 350 | { |
327 | if (fi.Friend.StartsWith(friendID.ToString())) | 351 | // local grid users |
328 | return fi; | 352 | return base.DeleteFriendship(agentID, exfriendID); |
329 | } | 353 | } |
330 | return null; | 354 | |
355 | // ok, at least one of them is foreigner, let's get their data | ||
356 | string agentUUI = string.Empty; | ||
357 | string friendUUI = string.Empty; | ||
358 | |||
359 | if (agentAccount != null) // agent is local, 'friend' is foreigner | ||
360 | { | ||
361 | // We need to look for its information in the friends list itself | ||
362 | FriendInfo[] finfos = GetFriends(agentID); | ||
363 | FriendInfo finfo = GetFriend(finfos, exfriendID); | ||
364 | if (finfo != null) | ||
365 | { | ||
366 | friendUUI = finfo.Friend; | ||
367 | |||
368 | // delete in the local friends service the reference to the foreign friend | ||
369 | FriendsService.Delete(agentID, friendUUI); | ||
370 | // and also the converse | ||
371 | FriendsService.Delete(friendUUI, agentID.ToString()); | ||
372 | |||
373 | // notify the exfriend's service | ||
374 | Util.FireAndForget(delegate { Delete(exfriendID, agentID, friendUUI); }); | ||
375 | |||
376 | m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentID, friendUUI); | ||
377 | return true; | ||
378 | } | ||
379 | } | ||
380 | else if (friendAccount != null) // agent is foreigner, 'friend' is local | ||
381 | { | ||
382 | agentUUI = GetUUI(exfriendID, agentID); | ||
383 | |||
384 | if (agentUUI != string.Empty) | ||
385 | { | ||
386 | // delete in the local friends service the reference to the foreign agent | ||
387 | FriendsService.Delete(exfriendID, agentUUI); | ||
388 | // and also the converse | ||
389 | FriendsService.Delete(agentUUI, exfriendID.ToString()); | ||
390 | |||
391 | // notify the agent's service? | ||
392 | Util.FireAndForget(delegate { Delete(agentID, exfriendID, agentUUI); }); | ||
393 | |||
394 | m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentUUI, exfriendID); | ||
395 | return true; | ||
396 | } | ||
397 | } | ||
398 | //else They're both foreigners! Can't handle this | ||
399 | |||
400 | return false; | ||
331 | } | 401 | } |
332 | 402 | ||
333 | protected override void DeleteFriendship(UUID agentID, UUID exfriendID) | 403 | private string GetUUI(UUID localUser, UUID foreignUser) |
334 | { | 404 | { |
335 | base.DeleteFriendship(agentID, exfriendID); | 405 | // Let's see if the user is here by any chance |
336 | // Maybe some of the base deletes will fail. | 406 | FriendInfo[] finfos = GetFriends(localUser); |
337 | // Let's delete the local friendship with foreign friend | 407 | if (finfos != EMPTY_FRIENDS) // friend is here, cool |
338 | FriendInfo[] friends = GetFriends(agentID); | ||
339 | foreach (FriendInfo finfo in friends) | ||
340 | { | 408 | { |
341 | if (finfo.Friend != exfriendID.ToString() && finfo.Friend.StartsWith(exfriendID.ToString())) | 409 | FriendInfo finfo = GetFriend(finfos, foreignUser); |
410 | if (finfo != null) | ||
342 | { | 411 | { |
343 | FriendsService.Delete(agentID, exfriendID.ToString()); | 412 | return finfo.Friend; |
344 | // TODO: delete the friendship on the other side | ||
345 | // Should use the homeurl given in finfo.Friend | ||
346 | } | 413 | } |
347 | } | 414 | } |
415 | else // user is not currently on this sim, need to get from the service | ||
416 | { | ||
417 | finfos = FriendsService.GetFriends(localUser); | ||
418 | foreach (FriendInfo finfo in finfos) | ||
419 | { | ||
420 | if (finfo.Friend.StartsWith(foreignUser.ToString())) // found it! | ||
421 | { | ||
422 | return finfo.Friend; | ||
423 | } | ||
424 | } | ||
425 | } | ||
426 | return string.Empty; | ||
348 | } | 427 | } |
349 | 428 | ||
429 | private void Delete(UUID foreignUser, UUID localUser, string uui) | ||
430 | { | ||
431 | UUID id; | ||
432 | string url = string.Empty, secret = string.Empty, tmp = string.Empty; | ||
433 | if (Util.ParseUniversalUserIdentifier(uui, out id, out url, out tmp, out tmp, out secret)) | ||
434 | { | ||
435 | m_log.DebugFormat("[HGFRIENDS MODULE]: Deleting friendship from {0}", url); | ||
436 | HGFriendsServicesConnector friendConn = new HGFriendsServicesConnector(url); | ||
437 | friendConn.DeleteFriendship(foreignUser, localUser, secret); | ||
438 | } | ||
439 | } | ||
350 | } | 440 | } |
351 | } | 441 | } |