aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs81
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs31
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs30
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs103
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs3
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs9
-rw-r--r--OpenSim/Region/Framework/Interfaces/IFriendsModule.cs11
-rw-r--r--OpenSim/Region/Framework/Scenes/EntityBase.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/EntityManager.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs23
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs49
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs79
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs14
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsActor.cs16
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs6
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs11
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs7
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs91
-rw-r--r--OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs2
20 files changed, 301 insertions, 281 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index 0c81bb2..5d94ff7 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Reflection; 31using System.Reflection;
32using System.Threading;
32using log4net; 33using log4net;
33using Nini.Config; 34using Nini.Config;
34using Nwc.XmlRpc; 35using Nwc.XmlRpc;
@@ -79,10 +80,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
79 protected IFriendsService m_FriendsService = null; 80 protected IFriendsService m_FriendsService = null;
80 protected FriendsSimConnector m_FriendsSimConnector; 81 protected FriendsSimConnector m_FriendsSimConnector;
81 82
82 protected Dictionary<UUID, UserFriendData> m_Friends = 83 /// <summary>
83 new Dictionary<UUID, UserFriendData>(); 84 /// Cache friends lists for users.
85 /// </summary>
86 /// <remarks>
87 /// This is a complex and error-prone thing to do. At the moment, we assume that the efficiency gained in
88 /// permissions checks outweighs the disadvantages of that complexity.
89 /// </remarks>
90 protected Dictionary<UUID, UserFriendData> m_Friends = new Dictionary<UUID, UserFriendData>();
84 91
85 protected HashSet<UUID> m_NeedsListOfFriends = new HashSet<UUID>(); 92 /// <summary>
93 /// Maintain a record of viewers that need to be sent notifications for friends that are online. This only
94 /// needs to be done on login. Subsequent online/offline friend changes are sent by a different mechanism.
95 /// </summary>
96 protected HashSet<UUID> m_NeedsListOfOnlineFriends = new HashSet<UUID>();
86 97
87 protected IPresenceService PresenceService 98 protected IPresenceService PresenceService
88 { 99 {
@@ -189,6 +200,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
189 { 200 {
190 if (!m_Enabled) 201 if (!m_Enabled)
191 return; 202 return;
203
192 m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name); 204 m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
193 205
194 m_Scenes.Add(scene); 206 m_Scenes.Add(scene);
@@ -241,16 +253,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
241 client.OnInstantMessage += OnInstantMessage; 253 client.OnInstantMessage += OnInstantMessage;
242 client.OnApproveFriendRequest += OnApproveFriendRequest; 254 client.OnApproveFriendRequest += OnApproveFriendRequest;
243 client.OnDenyFriendRequest += OnDenyFriendRequest; 255 client.OnDenyFriendRequest += OnDenyFriendRequest;
244 client.OnTerminateFriendship += OnTerminateFriendship; 256 client.OnTerminateFriendship += (thisClient, agentID, exfriendID) => RemoveFriendship(thisClient, exfriendID);
245 client.OnGrantUserRights += OnGrantUserRights; 257 client.OnGrantUserRights += OnGrantUserRights;
246 258
247 Util.FireAndForget(delegate { FetchFriendslist(client); }); 259 // Do not do this asynchronously. If we do, then subsequent code can outrace CacheFriends() and
260 // return misleading results from the still empty friends cache.
261 // If we absolutely need to do this asynchronously, then a signalling mechanism is needed so that calls
262 // to GetFriends() will wait until CacheFriends() completes. Locks are insufficient.
263 CacheFriends(client);
248 } 264 }
249 265
250 /// Fetch the friends list or increment the refcount for the existing 266 /// <summary>
251 /// friends list 267 /// Cache the friends list or increment the refcount for the existing friends list.
268 /// </summary>
269 /// <param name="client">
270 /// </param>
271 /// <returns>
252 /// Returns true if the list was fetched, false if it wasn't 272 /// Returns true if the list was fetched, false if it wasn't
253 protected virtual bool FetchFriendslist(IClientAPI client) 273 /// </returns>
274 protected virtual bool CacheFriends(IClientAPI client)
254 { 275 {
255 UUID agentID = client.AgentId; 276 UUID agentID = client.AgentId;
256 lock (m_Friends) 277 lock (m_Friends)
@@ -297,7 +318,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
297 318
298 private void OnMakeRootAgent(ScenePresence sp) 319 private void OnMakeRootAgent(ScenePresence sp)
299 { 320 {
300 RefetchFriends(sp.ControllingClient); 321 RecacheFriends(sp.ControllingClient);
301 } 322 }
302 323
303 private void OnClientLogin(IClientAPI client) 324 private void OnClientLogin(IClientAPI client)
@@ -309,8 +330,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
309 StatusChange(agentID, true); 330 StatusChange(agentID, true);
310 331
311 // Register that we need to send the list of online friends to this user 332 // Register that we need to send the list of online friends to this user
312 lock (m_NeedsListOfFriends) 333 lock (m_NeedsListOfOnlineFriends)
313 m_NeedsListOfFriends.Add(agentID); 334 m_NeedsListOfOnlineFriends.Add(agentID);
314 } 335 }
315 336
316 public virtual bool SendFriendsOnlineIfNeeded(IClientAPI client) 337 public virtual bool SendFriendsOnlineIfNeeded(IClientAPI client)
@@ -318,9 +339,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
318 UUID agentID = client.AgentId; 339 UUID agentID = client.AgentId;
319 340
320 // Check if the online friends list is needed 341 // Check if the online friends list is needed
321 lock (m_NeedsListOfFriends) 342 lock (m_NeedsListOfOnlineFriends)
322 { 343 {
323 if (!m_NeedsListOfFriends.Remove(agentID)) 344 if (!m_NeedsListOfOnlineFriends.Remove(agentID))
324 return false; 345 return false;
325 } 346 }
326 347
@@ -328,7 +349,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
328 List<UUID> online = GetOnlineFriends(agentID); 349 List<UUID> online = GetOnlineFriends(agentID);
329 if (online.Count > 0) 350 if (online.Count > 0)
330 { 351 {
331 m_log.DebugFormat("[FRIENDS MODULE]: User {0} in region {1} has {2} friends online", client.AgentId, client.Scene.RegionInfo.RegionName, online.Count); 352 m_log.DebugFormat(
353 "[FRIENDS MODULE]: User {0} in region {1} has {2} friends online",
354 client.Name, client.Scene.RegionInfo.RegionName, online.Count);
355
332 client.SendAgentOnline(online.ToArray()); 356 client.SendAgentOnline(online.ToArray());
333 } 357 }
334 358
@@ -586,7 +610,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
586 } 610 }
587 611
588 // Update the local cache 612 // Update the local cache
589 RefetchFriends(client); 613 RecacheFriends(client);
590 614
591 // 615 //
592 // Notify the friend 616 // Notify the friend
@@ -641,14 +665,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
641 } 665 }
642 } 666 }
643 } 667 }
644 668
645 private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID) 669 public void RemoveFriendship(IClientAPI client, UUID exfriendID)
646 { 670 {
647 if (!DeleteFriendship(agentID, exfriendID)) 671 if (!DeleteFriendship(client.AgentId, exfriendID))
648 client.SendAlertMessage("Unable to terminate friendship on this sim."); 672 client.SendAlertMessage("Unable to terminate friendship on this sim.");
649 673
650 // Update local cache 674 // Update local cache
651 RefetchFriends(client); 675 RecacheFriends(client);
652 676
653 client.SendTerminateFriend(exfriendID); 677 client.SendTerminateFriend(exfriendID);
654 678
@@ -667,9 +691,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
667 if (friendSession != null) 691 if (friendSession != null)
668 { 692 {
669 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); 693 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
670 m_FriendsSimConnector.FriendshipTerminated(region, agentID, exfriendID); 694 m_FriendsSimConnector.FriendshipTerminated(region, client.AgentId, exfriendID);
671 } 695 }
672 } 696 }
673 } 697 }
674 698
675 private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) 699 private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
@@ -769,7 +793,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
769 793
770 794
771 // Update the local cache 795 // Update the local cache
772 RefetchFriends(friendClient); 796 RecacheFriends(friendClient);
773 797
774 // we're done 798 // we're done
775 return true; 799 return true;
@@ -802,7 +826,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
802 // the friend in this sim as root agent 826 // the friend in this sim as root agent
803 friendClient.SendTerminateFriend(exfriendID); 827 friendClient.SendTerminateFriend(exfriendID);
804 // update local cache 828 // update local cache
805 RefetchFriends(friendClient); 829 RecacheFriends(friendClient);
806 // we're done 830 // we're done
807 return true; 831 return true;
808 } 832 }
@@ -819,16 +843,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
819 if (onlineBitChanged) 843 if (onlineBitChanged)
820 { 844 {
821 if ((rights & (int)FriendRights.CanSeeOnline) == 1) 845 if ((rights & (int)FriendRights.CanSeeOnline) == 1)
822 friendClient.SendAgentOnline(new UUID[] { new UUID(userID) }); 846 friendClient.SendAgentOnline(new UUID[] { userID });
823 else 847 else
824 friendClient.SendAgentOffline(new UUID[] { new UUID(userID) }); 848 friendClient.SendAgentOffline(new UUID[] { userID });
825 } 849 }
826 else 850 else
827 { 851 {
828 bool canEditObjectsChanged = ((rights ^ userFlags) & (int)FriendRights.CanModifyObjects) != 0; 852 bool canEditObjectsChanged = ((rights ^ userFlags) & (int)FriendRights.CanModifyObjects) != 0;
829 if (canEditObjectsChanged) 853 if (canEditObjectsChanged)
830 friendClient.SendChangeUserRights(userID, friendID, rights); 854 friendClient.SendChangeUserRights(userID, friendID, rights);
831
832 } 855 }
833 856
834 // Update local cache 857 // Update local cache
@@ -847,7 +870,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
847 IClientAPI friendClient = LocateClientObject(friendID); 870 IClientAPI friendClient = LocateClientObject(friendID);
848 if (friendClient != null) 871 if (friendClient != null)
849 { 872 {
850 // the friend in this sim as root agent 873 // the friend in this sim as root agent
851 if (online) 874 if (online)
852 friendClient.SendAgentOnline(new UUID[] { userID }); 875 friendClient.SendAgentOnline(new UUID[] { userID });
853 else 876 else
@@ -902,8 +925,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
902 return FriendsService.GetFriends(client.AgentId); 925 return FriendsService.GetFriends(client.AgentId);
903 } 926 }
904 927
905 private void RefetchFriends(IClientAPI client) 928 private void RecacheFriends(IClientAPI client)
906 { 929 {
930 // FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event
931 // is on the critical path for transferring an avatar from one region to another.
907 UUID agentID = client.AgentId; 932 UUID agentID = client.AgentId;
908 lock (m_Friends) 933 lock (m_Friends)
909 { 934 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
index 02b417f..9a97925 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
@@ -30,7 +30,6 @@ using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Reflection; 31using System.Reflection;
32using System.Threading; 32using System.Threading;
33
34using log4net; 33using log4net;
35using Nini.Config; 34using Nini.Config;
36using Nwc.XmlRpc; 35using Nwc.XmlRpc;
@@ -84,9 +83,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
84 83
85 #endregion 84 #endregion
86 85
87 protected override bool FetchFriendslist(IClientAPI client) 86 protected override bool CacheFriends(IClientAPI client)
88 { 87 {
89 if (base.FetchFriendslist(client)) 88// m_log.DebugFormat("[HGFRIENDS MODULE]: Entered CacheFriends for {0}", client.Name);
89
90 if (base.CacheFriends(client))
90 { 91 {
91 UUID agentID = client.AgentId; 92 UUID agentID = client.AgentId;
92 // we do this only for the root agent 93 // we do this only for the root agent
@@ -110,14 +111,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
110 } 111 }
111 } 112 }
112 } 113 }
114
115// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting CacheFriends for {0} since detected root agent", client.Name);
113 return true; 116 return true;
114 } 117 }
115 } 118 }
119
120// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting CacheFriends for {0} since detected not root agent", client.Name);
116 return false; 121 return false;
117 } 122 }
118 123
119 public override bool SendFriendsOnlineIfNeeded(IClientAPI client) 124 public override bool SendFriendsOnlineIfNeeded(IClientAPI client)
120 { 125 {
126// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering SendFriendsOnlineIfNeeded for {0}", client.Name);
127
121 if (base.SendFriendsOnlineIfNeeded(client)) 128 if (base.SendFriendsOnlineIfNeeded(client))
122 { 129 {
123 AgentCircuitData aCircuit = ((Scene)client.Scene).AuthenticateHandler.GetAgentCircuitData(client.AgentId); 130 AgentCircuitData aCircuit = ((Scene)client.Scene).AuthenticateHandler.GetAgentCircuitData(client.AgentId);
@@ -134,11 +141,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
134 } 141 }
135 } 142 }
136 } 143 }
144
145// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting SendFriendsOnlineIfNeeded for {0}", client.Name);
137 return false; 146 return false;
138 } 147 }
139 148
140 protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online) 149 protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
141 { 150 {
151// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering GetOnlineFriends for {0}", userID);
152
142 List<string> fList = new List<string>(); 153 List<string> fList = new List<string>();
143 foreach (string s in friendList) 154 foreach (string s in friendList)
144 { 155 {
@@ -157,6 +168,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
157 if (UUID.TryParse(pi.UserID, out presenceID)) 168 if (UUID.TryParse(pi.UserID, out presenceID))
158 online.Add(presenceID); 169 online.Add(presenceID);
159 } 170 }
171
172// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetOnlineFriends for {0}", userID);
160 } 173 }
161 174
162 //protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online) 175 //protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
@@ -246,6 +259,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
246 259
247 protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online) 260 protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
248 { 261 {
262// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID);
263
249 // First, let's divide the friends on a per-domain basis 264 // First, let's divide the friends on a per-domain basis
250 Dictionary<string, List<FriendInfo>> friendsPerDomain = new Dictionary<string, List<FriendInfo>>(); 265 Dictionary<string, List<FriendInfo>> friendsPerDomain = new Dictionary<string, List<FriendInfo>>();
251 foreach (FriendInfo friend in friendList) 266 foreach (FriendInfo friend in friendList)
@@ -298,6 +313,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
298 } 313 }
299 } 314 }
300 } 315 }
316
317// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting StatusNotify for {0}", userID);
301 } 318 }
302 319
303 protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) 320 protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
@@ -351,6 +368,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
351 368
352 protected override FriendInfo[] GetFriendsFromService(IClientAPI client) 369 protected override FriendInfo[] GetFriendsFromService(IClientAPI client)
353 { 370 {
371// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering GetFriendsFromService for {0}", client.Name);
372
354 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId); 373 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId);
355 if (account1 != null) 374 if (account1 != null)
356 return base.GetFriendsFromService(client); 375 return base.GetFriendsFromService(client);
@@ -365,6 +384,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
365 finfos = FriendsService.GetFriends(agentUUI); 384 finfos = FriendsService.GetFriends(agentUUI);
366 m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI); 385 m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI);
367 } 386 }
387
388// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetFriendsFromService for {0}", client.Name);
389
368 return finfos; 390 return finfos;
369 } 391 }
370 392
@@ -401,7 +423,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
401 } 423 }
402 424
403 return false; 425 return false;
404
405 } 426 }
406 427
407 protected override void StoreBackwards(UUID friendID, UUID agentID) 428 protected override void StoreBackwards(UUID friendID, UUID agentID)
@@ -627,4 +648,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
627 } 648 }
628 } 649 }
629 } 650 }
630} 651} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs
index c945dcf..682fbab 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs
@@ -71,12 +71,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
71 71
72 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId); 72 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
73 73
74 Assert.That(((TestClient)sp.ControllingClient).OfflineNotificationsReceived.Count, Is.EqualTo(0)); 74 Assert.That(((TestClient)sp.ControllingClient).ReceivedOfflineNotifications.Count, Is.EqualTo(0));
75 Assert.That(((TestClient)sp.ControllingClient).OnlineNotificationsReceived.Count, Is.EqualTo(0)); 75 Assert.That(((TestClient)sp.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(0));
76 } 76 }
77 77
78 [Test] 78 [Test]
79 public void TestAddFriendWhileOnline() 79 public void TestAddFriendshipWhileOnline()
80 { 80 {
81 TestHelpers.InMethod(); 81 TestHelpers.InMethod();
82// log4net.Config.XmlConfigurator.Configure(); 82// log4net.Config.XmlConfigurator.Configure();
@@ -91,8 +91,28 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
91 // notification. 91 // notification.
92 m_fm.AddFriendship(sp.ControllingClient, user2Id); 92 m_fm.AddFriendship(sp.ControllingClient, user2Id);
93 93
94 Assert.That(((TestClient)sp.ControllingClient).OfflineNotificationsReceived.Count, Is.EqualTo(0)); 94 Assert.That(((TestClient)sp.ControllingClient).ReceivedOfflineNotifications.Count, Is.EqualTo(0));
95 Assert.That(((TestClient)sp.ControllingClient).OnlineNotificationsReceived.Count, Is.EqualTo(1)); 95 Assert.That(((TestClient)sp.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(1));
96 }
97
98 [Test]
99 public void TestRemoveFriendshipWhileOnline()
100 {
101 TestHelpers.InMethod();
102// log4net.Config.XmlConfigurator.Configure();
103
104 UUID user1Id = TestHelpers.ParseTail(0x1);
105 UUID user2Id = TestHelpers.ParseTail(0x2);
106
107 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, user1Id);
108 SceneHelpers.AddScenePresence(m_scene, user2Id);
109
110 m_fm.AddFriendship(sp.ControllingClient, user2Id);
111 m_fm.RemoveFriendship(sp.ControllingClient, user2Id);
112
113 TestClient user1Client = sp.ControllingClient as TestClient;
114 Assert.That(user1Client.ReceivedFriendshipTerminations.Count, Is.EqualTo(1));
115 Assert.That(user1Client.ReceivedFriendshipTerminations[0], Is.EqualTo(user2Id));
96 } 116 }
97 } 117 }
98} \ No newline at end of file 118} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index bef0d69..a40a6a4 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -31,7 +31,6 @@ using System.Reflection;
31 31
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Framework.Console; 33using OpenSim.Framework.Console;
34
35using OpenSim.Region.Framework; 34using OpenSim.Region.Framework;
36using OpenSim.Region.Framework.Interfaces; 35using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
@@ -44,13 +43,13 @@ using Nini.Config;
44 43
45namespace OpenSim.Region.CoreModules.Framework.UserManagement 44namespace OpenSim.Region.CoreModules.Framework.UserManagement
46{ 45{
47 struct UserData 46 class UserData
48 { 47 {
49 public UUID Id; 48 public UUID Id { get; set; }
50 public string FirstName; 49 public string FirstName { get; set; }
51 public string LastName; 50 public string LastName { get; set; }
52 public string HomeURL; 51 public string HomeURL { get; set; }
53 public Dictionary<string, object> ServerURLs; 52 public Dictionary<string, object> ServerURLs { get; set; }
54 } 53 }
55 54
56 public class UserManagementModule : ISharedRegionModule, IUserManagement 55 public class UserManagementModule : ISharedRegionModule, IUserManagement
@@ -130,7 +129,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
130 public void Close() 129 public void Close()
131 { 130 {
132 m_Scenes.Clear(); 131 m_Scenes.Clear();
133 m_UserCache.Clear(); 132
133 lock (m_UserCache)
134 m_UserCache.Clear();
134 } 135 }
135 136
136 #endregion ISharedRegionModule 137 #endregion ISharedRegionModule
@@ -188,11 +189,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
188 { 189 {
189 string[] returnstring = new string[2]; 190 string[] returnstring = new string[2];
190 191
191 if (m_UserCache.ContainsKey(uuid)) 192 lock (m_UserCache)
192 { 193 {
193 returnstring[0] = m_UserCache[uuid].FirstName; 194 if (m_UserCache.ContainsKey(uuid))
194 returnstring[1] = m_UserCache[uuid].LastName; 195 {
195 return returnstring; 196 returnstring[0] = m_UserCache[uuid].FirstName;
197 returnstring[1] = m_UserCache[uuid].LastName;
198 return returnstring;
199 }
196 } 200 }
197 201
198 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, uuid); 202 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, uuid);
@@ -237,22 +241,36 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
237 241
238 public string GetUserHomeURL(UUID userID) 242 public string GetUserHomeURL(UUID userID)
239 { 243 {
240 if (m_UserCache.ContainsKey(userID)) 244 lock (m_UserCache)
241 return m_UserCache[userID].HomeURL; 245 {
246 if (m_UserCache.ContainsKey(userID))
247 return m_UserCache[userID].HomeURL;
248 }
242 249
243 return string.Empty; 250 return string.Empty;
244 } 251 }
245 252
246 public string GetUserServerURL(UUID userID, string serverType) 253 public string GetUserServerURL(UUID userID, string serverType)
247 { 254 {
248 if (m_UserCache.ContainsKey(userID)) 255 UserData userdata;
256 lock (m_UserCache)
257 m_UserCache.TryGetValue(userID, out userdata);
258
259 if (userdata != null)
249 { 260 {
250 UserData userdata = m_UserCache[userID]; 261// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Requested url type {0} for {1}", serverType, userID);
262
251 if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null) 263 if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null)
264 {
252 return userdata.ServerURLs[serverType].ToString(); 265 return userdata.ServerURLs[serverType].ToString();
266 }
253 267
254 if (userdata.HomeURL != string.Empty) 268 if (userdata.HomeURL != null && userdata.HomeURL != string.Empty)
255 { 269 {
270 m_log.DebugFormat(
271 "[USER MANAGEMENT MODULE]: Did not find url type {0} so requesting urls from '{1}' for {2}",
272 serverType, userdata.HomeURL, userID);
273
256 UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL); 274 UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL);
257 userdata.ServerURLs = uConn.GetServerURLs(userID); 275 userdata.ServerURLs = uConn.GetServerURLs(userID);
258 if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null) 276 if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null)
@@ -269,9 +287,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
269 if (account != null) 287 if (account != null)
270 return userID.ToString(); 288 return userID.ToString();
271 289
272 if (m_UserCache.ContainsKey(userID)) 290 UserData ud;
291 lock (m_UserCache)
292 m_UserCache.TryGetValue(userID, out ud);
293
294 if (ud != null)
273 { 295 {
274 UserData ud = m_UserCache[userID];
275 string homeURL = ud.HomeURL; 296 string homeURL = ud.HomeURL;
276 string first = ud.FirstName, last = ud.LastName; 297 string first = ud.FirstName, last = ud.LastName;
277 if (ud.LastName.StartsWith("@")) 298 if (ud.LastName.StartsWith("@"))
@@ -291,8 +312,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
291 312
292 public void AddUser(UUID uuid, string first, string last) 313 public void AddUser(UUID uuid, string first, string last)
293 { 314 {
294 if (m_UserCache.ContainsKey(uuid)) 315 lock (m_UserCache)
295 return; 316 {
317 if (m_UserCache.ContainsKey(uuid))
318 return;
319 }
296 320
297 UserData user = new UserData(); 321 UserData user = new UserData();
298 user.Id = uuid; 322 user.Id = uuid;
@@ -310,8 +334,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
310 334
311 public void AddUser(UUID id, string creatorData) 335 public void AddUser(UUID id, string creatorData)
312 { 336 {
313 if (m_UserCache.ContainsKey(id)) 337 lock (m_UserCache)
314 return; 338 {
339 if (m_UserCache.ContainsKey(id))
340 return;
341 }
315 342
316// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, craetorData {1}", id, creatorData); 343// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, craetorData {1}", id, creatorData);
317 344
@@ -402,22 +429,24 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
402 429
403 private void HandleShowUsers(string module, string[] cmd) 430 private void HandleShowUsers(string module, string[] cmd)
404 { 431 {
405 if (m_UserCache.Count == 0) 432 lock (m_UserCache)
406 { 433 {
407 MainConsole.Instance.Output("No users not found"); 434 if (m_UserCache.Count == 0)
435 {
436 MainConsole.Instance.Output("No users not found");
437 return;
438 }
439
440 MainConsole.Instance.Output("UUID User Name");
441 MainConsole.Instance.Output("-----------------------------------------------------------------------------");
442 foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache)
443 {
444 MainConsole.Instance.Output(String.Format("{0} {1} {2}",
445 kvp.Key, kvp.Value.FirstName, kvp.Value.LastName));
446 }
447
408 return; 448 return;
409 } 449 }
410
411 MainConsole.Instance.Output("UUID User Name");
412 MainConsole.Instance.Output("-----------------------------------------------------------------------------");
413 foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache)
414 {
415 MainConsole.Instance.Output(String.Format("{0} {1} {2}",
416 kvp.Key, kvp.Value.FirstName, kvp.Value.LastName));
417 }
418 return;
419 } 450 }
420
421
422 } 451 }
423} 452} \ 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 2e877f0..3963474 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -479,8 +479,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
479 } 479 }
480 480
481 protected bool IsFriendWithPerms(UUID user,UUID objectOwner) 481 protected bool IsFriendWithPerms(UUID user,UUID objectOwner)
482 { 482 {
483
484 if (user == UUID.Zero) 483 if (user == UUID.Zero)
485 return false; 484 return false;
486 485
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index b49f23c..ba4ddc1 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -65,7 +65,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
65 65
66 private OpenSim.Framework.BlockingQueue<MapRequestState> requests = new OpenSim.Framework.BlockingQueue<MapRequestState>(); 66 private OpenSim.Framework.BlockingQueue<MapRequestState> requests = new OpenSim.Framework.BlockingQueue<MapRequestState>();
67 67
68 //private IConfig m_config;
69 protected Scene m_scene; 68 protected Scene m_scene;
70 private List<MapBlockData> cachedMapBlocks = new List<MapBlockData>(); 69 private List<MapBlockData> cachedMapBlocks = new List<MapBlockData>();
71 private int cachedTime = 0; 70 private int cachedTime = 0;
@@ -348,7 +347,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
348 347
349// m_log.Debug("[WORLD MAP]: Starting remote MapItem request thread"); 348// m_log.Debug("[WORLD MAP]: Starting remote MapItem request thread");
350 349
351 Watchdog.StartThread(process, "MapItemRequestThread", ThreadPriority.BelowNormal, true); 350 Watchdog.StartThread(
351 process,
352 string.Format("MapItemRequestThread ({0})", m_scene.RegionInfo.RegionName),
353 ThreadPriority.BelowNormal,
354 true);
352 } 355 }
353 356
354 /// <summary> 357 /// <summary>
@@ -357,7 +360,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
357 private void StopThread() 360 private void StopThread()
358 { 361 {
359 MapRequestState st = new MapRequestState(); 362 MapRequestState st = new MapRequestState();
360 st.agentID=STOP_UUID; 363 st.agentID = STOP_UUID;
361 st.EstateID=0; 364 st.EstateID=0;
362 st.flags=0; 365 st.flags=0;
363 st.godlike=false; 366 st.godlike=false;
diff --git a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
index fdede34..061799e 100644
--- a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
@@ -44,6 +44,17 @@ namespace OpenSim.Region.Framework.Interfaces
44 /// <param name="friendID"></param> 44 /// <param name="friendID"></param>
45 void AddFriendship(IClientAPI client, UUID friendID); 45 void AddFriendship(IClientAPI client, UUID friendID);
46 46
47 /// <summary>
48 /// Remove a friendship between two users.
49 /// </summary>
50 /// <remarks>
51 /// Ultimately, it would be more useful to take in a user account here rather than having to have a user
52 /// present in the scene.
53 /// </remarks>
54 /// <param name="client"></param>
55 /// <param name="exFriendID"></param>
56 void RemoveFriendship(IClientAPI client, UUID exFriendID);
57
47 uint GetFriendPerms(UUID PrincipalID, UUID FriendID); 58 uint GetFriendPerms(UUID PrincipalID, UUID FriendID);
48 bool SendFriendsOnlineIfNeeded(IClientAPI client); 59 bool SendFriendsOnlineIfNeeded(IClientAPI client);
49 } 60 }
diff --git a/OpenSim/Region/Framework/Scenes/EntityBase.cs b/OpenSim/Region/Framework/Scenes/EntityBase.cs
index 664be01..741f53b 100644
--- a/OpenSim/Region/Framework/Scenes/EntityBase.cs
+++ b/OpenSim/Region/Framework/Scenes/EntityBase.cs
@@ -103,7 +103,11 @@ namespace OpenSim.Region.Framework.Scenes
103 public virtual uint LocalId 103 public virtual uint LocalId
104 { 104 {
105 get { return m_localId; } 105 get { return m_localId; }
106 set { m_localId = value; } 106 set
107 {
108 m_localId = value;
109// m_log.DebugFormat("[ENTITY BASE]: Set part {0} to local id {1}", Name, m_localId);
110 }
107 } 111 }
108 112
109 /// <summary> 113 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/EntityManager.cs b/OpenSim/Region/Framework/Scenes/EntityManager.cs
index 1812bd2..b788a3c 100644
--- a/OpenSim/Region/Framework/Scenes/EntityManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EntityManager.cs
@@ -79,7 +79,7 @@ namespace OpenSim.Region.Framework.Scenes
79 { 79 {
80 List<EntityBase> tmp = new List<EntityBase>(); 80 List<EntityBase> tmp = new List<EntityBase>();
81 81
82 m_entities.ForEach( 82 ForEach(
83 delegate(EntityBase entity) 83 delegate(EntityBase entity)
84 { 84 {
85 if (entity is T) 85 if (entity is T)
@@ -93,7 +93,7 @@ namespace OpenSim.Region.Framework.Scenes
93 public EntityBase[] GetEntities() 93 public EntityBase[] GetEntities()
94 { 94 {
95 List<EntityBase> tmp = new List<EntityBase>(m_entities.Count); 95 List<EntityBase> tmp = new List<EntityBase>(m_entities.Count);
96 m_entities.ForEach(delegate(EntityBase entity) { tmp.Add(entity); }); 96 ForEach(delegate(EntityBase entity) { tmp.Add(entity); });
97 return tmp.ToArray(); 97 return tmp.ToArray();
98 } 98 }
99 99
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 65c6a29..0049384 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -77,8 +77,10 @@ namespace OpenSim.Region.Framework.Scenes
77 /// </summary> 77 /// </summary>
78 public event OnNewClientDelegate OnNewClient; 78 public event OnNewClientDelegate OnNewClient;
79 79
80 public delegate void OnClientLoginDelegate(IClientAPI client); 80 /// <summary>
81 public event OnClientLoginDelegate OnClientLogin; 81 /// Fired if the client entering this sim is doing so as a new login
82 /// </summary>
83 public event Action<IClientAPI> OnClientLogin;
82 84
83 public delegate void OnNewPresenceDelegate(ScenePresence presence); 85 public delegate void OnNewPresenceDelegate(ScenePresence presence);
84 86
@@ -214,10 +216,15 @@ namespace OpenSim.Region.Framework.Scenes
214 public delegate void OnMakeChildAgentDelegate(ScenePresence presence); 216 public delegate void OnMakeChildAgentDelegate(ScenePresence presence);
215 public event OnMakeChildAgentDelegate OnMakeChildAgent; 217 public event OnMakeChildAgentDelegate OnMakeChildAgent;
216 218
217 public delegate void OnMakeRootAgentDelegate(ScenePresence presence);
218 public delegate void OnSaveNewWindlightProfileDelegate(); 219 public delegate void OnSaveNewWindlightProfileDelegate();
219 public delegate void OnSendNewWindlightProfileTargetedDelegate(RegionLightShareData wl, UUID user); 220 public delegate void OnSendNewWindlightProfileTargetedDelegate(RegionLightShareData wl, UUID user);
220 public event OnMakeRootAgentDelegate OnMakeRootAgent; 221
222 /// <summary>
223 /// This event is on the critical path for transferring an avatar from one region to another. Try and do
224 /// as little work on this event as possible, or do work asynchronously.
225 /// </summary>
226 public event Action<ScenePresence> OnMakeRootAgent;
227
221 public event OnSendNewWindlightProfileTargetedDelegate OnSendNewWindlightProfileTargeted; 228 public event OnSendNewWindlightProfileTargetedDelegate OnSendNewWindlightProfileTargeted;
222 public event OnSaveNewWindlightProfileDelegate OnSaveNewWindlightProfile; 229 public event OnSaveNewWindlightProfileDelegate OnSaveNewWindlightProfile;
223 230
@@ -655,10 +662,10 @@ namespace OpenSim.Region.Framework.Scenes
655 662
656 public void TriggerOnClientLogin(IClientAPI client) 663 public void TriggerOnClientLogin(IClientAPI client)
657 { 664 {
658 OnClientLoginDelegate handlerClientLogin = OnClientLogin; 665 Action<IClientAPI> handlerClientLogin = OnClientLogin;
659 if (handlerClientLogin != null) 666 if (handlerClientLogin != null)
660 { 667 {
661 foreach (OnClientLoginDelegate d in handlerClientLogin.GetInvocationList()) 668 foreach (Action<IClientAPI> d in handlerClientLogin.GetInvocationList())
662 { 669 {
663 try 670 try
664 { 671 {
@@ -1344,10 +1351,10 @@ namespace OpenSim.Region.Framework.Scenes
1344 1351
1345 public void TriggerOnMakeRootAgent(ScenePresence presence) 1352 public void TriggerOnMakeRootAgent(ScenePresence presence)
1346 { 1353 {
1347 OnMakeRootAgentDelegate handlerMakeRootAgent = OnMakeRootAgent; 1354 Action<ScenePresence> handlerMakeRootAgent = OnMakeRootAgent;
1348 if (handlerMakeRootAgent != null) 1355 if (handlerMakeRootAgent != null)
1349 { 1356 {
1350 foreach (OnMakeRootAgentDelegate d in handlerMakeRootAgent.GetInvocationList()) 1357 foreach (Action<ScenePresence> d in handlerMakeRootAgent.GetInvocationList())
1351 { 1358 {
1352 try 1359 try
1353 { 1360 {
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 876dfb2..b6067ea 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1148,8 +1148,8 @@ namespace OpenSim.Region.Framework.Scenes
1148 1148
1149 m_sceneGraph.Close(); 1149 m_sceneGraph.Close();
1150 1150
1151 // De-register with region communications (events cleanup) 1151 if (!GridService.DeregisterRegion(m_regInfo.RegionID))
1152 UnRegisterRegionWithComms(); 1152 m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", m_regInfo.RegionName);
1153 1153
1154 // call the base class Close method. 1154 // call the base class Close method.
1155 base.Close(); 1155 base.Close();
@@ -1177,7 +1177,9 @@ namespace OpenSim.Region.Framework.Scenes
1177 } 1177 }
1178 m_lastUpdate = Util.EnvironmentTickCount(); 1178 m_lastUpdate = Util.EnvironmentTickCount();
1179 1179
1180 HeartbeatThread = Watchdog.StartThread(Heartbeat, "Heartbeat for region " + RegionInfo.RegionName, ThreadPriority.Normal, false); 1180 HeartbeatThread
1181 = Watchdog.StartThread(
1182 Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false);
1181 } 1183 }
1182 1184
1183 /// <summary> 1185 /// <summary>
@@ -1663,8 +1665,6 @@ namespace OpenSim.Region.Framework.Scenes
1663 /// <exception cref="System.Exception">Thrown if registration of the region itself fails.</exception> 1665 /// <exception cref="System.Exception">Thrown if registration of the region itself fails.</exception>
1664 public void RegisterRegionWithGrid() 1666 public void RegisterRegionWithGrid()
1665 { 1667 {
1666 RegisterCommsEvents();
1667
1668 m_sceneGridService.SetScene(this); 1668 m_sceneGridService.SetScene(this);
1669 1669
1670 GridRegion region = new GridRegion(RegionInfo); 1670 GridRegion region = new GridRegion(RegionInfo);
@@ -2665,11 +2665,12 @@ namespace OpenSim.Region.Framework.Scenes
2665 // Send all scene object to the new client 2665 // Send all scene object to the new client
2666 Util.FireAndForget(delegate 2666 Util.FireAndForget(delegate
2667 { 2667 {
2668 Entities.ForEach(delegate(EntityBase e) 2668 EntityBase[] entities = Entities.GetEntities();
2669 foreach(EntityBase e in entities)
2669 { 2670 {
2670 if (e != null && e is SceneObjectGroup) 2671 if (e != null && e is SceneObjectGroup)
2671 ((SceneObjectGroup)e).SendFullUpdateToClient(client); 2672 ((SceneObjectGroup)e).SendFullUpdateToClient(client);
2672 }); 2673 }
2673 }); 2674 });
2674 } 2675 }
2675 2676
@@ -3332,40 +3333,6 @@ namespace OpenSim.Region.Framework.Scenes
3332 #region RegionComms 3333 #region RegionComms
3333 3334
3334 /// <summary> 3335 /// <summary>
3335 /// Register the methods that should be invoked when this scene receives various incoming events
3336 /// </summary>
3337 public void RegisterCommsEvents()
3338 {
3339 m_sceneGridService.OnAvatarCrossingIntoRegion += AgentCrossing;
3340 m_sceneGridService.OnCloseAgentConnection += IncomingCloseAgent;
3341 //m_eventManager.OnRegionUp += OtherRegionUp;
3342 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
3343 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar;
3344 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
3345 m_sceneGridService.OnGetLandData += GetLandData;
3346 }
3347
3348 /// <summary>
3349 /// Deregister this scene from receiving incoming region events
3350 /// </summary>
3351 public void UnRegisterRegionWithComms()
3352 {
3353 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid;
3354 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar;
3355 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate;
3356 //m_eventManager.OnRegionUp -= OtherRegionUp;
3357 m_sceneGridService.OnAvatarCrossingIntoRegion -= AgentCrossing;
3358 m_sceneGridService.OnCloseAgentConnection -= IncomingCloseAgent;
3359 m_sceneGridService.OnGetLandData -= GetLandData;
3360
3361 // this does nothing; should be removed
3362 m_sceneGridService.Close();
3363
3364 if (!GridService.DeregisterRegion(m_regInfo.RegionID))
3365 m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", m_regInfo.RegionName);
3366 }
3367
3368 /// <summary>
3369 /// Do the work necessary to initiate a new user connection for a particular scene. 3336 /// Do the work necessary to initiate a new user connection for a particular scene.
3370 /// At the moment, this consists of setting up the caps infrastructure 3337 /// At the moment, this consists of setting up the caps infrastructure
3371 /// The return bool should allow for connections to be refused, but as not all calling paths 3338 /// The return bool should allow for connections to be refused, but as not all calling paths
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index fe9fe31..12058c8 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -56,88 +56,12 @@ namespace OpenSim.Region.Framework.Scenes
56 protected RegionInfo m_regionInfo; 56 protected RegionInfo m_regionInfo;
57 protected Scene m_scene; 57 protected Scene m_scene;
58 58
59 protected RegionCommsListener regionCommsHost;
60
61 protected List<UUID> m_agentsInTransit;
62
63 /// <summary>
64 /// An agent is crossing into this region
65 /// </summary>
66 public event AgentCrossing OnAvatarCrossingIntoRegion;
67
68 /// <summary>
69 /// A user will arrive shortly, set up appropriate credentials so it can connect
70 /// </summary>
71// public event ExpectUserDelegate OnExpectUser;
72
73 /// <summary>
74 /// A Prim will arrive shortly
75 /// </summary>
76 public event CloseAgentConnection OnCloseAgentConnection;
77
78 /// <summary>
79 /// A new prim has arrived
80 /// </summary>
81// public event PrimCrossing OnPrimCrossingIntoRegion;
82
83 ///// <summary>
84 ///// A New Region is up and available
85 ///// </summary>
86 //public event RegionUp OnRegionUp;
87
88 /// <summary>
89 /// We have a child agent for this avatar and we're getting a status update about it
90 /// </summary>
91// public event ChildAgentUpdate OnChildAgentUpdate;
92 //public event RemoveKnownRegionsFromAvatarList OnRemoveKnownRegionFromAvatar;
93
94 /// <summary>
95 /// Time to log one of our users off. Grid Service sends this mostly
96 /// </summary>
97 public event LogOffUser OnLogOffUser;
98
99 /// <summary>
100 /// A region wants land data from us!
101 /// </summary>
102 public event GetLandData OnGetLandData;
103
104// private AgentCrossing handlerAvatarCrossingIntoRegion = null; // OnAvatarCrossingIntoRegion;
105// private ExpectUserDelegate handlerExpectUser = null; // OnExpectUser;
106// private CloseAgentConnection handlerCloseAgentConnection = null; // OnCloseAgentConnection;
107// private PrimCrossing handlerPrimCrossingIntoRegion = null; // OnPrimCrossingIntoRegion;
108 //private RegionUp handlerRegionUp = null; // OnRegionUp;
109// private ChildAgentUpdate handlerChildAgentUpdate = null; // OnChildAgentUpdate;
110 //private RemoveKnownRegionsFromAvatarList handlerRemoveKnownRegionFromAvatar = null; // OnRemoveKnownRegionFromAvatar;
111// private LogOffUser handlerLogOffUser = null;
112// private GetLandData handlerGetLandData = null; // OnGetLandData
113
114 public SceneCommunicationService()
115 {
116 }
117
118 public void SetScene(Scene s) 59 public void SetScene(Scene s)
119 { 60 {
120 m_scene = s; 61 m_scene = s;
121 m_regionInfo = s.RegionInfo; 62 m_regionInfo = s.RegionInfo;
122 } 63 }
123 64
124 /// <summary>
125 /// Register a region with the grid
126 /// </summary>
127 /// <param name="regionInfos"></param>
128 /// <exception cref="System.Exception">Thrown if region registration fails.</exception>
129 public void RegisterRegion(IInterregionCommsOut comms_out, RegionInfo regionInfos)
130 {
131 }
132
133 /// <summary>
134 /// This region is shutting down, de-register all events!
135 /// De-Register region from Grid!
136 /// </summary>
137 public void Close()
138 {
139 }
140
141 public delegate void InformNeighbourThatRegionUpDelegate(INeighbourService nService, RegionInfo region, ulong regionhandle); 65 public delegate void InformNeighbourThatRegionUpDelegate(INeighbourService nService, RegionInfo region, ulong regionhandle);
142 66
143 private void InformNeighborsThatRegionisUpCompleted(IAsyncResult iar) 67 private void InformNeighborsThatRegionisUpCompleted(IAsyncResult iar)
@@ -173,7 +97,6 @@ namespace OpenSim.Region.Framework.Scenes
173 } 97 }
174 } 98 }
175 99
176
177 public void InformNeighborsThatRegionisUp(INeighbourService neighbourService, RegionInfo region) 100 public void InformNeighborsThatRegionisUp(INeighbourService neighbourService, RegionInfo region)
178 { 101 {
179 //m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: Sending InterRegion Notification that region is up " + region.RegionName); 102 //m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: Sending InterRegion Notification that region is up " + region.RegionName);
@@ -190,7 +113,6 @@ namespace OpenSim.Region.Framework.Scenes
190 } 113 }
191 114
192 public delegate void SendChildAgentDataUpdateDelegate(AgentPosition cAgentData, UUID scopeID, GridRegion dest); 115 public delegate void SendChildAgentDataUpdateDelegate(AgentPosition cAgentData, UUID scopeID, GridRegion dest);
193
194 116
195 /// <summary> 117 /// <summary>
196 /// This informs all neighboring regions about the settings of it's child agent. 118 /// This informs all neighboring regions about the settings of it's child agent.
@@ -295,6 +217,5 @@ namespace OpenSim.Region.Framework.Scenes
295 { 217 {
296 return m_scene.GridService.GetRegionsByName(UUID.Zero, name, maxNumber); 218 return m_scene.GridService.GetRegionsByName(UUID.Zero, name, maxNumber);
297 } 219 }
298
299 } 220 }
300} 221}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 45ca0b7..e214f57 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -533,7 +533,11 @@ namespace OpenSim.Region.Framework.Scenes
533 public uint LocalId 533 public uint LocalId
534 { 534 {
535 get { return m_localId; } 535 get { return m_localId; }
536 set { m_localId = value; } 536 set
537 {
538 m_localId = value;
539// m_log.DebugFormat("[SCENE OBJECT PART]: Set part {0} to local id {1}", Name, m_localId);
540 }
537 } 541 }
538 542
539 public virtual string Name 543 public virtual string Name
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 839259f..d89c1c0 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -757,7 +757,7 @@ namespace OpenSim.Region.Framework.Scenes
757 m_name = String.Format("{0} {1}", Firstname, Lastname); 757 m_name = String.Format("{0} {1}", Firstname, Lastname);
758 m_scene = world; 758 m_scene = world;
759 m_uuid = client.AgentId; 759 m_uuid = client.AgentId;
760 m_localId = m_scene.AllocateLocalId(); 760 LocalId = m_scene.AllocateLocalId();
761 761
762 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); 762 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
763 if (account != null) 763 if (account != null)
@@ -860,9 +860,15 @@ namespace OpenSim.Region.Framework.Scenes
860 #region Status Methods 860 #region Status Methods
861 861
862 /// <summary> 862 /// <summary>
863 /// This turns a child agent, into a root agent 863 /// Turns a child agent into a root agent.
864 /// This is called when an agent teleports into a region, or if an 864 /// </summary>
865 /// agent crosses into this region from a neighbor over the border 865 /// Child agents are logged into neighbouring sims largely to observe changes. Root agents exist when the
866 /// avatar is actual in the sim. They can perform all actions.
867 /// This change is made whenever an avatar enters a region, whether by crossing over from a neighbouring sim,
868 /// teleporting in or on initial login.
869 ///
870 /// This method is on the critical path for transferring an avatar from one region to another. Delay here
871 /// delays that crossing.
866 /// </summary> 872 /// </summary>
867 public void MakeRootAgent(Vector3 pos, bool isFlying) 873 public void MakeRootAgent(Vector3 pos, bool isFlying)
868 { 874 {
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
index 49f60f8..798a0a4 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
@@ -25,8 +25,10 @@
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 log4net;
28using System; 29using System;
29using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Reflection;
30using OpenSim.Framework; 32using OpenSim.Framework;
31using OpenMetaverse; 33using OpenMetaverse;
32 34
@@ -46,10 +48,10 @@ namespace OpenSim.Region.Physics.Manager
46 48
47 public enum PIDHoverType 49 public enum PIDHoverType
48 { 50 {
49 Ground 51 Ground,
50 , GroundAndWater 52 GroundAndWater,
51 , Water 53 Water,
52 , Absolute 54 Absolute
53 } 55 }
54 56
55 public struct ContactPoint 57 public struct ContactPoint
@@ -114,6 +116,8 @@ namespace OpenSim.Region.Physics.Manager
114 116
115 public abstract class PhysicsActor 117 public abstract class PhysicsActor
116 { 118 {
119// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
120
117 public delegate void RequestTerseUpdate(); 121 public delegate void RequestTerseUpdate();
118 public delegate void CollisionUpdate(EventArgs e); 122 public delegate void CollisionUpdate(EventArgs e);
119 public delegate void OutOfBounds(Vector3 pos); 123 public delegate void OutOfBounds(Vector3 pos);
@@ -197,10 +201,10 @@ namespace OpenSim.Region.Physics.Manager
197 { 201 {
198 CollisionUpdate handler = OnCollisionUpdate; 202 CollisionUpdate handler = OnCollisionUpdate;
199 203
204// m_log.DebugFormat("[PHYSICS ACTOR]: Sending collision for {0}", LocalID);
205
200 if (handler != null) 206 if (handler != null)
201 {
202 handler(e); 207 handler(e);
203 }
204 } 208 }
205 209
206 public virtual void SetMaterial (int material) 210 public virtual void SetMaterial (int material)
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index 3630510..c37d588 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -108,7 +108,6 @@ namespace OpenSim.Region.Physics.OdePlugin
108 /// </summary> 108 /// </summary>
109 private Vector3 m_taintForce; 109 private Vector3 m_taintForce;
110 110
111 internal uint m_localID = 0;
112 // taints and their non-tainted counterparts 111 // taints and their non-tainted counterparts
113 private bool m_isPhysical = false; // the current physical status 112 private bool m_isPhysical = false; // the current physical status
114 private bool m_tainted_isPhysical = false; // set when the physical status is tainted (false=not existing in physics engine, true=existing) 113 private bool m_tainted_isPhysical = false; // set when the physical status is tainted (false=not existing in physics engine, true=existing)
@@ -231,11 +230,6 @@ namespace OpenSim.Region.Physics.OdePlugin
231 set { m_alwaysRun = value; } 230 set { m_alwaysRun = value; }
232 } 231 }
233 232
234 public override uint LocalID
235 {
236 set { m_localID = value; }
237 }
238
239 public override bool Grabbed 233 public override bool Grabbed
240 { 234 {
241 set { return; } 235 set { return; }
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index ffd6dc0..f07cf46 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -142,8 +142,6 @@ namespace OpenSim.Region.Physics.OdePlugin
142 public bool m_taintselected { get; private set; } 142 public bool m_taintselected { get; private set; }
143 public bool m_taintCollidesWater { get; private set; } 143 public bool m_taintCollidesWater { get; private set; }
144 144
145 public uint m_localID { get; private set; }
146
147 private bool m_taintforce = false; 145 private bool m_taintforce = false;
148 private bool m_taintaddangularforce = false; 146 private bool m_taintaddangularforce = false;
149 private Vector3 m_force; 147 private Vector3 m_force;
@@ -290,13 +288,6 @@ namespace OpenSim.Region.Physics.OdePlugin
290 set { return; } 288 set { return; }
291 } 289 }
292 290
293 public override uint LocalID
294 {
295 set {
296 //m_log.Info("[PHYSICS]: Setting TrackerID: " + value);
297 m_localID = value; }
298 }
299
300 public override bool Grabbed 291 public override bool Grabbed
301 { 292 {
302 set { return; } 293 set { return; }
@@ -1058,7 +1049,7 @@ Console.WriteLine("ZProcessTaints for " + Name);
1058 private void AddChildPrim(OdePrim prim) 1049 private void AddChildPrim(OdePrim prim)
1059 { 1050 {
1060//Console.WriteLine("AddChildPrim " + Name); 1051//Console.WriteLine("AddChildPrim " + Name);
1061 if (this.m_localID != prim.m_localID) 1052 if (LocalID != prim.LocalID)
1062 { 1053 {
1063 if (Body == IntPtr.Zero) 1054 if (Body == IntPtr.Zero)
1064 { 1055 {
diff --git a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
index 9d7aa94..7e3ec63 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
@@ -378,12 +378,13 @@ namespace OpenSim.Region.Physics.OdePlugin
378 // Loop over contacts, build results. 378 // Loop over contacts, build results.
379 for (int i = 0; i < count; i++) 379 for (int i = 0; i < count; i++)
380 { 380 {
381 if (p1 != null) { 381 if (p1 != null)
382 {
382 if (p1 is OdePrim) 383 if (p1 is OdePrim)
383 { 384 {
384 ContactResult collisionresult = new ContactResult(); 385 ContactResult collisionresult = new ContactResult();
385 386
386 collisionresult.ConsumerID = ((OdePrim)p1).m_localID; 387 collisionresult.ConsumerID = p1.LocalID;
387 collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z); 388 collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
388 collisionresult.Depth = contacts[i].depth; 389 collisionresult.Depth = contacts[i].depth;
389 collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y, 390 collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y,
@@ -399,7 +400,7 @@ namespace OpenSim.Region.Physics.OdePlugin
399 { 400 {
400 ContactResult collisionresult = new ContactResult(); 401 ContactResult collisionresult = new ContactResult();
401 402
402 collisionresult.ConsumerID = ((OdePrim)p2).m_localID; 403 collisionresult.ConsumerID = p2.LocalID;
403 collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z); 404 collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
404 collisionresult.Depth = contacts[i].depth; 405 collisionresult.Depth = contacts[i].depth;
405 collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y, 406 collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y,
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index c3279c6..43d852b 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -219,9 +219,14 @@ namespace OpenSim.Region.Physics.OdePlugin
219 private readonly List<d.ContactGeom> _perloopContact = new List<d.ContactGeom>(); 219 private readonly List<d.ContactGeom> _perloopContact = new List<d.ContactGeom>();
220 220
221 /// <summary> 221 /// <summary>
222 /// A list of actors that should receive collision events. 222 /// A dictionary of actors that should receive collision events.
223 /// </summary> 223 /// </summary>
224 private readonly List<PhysicsActor> _collisionEventPrim = new List<PhysicsActor>(); 224 private readonly Dictionary<uint, PhysicsActor> _collisionEventPrim = new Dictionary<uint, PhysicsActor>();
225
226 /// <summary>
227 /// A dictionary of collision event changes that are waiting to be processed.
228 /// </summary>
229 private readonly Dictionary<uint, PhysicsActor> _collisionEventPrimChanges = new Dictionary<uint, PhysicsActor>();
225 230
226 private readonly HashSet<OdeCharacter> _badCharacter = new HashSet<OdeCharacter>(); 231 private readonly HashSet<OdeCharacter> _badCharacter = new HashSet<OdeCharacter>();
227 public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>(); 232 public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>();
@@ -1301,8 +1306,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1301 { 1306 {
1302 case ActorTypes.Agent: 1307 case ActorTypes.Agent:
1303 cc1 = (OdeCharacter)p1; 1308 cc1 = (OdeCharacter)p1;
1304 obj2LocalID = cc1.m_localID; 1309 obj2LocalID = cc1.LocalID;
1305 cc1.AddCollisionEvent(cc2.m_localID, contact); 1310 cc1.AddCollisionEvent(cc2.LocalID, contact);
1306 //ctype = (int)CollisionCategories.Character; 1311 //ctype = (int)CollisionCategories.Character;
1307 1312
1308 //if (cc1.CollidingObj) 1313 //if (cc1.CollidingObj)
@@ -1317,8 +1322,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1317 if (p1 is OdePrim) 1322 if (p1 is OdePrim)
1318 { 1323 {
1319 cp1 = (OdePrim) p1; 1324 cp1 = (OdePrim) p1;
1320 obj2LocalID = cp1.m_localID; 1325 obj2LocalID = cp1.LocalID;
1321 cp1.AddCollisionEvent(cc2.m_localID, contact); 1326 cp1.AddCollisionEvent(cc2.LocalID, contact);
1322 } 1327 }
1323 //ctype = (int)CollisionCategories.Geom; 1328 //ctype = (int)CollisionCategories.Geom;
1324 1329
@@ -1354,8 +1359,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1354 if (p1 is OdeCharacter) 1359 if (p1 is OdeCharacter)
1355 { 1360 {
1356 cc1 = (OdeCharacter) p1; 1361 cc1 = (OdeCharacter) p1;
1357 obj2LocalID = cc1.m_localID; 1362 obj2LocalID = cc1.LocalID;
1358 cc1.AddCollisionEvent(cp2.m_localID, contact); 1363 cc1.AddCollisionEvent(cp2.LocalID, contact);
1359 //ctype = (int)CollisionCategories.Character; 1364 //ctype = (int)CollisionCategories.Character;
1360 1365
1361 //if (cc1.CollidingObj) 1366 //if (cc1.CollidingObj)
@@ -1370,8 +1375,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1370 if (p1 is OdePrim) 1375 if (p1 is OdePrim)
1371 { 1376 {
1372 cp1 = (OdePrim) p1; 1377 cp1 = (OdePrim) p1;
1373 obj2LocalID = cp1.m_localID; 1378 obj2LocalID = cp1.LocalID;
1374 cp1.AddCollisionEvent(cp2.m_localID, contact); 1379 cp1.AddCollisionEvent(cp2.LocalID, contact);
1375 //ctype = (int)CollisionCategories.Geom; 1380 //ctype = (int)CollisionCategories.Geom;
1376 1381
1377 //if (cp1.CollidingObj) 1382 //if (cp1.CollidingObj)
@@ -1633,13 +1638,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1633 /// <param name="obj"></param> 1638 /// <param name="obj"></param>
1634 internal void AddCollisionEventReporting(PhysicsActor obj) 1639 internal void AddCollisionEventReporting(PhysicsActor obj)
1635 { 1640 {
1636// m_log.DebugFormat("[PHYSICS]: Adding {0} to collision event reporting", obj.SOPName); 1641// m_log.DebugFormat("[PHYSICS]: Adding {0} {1} to collision event reporting", obj.SOPName, obj.LocalID);
1637 1642
1638 lock (_collisionEventPrim) 1643 lock (_collisionEventPrimChanges)
1639 { 1644 _collisionEventPrimChanges[obj.LocalID] = obj;
1640 if (!_collisionEventPrim.Contains(obj))
1641 _collisionEventPrim.Add(obj);
1642 }
1643 } 1645 }
1644 1646
1645 /// <summary> 1647 /// <summary>
@@ -1648,10 +1650,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1648 /// <param name="obj"></param> 1650 /// <param name="obj"></param>
1649 internal void RemoveCollisionEventReporting(PhysicsActor obj) 1651 internal void RemoveCollisionEventReporting(PhysicsActor obj)
1650 { 1652 {
1651// m_log.DebugFormat("[PHYSICS]: Removing {0} from collision event reporting", obj.SOPName); 1653// m_log.DebugFormat("[PHYSICS]: Removing {0} {1} from collision event reporting", obj.SOPName, obj.LocalID);
1652 1654
1653 lock (_collisionEventPrim) 1655 lock (_collisionEventPrimChanges)
1654 _collisionEventPrim.Remove(obj); 1656 _collisionEventPrimChanges[obj.LocalID] = null;
1655 } 1657 }
1656 1658
1657 #region Add/Remove Entities 1659 #region Add/Remove Entities
@@ -1752,9 +1754,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1752 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, 1754 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
1753 Vector3 size, Quaternion rotation, bool isPhysical, uint localid) 1755 Vector3 size, Quaternion rotation, bool isPhysical, uint localid)
1754 { 1756 {
1755#if SPAM 1757// m_log.DebugFormat("[ODE SCENE]: Adding physics actor to {0} {1}", primName, localid);
1756 m_log.DebugFormat("[PHYSICS]: Adding physics actor to {0}", primName);
1757#endif
1758 1758
1759 return AddPrim(primName, position, size, rotation, pbs, isPhysical, localid); 1759 return AddPrim(primName, position, size, rotation, pbs, isPhysical, localid);
1760 } 1760 }
@@ -2663,6 +2663,22 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
2663// m_physicsiterations = 10; 2663// m_physicsiterations = 10;
2664// } 2664// }
2665 2665
2666 // We change _collisionEventPrimChanges to avoid locking _collisionEventPrim itself and causing potential
2667 // deadlock if the collision event tries to lock something else later on which is already locked by a
2668 // caller that is adding or removing the collision event.
2669 lock (_collisionEventPrimChanges)
2670 {
2671 foreach (KeyValuePair<uint, PhysicsActor> kvp in _collisionEventPrimChanges)
2672 {
2673 if (kvp.Value == null)
2674 _collisionEventPrim.Remove(kvp.Key);
2675 else
2676 _collisionEventPrim[kvp.Key] = kvp.Value;
2677 }
2678
2679 _collisionEventPrimChanges.Clear();
2680 }
2681
2666 if (SupportsNINJAJoints) 2682 if (SupportsNINJAJoints)
2667 { 2683 {
2668 DeleteRequestedJoints(); // this must be outside of the lock (OdeLock) to avoid deadlocks 2684 DeleteRequestedJoints(); // this must be outside of the lock (OdeLock) to avoid deadlocks
@@ -2790,25 +2806,22 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
2790 2806
2791 collision_optimized(); 2807 collision_optimized();
2792 2808
2793 lock (_collisionEventPrim) 2809 foreach (PhysicsActor obj in _collisionEventPrim.Values)
2794 { 2810 {
2795 foreach (PhysicsActor obj in _collisionEventPrim) 2811// m_log.DebugFormat("[PHYSICS]: Assessing {0} {1} for collision events", obj.SOPName, obj.LocalID);
2796 {
2797// m_log.DebugFormat("[PHYSICS]: Assessing {0} for collision events", obj.SOPName);
2798 2812
2799 switch ((ActorTypes)obj.PhysicsActorType) 2813 switch ((ActorTypes)obj.PhysicsActorType)
2800 { 2814 {
2801 case ActorTypes.Agent: 2815 case ActorTypes.Agent:
2802 OdeCharacter cobj = (OdeCharacter)obj; 2816 OdeCharacter cobj = (OdeCharacter)obj;
2803 cobj.AddCollisionFrameTime(100); 2817 cobj.AddCollisionFrameTime(100);
2804 cobj.SendCollisions(); 2818 cobj.SendCollisions();
2805 break; 2819 break;
2806 2820
2807 case ActorTypes.Prim: 2821 case ActorTypes.Prim:
2808 OdePrim pobj = (OdePrim)obj; 2822 OdePrim pobj = (OdePrim)obj;
2809 pobj.SendCollisions(); 2823 pobj.SendCollisions();
2810 break; 2824 break;
2811 }
2812 } 2825 }
2813 } 2826 }
2814 2827
@@ -3731,7 +3744,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
3731 { 3744 {
3732 if (prm.CollisionScore > 0) 3745 if (prm.CollisionScore > 0)
3733 { 3746 {
3734 returncolliders.Add(prm.m_localID, prm.CollisionScore); 3747 returncolliders.Add(prm.LocalID, prm.CollisionScore);
3735 cnt++; 3748 cnt++;
3736 prm.CollisionScore = 0f; 3749 prm.CollisionScore = 0f;
3737 if (cnt > 25) 3750 if (cnt > 25)
diff --git a/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs b/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs
index 2ea810f..cbc6b95 100644
--- a/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs
+++ b/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs
@@ -104,7 +104,7 @@ namespace OpenSim.Region.Physics.OdePlugin.Tests
104 m_log.Info("TargetSpace: " + oprim.m_targetSpace + " - SceneMainSpace: " + pscene.space); 104 m_log.Info("TargetSpace: " + oprim.m_targetSpace + " - SceneMainSpace: " + pscene.space);
105 105
106 Assert.That(!oprim.m_taintadd); 106 Assert.That(!oprim.m_taintadd);
107 m_log.Info("Prim Position (" + oprim.m_localID + "): " + prim.Position.ToString()); 107 m_log.Info("Prim Position (" + oprim.LocalID + "): " + prim.Position);
108 108
109 // Make sure we're above the ground 109 // Make sure we're above the ground
110 //Assert.That(prim.Position.Z > 20f); 110 //Assert.That(prim.Position.Z > 20f);