aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS.txt1
-rw-r--r--OpenSim/Data/MSSQL/MSSQLManager.cs5
-rw-r--r--OpenSim/Data/Null/NullFriendsData.cs74
-rw-r--r--OpenSim/Data/Null/NullPresenceData.cs1
-rw-r--r--OpenSim/Data/Tests/RegionTests.cs8
-rw-r--r--OpenSim/Framework/ICallingCardModule.cs13
-rw-r--r--OpenSim/Framework/IClientAPI.cs6
-rw-r--r--OpenSim/Framework/Servers/VersionInfo.cs3
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs13
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs31
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs243
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs27
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs94
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs24
-rw-r--r--OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs9
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs10
-rw-r--r--OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/ICallingCardModule.cs40
-rw-r--r--OpenSim/Region/Framework/Interfaces/IFriendsModule.cs43
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs12
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs10
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs88
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs189
-rw-r--r--OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs2
-rw-r--r--OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs338
-rw-r--r--OpenSim/Services/Interfaces/IFriendsService.cs10
-rw-r--r--OpenSim/Services/PresenceService/PresenceService.cs7
-rw-r--r--OpenSim/Tests/Common/Helpers/SceneHelpers.cs12
-rw-r--r--OpenSim/Tests/Common/Mock/TestClient.cs43
-rw-r--r--prebuild.xml3
34 files changed, 947 insertions, 428 deletions
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
index 089d2f5..287073b 100644
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -71,6 +71,7 @@ what it is today.
71* CharlieO 71* CharlieO
72* ChrisDown 72* ChrisDown
73* Chris Yeoh (IBM) 73* Chris Yeoh (IBM)
74* controlbreak
74* coyled 75* coyled
75* Daedius 76* Daedius
76* Dong Jun Lan (IBM) 77* Dong Jun Lan (IBM)
diff --git a/OpenSim/Data/MSSQL/MSSQLManager.cs b/OpenSim/Data/MSSQL/MSSQLManager.cs
index 575fd21..62c38d3 100644
--- a/OpenSim/Data/MSSQL/MSSQLManager.cs
+++ b/OpenSim/Data/MSSQL/MSSQLManager.cs
@@ -104,6 +104,11 @@ namespace OpenSim.Data.MSSQL
104 { 104 {
105 return SqlDbType.BigInt; 105 return SqlDbType.BigInt;
106 } 106 }
107 if (type == typeof(DateTime))
108 {
109 return SqlDbType.DateTime;
110 }
111
107 return SqlDbType.VarChar; 112 return SqlDbType.VarChar;
108 } 113 }
109 114
diff --git a/OpenSim/Data/Null/NullFriendsData.cs b/OpenSim/Data/Null/NullFriendsData.cs
index 0a4b242..473999f 100644
--- a/OpenSim/Data/Null/NullFriendsData.cs
+++ b/OpenSim/Data/Null/NullFriendsData.cs
@@ -28,6 +28,9 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Reflection;
32using System.Threading;
33using log4net;
31using OpenMetaverse; 34using OpenMetaverse;
32using OpenSim.Framework; 35using OpenSim.Framework;
33using OpenSim.Data; 36using OpenSim.Data;
@@ -36,12 +39,26 @@ namespace OpenSim.Data.Null
36{ 39{
37 public class NullFriendsData : IFriendsData 40 public class NullFriendsData : IFriendsData
38 { 41 {
42// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43
39 private static List<FriendsData> m_Data = new List<FriendsData>(); 44 private static List<FriendsData> m_Data = new List<FriendsData>();
40 45
41 public NullFriendsData(string connectionString, string realm) 46 public NullFriendsData(string connectionString, string realm)
42 { 47 {
43 } 48 }
44 49
50 /// <summary>
51 /// Clear all friends data
52 /// </summary>
53 /// <remarks>
54 /// This is required by unit tests to clear the static data between test runs.
55 /// </remarks>
56 public static void Clear()
57 {
58 lock (m_Data)
59 m_Data.Clear();
60 }
61
45 public FriendsData[] GetFriends(UUID principalID) 62 public FriendsData[] GetFriends(UUID principalID)
46 { 63 {
47 return GetFriends(principalID.ToString()); 64 return GetFriends(principalID.ToString());
@@ -56,20 +73,30 @@ namespace OpenSim.Data.Null
56 /// <returns></returns> 73 /// <returns></returns>
57 public FriendsData[] GetFriends(string userID) 74 public FriendsData[] GetFriends(string userID)
58 { 75 {
59 List<FriendsData> lst = m_Data.FindAll(fdata => 76 lock (m_Data)
60 { 77 {
61 return fdata.PrincipalID == userID.ToString(); 78 List<FriendsData> lst = m_Data.FindAll(fdata =>
62 });
63
64 if (lst != null)
65 {
66 lst.ForEach(f =>
67 { 79 {
68 FriendsData f2 = m_Data.Find(candidateF2 => f.Friend == candidateF2.PrincipalID); 80 return fdata.PrincipalID == userID.ToString();
69 if (f2 != null) { f.Data["TheirFlags"] = f2.Data["Flags"]; }
70 }); 81 });
71 82
72 return lst.ToArray(); 83 if (lst != null)
84 {
85 lst.ForEach(f =>
86 {
87 FriendsData f2 = m_Data.Find(candidateF2 => f.Friend == candidateF2.PrincipalID);
88 if (f2 != null)
89 f.Data["TheirFlags"] = f2.Data["Flags"];
90
91 // m_log.DebugFormat(
92 // "[NULL FRIENDS DATA]: Got {0} {1} {2} for {3}",
93 // f.Friend, f.Data["Flags"], f2 != null ? f.Data["TheirFlags"] : "not found!", f.PrincipalID);
94 });
95
96 // m_log.DebugFormat("[NULL FRIENDS DATA]: Got {0} friends for {1}", lst.Count, userID);
97
98 return lst.ToArray();
99 }
73 } 100 }
74 101
75 return new FriendsData[0]; 102 return new FriendsData[0];
@@ -80,7 +107,11 @@ namespace OpenSim.Data.Null
80 if (data == null) 107 if (data == null)
81 return false; 108 return false;
82 109
83 m_Data.Add(data); 110// m_log.DebugFormat(
111// "[NULL FRIENDS DATA]: Storing {0} {1} {2}", data.PrincipalID, data.Friend, data.Data["Flags"]);
112
113 lock (m_Data)
114 m_Data.Add(data);
84 115
85 return true; 116 return true;
86 } 117 }
@@ -92,14 +123,21 @@ namespace OpenSim.Data.Null
92 123
93 public bool Delete(string userID, string friendID) 124 public bool Delete(string userID, string friendID)
94 { 125 {
95 List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); }); 126 lock (m_Data)
96 if (lst != null)
97 { 127 {
98 FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; }); 128 List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); });
99 if (friendID != null) 129 if (lst != null)
100 { 130 {
101 m_Data.Remove(friend); 131 FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; });
102 return true; 132 if (friendID != null)
133 {
134 // m_log.DebugFormat(
135 // "[NULL FRIENDS DATA]: Deleting friend {0} {1} for {2}",
136 // friend.Friend, friend.Data["Flags"], friend.PrincipalID);
137
138 m_Data.Remove(friend);
139 return true;
140 }
103 } 141 }
104 } 142 }
105 143
diff --git a/OpenSim/Data/Null/NullPresenceData.cs b/OpenSim/Data/Null/NullPresenceData.cs
index 91f1cc5..c06c223 100644
--- a/OpenSim/Data/Null/NullPresenceData.cs
+++ b/OpenSim/Data/Null/NullPresenceData.cs
@@ -110,7 +110,6 @@ namespace OpenSim.Data.Null
110 return false; 110 return false;
111 } 111 }
112 112
113
114 public PresenceData[] Get(string field, string data) 113 public PresenceData[] Get(string field, string data)
115 { 114 {
116 if (Instance != this) 115 if (Instance != this)
diff --git a/OpenSim/Data/Tests/RegionTests.cs b/OpenSim/Data/Tests/RegionTests.cs
index 1d806fc..1f03ec5 100644
--- a/OpenSim/Data/Tests/RegionTests.cs
+++ b/OpenSim/Data/Tests/RegionTests.cs
@@ -244,10 +244,10 @@ namespace OpenSim.Data.Tests
244 SceneObjectPart[] newparts = newsog.Parts; 244 SceneObjectPart[] newparts = newsog.Parts;
245 Assert.That(newparts.Length,Is.EqualTo(4), "Assert.That(newparts.Length,Is.EqualTo(4))"); 245 Assert.That(newparts.Length,Is.EqualTo(4), "Assert.That(newparts.Length,Is.EqualTo(4))");
246 246
247 Assert.That(newsog.HasChildPrim(tmp0), "Assert.That(newsog.HasChildPrim(tmp0))"); 247 Assert.That(newsog.ContainsPart(tmp0), "Assert.That(newsog.ContainsPart(tmp0))");
248 Assert.That(newsog.HasChildPrim(tmp1), "Assert.That(newsog.HasChildPrim(tmp1))"); 248 Assert.That(newsog.ContainsPart(tmp1), "Assert.That(newsog.ContainsPart(tmp1))");
249 Assert.That(newsog.HasChildPrim(tmp2), "Assert.That(newsog.HasChildPrim(tmp2))"); 249 Assert.That(newsog.ContainsPart(tmp2), "Assert.That(newsog.ContainsPart(tmp2))");
250 Assert.That(newsog.HasChildPrim(tmp3), "Assert.That(newsog.HasChildPrim(tmp3))"); 250 Assert.That(newsog.ContainsPart(tmp3), "Assert.That(newsog.ContainsPart(tmp3))");
251 } 251 }
252 252
253 [Test] 253 [Test]
diff --git a/OpenSim/Framework/ICallingCardModule.cs b/OpenSim/Framework/ICallingCardModule.cs
deleted file mode 100644
index 17e6de35..0000000
--- a/OpenSim/Framework/ICallingCardModule.cs
+++ /dev/null
@@ -1,13 +0,0 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using OpenMetaverse;
5using OpenSim.Framework;
6
7namespace OpenSim.Framework
8{
9 public interface ICallingCardModule
10 {
11 UUID CreateCallingCard(UUID userID, UUID creatorID, UUID folderID);
12 }
13}
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 881f815..2be78da 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -301,9 +301,9 @@ namespace OpenSim.Framework
301 public delegate void ConfirmXfer(IClientAPI remoteClient, ulong xferID, uint packetID); 301 public delegate void ConfirmXfer(IClientAPI remoteClient, ulong xferID, uint packetID);
302 302
303 public delegate void FriendActionDelegate( 303 public delegate void FriendActionDelegate(
304 IClientAPI remoteClient, UUID agentID, UUID transactionID, List<UUID> callingCardFolders); 304 IClientAPI remoteClient, UUID transactionID, List<UUID> callingCardFolders);
305 305
306 public delegate void FriendshipTermination(IClientAPI remoteClient, UUID agentID, UUID ExID); 306 public delegate void FriendshipTermination(IClientAPI remoteClient, UUID ExID);
307 307
308 public delegate void MoneyTransferRequest( 308 public delegate void MoneyTransferRequest(
309 UUID sourceID, UUID destID, int amount, int transactionType, string description); 309 UUID sourceID, UUID destID, int amount, int transactionType, string description);
@@ -464,7 +464,7 @@ namespace OpenSim.Framework
464 public delegate void AvatarNotesUpdate(IClientAPI client, UUID targetID, string notes); 464 public delegate void AvatarNotesUpdate(IClientAPI client, UUID targetID, string notes);
465 public delegate void MuteListRequest(IClientAPI client, uint muteCRC); 465 public delegate void MuteListRequest(IClientAPI client, uint muteCRC);
466 public delegate void AvatarInterestUpdate(IClientAPI client, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages); 466 public delegate void AvatarInterestUpdate(IClientAPI client, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages);
467 public delegate void GrantUserFriendRights(IClientAPI client, UUID requester, UUID target, int rights); 467 public delegate void GrantUserFriendRights(IClientAPI client, UUID target, int rights);
468 public delegate void PlacesQuery(UUID QueryID, UUID TransactionID, string QueryText, uint QueryFlags, byte Category, string SimName, IClientAPI client); 468 public delegate void PlacesQuery(UUID QueryID, UUID TransactionID, string QueryText, uint QueryFlags, byte Category, string SimName, IClientAPI client);
469 469
470 public delegate void AgentFOV(IClientAPI client, float verticalAngle); 470 public delegate void AgentFOV(IClientAPI client, float verticalAngle);
diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs
index 63ec257..016a174 100644
--- a/OpenSim/Framework/Servers/VersionInfo.cs
+++ b/OpenSim/Framework/Servers/VersionInfo.cs
@@ -39,7 +39,8 @@ namespace OpenSim
39 RC1, 39 RC1,
40 RC2, 40 RC2,
41 Release, 41 Release,
42 Post_Fixes 42 Post_Fixes,
43 Extended
43 } 44 }
44 45
45 public static string Version 46 public static string Version
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 54fc7f4..0496b7d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -5913,7 +5913,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5913 // My guess is this is the folder to stick the calling card into 5913 // My guess is this is the folder to stick the calling card into
5914 List<UUID> callingCardFolders = new List<UUID>(); 5914 List<UUID> callingCardFolders = new List<UUID>();
5915 5915
5916 UUID agentID = afriendpack.AgentData.AgentID;
5917 UUID transactionID = afriendpack.TransactionBlock.TransactionID; 5916 UUID transactionID = afriendpack.TransactionBlock.TransactionID;
5918 5917
5919 for (int fi = 0; fi < afriendpack.FolderData.Length; fi++) 5918 for (int fi = 0; fi < afriendpack.FolderData.Length; fi++)
@@ -5924,10 +5923,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5924 FriendActionDelegate handlerApproveFriendRequest = OnApproveFriendRequest; 5923 FriendActionDelegate handlerApproveFriendRequest = OnApproveFriendRequest;
5925 if (handlerApproveFriendRequest != null) 5924 if (handlerApproveFriendRequest != null)
5926 { 5925 {
5927 handlerApproveFriendRequest(this, agentID, transactionID, callingCardFolders); 5926 handlerApproveFriendRequest(this, transactionID, callingCardFolders);
5928 } 5927 }
5929 return true;
5930 5928
5929 return true;
5931 } 5930 }
5932 5931
5933 private bool HandlerDeclineFriendship(IClientAPI sender, Packet Pack) 5932 private bool HandlerDeclineFriendship(IClientAPI sender, Packet Pack)
@@ -5946,7 +5945,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5946 if (OnDenyFriendRequest != null) 5945 if (OnDenyFriendRequest != null)
5947 { 5946 {
5948 OnDenyFriendRequest(this, 5947 OnDenyFriendRequest(this,
5949 dfriendpack.AgentData.AgentID,
5950 dfriendpack.TransactionBlock.TransactionID, 5948 dfriendpack.TransactionBlock.TransactionID,
5951 null); 5949 null);
5952 } 5950 }
@@ -5966,14 +5964,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5966 } 5964 }
5967 #endregion 5965 #endregion
5968 5966
5969 UUID listOwnerAgentID = tfriendpack.AgentData.AgentID;
5970 UUID exFriendID = tfriendpack.ExBlock.OtherID; 5967 UUID exFriendID = tfriendpack.ExBlock.OtherID;
5971 FriendshipTermination TerminateFriendshipHandler = OnTerminateFriendship; 5968 FriendshipTermination TerminateFriendshipHandler = OnTerminateFriendship;
5972 if (TerminateFriendshipHandler != null) 5969 if (TerminateFriendshipHandler != null)
5973 { 5970 {
5974 TerminateFriendshipHandler(this, listOwnerAgentID, exFriendID); 5971 TerminateFriendshipHandler(this, exFriendID);
5975 return true; 5972 return true;
5976 } 5973 }
5974
5977 return false; 5975 return false;
5978 } 5976 }
5979 5977
@@ -11378,12 +11376,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11378 return true; 11376 return true;
11379 } 11377 }
11380 #endregion 11378 #endregion
11379
11381 GrantUserFriendRights GrantUserRightsHandler = OnGrantUserRights; 11380 GrantUserFriendRights GrantUserRightsHandler = OnGrantUserRights;
11382 if (GrantUserRightsHandler != null) 11381 if (GrantUserRightsHandler != null)
11383 GrantUserRightsHandler(this, 11382 GrantUserRightsHandler(this,
11384 GrantUserRights.AgentData.AgentID,
11385 GrantUserRights.Rights[0].AgentRelated, 11383 GrantUserRights.Rights[0].AgentRelated,
11386 GrantUserRights.Rights[0].RelatedRights); 11384 GrantUserRights.Rights[0].RelatedRights);
11385
11387 return true; 11386 return true;
11388 } 11387 }
11389 11388
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 @@
1using 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
28using System;
2using System.Collections.Generic; 29using System.Collections.Generic;
3using System.Reflection; 30using System.Reflection;
4using log4net; 31using log4net;
@@ -10,7 +37,7 @@ using OpenSim.Region.Framework.Scenes;
10using OpenSim.Services.Interfaces; 37using OpenSim.Services.Interfaces;
11using Mono.Addins; 38using Mono.Addins;
12 39
13namespace Careminster.XCallingCard.Modules 40namespace 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;
30using Nini.Config; 30using Nini.Config;
31using NUnit.Framework; 31using NUnit.Framework;
32using OpenMetaverse; 32using OpenMetaverse;
33using OpenSim.Data.Null;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Region.CoreModules.Avatar.Friends; 35using OpenSim.Region.CoreModules.Avatar.Friends;
35using OpenSim.Region.Framework.Scenes; 36using 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();
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 192d55f..aa99692 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -966,6 +966,30 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
966 } 966 }
967 } 967 }
968 968
969 int primcount = 0;
970 foreach (SceneObjectGroup g in objlist)
971 primcount += g.PrimCount;
972
973 if (!m_Scene.Permissions.CanRezObject(
974 primcount, remoteClient.AgentId, pos)
975 && !isAttachment)
976 {
977 // The client operates in no fail mode. It will
978 // have already removed the item from the folder
979 // if it's no copy.
980 // Put it back if it's not an attachment
981 //
982 if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!isAttachment))
983 remoteClient.SendBulkUpdateInventory(item);
984
985 ILandObject land = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y);
986 remoteClient.SendAlertMessage(string.Format(
987 "Can't rez object '{0}' at <{1:F3}, {2:F3}, {3:F3}> on parcel '{4}' in region {5}.",
988 item.Name, pos.X, pos.Y, pos.Z, land != null ? land.LandData.Name : "Unknown", m_Scene.RegionInfo.RegionName));
989
990 return false;
991 }
992
969 for (int i = 0; i < objlist.Count; i++) 993 for (int i = 0; i < objlist.Count; i++)
970 { 994 {
971 SceneObjectGroup so = objlist[i]; 995 SceneObjectGroup so = objlist[i];
diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
index ef9b4e0..176c86d 100644
--- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
@@ -319,7 +319,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
319 // Send message to avatar 319 // Send message to avatar
320 if (channel == 0) 320 if (channel == 0)
321 { 321 {
322 m_scene.SimChatBroadcast(Utils.StringToBytes(msg), ChatTypeEnum.Owner, 0, pos, name, id, false); 322 m_scene.SimChatBroadcast(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, false);
323 } 323 }
324 324
325 List<SceneObjectGroup> attachments = sp.GetAttachments(); 325 List<SceneObjectGroup> attachments = sp.GetAttachments();
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs
index e2e383f..ccfbf78 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs
@@ -27,14 +27,12 @@
27using System; 27using System;
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Reflection; 29using System.Reflection;
30 30using log4net;
31using OpenMetaverse;
31using OpenSim.Framework; 32using OpenSim.Framework;
32using OpenSim.Region.Framework.Scenes; 33using OpenSim.Region.Framework.Scenes;
33using OpenSim.Services.Interfaces; 34using OpenSim.Services.Interfaces;
34 35
35using OpenMetaverse;
36using log4net;
37
38namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence 36namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
39{ 37{
40 public class PresenceDetector 38 public class PresenceDetector
@@ -97,7 +95,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
97// m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); 95// m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName);
98 m_PresenceService.LogoutAgent(client.SessionId); 96 m_PresenceService.LogoutAgent(client.SessionId);
99 } 97 }
100
101 } 98 }
102 } 99 }
103} 100} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 4a654a3..82ccaf8 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -487,7 +487,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
487 return false; 487 return false;
488 } 488 }
489 489
490 protected bool IsFriendWithPerms(UUID user,UUID objectOwner) 490 protected bool IsFriendWithPerms(UUID user, UUID objectOwner)
491 { 491 {
492 if (user == UUID.Zero) 492 if (user == UUID.Zero)
493 return false; 493 return false;
@@ -495,11 +495,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
495 if (m_friendsModule == null) 495 if (m_friendsModule == null)
496 return false; 496 return false;
497 497
498 uint friendPerms = m_friendsModule.GetFriendPerms(user, objectOwner); 498 int friendPerms = m_friendsModule.GetRightsGrantedByFriend(user, objectOwner);
499 if ((friendPerms & (uint)FriendRights.CanModifyObjects) != 0) 499 return (friendPerms & (int)FriendRights.CanModifyObjects) != 0;
500 return true;
501
502 return false;
503 } 500 }
504 501
505 protected bool IsEstateManager(UUID user) 502 protected bool IsEstateManager(UUID user)
@@ -508,6 +505,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
508 505
509 return m_scene.RegionInfo.EstateSettings.IsEstateManager(user); 506 return m_scene.RegionInfo.EstateSettings.IsEstateManager(user);
510 } 507 }
508
511#endregion 509#endregion
512 510
513 public bool PropagatePermissions() 511 public bool PropagatePermissions()
diff --git a/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs b/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs
index ab8e1bf..f5f35bb 100644
--- a/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs
+++ b/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs
@@ -79,7 +79,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Vegetation
79 } 79 }
80 80
81 SceneObjectGroup sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape); 81 SceneObjectGroup sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape);
82 SceneObjectPart rootPart = sceneObject.GetChildPart(sceneObject.UUID); 82 SceneObjectPart rootPart = sceneObject.GetPart(sceneObject.UUID);
83 83
84 // if grass or tree, make phantom 84 // if grass or tree, make phantom
85 //rootPart.TrimPermissions(); 85 //rootPart.TrimPermissions();
diff --git a/OpenSim/Region/Framework/Interfaces/ICallingCardModule.cs b/OpenSim/Region/Framework/Interfaces/ICallingCardModule.cs
new file mode 100644
index 0000000..69682ac
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/ICallingCardModule.cs
@@ -0,0 +1,40 @@
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
28using System;
29using System.Collections.Generic;
30using System.Text;
31using OpenMetaverse;
32using OpenSim.Framework;
33
34namespace OpenSim.Framework
35{
36 public interface ICallingCardModule
37 {
38 UUID CreateCallingCard(UUID userID, UUID creatorID, UUID folderID);
39 }
40}
diff --git a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
index 061799e..7e87006 100644
--- a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
@@ -25,15 +25,32 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System.Collections.Generic;
28using OpenMetaverse; 29using OpenMetaverse;
29using OpenSim.Framework; 30using OpenSim.Framework;
30using System.Collections.Generic; 31using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
31 32
32namespace OpenSim.Region.Framework.Interfaces 33namespace OpenSim.Region.Framework.Interfaces
33{ 34{
34 public interface IFriendsModule 35 public interface IFriendsModule
35 { 36 {
36 /// <summary> 37 /// <summary>
38 /// Are friends cached on this simulator for a particular user?
39 /// </summary>
40 /// <param name="userID"></param>
41 /// <returns></returns>
42 bool AreFriendsCached(UUID userID);
43
44 /// <summary>
45 /// Get friends from local cache only
46 /// </summary>
47 /// <param name="userID"></param>
48 /// <returns>
49 /// An empty array if the user has no friends or friends have not been cached.
50 /// </returns>
51 FriendInfo[] GetFriendsFromCache(UUID userID);
52
53 /// <summary>
37 /// Add a friendship between two users. 54 /// Add a friendship between two users.
38 /// </summary> 55 /// </summary>
39 /// <remarks> 56 /// <remarks>
@@ -55,7 +72,27 @@ namespace OpenSim.Region.Framework.Interfaces
55 /// <param name="exFriendID"></param> 72 /// <param name="exFriendID"></param>
56 void RemoveFriendship(IClientAPI client, UUID exFriendID); 73 void RemoveFriendship(IClientAPI client, UUID exFriendID);
57 74
58 uint GetFriendPerms(UUID PrincipalID, UUID FriendID); 75 /// <summary>
76 /// Get permissions granted by a friend.
77 /// </summary>
78 /// <param name="userID">The user.</param>
79 /// <param name="friendID">The friend that granted.</param>
80 /// <returns>The permissions. These come from the FriendRights enum.</returns>
81 int GetRightsGrantedByFriend(UUID userID, UUID friendID);
82
83 /// <summary>
84 /// Grant permissions for a friend.
85 /// </summary>
86 /// <remarks>
87 /// This includes giving them the ability to see when the user is online and permission to edit the user's
88 /// objects.
89 /// Granting lower permissions than the friend currently has will rescind the extra permissions.
90 /// </remarks>
91 /// <param name="remoteClient">The user granting the permissions.</param>
92 /// <param name="friendID">The friend.</param>
93 /// <param name="perms">These come from the FriendRights enum.</param>
94 void GrantRights(IClientAPI remoteClient, UUID friendID, int perms);
95
59 bool SendFriendsOnlineIfNeeded(IClientAPI client); 96 bool SendFriendsOnlineIfNeeded(IClientAPI client);
60 } 97 }
61} 98} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index cf3270d..539ca14 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1883,7 +1883,7 @@ namespace OpenSim.Region.Framework.Scenes
1883 { 1883 {
1884 AddRestoredSceneObject(group, true, true); 1884 AddRestoredSceneObject(group, true, true);
1885 EventManager.TriggerOnSceneObjectLoaded(group); 1885 EventManager.TriggerOnSceneObjectLoaded(group);
1886 SceneObjectPart rootPart = group.GetChildPart(group.UUID); 1886 SceneObjectPart rootPart = group.GetPart(group.UUID);
1887 rootPart.Flags &= ~PrimFlags.Scripted; 1887 rootPart.Flags &= ~PrimFlags.Scripted;
1888 rootPart.TrimPermissions(); 1888 rootPart.TrimPermissions();
1889 1889
@@ -2031,10 +2031,16 @@ namespace OpenSim.Region.Framework.Scenes
2031 if (Permissions.CanRezObject(1, ownerID, pos)) 2031 if (Permissions.CanRezObject(1, ownerID, pos))
2032 { 2032 {
2033 // rez ON the ground, not IN the ground 2033 // rez ON the ground, not IN the ground
2034 // pos.Z += 0.25F; The rez point should now be correct so that its not in the ground 2034 // pos.Z += 0.25F; The rez point should now be correct so that its not in the ground
2035 2035
2036 AddNewPrim(ownerID, groupID, pos, rot, shape); 2036 AddNewPrim(ownerID, groupID, pos, rot, shape);
2037 } 2037 }
2038 else
2039 {
2040 IClientAPI client = null;
2041 if (TryGetClient(ownerID, out client))
2042 client.SendAlertMessage("You cannot create objects here.");
2043 }
2038 } 2044 }
2039 2045
2040 public virtual SceneObjectGroup AddNewPrim( 2046 public virtual SceneObjectGroup AddNewPrim(
@@ -4348,7 +4354,7 @@ namespace OpenSim.Region.Framework.Scenes
4348 { 4354 {
4349 if (ent is SceneObjectGroup) 4355 if (ent is SceneObjectGroup)
4350 { 4356 {
4351 SceneObjectPart part = ((SceneObjectGroup)ent).GetChildPart(((SceneObjectGroup)ent).UUID); 4357 SceneObjectPart part = ((SceneObjectGroup)ent).GetPart(((SceneObjectGroup)ent).UUID);
4352 if (part != null) 4358 if (part != null)
4353 { 4359 {
4354 if (part.Name == cmdparams[2]) 4360 if (part.Name == cmdparams[2])
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index ccc3f32..9fdbc54 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -941,7 +941,7 @@ namespace OpenSim.Region.Framework.Scenes
941 941
942 if (sog != null) 942 if (sog != null)
943 { 943 {
944 if (sog.HasChildPrim(localID)) 944 if (sog.ContainsPart(localID))
945 { 945 {
946// m_log.DebugFormat( 946// m_log.DebugFormat(
947// "[SCENE GRAPH]: Found scene object {0} {1} {2} containing part with local id {3} in {4}. Returning.", 947// "[SCENE GRAPH]: Found scene object {0} {1} {2} containing part with local id {3} in {4}. Returning.",
@@ -969,7 +969,7 @@ namespace OpenSim.Region.Framework.Scenes
969 if (ent is SceneObjectGroup) 969 if (ent is SceneObjectGroup)
970 { 970 {
971 sog = (SceneObjectGroup)ent; 971 sog = (SceneObjectGroup)ent;
972 if (sog.HasChildPrim(localID)) 972 if (sog.ContainsPart(localID))
973 { 973 {
974 lock (SceneObjectGroupsByLocalPartID) 974 lock (SceneObjectGroupsByLocalPartID)
975 SceneObjectGroupsByLocalPartID[localID] = sog; 975 SceneObjectGroupsByLocalPartID[localID] = sog;
@@ -1007,7 +1007,7 @@ namespace OpenSim.Region.Framework.Scenes
1007 if (ent is SceneObjectGroup) 1007 if (ent is SceneObjectGroup)
1008 { 1008 {
1009 sog = (SceneObjectGroup)ent; 1009 sog = (SceneObjectGroup)ent;
1010 if (sog.HasChildPrim(fullID)) 1010 if (sog.ContainsPart(fullID))
1011 { 1011 {
1012 lock (SceneObjectGroupsByFullPartID) 1012 lock (SceneObjectGroupsByFullPartID)
1013 SceneObjectGroupsByFullPartID[fullID] = sog; 1013 SceneObjectGroupsByFullPartID[fullID] = sog;
@@ -1096,7 +1096,7 @@ namespace OpenSim.Region.Framework.Scenes
1096 SceneObjectGroup group = GetGroupByPrim(localID); 1096 SceneObjectGroup group = GetGroupByPrim(localID);
1097 if (group == null) 1097 if (group == null)
1098 return null; 1098 return null;
1099 return group.GetChildPart(localID); 1099 return group.GetPart(localID);
1100 } 1100 }
1101 1101
1102 /// <summary> 1102 /// <summary>
@@ -1143,7 +1143,7 @@ namespace OpenSim.Region.Framework.Scenes
1143 SceneObjectGroup group = GetGroupByPrim(fullID); 1143 SceneObjectGroup group = GetGroupByPrim(fullID);
1144 if (group == null) 1144 if (group == null)
1145 return null; 1145 return null;
1146 return group.GetChildPart(fullID); 1146 return group.GetPart(fullID);
1147 } 1147 }
1148 1148
1149 /// <summary> 1149 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
index f3660a5..2effa25 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
@@ -92,7 +92,7 @@ namespace OpenSim.Region.Framework.Scenes
92 92
93 UUID newItemId = (copyItemID != UUID.Zero) ? copyItemID : item.ID; 93 UUID newItemId = (copyItemID != UUID.Zero) ? copyItemID : item.ID;
94 94
95 SceneObjectPart part = GetChildPart(localID); 95 SceneObjectPart part = GetPart(localID);
96 if (part != null) 96 if (part != null)
97 { 97 {
98 TaskInventoryItem taskItem = new TaskInventoryItem(); 98 TaskInventoryItem taskItem = new TaskInventoryItem();
@@ -166,7 +166,7 @@ namespace OpenSim.Region.Framework.Scenes
166 /// <returns>null if the item does not exist</returns> 166 /// <returns>null if the item does not exist</returns>
167 public TaskInventoryItem GetInventoryItem(uint primID, UUID itemID) 167 public TaskInventoryItem GetInventoryItem(uint primID, UUID itemID)
168 { 168 {
169 SceneObjectPart part = GetChildPart(primID); 169 SceneObjectPart part = GetPart(primID);
170 if (part != null) 170 if (part != null)
171 { 171 {
172 return part.Inventory.GetInventoryItem(itemID); 172 return part.Inventory.GetInventoryItem(itemID);
@@ -190,7 +190,7 @@ namespace OpenSim.Region.Framework.Scenes
190 /// <returns>false if the item did not exist, true if the update occurred succesfully</returns> 190 /// <returns>false if the item did not exist, true if the update occurred succesfully</returns>
191 public bool UpdateInventoryItem(TaskInventoryItem item) 191 public bool UpdateInventoryItem(TaskInventoryItem item)
192 { 192 {
193 SceneObjectPart part = GetChildPart(item.ParentPartID); 193 SceneObjectPart part = GetPart(item.ParentPartID);
194 if (part != null) 194 if (part != null)
195 { 195 {
196 part.Inventory.UpdateInventoryItem(item); 196 part.Inventory.UpdateInventoryItem(item);
@@ -210,7 +210,7 @@ namespace OpenSim.Region.Framework.Scenes
210 210
211 public int RemoveInventoryItem(uint localID, UUID itemID) 211 public int RemoveInventoryItem(uint localID, UUID itemID)
212 { 212 {
213 SceneObjectPart part = GetChildPart(localID); 213 SceneObjectPart part = GetPart(localID);
214 if (part != null) 214 if (part != null)
215 { 215 {
216 int type = part.Inventory.RemoveInventoryItem(itemID); 216 int type = part.Inventory.RemoveInventoryItem(itemID);
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 90ad098..11fd721 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -412,6 +412,24 @@ namespace OpenSim.Region.Framework.Scenes
412 return m_parts.ContainsKey(partID); 412 return m_parts.ContainsKey(partID);
413 } 413 }
414 414
415 /// <summary>
416 /// Does this group contain the given part?
417 /// should be able to remove these methods once we have a entity index in scene
418 /// </summary>
419 /// <param name="localID"></param>
420 /// <returns></returns>
421 public bool ContainsPart(uint localID)
422 {
423 SceneObjectPart[] parts = m_parts.GetArray();
424 for (int i = 0; i < parts.Length; i++)
425 {
426 if (parts[i].LocalId == localID)
427 return true;
428 }
429
430 return false;
431 }
432
415 /// <value> 433 /// <value>
416 /// The root part of this scene object 434 /// The root part of this scene object
417 /// </value> 435 /// </value>
@@ -1636,7 +1654,7 @@ namespace OpenSim.Region.Framework.Scenes
1636 1654
1637 public UUID GetPartsFullID(uint localID) 1655 public UUID GetPartsFullID(uint localID)
1638 { 1656 {
1639 SceneObjectPart part = GetChildPart(localID); 1657 SceneObjectPart part = GetPart(localID);
1640 if (part != null) 1658 if (part != null)
1641 { 1659 {
1642 return part.UUID; 1660 return part.UUID;
@@ -1652,7 +1670,7 @@ namespace OpenSim.Region.Framework.Scenes
1652 } 1670 }
1653 else 1671 else
1654 { 1672 {
1655 SceneObjectPart part = GetChildPart(localId); 1673 SceneObjectPart part = GetPart(localId);
1656 OnGrabPart(part, offsetPos, remoteClient); 1674 OnGrabPart(part, offsetPos, remoteClient);
1657 } 1675 }
1658 } 1676 }
@@ -2513,8 +2531,8 @@ namespace OpenSim.Region.Framework.Scenes
2513 /// Get a part with a given UUID 2531 /// Get a part with a given UUID
2514 /// </summary> 2532 /// </summary>
2515 /// <param name="primID"></param> 2533 /// <param name="primID"></param>
2516 /// <returns>null if a child part with the primID was not found</returns> 2534 /// <returns>null if a part with the primID was not found</returns>
2517 public SceneObjectPart GetChildPart(UUID primID) 2535 public SceneObjectPart GetPart(UUID primID)
2518 { 2536 {
2519 SceneObjectPart childPart; 2537 SceneObjectPart childPart;
2520 m_parts.TryGetValue(primID, out childPart); 2538 m_parts.TryGetValue(primID, out childPart);
@@ -2525,8 +2543,8 @@ namespace OpenSim.Region.Framework.Scenes
2525 /// Get a part with a given local ID 2543 /// Get a part with a given local ID
2526 /// </summary> 2544 /// </summary>
2527 /// <param name="localID"></param> 2545 /// <param name="localID"></param>
2528 /// <returns>null if a child part with the local ID was not found</returns> 2546 /// <returns>null if a part with the local ID was not found</returns>
2529 public SceneObjectPart GetChildPart(uint localID) 2547 public SceneObjectPart GetPart(uint localID)
2530 { 2548 {
2531 SceneObjectPart[] parts = m_parts.GetArray(); 2549 SceneObjectPart[] parts = m_parts.GetArray();
2532 for (int i = 0; i < parts.Length; i++) 2550 for (int i = 0; i < parts.Length; i++)
@@ -2538,35 +2556,6 @@ namespace OpenSim.Region.Framework.Scenes
2538 return null; 2556 return null;
2539 } 2557 }
2540 2558
2541 /// <summary>
2542 /// Does this group contain the child prim
2543 /// should be able to remove these methods once we have a entity index in scene
2544 /// </summary>
2545 /// <param name="primID"></param>
2546 /// <returns></returns>
2547 public bool HasChildPrim(UUID primID)
2548 {
2549 return m_parts.ContainsKey(primID);
2550 }
2551
2552 /// <summary>
2553 /// Does this group contain the child prim
2554 /// should be able to remove these methods once we have a entity index in scene
2555 /// </summary>
2556 /// <param name="localID"></param>
2557 /// <returns></returns>
2558 public bool HasChildPrim(uint localID)
2559 {
2560 SceneObjectPart[] parts = m_parts.GetArray();
2561 for (int i = 0; i < parts.Length; i++)
2562 {
2563 if (parts[i].LocalId == localID)
2564 return true;
2565 }
2566
2567 return false;
2568 }
2569
2570 #endregion 2559 #endregion
2571 2560
2572 #region Packet Handlers 2561 #region Packet Handlers
@@ -2720,7 +2709,7 @@ namespace OpenSim.Region.Framework.Scenes
2720 /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns> 2709 /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns>
2721 public SceneObjectGroup DelinkFromGroup(uint partID, bool sendEvents) 2710 public SceneObjectGroup DelinkFromGroup(uint partID, bool sendEvents)
2722 { 2711 {
2723 SceneObjectPart linkPart = GetChildPart(partID); 2712 SceneObjectPart linkPart = GetPart(partID);
2724 2713
2725 if (linkPart != null) 2714 if (linkPart != null)
2726 { 2715 {
@@ -3024,7 +3013,7 @@ namespace OpenSim.Region.Framework.Scenes
3024 /// <param name="localID"></param> 3013 /// <param name="localID"></param>
3025 public void SetPartName(string name, uint localID) 3014 public void SetPartName(string name, uint localID)
3026 { 3015 {
3027 SceneObjectPart part = GetChildPart(localID); 3016 SceneObjectPart part = GetPart(localID);
3028 if (part != null) 3017 if (part != null)
3029 { 3018 {
3030 part.Name = name; 3019 part.Name = name;
@@ -3033,7 +3022,7 @@ namespace OpenSim.Region.Framework.Scenes
3033 3022
3034 public void SetPartDescription(string des, uint localID) 3023 public void SetPartDescription(string des, uint localID)
3035 { 3024 {
3036 SceneObjectPart part = GetChildPart(localID); 3025 SceneObjectPart part = GetPart(localID);
3037 if (part != null) 3026 if (part != null)
3038 { 3027 {
3039 part.Description = des; 3028 part.Description = des;
@@ -3042,7 +3031,7 @@ namespace OpenSim.Region.Framework.Scenes
3042 3031
3043 public void SetPartText(string text, uint localID) 3032 public void SetPartText(string text, uint localID)
3044 { 3033 {
3045 SceneObjectPart part = GetChildPart(localID); 3034 SceneObjectPart part = GetPart(localID);
3046 if (part != null) 3035 if (part != null)
3047 { 3036 {
3048 part.SetText(text); 3037 part.SetText(text);
@@ -3051,7 +3040,7 @@ namespace OpenSim.Region.Framework.Scenes
3051 3040
3052 public void SetPartText(string text, UUID partID) 3041 public void SetPartText(string text, UUID partID)
3053 { 3042 {
3054 SceneObjectPart part = GetChildPart(partID); 3043 SceneObjectPart part = GetPart(partID);
3055 if (part != null) 3044 if (part != null)
3056 { 3045 {
3057 part.SetText(text); 3046 part.SetText(text);
@@ -3060,7 +3049,7 @@ namespace OpenSim.Region.Framework.Scenes
3060 3049
3061 public string GetPartName(uint localID) 3050 public string GetPartName(uint localID)
3062 { 3051 {
3063 SceneObjectPart part = GetChildPart(localID); 3052 SceneObjectPart part = GetPart(localID);
3064 if (part != null) 3053 if (part != null)
3065 { 3054 {
3066 return part.Name; 3055 return part.Name;
@@ -3070,7 +3059,7 @@ namespace OpenSim.Region.Framework.Scenes
3070 3059
3071 public string GetPartDescription(uint localID) 3060 public string GetPartDescription(uint localID)
3072 { 3061 {
3073 SceneObjectPart part = GetChildPart(localID); 3062 SceneObjectPart part = GetPart(localID);
3074 if (part != null) 3063 if (part != null)
3075 { 3064 {
3076 return part.Description; 3065 return part.Description;
@@ -3088,7 +3077,7 @@ namespace OpenSim.Region.Framework.Scenes
3088 /// <param name="SetVolumeDetect"></param> 3077 /// <param name="SetVolumeDetect"></param>
3089 public void UpdatePrimFlags(uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVolumeDetect) 3078 public void UpdatePrimFlags(uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVolumeDetect)
3090 { 3079 {
3091 SceneObjectPart selectionPart = GetChildPart(localID); 3080 SceneObjectPart selectionPart = GetPart(localID);
3092 3081
3093 if (SetTemporary && Scene != null) 3082 if (SetTemporary && Scene != null)
3094 { 3083 {
@@ -3148,7 +3137,7 @@ namespace OpenSim.Region.Framework.Scenes
3148 3137
3149 public void UpdateExtraParam(uint localID, ushort type, bool inUse, byte[] data) 3138 public void UpdateExtraParam(uint localID, ushort type, bool inUse, byte[] data)
3150 { 3139 {
3151 SceneObjectPart part = GetChildPart(localID); 3140 SceneObjectPart part = GetPart(localID);
3152 if (part != null) 3141 if (part != null)
3153 { 3142 {
3154 part.UpdateExtraParam(type, inUse, data); 3143 part.UpdateExtraParam(type, inUse, data);
@@ -3173,7 +3162,7 @@ namespace OpenSim.Region.Framework.Scenes
3173 /// <param name="textureEntry"></param> 3162 /// <param name="textureEntry"></param>
3174 public void UpdateTextureEntry(uint localID, byte[] textureEntry) 3163 public void UpdateTextureEntry(uint localID, byte[] textureEntry)
3175 { 3164 {
3176 SceneObjectPart part = GetChildPart(localID); 3165 SceneObjectPart part = GetPart(localID);
3177 if (part != null) 3166 if (part != null)
3178 { 3167 {
3179 part.UpdateTextureEntry(textureEntry); 3168 part.UpdateTextureEntry(textureEntry);
@@ -3205,7 +3194,7 @@ namespace OpenSim.Region.Framework.Scenes
3205 /// <param name="shapeBlock"></param> 3194 /// <param name="shapeBlock"></param>
3206 public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock, uint localID) 3195 public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock, uint localID)
3207 { 3196 {
3208 SceneObjectPart part = GetChildPart(localID); 3197 SceneObjectPart part = GetPart(localID);
3209 if (part != null) 3198 if (part != null)
3210 { 3199 {
3211 part.UpdateShape(shapeBlock); 3200 part.UpdateShape(shapeBlock);
@@ -3395,7 +3384,7 @@ namespace OpenSim.Region.Framework.Scenes
3395 3384
3396 public void UpdateSinglePosition(Vector3 pos, uint localID) 3385 public void UpdateSinglePosition(Vector3 pos, uint localID)
3397 { 3386 {
3398 SceneObjectPart part = GetChildPart(localID); 3387 SceneObjectPart part = GetPart(localID);
3399 3388
3400 if (part != null) 3389 if (part != null)
3401 { 3390 {
@@ -3508,7 +3497,8 @@ namespace OpenSim.Region.Framework.Scenes
3508 /// <param name="localID"></param> 3497 /// <param name="localID"></param>
3509 public void UpdateSingleRotation(Quaternion rot, uint localID) 3498 public void UpdateSingleRotation(Quaternion rot, uint localID)
3510 { 3499 {
3511 SceneObjectPart part = GetChildPart(localID); 3500 SceneObjectPart part = GetPart(localID);
3501
3512 SceneObjectPart[] parts = m_parts.GetArray(); 3502 SceneObjectPart[] parts = m_parts.GetArray();
3513 3503
3514 if (part != null) 3504 if (part != null)
@@ -3537,7 +3527,7 @@ namespace OpenSim.Region.Framework.Scenes
3537 /// <param name="localID"></param> 3527 /// <param name="localID"></param>
3538 public void UpdateSingleRotation(Quaternion rot, Vector3 pos, uint localID) 3528 public void UpdateSingleRotation(Quaternion rot, Vector3 pos, uint localID)
3539 { 3529 {
3540 SceneObjectPart part = GetChildPart(localID); 3530 SceneObjectPart part = GetPart(localID);
3541 if (part != null) 3531 if (part != null)
3542 { 3532 {
3543 if (m_rootPart.PhysActor != null) 3533 if (m_rootPart.PhysActor != null)
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index ac44ce9..a2649ee 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -815,7 +815,7 @@ namespace OpenSim.Region.Framework.Scenes
815 815
816 group.ResetIDs(); 816 group.ResetIDs();
817 817
818 SceneObjectPart rootPart = group.GetChildPart(group.UUID); 818 SceneObjectPart rootPart = group.GetPart(group.UUID);
819 819
820 // Since renaming the item in the inventory does not affect the name stored 820 // Since renaming the item in the inventory does not affect the name stored
821 // in the serialization, transfer the correct name from the inventory to the 821 // in the serialization, transfer the correct name from the inventory to the
diff --git a/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs
new file mode 100644
index 0000000..e68f9d0
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs
@@ -0,0 +1,189 @@
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
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Reflection;
32using System.Text;
33using log4net;
34using Mono.Addins;
35using NDesk.Options;
36using Nini.Config;
37using OpenMetaverse;
38using OpenSim.Framework;
39using OpenSim.Framework.Console;
40using OpenSim.Framework.Statistics;
41using OpenSim.Region.ClientStack.LindenUDP;
42using OpenSim.Region.CoreModules.Avatar.Friends;
43using OpenSim.Region.Framework.Interfaces;
44using OpenSim.Region.Framework.Scenes;
45using OpenSim.Services.Interfaces;
46using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
47
48namespace OpenSim.Region.OptionalModules.Avatar.Friends
49{
50 /// <summary>
51 /// A module that just holds commands for inspecting avatar appearance.
52 /// </summary>
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "FriendsCommandModule")]
54 public class FriendsCommandsModule : ISharedRegionModule
55 {
56// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
57
58 private Scene m_scene;
59 private IFriendsModule m_friendsModule;
60 private IUserManagement m_userManagementModule;
61
62// private IAvatarFactoryModule m_avatarFactory;
63
64 public string Name { get { return "Appearance Information Module"; } }
65
66 public Type ReplaceableInterface { get { return null; } }
67
68 public void Initialise(IConfigSource source)
69 {
70// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: INITIALIZED MODULE");
71 }
72
73 public void PostInitialise()
74 {
75// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: POST INITIALIZED MODULE");
76 }
77
78 public void Close()
79 {
80// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: CLOSED MODULE");
81 }
82
83 public void AddRegion(Scene scene)
84 {
85// m_log.DebugFormat("[FRIENDS COMMANDO MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
86 }
87
88 public void RemoveRegion(Scene scene)
89 {
90// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
91 }
92
93 public void RegionLoaded(Scene scene)
94 {
95// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
96
97 if (m_scene == null)
98 m_scene = scene;
99
100 m_friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
101 m_userManagementModule = m_scene.RequestModuleInterface<IUserManagement>();
102
103 if (m_friendsModule != null && m_userManagementModule != null)
104 {
105 m_scene.AddCommand(
106 "Friends", this, "friends show",
107 "friends show [--cache] <first-name> <last-name>",
108 "Show the friends for the given user if they exist.\n",
109 "The --cache option will show locally cached information for that user.",
110 HandleFriendsShowCommand);
111 }
112 }
113
114 protected void HandleFriendsShowCommand(string module, string[] cmd)
115 {
116 Dictionary<string, object> options = new Dictionary<string, object>();
117 OptionSet optionSet = new OptionSet().Add("c|cache", delegate (string v) { options["cache"] = v != null; });
118
119 List<string> mainParams = optionSet.Parse(cmd);
120
121 if (mainParams.Count != 4)
122 {
123 MainConsole.Instance.OutputFormat("Usage: friends show [--cache] <first-name> <last-name>");
124 return;
125 }
126
127 string firstName = mainParams[2];
128 string lastName = mainParams[3];
129
130 UUID userId = m_userManagementModule.GetUserIdByName(firstName, lastName);
131
132// UserAccount ua
133// = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, firstName, lastName);
134
135 if (userId == UUID.Zero)
136 {
137 MainConsole.Instance.OutputFormat("No such user as {0} {1}", firstName, lastName);
138 return;
139 }
140
141 FriendInfo[] friends;
142
143 if (options.ContainsKey("cache"))
144 {
145 if (!m_friendsModule.AreFriendsCached(userId))
146 {
147 MainConsole.Instance.OutputFormat("No friends cached on this simulator for {0} {1}", firstName, lastName);
148 return;
149 }
150 else
151 {
152 friends = m_friendsModule.GetFriendsFromCache(userId);
153 }
154 }
155 else
156 {
157 // FIXME: We're forced to do this right now because IFriendsService has no region connectors. We can't
158 // just expose FriendsModule.GetFriendsFromService() because it forces an IClientAPI requirement that
159 // can't currently be changed because of HGFriendsModule code that takes the scene from the client.
160 friends = ((FriendsModule)m_friendsModule).FriendsService.GetFriends(userId);
161 }
162
163 MainConsole.Instance.OutputFormat("Friends for {0} {1} {2}:", firstName, lastName, userId);
164
165 MainConsole.Instance.OutputFormat("UUID, Name, MyFlags, TheirFlags");
166
167 foreach (FriendInfo friend in friends)
168 {
169// MainConsole.Instance.OutputFormat(friend.PrincipalID.ToString());
170
171// string friendFirstName, friendLastName;
172//
173// UserAccount friendUa
174// = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friend.PrincipalID);
175
176 UUID friendId;
177 string friendName;
178
179 if (UUID.TryParse(friend.Friend, out friendId))
180 friendName = m_userManagementModule.GetUserName(friendId);
181 else
182 friendName = friend.Friend;
183
184 MainConsole.Instance.OutputFormat(
185 "{0} {1} {2} {3}", friend.Friend, friendName, friend.MyFlags, friend.TheirFlags);
186 }
187 }
188 }
189} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs
index a17eb41..51b0592 100644
--- a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs
+++ b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs
@@ -510,7 +510,7 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
510 } 510 }
511 511
512 SceneObjectGroup sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape); 512 SceneObjectGroup sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape);
513 SceneObjectPart rootPart = sceneObject.GetChildPart(sceneObject.UUID); 513 SceneObjectPart rootPart = sceneObject.GetPart(sceneObject.UUID);
514 514
515 rootPart.AddFlag(PrimFlags.Phantom); 515 rootPart.AddFlag(PrimFlags.Phantom);
516 516
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 4d7c40e..edfc0ef 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -4214,7 +4214,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4214 World.ForEachRootScenePresence(delegate(ScenePresence presence) 4214 World.ForEachRootScenePresence(delegate(ScenePresence presence)
4215 { 4215 {
4216 SceneObjectPart sitPart = presence.ParentPart; 4216 SceneObjectPart sitPart = presence.ParentPart;
4217 if (sitPart != null && m_host.ParentGroup.HasChildPrim(sitPart.LocalId)) 4217 if (sitPart != null && m_host.ParentGroup.ContainsPart(sitPart.LocalId))
4218 nametable.Add(presence.ControllingClient.Name); 4218 nametable.Add(presence.ControllingClient.Name);
4219 }); 4219 });
4220 4220
diff --git a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs
index a999886..cb686e2 100644
--- a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs
+++ b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Linq;
30using OpenMetaverse; 31using OpenMetaverse;
31using log4net; 32using log4net;
32using Nini.Config; 33using Nini.Config;
@@ -58,6 +59,8 @@ namespace OpenSim.Services.HypergridService
58 59
59 private UserAccountCache m_Cache; 60 private UserAccountCache m_Cache;
60 61
62 private ExpiringCache<UUID, List<XInventoryFolder>> m_SuitcaseTrees = new ExpiringCache<UUID,List<XInventoryFolder>>();
63
61 public HGSuitcaseInventoryService(IConfigSource config, string configName) 64 public HGSuitcaseInventoryService(IConfigSource config, string configName)
62 : base(config, configName) 65 : base(config, configName)
63 { 66 {
@@ -147,16 +150,17 @@ namespace OpenSim.Services.HypergridService
147 return GetRootFolder(principalID); 150 return GetRootFolder(principalID);
148 } 151 }
149 152
150 //
151 // Use the inherited methods
152 //
153 public override InventoryCollection GetFolderContent(UUID principalID, UUID folderID) 153 public override InventoryCollection GetFolderContent(UUID principalID, UUID folderID)
154 { 154 {
155 InventoryCollection coll = null; 155 InventoryCollection coll = null;
156 XInventoryFolder suitcase = GetSuitcaseXFolder(principalID);
156 XInventoryFolder root = GetRootXFolder(principalID); 157 XInventoryFolder root = GetRootXFolder(principalID);
158
159 if (!IsWithinSuitcaseTree(folderID, root, suitcase))
160 return new InventoryCollection();
161
157 if (folderID == root.folderID) // someone's asking for the root folder, we'll give them the suitcase 162 if (folderID == root.folderID) // someone's asking for the root folder, we'll give them the suitcase
158 { 163 {
159 XInventoryFolder suitcase = GetSuitcaseXFolder(principalID);
160 if (suitcase != null) 164 if (suitcase != null)
161 { 165 {
162 coll = base.GetFolderContent(principalID, suitcase.folderID); 166 coll = base.GetFolderContent(principalID, suitcase.folderID);
@@ -180,68 +184,69 @@ namespace OpenSim.Services.HypergridService
180 return coll; 184 return coll;
181 } 185 }
182 186
183 //public List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID) 187 public override List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID)
184 //{ 188 {
185 //} 189 // Let's do a bit of sanity checking, more than the base service does
190 // make sure the given folder exists under the suitcase tree of this user
191 XInventoryFolder root = GetRootXFolder(principalID);
192 XInventoryFolder suitcase = GetSuitcaseXFolder(principalID);
186 193
187 //public override bool AddFolder(InventoryFolderBase folder) 194 if (!IsWithinSuitcaseTree(folderID, root, suitcase))
188 //{ 195 return new List<InventoryItemBase>();
189 // // Check if it's under the Suitcase folder 196
190 // List<InventoryFolderBase> skel = base.GetInventorySkeleton(folder.Owner); 197 return base.GetFolderItems(principalID, folderID);
191 // InventoryFolderBase suitcase = GetRootFolder(folder.Owner); 198 }
192 // List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID);
193
194 // foreach (InventoryFolderBase f in suitDescendents)
195 // if (folder.ParentID == f.ID)
196 // {
197 // XInventoryFolder xFolder = ConvertFromOpenSim(folder);
198 // return m_Database.StoreFolder(xFolder);
199 // }
200 // return false;
201 //}
202 199
203 private List<InventoryFolderBase> GetDescendents(List<InventoryFolderBase> lst, UUID root) 200 public override bool AddFolder(InventoryFolderBase folder)
204 { 201 {
205 List<InventoryFolderBase> direct = lst.FindAll(delegate(InventoryFolderBase f) { return f.ParentID == root; }); 202 // Let's do a bit of sanity checking, more than the base service does
206 if (direct == null) 203 // make sure the given folder's parent folder exists under the suitcase tree of this user
207 return new List<InventoryFolderBase>(); 204 XInventoryFolder root = GetRootXFolder(folder.Owner);
205 XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner);
208 206
209 List<InventoryFolderBase> indirect = new List<InventoryFolderBase>(); 207 if (!IsWithinSuitcaseTree(folder.ParentID, root, suitcase))
210 foreach (InventoryFolderBase f in direct) 208 return false;
211 indirect.AddRange(GetDescendents(lst, f.ID));
212 209
213 direct.AddRange(indirect); 210 // OK, it's legit
214 return direct; 211 // Check if it's under the Root folder directly
212 if (folder.ParentID == root.folderID)
213 {
214 // someone's trying to add a subfolder of the root folder, we'll add it to the suitcase instead
215 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: AddFolder for root folder for user {0}. Adding in suitcase instead", folder.Owner);
216 folder.ParentID = suitcase.folderID;
217 }
218
219 return base.AddFolder(folder);
220 }
221
222 public bool UpdateFolder(InventoryFolderBase folder)
223 {
224 XInventoryFolder root = GetRootXFolder(folder.Owner);
225 XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner);
226
227 if (!IsWithinSuitcaseTree(folder.ID, root, suitcase))
228 return false;
229
230 return base.UpdateFolder(folder);
215 } 231 }
216 232
217 // Use inherited method 233 public override bool MoveFolder(InventoryFolderBase folder)
218 //public bool UpdateFolder(InventoryFolderBase folder) 234 {
219 //{ 235 XInventoryFolder root = GetRootXFolder(folder.Owner);
220 //} 236 XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner);
221 237
222 //public override bool MoveFolder(InventoryFolderBase folder) 238 if (!IsWithinSuitcaseTree(folder.ID, root, suitcase) || !IsWithinSuitcaseTree(folder.ParentID, root, suitcase))
223 //{ 239 return false;
224 // XInventoryFolder[] x = m_Database.GetFolders( 240
225 // new string[] { "folderID" }, 241 if (folder.ParentID == root.folderID)
226 // new string[] { folder.ID.ToString() }); 242 {
227 243 // someone's trying to add a subfolder of the root folder, we'll add it to the suitcase instead
228 // if (x.Length == 0) 244 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: MoveFolder to root folder for user {0}. Moving it to suitcase instead", folder.Owner);
229 // return false; 245 folder.ParentID = suitcase.folderID;
230 246 }
231 // // Check if it's under the Suitcase folder 247
232 // List<InventoryFolderBase> skel = base.GetInventorySkeleton(folder.Owner); 248 return base.MoveFolder(folder);
233 // InventoryFolderBase suitcase = GetRootFolder(folder.Owner); 249 }
234 // List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID);
235
236 // foreach (InventoryFolderBase f in suitDescendents)
237 // if (folder.ParentID == f.ID)
238 // {
239 // x[0].parentFolderID = folder.ParentID;
240 // return m_Database.StoreFolder(x[0]);
241 // }
242
243 // return false;
244 //}
245 250
246 public override bool DeleteFolders(UUID principalID, List<UUID> folderIDs) 251 public override bool DeleteFolders(UUID principalID, List<UUID> folderIDs)
247 { 252 {
@@ -255,78 +260,110 @@ namespace OpenSim.Services.HypergridService
255 return false; 260 return false;
256 } 261 }
257 262
258 // Unfortunately we need to use the inherited method because of how DeRez works. 263 public override bool AddItem(InventoryItemBase item)
259 // The viewer sends the folderID hard-wired in the derez message 264 {
260 //public override bool AddItem(InventoryItemBase item) 265 // Let's do a bit of sanity checking, more than the base service does
261 //{ 266 // make sure the given folder's parent folder exists under the suitcase tree of this user
262 // // Check if it's under the Suitcase folder 267 XInventoryFolder root = GetRootXFolder(item.Owner);
263 // List<InventoryFolderBase> skel = base.GetInventorySkeleton(item.Owner); 268 XInventoryFolder suitcase = GetSuitcaseXFolder(item.Owner);
264 // InventoryFolderBase suitcase = GetRootFolder(item.Owner);
265 // List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID);
266 269
267 // foreach (InventoryFolderBase f in suitDescendents) 270 if (!IsWithinSuitcaseTree(item.Folder, root, suitcase))
268 // if (item.Folder == f.ID) 271 return false;
269 // return m_Database.StoreItem(ConvertFromOpenSim(item));
270 272
271 // return false; 273 // OK, it's legit
272 //} 274 // Check if it's under the Root folder directly
275 if (item.Folder == root.folderID)
276 {
277 // someone's trying to add a subfolder of the root folder, we'll add it to the suitcase instead
278 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: AddItem for root folder for user {0}. Adding in suitcase instead", item.Owner);
279 item.Folder = suitcase.folderID;
280 }
273 281
274 //public override bool UpdateItem(InventoryItemBase item) 282 return base.AddItem(item);
275 //{
276 // // Check if it's under the Suitcase folder
277 // List<InventoryFolderBase> skel = base.GetInventorySkeleton(item.Owner);
278 // InventoryFolderBase suitcase = GetRootFolder(item.Owner);
279 // List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID);
280 283
281 // foreach (InventoryFolderBase f in suitDescendents) 284 }
282 // if (item.Folder == f.ID)
283 // return m_Database.StoreItem(ConvertFromOpenSim(item));
284 285
285 // return false; 286 public override bool UpdateItem(InventoryItemBase item)
286 //} 287 {
288 XInventoryFolder root = GetRootXFolder(item.Owner);
289 XInventoryFolder suitcase = GetSuitcaseXFolder(item.Owner);
287 290
288 //public override bool MoveItems(UUID principalID, List<InventoryItemBase> items) 291 if (!IsWithinSuitcaseTree(item.Folder, root, suitcase))
289 //{ 292 return false;
290 // // Principal is b0rked. *sigh* 293
291 // // 294 return base.UpdateItem(item);
292 // // Let's assume they all have the same principal 295 }
293 // // Check if it's under the Suitcase folder 296
294 // List<InventoryFolderBase> skel = base.GetInventorySkeleton(items[0].Owner); 297 public override bool MoveItems(UUID principalID, List<InventoryItemBase> items)
295 // InventoryFolderBase suitcase = GetRootFolder(items[0].Owner); 298 {
296 // List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID); 299 // Principal is b0rked. *sigh*
297 300
298 // foreach (InventoryItemBase i in items) 301 XInventoryFolder root = GetRootXFolder(items[0].Owner);
299 // { 302 XInventoryFolder suitcase = GetSuitcaseXFolder(items[0].Owner);
300 // foreach (InventoryFolderBase f in suitDescendents) 303
301 // if (i.Folder == f.ID) 304 if (!IsWithinSuitcaseTree(items[0].Folder, root, suitcase))
302 // m_Database.MoveItem(i.ID.ToString(), i.Folder.ToString()); 305 return false;
303 // } 306
304 307 foreach (InventoryItemBase it in items)
305 // return true; 308 if (it.Folder == root.folderID)
306 //} 309 {
310 // someone's trying to add a subfolder of the root folder, we'll add it to the suitcase instead
311 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: MoveItem to root folder for user {0}. Moving it to suitcase instead", it.Owner);
312 it.Folder = suitcase.folderID;
313 }
314
315 return base.MoveItems(principalID, items);
316
317 }
307 318
308 // Let these pass. Use inherited methods. 319 // Let these pass. Use inherited methods.
309 //public bool DeleteItems(UUID principalID, List<UUID> itemIDs) 320 public override bool DeleteItems(UUID principalID, List<UUID> itemIDs)
310 //{ 321 {
311 //} 322 return false;
323 }
312 324
313 //public override InventoryItemBase GetItem(InventoryItemBase item) 325 public override InventoryItemBase GetItem(InventoryItemBase item)
314 //{ 326 {
315 // InventoryItemBase it = base.GetItem(item); 327 InventoryItemBase it = base.GetItem(item);
316 // if (it != null) 328 XInventoryFolder root = GetRootXFolder(it.Owner);
317 // { 329 XInventoryFolder suitcase = GetSuitcaseXFolder(it.Owner);
318 // UserAccount user = m_Cache.GetUser(it.CreatorId);
319
320 // // Adjust the creator data
321 // if (user != null && it != null && (it.CreatorData == null || it.CreatorData == string.Empty))
322 // it.CreatorData = m_HomeURL + ";" + user.FirstName + " " + user.LastName;
323 // }
324 // return it;
325 //}
326 330
327 //public InventoryFolderBase GetFolder(InventoryFolderBase folder) 331 if (it != null)
328 //{ 332 {
329 //} 333 if (!IsWithinSuitcaseTree(it.Folder, root, suitcase))
334 return null;
335
336 if (it.Folder == suitcase.folderID)
337 it.Folder = root.folderID;
338
339 // UserAccount user = m_Cache.GetUser(it.CreatorId);
340
341 // // Adjust the creator data
342 // if (user != null && it != null && (it.CreatorData == null || it.CreatorData == string.Empty))
343 // it.CreatorData = m_HomeURL + ";" + user.FirstName + " " + user.LastName;
344 //}
345 }
346
347 return it;
348 }
349
350 public override InventoryFolderBase GetFolder(InventoryFolderBase folder)
351 {
352 InventoryFolderBase f = base.GetFolder(folder);
353 XInventoryFolder root = GetRootXFolder(f.Owner);
354 XInventoryFolder suitcase = GetSuitcaseXFolder(f.Owner);
355
356 if (f != null)
357 {
358 if (!IsWithinSuitcaseTree(f.ID, root, suitcase))
359 return null;
360
361 if (f.ParentID == suitcase.folderID)
362 f.ParentID = root.folderID;
363 }
364
365 return f;
366 }
330 367
331 //public List<InventoryItemBase> GetActiveGestures(UUID principalID) 368 //public List<InventoryItemBase> GetActiveGestures(UUID principalID)
332 //{ 369 //{
@@ -336,6 +373,19 @@ namespace OpenSim.Services.HypergridService
336 //{ 373 //{
337 //} 374 //}
338 375
376 #region Auxiliary functions
377 private XInventoryFolder GetXFolder(UUID userID, UUID folderID)
378 {
379 XInventoryFolder[] folders = m_Database.GetFolders(
380 new string[] { "agentID", "folderID" },
381 new string[] { userID.ToString(), folderID.ToString() });
382
383 if (folders.Length == 0)
384 return null;
385
386 return folders[0];
387 }
388
339 private XInventoryFolder GetRootXFolder(UUID principalID) 389 private XInventoryFolder GetRootXFolder(UUID principalID)
340 { 390 {
341 XInventoryFolder[] folders = m_Database.GetFolders( 391 XInventoryFolder[] folders = m_Database.GetFolders(
@@ -364,5 +414,53 @@ namespace OpenSim.Services.HypergridService
364 suitcase.folderID = rootID; 414 suitcase.folderID = rootID;
365 suitcase.parentFolderID = UUID.Zero; 415 suitcase.parentFolderID = UUID.Zero;
366 } 416 }
417
418 private List<XInventoryFolder> GetFolderTree(UUID root)
419 {
420 List<XInventoryFolder> t = null;
421 if (m_SuitcaseTrees.TryGetValue(root, out t))
422 return t;
423
424 t = GetFolderTreeRecursive(root);
425 m_SuitcaseTrees.AddOrUpdate(root, t, 120);
426 return t;
427 }
428
429 private List<XInventoryFolder> GetFolderTreeRecursive(UUID root)
430 {
431 List<XInventoryFolder> tree = new List<XInventoryFolder>();
432 XInventoryFolder[] folders = m_Database.GetFolders(
433 new string[] { "parentFolderID" },
434 new string[] { root.ToString() });
435
436 if (folders == null || (folders != null && folders.Length == 0))
437 return tree; // empty tree
438 else
439 {
440 foreach (XInventoryFolder f in folders)
441 {
442 tree.Add(f);
443 tree.AddRange(GetFolderTreeRecursive(f.folderID));
444 }
445 return tree;
446 }
447
448 }
449
450 private bool IsWithinSuitcaseTree(UUID folderID, XInventoryFolder root, XInventoryFolder suitcase)
451 {
452 List<XInventoryFolder> tree = new List<XInventoryFolder>();
453 tree.Add(root); // Warp! the tree is the real root folder plus the children of the suitcase folder
454 tree.AddRange(GetFolderTree(suitcase.folderID));
455 XInventoryFolder f = tree.Find(delegate(XInventoryFolder fl)
456 {
457 if (fl.folderID == folderID) return true;
458 else return false;
459 });
460
461 if (f == null) return false;
462 else return true;
463 }
464 #endregion
367 } 465 }
368} 466}
diff --git a/OpenSim/Services/Interfaces/IFriendsService.cs b/OpenSim/Services/Interfaces/IFriendsService.cs
index 1664f3b..d0d3b10 100644
--- a/OpenSim/Services/Interfaces/IFriendsService.cs
+++ b/OpenSim/Services/Interfaces/IFriendsService.cs
@@ -36,7 +36,15 @@ namespace OpenSim.Services.Interfaces
36 { 36 {
37 public UUID PrincipalID; 37 public UUID PrincipalID;
38 public string Friend; 38 public string Friend;
39
40 /// <summary>
41 /// The permissions that this user has granted to the friend.
42 /// </summary>
39 public int MyFlags; 43 public int MyFlags;
44
45 /// <summary>
46 /// The permissions that the friend has granted to this user.
47 /// </summary>
40 public int TheirFlags; 48 public int TheirFlags;
41 49
42 public FriendInfo() 50 public FriendInfo()
@@ -51,7 +59,7 @@ namespace OpenSim.Services.Interfaces
51 Friend = string.Empty; 59 Friend = string.Empty;
52 if (kvp.ContainsKey("Friend") && kvp["Friend"] != null) 60 if (kvp.ContainsKey("Friend") && kvp["Friend"] != null)
53 Friend = kvp["Friend"].ToString(); 61 Friend = kvp["Friend"].ToString();
54 MyFlags = 0; 62 MyFlags = (int)FriendRights.None;
55 if (kvp.ContainsKey("MyFlags") && kvp["MyFlags"] != null) 63 if (kvp.ContainsKey("MyFlags") && kvp["MyFlags"] != null)
56 Int32.TryParse(kvp["MyFlags"].ToString(), out MyFlags); 64 Int32.TryParse(kvp["MyFlags"].ToString(), out MyFlags);
57 TheirFlags = 0; 65 TheirFlags = 0;
diff --git a/OpenSim/Services/PresenceService/PresenceService.cs b/OpenSim/Services/PresenceService/PresenceService.cs
index c8ac38e..ed2703e 100644
--- a/OpenSim/Services/PresenceService/PresenceService.cs
+++ b/OpenSim/Services/PresenceService/PresenceService.cs
@@ -151,11 +151,12 @@ namespace OpenSim.Services.PresenceService
151 151
152 info.Add(ret); 152 info.Add(ret);
153 } 153 }
154
155// m_log.DebugFormat(
156// "[PRESENCE SERVICE]: GetAgents for {0} found {1} presences", userIDStr, data.Length);
154 } 157 }
155 158
156 // m_log.DebugFormat("[PRESENCE SERVICE]: GetAgents for {0} userIDs found {1} presences", userIDs.Length, info.Count);
157 return info.ToArray(); 159 return info.ToArray();
158 } 160 }
159
160 } 161 }
161} 162} \ No newline at end of file
diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs
index 7bf08ae..318758d 100644
--- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs
+++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs
@@ -369,8 +369,11 @@ namespace OpenSim.Tests.Common
369 agentData.AgentID = agentId; 369 agentData.AgentID = agentId;
370 agentData.firstname = firstName; 370 agentData.firstname = firstName;
371 agentData.lastname = "testlastname"; 371 agentData.lastname = "testlastname";
372 agentData.SessionID = UUID.Zero; 372
373 agentData.SecureSessionID = UUID.Zero; 373 // XXX: Sessions must be unique, otherwise one presence can overwrite another in NullPresenceData.
374 agentData.SessionID = UUID.Random();
375 agentData.SecureSessionID = UUID.Random();
376
374 agentData.circuitcode = 123; 377 agentData.circuitcode = 123;
375 agentData.BaseFolder = UUID.Zero; 378 agentData.BaseFolder = UUID.Zero;
376 agentData.InventoryFolder = UUID.Zero; 379 agentData.InventoryFolder = UUID.Zero;
@@ -416,7 +419,10 @@ namespace OpenSim.Tests.Common
416 // We emulate the proper login sequence here by doing things in four stages 419 // We emulate the proper login sequence here by doing things in four stages
417 420
418 // Stage 0: login 421 // Stage 0: login
419 scene.PresenceService.LoginAgent(agentData.AgentID.ToString(), agentData.SessionID, agentData.SecureSessionID); 422 // We need to punch through to the underlying service because scene will not, correctly, let us call it
423 // through it's reference to the LPSC
424 LocalPresenceServicesConnector lpsc = (LocalPresenceServicesConnector)scene.PresenceService;
425 lpsc.m_PresenceService.LoginAgent(agentData.AgentID.ToString(), agentData.SessionID, agentData.SecureSessionID);
420 426
421 // Stages 1 & 2 427 // Stages 1 & 2
422 ScenePresence sp = IntroduceClientToScene(scene, agentData, TeleportFlags.ViaLogin); 428 ScenePresence sp = IntroduceClientToScene(scene, agentData, TeleportFlags.ViaLogin);
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs
index 64dd1e4..6a7cb0a 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -349,15 +349,9 @@ namespace OpenSim.Tests.Common.Mock
349 get { return m_agentId; } 349 get { return m_agentId; }
350 } 350 }
351 351
352 public UUID SessionId 352 public UUID SessionId { get; set; }
353 {
354 get { return UUID.Zero; }
355 }
356 353
357 public UUID SecureSessionId 354 public UUID SecureSessionId { get; set; }
358 {
359 get { return UUID.Zero; }
360 }
361 355
362 public virtual string FirstName 356 public virtual string FirstName
363 { 357 {
@@ -381,11 +375,9 @@ namespace OpenSim.Tests.Common.Mock
381 get { return true; } 375 get { return true; }
382 set { } 376 set { }
383 } 377 }
384 public bool IsLoggingOut 378
385 { 379 public bool IsLoggingOut { get; set; }
386 get { return false; } 380
387 set { }
388 }
389 public UUID ActiveGroupId 381 public UUID ActiveGroupId
390 { 382 {
391 get { return UUID.Zero; } 383 get { return UUID.Zero; }
@@ -451,6 +443,8 @@ namespace OpenSim.Tests.Common.Mock
451 m_lastName = agentData.lastname; 443 m_lastName = agentData.lastname;
452 m_circuitCode = agentData.circuitcode; 444 m_circuitCode = agentData.circuitcode;
453 m_scene = scene; 445 m_scene = scene;
446 SessionId = agentData.SessionID;
447 SecureSessionId = agentData.SecureSessionID;
454 CapsSeedUrl = agentData.CapsPath; 448 CapsSeedUrl = agentData.CapsPath;
455 449
456 ReceivedOfflineNotifications = new List<UUID>(); 450 ReceivedOfflineNotifications = new List<UUID>();
@@ -902,12 +896,29 @@ namespace OpenSim.Tests.Common.Mock
902 { 896 {
903 } 897 }
904 898
905 public void Close() 899 /// <summary>
900 /// This is a TestClient only method to do shutdown tasks that are normally carried out by LLUDPServer.RemoveClient()
901 /// </summary>
902 public void Logout()
903 {
904 // We must set this here so that the presence is removed from the PresenceService by the PresenceDetector
905 IsLoggingOut = true;
906
907 Close();
908 }
909
910 public void Close(bool c)
906 { 911 {
907 Close(true); 912 Close();
908 } 913 }
909 public void Close(bool sendStop) 914
915 public void Close()
910 { 916 {
917 // Fire the callback for this connection closing
918 // This is necesary to get the presence detector to notice that a client has logged out.
919 if (OnConnectionClosed != null)
920 OnConnectionClosed(this);
921
911 m_scene.RemoveClient(AgentId, true); 922 m_scene.RemoveClient(AgentId, true);
912 } 923 }
913 924
diff --git a/prebuild.xml b/prebuild.xml
index 0123c2a..2f114da 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -1325,6 +1325,7 @@
1325 1325
1326 <ReferencePath>../../../bin/</ReferencePath> 1326 <ReferencePath>../../../bin/</ReferencePath>
1327 <Reference name="System"/> 1327 <Reference name="System"/>
1328 <Reference name="System.Core"/>
1328 <Reference name="System.Xml"/> 1329 <Reference name="System.Xml"/>
1329 <Reference name="OpenMetaverseTypes" path="../../../bin/"/> 1330 <Reference name="OpenMetaverseTypes" path="../../../bin/"/>
1330 <Reference name="OpenMetaverse" path="../../../bin/"/> 1331 <Reference name="OpenMetaverse" path="../../../bin/"/>
@@ -1764,6 +1765,7 @@
1764 <Reference name="System.Xml"/> 1765 <Reference name="System.Xml"/>
1765 <Reference name="System.Drawing"/> 1766 <Reference name="System.Drawing"/>
1766 <Reference name="System.Web"/> 1767 <Reference name="System.Web"/>
1768 <Reference name="NDesk.Options" path="../../../bin/"/>
1767 <Reference name="OpenMetaverseTypes" path="../../../bin/"/> 1769 <Reference name="OpenMetaverseTypes" path="../../../bin/"/>
1768 <Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/> 1770 <Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
1769 <Reference name="OpenMetaverse" path="../../../bin/"/> 1771 <Reference name="OpenMetaverse" path="../../../bin/"/>
@@ -3009,6 +3011,7 @@
3009 <Reference name="OpenMetaverseTypes" path="../../../bin/"/> 3011 <Reference name="OpenMetaverseTypes" path="../../../bin/"/>
3010 <Reference name="OpenMetaverse" path="../../../bin/"/> 3012 <Reference name="OpenMetaverse" path="../../../bin/"/>
3011 <Reference name="OpenSim.Data"/> 3013 <Reference name="OpenSim.Data"/>
3014 <Reference name="OpenSim.Data.Null"/>
3012 <Reference name="OpenSim.Framework"/> 3015 <Reference name="OpenSim.Framework"/>
3013 <Reference name="OpenSim.Framework.Serialization"/> 3016 <Reference name="OpenSim.Framework.Serialization"/>
3014 <Reference name="OpenSim.Framework.Communications"/> 3017 <Reference name="OpenSim.Framework.Communications"/>