diff options
author | Melanie | 2012-03-31 02:18:02 +0100 |
---|---|---|
committer | Melanie | 2012-03-31 02:18:02 +0100 |
commit | f3132c45d98af7bb38251ad95013c433b5eda9e5 (patch) | |
tree | efc3d6c0529678c0a56f5a505a52944012ea607a /OpenSim/Region/CoreModules/Avatar | |
parent | Merge branch 'master' into careminster (diff) | |
parent | refactor: Rename SOG.GetChildPart() to GetPart() since it can also return the... (diff) | |
download | opensim-SC-f3132c45d98af7bb38251ad95013c433b5eda9e5.zip opensim-SC-f3132c45d98af7bb38251ad95013c433b5eda9e5.tar.gz opensim-SC-f3132c45d98af7bb38251ad95013c433b5eda9e5.tar.bz2 opensim-SC-f3132c45d98af7bb38251ad95013c433b5eda9e5.tar.xz |
Merge branch 'master' into careminster
Conflicts:
OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
OpenSim/Tests/Common/Mock/TestClient.cs
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar')
4 files changed, 238 insertions, 157 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs index 5e2a651..d942e87 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs | |||
@@ -1,4 +1,31 @@ | |||
1 | using System; | 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 | |||
28 | using System; | ||
2 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
3 | using System.Reflection; | 30 | using System.Reflection; |
4 | using log4net; | 31 | using log4net; |
@@ -10,7 +37,7 @@ using OpenSim.Region.Framework.Scenes; | |||
10 | using OpenSim.Services.Interfaces; | 37 | using OpenSim.Services.Interfaces; |
11 | using Mono.Addins; | 38 | using Mono.Addins; |
12 | 39 | ||
13 | namespace Careminster.XCallingCard.Modules | 40 | namespace OpenSim.Region.CoreModules.Avatar.Friends |
14 | { | 41 | { |
15 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XCallingCard")] | 42 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XCallingCard")] |
16 | public class CallingCardModule : ISharedRegionModule, ICallingCardModule | 43 | public class CallingCardModule : ISharedRegionModule, ICallingCardModule |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 4cc0e19..f64c161 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | |||
@@ -51,12 +51,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
51 | { | 51 | { |
52 | public class FriendsModule : ISharedRegionModule, IFriendsModule | 52 | public class FriendsModule : ISharedRegionModule, IFriendsModule |
53 | { | 53 | { |
54 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
55 | |||
54 | protected bool m_Enabled = false; | 56 | protected bool m_Enabled = false; |
55 | 57 | ||
56 | protected class UserFriendData | 58 | protected class UserFriendData |
57 | { | 59 | { |
58 | public UUID PrincipalID; | 60 | public UUID PrincipalID; |
59 | public FriendInfo[] Friends; | 61 | public FriendInfo[] Friends; |
62 | public int Refcount; | ||
60 | 63 | ||
61 | public bool IsFriend(string friend) | 64 | public bool IsFriend(string friend) |
62 | { | 65 | { |
@@ -71,7 +74,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
71 | } | 74 | } |
72 | 75 | ||
73 | protected static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0]; | 76 | protected static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0]; |
74 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
75 | 77 | ||
76 | protected List<Scene> m_Scenes = new List<Scene>(); | 78 | protected List<Scene> m_Scenes = new List<Scene>(); |
77 | 79 | ||
@@ -108,7 +110,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
108 | } | 110 | } |
109 | } | 111 | } |
110 | 112 | ||
111 | protected IFriendsService FriendsService | 113 | public IFriendsService FriendsService |
112 | { | 114 | { |
113 | get | 115 | get |
114 | { | 116 | { |
@@ -155,7 +157,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
155 | InitModule(config); | 157 | InitModule(config); |
156 | 158 | ||
157 | m_Enabled = true; | 159 | m_Enabled = true; |
158 | m_log.InfoFormat("[FRIENDS MODULE]: {0} enabled.", Name); | 160 | m_log.DebugFormat("[FRIENDS MODULE]: {0} enabled.", Name); |
159 | } | 161 | } |
160 | } | 162 | } |
161 | } | 163 | } |
@@ -200,7 +202,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
200 | if (!m_Enabled) | 202 | if (!m_Enabled) |
201 | return; | 203 | return; |
202 | 204 | ||
203 | m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name); | 205 | // m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name); |
204 | 206 | ||
205 | m_Scenes.Add(scene); | 207 | m_Scenes.Add(scene); |
206 | scene.RegisterModuleInterface<IFriendsModule>(this); | 208 | scene.RegisterModuleInterface<IFriendsModule>(this); |
@@ -211,14 +213,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
211 | scene.EventManager.OnClientLogin += OnClientLogin; | 213 | scene.EventManager.OnClientLogin += OnClientLogin; |
212 | } | 214 | } |
213 | 215 | ||
214 | public virtual void RegionLoaded(Scene scene) | 216 | public virtual void RegionLoaded(Scene scene) {} |
215 | { | ||
216 | scene.AddCommand( | ||
217 | "Friends", this, "friends show cache", | ||
218 | "friends show cache [<first-name> <last-name>]", | ||
219 | "Show the friends cache for the given user", | ||
220 | HandleFriendsShowCacheCommand); | ||
221 | } | ||
222 | 217 | ||
223 | public void RemoveRegion(Scene scene) | 218 | public void RemoveRegion(Scene scene) |
224 | { | 219 | { |
@@ -240,13 +235,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
240 | 235 | ||
241 | #endregion | 236 | #endregion |
242 | 237 | ||
243 | public virtual uint GetFriendPerms(UUID principalID, UUID friendID) | 238 | public virtual int GetRightsGrantedByFriend(UUID principalID, UUID friendID) |
244 | { | 239 | { |
245 | FriendInfo[] friends = GetFriends(principalID); | 240 | FriendInfo[] friends = GetFriendsFromCache(principalID); |
246 | FriendInfo finfo = GetFriend(friends, friendID); | 241 | FriendInfo finfo = GetFriend(friends, friendID); |
247 | if (finfo != null) | 242 | if (finfo != null) |
248 | { | 243 | { |
249 | return (uint)finfo.TheirFlags; | 244 | return finfo.TheirFlags; |
250 | } | 245 | } |
251 | 246 | ||
252 | return 0; | 247 | return 0; |
@@ -254,15 +249,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
254 | 249 | ||
255 | private void OnNewClient(IClientAPI client) | 250 | private void OnNewClient(IClientAPI client) |
256 | { | 251 | { |
257 | if (client.SceneAgent.IsChildAgent) | ||
258 | return; | ||
259 | |||
260 | client.OnInstantMessage += OnInstantMessage; | 252 | client.OnInstantMessage += OnInstantMessage; |
261 | client.OnApproveFriendRequest += OnApproveFriendRequest; | 253 | client.OnApproveFriendRequest += OnApproveFriendRequest; |
262 | client.OnDenyFriendRequest += OnDenyFriendRequest; | 254 | client.OnDenyFriendRequest += OnDenyFriendRequest; |
263 | client.OnTerminateFriendship += (thisClient, agentID, exfriendID) => RemoveFriendship(thisClient, exfriendID); | 255 | client.OnTerminateFriendship += RemoveFriendship; |
264 | client.OnGrantUserRights += OnGrantUserRights; | 256 | client.OnGrantUserRights += GrantRights; |
265 | 257 | ||
258 | // We need to cache information for child agents as well as root agents so that friend edit/move/delete | ||
259 | // permissions will work across borders where both regions are on different simulators. | ||
260 | // | ||
266 | // Do not do this asynchronously. If we do, then subsequent code can outrace CacheFriends() and | 261 | // Do not do this asynchronously. If we do, then subsequent code can outrace CacheFriends() and |
267 | // return misleading results from the still empty friends cache. | 262 | // return misleading results from the still empty friends cache. |
268 | // If we absolutely need to do this asynchronously, then a signalling mechanism is needed so that calls | 263 | // If we absolutely need to do this asynchronously, then a signalling mechanism is needed so that calls |
@@ -283,14 +278,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
283 | UUID agentID = client.AgentId; | 278 | UUID agentID = client.AgentId; |
284 | lock (m_Friends) | 279 | lock (m_Friends) |
285 | { | 280 | { |
286 | UserFriendData friendsData = new UserFriendData(); | 281 | UserFriendData friendsData; |
287 | friendsData.PrincipalID = agentID; | 282 | if (m_Friends.TryGetValue(agentID, out friendsData)) |
288 | friendsData.Friends = GetFriendsFromService(client); | 283 | { |
284 | friendsData.Refcount++; | ||
285 | return false; | ||
286 | } | ||
287 | else | ||
288 | { | ||
289 | friendsData = new UserFriendData(); | ||
290 | friendsData.PrincipalID = agentID; | ||
291 | friendsData.Friends = GetFriendsFromService(client); | ||
292 | friendsData.Refcount = 1; | ||
289 | 293 | ||
290 | m_Friends[agentID] = friendsData; | 294 | m_Friends[agentID] = friendsData; |
295 | return true; | ||
296 | } | ||
291 | } | 297 | } |
292 | |||
293 | return true; | ||
294 | } | 298 | } |
295 | 299 | ||
296 | private void OnClientClosed(UUID agentID, Scene scene) | 300 | private void OnClientClosed(UUID agentID, Scene scene) |
@@ -300,17 +304,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
300 | { | 304 | { |
301 | // do this for root agents closing out | 305 | // do this for root agents closing out |
302 | StatusChange(agentID, false); | 306 | StatusChange(agentID, false); |
307 | } | ||
303 | 308 | ||
304 | lock (m_Friends) | 309 | lock (m_Friends) |
305 | m_Friends.Remove(agentID); | 310 | { |
311 | UserFriendData friendsData; | ||
312 | if (m_Friends.TryGetValue(agentID, out friendsData)) | ||
313 | { | ||
314 | friendsData.Refcount--; | ||
315 | if (friendsData.Refcount <= 0) | ||
316 | m_Friends.Remove(agentID); | ||
317 | } | ||
306 | } | 318 | } |
307 | } | 319 | } |
308 | 320 | ||
309 | private void OnMakeRootAgent(ScenePresence sp) | 321 | private void OnMakeRootAgent(ScenePresence sp) |
310 | { | 322 | { |
311 | // FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event | 323 | RecacheFriends(sp.ControllingClient); |
312 | // is on the critical path for transferring an avatar from one region to another. | ||
313 | CacheFriends(sp.ControllingClient); | ||
314 | } | 324 | } |
315 | 325 | ||
316 | private void OnClientLogin(IClientAPI client) | 326 | private void OnClientLogin(IClientAPI client) |
@@ -339,18 +349,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
339 | 349 | ||
340 | // Send the friends online | 350 | // Send the friends online |
341 | List<UUID> online = GetOnlineFriends(agentID); | 351 | List<UUID> online = GetOnlineFriends(agentID); |
342 | if (online.Count > 0) | ||
343 | { | ||
344 | m_log.DebugFormat( | ||
345 | "[FRIENDS MODULE]: User {0} in region {1} has {2} friends online", | ||
346 | client.Name, client.Scene.RegionInfo.RegionName, online.Count); | ||
347 | 352 | ||
353 | if (online.Count > 0) | ||
348 | client.SendAgentOnline(online.ToArray()); | 354 | client.SendAgentOnline(online.ToArray()); |
349 | } | ||
350 | 355 | ||
351 | // Send outstanding friendship offers | 356 | // Send outstanding friendship offers |
352 | List<string> outstanding = new List<string>(); | 357 | List<string> outstanding = new List<string>(); |
353 | FriendInfo[] friends = GetFriends(agentID); | 358 | FriendInfo[] friends = GetFriendsFromCache(agentID); |
354 | foreach (FriendInfo fi in friends) | 359 | foreach (FriendInfo fi in friends) |
355 | { | 360 | { |
356 | if (fi.TheirFlags == -1) | 361 | if (fi.TheirFlags == -1) |
@@ -406,23 +411,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
406 | List<UUID> GetOnlineFriends(UUID userID) | 411 | List<UUID> GetOnlineFriends(UUID userID) |
407 | { | 412 | { |
408 | List<string> friendList = new List<string>(); | 413 | List<string> friendList = new List<string>(); |
409 | List<UUID> online = new List<UUID>(); | ||
410 | 414 | ||
411 | FriendInfo[] friends = GetFriends(userID); | 415 | FriendInfo[] friends = GetFriendsFromCache(userID); |
412 | foreach (FriendInfo fi in friends) | 416 | foreach (FriendInfo fi in friends) |
413 | { | 417 | { |
414 | if (((fi.TheirFlags & 1) != 0) && (fi.TheirFlags != -1)) | 418 | if (((fi.TheirFlags & (int)FriendRights.CanSeeOnline) != 0) && (fi.TheirFlags != -1)) |
415 | friendList.Add(fi.Friend); | 419 | friendList.Add(fi.Friend); |
416 | } | 420 | } |
417 | 421 | ||
422 | List<UUID> online = new List<UUID>(); | ||
423 | |||
418 | if (friendList.Count > 0) | 424 | if (friendList.Count > 0) |
419 | GetOnlineFriends(userID, friendList, online); | 425 | GetOnlineFriends(userID, friendList, online); |
420 | 426 | ||
427 | // m_log.DebugFormat( | ||
428 | // "[FRIENDS MODULE]: User {0} has {1} friends online", userID, online.Count); | ||
429 | |||
421 | return online; | 430 | return online; |
422 | } | 431 | } |
423 | 432 | ||
424 | protected virtual void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online) | 433 | protected virtual void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online) |
425 | { | 434 | { |
435 | // m_log.DebugFormat( | ||
436 | // "[FRIENDS MODULE]: Looking for online presence of {0} users for {1}", friendList.Count, userID); | ||
437 | |||
426 | PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray()); | 438 | PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray()); |
427 | foreach (PresenceInfo pi in presence) | 439 | foreach (PresenceInfo pi in presence) |
428 | { | 440 | { |
@@ -473,13 +485,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
473 | /// <param name="online"></param> | 485 | /// <param name="online"></param> |
474 | private void StatusChange(UUID agentID, bool online) | 486 | private void StatusChange(UUID agentID, bool online) |
475 | { | 487 | { |
476 | FriendInfo[] friends = GetFriends(agentID); | 488 | FriendInfo[] friends = GetFriendsFromCache(agentID); |
477 | if (friends.Length > 0) | 489 | if (friends.Length > 0) |
478 | { | 490 | { |
479 | List<FriendInfo> friendList = new List<FriendInfo>(); | 491 | List<FriendInfo> friendList = new List<FriendInfo>(); |
480 | foreach (FriendInfo fi in friends) | 492 | foreach (FriendInfo fi in friends) |
481 | { | 493 | { |
482 | if (((fi.MyFlags & 1) != 0) && (fi.TheirFlags != -1)) | 494 | if (((fi.MyFlags & (int)FriendRights.CanSeeOnline) != 0) && (fi.TheirFlags != -1)) |
483 | friendList.Add(fi); | 495 | friendList.Add(fi); |
484 | } | 496 | } |
485 | 497 | ||
@@ -545,7 +557,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
545 | m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2} ({3})", principalID, client.FirstName + client.LastName, friendID, im.fromAgentName); | 557 | m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2} ({3})", principalID, client.FirstName + client.LastName, friendID, im.fromAgentName); |
546 | 558 | ||
547 | // Check that the friendship doesn't exist yet | 559 | // Check that the friendship doesn't exist yet |
548 | FriendInfo[] finfos = GetFriends(principalID); | 560 | FriendInfo[] finfos = GetFriendsFromCache(principalID); |
549 | if (finfos != null) | 561 | if (finfos != null) |
550 | { | 562 | { |
551 | FriendInfo f = GetFriend(finfos, friendID); | 563 | FriendInfo f = GetFriend(finfos, friendID); |
@@ -598,7 +610,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
598 | return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName; | 610 | return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName; |
599 | } | 611 | } |
600 | 612 | ||
601 | protected virtual void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) | 613 | protected virtual void OnApproveFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders) |
602 | { | 614 | { |
603 | m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", client.AgentId, friendID); | 615 | m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", client.AgentId, friendID); |
604 | 616 | ||
@@ -616,7 +628,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
616 | } | 628 | } |
617 | 629 | ||
618 | // Update the local cache. | 630 | // Update the local cache. |
619 | CacheFriends(client); | 631 | RecacheFriends(client); |
620 | 632 | ||
621 | // | 633 | // |
622 | // Notify the friend | 634 | // Notify the friend |
@@ -643,18 +655,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
643 | } | 655 | } |
644 | } | 656 | } |
645 | 657 | ||
646 | private void OnDenyFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) | 658 | private void OnDenyFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders) |
647 | { | 659 | { |
648 | m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID); | 660 | m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", client.AgentId, friendID); |
649 | 661 | ||
650 | DeleteFriendship(agentID, friendID); | 662 | DeleteFriendship(client.AgentId, friendID); |
651 | 663 | ||
652 | // | 664 | // |
653 | // Notify the friend | 665 | // Notify the friend |
654 | // | 666 | // |
655 | 667 | ||
656 | // Try local | 668 | // Try local |
657 | if (LocalFriendshipDenied(agentID, client.Name, friendID)) | 669 | if (LocalFriendshipDenied(client.AgentId, client.Name, friendID)) |
658 | return; | 670 | return; |
659 | 671 | ||
660 | PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); | 672 | PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); |
@@ -665,7 +677,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
665 | { | 677 | { |
666 | GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); | 678 | GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); |
667 | if (region != null) | 679 | if (region != null) |
668 | m_FriendsSimConnector.FriendshipDenied(region, agentID, client.Name, friendID); | 680 | m_FriendsSimConnector.FriendshipDenied(region, client.AgentId, client.Name, friendID); |
669 | else | 681 | else |
670 | m_log.WarnFormat("[FRIENDS]: Could not find region {0} in locating {1}", friendSession.RegionID, friendID); | 682 | m_log.WarnFormat("[FRIENDS]: Could not find region {0} in locating {1}", friendSession.RegionID, friendID); |
671 | } | 683 | } |
@@ -678,7 +690,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
678 | client.SendAlertMessage("Unable to terminate friendship on this sim."); | 690 | client.SendAlertMessage("Unable to terminate friendship on this sim."); |
679 | 691 | ||
680 | // Update local cache | 692 | // Update local cache |
681 | CacheFriends(client); | 693 | RecacheFriends(client); |
682 | 694 | ||
683 | client.SendTerminateFriend(exfriendID); | 695 | client.SendTerminateFriend(exfriendID); |
684 | 696 | ||
@@ -702,23 +714,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
702 | } | 714 | } |
703 | } | 715 | } |
704 | 716 | ||
705 | private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) | 717 | public void GrantRights(IClientAPI remoteClient, UUID friendID, int rights) |
706 | { | 718 | { |
707 | m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target); | 719 | UUID requester = remoteClient.AgentId; |
708 | 720 | ||
709 | FriendInfo[] friends = GetFriends(remoteClient.AgentId); | 721 | m_log.DebugFormat( |
722 | "[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", | ||
723 | requester, rights, friendID); | ||
724 | |||
725 | FriendInfo[] friends = GetFriendsFromCache(requester); | ||
710 | if (friends.Length == 0) | 726 | if (friends.Length == 0) |
711 | { | 727 | { |
712 | return; | 728 | return; |
713 | } | 729 | } |
714 | 730 | ||
715 | // Let's find the friend in this user's friend list | 731 | // Let's find the friend in this user's friend list |
716 | FriendInfo friend = GetFriend(friends, target); | 732 | FriendInfo friend = GetFriend(friends, friendID); |
717 | 733 | ||
718 | if (friend != null) // Found it | 734 | if (friend != null) // Found it |
719 | { | 735 | { |
720 | // Store it on the DB | 736 | // Store it on the DB |
721 | if (!StoreRights(requester, target, rights)) | 737 | if (!StoreRights(requester, friendID, rights)) |
722 | { | 738 | { |
723 | remoteClient.SendAlertMessage("Unable to grant rights."); | 739 | remoteClient.SendAlertMessage("Unable to grant rights."); |
724 | return; | 740 | return; |
@@ -729,17 +745,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
729 | friend.MyFlags = rights; | 745 | friend.MyFlags = rights; |
730 | 746 | ||
731 | // Always send this back to the original client | 747 | // Always send this back to the original client |
732 | remoteClient.SendChangeUserRights(requester, target, rights); | 748 | remoteClient.SendChangeUserRights(requester, friendID, rights); |
733 | 749 | ||
734 | // | 750 | // |
735 | // Notify the friend | 751 | // Notify the friend |
736 | // | 752 | // |
737 | 753 | ||
738 | // Try local | 754 | // Try local |
739 | if (LocalGrantRights(requester, target, myFlags, rights)) | 755 | if (LocalGrantRights(requester, friendID, myFlags, rights)) |
740 | return; | 756 | return; |
741 | 757 | ||
742 | PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { target.ToString() }); | 758 | PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); |
743 | if (friendSessions != null && friendSessions.Length > 0) | 759 | if (friendSessions != null && friendSessions.Length > 0) |
744 | { | 760 | { |
745 | PresenceInfo friendSession = friendSessions[0]; | 761 | PresenceInfo friendSession = friendSessions[0]; |
@@ -748,12 +764,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
748 | GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); | 764 | GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); |
749 | // TODO: You might want to send the delta to save the lookup | 765 | // TODO: You might want to send the delta to save the lookup |
750 | // on the other end!! | 766 | // on the other end!! |
751 | m_FriendsSimConnector.GrantRights(region, requester, target, myFlags, rights); | 767 | m_FriendsSimConnector.GrantRights(region, requester, friendID, myFlags, rights); |
752 | } | 768 | } |
753 | } | 769 | } |
754 | } | 770 | } |
755 | else | 771 | else |
756 | m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", target, requester); | 772 | { |
773 | m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", friendID, requester); | ||
774 | } | ||
757 | } | 775 | } |
758 | 776 | ||
759 | protected virtual FriendInfo GetFriend(FriendInfo[] friends, UUID friendID) | 777 | protected virtual FriendInfo GetFriend(FriendInfo[] friends, UUID friendID) |
@@ -797,9 +815,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
797 | ccm.CreateCallingCard(friendID, userID, UUID.Zero); | 815 | ccm.CreateCallingCard(friendID, userID, UUID.Zero); |
798 | } | 816 | } |
799 | 817 | ||
800 | |||
801 | // Update the local cache | 818 | // Update the local cache |
802 | CacheFriends(friendClient); | 819 | RecacheFriends(friendClient); |
803 | 820 | ||
804 | // we're done | 821 | // we're done |
805 | return true; | 822 | return true; |
@@ -832,7 +849,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
832 | // the friend in this sim as root agent | 849 | // the friend in this sim as root agent |
833 | friendClient.SendTerminateFriend(exfriendID); | 850 | friendClient.SendTerminateFriend(exfriendID); |
834 | // update local cache | 851 | // update local cache |
835 | CacheFriends(friendClient); | 852 | RecacheFriends(friendClient); |
836 | // we're done | 853 | // we're done |
837 | return true; | 854 | return true; |
838 | } | 855 | } |
@@ -891,20 +908,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
891 | #endregion | 908 | #endregion |
892 | 909 | ||
893 | #region Get / Set friends in several flavours | 910 | #region Get / Set friends in several flavours |
894 | /// <summary> | 911 | |
895 | /// Get friends from local cache only | 912 | public FriendInfo[] GetFriendsFromCache(UUID userID) |
896 | /// </summary> | ||
897 | /// <param name="agentID"></param> | ||
898 | /// <returns> | ||
899 | /// An empty array if the user has no friends or friends have not been cached. | ||
900 | /// </returns> | ||
901 | protected FriendInfo[] GetFriends(UUID agentID) | ||
902 | { | 913 | { |
903 | UserFriendData friendsData; | 914 | UserFriendData friendsData; |
904 | 915 | ||
905 | lock (m_Friends) | 916 | lock (m_Friends) |
906 | { | 917 | { |
907 | if (m_Friends.TryGetValue(agentID, out friendsData)) | 918 | if (m_Friends.TryGetValue(userID, out friendsData)) |
908 | return friendsData.Friends; | 919 | return friendsData.Friends; |
909 | } | 920 | } |
910 | 921 | ||
@@ -922,23 +933,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
922 | // Update local cache | 933 | // Update local cache |
923 | lock (m_Friends) | 934 | lock (m_Friends) |
924 | { | 935 | { |
925 | FriendInfo[] friends = GetFriends(friendID); | 936 | FriendInfo[] friends = GetFriendsFromCache(friendID); |
926 | FriendInfo finfo = GetFriend(friends, userID); | 937 | FriendInfo finfo = GetFriend(friends, userID); |
927 | finfo.TheirFlags = rights; | 938 | finfo.TheirFlags = rights; |
928 | } | 939 | } |
929 | } | 940 | } |
930 | 941 | ||
931 | protected virtual FriendInfo[] GetFriendsFromService(IClientAPI client) | 942 | public virtual FriendInfo[] GetFriendsFromService(IClientAPI client) |
932 | { | 943 | { |
933 | return FriendsService.GetFriends(client.AgentId); | 944 | return FriendsService.GetFriends(client.AgentId); |
934 | } | 945 | } |
935 | 946 | ||
936 | /// <summary> | 947 | protected void RecacheFriends(IClientAPI client) |
937 | /// Are friends cached on this simulator for a particular user? | 948 | { |
938 | /// </summary> | 949 | // FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event |
939 | /// <param name="userID"></param> | 950 | // is on the critical path for transferring an avatar from one region to another. |
940 | /// <returns></returns> | 951 | UUID agentID = client.AgentId; |
941 | protected bool AreFriendsCached(UUID userID) | 952 | lock (m_Friends) |
953 | { | ||
954 | UserFriendData friendsData; | ||
955 | if (m_Friends.TryGetValue(agentID, out friendsData)) | ||
956 | friendsData.Friends = GetFriendsFromService(client); | ||
957 | } | ||
958 | } | ||
959 | |||
960 | public bool AreFriendsCached(UUID userID) | ||
942 | { | 961 | { |
943 | lock (m_Friends) | 962 | lock (m_Friends) |
944 | return m_Friends.ContainsKey(userID); | 963 | return m_Friends.ContainsKey(userID); |
@@ -957,8 +976,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
957 | 976 | ||
958 | protected virtual void StoreFriendships(UUID agentID, UUID friendID) | 977 | protected virtual void StoreFriendships(UUID agentID, UUID friendID) |
959 | { | 978 | { |
960 | FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1); | 979 | FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), (int)FriendRights.CanSeeOnline); |
961 | FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1); | 980 | FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), (int)FriendRights.CanSeeOnline); |
962 | } | 981 | } |
963 | 982 | ||
964 | protected virtual bool DeleteFriendship(UUID agentID, UUID exfriendID) | 983 | protected virtual bool DeleteFriendship(UUID agentID, UUID exfriendID) |
@@ -969,61 +988,5 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
969 | } | 988 | } |
970 | 989 | ||
971 | #endregion | 990 | #endregion |
972 | |||
973 | protected void HandleFriendsShowCacheCommand(string module, string[] cmd) | ||
974 | { | ||
975 | if (cmd.Length != 5) | ||
976 | { | ||
977 | MainConsole.Instance.OutputFormat("Usage: friends show cache [<first-name> <last-name>]"); | ||
978 | return; | ||
979 | } | ||
980 | |||
981 | string firstName = cmd[3]; | ||
982 | string lastName = cmd[4]; | ||
983 | |||
984 | IUserManagement umModule = m_Scenes[0].RequestModuleInterface<IUserManagement>(); | ||
985 | UUID userId = umModule.GetUserIdByName(firstName, lastName); | ||
986 | |||
987 | // UserAccount ua | ||
988 | // = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, firstName, lastName); | ||
989 | |||
990 | if (userId == UUID.Zero) | ||
991 | { | ||
992 | MainConsole.Instance.OutputFormat("No such user as {0} {1}", firstName, lastName); | ||
993 | return; | ||
994 | } | ||
995 | |||
996 | if (!AreFriendsCached(userId)) | ||
997 | { | ||
998 | MainConsole.Instance.OutputFormat("No friends cached on this simulator for {0} {1}", firstName, lastName); | ||
999 | return; | ||
1000 | } | ||
1001 | |||
1002 | MainConsole.Instance.OutputFormat("Cached friends for {0} {1}:", firstName, lastName); | ||
1003 | |||
1004 | MainConsole.Instance.OutputFormat("UUID\n"); | ||
1005 | |||
1006 | FriendInfo[] friends = GetFriends(userId); | ||
1007 | |||
1008 | foreach (FriendInfo friend in friends) | ||
1009 | { | ||
1010 | // MainConsole.Instance.OutputFormat(friend.PrincipalID.ToString()); | ||
1011 | |||
1012 | // string friendFirstName, friendLastName; | ||
1013 | // | ||
1014 | // UserAccount friendUa | ||
1015 | // = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friend.PrincipalID); | ||
1016 | |||
1017 | UUID friendId; | ||
1018 | string friendName; | ||
1019 | |||
1020 | if (UUID.TryParse(friend.Friend, out friendId)) | ||
1021 | friendName = umModule.GetUserName(friendId); | ||
1022 | else | ||
1023 | friendName = friend.Friend; | ||
1024 | |||
1025 | MainConsole.Instance.OutputFormat("{0} {1} {2}", friendName, friend.MyFlags, friend.TheirFlags); | ||
1026 | } | ||
1027 | } | ||
1028 | } | 991 | } |
1029 | } | 992 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index 7bc3018..9a6d277 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | |||
@@ -105,12 +105,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
105 | 105 | ||
106 | #endregion | 106 | #endregion |
107 | 107 | ||
108 | protected override void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) | 108 | protected override void OnApproveFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders) |
109 | { | 109 | { |
110 | // Update the local cache. Yes, we need to do it right here | 110 | // Update the local cache. Yes, we need to do it right here |
111 | // because the HGFriendsService placed something on the DB | 111 | // because the HGFriendsService placed something on the DB |
112 | // from under the sim | 112 | // from under the sim |
113 | base.OnApproveFriendRequest(client, agentID, friendID, callingCardFolders); | 113 | base.OnApproveFriendRequest(client, friendID, callingCardFolders); |
114 | } | 114 | } |
115 | 115 | ||
116 | protected override bool CacheFriends(IClientAPI client) | 116 | protected override bool CacheFriends(IClientAPI client) |
@@ -121,7 +121,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
121 | { | 121 | { |
122 | UUID agentID = client.AgentId; | 122 | UUID agentID = client.AgentId; |
123 | // we do this only for the root agent | 123 | // we do this only for the root agent |
124 | if (!client.SceneAgent.IsChildAgent) | 124 | if (m_Friends[agentID].Refcount == 1) |
125 | { | 125 | { |
126 | // We need to preload the user management cache with the names | 126 | // We need to preload the user management cache with the names |
127 | // of foreign friends, just like we do with SOPs' creators | 127 | // of foreign friends, just like we do with SOPs' creators |
@@ -163,7 +163,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
163 | UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId); | 163 | UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId); |
164 | if (account == null) // foreign | 164 | if (account == null) // foreign |
165 | { | 165 | { |
166 | FriendInfo[] friends = GetFriends(client.AgentId); | 166 | FriendInfo[] friends = GetFriendsFromCache(client.AgentId); |
167 | foreach (FriendInfo f in friends) | 167 | foreach (FriendInfo f in friends) |
168 | { | 168 | { |
169 | client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags); | 169 | client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags); |
@@ -300,8 +300,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
300 | return null; | 300 | return null; |
301 | } | 301 | } |
302 | 302 | ||
303 | 303 | public override FriendInfo[] GetFriendsFromService(IClientAPI client) | |
304 | protected override FriendInfo[] GetFriendsFromService(IClientAPI client) | ||
305 | { | 304 | { |
306 | // m_log.DebugFormat("[HGFRIENDS MODULE]: Entering GetFriendsFromService for {0}", client.Name); | 305 | // m_log.DebugFormat("[HGFRIENDS MODULE]: Entering GetFriendsFromService for {0}", client.Name); |
307 | Boolean agentIsLocal = true; | 306 | Boolean agentIsLocal = true; |
@@ -346,7 +345,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
346 | 345 | ||
347 | if (agentIsLocal) // agent is local, friend is foreigner | 346 | if (agentIsLocal) // agent is local, friend is foreigner |
348 | { | 347 | { |
349 | FriendInfo[] finfos = GetFriends(agentID); | 348 | FriendInfo[] finfos = GetFriendsFromCache(agentID); |
350 | FriendInfo finfo = GetFriend(finfos, friendID); | 349 | FriendInfo finfo = GetFriend(finfos, friendID); |
351 | if (finfo != null) | 350 | if (finfo != null) |
352 | { | 351 | { |
@@ -426,14 +425,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
426 | agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode); | 425 | agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode); |
427 | agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); | 426 | agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); |
428 | agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); | 427 | agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); |
429 | CacheFriends(agentClient); | 428 | RecacheFriends(agentClient); |
430 | } | 429 | } |
431 | if (friendClient != null) | 430 | if (friendClient != null) |
432 | { | 431 | { |
433 | friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode); | 432 | friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode); |
434 | friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit); | 433 | friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit); |
435 | friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); | 434 | friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); |
436 | CacheFriends(friendClient); | 435 | RecacheFriends(friendClient); |
437 | } | 436 | } |
438 | 437 | ||
439 | m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}", | 438 | m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}", |
@@ -453,7 +452,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
453 | bool confirming = false; | 452 | bool confirming = false; |
454 | if (friendUUI == string.Empty) | 453 | if (friendUUI == string.Empty) |
455 | { | 454 | { |
456 | finfos = GetFriends(agentID); | 455 | finfos = GetFriendsFromCache(agentID); |
457 | foreach (FriendInfo finfo in finfos) | 456 | foreach (FriendInfo finfo in finfos) |
458 | { | 457 | { |
459 | if (finfo.TheirFlags == -1) | 458 | if (finfo.TheirFlags == -1) |
@@ -546,7 +545,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
546 | // Delete any previous friendship relations | 545 | // Delete any previous friendship relations |
547 | FriendInfo[] finfos = null; | 546 | FriendInfo[] finfos = null; |
548 | FriendInfo f = null; | 547 | FriendInfo f = null; |
549 | finfos = GetFriends(a1); | 548 | finfos = GetFriendsFromCache(a1); |
550 | if (finfos != null) | 549 | if (finfos != null) |
551 | { | 550 | { |
552 | f = GetFriend(finfos, a2); | 551 | f = GetFriend(finfos, a2); |
@@ -558,7 +557,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
558 | } | 557 | } |
559 | } | 558 | } |
560 | 559 | ||
561 | finfos = GetFriends(a2); | 560 | finfos = GetFriendsFromCache(a2); |
562 | if (finfos != null) | 561 | if (finfos != null) |
563 | { | 562 | { |
564 | f = GetFriend(finfos, a1); | 563 | f = GetFriend(finfos, a1); |
@@ -595,7 +594,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
595 | if (agentIsLocal) // agent is local, 'friend' is foreigner | 594 | if (agentIsLocal) // agent is local, 'friend' is foreigner |
596 | { | 595 | { |
597 | // We need to look for its information in the friends list itself | 596 | // We need to look for its information in the friends list itself |
598 | FriendInfo[] finfos = GetFriends(agentID); | 597 | FriendInfo[] finfos = GetFriendsFromCache(agentID); |
599 | FriendInfo finfo = GetFriend(finfos, exfriendID); | 598 | FriendInfo finfo = GetFriend(finfos, exfriendID); |
600 | if (finfo != null) | 599 | if (finfo != null) |
601 | { | 600 | { |
@@ -639,7 +638,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
639 | private string GetUUI(UUID localUser, UUID foreignUser) | 638 | private string GetUUI(UUID localUser, UUID foreignUser) |
640 | { | 639 | { |
641 | // Let's see if the user is here by any chance | 640 | // Let's see if the user is here by any chance |
642 | FriendInfo[] finfos = GetFriends(localUser); | 641 | FriendInfo[] finfos = GetFriendsFromCache(localUser); |
643 | if (finfos != EMPTY_FRIENDS) // friend is here, cool | 642 | if (finfos != EMPTY_FRIENDS) // friend is here, cool |
644 | { | 643 | { |
645 | FriendInfo finfo = GetFriend(finfos, foreignUser); | 644 | FriendInfo finfo = GetFriend(finfos, foreignUser); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs index 682fbab..45b4264 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs | |||
@@ -30,6 +30,7 @@ using System.Collections.Generic; | |||
30 | using Nini.Config; | 30 | using Nini.Config; |
31 | using NUnit.Framework; | 31 | using NUnit.Framework; |
32 | using OpenMetaverse; | 32 | using OpenMetaverse; |
33 | using OpenSim.Data.Null; | ||
33 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
34 | using OpenSim.Region.CoreModules.Avatar.Friends; | 35 | using OpenSim.Region.CoreModules.Avatar.Friends; |
35 | using OpenSim.Region.Framework.Scenes; | 36 | using OpenSim.Region.Framework.Scenes; |
@@ -44,9 +45,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests | |||
44 | private FriendsModule m_fm; | 45 | private FriendsModule m_fm; |
45 | private TestScene m_scene; | 46 | private TestScene m_scene; |
46 | 47 | ||
48 | [TestFixtureSetUp] | ||
49 | public void FixtureInit() | ||
50 | { | ||
51 | // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread. | ||
52 | Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest; | ||
53 | } | ||
54 | |||
55 | [TestFixtureTearDown] | ||
56 | public void TearDown() | ||
57 | { | ||
58 | // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple | ||
59 | // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression | ||
60 | // tests really shouldn't). | ||
61 | Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; | ||
62 | } | ||
63 | |||
47 | [SetUp] | 64 | [SetUp] |
48 | public void Init() | 65 | public void Init() |
49 | { | 66 | { |
67 | // We must clear friends data between tests since Data.Null holds it in static properties. This is necessary | ||
68 | // so that different services and simulator can share the data in standalone mode. This is pretty horrible | ||
69 | // effectively the statics are global variables. | ||
70 | NullFriendsData.Clear(); | ||
71 | |||
50 | IConfigSource config = new IniConfigSource(); | 72 | IConfigSource config = new IniConfigSource(); |
51 | config.AddConfig("Modules"); | 73 | config.AddConfig("Modules"); |
52 | // Not strictly necessary since FriendsModule assumes it is the default (!) | 74 | // Not strictly necessary since FriendsModule assumes it is the default (!) |
@@ -62,7 +84,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests | |||
62 | } | 84 | } |
63 | 85 | ||
64 | [Test] | 86 | [Test] |
65 | public void TestNoFriends() | 87 | public void TestLoginWithNoFriends() |
66 | { | 88 | { |
67 | TestHelpers.InMethod(); | 89 | TestHelpers.InMethod(); |
68 | // log4net.Config.XmlConfigurator.Configure(); | 90 | // log4net.Config.XmlConfigurator.Configure(); |
@@ -76,6 +98,76 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests | |||
76 | } | 98 | } |
77 | 99 | ||
78 | [Test] | 100 | [Test] |
101 | public void TestLoginWithOfflineFriends() | ||
102 | { | ||
103 | TestHelpers.InMethod(); | ||
104 | // log4net.Config.XmlConfigurator.Configure(); | ||
105 | |||
106 | UUID user1Id = TestHelpers.ParseTail(0x1); | ||
107 | UUID user2Id = TestHelpers.ParseTail(0x2); | ||
108 | |||
109 | // UserAccountHelpers.CreateUserWithInventory(m_scene, user1Id); | ||
110 | // UserAccountHelpers.CreateUserWithInventory(m_scene, user2Id); | ||
111 | // | ||
112 | // m_fm.AddFriendship(user1Id, user2Id); | ||
113 | |||
114 | ScenePresence sp1 = SceneHelpers.AddScenePresence(m_scene, user1Id); | ||
115 | ScenePresence sp2 = SceneHelpers.AddScenePresence(m_scene, user2Id); | ||
116 | |||
117 | m_fm.AddFriendship(sp1.ControllingClient, user2Id); | ||
118 | |||
119 | // Not necessary for this test. CanSeeOnline is automatically granted. | ||
120 | // m_fm.GrantRights(sp1.ControllingClient, user2Id, (int)FriendRights.CanSeeOnline); | ||
121 | |||
122 | // We must logout from the client end so that the presence service is correctly updated by the presence | ||
123 | // detector. This is listening to the OnConnectionClosed event on the client. | ||
124 | ((TestClient)sp1.ControllingClient).Logout(); | ||
125 | ((TestClient)sp2.ControllingClient).Logout(); | ||
126 | // m_scene.RemoveClient(sp1.UUID, true); | ||
127 | // m_scene.RemoveClient(sp2.UUID, true); | ||
128 | |||
129 | ScenePresence sp1Redux = SceneHelpers.AddScenePresence(m_scene, user1Id); | ||
130 | |||
131 | // We don't expect to receive notifications of offline friends on login, just online. | ||
132 | Assert.That(((TestClient)sp1Redux.ControllingClient).ReceivedOfflineNotifications.Count, Is.EqualTo(0)); | ||
133 | Assert.That(((TestClient)sp1Redux.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(0)); | ||
134 | } | ||
135 | |||
136 | [Test] | ||
137 | public void TestLoginWithOnlineFriends() | ||
138 | { | ||
139 | TestHelpers.InMethod(); | ||
140 | // log4net.Config.XmlConfigurator.Configure(); | ||
141 | |||
142 | UUID user1Id = TestHelpers.ParseTail(0x1); | ||
143 | UUID user2Id = TestHelpers.ParseTail(0x2); | ||
144 | |||
145 | // UserAccountHelpers.CreateUserWithInventory(m_scene, user1Id); | ||
146 | // UserAccountHelpers.CreateUserWithInventory(m_scene, user2Id); | ||
147 | // | ||
148 | // m_fm.AddFriendship(user1Id, user2Id); | ||
149 | |||
150 | ScenePresence sp1 = SceneHelpers.AddScenePresence(m_scene, user1Id); | ||
151 | ScenePresence sp2 = SceneHelpers.AddScenePresence(m_scene, user2Id); | ||
152 | |||
153 | m_fm.AddFriendship(sp1.ControllingClient, user2Id); | ||
154 | |||
155 | // Not necessary for this test. CanSeeOnline is automatically granted. | ||
156 | // m_fm.GrantRights(sp1.ControllingClient, user2Id, (int)FriendRights.CanSeeOnline); | ||
157 | |||
158 | // We must logout from the client end so that the presence service is correctly updated by the presence | ||
159 | // detector. This is listening to the OnConnectionClosed event on the client. | ||
160 | // ((TestClient)sp1.ControllingClient).Logout(); | ||
161 | ((TestClient)sp2.ControllingClient).Logout(); | ||
162 | // m_scene.RemoveClient(user2Id, true); | ||
163 | |||
164 | ScenePresence sp2Redux = SceneHelpers.AddScenePresence(m_scene, user2Id); | ||
165 | |||
166 | Assert.That(((TestClient)sp2Redux.ControllingClient).ReceivedOfflineNotifications.Count, Is.EqualTo(0)); | ||
167 | Assert.That(((TestClient)sp2Redux.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(1)); | ||
168 | } | ||
169 | |||
170 | [Test] | ||
79 | public void TestAddFriendshipWhileOnline() | 171 | public void TestAddFriendshipWhileOnline() |
80 | { | 172 | { |
81 | TestHelpers.InMethod(); | 173 | TestHelpers.InMethod(); |