diff options
author | Melanie Thielker | 2008-08-11 23:20:14 +0000 |
---|---|---|
committer | Melanie Thielker | 2008-08-11 23:20:14 +0000 |
commit | f9945bf87f93d9e676801af77c4a7fdaf3999ef4 (patch) | |
tree | df0fdd2c2dc79cab484478b8aee0704febbb49a5 | |
parent | * minor: replace hard tabs with soft 4 space tabs in previous patch (diff) | |
download | opensim-SC-f9945bf87f93d9e676801af77c4a7fdaf3999ef4.zip opensim-SC-f9945bf87f93d9e676801af77c4a7fdaf3999ef4.tar.gz opensim-SC-f9945bf87f93d9e676801af77c4a7fdaf3999ef4.tar.bz2 opensim-SC-f9945bf87f93d9e676801af77c4a7fdaf3999ef4.tar.xz |
Patch #9163 - Refactor initial packet sending out of InnerScene into
ScenePresence. Pace prim delivery to about 200 updates/s max. Break
a long-held lock that caused the notorious MapBlockQuery XMLRPC timeout
on agent login. Eliminate 60 second timeout at "Waiting for region handshake".
Fix region crossing/teleport response. Fix appearance in primmy regions.
-rw-r--r-- | OpenSim/Region/Environment/Scenes/InnerScene.cs | 37 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Scenes/Scene.cs | 9 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Scenes/ScenePresence.cs | 155 |
3 files changed, 73 insertions, 128 deletions
diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs index 8b395a2..c4e4919 100644 --- a/OpenSim/Region/Environment/Scenes/InnerScene.cs +++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs | |||
@@ -954,43 +954,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
954 | return LLUUID.Zero; | 954 | return LLUUID.Zero; |
955 | } | 955 | } |
956 | 956 | ||
957 | protected internal void SendAllSceneObjectsToClient(ScenePresence presence) | ||
958 | { | ||
959 | List<EntityBase> EntityList = GetEntities(); | ||
960 | |||
961 | foreach (EntityBase ent in EntityList) | ||
962 | { | ||
963 | if (ent is SceneObjectGroup) | ||
964 | { | ||
965 | // Only send child agents stuff in their draw distance. | ||
966 | // This will need to be done for every agent once we figure out | ||
967 | // what we're going to use to store prim that agents already got | ||
968 | // the initial update for and what we'll use to limit the | ||
969 | // space we check for new objects on movement. | ||
970 | |||
971 | if (presence.IsChildAgent && m_parentScene.m_seeIntoRegionFromNeighbor) | ||
972 | { | ||
973 | LLVector3 oLoc = ((SceneObjectGroup)ent).AbsolutePosition; | ||
974 | float distResult = (float)Util.GetDistanceTo(presence.AbsolutePosition, oLoc); | ||
975 | |||
976 | //m_log.Info("[DISTANCE]: " + distResult.ToString()); | ||
977 | |||
978 | if (distResult < presence.DrawDistance) | ||
979 | { | ||
980 | // Send Only if we don't already know about it. | ||
981 | // KnownPrim also makes the prim known when called. | ||
982 | if (!presence.KnownPrim(((SceneObjectGroup)ent).UUID)) | ||
983 | ((SceneObjectGroup)ent).ScheduleFullUpdateToAvatar(presence); | ||
984 | } | ||
985 | } | ||
986 | else | ||
987 | { | ||
988 | ((SceneObjectGroup)ent).ScheduleFullUpdateToAvatar(presence); | ||
989 | } | ||
990 | } | ||
991 | } | ||
992 | } | ||
993 | |||
994 | protected internal void ForEachClient(Action<IClientAPI> action) | 957 | protected internal void ForEachClient(Action<IClientAPI> action) |
995 | { | 958 | { |
996 | lock (ScenePresences) | 959 | lock (ScenePresences) |
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 33b2f6f..f39a0e6 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs | |||
@@ -3498,15 +3498,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
3498 | m_innerScene.RemovePhysicalPrim(num); | 3498 | m_innerScene.RemovePhysicalPrim(num); |
3499 | } | 3499 | } |
3500 | 3500 | ||
3501 | /// <summary> | ||
3502 | /// | ||
3503 | /// </summary> | ||
3504 | /// <param name="presence"></param> | ||
3505 | public void SendAllSceneObjectsToClient(ScenePresence presence) | ||
3506 | { | ||
3507 | m_innerScene.SendAllSceneObjectsToClient(presence); | ||
3508 | } | ||
3509 | |||
3510 | //The idea is to have a group of method that return a list of avatars meeting some requirement | 3501 | //The idea is to have a group of method that return a list of avatars meeting some requirement |
3511 | // ie it could be all m_scenePresences within a certain range of the calling prim/avatar. | 3502 | // ie it could be all m_scenePresences within a certain range of the calling prim/avatar. |
3512 | 3503 | ||
diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index e37b26b..1fcda03 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs | |||
@@ -128,7 +128,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
128 | // Agent moves with a PID controller causing a force to be exerted. | 128 | // Agent moves with a PID controller causing a force to be exerted. |
129 | private bool m_newForce = false; | 129 | private bool m_newForce = false; |
130 | private bool m_newCoarseLocations = true; | 130 | private bool m_newCoarseLocations = true; |
131 | private bool m_gotAllObjectsInScene = false; | ||
132 | private float m_health = 100f; | 131 | private float m_health = 100f; |
133 | 132 | ||
134 | private LLVector3 m_lastVelocity = LLVector3.Zero; | 133 | private LLVector3 m_lastVelocity = LLVector3.Zero; |
@@ -161,8 +160,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
161 | private LLVector3 m_autoPilotTarget = LLVector3.Zero; | 160 | private LLVector3 m_autoPilotTarget = LLVector3.Zero; |
162 | private bool m_sitAtAutoTarget = false; | 161 | private bool m_sitAtAutoTarget = false; |
163 | 162 | ||
164 | private List<LLUUID> m_knownPrimUUID = new List<LLUUID>(); | ||
165 | |||
166 | // Agent's Draw distance. | 163 | // Agent's Draw distance. |
167 | protected float m_DrawDistance = 0f; | 164 | protected float m_DrawDistance = 0f; |
168 | 165 | ||
@@ -193,6 +190,8 @@ namespace OpenSim.Region.Environment.Scenes | |||
193 | private LLVector3 posLastSignificantMove = new LLVector3(); | 190 | private LLVector3 posLastSignificantMove = new LLVector3(); |
194 | 191 | ||
195 | private UpdateQueue m_partsUpdateQueue = new UpdateQueue(); | 192 | private UpdateQueue m_partsUpdateQueue = new UpdateQueue(); |
193 | private Queue<SceneObjectGroup> m_pendingObjects = null; | ||
194 | |||
196 | private Dictionary<LLUUID, ScenePartUpdate> m_updateTimes = new Dictionary<LLUUID, ScenePartUpdate>(); | 195 | private Dictionary<LLUUID, ScenePartUpdate> m_updateTimes = new Dictionary<LLUUID, ScenePartUpdate>(); |
197 | 196 | ||
198 | #region Properties | 197 | #region Properties |
@@ -212,16 +211,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
212 | get { return m_movementflag; } | 211 | get { return m_movementflag; } |
213 | } | 212 | } |
214 | 213 | ||
215 | public bool KnownPrim(LLUUID primID) | ||
216 | { | ||
217 | if (m_knownPrimUUID.Contains(primID)) | ||
218 | { | ||
219 | return true; | ||
220 | } | ||
221 | m_knownPrimUUID.Add(primID); | ||
222 | return false; | ||
223 | } | ||
224 | |||
225 | public bool Updated | 214 | public bool Updated |
226 | { | 215 | { |
227 | set { m_updateflag = value; } | 216 | set { m_updateflag = value; } |
@@ -508,72 +497,93 @@ namespace OpenSim.Region.Environment.Scenes | |||
508 | //} | 497 | //} |
509 | m_perfMonMS = System.Environment.TickCount; | 498 | m_perfMonMS = System.Environment.TickCount; |
510 | 499 | ||
511 | if (!m_gotAllObjectsInScene) | 500 | if (m_pendingObjects == null) |
512 | { | 501 | { |
513 | if (!m_isChildAgent || m_scene.m_seeIntoRegionFromNeighbor) | 502 | if (!m_isChildAgent || m_scene.m_seeIntoRegionFromNeighbor) |
514 | { | 503 | { |
515 | m_scene.SendAllSceneObjectsToClient(this); | 504 | m_pendingObjects = new Queue<SceneObjectGroup>(); |
516 | m_gotAllObjectsInScene = true; | 505 | |
506 | foreach (EntityBase e in m_scene.Entities.Values) | ||
507 | if(e is SceneObjectGroup) | ||
508 | m_pendingObjects.Enqueue((SceneObjectGroup)e); | ||
517 | } | 509 | } |
518 | } | 510 | } |
519 | 511 | ||
520 | if (m_partsUpdateQueue.Count > 0) | 512 | while(m_pendingObjects.Count > 0 && m_partsUpdateQueue.Count < 60) |
513 | { | ||
514 | SceneObjectGroup g = m_pendingObjects.Dequeue(); | ||
515 | |||
516 | // This is where we should check for draw distance | ||
517 | // do culling and stuff. Problem with that is that until | ||
518 | // we recheck in movement, that won't work right. | ||
519 | // So it's not implemented now. | ||
520 | // | ||
521 | |||
522 | // Don't even queue if we have seent this one | ||
523 | // | ||
524 | if (!m_updateTimes.ContainsKey(g.UUID)) | ||
525 | g.ScheduleFullUpdateToAvatar(this); | ||
526 | } | ||
527 | |||
528 | int updateCount = 0; | ||
529 | |||
530 | while (m_partsUpdateQueue.Count > 0) | ||
521 | { | 531 | { |
522 | bool runUpdate = true; | 532 | SceneObjectPart part = m_partsUpdateQueue.Dequeue(); |
523 | int updateCount = 0; | 533 | if (m_updateTimes.ContainsKey(part.UUID)) |
524 | while (runUpdate) | ||
525 | { | 534 | { |
526 | SceneObjectPart part = m_partsUpdateQueue.Dequeue(); | 535 | ScenePartUpdate update = m_updateTimes[part.UUID]; |
527 | if (m_updateTimes.ContainsKey(part.UUID)) | ||
528 | { | ||
529 | ScenePartUpdate update = m_updateTimes[part.UUID]; | ||
530 | 536 | ||
531 | // We deal with the possibility that two updates occur at the same unix time | 537 | // We deal with the possibility that two updates occur at |
532 | // at the update point itself. | 538 | // the same unix time at the update point itself. |
533 | if (update.LastFullUpdateTime < part.TimeStampFull) | 539 | |
534 | { | 540 | if (update.LastFullUpdateTime < part.TimeStampFull) |
541 | { | ||
535 | // m_log.DebugFormat( | 542 | // m_log.DebugFormat( |
536 | // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", | 543 | // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", |
537 | // part.Name, part.UUID, part.TimeStampFull); | 544 | // part.Name, part.UUID, part.TimeStampFull); |
538 | 545 | ||
539 | part.SendFullUpdate(ControllingClient, GenerateClientFlags(part.UUID)); | 546 | part.SendFullUpdate(ControllingClient, |
547 | GenerateClientFlags(part.UUID)); | ||
540 | 548 | ||
541 | // We'll update to the part's timestamp rather than the current time to | 549 | // We'll update to the part's timestamp rather than |
542 | // avoid the race condition whereby the next tick occurs while we are | 550 | // the current time to avoid the race condition |
543 | // doing this update. If this happened, then subsequent updates which occurred | 551 | // whereby the next tick occurs while we are doing |
544 | // on the same tick or the next tick of the last update would be ignored. | 552 | // this update. If this happened, then subsequent |
545 | update.LastFullUpdateTime = part.TimeStampFull; | 553 | // updates which occurred on the same tick or the |
554 | // next tick of the last update would be ignored. | ||
546 | 555 | ||
547 | updateCount++; | 556 | update.LastFullUpdateTime = part.TimeStampFull; |
548 | } | 557 | |
549 | else if (update.LastTerseUpdateTime <= part.TimeStampTerse) | 558 | updateCount++; |
550 | { | 559 | } |
560 | else if (update.LastTerseUpdateTime <= part.TimeStampTerse) | ||
561 | { | ||
551 | // m_log.DebugFormat( | 562 | // m_log.DebugFormat( |
552 | // "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", | 563 | // "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", |
553 | // part.Name, part.UUID, part.TimeStampTerse); | 564 | // part.Name, part.UUID, part.TimeStampTerse); |
554 | 565 | ||
555 | part.SendTerseUpdate(ControllingClient); | 566 | part.SendTerseUpdate(ControllingClient); |
556 | 567 | ||
557 | update.LastTerseUpdateTime = part.TimeStampTerse; | 568 | update.LastTerseUpdateTime = part.TimeStampTerse; |
558 | updateCount++; | ||
559 | } | ||
560 | } | ||
561 | else | ||
562 | { | ||
563 | //never been sent to client before so do full update | ||
564 | part.SendFullUpdate(ControllingClient, GenerateClientFlags(part.UUID)); | ||
565 | ScenePartUpdate update = new ScenePartUpdate(); | ||
566 | update.FullID = part.UUID; | ||
567 | update.LastFullUpdateTime = part.TimeStampFull; | ||
568 | m_updateTimes.Add(part.UUID, update); | ||
569 | updateCount++; | 569 | updateCount++; |
570 | } | 570 | } |
571 | |||
572 | if (m_partsUpdateQueue.Count < 1 || updateCount > 60) | ||
573 | { | ||
574 | runUpdate = false; | ||
575 | } | ||
576 | } | 571 | } |
572 | else | ||
573 | { | ||
574 | //never been sent to client before so do full update | ||
575 | |||
576 | part.SendFullUpdate(ControllingClient, | ||
577 | GenerateClientFlags(part.UUID)); | ||
578 | ScenePartUpdate update = new ScenePartUpdate(); | ||
579 | update.FullID = part.UUID; | ||
580 | update.LastFullUpdateTime = part.TimeStampFull; | ||
581 | m_updateTimes.Add(part.UUID, update); | ||
582 | updateCount++; | ||
583 | } | ||
584 | |||
585 | if (updateCount > 60) | ||
586 | break; | ||
577 | } | 587 | } |
578 | 588 | ||
579 | m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS); | 589 | m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS); |
@@ -631,15 +641,13 @@ namespace OpenSim.Region.Environment.Scenes | |||
631 | m_scene.SwapRootAgentCount(false); | 641 | m_scene.SwapRootAgentCount(false); |
632 | m_scene.CommsManager.UserProfileCacheService.RequestInventoryForUser(m_uuid); | 642 | m_scene.CommsManager.UserProfileCacheService.RequestInventoryForUser(m_uuid); |
633 | m_scene.AddCapsHandler(m_uuid); | 643 | m_scene.AddCapsHandler(m_uuid); |
634 | //if (!m_gotAllObjectsInScene) | 644 | |
635 | //{ | 645 | // On the next prim update, all objects will be sent |
636 | m_scene.SendAllSceneObjectsToClient(this); | 646 | // |
647 | m_pendingObjects = null; | ||
637 | 648 | ||
638 | m_scene.EventManager.TriggerOnMakeRootAgent(this); | 649 | m_scene.EventManager.TriggerOnMakeRootAgent(this); |
639 | m_scene.CommsManager.UserService.UpdateUserCurrentRegion(UUID, m_scene.RegionInfo.RegionID, m_scene.RegionInfo.RegionHandle); | 650 | m_scene.CommsManager.UserService.UpdateUserCurrentRegion(UUID, m_scene.RegionInfo.RegionID, m_scene.RegionInfo.RegionHandle); |
640 | |||
641 | //m_gotAllObjectsInScene = true; | ||
642 | //} | ||
643 | } | 651 | } |
644 | 652 | ||
645 | /// <summary> | 653 | /// <summary> |
@@ -776,7 +784,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
776 | { | 784 | { |
777 | m_isChildAgent = false; | 785 | m_isChildAgent = false; |
778 | 786 | ||
779 | //this.m_scene.SendAllSceneObjectsToClient(this.ControllingClient); | ||
780 | MakeRootAgent(AbsolutePosition, false); | 787 | MakeRootAgent(AbsolutePosition, false); |
781 | } | 788 | } |
782 | } | 789 | } |
@@ -2043,7 +2050,8 @@ namespace OpenSim.Region.Environment.Scenes | |||
2043 | 2050 | ||
2044 | // Sends out the objects in the user's draw distance if m_sendTasksToChild is true. | 2051 | // Sends out the objects in the user's draw distance if m_sendTasksToChild is true. |
2045 | if (m_scene.m_seeIntoRegionFromNeighbor) | 2052 | if (m_scene.m_seeIntoRegionFromNeighbor) |
2046 | m_scene.SendAllSceneObjectsToClient(this); | 2053 | m_pendingObjects = null; |
2054 | |||
2047 | //cAgentData.AVHeight; | 2055 | //cAgentData.AVHeight; |
2048 | //cAgentData.regionHandle; | 2056 | //cAgentData.regionHandle; |
2049 | //m_velocity = cAgentData.Velocity; | 2057 | //m_velocity = cAgentData.Velocity; |
@@ -2248,10 +2256,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
2248 | m_attachments.Clear(); | 2256 | m_attachments.Clear(); |
2249 | } | 2257 | } |
2250 | } | 2258 | } |
2251 | lock (m_knownPrimUUID) | ||
2252 | { | ||
2253 | m_knownPrimUUID.Clear(); | ||
2254 | } | ||
2255 | lock (m_knownChildRegions) | 2259 | lock (m_knownChildRegions) |
2256 | { | 2260 | { |
2257 | m_knownChildRegions.Clear(); | 2261 | m_knownChildRegions.Clear(); |
@@ -2398,7 +2402,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
2398 | m_newForce = (bool)info.GetValue("m_newForce", typeof(bool)); | 2402 | m_newForce = (bool)info.GetValue("m_newForce", typeof(bool)); |
2399 | //m_newAvatar = (bool)info.GetValue("m_newAvatar", typeof(bool)); | 2403 | //m_newAvatar = (bool)info.GetValue("m_newAvatar", typeof(bool)); |
2400 | m_newCoarseLocations = (bool)info.GetValue("m_newCoarseLocations", typeof(bool)); | 2404 | m_newCoarseLocations = (bool)info.GetValue("m_newCoarseLocations", typeof(bool)); |
2401 | m_gotAllObjectsInScene = (bool)info.GetValue("m_gotAllObjectsInScene", typeof(bool)); | ||
2402 | m_avHeight = (float)info.GetValue("m_avHeight", typeof(float)); | 2405 | m_avHeight = (float)info.GetValue("m_avHeight", typeof(float)); |
2403 | crossingFromRegion = (ulong)info.GetValue("crossingFromRegion", typeof(ulong)); | 2406 | crossingFromRegion = (ulong)info.GetValue("crossingFromRegion", typeof(ulong)); |
2404 | 2407 | ||
@@ -2503,13 +2506,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
2503 | 2506 | ||
2504 | m_state = (byte)info.GetValue("m_state", typeof(byte)); | 2507 | m_state = (byte)info.GetValue("m_state", typeof(byte)); |
2505 | 2508 | ||
2506 | List<Guid> knownPrimUUID_work = (List<Guid>)info.GetValue("m_knownPrimUUID", typeof(List<Guid>)); | ||
2507 | |||
2508 | foreach (Guid id in knownPrimUUID_work) | ||
2509 | { | ||
2510 | m_knownPrimUUID.Add(new LLUUID(id)); | ||
2511 | } | ||
2512 | |||
2513 | //System.Console.WriteLine("ScenePresence Deserialize END"); | 2509 | //System.Console.WriteLine("ScenePresence Deserialize END"); |
2514 | } | 2510 | } |
2515 | 2511 | ||
@@ -2551,7 +2547,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
2551 | info.AddValue("m_newForce", m_newForce); | 2547 | info.AddValue("m_newForce", m_newForce); |
2552 | //info.AddValue("m_newAvatar", m_newAvatar); | 2548 | //info.AddValue("m_newAvatar", m_newAvatar); |
2553 | info.AddValue("m_newCoarseLocations", m_newCoarseLocations); | 2549 | info.AddValue("m_newCoarseLocations", m_newCoarseLocations); |
2554 | info.AddValue("m_gotAllObjectsInScene", m_gotAllObjectsInScene); | 2550 | info.AddValue("m_gotAllObjectsInScene", false); |
2555 | info.AddValue("m_avHeight", m_avHeight); | 2551 | info.AddValue("m_avHeight", m_avHeight); |
2556 | 2552 | ||
2557 | // info.AddValue("m_regionInfo", m_regionInfo); | 2553 | // info.AddValue("m_regionInfo", m_regionInfo); |
@@ -2650,11 +2646,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
2650 | 2646 | ||
2651 | List<Guid> knownPrimUUID_work = new List<Guid>(); | 2647 | List<Guid> knownPrimUUID_work = new List<Guid>(); |
2652 | 2648 | ||
2653 | foreach (LLUUID id in m_knownPrimUUID) | ||
2654 | { | ||
2655 | knownPrimUUID_work.Add(id.UUID); | ||
2656 | } | ||
2657 | |||
2658 | info.AddValue("m_knownPrimUUID", knownPrimUUID_work); | 2649 | info.AddValue("m_knownPrimUUID", knownPrimUUID_work); |
2659 | } | 2650 | } |
2660 | 2651 | ||