diff options
author | Dan Lake | 2010-03-19 05:51:16 -0700 |
---|---|---|
committer | John Hurliman | 2010-03-19 15:16:35 -0700 |
commit | 859bc717a4fe4cd5810ad9889cfb9b1e7f5c2046 (patch) | |
tree | dcce6c74d201b52c1a04ec9ec2cb90ce068fc020 | |
parent | Inconsistent locking of ScenePresence array in SceneGraph. Fixed by eliminati... (diff) | |
download | opensim-SC_OLD-859bc717a4fe4cd5810ad9889cfb9b1e7f5c2046.zip opensim-SC_OLD-859bc717a4fe4cd5810ad9889cfb9b1e7f5c2046.tar.gz opensim-SC_OLD-859bc717a4fe4cd5810ad9889cfb9b1e7f5c2046.tar.bz2 opensim-SC_OLD-859bc717a4fe4cd5810ad9889cfb9b1e7f5c2046.tar.xz |
Cleaned up access to scenepresences in scenegraph. GetScenePresences and GetAvatars have been removed to consolidate locking and iteration within SceneGraph. All callers which used these to then iterate over presences have been refactored to instead pass their delegates to Scene.ForEachScenePresence(Action<ScenePresence>).
22 files changed, 366 insertions, 501 deletions
diff --git a/OpenSim/ApplicationPlugins/Rest/Inventory/tests/Remote.cs b/OpenSim/ApplicationPlugins/Rest/Inventory/tests/Remote.cs index b15b337..4333ef1 100644 --- a/OpenSim/ApplicationPlugins/Rest/Inventory/tests/Remote.cs +++ b/OpenSim/ApplicationPlugins/Rest/Inventory/tests/Remote.cs | |||
@@ -123,10 +123,15 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests | |||
123 | 123 | ||
124 | private void DoMove(RequestData rdata) | 124 | private void DoMove(RequestData rdata) |
125 | { | 125 | { |
126 | if (rdata.Parameters.Length >= 6) | 126 | if (rdata.Parameters.Length < 6) |
127 | { | ||
128 | Rest.Log.WarnFormat("{0} Move: No movement information provided", MsgId); | ||
129 | rdata.Fail(Rest.HttpStatusCodeBadRequest, "no movement information provided"); | ||
130 | } | ||
131 | else | ||
127 | { | 132 | { |
128 | string[] names = rdata.Parameters[PARM_MOVE_AVATAR].Split(Rest.CA_SPACE); | 133 | string[] names = rdata.Parameters[PARM_MOVE_AVATAR].Split(Rest.CA_SPACE); |
129 | ScenePresence avatar = null; | 134 | ScenePresence presence = null; |
130 | Scene scene = null; | 135 | Scene scene = null; |
131 | 136 | ||
132 | if (names.Length != 2) | 137 | if (names.Length != 2) |
@@ -141,21 +146,19 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests | |||
141 | // The first parameter should be an avatar name, look for the | 146 | // The first parameter should be an avatar name, look for the |
142 | // avatar in the known regions first. | 147 | // avatar in the known regions first. |
143 | 148 | ||
144 | foreach (Scene cs in Rest.main.SceneManager.Scenes) | 149 | Rest.main.SceneManager.ForEachScene(delegate(Scene s) |
145 | { | 150 | { |
146 | foreach (ScenePresence presence in cs.GetAvatars()) | 151 | s.ForEachScenePresence(delegate(ScenePresence sp) |
147 | { | 152 | { |
148 | if (presence.Firstname == names[0] && | 153 | if (sp.Firstname == names[0] && sp.Lastname == names[1]) |
149 | presence.Lastname == names[1]) | ||
150 | { | 154 | { |
151 | scene = cs; | 155 | scene = s; |
152 | avatar = presence; | 156 | presence = sp; |
153 | break; | ||
154 | } | 157 | } |
155 | } | 158 | }); |
156 | } | 159 | }); |
157 | 160 | ||
158 | if (avatar != null) | 161 | if (presence != null) |
159 | { | 162 | { |
160 | Rest.Log.DebugFormat("{0} Move : Avatar {1} located in region {2}", | 163 | Rest.Log.DebugFormat("{0} Move : Avatar {1} located in region {2}", |
161 | MsgId, rdata.Parameters[PARM_MOVE_AVATAR], scene.RegionInfo.RegionName); | 164 | MsgId, rdata.Parameters[PARM_MOVE_AVATAR], scene.RegionInfo.RegionName); |
@@ -166,14 +169,13 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests | |||
166 | float y = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Y]); | 169 | float y = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Y]); |
167 | float z = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Z]); | 170 | float z = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Z]); |
168 | Vector3 vector = new Vector3(x,y,z); | 171 | Vector3 vector = new Vector3(x,y,z); |
169 | avatar.DoAutoPilot(0,vector,avatar.ControllingClient); | 172 | presence.DoAutoPilot(0,vector,presence.ControllingClient); |
170 | } | 173 | } |
171 | catch (Exception e) | 174 | catch (Exception e) |
172 | { | 175 | { |
173 | rdata.Fail(Rest.HttpStatusCodeBadRequest, | 176 | rdata.Fail(Rest.HttpStatusCodeBadRequest, |
174 | String.Format("invalid parameters: {0}", e.Message)); | 177 | String.Format("invalid parameters: {0}", e.Message)); |
175 | } | 178 | } |
176 | |||
177 | } | 179 | } |
178 | else | 180 | else |
179 | { | 181 | { |
@@ -183,12 +185,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests | |||
183 | 185 | ||
184 | rdata.Complete(); | 186 | rdata.Complete(); |
185 | rdata.Respond("OK"); | 187 | rdata.Respond("OK"); |
186 | |||
187 | } | ||
188 | else | ||
189 | { | ||
190 | Rest.Log.WarnFormat("{0} Move: No movement information provided", MsgId); | ||
191 | rdata.Fail(Rest.HttpStatusCodeBadRequest, "no movement information provided"); | ||
192 | } | 188 | } |
193 | } | 189 | } |
194 | 190 | ||
diff --git a/OpenSim/ApplicationPlugins/Rest/Regions/GETHandler.cs b/OpenSim/ApplicationPlugins/Rest/Regions/GETHandler.cs index ed18207..dea166d 100644 --- a/OpenSim/ApplicationPlugins/Rest/Regions/GETHandler.cs +++ b/OpenSim/ApplicationPlugins/Rest/Regions/GETHandler.cs | |||
@@ -192,7 +192,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Regions | |||
192 | 192 | ||
193 | protected string RegionStats(OSHttpResponse httpResponse, Scene scene) | 193 | protected string RegionStats(OSHttpResponse httpResponse, Scene scene) |
194 | { | 194 | { |
195 | int users = scene.GetAvatars().Count; | 195 | int users = scene.GetRootAgentCount(); |
196 | int objects = scene.Entities.Count - users; | 196 | int objects = scene.Entities.Count - users; |
197 | 197 | ||
198 | RestXmlWriter rxw = new RestXmlWriter(new StringWriter()); | 198 | RestXmlWriter rxw = new RestXmlWriter(new StringWriter()); |
diff --git a/OpenSim/ApplicationPlugins/Rest/Regions/GETRegionInfoHandler.cs b/OpenSim/ApplicationPlugins/Rest/Regions/GETRegionInfoHandler.cs index 734b668..279db4c 100644 --- a/OpenSim/ApplicationPlugins/Rest/Regions/GETRegionInfoHandler.cs +++ b/OpenSim/ApplicationPlugins/Rest/Regions/GETRegionInfoHandler.cs | |||
@@ -117,7 +117,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Regions | |||
117 | rxw.WriteString(s.RegionInfo.InternalEndPoint.ToString()); | 117 | rxw.WriteString(s.RegionInfo.InternalEndPoint.ToString()); |
118 | rxw.WriteEndAttribute(); | 118 | rxw.WriteEndAttribute(); |
119 | 119 | ||
120 | int users = s.GetAvatars().Count; | 120 | int users = s.GetRootAgentCount(); |
121 | rxw.WriteStartAttribute(String.Empty, "avatars", String.Empty); | 121 | rxw.WriteStartAttribute(String.Empty, "avatars", String.Empty); |
122 | rxw.WriteValue(users); | 122 | rxw.WriteValue(users); |
123 | rxw.WriteEndAttribute(); | 123 | rxw.WriteEndAttribute(); |
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 464d922..91d40ab 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs | |||
@@ -468,26 +468,20 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
468 | 468 | ||
469 | private void handleEstateTeleportAllUsersHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID) | 469 | private void handleEstateTeleportAllUsersHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID) |
470 | { | 470 | { |
471 | // Get a fresh list that will not change as people get teleported away | 471 | m_scene.ForEachScenePresence(delegate(ScenePresence sp) |
472 | List<ScenePresence> presences = m_scene.GetScenePresences(); | ||
473 | |||
474 | foreach(ScenePresence p in presences) | ||
475 | { | 472 | { |
476 | if (p.UUID != senderID) | 473 | if (sp.UUID != senderID) |
477 | { | 474 | { |
475 | ScenePresence p = m_scene.GetScenePresence(sp.UUID); | ||
478 | // make sure they are still there, we could be working down a long list | 476 | // make sure they are still there, we could be working down a long list |
479 | ScenePresence s = m_scene.GetScenePresence(p.UUID); | 477 | // Also make sure they are actually in the region |
480 | if (s != null) | 478 | if (p != null && !p.IsChildAgent) |
481 | { | 479 | { |
482 | // Also make sure they are actually in the region | 480 | p.ControllingClient.SendTeleportLocationStart(); |
483 | if (!s.IsChildAgent) | 481 | m_scene.TeleportClientHome(p.UUID, p.ControllingClient); |
484 | { | ||
485 | s.ControllingClient.SendTeleportLocationStart(); | ||
486 | m_scene.TeleportClientHome(s.UUID, s.ControllingClient); | ||
487 | } | ||
488 | } | 482 | } |
489 | } | 483 | } |
490 | } | 484 | }); |
491 | } | 485 | } |
492 | private void AbortTerrainXferHandler(IClientAPI remoteClient, ulong XferID) | 486 | private void AbortTerrainXferHandler(IClientAPI remoteClient, ulong XferID) |
493 | { | 487 | { |
@@ -765,12 +759,11 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
765 | 759 | ||
766 | public void sendRegionInfoPacketToAll() | 760 | public void sendRegionInfoPacketToAll() |
767 | { | 761 | { |
768 | List<ScenePresence> avatars = m_scene.GetAvatars(); | 762 | m_scene.ForEachScenePresence(delegate(ScenePresence sp) |
769 | |||
770 | for (int i = 0; i < avatars.Count; i++) | ||
771 | { | 763 | { |
772 | HandleRegionInfoRequest(avatars[i].ControllingClient); | 764 | if (!sp.IsChildAgent) |
773 | } | 765 | HandleRegionInfoRequest(sp.ControllingClient); |
766 | }); | ||
774 | } | 767 | } |
775 | 768 | ||
776 | public void sendRegionHandshake(IClientAPI remoteClient) | 769 | public void sendRegionHandshake(IClientAPI remoteClient) |
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 1279ac1..5750aa4 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | |||
@@ -191,9 +191,9 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
191 | forcedPosition = null; | 191 | forcedPosition = null; |
192 | } | 192 | } |
193 | //if we are far away, teleport | 193 | //if we are far away, teleport |
194 | else if (Vector3.Distance(clientAvatar.AbsolutePosition,forcedPosition.Value) > 3) | 194 | else if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition.Value) > 3) |
195 | { | 195 | { |
196 | Debug.WriteLine(string.Format("Teleporting out because {0} is too far from avatar position {1}",forcedPosition.Value,clientAvatar.AbsolutePosition)); | 196 | Debug.WriteLine(string.Format("Teleporting out because {0} is too far from avatar position {1}", forcedPosition.Value, clientAvatar.AbsolutePosition)); |
197 | clientAvatar.Teleport(forcedPosition.Value); | 197 | clientAvatar.Teleport(forcedPosition.Value); |
198 | forcedPosition = null; | 198 | forcedPosition = null; |
199 | } | 199 | } |
@@ -374,30 +374,27 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
374 | } | 374 | } |
375 | } | 375 | } |
376 | 376 | ||
377 | public void SendOutNearestBanLine(IClientAPI avatar) | 377 | public void SendOutNearestBanLine(IClientAPI client) |
378 | { | 378 | { |
379 | List<ScenePresence> avatars = m_scene.GetAvatars(); | 379 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); |
380 | foreach (ScenePresence presence in avatars) | 380 | if (sp == null || sp.IsChildAgent) |
381 | return; | ||
382 | |||
383 | List<ILandObject> checkLandParcels = ParcelsNearPoint(sp.AbsolutePosition); | ||
384 | foreach (ILandObject checkBan in checkLandParcels) | ||
381 | { | 385 | { |
382 | if (presence.UUID == avatar.AgentId) | 386 | if (checkBan.IsBannedFromLand(client.AgentId)) |
383 | { | 387 | { |
384 | List<ILandObject> checkLandParcels = ParcelsNearPoint(presence.AbsolutePosition); | 388 | checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, false, (int)ParcelResult.Single, client); |
385 | foreach (ILandObject checkBan in checkLandParcels) | 389 | return; //Only send one |
386 | { | 390 | } |
387 | if (checkBan.IsBannedFromLand(avatar.AgentId)) | 391 | if (checkBan.IsRestrictedFromLand(client.AgentId)) |
388 | { | 392 | { |
389 | checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, false, (int)ParcelResult.Single, avatar); | 393 | checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, false, (int)ParcelResult.Single, client); |
390 | return; //Only send one | 394 | return; //Only send one |
391 | } | ||
392 | if (checkBan.IsRestrictedFromLand(avatar.AgentId)) | ||
393 | { | ||
394 | checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, false, (int)ParcelResult.Single, avatar); | ||
395 | return; //Only send one | ||
396 | } | ||
397 | } | ||
398 | return; | ||
399 | } | 395 | } |
400 | } | 396 | } |
397 | return; | ||
401 | } | 398 | } |
402 | 399 | ||
403 | public void SendLandUpdate(ScenePresence avatar, bool force) | 400 | public void SendLandUpdate(ScenePresence avatar, bool force) |
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index e85136a..b2d9b66 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs | |||
@@ -332,36 +332,38 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
332 | 332 | ||
333 | public void SendLandUpdateToAvatarsOverMe(bool snap_selection) | 333 | public void SendLandUpdateToAvatarsOverMe(bool snap_selection) |
334 | { | 334 | { |
335 | List<ScenePresence> avatars = m_scene.GetAvatars(); | 335 | m_scene.ForEachScenePresence(delegate(ScenePresence avatar) |
336 | ILandObject over = null; | ||
337 | for (int i = 0; i < avatars.Count; i++) | ||
338 | { | 336 | { |
337 | if (avatar.IsChildAgent) | ||
338 | return; | ||
339 | |||
340 | ILandObject over = null; | ||
339 | try | 341 | try |
340 | { | 342 | { |
341 | over = | 343 | over = |
342 | m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatars[i].AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)), | 344 | m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)), |
343 | Util.Clamp<int>((int)Math.Round(avatars[i].AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1))); | 345 | Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1))); |
344 | } | 346 | } |
345 | catch (Exception) | 347 | catch (Exception) |
346 | { | 348 | { |
347 | m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatars[i].AbsolutePosition.X) + " y: " + | 349 | m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " + |
348 | Math.Round(avatars[i].AbsolutePosition.Y)); | 350 | Math.Round(avatar.AbsolutePosition.Y)); |
349 | } | 351 | } |
350 | 352 | ||
351 | if (over != null) | 353 | if (over != null) |
352 | { | 354 | { |
353 | if (over.LandData.LocalID == LandData.LocalID) | 355 | if (over.LandData.LocalID == LandData.LocalID) |
354 | { | 356 | { |
355 | if (((over.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) && | 357 | if (((over.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) && |
356 | m_scene.RegionInfo.RegionSettings.AllowDamage) | 358 | m_scene.RegionInfo.RegionSettings.AllowDamage) |
357 | avatars[i].Invulnerable = false; | 359 | avatar.Invulnerable = false; |
358 | else | 360 | else |
359 | avatars[i].Invulnerable = true; | 361 | avatar.Invulnerable = true; |
360 | 362 | ||
361 | SendLandUpdateToClient(snap_selection, avatars[i].ControllingClient); | 363 | SendLandUpdateToClient(snap_selection, avatar.ControllingClient); |
362 | } | 364 | } |
363 | } | 365 | } |
364 | } | 366 | }); |
365 | } | 367 | } |
366 | 368 | ||
367 | #endregion | 369 | #endregion |
diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs index 1f5a4ff..a52fea4 100644 --- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs +++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs | |||
@@ -62,40 +62,46 @@ namespace OpenSim.Region.CoreModules.World.Sound | |||
62 | public virtual void PlayAttachedSound( | 62 | public virtual void PlayAttachedSound( |
63 | UUID soundID, UUID ownerID, UUID objectID, double gain, Vector3 position, byte flags, float radius) | 63 | UUID soundID, UUID ownerID, UUID objectID, double gain, Vector3 position, byte flags, float radius) |
64 | { | 64 | { |
65 | foreach (ScenePresence p in m_scene.GetAvatars()) | 65 | m_scene.ForEachScenePresence(delegate(ScenePresence sp) |
66 | { | 66 | { |
67 | double dis = Util.GetDistanceTo(p.AbsolutePosition, position); | 67 | if (sp.IsChildAgent) |
68 | return; | ||
69 | |||
70 | double dis = Util.GetDistanceTo(sp.AbsolutePosition, position); | ||
68 | if (dis > 100.0) // Max audio distance | 71 | if (dis > 100.0) // Max audio distance |
69 | continue; | 72 | return; |
70 | 73 | ||
71 | // Scale by distance | 74 | // Scale by distance |
72 | if (radius == 0) | 75 | if (radius == 0) |
73 | gain = (float)((double)gain * ((100.0 - dis) / 100.0)); | 76 | gain = (float)((double)gain * ((100.0 - dis) / 100.0)); |
74 | else | 77 | else |
75 | gain = (float)((double)gain * ((radius - dis) / radius)); | 78 | gain = (float)((double)gain * ((radius - dis) / radius)); |
76 | 79 | ||
77 | p.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, (float)gain, flags); | 80 | sp.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, (float)gain, flags); |
78 | } | 81 | }); |
79 | } | 82 | } |
80 | 83 | ||
81 | public virtual void TriggerSound( | 84 | public virtual void TriggerSound( |
82 | UUID soundId, UUID ownerID, UUID objectID, UUID parentID, double gain, Vector3 position, UInt64 handle, float radius) | 85 | UUID soundId, UUID ownerID, UUID objectID, UUID parentID, double gain, Vector3 position, UInt64 handle, float radius) |
83 | { | 86 | { |
84 | foreach (ScenePresence p in m_scene.GetAvatars()) | 87 | m_scene.ForEachScenePresence(delegate(ScenePresence sp) |
85 | { | 88 | { |
86 | double dis = Util.GetDistanceTo(p.AbsolutePosition, position); | 89 | if (sp.IsChildAgent) |
90 | return; | ||
91 | |||
92 | double dis = Util.GetDistanceTo(sp.AbsolutePosition, position); | ||
87 | if (dis > 100.0) // Max audio distance | 93 | if (dis > 100.0) // Max audio distance |
88 | continue; | 94 | return; |
89 | 95 | ||
90 | // Scale by distance | 96 | // Scale by distance |
91 | if (radius == 0) | 97 | if (radius == 0) |
92 | gain = (float)((double)gain * ((100.0 - dis) / 100.0)); | 98 | gain = (float)((double)gain * ((100.0 - dis) / 100.0)); |
93 | else | 99 | else |
94 | gain = (float)((double)gain * ((radius - dis) / radius)); | 100 | gain = (float)((double)gain * ((radius - dis) / radius)); |
95 | 101 | ||
96 | p.ControllingClient.SendTriggeredSound( | 102 | sp.ControllingClient.SendTriggeredSound( |
97 | soundId, ownerID, objectID, parentID, handle, position, (float)gain); | 103 | soundId, ownerID, objectID, parentID, handle, position, (float)gain); |
98 | } | 104 | }); |
99 | } | 105 | } |
100 | } | 106 | } |
101 | } | 107 | } |
diff --git a/OpenSim/Region/CoreModules/World/Sun/SunModule.cs b/OpenSim/Region/CoreModules/World/Sun/SunModule.cs index 0712a7f..a6dc2ec 100644 --- a/OpenSim/Region/CoreModules/World/Sun/SunModule.cs +++ b/OpenSim/Region/CoreModules/World/Sun/SunModule.cs | |||
@@ -509,14 +509,13 @@ namespace OpenSim.Region.CoreModules | |||
509 | 509 | ||
510 | private void SunUpdateToAllClients() | 510 | private void SunUpdateToAllClients() |
511 | { | 511 | { |
512 | List<ScenePresence> avatars = m_scene.GetAvatars(); | 512 | m_scene.ForEachScenePresence(delegate(ScenePresence sp) |
513 | foreach (ScenePresence avatar in avatars) | ||
514 | { | 513 | { |
515 | if (!avatar.IsChildAgent) | 514 | if (!sp.IsChildAgent) |
516 | { | 515 | { |
517 | SunToClient(avatar.ControllingClient); | 516 | SunToClient(sp.ControllingClient); |
518 | } | 517 | } |
519 | } | 518 | }); |
520 | } | 519 | } |
521 | 520 | ||
522 | #region ISunModule Members | 521 | #region ISunModule Members |
diff --git a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs index 3283c1f..9736b73 100644 --- a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs +++ b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs | |||
@@ -425,9 +425,7 @@ namespace OpenSim.Region.CoreModules | |||
425 | { | 425 | { |
426 | if (m_ready) | 426 | if (m_ready) |
427 | { | 427 | { |
428 | List<ScenePresence> avatars = m_scene.GetAvatars(); | 428 | if(m_scene.GetRootAgentCount() > 0) |
429 | |||
430 | if (avatars.Count > 0) | ||
431 | { | 429 | { |
432 | // Ask wind plugin to generate a LL wind array to be cached locally | 430 | // Ask wind plugin to generate a LL wind array to be cached locally |
433 | // Try not to update this too often, as it may involve array copies | 431 | // Try not to update this too often, as it may involve array copies |
@@ -437,11 +435,11 @@ namespace OpenSim.Region.CoreModules | |||
437 | m_frameLastUpdateClientArray = m_frame; | 435 | m_frameLastUpdateClientArray = m_frame; |
438 | } | 436 | } |
439 | 437 | ||
440 | foreach (ScenePresence avatar in avatars) | 438 | m_scene.ForEachScenePresence(delegate(ScenePresence sp) |
441 | { | 439 | { |
442 | if (!avatar.IsChildAgent) | 440 | if (!sp.IsChildAgent) |
443 | avatar.ControllingClient.SendWindData(windSpeeds); | 441 | sp.ControllingClient.SendWindData(windSpeeds); |
444 | } | 442 | }); |
445 | } | 443 | } |
446 | } | 444 | } |
447 | } | 445 | } |
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index b63d014..f1cc0dd 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | |||
@@ -304,25 +304,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
304 | /// <param name="AgentId">AgentID that logged out</param> | 304 | /// <param name="AgentId">AgentID that logged out</param> |
305 | private void ClientLoggedOut(UUID AgentId, Scene scene) | 305 | private void ClientLoggedOut(UUID AgentId, Scene scene) |
306 | { | 306 | { |
307 | List<ScenePresence> presences = m_scene.GetAvatars(); | ||
308 | int rootcount = 0; | ||
309 | for (int i=0;i<presences.Count;i++) | ||
310 | { | ||
311 | if (presences[i] != null) | ||
312 | { | ||
313 | if (!presences[i].IsChildAgent) | ||
314 | rootcount++; | ||
315 | } | ||
316 | } | ||
317 | if (rootcount <= 1) | ||
318 | StopThread(); | ||
319 | |||
320 | lock (m_rootAgents) | 307 | lock (m_rootAgents) |
321 | { | 308 | { |
322 | if (m_rootAgents.Contains(AgentId)) | 309 | m_rootAgents.Remove(AgentId); |
323 | { | 310 | if(m_rootAgents.Count == 0) |
324 | m_rootAgents.Remove(AgentId); | 311 | StopThread(); |
325 | } | ||
326 | } | 312 | } |
327 | } | 313 | } |
328 | #endregion | 314 | #endregion |
@@ -375,11 +361,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
375 | if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle) | 361 | if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle) |
376 | { | 362 | { |
377 | // Local Map Item Request | 363 | // Local Map Item Request |
378 | List<ScenePresence> avatars = m_scene.GetAvatars(); | ||
379 | int tc = Environment.TickCount; | 364 | int tc = Environment.TickCount; |
380 | List<mapItemReply> mapitems = new List<mapItemReply>(); | 365 | List<mapItemReply> mapitems = new List<mapItemReply>(); |
381 | mapItemReply mapitem = new mapItemReply(); | 366 | mapItemReply mapitem = new mapItemReply(); |
382 | if (avatars.Count == 0 || avatars.Count == 1) | 367 | if (m_scene.GetRootAgentCount() <= 1) |
383 | { | 368 | { |
384 | mapitem = new mapItemReply(); | 369 | mapitem = new mapItemReply(); |
385 | mapitem.x = (uint)(xstart + 1); | 370 | mapitem.x = (uint)(xstart + 1); |
@@ -392,21 +377,21 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
392 | } | 377 | } |
393 | else | 378 | else |
394 | { | 379 | { |
395 | foreach (ScenePresence av in avatars) | 380 | m_scene.ForEachScenePresence(delegate(ScenePresence sp) |
396 | { | 381 | { |
397 | // Don't send a green dot for yourself | 382 | // Don't send a green dot for yourself |
398 | if (av.UUID != remoteClient.AgentId) | 383 | if (!sp.IsChildAgent && sp.UUID != remoteClient.AgentId) |
399 | { | 384 | { |
400 | mapitem = new mapItemReply(); | 385 | mapitem = new mapItemReply(); |
401 | mapitem.x = (uint)(xstart + av.AbsolutePosition.X); | 386 | mapitem.x = (uint)(xstart + sp.AbsolutePosition.X); |
402 | mapitem.y = (uint)(ystart + av.AbsolutePosition.Y); | 387 | mapitem.y = (uint)(ystart + sp.AbsolutePosition.Y); |
403 | mapitem.id = UUID.Zero; | 388 | mapitem.id = UUID.Zero; |
404 | mapitem.name = Util.Md5Hash(m_scene.RegionInfo.RegionName + tc.ToString()); | 389 | mapitem.name = Util.Md5Hash(m_scene.RegionInfo.RegionName + tc.ToString()); |
405 | mapitem.Extra = 1; | 390 | mapitem.Extra = 1; |
406 | mapitem.Extra2 = 0; | 391 | mapitem.Extra2 = 0; |
407 | mapitems.Add(mapitem); | 392 | mapitems.Add(mapitem); |
408 | } | 393 | } |
409 | } | 394 | }); |
410 | } | 395 | } |
411 | remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags); | 396 | remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags); |
412 | } | 397 | } |
@@ -981,51 +966,35 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
981 | Utils.LongToUInts(m_scene.RegionInfo.RegionHandle,out xstart,out ystart); | 966 | Utils.LongToUInts(m_scene.RegionInfo.RegionHandle,out xstart,out ystart); |
982 | 967 | ||
983 | OSDMap responsemap = new OSDMap(); | 968 | OSDMap responsemap = new OSDMap(); |
984 | List<ScenePresence> avatars = m_scene.GetAvatars(); | ||
985 | OSDArray responsearr = new OSDArray(avatars.Count); | ||
986 | OSDMap responsemapdata = new OSDMap(); | ||
987 | int tc = Environment.TickCount; | 969 | int tc = Environment.TickCount; |
988 | /* | 970 | if (m_scene.GetRootAgentCount() == 0) |
989 | foreach (ScenePresence av in avatars) | ||
990 | { | ||
991 | responsemapdata = new OSDMap(); | ||
992 | responsemapdata["X"] = OSD.FromInteger((int)(xstart + av.AbsolutePosition.X)); | ||
993 | responsemapdata["Y"] = OSD.FromInteger((int)(ystart + av.AbsolutePosition.Y)); | ||
994 | responsemapdata["ID"] = OSD.FromUUID(UUID.Zero); | ||
995 | responsemapdata["Name"] = OSD.FromString("TH"); | ||
996 | responsemapdata["Extra"] = OSD.FromInteger(0); | ||
997 | responsemapdata["Extra2"] = OSD.FromInteger(0); | ||
998 | responsearr.Add(responsemapdata); | ||
999 | } | ||
1000 | responsemap["1"] = responsearr; | ||
1001 | */ | ||
1002 | if (avatars.Count == 0) | ||
1003 | { | 971 | { |
1004 | responsemapdata = new OSDMap(); | 972 | OSDMap responsemapdata = new OSDMap(); |
1005 | responsemapdata["X"] = OSD.FromInteger((int)(xstart + 1)); | 973 | responsemapdata["X"] = OSD.FromInteger((int)(xstart + 1)); |
1006 | responsemapdata["Y"] = OSD.FromInteger((int)(ystart + 1)); | 974 | responsemapdata["Y"] = OSD.FromInteger((int)(ystart + 1)); |
1007 | responsemapdata["ID"] = OSD.FromUUID(UUID.Zero); | 975 | responsemapdata["ID"] = OSD.FromUUID(UUID.Zero); |
1008 | responsemapdata["Name"] = OSD.FromString(Util.Md5Hash(m_scene.RegionInfo.RegionName + tc.ToString())); | 976 | responsemapdata["Name"] = OSD.FromString(Util.Md5Hash(m_scene.RegionInfo.RegionName + tc.ToString())); |
1009 | responsemapdata["Extra"] = OSD.FromInteger(0); | 977 | responsemapdata["Extra"] = OSD.FromInteger(0); |
1010 | responsemapdata["Extra2"] = OSD.FromInteger(0); | 978 | responsemapdata["Extra2"] = OSD.FromInteger(0); |
979 | OSDArray responsearr = new OSDArray(); | ||
1011 | responsearr.Add(responsemapdata); | 980 | responsearr.Add(responsemapdata); |
1012 | 981 | ||
1013 | responsemap["6"] = responsearr; | 982 | responsemap["6"] = responsearr; |
1014 | } | 983 | } |
1015 | else | 984 | else |
1016 | { | 985 | { |
1017 | responsearr = new OSDArray(avatars.Count); | 986 | OSDArray responsearr = new OSDArray(m_scene.GetRootAgentCount()); |
1018 | foreach (ScenePresence av in avatars) | 987 | m_scene.ForEachScenePresence(delegate(ScenePresence sp) |
1019 | { | 988 | { |
1020 | responsemapdata = new OSDMap(); | 989 | OSDMap responsemapdata = new OSDMap(); |
1021 | responsemapdata["X"] = OSD.FromInteger((int)(xstart + av.AbsolutePosition.X)); | 990 | responsemapdata["X"] = OSD.FromInteger((int)(xstart + sp.AbsolutePosition.X)); |
1022 | responsemapdata["Y"] = OSD.FromInteger((int)(ystart + av.AbsolutePosition.Y)); | 991 | responsemapdata["Y"] = OSD.FromInteger((int)(ystart + sp.AbsolutePosition.Y)); |
1023 | responsemapdata["ID"] = OSD.FromUUID(UUID.Zero); | 992 | responsemapdata["ID"] = OSD.FromUUID(UUID.Zero); |
1024 | responsemapdata["Name"] = OSD.FromString(Util.Md5Hash(m_scene.RegionInfo.RegionName + tc.ToString())); | 993 | responsemapdata["Name"] = OSD.FromString(Util.Md5Hash(m_scene.RegionInfo.RegionName + tc.ToString())); |
1025 | responsemapdata["Extra"] = OSD.FromInteger(1); | 994 | responsemapdata["Extra"] = OSD.FromInteger(1); |
1026 | responsemapdata["Extra2"] = OSD.FromInteger(0); | 995 | responsemapdata["Extra2"] = OSD.FromInteger(0); |
1027 | responsearr.Add(responsemapdata); | 996 | responsearr.Add(responsemapdata); |
1028 | } | 997 | }); |
1029 | responsemap["6"] = responsearr; | 998 | responsemap["6"] = responsearr; |
1030 | } | 999 | } |
1031 | return responsemap; | 1000 | return responsemap; |
@@ -1107,25 +1076,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1107 | 1076 | ||
1108 | private void MakeChildAgent(ScenePresence avatar) | 1077 | private void MakeChildAgent(ScenePresence avatar) |
1109 | { | 1078 | { |
1110 | List<ScenePresence> presences = m_scene.GetAvatars(); | ||
1111 | int rootcount = 0; | ||
1112 | for (int i = 0; i < presences.Count; i++) | ||
1113 | { | ||
1114 | if (presences[i] != null) | ||
1115 | { | ||
1116 | if (!presences[i].IsChildAgent) | ||
1117 | rootcount++; | ||
1118 | } | ||
1119 | } | ||
1120 | if (rootcount <= 1) | ||
1121 | StopThread(); | ||
1122 | |||
1123 | lock (m_rootAgents) | 1079 | lock (m_rootAgents) |
1124 | { | 1080 | { |
1125 | if (m_rootAgents.Contains(avatar.UUID)) | 1081 | m_rootAgents.Remove(avatar.UUID); |
1126 | { | 1082 | if (m_rootAgents.Count == 0) |
1127 | m_rootAgents.Remove(avatar.UUID); | 1083 | StopThread(); |
1128 | } | ||
1129 | } | 1084 | } |
1130 | } | 1085 | } |
1131 | 1086 | ||
diff --git a/OpenSim/Region/Examples/SimpleModule/RegionModule.cs b/OpenSim/Region/Examples/SimpleModule/RegionModule.cs index e1d5bdc..6da41db 100644 --- a/OpenSim/Region/Examples/SimpleModule/RegionModule.cs +++ b/OpenSim/Region/Examples/SimpleModule/RegionModule.cs | |||
@@ -88,12 +88,12 @@ namespace OpenSim.Region.Examples.SimpleModule | |||
88 | m_scene.AgentCrossing(m_character.AgentId, Vector3.Zero, false); | 88 | m_scene.AgentCrossing(m_character.AgentId, Vector3.Zero, false); |
89 | } | 89 | } |
90 | 90 | ||
91 | List<ScenePresence> avatars = m_scene.GetAvatars(); | 91 | m_scene.ForEachScenePresence(delegate(ScenePresence sp) |
92 | foreach (ScenePresence avatar in avatars) | ||
93 | { | 92 | { |
94 | avatar.AbsolutePosition = | 93 | if (!sp.IsChildAgent) |
95 | new Vector3((float)Util.RandomClass.Next(100, 200), (float)Util.RandomClass.Next(30, 200), 2); | 94 | sp.AbsolutePosition = |
96 | } | 95 | new Vector3((float)Util.RandomClass.Next(100, 200), (float)Util.RandomClass.Next(30, 200), 2); |
96 | }); | ||
97 | } | 97 | } |
98 | 98 | ||
99 | // private void AddComplexObjects(RegionInfo regionInfo, Vector3 pos) | 99 | // private void AddComplexObjects(RegionInfo regionInfo, Vector3 pos) |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index a86a33c..4b97e39 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -3269,7 +3269,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3269 | } | 3269 | } |
3270 | } | 3270 | } |
3271 | 3271 | ||
3272 | ScenePresence sp = m_sceneGraph.GetScenePresence(agent.AgentID); | 3272 | ScenePresence sp = GetScenePresence(agent.AgentID); |
3273 | if (sp != null) | 3273 | if (sp != null) |
3274 | { | 3274 | { |
3275 | m_log.DebugFormat( | 3275 | m_log.DebugFormat( |
@@ -3561,8 +3561,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3561 | /// <param name="message">message to display to the user. Reason for being logged off</param> | 3561 | /// <param name="message">message to display to the user. Reason for being logged off</param> |
3562 | public void HandleLogOffUserFromGrid(UUID AvatarID, UUID RegionSecret, string message) | 3562 | public void HandleLogOffUserFromGrid(UUID AvatarID, UUID RegionSecret, string message) |
3563 | { | 3563 | { |
3564 | ScenePresence loggingOffUser = null; | 3564 | ScenePresence loggingOffUser = GetScenePresence(AvatarID); |
3565 | loggingOffUser = GetScenePresence(AvatarID); | ||
3566 | if (loggingOffUser != null) | 3565 | if (loggingOffUser != null) |
3567 | { | 3566 | { |
3568 | UUID localRegionSecret = UUID.Zero; | 3567 | UUID localRegionSecret = UUID.Zero; |
@@ -3598,8 +3597,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3598 | /// <param name="isFlying"></param> | 3597 | /// <param name="isFlying"></param> |
3599 | public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying) | 3598 | public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying) |
3600 | { | 3599 | { |
3601 | ScenePresence presence; | 3600 | ScenePresence presence = GetScenePresence(agentID); |
3602 | if(m_sceneGraph.TryGetAvatar(agentID, out presence)) | 3601 | if(presence != null) |
3603 | { | 3602 | { |
3604 | try | 3603 | try |
3605 | { | 3604 | { |
@@ -3773,8 +3772,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3773 | public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position, | 3772 | public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position, |
3774 | Vector3 lookAt, uint teleportFlags) | 3773 | Vector3 lookAt, uint teleportFlags) |
3775 | { | 3774 | { |
3776 | ScenePresence sp; | 3775 | ScenePresence sp = GetScenePresence(remoteClient.AgentId); |
3777 | if(m_sceneGraph.TryGetAvatar(remoteClient.AgentId, out sp)) | 3776 | if (sp != null) |
3778 | { | 3777 | { |
3779 | uint regionX = m_regInfo.RegionLocX; | 3778 | uint regionX = m_regInfo.RegionLocX; |
3780 | uint regionY = m_regInfo.RegionLocY; | 3779 | uint regionY = m_regInfo.RegionLocY; |
@@ -3952,17 +3951,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
3952 | m_log.ErrorFormat("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16}{5,-16}{6,-16}", "Firstname", "Lastname", | 3951 | m_log.ErrorFormat("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16}{5,-16}{6,-16}", "Firstname", "Lastname", |
3953 | "Agent ID", "Session ID", "Circuit", "IP", "World"); | 3952 | "Agent ID", "Session ID", "Circuit", "IP", "World"); |
3954 | 3953 | ||
3955 | foreach (ScenePresence scenePresence in GetAvatars()) | 3954 | ForEachScenePresence(delegate(ScenePresence sp) |
3956 | { | 3955 | { |
3957 | m_log.ErrorFormat("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16},{5,-16}{6,-16}", | 3956 | m_log.ErrorFormat("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16},{5,-16}{6,-16}", |
3958 | scenePresence.Firstname, | 3957 | sp.Firstname, |
3959 | scenePresence.Lastname, | 3958 | sp.Lastname, |
3960 | scenePresence.UUID, | 3959 | sp.UUID, |
3961 | scenePresence.ControllingClient.AgentId, | 3960 | sp.ControllingClient.AgentId, |
3962 | "Unknown", | 3961 | "Unknown", |
3963 | "Unknown", | 3962 | "Unknown", |
3964 | RegionInfo.RegionName); | 3963 | RegionInfo.RegionName); |
3965 | } | 3964 | }); |
3966 | 3965 | ||
3967 | break; | 3966 | break; |
3968 | } | 3967 | } |
@@ -4128,72 +4127,42 @@ namespace OpenSim.Region.Framework.Scenes | |||
4128 | m_sceneGraph.RemovePhysicalPrim(num); | 4127 | m_sceneGraph.RemovePhysicalPrim(num); |
4129 | } | 4128 | } |
4130 | 4129 | ||
4131 | //The idea is to have a group of method that return a list of avatars meeting some requirement | 4130 | public int GetRootAgentCount() |
4132 | // ie it could be all m_scenePresences within a certain range of the calling prim/avatar. | ||
4133 | // | ||
4134 | // GetAvatars returns a new list of all root agent presences in the scene | ||
4135 | // GetScenePresences returns a new list of all presences in the scene or a filter may be passed. | ||
4136 | // GetScenePresence returns the presence with matching UUID or first/last name. | ||
4137 | // ForEachScenePresence requests the Scene to run a delegate function against all presences. | ||
4138 | |||
4139 | /// <summary> | ||
4140 | /// Return a list of all avatars in this region. | ||
4141 | /// This list is a new object, so it can be iterated over without locking. | ||
4142 | /// </summary> | ||
4143 | /// <returns></returns> | ||
4144 | public List<ScenePresence> GetAvatars() | ||
4145 | { | ||
4146 | return m_sceneGraph.GetAvatars(); | ||
4147 | } | ||
4148 | |||
4149 | /// <summary> | ||
4150 | /// Return a list of all ScenePresences in this region. This returns child agents as well as root agents. | ||
4151 | /// This list is a new object, so it can be iterated over without locking. | ||
4152 | /// </summary> | ||
4153 | /// <returns></returns> | ||
4154 | public List<ScenePresence> GetScenePresences() | ||
4155 | { | 4131 | { |
4156 | return m_sceneGraph.GetScenePresences(); | 4132 | return m_sceneGraph.GetRootAgentCount(); |
4157 | } | 4133 | } |
4158 | 4134 | ||
4159 | /// <summary> | 4135 | public int GetChildAgentCount() |
4160 | /// Request a filtered list of ScenePresences in this region. | ||
4161 | /// This list is a new object, so it can be iterated over without locking. | ||
4162 | /// </summary> | ||
4163 | /// <param name="filter"></param> | ||
4164 | /// <returns></returns> | ||
4165 | public List<ScenePresence> GetScenePresences(FilterAvatarList filter) | ||
4166 | { | 4136 | { |
4167 | return m_sceneGraph.GetScenePresences(filter); | 4137 | return m_sceneGraph.GetChildAgentCount(); |
4168 | } | 4138 | } |
4169 | 4139 | ||
4170 | /// <summary> | 4140 | /// <summary> |
4171 | /// Request a scene presence by UUID | 4141 | /// Request a scene presence by UUID. Fast, indexed lookup. |
4172 | /// </summary> | 4142 | /// </summary> |
4173 | /// <param name="avatarID"></param> | 4143 | /// <param name="agentID"></param> |
4174 | /// <returns></returns> | 4144 | /// <returns>null if the presence was not found</returns> |
4175 | public ScenePresence GetScenePresence(UUID avatarID) | 4145 | public ScenePresence GetScenePresence(UUID agentID) |
4176 | { | 4146 | { |
4177 | return m_sceneGraph.GetScenePresence(avatarID); | 4147 | return m_sceneGraph.GetScenePresence(agentID); |
4178 | } | 4148 | } |
4179 | 4149 | ||
4180 | /// <summary> | 4150 | /// <summary> |
4181 | /// Request the ScenePresence in this region by first/last name. | 4151 | /// Request the scene presence by name. |
4182 | /// Should normally only be a single match, but first is always returned | ||
4183 | /// </summary> | 4152 | /// </summary> |
4184 | /// <param name="firstName"></param> | 4153 | /// <param name="firstName"></param> |
4185 | /// <param name="lastName"></param> | 4154 | /// <param name="lastName"></param> |
4186 | /// <returns></returns> | 4155 | /// <returns>null if the presence was not found</returns> |
4187 | public ScenePresence GetScenePresence(string firstName, string lastName) | 4156 | public ScenePresence GetScenePresence(string firstName, string lastName) |
4188 | { | 4157 | { |
4189 | return m_sceneGraph.GetScenePresence(firstName, lastName); | 4158 | return m_sceneGraph.GetScenePresence(firstName, lastName); |
4190 | } | 4159 | } |
4191 | 4160 | ||
4192 | /// <summary> | 4161 | /// <summary> |
4193 | /// Request the ScenePresence in this region by localID. | 4162 | /// Request the scene presence by localID. |
4194 | /// </summary> | 4163 | /// </summary> |
4195 | /// <param name="localID"></param> | 4164 | /// <param name="localID"></param> |
4196 | /// <returns></returns> | 4165 | /// <returns>null if the presence was not found</returns> |
4197 | public ScenePresence GetScenePresence(uint localID) | 4166 | public ScenePresence GetScenePresence(uint localID) |
4198 | { | 4167 | { |
4199 | return m_sceneGraph.GetScenePresence(localID); | 4168 | return m_sceneGraph.GetScenePresence(localID); |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index d259c42..b6e5995 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -699,116 +699,84 @@ namespace OpenSim.Region.Framework.Scenes | |||
699 | return null; | 699 | return null; |
700 | } | 700 | } |
701 | 701 | ||
702 | // The idea is to have a group of method that return a list of avatars meeting some requirement | ||
703 | // ie it could be all m_scenePresences within a certain range of the calling prim/avatar. | ||
704 | // | ||
705 | // GetAvatars returns a new list of all root agent presences in the scene | ||
706 | // GetScenePresences returns a new list of all presences in the scene or a filter may be passed. | ||
707 | // GetScenePresence returns the presence with matching UUID or the first presence matching the passed filter. | ||
708 | // ForEachScenePresence requests the Scene to run a delegate function against all presences. | ||
709 | |||
710 | /// <summary> | 702 | /// <summary> |
711 | /// Request a list of all avatars in this region (no child agents) | 703 | /// Request a copy of m_scenePresences in this World |
712 | /// This list is a new object, so it can be iterated over without locking. | 704 | /// There is no guarantee that presences will remain in the scene after the list is returned. |
705 | /// This list should remain private to SceneGraph. Callers wishing to iterate should instead | ||
706 | /// pass a delegate to ForEachScenePresence. | ||
713 | /// </summary> | 707 | /// </summary> |
714 | /// <returns></returns> | 708 | /// <returns></returns> |
715 | public List<ScenePresence> GetAvatars() | 709 | private List<ScenePresence> GetScenePresences() |
716 | { | 710 | { |
717 | return GetScenePresences(delegate(ScenePresence scenePresence) | 711 | lock (m_scenePresences) |
718 | { | 712 | return new List<ScenePresence>(m_scenePresenceArray); |
719 | return !scenePresence.IsChildAgent; | ||
720 | }); | ||
721 | } | 713 | } |
722 | 714 | ||
723 | /// <summary> | 715 | /// <summary> |
724 | /// Request a list of m_scenePresences in this World | 716 | /// Request a scene presence by UUID. Fast, indexed lookup. |
725 | /// Returns a copy so it can be iterated without a lock. | ||
726 | /// There is no guarantee that presences will remain in the scene after the list is returned. | ||
727 | /// </summary> | 717 | /// </summary> |
728 | /// <returns></returns> | 718 | /// <param name="agentID"></param> |
729 | protected internal List<ScenePresence> GetScenePresences() | 719 | /// <returns>null if the presence was not found</returns> |
720 | protected internal ScenePresence GetScenePresence(UUID agentID) | ||
730 | { | 721 | { |
731 | List<ScenePresence> result; | 722 | ScenePresence sp; |
732 | lock (m_scenePresences) | 723 | lock (m_scenePresences) |
733 | { | 724 | { |
734 | result = new List<ScenePresence>(m_scenePresenceArray.Length); | 725 | m_scenePresences.TryGetValue(agentID, out sp); |
735 | result.AddRange(m_scenePresenceArray); | ||
736 | } | 726 | } |
737 | return result; | 727 | return sp; |
738 | } | 728 | } |
739 | 729 | ||
740 | /// <summary> | 730 | /// <summary> |
741 | /// Request a filtered list of m_scenePresences in this World | 731 | /// Request the scene presence by name. |
742 | /// Returns a copy so it can be iterated without a lock. | ||
743 | /// There is no guarantee that presences will remain in the scene after the list is returned. | ||
744 | /// </summary> | 732 | /// </summary> |
745 | /// <returns></returns> | 733 | /// <param name="firstName"></param> |
746 | protected internal List<ScenePresence> GetScenePresences(FilterAvatarList filter) | 734 | /// <param name="lastName"></param> |
735 | /// <returns>null if the presence was not found</returns> | ||
736 | protected internal ScenePresence GetScenePresence(string firstName, string lastName) | ||
747 | { | 737 | { |
748 | List<ScenePresence> result = new List<ScenePresence>(); | 738 | foreach (ScenePresence presence in GetScenePresences()) |
749 | // Check each ScenePresence against the filter | ||
750 | ForEachScenePresence(delegate(ScenePresence presence) | ||
751 | { | 739 | { |
752 | if (filter(presence)) | 740 | if (presence.Firstname == firstName && presence.Lastname == lastName) |
753 | result.Add(presence); | 741 | return presence; |
754 | }); | 742 | } |
755 | return result; | 743 | return null; |
756 | } | 744 | } |
757 | 745 | ||
758 | /// <summary> | 746 | /// <summary> |
759 | /// Request the ScenePresence in this region matching filter. | 747 | /// Request the scene presence by localID. |
760 | /// Only the first match is returned. | ||
761 | /// | ||
762 | /// </summary> | 748 | /// </summary> |
763 | /// <param name="filter"></param> | 749 | /// <param name="localID"></param> |
764 | /// <returns></returns> | 750 | /// <returns>null if the presence was not found</returns> |
765 | protected internal ScenePresence GetScenePresence(FilterAvatarList filter) | 751 | protected internal ScenePresence GetScenePresence(uint localID) |
766 | { | 752 | { |
767 | ScenePresence result = null; | 753 | foreach (ScenePresence presence in GetScenePresences()) |
768 | // Get all of the ScenePresences | 754 | if (presence.LocalId == localID) |
769 | List<ScenePresence> presences = GetScenePresences(); | 755 | return presence; |
770 | foreach (ScenePresence presence in presences) | 756 | return null; |
771 | { | ||
772 | if (filter(presence)) | ||
773 | { | ||
774 | result = presence; | ||
775 | break; | ||
776 | } | ||
777 | } | ||
778 | return result; | ||
779 | } | 757 | } |
780 | 758 | ||
781 | protected internal ScenePresence GetScenePresence(string firstName, string lastName) | 759 | protected internal bool TryGetAvatar(UUID agentID, out ScenePresence avatar) |
782 | { | 760 | { |
783 | return GetScenePresence(delegate(ScenePresence presence) | 761 | lock (m_scenePresences) |
784 | { | 762 | { |
785 | return(presence.Firstname == firstName && presence.Lastname == lastName); | 763 | m_scenePresences.TryGetValue(agentID, out avatar); |
786 | }); | 764 | } |
787 | } | 765 | return (avatar != null); |
788 | |||
789 | /// <summary> | ||
790 | /// Request a scene presence by UUID | ||
791 | /// </summary> | ||
792 | /// <param name="agentID"></param> | ||
793 | /// <returns>null if the agent was not found</returns> | ||
794 | protected internal ScenePresence GetScenePresence(UUID agentID) | ||
795 | { | ||
796 | ScenePresence sp; | ||
797 | TryGetAvatar(agentID, out sp); | ||
798 | return sp; | ||
799 | } | 766 | } |
800 | 767 | ||
801 | /// <summary> | 768 | protected internal bool TryGetAvatarByName(string name, out ScenePresence avatar) |
802 | /// Request the ScenePresence in this region by localID. | ||
803 | /// </summary> | ||
804 | /// <param name="localID"></param> | ||
805 | /// <returns></returns> | ||
806 | protected internal ScenePresence GetScenePresence(uint localID) | ||
807 | { | 769 | { |
808 | return GetScenePresence(delegate(ScenePresence presence) | 770 | avatar = null; |
771 | foreach (ScenePresence presence in GetScenePresences()) | ||
809 | { | 772 | { |
810 | return (presence.LocalId == localID); | 773 | if (String.Compare(name, presence.ControllingClient.Name, true) == 0) |
811 | }); | 774 | { |
775 | avatar = presence; | ||
776 | break; | ||
777 | } | ||
778 | } | ||
779 | return (avatar != null); | ||
812 | } | 780 | } |
813 | 781 | ||
814 | /// <summary> | 782 | /// <summary> |
@@ -962,24 +930,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
962 | return group.GetChildPart(fullID); | 930 | return group.GetChildPart(fullID); |
963 | } | 931 | } |
964 | 932 | ||
965 | protected internal bool TryGetAvatar(UUID avatarId, out ScenePresence avatar) | ||
966 | { | ||
967 | lock (m_scenePresences) | ||
968 | { | ||
969 | m_scenePresences.TryGetValue(avatarId, out avatar); | ||
970 | } | ||
971 | return (avatar != null); | ||
972 | } | ||
973 | |||
974 | protected internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) | ||
975 | { | ||
976 | avatar = GetScenePresence(delegate(ScenePresence presence) | ||
977 | { | ||
978 | return (String.Compare(avatarName, presence.ControllingClient.Name, true) == 0); | ||
979 | }); | ||
980 | return (avatar != null); | ||
981 | } | ||
982 | |||
983 | /// <summary> | 933 | /// <summary> |
984 | /// Returns a list of the entities in the scene. This is a new list so no locking is required to iterate over | 934 | /// Returns a list of the entities in the scene. This is a new list so no locking is required to iterate over |
985 | /// it | 935 | /// it |
@@ -1042,6 +992,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
1042 | return UUID.Zero; | 992 | return UUID.Zero; |
1043 | } | 993 | } |
1044 | 994 | ||
995 | /// <summary> | ||
996 | /// Performs action on all scene object groups. | ||
997 | /// </summary> | ||
998 | /// <param name="action"></param> | ||
1045 | protected internal void ForEachSOG(Action<SceneObjectGroup> action) | 999 | protected internal void ForEachSOG(Action<SceneObjectGroup> action) |
1046 | { | 1000 | { |
1047 | List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); | 1001 | List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); |
@@ -1061,23 +1015,41 @@ namespace OpenSim.Region.Framework.Scenes | |||
1061 | 1015 | ||
1062 | 1016 | ||
1063 | /// <summary> | 1017 | /// <summary> |
1064 | /// Performs action on all scene presences. | 1018 | /// Performs action on all scene presences. This can ultimately run the actions in parallel but |
1019 | /// any delegates passed in will need to implement their own locking on data they reference and | ||
1020 | /// modify outside of the scope of the delegate. | ||
1065 | /// </summary> | 1021 | /// </summary> |
1066 | /// <param name="action"></param> | 1022 | /// <param name="action"></param> |
1067 | public void ForEachScenePresence(Action<ScenePresence> action) | 1023 | public void ForEachScenePresence(Action<ScenePresence> action) |
1068 | { | 1024 | { |
1069 | List<ScenePresence> presences = GetScenePresences(); | 1025 | // Once all callers have their delegates configured for parallelism, we can unleash this |
1070 | try | 1026 | /* |
1027 | Action<ScenePresence> protectedAction = new Action<ScenePresence>(delegate(ScenePresence sp) | ||
1028 | { | ||
1029 | try | ||
1030 | { | ||
1031 | action(sp); | ||
1032 | } | ||
1033 | catch (Exception e) | ||
1034 | { | ||
1035 | m_log.Info("[BUG] in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString()); | ||
1036 | m_log.Info("[BUG] Stack Trace: " + e.StackTrace); | ||
1037 | } | ||
1038 | }); | ||
1039 | Parallel.ForEach<ScenePresence>(GetScenePresences(), protectedAction); | ||
1040 | */ | ||
1041 | // For now, perform actiona serially | ||
1042 | foreach (ScenePresence sp in GetScenePresences()) | ||
1071 | { | 1043 | { |
1072 | foreach(ScenePresence presence in presences) | 1044 | try |
1073 | { | 1045 | { |
1074 | action(presence); | 1046 | action(sp); |
1047 | } | ||
1048 | catch (Exception e) | ||
1049 | { | ||
1050 | m_log.Info("[BUG] in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString()); | ||
1051 | m_log.Info("[BUG] Stack Trace: " + e.StackTrace); | ||
1075 | } | 1052 | } |
1076 | } | ||
1077 | catch (Exception e) | ||
1078 | { | ||
1079 | m_log.Info("[BUG] in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString()); | ||
1080 | m_log.Info("[BUG] Stack Trace: " + e.StackTrace); | ||
1081 | } | 1053 | } |
1082 | } | 1054 | } |
1083 | 1055 | ||
diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs index a955532..1168341 100644 --- a/OpenSim/Region/Framework/Scenes/SceneManager.cs +++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs | |||
@@ -454,8 +454,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
454 | 454 | ||
455 | ForEachCurrentScene(delegate(Scene scene) | 455 | ForEachCurrentScene(delegate(Scene scene) |
456 | { | 456 | { |
457 | List<ScenePresence> scenePresences = scene.GetScenePresences(); | 457 | scene.ForEachScenePresence(delegate(ScenePresence sp) |
458 | presences.AddRange(scenePresences); | 458 | { |
459 | presences.Add(sp); | ||
460 | }); | ||
459 | }); | 461 | }); |
460 | 462 | ||
461 | return presences; | 463 | return presences; |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 0e21487..88bdf31 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -1321,11 +1321,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1321 | if (volume < 0) | 1321 | if (volume < 0) |
1322 | volume = 0; | 1322 | volume = 0; |
1323 | 1323 | ||
1324 | List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); | 1324 | m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence sp) |
1325 | foreach (ScenePresence p in avatarts) | ||
1326 | { | 1325 | { |
1327 | p.ControllingClient.SendAttachedSoundGainChange(UUID, (float)volume); | 1326 | if(!sp.IsChildAgent) |
1328 | } | 1327 | sp.ControllingClient.SendAttachedSoundGainChange(UUID, (float)volume); |
1328 | }); | ||
1329 | } | 1329 | } |
1330 | 1330 | ||
1331 | /// <summary> | 1331 | /// <summary> |
@@ -2609,12 +2609,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2609 | } | 2609 | } |
2610 | } | 2610 | } |
2611 | 2611 | ||
2612 | List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); | 2612 | m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence sp) |
2613 | foreach (ScenePresence p in avatarts) | ||
2614 | { | 2613 | { |
2615 | if (!(Util.GetDistanceTo(p.AbsolutePosition, AbsolutePosition) >= 100)) | 2614 | if (sp.IsChildAgent) |
2616 | p.ControllingClient.SendPreLoadSound(objectID, objectID, soundID); | 2615 | return; |
2617 | } | 2616 | if (!(Util.GetDistanceTo(sp.AbsolutePosition, AbsolutePosition) >= 100)) |
2617 | sp.ControllingClient.SendPreLoadSound(objectID, objectID, soundID); | ||
2618 | }); | ||
2618 | } | 2619 | } |
2619 | 2620 | ||
2620 | public void RemFlag(PrimFlags flag) | 2621 | public void RemFlag(PrimFlags flag) |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 766f6d3..b5f6217 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -2396,35 +2396,33 @@ namespace OpenSim.Region.Framework.Scenes | |||
2396 | 2396 | ||
2397 | List<Vector3> CoarseLocations = new List<Vector3>(); | 2397 | List<Vector3> CoarseLocations = new List<Vector3>(); |
2398 | List<UUID> AvatarUUIDs = new List<UUID>(); | 2398 | List<UUID> AvatarUUIDs = new List<UUID>(); |
2399 | List<ScenePresence> avatars = m_scene.GetAvatars(); | 2399 | m_scene.ForEachScenePresence(delegate(ScenePresence sp) |
2400 | for (int i = 0; i < avatars.Count; i++) | ||
2401 | { | 2400 | { |
2402 | // Requested by LibOMV. Send Course Location on self. | 2401 | if (sp.IsChildAgent) |
2403 | //if (avatars[i] != this) | 2402 | return; |
2404 | //{ | 2403 | |
2405 | if (avatars[i].ParentID != 0) | 2404 | if (sp.ParentID != 0) |
2405 | { | ||
2406 | // sitting avatar | ||
2407 | SceneObjectPart sop = m_scene.GetSceneObjectPart(sp.ParentID); | ||
2408 | if (sop != null) | ||
2406 | { | 2409 | { |
2407 | // sitting avatar | 2410 | CoarseLocations.Add(sop.AbsolutePosition + sp.m_pos); |
2408 | SceneObjectPart sop = m_scene.GetSceneObjectPart(avatars[i].ParentID); | 2411 | AvatarUUIDs.Add(sp.UUID); |
2409 | if (sop != null) | ||
2410 | { | ||
2411 | CoarseLocations.Add(sop.AbsolutePosition + avatars[i].m_pos); | ||
2412 | AvatarUUIDs.Add(avatars[i].UUID); | ||
2413 | } | ||
2414 | else | ||
2415 | { | ||
2416 | // we can't find the parent.. ! arg! | ||
2417 | CoarseLocations.Add(avatars[i].m_pos); | ||
2418 | AvatarUUIDs.Add(avatars[i].UUID); | ||
2419 | } | ||
2420 | } | 2412 | } |
2421 | else | 2413 | else |
2422 | { | 2414 | { |
2423 | CoarseLocations.Add(avatars[i].m_pos); | 2415 | // we can't find the parent.. ! arg! |
2424 | AvatarUUIDs.Add(avatars[i].UUID); | 2416 | CoarseLocations.Add(sp.m_pos); |
2417 | AvatarUUIDs.Add(sp.UUID); | ||
2425 | } | 2418 | } |
2426 | //} | 2419 | } |
2427 | } | 2420 | else |
2421 | { | ||
2422 | CoarseLocations.Add(sp.m_pos); | ||
2423 | AvatarUUIDs.Add(sp.UUID); | ||
2424 | } | ||
2425 | }); | ||
2428 | 2426 | ||
2429 | m_controllingClient.SendCoarseLocationUpdate(AvatarUUIDs, CoarseLocations); | 2427 | m_controllingClient.SendCoarseLocationUpdate(AvatarUUIDs, CoarseLocations); |
2430 | 2428 | ||
@@ -2498,13 +2496,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
2498 | m_perfMonMS = Util.EnvironmentTickCount(); | 2496 | m_perfMonMS = Util.EnvironmentTickCount(); |
2499 | 2497 | ||
2500 | // only send update from root agents to other clients; children are only "listening posts" | 2498 | // only send update from root agents to other clients; children are only "listening posts" |
2501 | List<ScenePresence> avatars = m_scene.GetAvatars(); | 2499 | int count = 0; |
2502 | foreach (ScenePresence avatar in avatars) | 2500 | m_scene.ForEachScenePresence(delegate(ScenePresence sp) |
2503 | { | 2501 | { |
2504 | SendFullUpdateToOtherClient(avatar); | 2502 | if (sp.IsChildAgent) |
2505 | 2503 | return; | |
2506 | } | 2504 | SendFullUpdateToOtherClient(sp); |
2507 | m_scene.StatsReporter.AddAgentUpdates(avatars.Count); | 2505 | ++count; |
2506 | }); | ||
2507 | m_scene.StatsReporter.AddAgentUpdates(count); | ||
2508 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); | 2508 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); |
2509 | 2509 | ||
2510 | Animator.SendAnimPack(); | 2510 | Animator.SendAnimPack(); |
diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index c864993..b85bac6 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs | |||
@@ -318,9 +318,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge | |||
318 | { | 318 | { |
319 | Scene scene = client.Scene as Scene; | 319 | Scene scene = client.Scene as Scene; |
320 | m_log.DebugFormat("[Concierge]: {0} logs off from {1}", client.Name, scene.RegionInfo.RegionName); | 320 | m_log.DebugFormat("[Concierge]: {0} logs off from {1}", client.Name, scene.RegionInfo.RegionName); |
321 | List<ScenePresence> avs = scene.GetAvatars(); | 321 | AnnounceToAgentsRegion(scene, String.Format(m_announceLeaving, client.Name, scene.RegionInfo.RegionName, scene.GetRootAgentCount())); |
322 | AnnounceToAgentsRegion(scene, String.Format(m_announceLeaving, client.Name, scene.RegionInfo.RegionName, avs.Count)); | 322 | UpdateBroker(scene); |
323 | UpdateBroker(scene, avs); | ||
324 | } | 323 | } |
325 | } | 324 | } |
326 | 325 | ||
@@ -331,11 +330,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge | |||
331 | { | 330 | { |
332 | Scene scene = agent.Scene; | 331 | Scene scene = agent.Scene; |
333 | m_log.DebugFormat("[Concierge]: {0} enters {1}", agent.Name, scene.RegionInfo.RegionName); | 332 | m_log.DebugFormat("[Concierge]: {0} enters {1}", agent.Name, scene.RegionInfo.RegionName); |
334 | List<ScenePresence> avs = scene.GetAvatars(); | ||
335 | WelcomeAvatar(agent, scene); | 333 | WelcomeAvatar(agent, scene); |
336 | AnnounceToAgentsRegion(scene, String.Format(m_announceEntering, agent.Name, | 334 | AnnounceToAgentsRegion(scene, String.Format(m_announceEntering, agent.Name, |
337 | scene.RegionInfo.RegionName, avs.Count)); | 335 | scene.RegionInfo.RegionName, scene.GetRootAgentCount())); |
338 | UpdateBroker(scene, avs); | 336 | UpdateBroker(scene); |
339 | } | 337 | } |
340 | } | 338 | } |
341 | 339 | ||
@@ -346,10 +344,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge | |||
346 | { | 344 | { |
347 | Scene scene = agent.Scene; | 345 | Scene scene = agent.Scene; |
348 | m_log.DebugFormat("[Concierge]: {0} leaves {1}", agent.Name, scene.RegionInfo.RegionName); | 346 | m_log.DebugFormat("[Concierge]: {0} leaves {1}", agent.Name, scene.RegionInfo.RegionName); |
349 | List<ScenePresence> avs = scene.GetAvatars(); | ||
350 | AnnounceToAgentsRegion(scene, String.Format(m_announceLeaving, agent.Name, | 347 | AnnounceToAgentsRegion(scene, String.Format(m_announceLeaving, agent.Name, |
351 | scene.RegionInfo.RegionName, avs.Count)); | 348 | scene.RegionInfo.RegionName, scene.GetRootAgentCount())); |
352 | UpdateBroker(scene, avs); | 349 | UpdateBroker(scene); |
353 | } | 350 | } |
354 | } | 351 | } |
355 | 352 | ||
@@ -368,7 +365,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge | |||
368 | } | 365 | } |
369 | } | 366 | } |
370 | 367 | ||
371 | protected void UpdateBroker(IScene scene, List<ScenePresence> avatars) | 368 | protected void UpdateBroker(Scene scene) |
372 | { | 369 | { |
373 | if (String.IsNullOrEmpty(m_brokerURI)) | 370 | if (String.IsNullOrEmpty(m_brokerURI)) |
374 | return; | 371 | return; |
@@ -377,24 +374,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge | |||
377 | 374 | ||
378 | // create XML sniplet | 375 | // create XML sniplet |
379 | StringBuilder list = new StringBuilder(); | 376 | StringBuilder list = new StringBuilder(); |
380 | if (0 == avatars.Count) | 377 | list.Append(String.Format("<avatars count=\"{0}\" region_name=\"{1}\" region_uuid=\"{2}\" timestamp=\"{3}\">\n", |
381 | { | 378 | scene.GetRootAgentCount(), scene.RegionInfo.RegionName, |
382 | list.Append(String.Format("<avatars count=\"0\" region_name=\"{0}\" region_uuid=\"{1}\" timestamp=\"{2}\" />", | 379 | scene.RegionInfo.RegionID, |
383 | scene.RegionInfo.RegionName, scene.RegionInfo.RegionID, | ||
384 | DateTime.UtcNow.ToString("s"))); | 380 | DateTime.UtcNow.ToString("s"))); |
385 | } | 381 | scene.ForEachScenePresence(delegate(ScenePresence sp) |
386 | else | ||
387 | { | 382 | { |
388 | list.Append(String.Format("<avatars count=\"{0}\" region_name=\"{1}\" region_uuid=\"{2}\" timestamp=\"{3}\">\n", | 383 | if (!sp.IsChildAgent) |
389 | avatars.Count, scene.RegionInfo.RegionName, | ||
390 | scene.RegionInfo.RegionID, | ||
391 | DateTime.UtcNow.ToString("s"))); | ||
392 | foreach (ScenePresence av in avatars) | ||
393 | { | 384 | { |
394 | list.Append(String.Format(" <avatar name=\"{0}\" uuid=\"{1}\" />\n", av.Name, av.UUID)); | 385 | list.Append(String.Format(" <avatar name=\"{0}\" uuid=\"{1}\" />\n", sp.Name, sp.UUID)); |
386 | list.Append("</avatars>"); | ||
395 | } | 387 | } |
396 | list.Append("</avatars>"); | 388 | }); |
397 | } | ||
398 | string payload = list.ToString(); | 389 | string payload = list.ToString(); |
399 | 390 | ||
400 | // post via REST to broker | 391 | // post via REST to broker |
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index 1a99c83..7a43537 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs | |||
@@ -707,36 +707,37 @@ namespace OpenSim.Region.RegionCombinerModule | |||
707 | return; | 707 | return; |
708 | } | 708 | } |
709 | 709 | ||
710 | List<ScenePresence> avatars = connectiondata.RegionScene.GetAvatars(); | ||
711 | List<Vector3> CoarseLocations = new List<Vector3>(); | 710 | List<Vector3> CoarseLocations = new List<Vector3>(); |
712 | List<UUID> AvatarUUIDs = new List<UUID>(); | 711 | List<UUID> AvatarUUIDs = new List<UUID>(); |
713 | for (int i = 0; i < avatars.Count; i++) | 712 | connectiondata.RegionScene.ForEachScenePresence(delegate(ScenePresence sp) |
714 | { | 713 | { |
715 | if (avatars[i].UUID != presence.UUID) | 714 | if (sp.IsChildAgent) |
715 | return; | ||
716 | if (sp.UUID != presence.UUID) | ||
716 | { | 717 | { |
717 | if (avatars[i].ParentID != 0) | 718 | if (sp.ParentID != 0) |
718 | { | 719 | { |
719 | // sitting avatar | 720 | // sitting avatar |
720 | SceneObjectPart sop = connectiondata.RegionScene.GetSceneObjectPart(avatars[i].ParentID); | 721 | SceneObjectPart sop = connectiondata.RegionScene.GetSceneObjectPart(sp.ParentID); |
721 | if (sop != null) | 722 | if (sop != null) |
722 | { | 723 | { |
723 | CoarseLocations.Add(sop.AbsolutePosition + avatars[i].AbsolutePosition); | 724 | CoarseLocations.Add(sop.AbsolutePosition + sp.AbsolutePosition); |
724 | AvatarUUIDs.Add(avatars[i].UUID); | 725 | AvatarUUIDs.Add(sp.UUID); |
725 | } | 726 | } |
726 | else | 727 | else |
727 | { | 728 | { |
728 | // we can't find the parent.. ! arg! | 729 | // we can't find the parent.. ! arg! |
729 | CoarseLocations.Add(avatars[i].AbsolutePosition); | 730 | CoarseLocations.Add(sp.AbsolutePosition); |
730 | AvatarUUIDs.Add(avatars[i].UUID); | 731 | AvatarUUIDs.Add(sp.UUID); |
731 | } | 732 | } |
732 | } | 733 | } |
733 | else | 734 | else |
734 | { | 735 | { |
735 | CoarseLocations.Add(avatars[i].AbsolutePosition); | 736 | CoarseLocations.Add(sp.AbsolutePosition); |
736 | AvatarUUIDs.Add(avatars[i].UUID); | 737 | AvatarUUIDs.Add(sp.UUID); |
737 | } | 738 | } |
738 | } | 739 | } |
739 | } | 740 | }); |
740 | DistributeCourseLocationUpdates(CoarseLocations, AvatarUUIDs, connectiondata, presence); | 741 | DistributeCourseLocationUpdates(CoarseLocations, AvatarUUIDs, connectiondata, presence); |
741 | } | 742 | } |
742 | 743 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index b040ca77..3ccbb3a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -5092,7 +5092,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5092 | public LSL_Integer llGetRegionAgentCount() | 5092 | public LSL_Integer llGetRegionAgentCount() |
5093 | { | 5093 | { |
5094 | m_host.AddScriptLPS(1); | 5094 | m_host.AddScriptLPS(1); |
5095 | return new LSL_Integer(World.GetAvatars().Count); | 5095 | return new LSL_Integer(World.GetRootAgentCount()); |
5096 | } | 5096 | } |
5097 | 5097 | ||
5098 | public LSL_Vector llGetRegionCorner() | 5098 | public LSL_Vector llGetRegionCorner() |
@@ -8771,17 +8771,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8771 | landObject.SetMediaUrl(url); | 8771 | landObject.SetMediaUrl(url); |
8772 | 8772 | ||
8773 | // now send to all (non-child) agents | 8773 | // now send to all (non-child) agents |
8774 | List<ScenePresence> agents = World.GetAvatars(); | 8774 | World.ForEachScenePresence(delegate(ScenePresence sp) |
8775 | foreach (ScenePresence agent in agents) | ||
8776 | { | 8775 | { |
8777 | agent.ControllingClient.SendParcelMediaUpdate(landData.MediaURL, | 8776 | if (!sp.IsChildAgent) |
8778 | landData.MediaID, | 8777 | { |
8779 | landData.MediaAutoScale, | 8778 | sp.ControllingClient.SendParcelMediaUpdate(landData.MediaURL, |
8780 | mediaType, | 8779 | landData.MediaID, |
8781 | description, | 8780 | landData.MediaAutoScale, |
8782 | width, height, | 8781 | mediaType, |
8783 | loop); | 8782 | description, |
8784 | } | 8783 | width, height, |
8784 | loop); | ||
8785 | } | ||
8786 | }); | ||
8785 | } | 8787 | } |
8786 | else if (!presence.IsChildAgent) | 8788 | else if (!presence.IsChildAgent) |
8787 | { | 8789 | { |
@@ -8802,13 +8804,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8802 | if (presence == null) | 8804 | if (presence == null) |
8803 | { | 8805 | { |
8804 | // send to all (non-child) agents | 8806 | // send to all (non-child) agents |
8805 | List<ScenePresence> agents = World.GetAvatars(); | 8807 | World.ForEachScenePresence(delegate(ScenePresence sp) |
8806 | foreach (ScenePresence agent in agents) | ||
8807 | { | 8808 | { |
8808 | agent.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? | 8809 | if (!sp.IsChildAgent) |
8809 | (ParcelMediaCommandEnum)commandToSend, | 8810 | { |
8810 | time); | 8811 | sp.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? |
8811 | } | 8812 | (ParcelMediaCommandEnum)commandToSend, |
8813 | time); | ||
8814 | } | ||
8815 | }); | ||
8812 | } | 8816 | } |
8813 | else if (!presence.IsChildAgent) | 8817 | else if (!presence.IsChildAgent) |
8814 | { | 8818 | { |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 85ee29d..7e68cc7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | |||
@@ -697,10 +697,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
697 | CheckThreatLevel(ThreatLevel.None, "osGetAgents"); | 697 | CheckThreatLevel(ThreatLevel.None, "osGetAgents"); |
698 | 698 | ||
699 | LSL_List result = new LSL_List(); | 699 | LSL_List result = new LSL_List(); |
700 | foreach (ScenePresence avatar in World.GetAvatars()) | 700 | World.ForEachScenePresence(delegate(ScenePresence sp) |
701 | { | 701 | { |
702 | result.Add(avatar.Name); | 702 | if (!sp.IsChildAgent) |
703 | } | 703 | result.Add(sp.Name); |
704 | }); | ||
704 | return result; | 705 | return result; |
705 | } | 706 | } |
706 | 707 | ||
@@ -1985,19 +1986,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1985 | CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); | 1986 | CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); |
1986 | if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID)) | 1987 | if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID)) |
1987 | { | 1988 | { |
1988 | foreach (ScenePresence presence in World.GetAvatars()) | 1989 | World.ForEachScenePresence(delegate(ScenePresence sp) |
1989 | { | 1990 | { |
1990 | if ((presence.Firstname == FirstName) && | 1991 | if (!sp.IsChildAgent && |
1991 | presence.Lastname == SurName) | 1992 | sp.Firstname == FirstName && |
1993 | sp.Lastname == SurName) | ||
1992 | { | 1994 | { |
1993 | // kick client... | 1995 | // kick client... |
1994 | if (alert != null) | 1996 | if (alert != null) |
1995 | presence.ControllingClient.Kick(alert); | 1997 | sp.ControllingClient.Kick(alert); |
1996 | 1998 | ||
1997 | // ...and close on our side | 1999 | // ...and close on our side |
1998 | presence.Scene.IncomingCloseAgent(presence.UUID); | 2000 | sp.Scene.IncomingCloseAgent(sp.UUID); |
1999 | } | 2001 | } |
2000 | } | 2002 | }); |
2001 | } | 2003 | } |
2002 | } | 2004 | } |
2003 | 2005 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs index 829fbb7..6cbf260 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs | |||
@@ -404,70 +404,40 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
404 | 404 | ||
405 | private List<SensedEntity> doAgentSensor(SenseRepeatClass ts) | 405 | private List<SensedEntity> doAgentSensor(SenseRepeatClass ts) |
406 | { | 406 | { |
407 | List<ScenePresence> presences; | ||
408 | List<SensedEntity> sensedEntities = new List<SensedEntity>(); | 407 | List<SensedEntity> sensedEntities = new List<SensedEntity>(); |
409 | 408 | ||
410 | // If this is an avatar sense by key try to get them directly | ||
411 | // rather than getting a list to scan through | ||
412 | if (ts.keyID != UUID.Zero) | ||
413 | { | ||
414 | ScenePresence p = m_CmdManager.m_ScriptEngine.World.GetScenePresence(ts.keyID); | ||
415 | if (p == null) | ||
416 | return sensedEntities; | ||
417 | presences = new List<ScenePresence>(); | ||
418 | presences.Add(p); | ||
419 | } | ||
420 | else | ||
421 | { | ||
422 | presences = new List<ScenePresence>(m_CmdManager.m_ScriptEngine.World.GetScenePresences()); | ||
423 | } | ||
424 | |||
425 | // If nobody about quit fast | 409 | // If nobody about quit fast |
426 | if (presences.Count == 0) | 410 | if(m_CmdManager.m_ScriptEngine.World.GetRootAgentCount() == 0) |
427 | return sensedEntities; | 411 | return sensedEntities; |
428 | 412 | ||
429 | SceneObjectPart SensePoint = ts.host; | 413 | SceneObjectPart SensePoint = ts.host; |
430 | |||
431 | Vector3 fromRegionPos = SensePoint.AbsolutePosition; | 414 | Vector3 fromRegionPos = SensePoint.AbsolutePosition; |
432 | |||
433 | Quaternion q = SensePoint.RotationOffset; | 415 | Quaternion q = SensePoint.RotationOffset; |
434 | LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); | 416 | LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); |
435 | LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); | 417 | LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); |
436 | double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); | 418 | double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); |
437 | |||
438 | bool attached = (SensePoint.AttachmentPoint != 0); | 419 | bool attached = (SensePoint.AttachmentPoint != 0); |
439 | bool nameSearch = (ts.name != null && ts.name != ""); | ||
440 | Vector3 toRegionPos; | 420 | Vector3 toRegionPos; |
441 | double dis; | 421 | double dis; |
442 | 422 | ||
443 | for (int i = 0; i < presences.Count; i++) | 423 | Action<ScenePresence> senseEntity = new Action<ScenePresence>(delegate(ScenePresence presence) |
444 | { | 424 | { |
445 | ScenePresence presence = presences[i]; | 425 | if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0) |
446 | bool keep = true; | 426 | return; |
427 | |||
428 | // if the object the script is in is attached and the avatar is the owner | ||
429 | // then this one is not wanted | ||
430 | if (attached && presence.UUID == SensePoint.OwnerID) | ||
431 | return; | ||
447 | 432 | ||
448 | if (presence.IsDeleted) | ||
449 | continue; | ||
450 | |||
451 | if (presence.IsChildAgent) | ||
452 | keep = false; | ||
453 | toRegionPos = presence.AbsolutePosition; | 433 | toRegionPos = presence.AbsolutePosition; |
454 | |||
455 | dis = Math.Abs(Util.GetDistanceTo(toRegionPos, fromRegionPos)); | 434 | dis = Math.Abs(Util.GetDistanceTo(toRegionPos, fromRegionPos)); |
456 | 435 | ||
457 | // are they in range | 436 | // are they in range |
458 | if (keep && dis <= ts.range) | 437 | if (dis <= ts.range) |
459 | { | 438 | { |
460 | // if the object the script is in is attached and the avatar is the owner | ||
461 | // then this one is not wanted | ||
462 | if (attached && presence.UUID == SensePoint.OwnerID) | ||
463 | keep = false; | ||
464 | |||
465 | // check the name if needed | ||
466 | if (keep && nameSearch && ts.name != presence.Name) | ||
467 | keep = false; | ||
468 | |||
469 | // Are they in the required angle of view | 439 | // Are they in the required angle of view |
470 | if (keep && ts.arc < Math.PI) | 440 | if (ts.arc < Math.PI) |
471 | { | 441 | { |
472 | // not omni-directional. Can you see it ? | 442 | // not omni-directional. Can you see it ? |
473 | // vec forward_dir = llRot2Fwd(llGetRot()) | 443 | // vec forward_dir = llRot2Fwd(llGetRot()) |
@@ -488,26 +458,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
488 | catch | 458 | catch |
489 | { | 459 | { |
490 | } | 460 | } |
491 | if (ang_obj > ts.arc) keep = false; | 461 | if (ang_obj <= ts.arc) |
462 | { | ||
463 | sensedEntities.Add(new SensedEntity(dis, presence.UUID)); | ||
464 | } | ||
492 | } | 465 | } |
493 | } | 466 | } |
494 | else | 467 | }); |
495 | { | ||
496 | keep = false; | ||
497 | } | ||
498 | 468 | ||
499 | // Do not report gods, not even minor ones | 469 | // If this is an avatar sense by key try to get them directly |
500 | if (keep && presence.GodLevel > 0.0) | 470 | // rather than getting a list to scan through |
501 | keep = false; | 471 | if (ts.keyID != UUID.Zero) |
502 | 472 | { | |
503 | if (keep) // add to list with distance | 473 | ScenePresence sp; |
504 | { | 474 | // Try direct lookup by UUID |
505 | sensedEntities.Add(new SensedEntity(dis, presence.UUID)); | 475 | if(!m_CmdManager.m_ScriptEngine.World.TryGetAvatar(ts.keyID, out sp)) |
506 | } | ||
507 | |||
508 | // If this is a search by name and we have just found it then no more to do | ||
509 | if (nameSearch && ts.name == presence.Name) | ||
510 | return sensedEntities; | 476 | return sensedEntities; |
477 | senseEntity(sp); | ||
478 | } | ||
479 | else if (ts.name != null && ts.name != "") | ||
480 | { | ||
481 | ScenePresence sp; | ||
482 | // Try lookup by name will return if/when found | ||
483 | if (!m_CmdManager.m_ScriptEngine.World.TryGetAvatarByName(ts.name, out sp)) | ||
484 | return sensedEntities; | ||
485 | senseEntity(sp); | ||
486 | } | ||
487 | else | ||
488 | { | ||
489 | m_CmdManager.m_ScriptEngine.World.ForEachScenePresence(senseEntity); | ||
511 | } | 490 | } |
512 | return sensedEntities; | 491 | return sensedEntities; |
513 | } | 492 | } |
diff --git a/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs b/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs index a567413..dcbd717 100644 --- a/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs +++ b/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs | |||
@@ -68,17 +68,15 @@ namespace OpenSim.Region.UserStatistics | |||
68 | HTMLUtil.OL_O(ref output, ""); | 68 | HTMLUtil.OL_O(ref output, ""); |
69 | foreach (Scene scene in all_scenes) | 69 | foreach (Scene scene in all_scenes) |
70 | { | 70 | { |
71 | List<ScenePresence> avatarInScene = scene.GetScenePresences(); | ||
72 | |||
73 | HTMLUtil.LI_O(ref output, String.Empty); | 71 | HTMLUtil.LI_O(ref output, String.Empty); |
74 | output.Append(scene.RegionInfo.RegionName); | 72 | output.Append(scene.RegionInfo.RegionName); |
75 | HTMLUtil.OL_O(ref output, String.Empty); | 73 | HTMLUtil.OL_O(ref output, String.Empty); |
76 | foreach (ScenePresence av in avatarInScene) | 74 | scene.ForEachScenePresence(delegate(ScenePresence av) |
77 | { | 75 | { |
78 | Dictionary<string,string> queues = new Dictionary<string, string>(); | 76 | Dictionary<string, string> queues = new Dictionary<string, string>(); |
79 | if (av.ControllingClient is IStatsCollector) | 77 | if (av.ControllingClient is IStatsCollector) |
80 | { | 78 | { |
81 | IStatsCollector isClient = (IStatsCollector) av.ControllingClient; | 79 | IStatsCollector isClient = (IStatsCollector)av.ControllingClient; |
82 | queues = decodeQueueReport(isClient.Report()); | 80 | queues = decodeQueueReport(isClient.Report()); |
83 | } | 81 | } |
84 | HTMLUtil.LI_O(ref output, String.Empty); | 82 | HTMLUtil.LI_O(ref output, String.Empty); |
@@ -92,8 +90,8 @@ namespace OpenSim.Region.UserStatistics | |||
92 | else | 90 | else |
93 | { | 91 | { |
94 | output.Append(string.Format("<br /><NOBR>Position: <{0},{1},{2}></NOBR>", (int)av.AbsolutePosition.X, | 92 | output.Append(string.Format("<br /><NOBR>Position: <{0},{1},{2}></NOBR>", (int)av.AbsolutePosition.X, |
95 | (int) av.AbsolutePosition.Y, | 93 | (int)av.AbsolutePosition.Y, |
96 | (int) av.AbsolutePosition.Z)); | 94 | (int)av.AbsolutePosition.Z)); |
97 | } | 95 | } |
98 | Dictionary<string, int> throttles = DecodeClientThrottles(av.ControllingClient.GetThrottlesPacked(1)); | 96 | Dictionary<string, int> throttles = DecodeClientThrottles(av.ControllingClient.GetThrottlesPacked(1)); |
99 | 97 | ||
@@ -124,7 +122,7 @@ namespace OpenSim.Region.UserStatistics | |||
124 | 122 | ||
125 | HTMLUtil.UL_C(ref output); | 123 | HTMLUtil.UL_C(ref output); |
126 | HTMLUtil.LI_C(ref output); | 124 | HTMLUtil.LI_C(ref output); |
127 | } | 125 | }); |
128 | HTMLUtil.OL_C(ref output); | 126 | HTMLUtil.OL_C(ref output); |
129 | } | 127 | } |
130 | HTMLUtil.OL_C(ref output); | 128 | HTMLUtil.OL_C(ref output); |