diff options
Diffstat (limited to 'OpenSim/Region')
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; | |||
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using System.Threading; | ||
32 | using log4net; | 33 | using log4net; |
33 | using Nini.Config; | 34 | using Nini.Config; |
34 | using Nwc.XmlRpc; | 35 | using 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; | |||
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using System.Threading; | 32 | using System.Threading; |
33 | |||
34 | using log4net; | 33 | using log4net; |
35 | using Nini.Config; | 34 | using Nini.Config; |
36 | using Nwc.XmlRpc; | 35 | using 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 | ||
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Framework.Console; | 33 | using OpenSim.Framework.Console; |
34 | |||
35 | using OpenSim.Region.Framework; | 34 | using OpenSim.Region.Framework; |
36 | using OpenSim.Region.Framework.Interfaces; | 35 | using OpenSim.Region.Framework.Interfaces; |
37 | using OpenSim.Region.Framework.Scenes; | 36 | using OpenSim.Region.Framework.Scenes; |
@@ -44,13 +43,13 @@ using Nini.Config; | |||
44 | 43 | ||
45 | namespace OpenSim.Region.CoreModules.Framework.UserManagement | 44 | namespace 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 149d2d3..0eeb22a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -1147,8 +1147,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1147 | 1147 | ||
1148 | m_sceneGraph.Close(); | 1148 | m_sceneGraph.Close(); |
1149 | 1149 | ||
1150 | // De-register with region communications (events cleanup) | 1150 | if (!GridService.DeregisterRegion(m_regInfo.RegionID)) |
1151 | UnRegisterRegionWithComms(); | 1151 | m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", m_regInfo.RegionName); |
1152 | 1152 | ||
1153 | // call the base class Close method. | 1153 | // call the base class Close method. |
1154 | base.Close(); | 1154 | base.Close(); |
@@ -1173,7 +1173,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1173 | } | 1173 | } |
1174 | m_lastUpdate = Util.EnvironmentTickCount(); | 1174 | m_lastUpdate = Util.EnvironmentTickCount(); |
1175 | 1175 | ||
1176 | HeartbeatThread = Watchdog.StartThread(Heartbeat, "Heartbeat for region " + RegionInfo.RegionName, ThreadPriority.Normal, false); | 1176 | HeartbeatThread |
1177 | = Watchdog.StartThread( | ||
1178 | Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false); | ||
1177 | } | 1179 | } |
1178 | 1180 | ||
1179 | /// <summary> | 1181 | /// <summary> |
@@ -1659,8 +1661,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1659 | /// <exception cref="System.Exception">Thrown if registration of the region itself fails.</exception> | 1661 | /// <exception cref="System.Exception">Thrown if registration of the region itself fails.</exception> |
1660 | public void RegisterRegionWithGrid() | 1662 | public void RegisterRegionWithGrid() |
1661 | { | 1663 | { |
1662 | RegisterCommsEvents(); | ||
1663 | |||
1664 | m_sceneGridService.SetScene(this); | 1664 | m_sceneGridService.SetScene(this); |
1665 | 1665 | ||
1666 | GridRegion region = new GridRegion(RegionInfo); | 1666 | GridRegion region = new GridRegion(RegionInfo); |
@@ -2661,11 +2661,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2661 | // Send all scene object to the new client | 2661 | // Send all scene object to the new client |
2662 | Util.FireAndForget(delegate | 2662 | Util.FireAndForget(delegate |
2663 | { | 2663 | { |
2664 | Entities.ForEach(delegate(EntityBase e) | 2664 | EntityBase[] entities = Entities.GetEntities(); |
2665 | foreach(EntityBase e in entities) | ||
2665 | { | 2666 | { |
2666 | if (e != null && e is SceneObjectGroup) | 2667 | if (e != null && e is SceneObjectGroup) |
2667 | ((SceneObjectGroup)e).SendFullUpdateToClient(client); | 2668 | ((SceneObjectGroup)e).SendFullUpdateToClient(client); |
2668 | }); | 2669 | } |
2669 | }); | 2670 | }); |
2670 | } | 2671 | } |
2671 | 2672 | ||
@@ -3328,40 +3329,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
3328 | #region RegionComms | 3329 | #region RegionComms |
3329 | 3330 | ||
3330 | /// <summary> | 3331 | /// <summary> |
3331 | /// Register the methods that should be invoked when this scene receives various incoming events | ||
3332 | /// </summary> | ||
3333 | public void RegisterCommsEvents() | ||
3334 | { | ||
3335 | m_sceneGridService.OnAvatarCrossingIntoRegion += AgentCrossing; | ||
3336 | m_sceneGridService.OnCloseAgentConnection += IncomingCloseAgent; | ||
3337 | //m_eventManager.OnRegionUp += OtherRegionUp; | ||
3338 | //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate; | ||
3339 | //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar; | ||
3340 | m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid; | ||
3341 | m_sceneGridService.OnGetLandData += GetLandData; | ||
3342 | } | ||
3343 | |||
3344 | /// <summary> | ||
3345 | /// Deregister this scene from receiving incoming region events | ||
3346 | /// </summary> | ||
3347 | public void UnRegisterRegionWithComms() | ||
3348 | { | ||
3349 | m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid; | ||
3350 | //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar; | ||
3351 | //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate; | ||
3352 | //m_eventManager.OnRegionUp -= OtherRegionUp; | ||
3353 | m_sceneGridService.OnAvatarCrossingIntoRegion -= AgentCrossing; | ||
3354 | m_sceneGridService.OnCloseAgentConnection -= IncomingCloseAgent; | ||
3355 | m_sceneGridService.OnGetLandData -= GetLandData; | ||
3356 | |||
3357 | // this does nothing; should be removed | ||
3358 | m_sceneGridService.Close(); | ||
3359 | |||
3360 | if (!GridService.DeregisterRegion(m_regInfo.RegionID)) | ||
3361 | m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", m_regInfo.RegionName); | ||
3362 | } | ||
3363 | |||
3364 | /// <summary> | ||
3365 | /// Do the work necessary to initiate a new user connection for a particular scene. | 3332 | /// Do the work necessary to initiate a new user connection for a particular scene. |
3366 | /// At the moment, this consists of setting up the caps infrastructure | 3333 | /// At the moment, this consists of setting up the caps infrastructure |
3367 | /// The return bool should allow for connections to be refused, but as not all calling paths | 3334 | /// 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 | ||
28 | using log4net; | ||
28 | using System; | 29 | using System; |
29 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Reflection; | ||
30 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
31 | using OpenMetaverse; | 33 | using 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); |