aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorUbitUmarov2012-04-01 11:20:11 +0100
committerUbitUmarov2012-04-01 11:20:11 +0100
commitd5e123c1064df424f377ed7511e7dd3721c7be8b (patch)
treee0fb702dc1d5e3d26e6a108d47d2e7c898cd1907 /OpenSim
parent reduced instability in vertical atractor with eficiency of 1 and banking (diff)
parentMerge branch 'master' into careminster (diff)
downloadopensim-SC-d5e123c1064df424f377ed7511e7dd3721c7be8b.zip
opensim-SC-d5e123c1064df424f377ed7511e7dd3721c7be8b.tar.gz
opensim-SC-d5e123c1064df424f377ed7511e7dd3721c7be8b.tar.bz2
opensim-SC-d5e123c1064df424f377ed7511e7dd3721c7be8b.tar.xz
Merge branch 'master' of ssh://3dhosting.de/var/git/careminster into ubitwork
Diffstat (limited to 'OpenSim')
-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.cs8
-rw-r--r--OpenSim/Framework/LandData.cs2
-rw-r--r--OpenSim/Framework/Servers/VersionInfo.cs3
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs65
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs313
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs185
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs21
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs94
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs69
-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/MapImage/MapImageServiceModule.cs19
-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/CoreModules/World/Warp3DMap/MapImageModule.cs30
-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/EventManager.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs16
-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/Framework/Scenes/ScenePresence.cs16
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs4
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs189
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs2
-rw-r--r--OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs12
-rw-r--r--OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs466
-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.cs45
40 files changed, 1596 insertions, 336 deletions
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 004b1a6..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);
@@ -717,7 +717,7 @@ namespace OpenSim.Framework
717 /// The scene agent for this client. This will only be set if the client has an agent in a scene (i.e. if it 717 /// The scene agent for this client. This will only be set if the client has an agent in a scene (i.e. if it
718 /// is connected). 718 /// is connected).
719 /// </summary> 719 /// </summary>
720 ISceneAgent SceneAgent { get; } 720 ISceneAgent SceneAgent { get; set; }
721 721
722 UUID SessionId { get; } 722 UUID SessionId { get; }
723 723
diff --git a/OpenSim/Framework/LandData.cs b/OpenSim/Framework/LandData.cs
index 9a9a6bf..dcaa46d 100644
--- a/OpenSim/Framework/LandData.cs
+++ b/OpenSim/Framework/LandData.cs
@@ -69,7 +69,7 @@ namespace OpenSim.Framework
69 (uint) ParcelFlags.AllowAPrimitiveEntry | 69 (uint) ParcelFlags.AllowAPrimitiveEntry |
70 (uint) ParcelFlags.AllowDeedToGroup | 70 (uint) ParcelFlags.AllowDeedToGroup |
71 (uint) ParcelFlags.CreateObjects | (uint) ParcelFlags.AllowOtherScripts | 71 (uint) ParcelFlags.CreateObjects | (uint) ParcelFlags.AllowOtherScripts |
72 (uint) ParcelFlags.SoundLocal; 72 (uint) ParcelFlags.SoundLocal | (uint) ParcelFlags.AllowVoiceChat;
73 73
74 private byte _landingType = 0; 74 private byte _landingType = 0;
75 private string _name = "Your Parcel"; 75 private string _name = "Your Parcel";
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 d0920d2..3118613 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -396,7 +396,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
396 } 396 }
397 } 397 }
398 public UUID AgentId { get { return m_agentId; } } 398 public UUID AgentId { get { return m_agentId; } }
399 public ISceneAgent SceneAgent { get; private set; } 399 public ISceneAgent SceneAgent { get; set; }
400 public UUID ActiveGroupId { get { return m_activeGroupID; } } 400 public UUID ActiveGroupId { get { return m_activeGroupID; } }
401 public string ActiveGroupName { get { return m_activeGroupName; } } 401 public string ActiveGroupName { get { return m_activeGroupName; } }
402 public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } } 402 public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } }
@@ -719,7 +719,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
719 719
720 public virtual void Start() 720 public virtual void Start()
721 { 721 {
722 SceneAgent = m_scene.AddNewClient(this, PresenceType.User); 722 m_scene.AddNewClient(this, PresenceType.User);
723 723
724 RefreshGroupMembership(); 724 RefreshGroupMembership();
725 } 725 }
@@ -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
@@ -12455,7 +12454,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12455 ItemData.Add(ItemDataMap); 12454 ItemData.Add(ItemDataMap);
12456 } 12455 }
12457 12456
12458 llsd.Add("ItemData", ItemData); 12457 llsd.Add("InventoryData", ItemData);
12459 12458
12460 eq.Enqueue(BuildEvent("RemoveInventoryItem", 12459 eq.Enqueue(BuildEvent("RemoveInventoryItem",
12461 llsd), AgentId); 12460 llsd), AgentId);
@@ -12499,6 +12498,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12499 llsd), AgentId); 12498 llsd), AgentId);
12500 } 12499 }
12501 12500
12501 private byte[] EncodeU32(uint val)
12502 {
12503 byte[] ret = BitConverter.GetBytes(val);
12504 if (BitConverter.IsLittleEndian)
12505 Array.Reverse(ret);
12506 return ret;
12507 }
12508
12502 public void SendBulkUpdateInventory(InventoryFolderBase[] folders, InventoryItemBase[] items) 12509 public void SendBulkUpdateInventory(InventoryFolderBase[] folders, InventoryItemBase[] items)
12503 { 12510 {
12504 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>(); 12511 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
@@ -12514,6 +12521,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12514 OSDMap AgentDataMap = new OSDMap(1); 12521 OSDMap AgentDataMap = new OSDMap(1);
12515 AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId)); 12522 AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId));
12516 AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId)); 12523 AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId));
12524 AgentDataMap.Add("TransactionID", OSD.FromUUID(UUID.Random()));
12517 12525
12518 OSDArray AgentData = new OSDArray(1); 12526 OSDArray AgentData = new OSDArray(1);
12519 AgentData.Add(AgentDataMap); 12527 AgentData.Add(AgentDataMap);
@@ -12541,10 +12549,47 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12541 foreach (InventoryItemBase item in items) 12549 foreach (InventoryItemBase item in items)
12542 { 12550 {
12543 OSDMap ItemDataMap = new OSDMap(); 12551 OSDMap ItemDataMap = new OSDMap();
12552
12553 ItemDataMap.Add("ItemID", OSD.FromUUID(item.ID));
12554 ItemDataMap.Add("FolderID", OSD.FromUUID(item.Folder));
12555
12556 ItemDataMap.Add("CreatorID", OSD.FromUUID(item.CreatorIdAsUuid));
12557 ItemDataMap.Add("OwnerID", OSD.FromUUID(item.Owner));
12558 ItemDataMap.Add("GroupID", OSD.FromUUID(item.GroupID));
12559 ItemDataMap.Add("BaseMask", OSD.FromBinary(EncodeU32((uint)item.BasePermissions)));
12560 ItemDataMap.Add("OwnerMask", OSD.FromBinary(EncodeU32((uint)item.CurrentPermissions)));
12561 ItemDataMap.Add("GroupMask", OSD.FromBinary(EncodeU32((uint)item.GroupPermissions)));
12562 ItemDataMap.Add("EveryoneMask", OSD.FromBinary(EncodeU32((uint)item.EveryOnePermissions)));
12563 ItemDataMap.Add("NextOwnerMask", OSD.FromBinary(EncodeU32((uint)item.NextPermissions)));
12564 ItemDataMap.Add("GroupOwned", OSD.FromBoolean(item.GroupOwned));
12565 ItemDataMap.Add("AssetID", OSD.FromUUID(item.AssetID));
12566 ItemDataMap.Add("Type", OSD.FromInteger(item.AssetType));
12567 ItemDataMap.Add("InvType", OSD.FromInteger(item.InvType));
12568 ItemDataMap.Add("Flags", OSD.FromBinary(EncodeU32((uint)item.Flags)));
12569 ItemDataMap.Add("SaleType", OSD.FromInteger((byte)item.SaleType));
12570 ItemDataMap.Add("SalePrice", OSD.FromInteger(item.SalePrice));
12571 ItemDataMap.Add("Name", OSD.FromString(item.Name));
12572 ItemDataMap.Add("Description", OSD.FromString(item.Description));
12573 ItemDataMap.Add("CreationDate", OSD.FromInteger(item.CreationDate));
12574
12575 ItemDataMap.Add("CRC", OSD.FromBinary(EncodeU32(
12576 Helpers.InventoryCRC(1000, 0, (sbyte)item.InvType,
12577 (sbyte)item.AssetType, item.AssetID,
12578 item.GroupID, 100,
12579 item.Owner, item.CreatorIdAsUuid,
12580 item.ID, item.Folder,
12581 (uint)PermissionMask.All, 1, (uint)PermissionMask.All, (uint)PermissionMask.All,
12582 (uint)PermissionMask.All)
12583 )));
12584 ItemDataMap.Add("CallbackID", 0);
12585
12544 ItemData.Add(ItemDataMap); 12586 ItemData.Add(ItemDataMap);
12545 } 12587 }
12546 12588
12547 llsd.Add("ItemData", ItemData); 12589 llsd.Add("ItemData", ItemData);
12590
12591 eq.Enqueue(BuildEvent("BulkUpdateInventory",
12592 llsd), AgentId);
12548 } 12593 }
12549 } 12594 }
12550} 12595}
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs
new file mode 100644
index 0000000..d942e87
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs
@@ -0,0 +1,313 @@
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.Reflection;
31using log4net;
32using Nini.Config;
33using OpenMetaverse;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Services.Interfaces;
38using Mono.Addins;
39
40namespace OpenSim.Region.CoreModules.Avatar.Friends
41{
42 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XCallingCard")]
43 public class CallingCardModule : ISharedRegionModule, ICallingCardModule
44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 protected List<Scene> m_Scenes = new List<Scene>();
47 protected bool m_Enabled = true;
48
49 public void Initialise(IConfigSource source)
50 {
51 IConfig ccConfig = source.Configs["XCallingCard"];
52 if (ccConfig != null)
53 m_Enabled = ccConfig.GetBoolean("Enabled", true);
54 }
55
56 public void AddRegion(Scene scene)
57 {
58 if (!m_Enabled)
59 return;
60
61 m_Scenes.Add(scene);
62
63 scene.RegisterModuleInterface<ICallingCardModule>(this);
64 }
65
66 public void RemoveRegion(Scene scene)
67 {
68 if (!m_Enabled)
69 return;
70
71 m_Scenes.Remove(scene);
72
73 scene.EventManager.OnNewClient -= OnNewClient;
74 scene.EventManager.OnIncomingInstantMessage +=
75 OnIncomingInstantMessage;
76
77 scene.UnregisterModuleInterface<ICallingCardModule>(this);
78 }
79
80 public void RegionLoaded(Scene scene)
81 {
82 if (!m_Enabled)
83 return;
84 scene.EventManager.OnNewClient += OnNewClient;
85 }
86
87 public void PostInitialise()
88 {
89 }
90
91 public void Close()
92 {
93 }
94
95 public Type ReplaceableInterface
96 {
97 get { return null; }
98 }
99
100 public string Name
101 {
102 get { return "XCallingCardModule"; }
103 }
104
105 private void OnNewClient(IClientAPI client)
106 {
107 client.OnOfferCallingCard += OnOfferCallingCard;
108 client.OnAcceptCallingCard += OnAcceptCallingCard;
109 client.OnDeclineCallingCard += OnDeclineCallingCard;
110 }
111
112 private void OnOfferCallingCard(IClientAPI client, UUID destID, UUID transactionID)
113 {
114 ScenePresence sp = GetClientPresence(client.AgentId);
115 if (sp != null)
116 {
117 // If we're in god mode, we reverse the meaning. Offer
118 // calling card becomes "Take a calling card" for that
119 // person, no matter if they agree or not.
120 if (sp.GodLevel >= 200)
121 {
122 CreateCallingCard(client.AgentId, destID, UUID.Zero, true);
123 return;
124 }
125 }
126
127 IClientAPI dest = FindClientObject(destID);
128 if (dest != null)
129 {
130 DoCallingCardOffer(dest, client.AgentId);
131 return;
132 }
133
134 IMessageTransferModule transferModule =
135 m_Scenes[0].RequestModuleInterface<IMessageTransferModule>();
136
137 if (transferModule != null)
138 {
139 transferModule.SendInstantMessage(new GridInstantMessage(
140 client.Scene, client.AgentId,
141 client.FirstName+" "+client.LastName,
142 destID, (byte)211, false,
143 String.Empty,
144 transactionID, false, new Vector3(), new byte[0]),
145 delegate(bool success) {} );
146 }
147 }
148
149 private void DoCallingCardOffer(IClientAPI dest, UUID from)
150 {
151 UUID itemID = CreateCallingCard(dest.AgentId, from, UUID.Zero, false);
152
153 dest.SendOfferCallingCard(from, itemID);
154 }
155
156 // Create a calling card in the user's inventory. This is called
157 // from direct calling card creation, when the offer is forwarded,
158 // and from the friends module when the friend is confirmed.
159 // Because of the latter, it will send a bulk inventory update
160 // if the receiving user is in the same simulator.
161 public UUID CreateCallingCard(UUID userID, UUID creatorID, UUID folderID)
162 {
163 return CreateCallingCard(userID, creatorID, folderID, false);
164 }
165
166 private UUID CreateCallingCard(UUID userID, UUID creatorID, UUID folderID, bool isGod)
167 {
168 IUserAccountService userv = m_Scenes[0].UserAccountService;
169 if (userv == null)
170 return UUID.Zero;
171
172 UserAccount info = userv.GetUserAccount(UUID.Zero, creatorID);
173 if (info == null)
174 return UUID.Zero;
175
176 IInventoryService inv = m_Scenes[0].InventoryService;
177 if (inv == null)
178 return UUID.Zero;
179
180 if (folderID == UUID.Zero)
181 {
182 InventoryFolderBase folder = inv.GetFolderForType(userID,
183 AssetType.CallingCard);
184
185 if (folder == null) // Nowhere to put it
186 return UUID.Zero;
187
188 folderID = folder.ID;
189 }
190
191 m_log.DebugFormat("[XCALLINGCARD]: Creating calling card for {0} in inventory of {1}", info.Name, userID);
192
193 InventoryItemBase item = new InventoryItemBase();
194 item.AssetID = UUID.Zero;
195 item.AssetType = (int)AssetType.CallingCard;
196 item.BasePermissions = (uint)(PermissionMask.Copy | PermissionMask.Modify);
197 if (isGod)
198 item.BasePermissions = (uint)(PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Move);
199
200 item.EveryOnePermissions = (uint)PermissionMask.None;
201 item.CurrentPermissions = item.BasePermissions;
202 item.NextPermissions = (uint)(PermissionMask.Copy | PermissionMask.Modify);
203
204 item.ID = UUID.Random();
205 item.CreatorId = creatorID.ToString();
206 item.Owner = userID;
207 item.GroupID = UUID.Zero;
208 item.GroupOwned = false;
209 item.Folder = folderID;
210
211 item.CreationDate = Util.UnixTimeSinceEpoch();
212 item.InvType = (int)InventoryType.CallingCard;
213 item.Flags = 0;
214
215 item.Name = info.Name;
216 item.Description = "";
217
218 item.SalePrice = 10;
219 item.SaleType = (byte)SaleType.Not;
220
221 inv.AddItem(item);
222
223 IClientAPI client = FindClientObject(userID);
224 if (client != null)
225 client.SendBulkUpdateInventory(item);
226
227 return item.ID;
228 }
229
230 private void OnAcceptCallingCard(IClientAPI client, UUID transactionID, UUID folderID)
231 {
232 }
233
234 private void OnDeclineCallingCard(IClientAPI client, UUID transactionID)
235 {
236 IInventoryService invService = m_Scenes[0].InventoryService;
237
238 InventoryFolderBase trashFolder =
239 invService.GetFolderForType(client.AgentId, AssetType.TrashFolder);
240
241 InventoryItemBase item = new InventoryItemBase(transactionID, client.AgentId);
242 item = invService.GetItem(item);
243
244 if (item != null && trashFolder != null)
245 {
246 item.Folder = trashFolder.ID;
247 List<UUID> uuids = new List<UUID>();
248 uuids.Add(item.ID);
249 invService.DeleteItems(item.Owner, uuids);
250 m_Scenes[0].AddInventoryItem(client, item);
251 }
252 }
253
254 public IClientAPI FindClientObject(UUID agentID)
255 {
256 Scene scene = GetClientScene(agentID);
257 if (scene == null)
258 return null;
259
260 ScenePresence presence = scene.GetScenePresence(agentID);
261 if (presence == null)
262 return null;
263
264 return presence.ControllingClient;
265 }
266
267 private Scene GetClientScene(UUID agentId)
268 {
269 lock (m_Scenes)
270 {
271 foreach (Scene scene in m_Scenes)
272 {
273 ScenePresence presence = scene.GetScenePresence(agentId);
274 if (presence != null)
275 {
276 if (!presence.IsChildAgent)
277 return scene;
278 }
279 }
280 }
281 return null;
282 }
283
284 private ScenePresence GetClientPresence(UUID agentId)
285 {
286 lock (m_Scenes)
287 {
288 foreach (Scene scene in m_Scenes)
289 {
290 ScenePresence presence = scene.GetScenePresence(agentId);
291 if (presence != null)
292 {
293 if (!presence.IsChildAgent)
294 return presence;
295 }
296 }
297 }
298 return null;
299 }
300
301 private void OnIncomingInstantMessage(GridInstantMessage msg)
302 {
303 if (msg.dialog == (uint)211)
304 {
305 IClientAPI client = FindClientObject(new UUID(msg.toAgentID));
306 if (client == null)
307 return;
308
309 DoCallingCardOffer(client, new UUID(msg.fromAgentID));
310 }
311 }
312 }
313}
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index 8e32fcc..f64c161 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -51,6 +51,8 @@ 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
@@ -72,7 +74,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
72 } 74 }
73 75
74 protected static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0]; 76 protected static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0];
75 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
76 77
77 protected List<Scene> m_Scenes = new List<Scene>(); 78 protected List<Scene> m_Scenes = new List<Scene>();
78 79
@@ -109,7 +110,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
109 } 110 }
110 } 111 }
111 112
112 protected IFriendsService FriendsService 113 public IFriendsService FriendsService
113 { 114 {
114 get 115 get
115 { 116 {
@@ -156,7 +157,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
156 InitModule(config); 157 InitModule(config);
157 158
158 m_Enabled = true; 159 m_Enabled = true;
159 m_log.InfoFormat("[FRIENDS MODULE]: {0} enabled.", Name); 160 m_log.DebugFormat("[FRIENDS MODULE]: {0} enabled.", Name);
160 } 161 }
161 } 162 }
162 } 163 }
@@ -201,7 +202,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
201 if (!m_Enabled) 202 if (!m_Enabled)
202 return; 203 return;
203 204
204 m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name); 205// m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
205 206
206 m_Scenes.Add(scene); 207 m_Scenes.Add(scene);
207 scene.RegisterModuleInterface<IFriendsModule>(this); 208 scene.RegisterModuleInterface<IFriendsModule>(this);
@@ -212,14 +213,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
212 scene.EventManager.OnClientLogin += OnClientLogin; 213 scene.EventManager.OnClientLogin += OnClientLogin;
213 } 214 }
214 215
215 public virtual void RegionLoaded(Scene scene) 216 public virtual void RegionLoaded(Scene scene) {}
216 {
217 scene.AddCommand(
218 "Friends", this, "friends show cache",
219 "friends show cache [<first-name> <last-name>]",
220 "Show the friends cache for the given user",
221 HandleFriendsShowCacheCommand);
222 }
223 217
224 public void RemoveRegion(Scene scene) 218 public void RemoveRegion(Scene scene)
225 { 219 {
@@ -241,13 +235,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
241 235
242 #endregion 236 #endregion
243 237
244 public virtual uint GetFriendPerms(UUID principalID, UUID friendID) 238 public virtual int GetRightsGrantedByFriend(UUID principalID, UUID friendID)
245 { 239 {
246 FriendInfo[] friends = GetFriends(principalID); 240 FriendInfo[] friends = GetFriendsFromCache(principalID);
247 FriendInfo finfo = GetFriend(friends, friendID); 241 FriendInfo finfo = GetFriend(friends, friendID);
248 if (finfo != null) 242 if (finfo != null)
249 { 243 {
250 return (uint)finfo.TheirFlags; 244 return finfo.TheirFlags;
251 } 245 }
252 246
253 return 0; 247 return 0;
@@ -258,9 +252,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
258 client.OnInstantMessage += OnInstantMessage; 252 client.OnInstantMessage += OnInstantMessage;
259 client.OnApproveFriendRequest += OnApproveFriendRequest; 253 client.OnApproveFriendRequest += OnApproveFriendRequest;
260 client.OnDenyFriendRequest += OnDenyFriendRequest; 254 client.OnDenyFriendRequest += OnDenyFriendRequest;
261 client.OnTerminateFriendship += (thisClient, agentID, exfriendID) => RemoveFriendship(thisClient, exfriendID); 255 client.OnTerminateFriendship += RemoveFriendship;
262 client.OnGrantUserRights += OnGrantUserRights; 256 client.OnGrantUserRights += GrantRights;
263 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 //
264 // 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
265 // return misleading results from the still empty friends cache. 262 // return misleading results from the still empty friends cache.
266 // 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
@@ -352,18 +349,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
352 349
353 // Send the friends online 350 // Send the friends online
354 List<UUID> online = GetOnlineFriends(agentID); 351 List<UUID> online = GetOnlineFriends(agentID);
355 if (online.Count > 0)
356 {
357 m_log.DebugFormat(
358 "[FRIENDS MODULE]: User {0} in region {1} has {2} friends online",
359 client.Name, client.Scene.RegionInfo.RegionName, online.Count);
360 352
353 if (online.Count > 0)
361 client.SendAgentOnline(online.ToArray()); 354 client.SendAgentOnline(online.ToArray());
362 }
363 355
364 // Send outstanding friendship offers 356 // Send outstanding friendship offers
365 List<string> outstanding = new List<string>(); 357 List<string> outstanding = new List<string>();
366 FriendInfo[] friends = GetFriends(agentID); 358 FriendInfo[] friends = GetFriendsFromCache(agentID);
367 foreach (FriendInfo fi in friends) 359 foreach (FriendInfo fi in friends)
368 { 360 {
369 if (fi.TheirFlags == -1) 361 if (fi.TheirFlags == -1)
@@ -419,23 +411,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
419 List<UUID> GetOnlineFriends(UUID userID) 411 List<UUID> GetOnlineFriends(UUID userID)
420 { 412 {
421 List<string> friendList = new List<string>(); 413 List<string> friendList = new List<string>();
422 List<UUID> online = new List<UUID>();
423 414
424 FriendInfo[] friends = GetFriends(userID); 415 FriendInfo[] friends = GetFriendsFromCache(userID);
425 foreach (FriendInfo fi in friends) 416 foreach (FriendInfo fi in friends)
426 { 417 {
427 if (((fi.TheirFlags & 1) != 0) && (fi.TheirFlags != -1)) 418 if (((fi.TheirFlags & (int)FriendRights.CanSeeOnline) != 0) && (fi.TheirFlags != -1))
428 friendList.Add(fi.Friend); 419 friendList.Add(fi.Friend);
429 } 420 }
430 421
422 List<UUID> online = new List<UUID>();
423
431 if (friendList.Count > 0) 424 if (friendList.Count > 0)
432 GetOnlineFriends(userID, friendList, online); 425 GetOnlineFriends(userID, friendList, online);
433 426
427// m_log.DebugFormat(
428// "[FRIENDS MODULE]: User {0} has {1} friends online", userID, online.Count);
429
434 return online; 430 return online;
435 } 431 }
436 432
437 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)
438 { 434 {
435// m_log.DebugFormat(
436// "[FRIENDS MODULE]: Looking for online presence of {0} users for {1}", friendList.Count, userID);
437
439 PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray()); 438 PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
440 foreach (PresenceInfo pi in presence) 439 foreach (PresenceInfo pi in presence)
441 { 440 {
@@ -486,13 +485,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
486 /// <param name="online"></param> 485 /// <param name="online"></param>
487 private void StatusChange(UUID agentID, bool online) 486 private void StatusChange(UUID agentID, bool online)
488 { 487 {
489 FriendInfo[] friends = GetFriends(agentID); 488 FriendInfo[] friends = GetFriendsFromCache(agentID);
490 if (friends.Length > 0) 489 if (friends.Length > 0)
491 { 490 {
492 List<FriendInfo> friendList = new List<FriendInfo>(); 491 List<FriendInfo> friendList = new List<FriendInfo>();
493 foreach (FriendInfo fi in friends) 492 foreach (FriendInfo fi in friends)
494 { 493 {
495 if (((fi.MyFlags & 1) != 0) && (fi.TheirFlags != -1)) 494 if (((fi.MyFlags & (int)FriendRights.CanSeeOnline) != 0) && (fi.TheirFlags != -1))
496 friendList.Add(fi); 495 friendList.Add(fi);
497 } 496 }
498 497
@@ -558,7 +557,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
558 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);
559 558
560 // Check that the friendship doesn't exist yet 559 // Check that the friendship doesn't exist yet
561 FriendInfo[] finfos = GetFriends(principalID); 560 FriendInfo[] finfos = GetFriendsFromCache(principalID);
562 if (finfos != null) 561 if (finfos != null)
563 { 562 {
564 FriendInfo f = GetFriend(finfos, friendID); 563 FriendInfo f = GetFriend(finfos, friendID);
@@ -611,7 +610,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
611 return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName; 610 return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
612 } 611 }
613 612
614 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)
615 { 614 {
616 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);
617 616
@@ -628,7 +627,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
628 ccm.CreateCallingCard(client.AgentId, friendID, UUID.Zero); 627 ccm.CreateCallingCard(client.AgentId, friendID, UUID.Zero);
629 } 628 }
630 629
631 // Update the local cache 630 // Update the local cache.
632 RecacheFriends(client); 631 RecacheFriends(client);
633 632
634 // 633 //
@@ -656,18 +655,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
656 } 655 }
657 } 656 }
658 657
659 private void OnDenyFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) 658 private void OnDenyFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders)
660 { 659 {
661 m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID); 660 m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", client.AgentId, friendID);
662 661
663 DeleteFriendship(agentID, friendID); 662 DeleteFriendship(client.AgentId, friendID);
664 663
665 // 664 //
666 // Notify the friend 665 // Notify the friend
667 // 666 //
668 667
669 // Try local 668 // Try local
670 if (LocalFriendshipDenied(agentID, client.Name, friendID)) 669 if (LocalFriendshipDenied(client.AgentId, client.Name, friendID))
671 return; 670 return;
672 671
673 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); 672 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
@@ -678,7 +677,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
678 { 677 {
679 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); 678 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
680 if (region != null) 679 if (region != null)
681 m_FriendsSimConnector.FriendshipDenied(region, agentID, client.Name, friendID); 680 m_FriendsSimConnector.FriendshipDenied(region, client.AgentId, client.Name, friendID);
682 else 681 else
683 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);
684 } 683 }
@@ -715,23 +714,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
715 } 714 }
716 } 715 }
717 716
718 private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) 717 public void GrantRights(IClientAPI remoteClient, UUID friendID, int rights)
719 { 718 {
720 m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target); 719 UUID requester = remoteClient.AgentId;
721 720
722 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);
723 if (friends.Length == 0) 726 if (friends.Length == 0)
724 { 727 {
725 return; 728 return;
726 } 729 }
727 730
728 // Let's find the friend in this user's friend list 731 // Let's find the friend in this user's friend list
729 FriendInfo friend = GetFriend(friends, target); 732 FriendInfo friend = GetFriend(friends, friendID);
730 733
731 if (friend != null) // Found it 734 if (friend != null) // Found it
732 { 735 {
733 // Store it on the DB 736 // Store it on the DB
734 if (!StoreRights(requester, target, rights)) 737 if (!StoreRights(requester, friendID, rights))
735 { 738 {
736 remoteClient.SendAlertMessage("Unable to grant rights."); 739 remoteClient.SendAlertMessage("Unable to grant rights.");
737 return; 740 return;
@@ -742,17 +745,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
742 friend.MyFlags = rights; 745 friend.MyFlags = rights;
743 746
744 // Always send this back to the original client 747 // Always send this back to the original client
745 remoteClient.SendChangeUserRights(requester, target, rights); 748 remoteClient.SendChangeUserRights(requester, friendID, rights);
746 749
747 // 750 //
748 // Notify the friend 751 // Notify the friend
749 // 752 //
750 753
751 // Try local 754 // Try local
752 if (LocalGrantRights(requester, target, myFlags, rights)) 755 if (LocalGrantRights(requester, friendID, myFlags, rights))
753 return; 756 return;
754 757
755 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { target.ToString() }); 758 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
756 if (friendSessions != null && friendSessions.Length > 0) 759 if (friendSessions != null && friendSessions.Length > 0)
757 { 760 {
758 PresenceInfo friendSession = friendSessions[0]; 761 PresenceInfo friendSession = friendSessions[0];
@@ -761,12 +764,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
761 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); 764 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
762 // 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
763 // on the other end!! 766 // on the other end!!
764 m_FriendsSimConnector.GrantRights(region, requester, target, myFlags, rights); 767 m_FriendsSimConnector.GrantRights(region, requester, friendID, myFlags, rights);
765 } 768 }
766 } 769 }
767 } 770 }
768 else 771 else
769 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 }
770 } 775 }
771 776
772 protected virtual FriendInfo GetFriend(FriendInfo[] friends, UUID friendID) 777 protected virtual FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
@@ -810,7 +815,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
810 ccm.CreateCallingCard(friendID, userID, UUID.Zero); 815 ccm.CreateCallingCard(friendID, userID, UUID.Zero);
811 } 816 }
812 817
813
814 // Update the local cache 818 // Update the local cache
815 RecacheFriends(friendClient); 819 RecacheFriends(friendClient);
816 820
@@ -904,20 +908,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
904 #endregion 908 #endregion
905 909
906 #region Get / Set friends in several flavours 910 #region Get / Set friends in several flavours
907 /// <summary> 911
908 /// Get friends from local cache only 912 public FriendInfo[] GetFriendsFromCache(UUID userID)
909 /// </summary>
910 /// <param name="agentID"></param>
911 /// <returns>
912 /// An empty array if the user has no friends or friends have not been cached.
913 /// </returns>
914 protected FriendInfo[] GetFriends(UUID agentID)
915 { 913 {
916 UserFriendData friendsData; 914 UserFriendData friendsData;
917 915
918 lock (m_Friends) 916 lock (m_Friends)
919 { 917 {
920 if (m_Friends.TryGetValue(agentID, out friendsData)) 918 if (m_Friends.TryGetValue(userID, out friendsData))
921 return friendsData.Friends; 919 return friendsData.Friends;
922 } 920 }
923 921
@@ -935,13 +933,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
935 // Update local cache 933 // Update local cache
936 lock (m_Friends) 934 lock (m_Friends)
937 { 935 {
938 FriendInfo[] friends = GetFriends(friendID); 936 FriendInfo[] friends = GetFriendsFromCache(friendID);
939 FriendInfo finfo = GetFriend(friends, userID); 937 FriendInfo finfo = GetFriend(friends, userID);
940 finfo.TheirFlags = rights; 938 finfo.TheirFlags = rights;
941 } 939 }
942 } 940 }
943 941
944 protected virtual FriendInfo[] GetFriendsFromService(IClientAPI client) 942 public virtual FriendInfo[] GetFriendsFromService(IClientAPI client)
945 { 943 {
946 return FriendsService.GetFriends(client.AgentId); 944 return FriendsService.GetFriends(client.AgentId);
947 } 945 }
@@ -959,12 +957,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
959 } 957 }
960 } 958 }
961 959
962 /// <summary> 960 public bool AreFriendsCached(UUID userID)
963 /// Are friends cached on this simulator for a particular user?
964 /// </summary>
965 /// <param name="userID"></param>
966 /// <returns></returns>
967 protected bool AreFriendsCached(UUID userID)
968 { 961 {
969 lock (m_Friends) 962 lock (m_Friends)
970 return m_Friends.ContainsKey(userID); 963 return m_Friends.ContainsKey(userID);
@@ -983,8 +976,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
983 976
984 protected virtual void StoreFriendships(UUID agentID, UUID friendID) 977 protected virtual void StoreFriendships(UUID agentID, UUID friendID)
985 { 978 {
986 FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1); 979 FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), (int)FriendRights.CanSeeOnline);
987 FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1); 980 FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), (int)FriendRights.CanSeeOnline);
988 } 981 }
989 982
990 protected virtual bool DeleteFriendship(UUID agentID, UUID exfriendID) 983 protected virtual bool DeleteFriendship(UUID agentID, UUID exfriendID)
@@ -995,61 +988,5 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
995 } 988 }
996 989
997 #endregion 990 #endregion
998
999 protected void HandleFriendsShowCacheCommand(string module, string[] cmd)
1000 {
1001 if (cmd.Length != 5)
1002 {
1003 MainConsole.Instance.OutputFormat("Usage: friends show cache [<first-name> <last-name>]");
1004 return;
1005 }
1006
1007 string firstName = cmd[3];
1008 string lastName = cmd[4];
1009
1010 IUserManagement umModule = m_Scenes[0].RequestModuleInterface<IUserManagement>();
1011 UUID userId = umModule.GetUserIdByName(firstName, lastName);
1012
1013// UserAccount ua
1014// = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, firstName, lastName);
1015
1016 if (userId == UUID.Zero)
1017 {
1018 MainConsole.Instance.OutputFormat("No such user as {0} {1}", firstName, lastName);
1019 return;
1020 }
1021
1022 if (!AreFriendsCached(userId))
1023 {
1024 MainConsole.Instance.OutputFormat("No friends cached on this simulator for {0} {1}", firstName, lastName);
1025 return;
1026 }
1027
1028 MainConsole.Instance.OutputFormat("Cached friends for {0} {1}:", firstName, lastName);
1029
1030 MainConsole.Instance.OutputFormat("UUID\n");
1031
1032 FriendInfo[] friends = GetFriends(userId);
1033
1034 foreach (FriendInfo friend in friends)
1035 {
1036// MainConsole.Instance.OutputFormat(friend.PrincipalID.ToString());
1037
1038// string friendFirstName, friendLastName;
1039//
1040// UserAccount friendUa
1041// = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friend.PrincipalID);
1042
1043 UUID friendId;
1044 string friendName;
1045
1046 if (UUID.TryParse(friend.Friend, out friendId))
1047 friendName = umModule.GetUserName(friendId);
1048 else
1049 friendName = friend.Friend;
1050
1051 MainConsole.Instance.OutputFormat("{0} {1} {2}", friendName, friend.MyFlags, friend.TheirFlags);
1052 }
1053 }
1054 } 991 }
1055} \ No newline at end of file 992}
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
index e50a84a..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)
@@ -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 {
@@ -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/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index aaba7fd..6fc8e4d 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -71,7 +71,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
71 if (name == Name) 71 if (name == Name)
72 { 72 {
73 InitialiseCommon(source); 73 InitialiseCommon(source);
74 IConfig transferConfig = source.Configs["HGEntityTransfer"]; 74 IConfig transferConfig = source.Configs["HGEntityTransferModule"];
75 if (transferConfig != null) 75 if (transferConfig != null)
76 m_RestrictInventoryAccessAbroad = transferConfig.GetBoolean("RestrictInventoryAccessAbroad", false); 76 m_RestrictInventoryAccessAbroad = transferConfig.GetBoolean("RestrictInventoryAccessAbroad", false);
77 77
@@ -94,6 +94,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
94 client.OnTeleportHomeRequest += TriggerTeleportHome; 94 client.OnTeleportHomeRequest += TriggerTeleportHome;
95 client.OnTeleportLandmarkRequest += RequestTeleportLandmark; 95 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
96 client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed); 96 client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed);
97 client.OnCompleteMovementToRegion += new Action<IClientAPI, bool>(OnCompleteMovementToRegion);
98 }
99
100 protected void OnCompleteMovementToRegion(IClientAPI client, bool arg2)
101 {
102 // HACK HACK -- just seeing how the viewer responds
103 // Let's send the Suitcase or the real root folder folder for incoming HG agents
104 // Visiting agents get their suitcase contents; incoming local users get their real root folder's content
105 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: OnCompleteMovementToRegion of user {0}", client.AgentId);
106 object sp = null;
107 if (client.Scene.TryGetScenePresence(client.AgentId, out sp))
108 {
109 if (sp is ScenePresence)
110 {
111 AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId);
112 if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
113 {
114 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: ViaHGLogin");
115 if (m_RestrictInventoryAccessAbroad)
116 {
117 RestoreRootFolderContents(client);
118 }
119 }
120 }
121 }
97 } 122 }
98 123
99 124
@@ -105,6 +130,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
105 { 130 {
106 m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); 131 m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService);
107 m_Initialized = true; 132 m_Initialized = true;
133
134 scene.AddCommand(
135 "HG", this, "send inventory",
136 "send inventory",
137 "Don't use this",
138 HandleSendInventory);
139
108 } 140 }
109 141
110 } 142 }
@@ -374,7 +406,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
374 InventoryFolderBase root = m_Scenes[0].InventoryService.GetRootFolder(client.AgentId); 406 InventoryFolderBase root = m_Scenes[0].InventoryService.GetRootFolder(client.AgentId);
375 if (root != null) 407 if (root != null)
376 { 408 {
377 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Removing root inventory"); 409 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Removing root inventory for user {0}", client.AgentId);
378 InventoryCollection content = m_Scenes[0].InventoryService.GetFolderContent(client.AgentId, root.ID); 410 InventoryCollection content = m_Scenes[0].InventoryService.GetFolderContent(client.AgentId, root.ID);
379 UUID[] ids = new UUID[content.Folders.Count]; 411 UUID[] ids = new UUID[content.Folders.Count];
380 int i = 0; 412 int i = 0;
@@ -393,12 +425,26 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
393 425
394 private void RestoreRootFolderContents(IClientAPI client) 426 private void RestoreRootFolderContents(IClientAPI client)
395 { 427 {
396 // Restore the user's inventory, because we removed it earlier on 428 if (client is IClientCore)
397 InventoryFolderBase root = m_Scenes[0].InventoryService.GetRootFolder(client.AgentId);
398 if (root != null)
399 { 429 {
400 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Restoring root inventory"); 430 IClientCore core = (IClientCore)client;
401 client.SendBulkUpdateInventory(root); 431 IClientInventory inv;
432
433 if (core.TryGet<IClientInventory>(out inv))
434 {
435 InventoryFolderBase root = m_Scenes[0].InventoryService.GetRootFolder(client.AgentId);
436 client.SendBulkUpdateInventory(root);
437 //if (root != null)
438 //{
439 // m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Restoring root inventory for user {0}", client.AgentId);
440 // InventoryCollection content = m_Scenes[0].InventoryService.GetFolderContent(client.AgentId, root.ID);
441 // m_log.DebugFormat("[XXX]: Folder name {0}, id {1}, parent {2}", root.Name, root.ID, root.ParentID);
442 // foreach (InventoryItemBase i in content.Items)
443 // m_log.DebugFormat("[XXX]: Name={0}, folderID={1}", i.Name, i.Folder);
444
445 // inv.SendBulkUpdateInventory(content.Folders.ToArray(), content.Items.ToArray());
446 //}
447 }
402 } 448 }
403 } 449 }
404 450
@@ -418,5 +464,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
418 region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), (int)0); 464 region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), (int)0);
419 return region; 465 return region;
420 } 466 }
467
468 protected void HandleSendInventory(string module, string[] cmd)
469 {
470 m_Scenes[0].ForEachClient(delegate(IClientAPI client)
471 {
472 RestoreRootFolderContents(client);
473 });
474 }
475
421 } 476 }
422} 477}
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/MapImage/MapImageServiceModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
index 6d3ace9..3b862da 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
@@ -93,8 +93,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
93 if (config == null) 93 if (config == null)
94 return; 94 return;
95 95
96 int refreshminutes = Convert.ToInt32(config.GetString("RefreshTime")); 96 int refreshminutes = Convert.ToInt32(config.GetString("RefreshTime", "-1"));
97 if (refreshminutes <= 0) 97 if (refreshminutes < 0)
98 { 98 {
99 m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: No refresh time given in config. Module disabled."); 99 m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: No refresh time given in config. Module disabled.");
100 return; 100 return;
@@ -117,12 +117,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
117 return; 117 return;
118 } 118 }
119 119
120 m_refreshTimer.Enabled = true; 120 if (m_refreshtime > 0)
121 m_refreshTimer.AutoReset = true; 121 {
122 m_refreshTimer.Interval = m_refreshtime; 122 m_refreshTimer.Enabled = true;
123 m_refreshTimer.Elapsed += new ElapsedEventHandler(HandleMaptileRefresh); 123 m_refreshTimer.AutoReset = true;
124 m_refreshTimer.Interval = m_refreshtime;
125 m_refreshTimer.Elapsed += new ElapsedEventHandler(HandleMaptileRefresh);
126 }
124 127
125 m_log.InfoFormat("[MAP IMAGE SERVICE MODULE]: enabled with refresh time {0}min and service object {1}", 128 m_log.InfoFormat("[MAP IMAGE SERVICE MODULE]: enabled with refresh time {0} min and service object {1}",
126 refreshminutes, service); 129 refreshminutes, service);
127 130
128 m_enabled = true; 131 m_enabled = true;
@@ -238,4 +241,4 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
238 } 241 }
239 } 242 }
240 } 243 }
241} \ No newline at end of file 244}
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/CoreModules/World/Warp3DMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs
index 6163fd1..e6f2855 100644
--- a/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs
+++ b/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs
@@ -64,6 +64,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
64 private bool m_useAntiAliasing = false; // TODO: Make this a config option 64 private bool m_useAntiAliasing = false; // TODO: Make this a config option
65 private bool m_Enabled = false; 65 private bool m_Enabled = false;
66 66
67 private Bitmap lastImage = null;
68 private DateTime lastImageTime = DateTime.MinValue;
69
67 #region IRegionModule Members 70 #region IRegionModule Members
68 71
69 public void Initialise(IConfigSource source) 72 public void Initialise(IConfigSource source)
@@ -86,14 +89,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
86 89
87 List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); 90 List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory());
88 if (renderers.Count > 0) 91 if (renderers.Count > 0)
89 { 92 m_log.Info("[MAPTILE]: Loaded prim mesher " + renderers[0]);
90 m_primMesher = RenderingLoader.LoadRenderer(renderers[0]);
91 m_log.Info("[MAPTILE]: Loaded prim mesher " + m_primMesher.ToString());
92 }
93 else 93 else
94 {
95 m_log.Info("[MAPTILE]: No prim mesher loaded, prim rendering will be disabled"); 94 m_log.Info("[MAPTILE]: No prim mesher loaded, prim rendering will be disabled");
96 }
97 95
98 m_scene.RegisterModuleInterface<IMapImageGenerator>(this); 96 m_scene.RegisterModuleInterface<IMapImageGenerator>(this);
99 } 97 }
@@ -126,9 +124,25 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
126 124
127 public Bitmap CreateMapTile() 125 public Bitmap CreateMapTile()
128 { 126 {
127 if ((DateTime.Now - lastImageTime).TotalSeconds < 3600)
128 {
129 return lastImage.Clone(new Rectangle(0, 0, 256, 256), lastImage.PixelFormat);
130 }
131
132 List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory());
133 if (renderers.Count > 0)
134 {
135 m_primMesher = RenderingLoader.LoadRenderer(renderers[0]);
136 }
137
129 Vector3 camPos = new Vector3(127.5f, 127.5f, 221.7025033688163f); 138 Vector3 camPos = new Vector3(127.5f, 127.5f, 221.7025033688163f);
130 Viewport viewport = new Viewport(camPos, -Vector3.UnitZ, 1024f, 0.1f, (int)Constants.RegionSize, (int)Constants.RegionSize, (float)Constants.RegionSize, (float)Constants.RegionSize); 139 Viewport viewport = new Viewport(camPos, -Vector3.UnitZ, 1024f, 0.1f, (int)Constants.RegionSize, (int)Constants.RegionSize, (float)Constants.RegionSize, (float)Constants.RegionSize);
131 return CreateMapTile(viewport, false); 140 Bitmap tile = CreateMapTile(viewport, false);
141 m_primMesher = null;
142
143 lastImage = tile;
144 lastImageTime = DateTime.Now;
145 return lastImage.Clone(new Rectangle(0, 0, 256, 256), lastImage.PixelFormat);
132 } 146 }
133 147
134 public Bitmap CreateViewImage(Vector3 camPos, Vector3 camDir, float fov, int width, int height, bool useTextures) 148 public Bitmap CreateViewImage(Vector3 camPos, Vector3 camDir, float fov, int width, int height, bool useTextures)
@@ -655,4 +669,4 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
655 return result; 669 return result;
656 } 670 }
657 } 671 }
658} \ No newline at end of file 672}
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/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 470ce2e..741d233 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -75,6 +75,7 @@ namespace OpenSim.Region.Framework.Scenes
75 /// Triggered when a new client is added to the scene. 75 /// Triggered when a new client is added to the scene.
76 /// </summary> 76 /// </summary>
77 /// <remarks> 77 /// <remarks>
78 /// This is triggered for both child and root agent client connections.
78 /// Triggered before OnClientLogin. 79 /// Triggered before OnClientLogin.
79 /// </remarks> 80 /// </remarks>
80 public event OnNewClientDelegate OnNewClient; 81 public event OnNewClientDelegate OnNewClient;
@@ -195,7 +196,7 @@ namespace OpenSim.Region.Framework.Scenes
195 public delegate void ClientClosed(UUID clientID, Scene scene); 196 public delegate void ClientClosed(UUID clientID, Scene scene);
196 197
197 /// <summary> 198 /// <summary>
198 /// Fired when a client is removed from a scene. 199 /// Fired when a client is removed from a scene whether it's a child or a root agent.
199 /// </summary> 200 /// </summary>
200 /// <remarks> 201 /// <remarks>
201 /// At the point of firing, the scene still contains the client's scene presence. 202 /// At the point of firing, the scene still contains the client's scene presence.
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index cac178d..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(
@@ -2795,6 +2801,10 @@ namespace OpenSim.Region.Framework.Scenes
2795 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); 2801 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName);
2796 } 2802 }
2797 2803
2804 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
2805 // client is for a root or child agent.
2806 client.SceneAgent = sp;
2807
2798 m_LastLogin = Util.EnvironmentTickCount(); 2808 m_LastLogin = Util.EnvironmentTickCount();
2799 2809
2800 // Cache the user's name 2810 // Cache the user's name
@@ -4344,7 +4354,7 @@ namespace OpenSim.Region.Framework.Scenes
4344 { 4354 {
4345 if (ent is SceneObjectGroup) 4355 if (ent is SceneObjectGroup)
4346 { 4356 {
4347 SceneObjectPart part = ((SceneObjectGroup)ent).GetChildPart(((SceneObjectGroup)ent).UUID); 4357 SceneObjectPart part = ((SceneObjectGroup)ent).GetPart(((SceneObjectGroup)ent).UUID);
4348 if (part != null) 4358 if (part != null)
4349 { 4359 {
4350 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/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index ee8a236..ed3a7f1 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1237,22 +1237,6 @@ namespace OpenSim.Region.Framework.Scenes
1237 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1237 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1238 } 1238 }
1239 1239
1240 // HACK HACK -- just seeing how the viewer responds
1241 // Let's send the Suitcase or the real root folder folder for incoming HG agents
1242 // Visiting agents get their suitcase contents; incoming local users get their real root folder's content
1243 AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(UUID);
1244 if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
1245 {
1246 // HACK FOR NOW. JUST TESTING, SO KEEPING EVERYONE ELSE OUT OF THESE TESTS
1247 IConfig config = m_scene.Config.Configs["HGEntityTransferModule"];
1248 if (config != null && config.GetBoolean("RestrictInventoryAccessAbroad", false))
1249 {
1250 m_log.DebugFormat("[SCENE]: Sending root folder to viewer...");
1251 InventoryFolderBase root = m_scene.InventoryService.GetRootFolder(client.AgentId);
1252 //InventoryCollection rootContents = InventoryService.GetFolderContent(client.AgentId, root.ID);
1253 client.SendBulkUpdateInventory(root);
1254 }
1255 }
1256 1240
1257// m_log.DebugFormat( 1241// m_log.DebugFormat(
1258// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", 1242// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 655f3a5..a37e997 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -55,7 +55,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
55 55
56 private UUID m_agentID = UUID.Random(); 56 private UUID m_agentID = UUID.Random();
57 57
58 public ISceneAgent SceneAgent { get; private set; } 58 public ISceneAgent SceneAgent { get; set; }
59 59
60 private string m_username; 60 private string m_username;
61 private string m_nick; 61 private string m_nick;
@@ -903,7 +903,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
903 903
904 public void Start() 904 public void Start()
905 { 905 {
906 SceneAgent = m_scene.AddNewClient(this, PresenceType.User); 906 m_scene.AddNewClient(this, PresenceType.User);
907 907
908 // Mimicking LLClientView which gets always set appearance from client. 908 // Mimicking LLClientView which gets always set appearance from client.
909 AvatarAppearance appearance; 909 AvatarAppearance appearance;
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/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index a2375fe..c3335f0 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -72,7 +72,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
72 get { return m_ownerID; } 72 get { return m_ownerID; }
73 } 73 }
74 74
75 public ISceneAgent SceneAgent { get { throw new NotImplementedException(); } } 75 public ISceneAgent SceneAgent { get; set; }
76 76
77 public void Say(string message) 77 public void Say(string message)
78 { 78 {
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..ce05b8c 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
@@ -4680,12 +4680,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4680 // agent must not be a god 4680 // agent must not be a god
4681 if (presence.GodLevel >= 200) return; 4681 if (presence.GodLevel >= 200) return;
4682 4682
4683 if (simname == String.Empty)
4684 simname = World.RegionInfo.RegionName;
4685
4683 // agent must be over the owners land 4686 // agent must be over the owners land
4684 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4687 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4685 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4688 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4686 { 4689 {
4687 World.RequestTeleportLocation(presence.ControllingClient, simname, new Vector3((float)pos.x, (float)pos.y, (float)pos.z), new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z), (uint)TeleportFlags.ViaLocation); 4690 World.RequestTeleportLocation(presence.ControllingClient, simname, new Vector3((float)pos.x, (float)pos.y, (float)pos.z), new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z), (uint)TeleportFlags.ViaLocation);
4688 } 4691 }
4692 else // or must be wearing the prim
4693 {
4694 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4695 {
4696 World.RequestTeleportLocation(presence.ControllingClient, simname, new Vector3((float)pos.x, (float)pos.y, (float)pos.z), new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z), (uint)TeleportFlags.ViaLocation);
4697 }
4698 }
4689 } 4699 }
4690 } 4700 }
4691 } 4701 }
diff --git a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs
new file mode 100644
index 0000000..cb686e2
--- /dev/null
+++ b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs
@@ -0,0 +1,466 @@
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 OpenMetaverse;
32using log4net;
33using Nini.Config;
34using System.Reflection;
35using OpenSim.Services.Base;
36using OpenSim.Services.Interfaces;
37using OpenSim.Services.InventoryService;
38using OpenSim.Data;
39using OpenSim.Framework;
40using OpenSim.Server.Base;
41
42namespace OpenSim.Services.HypergridService
43{
44 /// <summary>
45 /// Hypergrid inventory service. It serves the IInventoryService interface,
46 /// but implements it in ways that are appropriate for inter-grid
47 /// inventory exchanges. Specifically, it does not performs deletions
48 /// and it responds to GetRootFolder requests with the ID of the
49 /// Suitcase folder, not the actual "My Inventory" folder.
50 /// </summary>
51 public class HGSuitcaseInventoryService : XInventoryService, IInventoryService
52 {
53 private static readonly ILog m_log =
54 LogManager.GetLogger(
55 MethodBase.GetCurrentMethod().DeclaringType);
56
57 private string m_HomeURL;
58 private IUserAccountService m_UserAccountService;
59
60 private UserAccountCache m_Cache;
61
62 private ExpiringCache<UUID, List<XInventoryFolder>> m_SuitcaseTrees = new ExpiringCache<UUID,List<XInventoryFolder>>();
63
64 public HGSuitcaseInventoryService(IConfigSource config, string configName)
65 : base(config, configName)
66 {
67 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Starting with config name {0}", configName);
68 if (configName != string.Empty)
69 m_ConfigName = configName;
70
71 if (m_Database == null)
72 m_log.WarnFormat("[XXX]: m_Database is null!");
73
74 //
75 // Try reading the [InventoryService] section, if it exists
76 //
77 IConfig invConfig = config.Configs[m_ConfigName];
78 if (invConfig != null)
79 {
80 // realm = authConfig.GetString("Realm", realm);
81 string userAccountsDll = invConfig.GetString("UserAccountsService", string.Empty);
82 if (userAccountsDll == string.Empty)
83 throw new Exception("Please specify UserAccountsService in HGInventoryService configuration");
84
85 Object[] args = new Object[] { config };
86 m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(userAccountsDll, args);
87 if (m_UserAccountService == null)
88 throw new Exception(String.Format("Unable to create UserAccountService from {0}", userAccountsDll));
89
90 // legacy configuration [obsolete]
91 m_HomeURL = invConfig.GetString("ProfileServerURI", string.Empty);
92 // Preferred
93 m_HomeURL = invConfig.GetString("HomeURI", m_HomeURL);
94
95 m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService);
96 }
97
98 m_log.Debug("[HG SUITCASE INVENTORY SERVICE]: Starting...");
99 }
100
101 public override bool CreateUserInventory(UUID principalID)
102 {
103 // NOGO
104 return false;
105 }
106
107
108 public override List<InventoryFolderBase> GetInventorySkeleton(UUID principalID)
109 {
110 // NOGO for this inventory service
111 return new List<InventoryFolderBase>();
112 }
113
114 public override InventoryFolderBase GetRootFolder(UUID principalID)
115 {
116 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetRootFolder for {0}", principalID);
117 if (m_Database == null)
118 m_log.ErrorFormat("[XXX]: m_Database is NULL!");
119
120 // Let's find out the local root folder
121 XInventoryFolder root = GetRootXFolder(principalID); ;
122 if (root == null)
123 {
124 m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: Unable to retrieve local root folder for user {0}", principalID);
125 }
126
127 // Warp! Root folder for travelers is the suitcase folder
128 XInventoryFolder suitcase = GetSuitcaseXFolder(principalID);
129
130 if (suitcase == null)
131 {
132 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: User {0} does not have a Suitcase folder. Creating it...", principalID);
133 // make one, and let's add it to the user's inventory as a direct child of the root folder
134 suitcase = CreateFolder(principalID, root.folderID, 100, "My Suitcase");
135 if (suitcase == null)
136 m_log.ErrorFormat("[HG SUITCASE INVENTORY SERVICE]: Unable to create suitcase folder");
137
138 m_Database.StoreFolder(suitcase);
139 }
140
141 // Now let's change the folder ID to match that of the real root folder
142 SetAsRootFolder(suitcase, root.folderID);
143
144 return ConvertToOpenSim(suitcase);
145 }
146
147 public override InventoryFolderBase GetFolderForType(UUID principalID, AssetType type)
148 {
149 //m_log.DebugFormat("[HG INVENTORY SERVICE]: GetFolderForType for {0} {0}", principalID, type);
150 return GetRootFolder(principalID);
151 }
152
153 public override InventoryCollection GetFolderContent(UUID principalID, UUID folderID)
154 {
155 InventoryCollection coll = null;
156 XInventoryFolder suitcase = GetSuitcaseXFolder(principalID);
157 XInventoryFolder root = GetRootXFolder(principalID);
158
159 if (!IsWithinSuitcaseTree(folderID, root, suitcase))
160 return new InventoryCollection();
161
162 if (folderID == root.folderID) // someone's asking for the root folder, we'll give them the suitcase
163 {
164 if (suitcase != null)
165 {
166 coll = base.GetFolderContent(principalID, suitcase.folderID);
167 foreach (InventoryFolderBase f in coll.Folders)
168 f.ParentID = root.folderID;
169 foreach (InventoryItemBase i in coll.Items)
170 i.Folder = root.folderID;
171 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetFolderContent for root folder returned content for suitcase folder");
172 }
173 }
174 else
175 {
176 coll = base.GetFolderContent(principalID, folderID);
177 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetFolderContent for non-root folder {0}", folderID);
178 }
179 if (coll == null)
180 {
181 m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: Something wrong with user {0}'s suitcase folder", principalID);
182 coll = new InventoryCollection();
183 }
184 return coll;
185 }
186
187 public override List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID)
188 {
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);
193
194 if (!IsWithinSuitcaseTree(folderID, root, suitcase))
195 return new List<InventoryItemBase>();
196
197 return base.GetFolderItems(principalID, folderID);
198 }
199
200 public override bool AddFolder(InventoryFolderBase folder)
201 {
202 // Let's do a bit of sanity checking, more than the base service does
203 // make sure the given folder's parent folder exists under the suitcase tree of this user
204 XInventoryFolder root = GetRootXFolder(folder.Owner);
205 XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner);
206
207 if (!IsWithinSuitcaseTree(folder.ParentID, root, suitcase))
208 return false;
209
210 // OK, it's legit
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);
231 }
232
233 public override bool MoveFolder(InventoryFolderBase folder)
234 {
235 XInventoryFolder root = GetRootXFolder(folder.Owner);
236 XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner);
237
238 if (!IsWithinSuitcaseTree(folder.ID, root, suitcase) || !IsWithinSuitcaseTree(folder.ParentID, root, suitcase))
239 return false;
240
241 if (folder.ParentID == root.folderID)
242 {
243 // someone's trying to add a subfolder of the root folder, we'll add it to the suitcase instead
244 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: MoveFolder to root folder for user {0}. Moving it to suitcase instead", folder.Owner);
245 folder.ParentID = suitcase.folderID;
246 }
247
248 return base.MoveFolder(folder);
249 }
250
251 public override bool DeleteFolders(UUID principalID, List<UUID> folderIDs)
252 {
253 // NOGO
254 return false;
255 }
256
257 public override bool PurgeFolder(InventoryFolderBase folder)
258 {
259 // NOGO
260 return false;
261 }
262
263 public override bool AddItem(InventoryItemBase item)
264 {
265 // Let's do a bit of sanity checking, more than the base service does
266 // make sure the given folder's parent folder exists under the suitcase tree of this user
267 XInventoryFolder root = GetRootXFolder(item.Owner);
268 XInventoryFolder suitcase = GetSuitcaseXFolder(item.Owner);
269
270 if (!IsWithinSuitcaseTree(item.Folder, root, suitcase))
271 return false;
272
273 // OK, it's legit
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 }
281
282 return base.AddItem(item);
283
284 }
285
286 public override bool UpdateItem(InventoryItemBase item)
287 {
288 XInventoryFolder root = GetRootXFolder(item.Owner);
289 XInventoryFolder suitcase = GetSuitcaseXFolder(item.Owner);
290
291 if (!IsWithinSuitcaseTree(item.Folder, root, suitcase))
292 return false;
293
294 return base.UpdateItem(item);
295 }
296
297 public override bool MoveItems(UUID principalID, List<InventoryItemBase> items)
298 {
299 // Principal is b0rked. *sigh*
300
301 XInventoryFolder root = GetRootXFolder(items[0].Owner);
302 XInventoryFolder suitcase = GetSuitcaseXFolder(items[0].Owner);
303
304 if (!IsWithinSuitcaseTree(items[0].Folder, root, suitcase))
305 return false;
306
307 foreach (InventoryItemBase it in items)
308 if (it.Folder == root.folderID)
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 }
318
319 // Let these pass. Use inherited methods.
320 public override bool DeleteItems(UUID principalID, List<UUID> itemIDs)
321 {
322 return false;
323 }
324
325 public override InventoryItemBase GetItem(InventoryItemBase item)
326 {
327 InventoryItemBase it = base.GetItem(item);
328 XInventoryFolder root = GetRootXFolder(it.Owner);
329 XInventoryFolder suitcase = GetSuitcaseXFolder(it.Owner);
330
331 if (it != null)
332 {
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 }
367
368 //public List<InventoryItemBase> GetActiveGestures(UUID principalID)
369 //{
370 //}
371
372 //public int GetAssetPermissions(UUID principalID, UUID assetID)
373 //{
374 //}
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
389 private XInventoryFolder GetRootXFolder(UUID principalID)
390 {
391 XInventoryFolder[] folders = m_Database.GetFolders(
392 new string[] { "agentID", "folderName", "type" },
393 new string[] { principalID.ToString(), "My Inventory", ((int)AssetType.RootFolder).ToString() });
394
395 if (folders != null && folders.Length > 0)
396 return folders[0];
397 return null;
398 }
399
400 private XInventoryFolder GetSuitcaseXFolder(UUID principalID)
401 {
402 // Warp! Root folder for travelers
403 XInventoryFolder[] folders = m_Database.GetFolders(
404 new string[] { "agentID", "type" },
405 new string[] { principalID.ToString(), "100" }); // This is a special folder type...
406
407 if (folders != null && folders.Length > 0)
408 return folders[0];
409 return null;
410 }
411
412 private void SetAsRootFolder(XInventoryFolder suitcase, UUID rootID)
413 {
414 suitcase.folderID = rootID;
415 suitcase.parentFolderID = UUID.Zero;
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
465 }
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 81a5cf7..6a7cb0a 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -329,7 +329,7 @@ namespace OpenSim.Tests.Common.Mock
329 /// </value> 329 /// </value>
330 private UUID m_agentId; 330 private UUID m_agentId;
331 331
332 public ISceneAgent SceneAgent { get { throw new NotImplementedException(); } } 332 public ISceneAgent SceneAgent { get; set; }
333 333
334 /// <value> 334 /// <value>
335 /// The last caps seed url that this client was given. 335 /// The last caps seed url that this client was given.
@@ -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