aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDan Lake2010-03-19 05:51:16 -0700
committerJohn Hurliman2010-03-19 15:16:35 -0700
commit859bc717a4fe4cd5810ad9889cfb9b1e7f5c2046 (patch)
treedcce6c74d201b52c1a04ec9ec2cb90ce068fc020
parentInconsistent locking of ScenePresence array in SceneGraph. Fixed by eliminati... (diff)
downloadopensim-SC-859bc717a4fe4cd5810ad9889cfb9b1e7f5c2046.zip
opensim-SC-859bc717a4fe4cd5810ad9889cfb9b1e7f5c2046.tar.gz
opensim-SC-859bc717a4fe4cd5810ad9889cfb9b1e7f5c2046.tar.bz2
opensim-SC-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>).
Diffstat (limited to '')
-rw-r--r--OpenSim/ApplicationPlugins/Rest/Inventory/tests/Remote.cs36
-rw-r--r--OpenSim/ApplicationPlugins/Rest/Regions/GETHandler.cs2
-rw-r--r--OpenSim/ApplicationPlugins/Rest/Regions/GETRegionInfoHandler.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs31
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs39
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs26
-rw-r--r--OpenSim/Region/CoreModules/World/Sound/SoundModule.cs34
-rw-r--r--OpenSim/Region/CoreModules/World/Sun/SunModule.cs9
-rw-r--r--OpenSim/Region/CoreModules/World/Wind/WindModule.cs12
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs87
-rw-r--r--OpenSim/Region/Examples/SimpleModule/RegionModule.cs10
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs81
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs186
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneManager.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs19
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs58
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs39
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs25
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs38
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs93
-rw-r--r--OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs14
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);