diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs')
-rwxr-xr-x | OpenSim/Region/Framework/Scenes/Scene.cs | 1339 |
1 files changed, 850 insertions, 489 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 2fe6e22..2fcb78d 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -61,8 +61,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
61 | { | 61 | { |
62 | private const long DEFAULT_MIN_TIME_FOR_PERSISTENCE = 60L; | 62 | private const long DEFAULT_MIN_TIME_FOR_PERSISTENCE = 60L; |
63 | private const long DEFAULT_MAX_TIME_FOR_PERSISTENCE = 600L; | 63 | private const long DEFAULT_MAX_TIME_FOR_PERSISTENCE = 600L; |
64 | 64 | ||
65 | public const int m_defaultNumberFramesStored = 10; | ||
66 | 65 | ||
67 | public delegate void SynchronizeSceneHandler(Scene scene); | 66 | public delegate void SynchronizeSceneHandler(Scene scene); |
68 | 67 | ||
@@ -105,9 +104,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
105 | /// <summary> | 104 | /// <summary> |
106 | /// If false then physical objects are disabled, though collisions will continue as normal. | 105 | /// If false then physical objects are disabled, though collisions will continue as normal. |
107 | /// </summary> | 106 | /// </summary> |
108 | public bool PhysicsEnabled | 107 | |
109 | { | 108 | public bool PhysicsEnabled |
110 | get | 109 | { |
110 | get | ||
111 | { | 111 | { |
112 | return m_physicsEnabled; | 112 | return m_physicsEnabled; |
113 | } | 113 | } |
@@ -216,7 +216,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
216 | /// <summary> | 216 | /// <summary> |
217 | /// Maximum value of the size of a physical prim in each axis | 217 | /// Maximum value of the size of a physical prim in each axis |
218 | /// </summary> | 218 | /// </summary> |
219 | public float m_maxPhys = 64; | 219 | public float m_maxPhys = 10; |
220 | 220 | ||
221 | /// <summary> | 221 | /// <summary> |
222 | /// Max prims an object will hold | 222 | /// Max prims an object will hold |
@@ -228,10 +228,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
228 | public bool m_allowScriptCrossings = true; | 228 | public bool m_allowScriptCrossings = true; |
229 | 229 | ||
230 | /// <summary> | 230 | /// <summary> |
231 | |||
231 | /// Can avatars cross from and to this region? | 232 | /// Can avatars cross from and to this region? |
232 | /// </summary> | 233 | /// </summary> |
233 | public bool AllowAvatarCrossing { get; set; } | 234 | public bool AllowAvatarCrossing { get; set; } |
234 | 235 | ||
236 | /// Max prims an Physical object will hold | ||
237 | /// </summary> | ||
238 | /// | ||
239 | public int m_linksetPhysCapacity = 0; | ||
240 | |||
235 | public bool m_useFlySlow; | 241 | public bool m_useFlySlow; |
236 | public bool m_useTrashOnDelete = true; | 242 | public bool m_useTrashOnDelete = true; |
237 | 243 | ||
@@ -265,20 +271,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
265 | /// </summary> | 271 | /// </summary> |
266 | public int ChildTerseUpdatePeriod { get; set; } | 272 | public int ChildTerseUpdatePeriod { get; set; } |
267 | 273 | ||
268 | protected float m_defaultDrawDistance = 255.0f; | 274 | protected float m_defaultDrawDistance = 255f; |
269 | public float DefaultDrawDistance | 275 | public float DefaultDrawDistance |
270 | { | 276 | { |
271 | // get { return m_defaultDrawDistance; } | 277 | get { return m_defaultDrawDistance; } |
272 | get | 278 | } |
273 | { | ||
274 | if (RegionInfo != null) | ||
275 | { | ||
276 | float largestDimension = Math.Max(RegionInfo.RegionSizeX, RegionInfo.RegionSizeY); | ||
277 | m_defaultDrawDistance = Math.Max(m_defaultDrawDistance, largestDimension); | ||
278 | 279 | ||
279 | } | 280 | protected float m_maxDrawDistance = 512.0f; |
280 | return m_defaultDrawDistance; | 281 | // protected float m_maxDrawDistance = 256.0f; |
281 | } | 282 | public float MaxDrawDistance |
283 | { | ||
284 | get { return m_maxDrawDistance; } | ||
282 | } | 285 | } |
283 | 286 | ||
284 | private List<string> m_AllowedViewers = new List<string>(); | 287 | private List<string> m_AllowedViewers = new List<string>(); |
@@ -287,8 +290,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
287 | // TODO: need to figure out how allow client agents but deny | 290 | // TODO: need to figure out how allow client agents but deny |
288 | // root agents when ACL denies access to root agent | 291 | // root agents when ACL denies access to root agent |
289 | public bool m_strictAccessControl = true; | 292 | public bool m_strictAccessControl = true; |
290 | 293 | public bool m_seeIntoBannedRegion = false; | |
291 | public int MaxUndoCount { get; set; } | 294 | public int MaxUndoCount = 5; |
292 | 295 | ||
293 | public bool SeeIntoRegion { get; set; } | 296 | public bool SeeIntoRegion { get; set; } |
294 | 297 | ||
@@ -306,11 +309,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
306 | 309 | ||
307 | protected int m_splitRegionID; | 310 | protected int m_splitRegionID; |
308 | protected Timer m_restartWaitTimer = new Timer(); | 311 | protected Timer m_restartWaitTimer = new Timer(); |
312 | protected Timer m_timerWatchdog = new Timer(); | ||
309 | protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); | 313 | protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); |
310 | protected List<RegionInfo> m_neighbours = new List<RegionInfo>(); | 314 | protected List<RegionInfo> m_neighbours = new List<RegionInfo>(); |
311 | protected string m_simulatorVersion = "OpenSimulator Server"; | 315 | protected string m_simulatorVersion = "OpenSimulator Server"; |
312 | protected AgentCircuitManager m_authenticateHandler; | 316 | protected AgentCircuitManager m_authenticateHandler; |
313 | protected SceneCommunicationService m_sceneGridService; | 317 | protected SceneCommunicationService m_sceneGridService; |
318 | protected ISnmpModule m_snmpService = null; | ||
314 | 319 | ||
315 | protected ISimulationDataService m_SimulationDataService; | 320 | protected ISimulationDataService m_SimulationDataService; |
316 | protected IEstateDataService m_EstateDataService; | 321 | protected IEstateDataService m_EstateDataService; |
@@ -339,17 +344,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
339 | private Dictionary<string, string> m_extraSettings; | 344 | private Dictionary<string, string> m_extraSettings; |
340 | 345 | ||
341 | /// <summary> | 346 | /// <summary> |
342 | /// If true then the next time the scene loop is activated, updates will be performed by firing of a timer | ||
343 | /// rather than on a single thread that sleeps. | ||
344 | /// </summary> | ||
345 | public bool UpdateOnTimer { get; set; } | ||
346 | |||
347 | /// <summary> | ||
348 | /// Only used if we are updating scene on a timer rather than sleeping a thread. | ||
349 | /// </summary> | ||
350 | private Timer m_sceneUpdateTimer; | ||
351 | |||
352 | /// <summary> | ||
353 | /// Current scene frame number | 347 | /// Current scene frame number |
354 | /// </summary> | 348 | /// </summary> |
355 | public uint Frame | 349 | public uint Frame |
@@ -364,24 +358,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
364 | public uint MaintenanceRun { get; private set; } | 358 | public uint MaintenanceRun { get; private set; } |
365 | 359 | ||
366 | /// <summary> | 360 | /// <summary> |
367 | /// The minimum length of time in milliseconds that will be taken for a scene frame. If the frame takes less time then we | 361 | /// Frame time |
368 | /// will sleep for the remaining period. | ||
369 | /// </summary> | ||
370 | /// <remarks> | ||
371 | /// One can tweak this number to experiment. One current effect of reducing it is to make avatar animations | ||
372 | /// occur too quickly (viewer 1) or with even more slide (viewer 2). | ||
373 | /// </remarks> | 362 | /// </remarks> |
374 | public int MinFrameTicks | 363 | public float FrameTime { get; private set; } |
375 | { | ||
376 | get { return m_minFrameTicks; } | ||
377 | private set | ||
378 | { | ||
379 | m_minFrameTicks = value; | ||
380 | MinFrameSeconds = (float)m_minFrameTicks / 1000; | ||
381 | } | ||
382 | } | ||
383 | private int m_minFrameTicks; | ||
384 | |||
385 | public int FrameTimeWarnPercent { get; private set; } | 364 | public int FrameTimeWarnPercent { get; private set; } |
386 | public int FrameTimeCritPercent { get; private set; } | 365 | public int FrameTimeCritPercent { get; private set; } |
387 | 366 | ||
@@ -395,17 +374,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
395 | /// <remarks> | 374 | /// <remarks> |
396 | /// Always derived from MinFrameTicks. | 375 | /// Always derived from MinFrameTicks. |
397 | /// </remarks> | 376 | /// </remarks> |
398 | public float MinFrameSeconds { get; private set; } | 377 | public float MinMaintenanceTime { get; private set; } |
399 | |||
400 | /// <summary> | ||
401 | /// The minimum length of time in milliseconds that will be taken for a scene frame. If the frame takes less time then we | ||
402 | /// will sleep for the remaining period. | ||
403 | /// </summary> | ||
404 | /// <remarks> | ||
405 | /// One can tweak this number to experiment. One current effect of reducing it is to make avatar animations | ||
406 | /// occur too quickly (viewer 1) or with even more slide (viewer 2). | ||
407 | /// </remarks> | ||
408 | public int MinMaintenanceTicks { get; set; } | ||
409 | 378 | ||
410 | private int m_update_physics = 1; | 379 | private int m_update_physics = 1; |
411 | private int m_update_entitymovement = 1; | 380 | private int m_update_entitymovement = 1; |
@@ -413,22 +382,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
413 | private int m_update_presences = 1; // Update scene presence movements | 382 | private int m_update_presences = 1; // Update scene presence movements |
414 | private int m_update_events = 1; | 383 | private int m_update_events = 1; |
415 | private int m_update_backup = 200; | 384 | private int m_update_backup = 200; |
416 | private int m_update_terrain = 50; | 385 | |
417 | // private int m_update_land = 1; | 386 | private int m_update_terrain = 1000; |
387 | private int m_update_land = 10; | ||
388 | |||
418 | private int m_update_coarse_locations = 50; | 389 | private int m_update_coarse_locations = 50; |
419 | private int m_update_temp_cleaning = 180; | 390 | private int m_update_temp_cleaning = 180; |
420 | 391 | ||
421 | private int agentMS; | 392 | private float agentMS; |
422 | private int frameMS; | 393 | private float frameMS; |
423 | private int physicsMS2; | 394 | private float physicsMS2; |
424 | private int physicsMS; | 395 | private float physicsMS; |
425 | private int otherMS; | 396 | private float otherMS; |
426 | private int tempOnRezMS; | 397 | private float tempOnRezMS; |
427 | private int eventMS; | 398 | private float eventMS; |
428 | private int backupMS; | 399 | private float backupMS; |
429 | private int terrainMS; | 400 | private float terrainMS; |
430 | private int landMS; | 401 | private float landMS; |
431 | private int spareMS; | ||
432 | 402 | ||
433 | // A temporary configuration flag to enable using FireAndForget to process | 403 | // A temporary configuration flag to enable using FireAndForget to process |
434 | // collisions from the physics engine. There is a problem with collisions | 404 | // collisions from the physics engine. There is a problem with collisions |
@@ -446,6 +416,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
446 | /// </summary> | 416 | /// </summary> |
447 | private int m_lastFrameTick; | 417 | private int m_lastFrameTick; |
448 | 418 | ||
419 | public bool CombineRegions = false; | ||
449 | /// <summary> | 420 | /// <summary> |
450 | /// Tick at which the last maintenance run occurred. | 421 | /// Tick at which the last maintenance run occurred. |
451 | /// </summary> | 422 | /// </summary> |
@@ -477,7 +448,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
477 | private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing | 448 | private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing |
478 | private volatile bool m_backingup; | 449 | private volatile bool m_backingup; |
479 | private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>(); | 450 | private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>(); |
480 | private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>(); | 451 | private Dictionary<UUID, int> m_groupsWithTargets = new Dictionary<UUID, int>(); |
481 | 452 | ||
482 | private string m_defaultScriptEngine; | 453 | private string m_defaultScriptEngine; |
483 | 454 | ||
@@ -492,6 +463,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
492 | /// </summary> | 463 | /// </summary> |
493 | private int m_LastLogin; | 464 | private int m_LastLogin; |
494 | 465 | ||
466 | private int m_lastIncoming; | ||
467 | private int m_lastOutgoing; | ||
468 | private int m_hbRestarts = 0; | ||
469 | |||
470 | |||
495 | /// <summary> | 471 | /// <summary> |
496 | /// Thread that runs the scene loop. | 472 | /// Thread that runs the scene loop. |
497 | /// </summary> | 473 | /// </summary> |
@@ -540,6 +516,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
540 | public bool IsRunning { get { return m_isRunning; } } | 516 | public bool IsRunning { get { return m_isRunning; } } |
541 | private volatile bool m_isRunning; | 517 | private volatile bool m_isRunning; |
542 | 518 | ||
519 | // private int m_lastUpdate; | ||
520 | private bool m_firstHeartbeat = true; | ||
521 | |||
522 | private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time; | ||
523 | private bool m_reprioritizationEnabled = true; | ||
524 | private double m_reprioritizationInterval = 5000.0; | ||
525 | private double m_rootReprioritizationDistance = 10.0; | ||
526 | private double m_childReprioritizationDistance = 20.0; | ||
527 | |||
528 | |||
543 | private Timer m_mapGenerationTimer = new Timer(); | 529 | private Timer m_mapGenerationTimer = new Timer(); |
544 | private bool m_generateMaptiles; | 530 | private bool m_generateMaptiles; |
545 | 531 | ||
@@ -571,6 +557,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
571 | get { return m_sceneGridService; } | 557 | get { return m_sceneGridService; } |
572 | } | 558 | } |
573 | 559 | ||
560 | public ISnmpModule SnmpService | ||
561 | { | ||
562 | get | ||
563 | { | ||
564 | if (m_snmpService == null) | ||
565 | { | ||
566 | m_snmpService = RequestModuleInterface<ISnmpModule>(); | ||
567 | } | ||
568 | |||
569 | return m_snmpService; | ||
570 | } | ||
571 | } | ||
572 | |||
574 | public ISimulationDataService SimulationDataService | 573 | public ISimulationDataService SimulationDataService |
575 | { | 574 | { |
576 | get | 575 | get |
@@ -777,15 +776,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
777 | get { return m_capsModule; } | 776 | get { return m_capsModule; } |
778 | } | 777 | } |
779 | 778 | ||
780 | public int MonitorFrameTime { get { return frameMS; } } | 779 | public int MonitorFrameTime { get { return (int)frameMS; } } |
781 | public int MonitorPhysicsUpdateTime { get { return physicsMS; } } | 780 | public int MonitorPhysicsUpdateTime { get { return (int)physicsMS; } } |
782 | public int MonitorPhysicsSyncTime { get { return physicsMS2; } } | 781 | public int MonitorPhysicsSyncTime { get { return (int)physicsMS2; } } |
783 | public int MonitorOtherTime { get { return otherMS; } } | 782 | public int MonitorOtherTime { get { return (int)otherMS; } } |
784 | public int MonitorTempOnRezTime { get { return tempOnRezMS; } } | 783 | public int MonitorTempOnRezTime { get { return (int)tempOnRezMS; } } |
785 | public int MonitorEventTime { get { return eventMS; } } // This may need to be divided into each event? | 784 | public int MonitorEventTime { get { return (int)eventMS; } } // This may need to be divided into each event? |
786 | public int MonitorBackupTime { get { return backupMS; } } | 785 | public int MonitorBackupTime { get { return (int)backupMS; } } |
787 | public int MonitorTerrainTime { get { return terrainMS; } } | 786 | public int MonitorTerrainTime { get { return (int)terrainMS; } } |
788 | public int MonitorLandTime { get { return landMS; } } | 787 | public int MonitorLandTime { get { return (int)landMS; } } |
789 | public int MonitorLastFrameTick { get { return m_lastFrameTick; } } | 788 | public int MonitorLastFrameTick { get { return m_lastFrameTick; } } |
790 | 789 | ||
791 | public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get; set; } | 790 | public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get; set; } |
@@ -863,11 +862,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
863 | : this(regInfo) | 862 | : this(regInfo) |
864 | { | 863 | { |
865 | m_config = config; | 864 | m_config = config; |
866 | MinFrameTicks = 89; | 865 | FrameTime = 0.0908f; |
867 | FrameTimeWarnPercent = 60; | 866 | FrameTimeWarnPercent = 60; |
868 | FrameTimeCritPercent = 40; | 867 | FrameTimeCritPercent = 40; |
869 | Normalized55FPS = true; | 868 | Normalized55FPS = true; |
870 | MinMaintenanceTicks = 1000; | 869 | MinMaintenanceTime = 1; |
871 | SeeIntoRegion = true; | 870 | SeeIntoRegion = true; |
872 | 871 | ||
873 | Random random = new Random(); | 872 | Random random = new Random(); |
@@ -878,6 +877,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
878 | m_SimulationDataService = simDataService; | 877 | m_SimulationDataService = simDataService; |
879 | m_EstateDataService = estateDataService; | 878 | m_EstateDataService = estateDataService; |
880 | 879 | ||
880 | m_lastIncoming = 0; | ||
881 | m_lastOutgoing = 0; | ||
882 | |||
881 | m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this); | 883 | m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this); |
882 | m_asyncSceneObjectDeleter.Enabled = true; | 884 | m_asyncSceneObjectDeleter.Enabled = true; |
883 | 885 | ||
@@ -935,7 +937,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
935 | EventManager.OnLandObjectRemoved += | 937 | EventManager.OnLandObjectRemoved += |
936 | new EventManager.LandObjectRemoved(simDataService.RemoveLandObject); | 938 | new EventManager.LandObjectRemoved(simDataService.RemoveLandObject); |
937 | 939 | ||
938 | RegisterDefaultSceneEvents(); | 940 | RegisterDefaultSceneEvents(); |
939 | 941 | ||
940 | // XXX: Don't set the public property since we don't want to activate here. This needs to be handled | 942 | // XXX: Don't set the public property since we don't want to activate here. This needs to be handled |
941 | // better in the future. | 943 | // better in the future. |
@@ -956,6 +958,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
956 | StartDisabled = startupConfig.GetBoolean("StartDisabled", false); | 958 | StartDisabled = startupConfig.GetBoolean("StartDisabled", false); |
957 | 959 | ||
958 | m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance", m_defaultDrawDistance); | 960 | m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance", m_defaultDrawDistance); |
961 | m_maxDrawDistance = startupConfig.GetFloat("MaxDrawDistance", m_maxDrawDistance); | ||
962 | |||
963 | if (m_defaultDrawDistance > m_maxDrawDistance) | ||
964 | m_defaultDrawDistance = m_maxDrawDistance; | ||
965 | |||
959 | UseBackup = startupConfig.GetBoolean("UseSceneBackup", UseBackup); | 966 | UseBackup = startupConfig.GetBoolean("UseSceneBackup", UseBackup); |
960 | if (!UseBackup) | 967 | if (!UseBackup) |
961 | m_log.InfoFormat("[SCENE]: Backup has been disabled for {0}", RegionInfo.RegionName); | 968 | m_log.InfoFormat("[SCENE]: Backup has been disabled for {0}", RegionInfo.RegionName); |
@@ -967,9 +974,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
967 | 974 | ||
968 | MaxUndoCount = startupConfig.GetInt("MaxPrimUndos", 20); | 975 | MaxUndoCount = startupConfig.GetInt("MaxPrimUndos", 20); |
969 | 976 | ||
970 | PhysicalPrims = startupConfig.GetBoolean("physical_prim", PhysicalPrims); | 977 | PhysicalPrims = startupConfig.GetBoolean("physical_prim", true); |
971 | CollidablePrims = startupConfig.GetBoolean("collidable_prim", CollidablePrims); | 978 | CollidablePrims = startupConfig.GetBoolean("collidable_prim", true); |
972 | |||
973 | m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys); | 979 | m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys); |
974 | if (RegionInfo.NonphysPrimMin > 0) | 980 | if (RegionInfo.NonphysPrimMin > 0) |
975 | { | 981 | { |
@@ -989,11 +995,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
989 | } | 995 | } |
990 | 996 | ||
991 | m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys); | 997 | m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys); |
998 | |||
992 | if (RegionInfo.PhysPrimMax > 0) | 999 | if (RegionInfo.PhysPrimMax > 0) |
993 | { | 1000 | { |
994 | m_maxPhys = RegionInfo.PhysPrimMax; | 1001 | m_maxPhys = RegionInfo.PhysPrimMax; |
995 | } | 1002 | } |
996 | 1003 | ||
1004 | m_linksetCapacity = startupConfig.GetInt("LinksetPrims", m_linksetCapacity); | ||
1005 | if (RegionInfo.LinksetCapacity > 0) | ||
1006 | { | ||
1007 | m_linksetCapacity = RegionInfo.LinksetCapacity; | ||
1008 | } | ||
1009 | |||
1010 | m_linksetPhysCapacity = startupConfig.GetInt("LinksetPhysPrims", m_linksetPhysCapacity); | ||
1011 | |||
1012 | |||
1013 | SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest"); | ||
1014 | TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false); | ||
1015 | |||
997 | // Here, if clamping is requested in either global or | 1016 | // Here, if clamping is requested in either global or |
998 | // local config, it will be used | 1017 | // local config, it will be used |
999 | // | 1018 | // |
@@ -1003,13 +1022,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1003 | m_clampPrimSize = true; | 1022 | m_clampPrimSize = true; |
1004 | } | 1023 | } |
1005 | 1024 | ||
1006 | m_linksetCapacity = startupConfig.GetInt("LinksetPrims", m_linksetCapacity); | 1025 | m_useTrashOnDelete = startupConfig.GetBoolean("UseTrashOnDelete",m_useTrashOnDelete); |
1007 | if (RegionInfo.LinksetCapacity > 0) | ||
1008 | { | ||
1009 | m_linksetCapacity = RegionInfo.LinksetCapacity; | ||
1010 | } | ||
1011 | |||
1012 | m_useTrashOnDelete = startupConfig.GetBoolean("UseTrashOnDelete", m_useTrashOnDelete); | ||
1013 | m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries); | 1026 | m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries); |
1014 | m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings); | 1027 | m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings); |
1015 | m_dontPersistBefore = | 1028 | m_dontPersistBefore = |
@@ -1020,11 +1033,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1020 | m_persistAfter *= 10000000; | 1033 | m_persistAfter *= 10000000; |
1021 | 1034 | ||
1022 | m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); | 1035 | m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); |
1023 | 1036 | m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine); | |
1024 | SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest"); | ||
1025 | TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false); | ||
1026 | 1037 | ||
1027 | m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); | 1038 | m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); |
1039 | m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion); | ||
1040 | CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false); | ||
1028 | 1041 | ||
1029 | string[] possibleMapConfigSections = new string[] { "Map", "Startup" }; | 1042 | string[] possibleMapConfigSections = new string[] { "Map", "Startup" }; |
1030 | 1043 | ||
@@ -1070,7 +1083,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1070 | 1083 | ||
1071 | if (grant.Length > 0) | 1084 | if (grant.Length > 0) |
1072 | { | 1085 | { |
1073 | foreach (string viewer in grant.Split('|')) | 1086 | foreach (string viewer in grant.Split(',')) |
1074 | { | 1087 | { |
1075 | m_AllowedViewers.Add(viewer.Trim().ToLower()); | 1088 | m_AllowedViewers.Add(viewer.Trim().ToLower()); |
1076 | } | 1089 | } |
@@ -1086,17 +1099,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
1086 | 1099 | ||
1087 | if (grant.Length > 0) | 1100 | if (grant.Length > 0) |
1088 | { | 1101 | { |
1089 | foreach (string viewer in grant.Split('|')) | 1102 | foreach (string viewer in grant.Split(',')) |
1090 | { | 1103 | { |
1091 | m_BannedViewers.Add(viewer.Trim().ToLower()); | 1104 | m_BannedViewers.Add(viewer.Trim().ToLower()); |
1092 | } | 1105 | } |
1093 | } | 1106 | } |
1094 | 1107 | ||
1095 | if (startupConfig.Contains("MinFrameTime")) | 1108 | FrameTime = startupConfig.GetFloat( "FrameTime", FrameTime); |
1096 | MinFrameTicks = (int)(startupConfig.GetFloat("MinFrameTime") * 1000); | ||
1097 | FrameTimeWarnPercent = startupConfig.GetInt( "FrameTimeWarnPercent", FrameTimeWarnPercent); | 1109 | FrameTimeWarnPercent = startupConfig.GetInt( "FrameTimeWarnPercent", FrameTimeWarnPercent); |
1098 | FrameTimeCritPercent = startupConfig.GetInt( "FrameTimeCritPercent", FrameTimeCritPercent); | 1110 | FrameTimeCritPercent = startupConfig.GetInt( "FrameTimeCritPercent", FrameTimeCritPercent); |
1099 | Normalized55FPS = startupConfig.GetBoolean( "Normalized55FPS", Normalized55FPS); | 1111 | Normalized55FPS = startupConfig.GetBoolean( "Normalized55FPS", Normalized55FPS); |
1100 | 1112 | ||
1101 | m_update_backup = startupConfig.GetInt("UpdateStorageEveryNFrames", m_update_backup); | 1113 | m_update_backup = startupConfig.GetInt("UpdateStorageEveryNFrames", m_update_backup); |
1102 | m_update_coarse_locations = startupConfig.GetInt("UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations); | 1114 | m_update_coarse_locations = startupConfig.GetInt("UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations); |
@@ -1174,39 +1186,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1174 | 1186 | ||
1175 | #endregion Interest Management | 1187 | #endregion Interest Management |
1176 | 1188 | ||
1177 | // The timer used by the Stopwatch class depends on the system hardware and operating system; inform | ||
1178 | // if the timer is based on a high-resolution performance counter or based on the system timer; | ||
1179 | // the performance counter will provide a more precise time than the system timer | ||
1180 | if (Stopwatch.IsHighResolution) | ||
1181 | m_log.InfoFormat("[SCENE]: Using high-resolution performance counter for statistics."); | ||
1182 | else | ||
1183 | m_log.InfoFormat("[SCENE]: Using system timer for statistics."); | ||
1184 | 1189 | ||
1185 | // Acquire the statistics section of the OpenSim.ini file located | 1190 | StatsReporter = new SimStatsReporter(this); |
1186 | // in the bin directory | ||
1187 | IConfig statisticsConfig = m_config.Configs["Statistics"]; | ||
1188 | |||
1189 | // Confirm that the statistics section existed in the configuration | ||
1190 | // file | ||
1191 | if (statisticsConfig != null) | ||
1192 | { | ||
1193 | // Create the StatsReporter using the number of frames to store | ||
1194 | // for the frame time statistics, or 10 frames if the config | ||
1195 | // file doesn't contain a value | ||
1196 | StatsReporter = new SimStatsReporter(this, | ||
1197 | statisticsConfig.GetInt("NumberOfFrames", | ||
1198 | m_defaultNumberFramesStored)); | ||
1199 | } | ||
1200 | else | ||
1201 | { | ||
1202 | // Create a StatsReporter with the current scene and a default | ||
1203 | // 10 frames stored for the frame time statistics | ||
1204 | StatsReporter = new SimStatsReporter(this); | ||
1205 | } | ||
1206 | 1191 | ||
1207 | StatsReporter.OnSendStatsResult += SendSimStatsPackets; | 1192 | StatsReporter.OnSendStatsResult += SendSimStatsPackets; |
1208 | StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats; | 1193 | StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats; |
1209 | 1194 | ||
1210 | } | 1195 | } |
1211 | 1196 | ||
1212 | public Scene(RegionInfo regInfo) | 1197 | public Scene(RegionInfo regInfo) |
@@ -1249,6 +1234,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1249 | m_eventManager = new EventManager(); | 1234 | m_eventManager = new EventManager(); |
1250 | 1235 | ||
1251 | m_permissions = new ScenePermissions(this); | 1236 | m_permissions = new ScenePermissions(this); |
1237 | |||
1252 | } | 1238 | } |
1253 | 1239 | ||
1254 | #endregion | 1240 | #endregion |
@@ -1285,7 +1271,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1285 | if (!fm.TryGetFeature("OpenSimExtras", out openSimExtras)) | 1271 | if (!fm.TryGetFeature("OpenSimExtras", out openSimExtras)) |
1286 | openSimExtras = new OSDMap(); | 1272 | openSimExtras = new OSDMap(); |
1287 | 1273 | ||
1288 | float FrameTime = MinFrameTicks / 1000.0f; | ||
1289 | float statisticsFPSfactor = 1.0f; | 1274 | float statisticsFPSfactor = 1.0f; |
1290 | if(Normalized55FPS) | 1275 | if(Normalized55FPS) |
1291 | statisticsFPSfactor = 55.0f * FrameTime; | 1276 | statisticsFPSfactor = 55.0f * FrameTime; |
@@ -1325,20 +1310,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1325 | { | 1310 | { |
1326 | if (RegionInfo.RegionHandle != otherRegion.RegionHandle) | 1311 | if (RegionInfo.RegionHandle != otherRegion.RegionHandle) |
1327 | { | 1312 | { |
1328 | //// If these are cast to INT because long + negative values + abs returns invalid data | ||
1329 | //int resultX = Math.Abs((int)xcell - (int)RegionInfo.RegionLocX); | ||
1330 | //int resultY = Math.Abs((int)ycell - (int)RegionInfo.RegionLocY); | ||
1331 | //if (resultX <= 1 && resultY <= 1) | ||
1332 | float dist = (float)Math.Max(DefaultDrawDistance, | ||
1333 | (float)Math.Max(RegionInfo.RegionSizeX, RegionInfo.RegionSizeY)); | ||
1334 | uint newRegionX, newRegionY, thisRegionX, thisRegionY; | ||
1335 | Util.RegionHandleToRegionLoc(otherRegion.RegionHandle, out newRegionX, out newRegionY); | ||
1336 | Util.RegionHandleToRegionLoc(RegionInfo.RegionHandle, out thisRegionX, out thisRegionY); | ||
1337 | 1313 | ||
1338 | //m_log.InfoFormat("[SCENE]: (on region {0}): Region {1} up in coords {2}-{3}", | 1314 | if (isNeighborRegion(otherRegion)) |
1339 | // RegionInfo.RegionName, otherRegion.RegionName, newRegionX, newRegionY); | ||
1340 | |||
1341 | if (!Util.IsOutsideView(dist, thisRegionX, newRegionX, thisRegionY, newRegionY)) | ||
1342 | { | 1315 | { |
1343 | // Let the grid service module know, so this can be cached | 1316 | // Let the grid service module know, so this can be cached |
1344 | m_eventManager.TriggerOnRegionUp(otherRegion); | 1317 | m_eventManager.TriggerOnRegionUp(otherRegion); |
@@ -1373,6 +1346,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1373 | } | 1346 | } |
1374 | } | 1347 | } |
1375 | 1348 | ||
1349 | public bool isNeighborRegion(GridRegion otherRegion) | ||
1350 | { | ||
1351 | int tmp = otherRegion.RegionLocX - (int)RegionInfo.WorldLocX; ; | ||
1352 | |||
1353 | if (tmp < -otherRegion.RegionSizeX && tmp > RegionInfo.RegionSizeX) | ||
1354 | return false; | ||
1355 | |||
1356 | tmp = otherRegion.RegionLocY - (int)RegionInfo.WorldLocY; | ||
1357 | |||
1358 | if (tmp < -otherRegion.RegionSizeY && tmp > RegionInfo.RegionSizeY) | ||
1359 | return false; | ||
1360 | |||
1361 | return true; | ||
1362 | } | ||
1363 | |||
1376 | public void AddNeighborRegion(RegionInfo region) | 1364 | public void AddNeighborRegion(RegionInfo region) |
1377 | { | 1365 | { |
1378 | lock (m_neighbours) | 1366 | lock (m_neighbours) |
@@ -1504,8 +1492,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1504 | // Stop all client threads. | 1492 | // Stop all client threads. |
1505 | ForEachScenePresence(delegate(ScenePresence avatar) { CloseAgent(avatar.UUID, false); }); | 1493 | ForEachScenePresence(delegate(ScenePresence avatar) { CloseAgent(avatar.UUID, false); }); |
1506 | 1494 | ||
1507 | m_log.Debug("[SCENE]: Persisting changed objects"); | 1495 | m_log.Debug("[SCENE]: TriggerSceneShuttingDown"); |
1508 | EventManager.TriggerSceneShuttingDown(this); | 1496 | EventManager.TriggerSceneShuttingDown(this); |
1497 | |||
1498 | m_log.Debug("[SCENE]: Persisting changed objects"); | ||
1499 | |||
1509 | Backup(false); | 1500 | Backup(false); |
1510 | m_sceneGraph.Close(); | 1501 | m_sceneGraph.Close(); |
1511 | 1502 | ||
@@ -1519,6 +1510,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1519 | // attempt to reference a null or disposed physics scene. | 1510 | // attempt to reference a null or disposed physics scene. |
1520 | if (PhysicsScene != null) | 1511 | if (PhysicsScene != null) |
1521 | { | 1512 | { |
1513 | m_log.Debug("[SCENE]: Dispose Physics"); | ||
1522 | PhysicsScene phys = PhysicsScene; | 1514 | PhysicsScene phys = PhysicsScene; |
1523 | // remove the physics engine from both Scene and SceneGraph | 1515 | // remove the physics engine from both Scene and SceneGraph |
1524 | PhysicsScene = null; | 1516 | PhysicsScene = null; |
@@ -1550,10 +1542,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
1550 | // m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); | 1542 | // m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); |
1551 | if (m_heartbeatThread != null) | 1543 | if (m_heartbeatThread != null) |
1552 | { | 1544 | { |
1545 | m_hbRestarts++; | ||
1546 | if(m_hbRestarts > 10) | ||
1547 | Environment.Exit(1); | ||
1548 | m_log.ErrorFormat("[SCENE]: Restarting heartbeat thread because it hasn't reported in in region {0}", RegionInfo.RegionName); | ||
1549 | |||
1550 | //int pid = System.Diagnostics.Process.GetCurrentProcess().Id; | ||
1551 | //System.Diagnostics.Process proc = new System.Diagnostics.Process(); | ||
1552 | //proc.EnableRaisingEvents=false; | ||
1553 | //proc.StartInfo.FileName = "/bin/kill"; | ||
1554 | //proc.StartInfo.Arguments = "-QUIT " + pid.ToString(); | ||
1555 | //proc.Start(); | ||
1556 | //proc.WaitForExit(); | ||
1557 | //Thread.Sleep(1000); | ||
1558 | //Environment.Exit(1); | ||
1553 | m_heartbeatThread.Abort(); | 1559 | m_heartbeatThread.Abort(); |
1560 | Watchdog.AbortThread(m_heartbeatThread.ManagedThreadId); | ||
1554 | m_heartbeatThread = null; | 1561 | m_heartbeatThread = null; |
1555 | } | 1562 | } |
1556 | 1563 | ||
1564 | // tell physics to finish building actor | ||
1565 | m_sceneGraph.ProcessPhysicsPreSimulation(); | ||
1566 | |||
1557 | m_heartbeatThread | 1567 | m_heartbeatThread |
1558 | = WorkManager.StartThread( | 1568 | = WorkManager.StartThread( |
1559 | Heartbeat, string.Format("Heartbeat-({0})", RegionInfo.RegionName.Replace(" ", "_")), ThreadPriority.Normal, false, false); | 1569 | Heartbeat, string.Format("Heartbeat-({0})", RegionInfo.RegionName.Replace(" ", "_")), ThreadPriority.Normal, false, false); |
@@ -1601,45 +1611,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1601 | 1611 | ||
1602 | Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true; | 1612 | Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true; |
1603 | m_lastFrameTick = Util.EnvironmentTickCount(); | 1613 | m_lastFrameTick = Util.EnvironmentTickCount(); |
1604 | 1614 | Update(-1); | |
1605 | if (UpdateOnTimer) | 1615 | } |
1606 | { | ||
1607 | m_sceneUpdateTimer = new Timer(MinFrameTicks); | ||
1608 | m_sceneUpdateTimer.AutoReset = true; | ||
1609 | m_sceneUpdateTimer.Elapsed += Update; | ||
1610 | m_sceneUpdateTimer.Start(); | ||
1611 | } | ||
1612 | else | ||
1613 | { | ||
1614 | Thread.CurrentThread.Priority = ThreadPriority.Highest; | ||
1615 | Update(-1); | ||
1616 | Watchdog.RemoveThread(); | ||
1617 | m_isRunning = false; | ||
1618 | } | ||
1619 | } | ||
1620 | |||
1621 | private volatile bool m_isTimerUpdateRunning; | ||
1622 | |||
1623 | private void Update(object sender, ElapsedEventArgs e) | ||
1624 | { | ||
1625 | if (m_isTimerUpdateRunning) | ||
1626 | return; | ||
1627 | |||
1628 | m_isTimerUpdateRunning = true; | ||
1629 | |||
1630 | // If the last frame did not complete on time, then immediately start the next update on the same thread | ||
1631 | // and ignore further timed updates until we have a frame that had spare time. | ||
1632 | while (!Update(1) && Active) { } | ||
1633 | |||
1634 | if (!Active || m_shuttingDown) | ||
1635 | { | ||
1636 | m_sceneUpdateTimer.Stop(); | ||
1637 | m_sceneUpdateTimer = null; | ||
1638 | m_isRunning = false; | ||
1639 | } | ||
1640 | |||
1641 | m_isTimerUpdateRunning = false; | ||
1642 | } | ||
1643 | 1616 | ||
1644 | private void Maintenance() | 1617 | private void Maintenance() |
1645 | { | 1618 | { |
@@ -1708,24 +1681,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
1708 | previousMaintenanceTick = m_lastMaintenanceTick; | 1681 | previousMaintenanceTick = m_lastMaintenanceTick; |
1709 | m_lastMaintenanceTick = Util.EnvironmentTickCount(); | 1682 | m_lastMaintenanceTick = Util.EnvironmentTickCount(); |
1710 | runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc); | 1683 | runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc); |
1711 | runtc = MinMaintenanceTicks - runtc; | 1684 | runtc = (int)(MinMaintenanceTime * 1000) - runtc; |
1712 | 1685 | ||
1713 | if (runtc > 0) | 1686 | if (runtc > 0) |
1714 | m_maintenanceWaitEvent.WaitOne(runtc); | 1687 | m_maintenanceWaitEvent.WaitOne(runtc); |
1715 | 1688 | ||
1716 | // Optionally warn if a frame takes double the amount of time that it should. | 1689 | // Optionally warn if a frame takes double the amount of time that it should. |
1717 | if (DebugUpdates | 1690 | if (DebugUpdates |
1718 | && Util.EnvironmentTickCountSubtract( | 1691 | && Util.EnvironmentTickCountSubtract( |
1719 | m_lastMaintenanceTick, previousMaintenanceTick) > MinMaintenanceTicks * 2) | 1692 | m_lastMaintenanceTick, previousMaintenanceTick) > (int)(MinMaintenanceTime * 1000 * 2)) |
1720 | m_log.WarnFormat( | 1693 | m_log.WarnFormat( |
1721 | "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}", | 1694 | "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}", |
1722 | Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick), | 1695 | Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick), |
1723 | MinMaintenanceTicks, | 1696 | MinMaintenanceTime * 1000, |
1724 | RegionInfo.RegionName); | 1697 | RegionInfo.RegionName); |
1725 | } | 1698 | } |
1726 | } | 1699 | } |
1727 | 1700 | ||
1728 | public override bool Update(int frames) | 1701 | public override void Update(int frames) |
1729 | { | 1702 | { |
1730 | long? endFrame = null; | 1703 | long? endFrame = null; |
1731 | 1704 | ||
@@ -1733,119 +1706,78 @@ namespace OpenSim.Region.Framework.Scenes | |||
1733 | endFrame = Frame + frames; | 1706 | endFrame = Frame + frames; |
1734 | 1707 | ||
1735 | float physicsFPS = 0f; | 1708 | float physicsFPS = 0f; |
1736 | int previousFrameTick, tmpMS; | 1709 | float frameTimeMS = FrameTime * 1000.0f; |
1737 | 1710 | ||
1738 | // These variables will be used to save the precise frame time using the | 1711 | int previousFrameTick; |
1739 | // Stopwatch class of Microsoft SDK; the times are recorded at the start | 1712 | |
1740 | // and end of a particular section of code, and then used to calculate | 1713 | double tmpMS; |
1741 | // the frame times, which are the sums of the sections for each given name | 1714 | double tmpMS2; |
1742 | double preciseTotalFrameTime = 0.0; | 1715 | double framestart; |
1743 | double preciseSimFrameTime = 0.0; | 1716 | float sleepMS; |
1744 | double precisePhysicsFrameTime = 0.0; | 1717 | float sleepError = 0; |
1745 | Stopwatch totalFrameStopwatch = new Stopwatch(); | ||
1746 | Stopwatch simFrameStopwatch = new Stopwatch(); | ||
1747 | Stopwatch physicsFrameStopwatch = new Stopwatch(); | ||
1748 | |||
1749 | // Begin the stopwatch to keep track of the time that the frame | ||
1750 | // started running to determine how long the frame took to complete | ||
1751 | totalFrameStopwatch.Start(); | ||
1752 | 1718 | ||
1753 | while (!m_shuttingDown && ((endFrame == null && Active) || Frame < endFrame)) | 1719 | while (!m_shuttingDown && ((endFrame == null && Active) || Frame < endFrame)) |
1754 | { | 1720 | { |
1721 | framestart = Util.GetTimeStampMS(); | ||
1755 | ++Frame; | 1722 | ++Frame; |
1756 | 1723 | ||
1757 | // m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName); | 1724 | // m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName); |
1758 | 1725 | ||
1759 | agentMS = eventMS = backupMS = terrainMS = landMS = spareMS = 0; | 1726 | agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0f; |
1760 | 1727 | ||
1761 | try | 1728 | try |
1762 | { | 1729 | { |
1763 | EventManager.TriggerRegionHeartbeatStart(this); | 1730 | EventManager.TriggerRegionHeartbeatStart(this); |
1764 | 1731 | ||
1765 | // Apply taints in terrain module to terrain in physics scene | 1732 | // Apply taints in terrain module to terrain in physics scene |
1733 | |||
1734 | tmpMS = Util.GetTimeStampMS(); | ||
1735 | |||
1736 | if (Frame % 4 == 0) | ||
1737 | { | ||
1738 | CheckTerrainUpdates(); | ||
1739 | } | ||
1740 | |||
1766 | if (Frame % m_update_terrain == 0) | 1741 | if (Frame % m_update_terrain == 0) |
1767 | { | 1742 | { |
1768 | // At several points inside the code there was a need to | ||
1769 | // create a more precise measurement of time elapsed. | ||
1770 | // This led to the addition of variables that have a | ||
1771 | // similar function and thus remain tightly connected to | ||
1772 | // their original counterparts. However, the original | ||
1773 | // code is not receiving comments from our group because | ||
1774 | // we don't feel right modifying the code to that degree | ||
1775 | // at this point in time, the precise values all begin | ||
1776 | // with the keyword precise | ||
1777 | tmpMS = Util.EnvironmentTickCount(); | ||
1778 | simFrameStopwatch.Start(); | ||
1779 | UpdateTerrain(); | 1743 | UpdateTerrain(); |
1780 | |||
1781 | // Get the simulation frame time that the avatar force | ||
1782 | // input took | ||
1783 | simFrameStopwatch.Stop(); | ||
1784 | preciseSimFrameTime = | ||
1785 | simFrameStopwatch.Elapsed.TotalMilliseconds; | ||
1786 | terrainMS = Util.EnvironmentTickCountSubtract(tmpMS); | ||
1787 | } | 1744 | } |
1788 | 1745 | ||
1789 | // At several points inside the code there was a need to | 1746 | tmpMS2 = Util.GetTimeStampMS(); |
1790 | // create a more precise measurement of time elapsed. This | 1747 | terrainMS = (float)(tmpMS2 - tmpMS); |
1791 | // led to the addition of variables that have a similar | 1748 | tmpMS = tmpMS2; |
1792 | // function and thus remain tightly connected to their | ||
1793 | // original counterparts. However, the original code is | ||
1794 | // not receiving comments from our group because we don't | ||
1795 | // feel right modifying the code to that degree at this | ||
1796 | // point in time, the precise values all begin with the | ||
1797 | // keyword precise | ||
1798 | 1749 | ||
1799 | tmpMS = Util.EnvironmentTickCount(); | ||
1800 | |||
1801 | // Begin the stopwatch to track the time to prepare physics | ||
1802 | physicsFrameStopwatch.Start(); | ||
1803 | if (PhysicsEnabled && Frame % m_update_physics == 0) | 1750 | if (PhysicsEnabled && Frame % m_update_physics == 0) |
1804 | m_sceneGraph.UpdatePreparePhysics(); | 1751 | m_sceneGraph.UpdatePreparePhysics(); |
1805 | 1752 | ||
1806 | // Get the time it took to prepare the physics, this | 1753 | tmpMS2 = Util.GetTimeStampMS(); |
1807 | // would report the most precise time that physics was | 1754 | physicsMS2 = (float)(tmpMS2 - tmpMS); |
1808 | // running on the machine and should the physics not be | 1755 | tmpMS = tmpMS2; |
1809 | // enabled will report the time it took to check if physics | ||
1810 | // was enabled | ||
1811 | physicsFrameStopwatch.Stop(); | ||
1812 | precisePhysicsFrameTime = physicsFrameStopwatch.Elapsed.TotalMilliseconds; | ||
1813 | physicsMS2 = Util.EnvironmentTickCountSubtract(tmpMS); | ||
1814 | 1756 | ||
1815 | // Apply any pending avatar force input to the avatar's velocity | 1757 | // Apply any pending avatar force input to the avatar's velocity |
1816 | tmpMS = Util.EnvironmentTickCount(); | ||
1817 | simFrameStopwatch.Restart(); | ||
1818 | if (Frame % m_update_entitymovement == 0) | 1758 | if (Frame % m_update_entitymovement == 0) |
1819 | m_sceneGraph.UpdateScenePresenceMovement(); | 1759 | m_sceneGraph.UpdateScenePresenceMovement(); |
1820 | 1760 | ||
1821 | // Get the simulation frame time that the avatar force input | 1761 | // Get the simulation frame time that the avatar force input |
1822 | // took | 1762 | // took |
1823 | simFrameStopwatch.Stop(); | 1763 | tmpMS2 = Util.GetTimeStampMS(); |
1824 | preciseSimFrameTime += | 1764 | agentMS = (float)(tmpMS2 - tmpMS); |
1825 | simFrameStopwatch.Elapsed.TotalMilliseconds; | 1765 | tmpMS = tmpMS2; |
1826 | agentMS = Util.EnvironmentTickCountSubtract(tmpMS); | ||
1827 | 1766 | ||
1828 | // Perform the main physics update. This will do the actual work of moving objects and avatars according to their | 1767 | // Perform the main physics update. This will do the actual work of moving objects and avatars according to their |
1829 | // velocity | 1768 | // velocity |
1830 | tmpMS = Util.EnvironmentTickCount(); | ||
1831 | physicsFrameStopwatch.Restart(); | ||
1832 | if (Frame % m_update_physics == 0) | 1769 | if (Frame % m_update_physics == 0) |
1833 | { | 1770 | { |
1834 | if (PhysicsEnabled) | 1771 | if (PhysicsEnabled) |
1835 | physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameSeconds); | 1772 | physicsFPS = m_sceneGraph.UpdatePhysics(FrameTime); |
1836 | 1773 | ||
1837 | if (SynchronizeScene != null) | 1774 | if (SynchronizeScene != null) |
1838 | SynchronizeScene(this); | 1775 | SynchronizeScene(this); |
1839 | } | 1776 | } |
1840 | 1777 | ||
1841 | // Add the main physics update time to the prepare physics time | 1778 | tmpMS2 = Util.GetTimeStampMS(); |
1842 | physicsFrameStopwatch.Stop(); | 1779 | physicsMS = (float)(tmpMS2 - tmpMS); |
1843 | precisePhysicsFrameTime += physicsFrameStopwatch.Elapsed.TotalMilliseconds; | 1780 | tmpMS = tmpMS2; |
1844 | physicsMS = Util.EnvironmentTickCountSubtract(tmpMS); | ||
1845 | |||
1846 | // Start the stopwatch for the remainder of the simulation | ||
1847 | simFrameStopwatch.Restart(); | ||
1848 | tmpMS = Util.EnvironmentTickCount(); | ||
1849 | 1781 | ||
1850 | // Check if any objects have reached their targets | 1782 | // Check if any objects have reached their targets |
1851 | CheckAtTargets(); | 1783 | CheckAtTargets(); |
@@ -1860,20 +1792,36 @@ namespace OpenSim.Region.Framework.Scenes | |||
1860 | if (Frame % m_update_presences == 0) | 1792 | if (Frame % m_update_presences == 0) |
1861 | m_sceneGraph.UpdatePresences(); | 1793 | m_sceneGraph.UpdatePresences(); |
1862 | 1794 | ||
1863 | agentMS += Util.EnvironmentTickCountSubtract(tmpMS); | 1795 | tmpMS2 = Util.GetTimeStampMS(); |
1864 | 1796 | agentMS += (float)(tmpMS2 - tmpMS); | |
1797 | tmpMS = tmpMS2; | ||
1798 | |||
1799 | // Delete temp-on-rez stuff | ||
1800 | if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps) | ||
1801 | { | ||
1802 | m_cleaningTemps = true; | ||
1803 | Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; }); | ||
1804 | tmpMS2 = Util.GetTimeStampMS(); | ||
1805 | tempOnRezMS = (float)(tmpMS2 - tmpMS); // bad.. counts the FireAndForget, not CleanTempObjects | ||
1806 | tmpMS = tmpMS2; | ||
1807 | } | ||
1808 | |||
1865 | if (Frame % m_update_events == 0) | 1809 | if (Frame % m_update_events == 0) |
1866 | { | 1810 | { |
1867 | tmpMS = Util.EnvironmentTickCount(); | ||
1868 | UpdateEvents(); | 1811 | UpdateEvents(); |
1869 | eventMS = Util.EnvironmentTickCountSubtract(tmpMS); | 1812 | |
1813 | tmpMS2 = Util.GetTimeStampMS(); | ||
1814 | eventMS = (float)(tmpMS2 - tmpMS); | ||
1815 | tmpMS = tmpMS2; | ||
1870 | } | 1816 | } |
1871 | 1817 | ||
1872 | if (PeriodicBackup && Frame % m_update_backup == 0) | 1818 | if (PeriodicBackup && Frame % m_update_backup == 0) |
1873 | { | 1819 | { |
1874 | tmpMS = Util.EnvironmentTickCount(); | ||
1875 | UpdateStorageBackup(); | 1820 | UpdateStorageBackup(); |
1876 | backupMS = Util.EnvironmentTickCountSubtract(tmpMS); | 1821 | |
1822 | tmpMS2 = Util.GetTimeStampMS(); | ||
1823 | backupMS = (float)(tmpMS2 - tmpMS); | ||
1824 | tmpMS = tmpMS2; | ||
1877 | } | 1825 | } |
1878 | 1826 | ||
1879 | //if (Frame % m_update_land == 0) | 1827 | //if (Frame % m_update_land == 0) |
@@ -1930,79 +1878,64 @@ namespace OpenSim.Region.Framework.Scenes | |||
1930 | } | 1878 | } |
1931 | 1879 | ||
1932 | EventManager.TriggerRegionHeartbeatEnd(this); | 1880 | EventManager.TriggerRegionHeartbeatEnd(this); |
1933 | otherMS = eventMS + backupMS + terrainMS + landMS; | 1881 | m_firstHeartbeat = false; |
1882 | Watchdog.UpdateThread(); | ||
1934 | 1883 | ||
1935 | // Get the elapsed time for the simulation frame | 1884 | otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS; |
1936 | simFrameStopwatch.Stop(); | ||
1937 | preciseSimFrameTime += | ||
1938 | simFrameStopwatch.Elapsed.TotalMilliseconds; | ||
1939 | 1885 | ||
1940 | if (!UpdateOnTimer) | 1886 | tmpMS = Util.GetTimeStampMS(); |
1941 | { | ||
1942 | Watchdog.UpdateThread(); | ||
1943 | 1887 | ||
1944 | spareMS = MinFrameTicks - Util.EnvironmentTickCountSubtract(m_lastFrameTick); | 1888 | previousFrameTick = m_lastFrameTick; |
1889 | m_lastFrameTick = (int)(tmpMS + 0.5); | ||
1945 | 1890 | ||
1946 | if (spareMS > 0) | 1891 | // estimate sleep time |
1947 | m_updateWaitEvent.WaitOne(spareMS); | 1892 | tmpMS2 = tmpMS - framestart; |
1948 | else | 1893 | tmpMS2 = (double)frameTimeMS - tmpMS2 - sleepError; |
1949 | spareMS = 0; | ||
1950 | } | ||
1951 | else | ||
1952 | { | ||
1953 | spareMS = Math.Max(0, MinFrameTicks - physicsMS2 - agentMS - physicsMS - otherMS); | ||
1954 | } | ||
1955 | 1894 | ||
1956 | // Get the total frame time | 1895 | // reuse frameMS as temporary |
1957 | totalFrameStopwatch.Stop(); | 1896 | frameMS = (float)tmpMS2; |
1958 | preciseTotalFrameTime = | 1897 | |
1959 | totalFrameStopwatch.Elapsed.TotalMilliseconds; | 1898 | // sleep if we can |
1899 | if (tmpMS2 > 0) | ||
1900 | { | ||
1901 | Thread.Sleep((int)(tmpMS2 + 0.5)); | ||
1960 | 1902 | ||
1961 | // Restart the stopwatch for the total time of the next frame | 1903 | tmpMS2 = Util.GetTimeStampMS(); |
1962 | totalFrameStopwatch.Restart(); | 1904 | sleepMS = (float)(tmpMS2 - tmpMS); |
1905 | sleepError = sleepMS - frameMS; | ||
1906 | Util.Clamp(sleepError, 0.0f, 20f); | ||
1907 | frameMS = (float)(tmpMS2 - framestart); | ||
1908 | } | ||
1909 | else | ||
1910 | { | ||
1911 | tmpMS2 = Util.GetTimeStampMS(); | ||
1912 | frameMS = (float)(tmpMS2 - framestart); | ||
1913 | sleepMS = 0.0f; | ||
1914 | sleepError = 0.0f; | ||
1915 | } | ||
1963 | 1916 | ||
1964 | previousFrameTick = m_lastFrameTick; | 1917 | // script time is not scene frame time, but is displayed per frame |
1965 | frameMS = Util.EnvironmentTickCountSubtract(m_lastFrameTick); | 1918 | float scriptTimeMS = GetAndResetScriptExecutionTime(); |
1966 | m_lastFrameTick = Util.EnvironmentTickCount(); | 1919 | StatsReporter.AddFrameStats(TimeDilation, physicsFPS, agentMS, |
1920 | physicsMS + physicsMS2, otherMS , sleepMS, frameMS, scriptTimeMS); | ||
1921 | |||
1922 | |||
1967 | 1923 | ||
1968 | // if (Frame%m_update_avatars == 0) | 1924 | // if (Frame%m_update_avatars == 0) |
1969 | // UpdateInWorldTime(); | 1925 | // UpdateInWorldTime(); |
1970 | StatsReporter.AddPhysicsFPS(physicsFPS); | ||
1971 | StatsReporter.AddTimeDilation(TimeDilation); | ||
1972 | StatsReporter.AddFPS(1); | ||
1973 | |||
1974 | StatsReporter.addFrameMS(frameMS); | ||
1975 | StatsReporter.addAgentMS(agentMS); | ||
1976 | StatsReporter.addPhysicsMS(physicsMS + physicsMS2); | ||
1977 | StatsReporter.addOtherMS(otherMS); | ||
1978 | StatsReporter.AddSpareMS(spareMS); | ||
1979 | StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS()); | ||
1980 | StatsReporter.AddScriptMS((int) GetAndResetScriptExecutionTime()); | ||
1981 | |||
1982 | // Send the correct time values to the stats reporter for the | ||
1983 | // frame times | ||
1984 | StatsReporter.addFrameTimeMilliseconds(preciseTotalFrameTime, | ||
1985 | preciseSimFrameTime, precisePhysicsFrameTime, 0.0); | ||
1986 | |||
1987 | // Send the correct number of frames that the physics library | ||
1988 | // has processed to the stats reporter | ||
1989 | StatsReporter.addPhysicsFrame(1); | ||
1990 | 1926 | ||
1991 | // Optionally warn if a frame takes double the amount of time that it should. | 1927 | // Optionally warn if a frame takes double the amount of time that it should. |
1992 | if (DebugUpdates | 1928 | if (DebugUpdates |
1993 | && Util.EnvironmentTickCountSubtract( | 1929 | && Util.EnvironmentTickCountSubtract( |
1994 | m_lastFrameTick, previousFrameTick) > MinFrameTicks * 2) | 1930 | m_lastFrameTick, previousFrameTick) > (int)(FrameTime * 1000 * 2)) |
1931 | |||
1995 | m_log.WarnFormat( | 1932 | m_log.WarnFormat( |
1996 | "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}", | 1933 | "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}", |
1997 | Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick), | 1934 | Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick), |
1998 | MinFrameTicks, | 1935 | FrameTime * 1000, |
1936 | |||
1999 | RegionInfo.RegionName); | 1937 | RegionInfo.RegionName); |
2000 | } | 1938 | } |
2001 | |||
2002 | // Finished updating scene frame, so stop the total frame's Stopwatch | ||
2003 | totalFrameStopwatch.Stop(); | ||
2004 | |||
2005 | return spareMS >= 0; | ||
2006 | } | 1939 | } |
2007 | 1940 | ||
2008 | /// <summary> | 1941 | /// <summary> |
@@ -2011,24 +1944,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
2011 | /// <param name="ticks">Elapsed Stopwatch ticks</param> | 1944 | /// <param name="ticks">Elapsed Stopwatch ticks</param> |
2012 | public void AddScriptExecutionTime(long ticks) | 1945 | public void AddScriptExecutionTime(long ticks) |
2013 | { | 1946 | { |
1947 | StatsReporter.addScriptEvents(1); | ||
2014 | Interlocked.Add(ref m_scriptExecutionTime, ticks); | 1948 | Interlocked.Add(ref m_scriptExecutionTime, ticks); |
2015 | } | 1949 | } |
2016 | 1950 | ||
2017 | /// <summary> | 1951 | /// <summary> |
2018 | /// Returns the total execution time of all the scripts in the region since the last frame | 1952 | /// Returns the total execution time of all the scripts in the region since the last call |
2019 | /// (in milliseconds), and clears the value in preparation for the next frame. | 1953 | /// (in milliseconds), and clears the value in preparation for the next call. |
2020 | /// </summary> | 1954 | /// </summary> |
2021 | /// <returns>Time in milliseconds</returns> | 1955 | /// <returns>Time in milliseconds</returns> |
2022 | private long GetAndResetScriptExecutionTime() | 1956 | |
1957 | // Warning: this is now called from StatsReporter, and can't be shared | ||
1958 | |||
1959 | public long GetAndResetScriptExecutionTime() | ||
2023 | { | 1960 | { |
2024 | long ticks = Interlocked.Exchange(ref m_scriptExecutionTime, 0); | 1961 | long ticks = Interlocked.Exchange(ref m_scriptExecutionTime, 0); |
2025 | return (ticks * 1000) / Stopwatch.Frequency; | 1962 | return (ticks * 1000L) / Stopwatch.Frequency; |
2026 | } | 1963 | } |
2027 | 1964 | ||
2028 | public void AddGroupTarget(SceneObjectGroup grp) | 1965 | public void AddGroupTarget(SceneObjectGroup grp) |
2029 | { | 1966 | { |
2030 | lock (m_groupsWithTargets) | 1967 | lock (m_groupsWithTargets) |
2031 | m_groupsWithTargets[grp.UUID] = grp; | 1968 | m_groupsWithTargets[grp.UUID] = 0; |
2032 | } | 1969 | } |
2033 | 1970 | ||
2034 | public void RemoveGroupTarget(SceneObjectGroup grp) | 1971 | public void RemoveGroupTarget(SceneObjectGroup grp) |
@@ -2039,18 +1976,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
2039 | 1976 | ||
2040 | private void CheckAtTargets() | 1977 | private void CheckAtTargets() |
2041 | { | 1978 | { |
2042 | List<SceneObjectGroup> objs = null; | 1979 | List<UUID> objs = null; |
2043 | 1980 | ||
2044 | lock (m_groupsWithTargets) | 1981 | lock (m_groupsWithTargets) |
2045 | { | 1982 | { |
2046 | if (m_groupsWithTargets.Count != 0) | 1983 | if (m_groupsWithTargets.Count != 0) |
2047 | objs = new List<SceneObjectGroup>(m_groupsWithTargets.Values); | 1984 | objs = new List<UUID>(m_groupsWithTargets.Keys); |
2048 | } | 1985 | } |
2049 | 1986 | ||
2050 | if (objs != null) | 1987 | if (objs != null) |
2051 | { | 1988 | { |
2052 | foreach (SceneObjectGroup entry in objs) | 1989 | foreach (UUID entry in objs) |
2053 | entry.checkAtTargets(); | 1990 | { |
1991 | SceneObjectGroup grp = GetSceneObjectGroup(entry); | ||
1992 | if (grp == null) | ||
1993 | m_groupsWithTargets.Remove(entry); | ||
1994 | else | ||
1995 | grp.checkAtTargets(); | ||
1996 | } | ||
2054 | } | 1997 | } |
2055 | } | 1998 | } |
2056 | 1999 | ||
@@ -2074,6 +2017,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
2074 | EventManager.TriggerTerrainTick(); | 2017 | EventManager.TriggerTerrainTick(); |
2075 | } | 2018 | } |
2076 | 2019 | ||
2020 | private void CheckTerrainUpdates() | ||
2021 | { | ||
2022 | EventManager.TriggerTerrainCheckUpdates(); | ||
2023 | } | ||
2024 | |||
2077 | /// <summary> | 2025 | /// <summary> |
2078 | /// Back up queued up changes | 2026 | /// Back up queued up changes |
2079 | /// </summary> | 2027 | /// </summary> |
@@ -2125,7 +2073,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2125 | msg.fromAgentName = "Server"; | 2073 | msg.fromAgentName = "Server"; |
2126 | msg.dialog = (byte)19; // Object msg | 2074 | msg.dialog = (byte)19; // Object msg |
2127 | msg.fromGroup = false; | 2075 | msg.fromGroup = false; |
2128 | msg.offline = (byte)0; | 2076 | msg.offline = (byte)1; |
2129 | msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID; | 2077 | msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID; |
2130 | msg.Position = Vector3.Zero; | 2078 | msg.Position = Vector3.Zero; |
2131 | msg.RegionID = RegionInfo.RegionID.Guid; | 2079 | msg.RegionID = RegionInfo.RegionID.Guid; |
@@ -2277,7 +2225,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2277 | //// stored in the GridService, because that's what the world map module uses | 2225 | //// stored in the GridService, because that's what the world map module uses |
2278 | //// to send the map image UUIDs (of other regions) to the viewer... | 2226 | //// to send the map image UUIDs (of other regions) to the viewer... |
2279 | if (m_generateMaptiles) | 2227 | if (m_generateMaptiles) |
2280 | RegenerateMaptile(); | 2228 | RegenerateMaptile(); |
2281 | 2229 | ||
2282 | GridRegion region = new GridRegion(RegionInfo); | 2230 | GridRegion region = new GridRegion(RegionInfo); |
2283 | string error = GridService.RegisterRegion(RegionInfo.ScopeID, region); | 2231 | string error = GridService.RegisterRegion(RegionInfo.ScopeID, region); |
@@ -2361,7 +2309,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2361 | return PhysicsScene.SupportsRaycastWorldFiltered(); | 2309 | return PhysicsScene.SupportsRaycastWorldFiltered(); |
2362 | } | 2310 | } |
2363 | 2311 | ||
2364 | public object RayCastFiltered(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter) | 2312 | public object RayCastFiltered(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter) |
2365 | { | 2313 | { |
2366 | if (PhysicsScene == null) | 2314 | if (PhysicsScene == null) |
2367 | return null; | 2315 | return null; |
@@ -2383,93 +2331,166 @@ namespace OpenSim.Region.Framework.Scenes | |||
2383 | /// <returns></returns> | 2331 | /// <returns></returns> |
2384 | public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter) | 2332 | public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter) |
2385 | { | 2333 | { |
2386 | Vector3 pos = Vector3.Zero; | ||
2387 | if (RayEndIsIntersection == (byte)1) | ||
2388 | { | ||
2389 | pos = RayEnd; | ||
2390 | return pos; | ||
2391 | } | ||
2392 | 2334 | ||
2393 | if (RayTargetID != UUID.Zero) | 2335 | Vector3 dir = RayEnd - RayStart; |
2336 | |||
2337 | float wheight = (float)RegionInfo.RegionSettings.WaterHeight; | ||
2338 | Vector3 wpos = Vector3.Zero; | ||
2339 | // Check for water surface intersection from above | ||
2340 | if ((RayStart.Z > wheight) && (RayEnd.Z < wheight)) | ||
2394 | { | 2341 | { |
2395 | SceneObjectPart target = GetSceneObjectPart(RayTargetID); | 2342 | float ratio = (wheight - RayStart.Z) / dir.Z; |
2343 | wpos.X = RayStart.X + (ratio * dir.X); | ||
2344 | wpos.Y = RayStart.Y + (ratio * dir.Y); | ||
2345 | wpos.Z = wheight; | ||
2346 | } | ||
2396 | 2347 | ||
2397 | Vector3 direction = Vector3.Normalize(RayEnd - RayStart); | 2348 | Vector3 pos = Vector3.Zero; |
2398 | Vector3 AXOrigin = RayStart; | ||
2399 | Vector3 AXdirection = direction; | ||
2400 | 2349 | ||
2401 | if (target != null) | 2350 | if (RayEndIsIntersection != (byte)1) |
2351 | { | ||
2352 | float dist = dir.Length(); | ||
2353 | if (dist != 0) | ||
2402 | { | 2354 | { |
2403 | pos = target.AbsolutePosition; | 2355 | Vector3 direction = dir * (1 / dist); |
2404 | //m_log.Info("[OBJECT_REZ]: TargetPos: " + pos.ToString() + ", RayStart: " + RayStart.ToString() + ", RayEnd: " + RayEnd.ToString() + ", Volume: " + Util.GetDistanceTo(RayStart,RayEnd).ToString() + ", mag1: " + Util.GetMagnitude(RayStart).ToString() + ", mag2: " + Util.GetMagnitude(RayEnd).ToString()); | ||
2405 | 2356 | ||
2406 | // TODO: Raytrace better here | 2357 | dist += 1.0f; |
2407 | 2358 | ||
2408 | //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection)); | 2359 | if (SupportsRayCastFiltered()) |
2409 | Ray NewRay = new Ray(AXOrigin, AXdirection); | 2360 | { |
2361 | RayFilterFlags rayfilter = RayFilterFlags.BackFaceCull; | ||
2362 | rayfilter |= RayFilterFlags.land; | ||
2363 | rayfilter |= RayFilterFlags.physical; | ||
2364 | rayfilter |= RayFilterFlags.nonphysical; | ||
2365 | rayfilter |= RayFilterFlags.LSLPhantom; // ubODE will only see volume detectors | ||
2366 | |||
2367 | // get some more contacts ??? | ||
2368 | int physcount = 4; | ||
2369 | |||
2370 | List<ContactResult> physresults = | ||
2371 | (List<ContactResult>)RayCastFiltered(RayStart, direction, dist, physcount, rayfilter); | ||
2372 | if (physresults != null && physresults.Count > 0) | ||
2373 | { | ||
2374 | // look for terrain ? | ||
2375 | if(RayTargetID == UUID.Zero) | ||
2376 | { | ||
2377 | foreach (ContactResult r in physresults) | ||
2378 | { | ||
2379 | if (r.ConsumerID == 0) | ||
2380 | { | ||
2381 | pos = r.Normal * scale; | ||
2382 | pos *= 0.5f; | ||
2383 | pos = r.Pos + pos; | ||
2384 | |||
2385 | if (wpos.Z > pos.Z) pos = wpos; | ||
2386 | return pos; | ||
2387 | } | ||
2388 | } | ||
2389 | } | ||
2390 | else | ||
2391 | { | ||
2392 | foreach (ContactResult r in physresults) | ||
2393 | { | ||
2394 | SceneObjectPart part = GetSceneObjectPart(r.ConsumerID); | ||
2395 | if (part == null) | ||
2396 | continue; | ||
2397 | if (part.UUID == RayTargetID) | ||
2398 | { | ||
2399 | pos = r.Normal * scale; | ||
2400 | pos *= 0.5f; | ||
2401 | pos = r.Pos + pos; | ||
2402 | |||
2403 | if (wpos.Z > pos.Z) pos = wpos; | ||
2404 | return pos; | ||
2405 | } | ||
2406 | } | ||
2407 | } | ||
2408 | // else the first we got | ||
2409 | pos = physresults[0].Normal * scale; | ||
2410 | pos *= 0.5f; | ||
2411 | pos = physresults[0].Pos + pos; | ||
2412 | |||
2413 | if (wpos.Z > pos.Z) | ||
2414 | pos = wpos; | ||
2415 | return pos; | ||
2416 | } | ||
2410 | 2417 | ||
2411 | // Ray Trace against target here | 2418 | } |
2412 | EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter); | 2419 | if (RayTargetID != UUID.Zero) |
2420 | { | ||
2421 | SceneObjectPart target = GetSceneObjectPart(RayTargetID); | ||
2413 | 2422 | ||
2414 | // Un-comment out the following line to Get Raytrace results printed to the console. | 2423 | Ray NewRay = new Ray(RayStart, direction); |
2415 | // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); | ||
2416 | float ScaleOffset = 0.5f; | ||
2417 | 2424 | ||
2418 | // If we hit something | 2425 | if (target != null) |
2419 | if (ei.HitTF) | 2426 | { |
2420 | { | 2427 | pos = target.AbsolutePosition; |
2421 | Vector3 scaleComponent = ei.AAfaceNormal; | ||
2422 | if (scaleComponent.X != 0) ScaleOffset = scale.X; | ||
2423 | if (scaleComponent.Y != 0) ScaleOffset = scale.Y; | ||
2424 | if (scaleComponent.Z != 0) ScaleOffset = scale.Z; | ||
2425 | ScaleOffset = Math.Abs(ScaleOffset); | ||
2426 | Vector3 intersectionpoint = ei.ipoint; | ||
2427 | Vector3 normal = ei.normal; | ||
2428 | // Set the position to the intersection point | ||
2429 | Vector3 offset = (normal * (ScaleOffset / 2f)); | ||
2430 | pos = (intersectionpoint + offset); | ||
2431 | |||
2432 | //Seems to make no sense to do this as this call is used for rezzing from inventory as well, and with inventory items their size is not always 0.5f | ||
2433 | //And in cases when we weren't rezzing from inventory we were re-adding the 0.25 straight after calling this method | ||
2434 | // Un-offset the prim (it gets offset later by the consumer method) | ||
2435 | //pos.Z -= 0.25F; | ||
2436 | 2428 | ||
2437 | } | 2429 | // Ray Trace against target here |
2430 | EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter); | ||
2438 | 2431 | ||
2439 | return pos; | 2432 | // Un-comment out the following line to Get Raytrace results printed to the console. |
2440 | } | 2433 | // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); |
2441 | else | 2434 | float ScaleOffset = 0.5f; |
2442 | { | ||
2443 | // We don't have a target here, so we're going to raytrace all the objects in the scene. | ||
2444 | 2435 | ||
2445 | EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false); | 2436 | // If we hit something |
2437 | if (ei.HitTF) | ||
2438 | { | ||
2439 | Vector3 scaleComponent = ei.AAfaceNormal; | ||
2440 | if (scaleComponent.X != 0) ScaleOffset = scale.X; | ||
2441 | if (scaleComponent.Y != 0) ScaleOffset = scale.Y; | ||
2442 | if (scaleComponent.Z != 0) ScaleOffset = scale.Z; | ||
2443 | ScaleOffset = Math.Abs(ScaleOffset); | ||
2444 | Vector3 intersectionpoint = ei.ipoint; | ||
2445 | Vector3 normal = ei.normal; | ||
2446 | // Set the position to the intersection point | ||
2447 | Vector3 offset = (normal * (ScaleOffset / 2f)); | ||
2448 | pos = (intersectionpoint + offset); | ||
2449 | |||
2450 | //Seems to make no sense to do this as this call is used for rezzing from inventory as well, and with inventory items their size is not always 0.5f | ||
2451 | //And in cases when we weren't rezzing from inventory we were re-adding the 0.25 straight after calling this method | ||
2452 | // Un-offset the prim (it gets offset later by the consumer method) | ||
2453 | //pos.Z -= 0.25F; | ||
2454 | |||
2455 | if (wpos.Z > pos.Z) pos = wpos; | ||
2456 | return pos; | ||
2457 | } | ||
2458 | } | ||
2459 | else | ||
2460 | { | ||
2461 | // We don't have a target here, so we're going to raytrace all the objects in the scene. | ||
2462 | EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(NewRay, true, false); | ||
2446 | 2463 | ||
2447 | // Un-comment the following line to print the raytrace results to the console. | 2464 | // Un-comment the following line to print the raytrace results to the console. |
2448 | //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); | 2465 | //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); |
2449 | 2466 | ||
2450 | if (ei.HitTF) | 2467 | if (ei.HitTF) |
2451 | { | 2468 | { |
2452 | pos = ei.ipoint; | 2469 | pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); |
2453 | } | 2470 | } |
2454 | else | 2471 | else |
2455 | { | 2472 | { |
2456 | // fall back to our stupid functionality | 2473 | // fall back to our stupid functionality |
2457 | pos = RayEnd; | 2474 | pos = RayEnd; |
2458 | } | 2475 | } |
2459 | 2476 | ||
2460 | return pos; | 2477 | if (wpos.Z > pos.Z) pos = wpos; |
2478 | return pos; | ||
2479 | } | ||
2480 | } | ||
2461 | } | 2481 | } |
2462 | } | 2482 | } |
2463 | else | ||
2464 | { | ||
2465 | // fall back to our stupid functionality | ||
2466 | pos = RayEnd; | ||
2467 | 2483 | ||
2468 | //increase height so its above the ground. | 2484 | // fall back to our stupid functionality |
2469 | //should be getting the normal of the ground at the rez point and using that? | 2485 | pos = RayEnd; |
2470 | pos.Z += scale.Z / 2f; | 2486 | |
2471 | return pos; | 2487 | //increase height so its above the ground. |
2472 | } | 2488 | //should be getting the normal of the ground at the rez point and using that? |
2489 | pos.Z += scale.Z / 2f; | ||
2490 | // return pos; | ||
2491 | // check against posible water intercept | ||
2492 | if (wpos.Z > pos.Z) pos = wpos; | ||
2493 | return pos; | ||
2473 | } | 2494 | } |
2474 | 2495 | ||
2475 | 2496 | ||
@@ -2560,12 +2581,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2560 | { | 2581 | { |
2561 | if (m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates)) | 2582 | if (m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates)) |
2562 | { | 2583 | { |
2584 | sceneObject.IsDeleted = false; | ||
2563 | EventManager.TriggerObjectAddedToScene(sceneObject); | 2585 | EventManager.TriggerObjectAddedToScene(sceneObject); |
2564 | return true; | 2586 | return true; |
2565 | } | 2587 | } |
2566 | 2588 | ||
2567 | return false; | 2589 | return false; |
2568 | |||
2569 | } | 2590 | } |
2570 | 2591 | ||
2571 | /// <summary> | 2592 | /// <summary> |
@@ -2657,6 +2678,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
2657 | /// </summary> | 2678 | /// </summary> |
2658 | public void DeleteAllSceneObjects() | 2679 | public void DeleteAllSceneObjects() |
2659 | { | 2680 | { |
2681 | DeleteAllSceneObjects(false); | ||
2682 | } | ||
2683 | |||
2684 | /// <summary> | ||
2685 | /// Delete every object from the scene. This does not include attachments worn by avatars. | ||
2686 | /// </summary> | ||
2687 | public void DeleteAllSceneObjects(bool exceptNoCopy) | ||
2688 | { | ||
2689 | List<SceneObjectGroup> toReturn = new List<SceneObjectGroup>(); | ||
2660 | lock (Entities) | 2690 | lock (Entities) |
2661 | { | 2691 | { |
2662 | EntityBase[] entities = Entities.GetEntities(); | 2692 | EntityBase[] entities = Entities.GetEntities(); |
@@ -2665,11 +2695,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
2665 | if (e is SceneObjectGroup) | 2695 | if (e is SceneObjectGroup) |
2666 | { | 2696 | { |
2667 | SceneObjectGroup sog = (SceneObjectGroup)e; | 2697 | SceneObjectGroup sog = (SceneObjectGroup)e; |
2668 | if (!sog.IsAttachment) | 2698 | if (sog != null && !sog.IsAttachment) |
2669 | DeleteSceneObject((SceneObjectGroup)e, false); | 2699 | { |
2700 | if (!exceptNoCopy || ((sog.GetEffectivePermissions() & (uint)PermissionMask.Copy) != 0)) | ||
2701 | { | ||
2702 | DeleteSceneObject((SceneObjectGroup)e, false); | ||
2703 | } | ||
2704 | else | ||
2705 | { | ||
2706 | toReturn.Add((SceneObjectGroup)e); | ||
2707 | } | ||
2708 | } | ||
2670 | } | 2709 | } |
2671 | } | 2710 | } |
2672 | } | 2711 | } |
2712 | if (toReturn.Count > 0) | ||
2713 | { | ||
2714 | returnObjects(toReturn.ToArray(), UUID.Zero); | ||
2715 | } | ||
2673 | } | 2716 | } |
2674 | 2717 | ||
2675 | /// <summary> | 2718 | /// <summary> |
@@ -2700,6 +2743,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2700 | else | 2743 | else |
2701 | group.StopScriptInstances(); | 2744 | group.StopScriptInstances(); |
2702 | 2745 | ||
2746 | List<ScenePresence> avatars = group.GetSittingAvatars(); | ||
2747 | foreach (ScenePresence av in avatars) | ||
2748 | { | ||
2749 | if(av.ParentUUID == UUID.Zero) | ||
2750 | av.StandUp(); | ||
2751 | } | ||
2752 | |||
2703 | SceneObjectPart[] partList = group.Parts; | 2753 | SceneObjectPart[] partList = group.Parts; |
2704 | 2754 | ||
2705 | foreach (SceneObjectPart part in partList) | 2755 | foreach (SceneObjectPart part in partList) |
@@ -2727,6 +2777,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2727 | } | 2777 | } |
2728 | 2778 | ||
2729 | group.DeleteGroupFromScene(silent); | 2779 | group.DeleteGroupFromScene(silent); |
2780 | if (!silent) | ||
2781 | SendKillObject(new List<uint>() { group.LocalId }); | ||
2730 | 2782 | ||
2731 | // m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); | 2783 | // m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); |
2732 | } | 2784 | } |
@@ -2763,6 +2815,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2763 | return false; | 2815 | return false; |
2764 | } | 2816 | } |
2765 | 2817 | ||
2818 | |||
2819 | public void updateScenePartGroup(SceneObjectPart part, SceneObjectGroup grp) | ||
2820 | { | ||
2821 | m_sceneGraph.updateScenePartGroup(part, grp); | ||
2822 | } | ||
2823 | |||
2824 | /* not in use, outdate by async method | ||
2766 | /// <summary> | 2825 | /// <summary> |
2767 | /// Move the given scene object into a new region depending on which region its absolute position has moved | 2826 | /// Move the given scene object into a new region depending on which region its absolute position has moved |
2768 | /// into. | 2827 | /// into. |
@@ -2811,6 +2870,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2811 | if (EntityTransferModule != null) | 2870 | if (EntityTransferModule != null) |
2812 | EntityTransferModule.Cross(grp, attemptedPosition, silent); | 2871 | EntityTransferModule.Cross(grp, attemptedPosition, silent); |
2813 | } | 2872 | } |
2873 | */ | ||
2814 | 2874 | ||
2815 | // Simple test to see if a position is in the current region. | 2875 | // Simple test to see if a position is in the current region. |
2816 | // This test is mostly used to see if a region crossing is necessary. | 2876 | // This test is mostly used to see if a region crossing is necessary. |
@@ -2828,7 +2888,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2828 | if (regionCombinerModule == null) | 2888 | if (regionCombinerModule == null) |
2829 | { | 2889 | { |
2830 | // Regular region. Just check for region size | 2890 | // Regular region. Just check for region size |
2831 | if (xx < RegionInfo.RegionSizeX && yy < RegionInfo.RegionSizeY) | 2891 | if (xx < RegionInfo.RegionSizeX && yy < RegionInfo.RegionSizeY ) |
2832 | ret = true; | 2892 | ret = true; |
2833 | } | 2893 | } |
2834 | else | 2894 | else |
@@ -2836,9 +2896,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2836 | // We're in a mega-region so see if we are still in that larger region | 2896 | // We're in a mega-region so see if we are still in that larger region |
2837 | ret = regionCombinerModule.PositionIsInMegaregion(this.RegionInfo.RegionID, xx, yy); | 2897 | ret = regionCombinerModule.PositionIsInMegaregion(this.RegionInfo.RegionID, xx, yy); |
2838 | } | 2898 | } |
2839 | |||
2840 | return ret; | 2899 | return ret; |
2841 | |||
2842 | } | 2900 | } |
2843 | 2901 | ||
2844 | /// <summary> | 2902 | /// <summary> |
@@ -2862,8 +2920,52 @@ namespace OpenSim.Region.Framework.Scenes | |||
2862 | return false; | 2920 | return false; |
2863 | } | 2921 | } |
2864 | 2922 | ||
2865 | if (!EntityTransferModule.HandleIncomingSceneObject(newObject, newPosition)) | 2923 | // If the user is banned, we won't let any of their objects |
2924 | // enter. Period. | ||
2925 | // | ||
2926 | if (RegionInfo.EstateSettings.IsBanned(newObject.OwnerID, 36)) | ||
2927 | { | ||
2928 | m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", newObject.OwnerID); | ||
2866 | return false; | 2929 | return false; |
2930 | } | ||
2931 | |||
2932 | if (newPosition != Vector3.Zero) | ||
2933 | newObject.RootPart.GroupPosition = newPosition; | ||
2934 | |||
2935 | if (!AddSceneObject(newObject)) | ||
2936 | { | ||
2937 | m_log.DebugFormat( | ||
2938 | "[INTERREGION]: Problem adding scene object {0} in {1} ", newObject.UUID, RegionInfo.RegionName); | ||
2939 | return false; | ||
2940 | } | ||
2941 | |||
2942 | if (!newObject.IsAttachment) | ||
2943 | { | ||
2944 | // FIXME: It would be better to never add the scene object at all rather than add it and then delete | ||
2945 | // it | ||
2946 | if (!Permissions.CanObjectEntry(newObject.UUID, true, newObject.AbsolutePosition)) | ||
2947 | { | ||
2948 | // Deny non attachments based on parcel settings | ||
2949 | // | ||
2950 | m_log.Info("[INTERREGION]: Denied prim crossing because of parcel settings"); | ||
2951 | |||
2952 | DeleteSceneObject(newObject, false); | ||
2953 | |||
2954 | return false; | ||
2955 | } | ||
2956 | |||
2957 | // For attachments, we need to wait until the agent is root | ||
2958 | // before we restart the scripts, or else some functions won't work. | ||
2959 | newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); | ||
2960 | newObject.ResumeScripts(); | ||
2961 | |||
2962 | // AddSceneObject already does this and doing it again messes | ||
2963 | // up region crossings, so don't. | ||
2964 | //if (newObject.RootPart.KeyframeMotion != null) | ||
2965 | // newObject.RootPart.KeyframeMotion.UpdateSceneObject(newObject); | ||
2966 | } | ||
2967 | |||
2968 | |||
2867 | 2969 | ||
2868 | // Do this as late as possible so that listeners have full access to the incoming object | 2970 | // Do this as late as possible so that listeners have full access to the incoming object |
2869 | EventManager.TriggerOnIncomingSceneObject(newObject); | 2971 | EventManager.TriggerOnIncomingSceneObject(newObject); |
@@ -2880,6 +2982,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
2880 | /// <returns>True if the SceneObjectGroup was added, False if it was not</returns> | 2982 | /// <returns>True if the SceneObjectGroup was added, False if it was not</returns> |
2881 | public bool AddSceneObject(SceneObjectGroup sceneObject) | 2983 | public bool AddSceneObject(SceneObjectGroup sceneObject) |
2882 | { | 2984 | { |
2985 | if (sceneObject.OwnerID == UUID.Zero) | ||
2986 | { | ||
2987 | m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero", sceneObject.UUID); | ||
2988 | return false; | ||
2989 | } | ||
2990 | |||
2991 | // If the user is banned, we won't let any of their objects | ||
2992 | // enter. Period. | ||
2993 | // | ||
2994 | int flags = GetUserFlags(sceneObject.OwnerID); | ||
2995 | if (RegionInfo.EstateSettings.IsBanned(sceneObject.OwnerID, flags)) | ||
2996 | { | ||
2997 | m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", sceneObject.OwnerID); | ||
2998 | |||
2999 | return false; | ||
3000 | } | ||
3001 | |||
2883 | // Force allocation of new LocalId | 3002 | // Force allocation of new LocalId |
2884 | // | 3003 | // |
2885 | SceneObjectPart[] parts = sceneObject.Parts; | 3004 | SceneObjectPart[] parts = sceneObject.Parts; |
@@ -2916,22 +3035,62 @@ namespace OpenSim.Region.Framework.Scenes | |||
2916 | // information that this is due to a teleport/border cross rather than an ordinary attachment. | 3035 | // information that this is due to a teleport/border cross rather than an ordinary attachment. |
2917 | // We currently do this in Scene.MakeRootAgent() instead. | 3036 | // We currently do this in Scene.MakeRootAgent() instead. |
2918 | if (AttachmentsModule != null) | 3037 | if (AttachmentsModule != null) |
2919 | AttachmentsModule.AttachObject(sp, grp, 0, false, false, true); | 3038 | AttachmentsModule.AttachObject(sp, grp, 0, false, false, false, true); |
2920 | } | 3039 | } |
2921 | else | 3040 | else |
2922 | { | 3041 | { |
3042 | m_log.DebugFormat("[SCENE]: Attachment {0} arrived and scene presence was not found, setting to temp", sceneObject.UUID); | ||
2923 | RootPrim.RemFlag(PrimFlags.TemporaryOnRez); | 3043 | RootPrim.RemFlag(PrimFlags.TemporaryOnRez); |
2924 | RootPrim.AddFlag(PrimFlags.TemporaryOnRez); | 3044 | RootPrim.AddFlag(PrimFlags.TemporaryOnRez); |
2925 | } | 3045 | } |
3046 | if (sceneObject.OwnerID == UUID.Zero) | ||
3047 | { | ||
3048 | m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero after attachment processing. BUG!", sceneObject.UUID); | ||
3049 | return false; | ||
3050 | } | ||
2926 | } | 3051 | } |
2927 | else | 3052 | else |
2928 | { | 3053 | { |
3054 | if (sceneObject.OwnerID == UUID.Zero) | ||
3055 | { | ||
3056 | m_log.ErrorFormat("[SCENE]: Owner ID for non-attachment {0} was zero", sceneObject.UUID); | ||
3057 | return false; | ||
3058 | } | ||
2929 | AddRestoredSceneObject(sceneObject, true, false); | 3059 | AddRestoredSceneObject(sceneObject, true, false); |
2930 | } | 3060 | } |
2931 | 3061 | ||
2932 | return true; | 3062 | return true; |
2933 | } | 3063 | } |
2934 | 3064 | ||
3065 | private int GetStateSource(SceneObjectGroup sog) | ||
3066 | { | ||
3067 | ScenePresence sp = GetScenePresence(sog.OwnerID); | ||
3068 | |||
3069 | if (sp != null) | ||
3070 | return sp.GetStateSource(); | ||
3071 | |||
3072 | return 2; // StateSource.PrimCrossing | ||
3073 | } | ||
3074 | |||
3075 | public int GetUserFlags(UUID user) | ||
3076 | { | ||
3077 | //Unfortunately the SP approach means that the value is cached until region is restarted | ||
3078 | /* | ||
3079 | ScenePresence sp; | ||
3080 | if (TryGetScenePresence(user, out sp)) | ||
3081 | { | ||
3082 | return sp.UserFlags; | ||
3083 | } | ||
3084 | else | ||
3085 | { | ||
3086 | */ | ||
3087 | UserAccount uac = UserAccountService.GetUserAccount(RegionInfo.ScopeID, user); | ||
3088 | if (uac == null) | ||
3089 | return 0; | ||
3090 | return uac.UserFlags; | ||
3091 | //} | ||
3092 | } | ||
3093 | |||
2935 | #endregion | 3094 | #endregion |
2936 | 3095 | ||
2937 | #region Add/Remove Avatar Methods | 3096 | #region Add/Remove Avatar Methods |
@@ -2967,8 +3126,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2967 | vialogin | 3126 | vialogin |
2968 | = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 | 3127 | = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 |
2969 | || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; | 3128 | || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; |
2970 | 3129 | ||
2971 | // CheckHeartbeat(); | 3130 | CheckHeartbeat(); |
3131 | |||
2972 | 3132 | ||
2973 | sp = GetScenePresence(client.AgentId); | 3133 | sp = GetScenePresence(client.AgentId); |
2974 | 3134 | ||
@@ -2979,27 +3139,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
2979 | if (sp == null) | 3139 | if (sp == null) |
2980 | { | 3140 | { |
2981 | m_log.DebugFormat( | 3141 | m_log.DebugFormat( |
2982 | "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", | 3142 | "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}, tpflags: {4}", |
2983 | client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); | 3143 | client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos, |
2984 | 3144 | ((TPFlags)aCircuit.teleportFlags).ToString()); | |
2985 | sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type); | 3145 | |
2986 | |||
2987 | // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the | ||
2988 | // client is for a root or child agent. | ||
2989 | // We must also set this before adding the client to the client manager so that an exception later on | ||
2990 | // does not leave a client manager entry without the scene agent set, which will cause other code | ||
2991 | // to fail since any entry in the client manager should have a ScenePresence | ||
2992 | // | ||
2993 | // XXX: This may be better set for a new client before that client is added to the client manager. | ||
2994 | // But need to know what happens in the case where a ScenePresence is already present (and if this | ||
2995 | // actually occurs). | ||
2996 | client.SceneAgent = sp; | ||
2997 | |||
2998 | m_clientManager.Add(client); | 3146 | m_clientManager.Add(client); |
2999 | SubscribeToClientEvents(client); | 3147 | SubscribeToClientEvents(client); |
3000 | m_eventManager.TriggerOnNewPresence(sp); | 3148 | |
3149 | sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type); | ||
3001 | 3150 | ||
3002 | sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags; | 3151 | sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags; |
3152 | |||
3153 | /* done in completMovement | ||
3154 | InventoryFolderBase cof = InventoryService.GetFolderForType(client.AgentId, (AssetType)46); | ||
3155 | if (cof == null) | ||
3156 | sp.COF = UUID.Zero; | ||
3157 | else | ||
3158 | sp.COF = cof.ID; | ||
3159 | |||
3160 | m_log.DebugFormat("[SCENE]: COF for {0} is {1}", client.AgentId, sp.COF); | ||
3161 | */ | ||
3162 | m_eventManager.TriggerOnNewPresence(sp); | ||
3003 | } | 3163 | } |
3004 | else | 3164 | else |
3005 | { | 3165 | { |
@@ -3008,7 +3168,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3008 | // XXX: This may be better set for a new client before that client is added to the client manager. | 3168 | // XXX: This may be better set for a new client before that client is added to the client manager. |
3009 | // But need to know what happens in the case where a ScenePresence is already present (and if this | 3169 | // But need to know what happens in the case where a ScenePresence is already present (and if this |
3010 | // actually occurs). | 3170 | // actually occurs). |
3011 | client.SceneAgent = sp; | 3171 | |
3012 | 3172 | ||
3013 | m_log.WarnFormat( | 3173 | m_log.WarnFormat( |
3014 | "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", | 3174 | "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", |
@@ -3016,6 +3176,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3016 | 3176 | ||
3017 | reallyNew = false; | 3177 | reallyNew = false; |
3018 | } | 3178 | } |
3179 | client.SceneAgent = sp; | ||
3019 | 3180 | ||
3020 | // This is currently also being done earlier in NewUserConnection for real users to see if this | 3181 | // This is currently also being done earlier in NewUserConnection for real users to see if this |
3021 | // resolves problems where HG agents are occasionally seen by others as "Unknown user" in chat and other | 3182 | // resolves problems where HG agents are occasionally seen by others as "Unknown user" in chat and other |
@@ -3134,19 +3295,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
3134 | // and the scene presence and the client, if they exist | 3295 | // and the scene presence and the client, if they exist |
3135 | try | 3296 | try |
3136 | { | 3297 | { |
3137 | // We need to wait for the client to make UDP contact first. | ||
3138 | // It's the UDP contact that creates the scene presence | ||
3139 | ScenePresence sp = WaitGetScenePresence(agentID); | 3298 | ScenePresence sp = WaitGetScenePresence(agentID); |
3299 | |||
3140 | if (sp != null) | 3300 | if (sp != null) |
3141 | { | 3301 | { |
3142 | PresenceService.LogoutAgent(sp.ControllingClient.SessionId); | 3302 | PresenceService.LogoutAgent(sp.ControllingClient.SessionId); |
3143 | 3303 | ||
3144 | CloseAgent(sp.UUID, false); | 3304 | CloseAgent(sp.UUID, false); |
3145 | } | 3305 | } |
3146 | else | 3306 | |
3147 | { | ||
3148 | m_log.WarnFormat("[SCENE]: Could not find scene presence for {0}", agentID); | ||
3149 | } | ||
3150 | // BANG! SLASH! | 3307 | // BANG! SLASH! |
3151 | m_authenticateHandler.RemoveCircuit(agentID); | 3308 | m_authenticateHandler.RemoveCircuit(agentID); |
3152 | 3309 | ||
@@ -3183,7 +3340,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3183 | 3340 | ||
3184 | public virtual void SubscribeToClientTerrainEvents(IClientAPI client) | 3341 | public virtual void SubscribeToClientTerrainEvents(IClientAPI client) |
3185 | { | 3342 | { |
3186 | client.OnRegionHandShakeReply += SendLayerData; | 3343 | // client.OnRegionHandShakeReply += SendLayerData; |
3187 | } | 3344 | } |
3188 | 3345 | ||
3189 | public virtual void SubscribeToClientPrimEvents(IClientAPI client) | 3346 | public virtual void SubscribeToClientPrimEvents(IClientAPI client) |
@@ -3191,6 +3348,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3191 | client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimGroupPosition; | 3348 | client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimGroupPosition; |
3192 | client.OnUpdatePrimSinglePosition += m_sceneGraph.UpdatePrimSinglePosition; | 3349 | client.OnUpdatePrimSinglePosition += m_sceneGraph.UpdatePrimSinglePosition; |
3193 | 3350 | ||
3351 | client.onClientChangeObject += m_sceneGraph.ClientChangeObject; | ||
3352 | |||
3194 | client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimGroupRotation; | 3353 | client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimGroupRotation; |
3195 | client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimGroupRotation; | 3354 | client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimGroupRotation; |
3196 | client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation; | 3355 | client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation; |
@@ -3247,6 +3406,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3247 | client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory; | 3406 | client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory; |
3248 | client.OnUpdateInventoryItem += UpdateInventoryItemAsset; | 3407 | client.OnUpdateInventoryItem += UpdateInventoryItemAsset; |
3249 | client.OnCopyInventoryItem += CopyInventoryItem; | 3408 | client.OnCopyInventoryItem += CopyInventoryItem; |
3409 | client.OnMoveItemsAndLeaveCopy += MoveInventoryItemsLeaveCopy; | ||
3250 | client.OnMoveInventoryItem += MoveInventoryItem; | 3410 | client.OnMoveInventoryItem += MoveInventoryItem; |
3251 | client.OnRemoveInventoryItem += RemoveInventoryItem; | 3411 | client.OnRemoveInventoryItem += RemoveInventoryItem; |
3252 | client.OnRemoveInventoryFolder += RemoveInventoryFolder; | 3412 | client.OnRemoveInventoryFolder += RemoveInventoryFolder; |
@@ -3308,7 +3468,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3308 | 3468 | ||
3309 | public virtual void UnSubscribeToClientTerrainEvents(IClientAPI client) | 3469 | public virtual void UnSubscribeToClientTerrainEvents(IClientAPI client) |
3310 | { | 3470 | { |
3311 | client.OnRegionHandShakeReply -= SendLayerData; | 3471 | // client.OnRegionHandShakeReply -= SendLayerData; |
3312 | } | 3472 | } |
3313 | 3473 | ||
3314 | public virtual void UnSubscribeToClientPrimEvents(IClientAPI client) | 3474 | public virtual void UnSubscribeToClientPrimEvents(IClientAPI client) |
@@ -3316,6 +3476,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3316 | client.OnUpdatePrimGroupPosition -= m_sceneGraph.UpdatePrimGroupPosition; | 3476 | client.OnUpdatePrimGroupPosition -= m_sceneGraph.UpdatePrimGroupPosition; |
3317 | client.OnUpdatePrimSinglePosition -= m_sceneGraph.UpdatePrimSinglePosition; | 3477 | client.OnUpdatePrimSinglePosition -= m_sceneGraph.UpdatePrimSinglePosition; |
3318 | 3478 | ||
3479 | client.onClientChangeObject -= m_sceneGraph.ClientChangeObject; | ||
3480 | |||
3319 | client.OnUpdatePrimGroupRotation -= m_sceneGraph.UpdatePrimGroupRotation; | 3481 | client.OnUpdatePrimGroupRotation -= m_sceneGraph.UpdatePrimGroupRotation; |
3320 | client.OnUpdatePrimGroupMouseRotation -= m_sceneGraph.UpdatePrimGroupRotation; | 3482 | client.OnUpdatePrimGroupMouseRotation -= m_sceneGraph.UpdatePrimGroupRotation; |
3321 | client.OnUpdatePrimSingleRotation -= m_sceneGraph.UpdatePrimSingleRotation; | 3483 | client.OnUpdatePrimSingleRotation -= m_sceneGraph.UpdatePrimSingleRotation; |
@@ -3473,16 +3635,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
3473 | if (target != null && target2 != null) | 3635 | if (target != null && target2 != null) |
3474 | { | 3636 | { |
3475 | Vector3 direction = Vector3.Normalize(RayEnd - RayStart); | 3637 | Vector3 direction = Vector3.Normalize(RayEnd - RayStart); |
3476 | Vector3 AXOrigin = RayStart; | 3638 | |
3477 | Vector3 AXdirection = direction; | ||
3478 | |||
3479 | pos = target2.AbsolutePosition; | 3639 | pos = target2.AbsolutePosition; |
3480 | //m_log.Info("[OBJECT_REZ]: TargetPos: " + pos.ToString() + ", RayStart: " + RayStart.ToString() + ", RayEnd: " + RayEnd.ToString() + ", Volume: " + Util.GetDistanceTo(RayStart,RayEnd).ToString() + ", mag1: " + Util.GetMagnitude(RayStart).ToString() + ", mag2: " + Util.GetMagnitude(RayEnd).ToString()); | 3640 | //m_log.Info("[OBJECT_REZ]: TargetPos: " + pos.ToString() + ", RayStart: " + RayStart.ToString() + ", RayEnd: " + RayEnd.ToString() + ", Volume: " + Util.GetDistanceTo(RayStart,RayEnd).ToString() + ", mag1: " + Util.GetMagnitude(RayStart).ToString() + ", mag2: " + Util.GetMagnitude(RayEnd).ToString()); |
3481 | 3641 | ||
3482 | // TODO: Raytrace better here | 3642 | // TODO: Raytrace better here |
3483 | 3643 | ||
3484 | //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection)); | 3644 | //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection)); |
3485 | Ray NewRay = new Ray(AXOrigin, AXdirection); | 3645 | Ray NewRay = new Ray(RayStart,direction); |
3486 | 3646 | ||
3487 | // Ray Trace against target here | 3647 | // Ray Trace against target here |
3488 | EntityIntersection ei = target2.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, CopyCenters); | 3648 | EntityIntersection ei = target2.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, CopyCenters); |
@@ -3564,6 +3724,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3564 | /// <param name='closeChildAgents'> | 3724 | /// <param name='closeChildAgents'> |
3565 | /// Close the neighbour child agents associated with this client. | 3725 | /// Close the neighbour child agents associated with this client. |
3566 | /// </param> | 3726 | /// </param> |
3727 | /// | ||
3728 | |||
3729 | private object m_removeClientPrivLock = new Object(); | ||
3730 | |||
3567 | public void RemoveClient(UUID agentID, bool closeChildAgents) | 3731 | public void RemoveClient(UUID agentID, bool closeChildAgents) |
3568 | { | 3732 | { |
3569 | AgentCircuitData acd = m_authenticateHandler.GetAgentCircuitData(agentID); | 3733 | AgentCircuitData acd = m_authenticateHandler.GetAgentCircuitData(agentID); |
@@ -3580,8 +3744,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3580 | } | 3744 | } |
3581 | 3745 | ||
3582 | // TODO: Can we now remove this lock? | 3746 | // TODO: Can we now remove this lock? |
3583 | lock (acd) | 3747 | lock (m_removeClientPrivLock) |
3584 | { | 3748 | { |
3585 | bool isChildAgent = false; | 3749 | bool isChildAgent = false; |
3586 | 3750 | ||
3587 | ScenePresence avatar = GetScenePresence(agentID); | 3751 | ScenePresence avatar = GetScenePresence(agentID); |
@@ -3625,8 +3789,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3625 | // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop | 3789 | // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop |
3626 | // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI | 3790 | // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI |
3627 | if (closeChildAgents && CapsModule != null) | 3791 | if (closeChildAgents && CapsModule != null) |
3628 | CapsModule.RemoveCaps(agentID); | 3792 | CapsModule.RemoveCaps(agentID, avatar.ControllingClient.CircuitCode); |
3629 | 3793 | ||
3630 | if (closeChildAgents && !isChildAgent) | 3794 | if (closeChildAgents && !isChildAgent) |
3631 | { | 3795 | { |
3632 | List<ulong> regions = avatar.KnownRegionHandles; | 3796 | List<ulong> regions = avatar.KnownRegionHandles; |
@@ -3637,13 +3801,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
3637 | } | 3801 | } |
3638 | 3802 | ||
3639 | m_eventManager.TriggerClientClosed(agentID, this); | 3803 | m_eventManager.TriggerClientClosed(agentID, this); |
3804 | // m_log.Debug("[Scene]TriggerClientClosed done"); | ||
3640 | m_eventManager.TriggerOnRemovePresence(agentID); | 3805 | m_eventManager.TriggerOnRemovePresence(agentID); |
3641 | 3806 | // m_log.Debug("[Scene]TriggerOnRemovePresence done"); | |
3807 | |||
3642 | if (!isChildAgent) | 3808 | if (!isChildAgent) |
3643 | { | 3809 | { |
3644 | if (AttachmentsModule != null) | 3810 | if (AttachmentsModule != null) |
3645 | { | 3811 | { |
3812 | // m_log.Debug("[Scene]DeRezAttachments"); | ||
3646 | AttachmentsModule.DeRezAttachments(avatar); | 3813 | AttachmentsModule.DeRezAttachments(avatar); |
3814 | // m_log.Debug("[Scene]DeRezAttachments done"); | ||
3647 | } | 3815 | } |
3648 | 3816 | ||
3649 | ForEachClient( | 3817 | ForEachClient( |
@@ -3657,7 +3825,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
3657 | 3825 | ||
3658 | // It's possible for child agents to have transactions if changes are being made cross-border. | 3826 | // It's possible for child agents to have transactions if changes are being made cross-border. |
3659 | if (AgentTransactionsModule != null) | 3827 | if (AgentTransactionsModule != null) |
3828 | { | ||
3829 | // m_log.Debug("[Scene]RemoveAgentAssetTransactions"); | ||
3660 | AgentTransactionsModule.RemoveAgentAssetTransactions(agentID); | 3830 | AgentTransactionsModule.RemoveAgentAssetTransactions(agentID); |
3831 | } | ||
3832 | m_log.Debug("[Scene] The avatar has left the building"); | ||
3661 | } | 3833 | } |
3662 | catch (Exception e) | 3834 | catch (Exception e) |
3663 | { | 3835 | { |
@@ -3776,6 +3948,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
3776 | /// or other applications where a full grid/Hypergrid presence may not be required.</param> | 3948 | /// or other applications where a full grid/Hypergrid presence may not be required.</param> |
3777 | /// <returns>True if the region accepts this agent. False if it does not. False will | 3949 | /// <returns>True if the region accepts this agent. False if it does not. False will |
3778 | /// also return a reason.</returns> | 3950 | /// also return a reason.</returns> |
3951 | /// | ||
3952 | private object m_newUserConnLock = new object(); | ||
3953 | |||
3779 | public bool NewUserConnection(AgentCircuitData acd, uint teleportFlags, GridRegion source, out string reason, bool requirePresenceLookup) | 3954 | public bool NewUserConnection(AgentCircuitData acd, uint teleportFlags, GridRegion source, out string reason, bool requirePresenceLookup) |
3780 | { | 3955 | { |
3781 | bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 || | 3956 | bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 || |
@@ -3809,6 +3984,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3809 | (source == null) ? "" : string.Format("From region {0} ({1}){2}", source.RegionName, source.RegionID, (source.RawServerURI == null) ? "" : " @ " + source.ServerURI) | 3984 | (source == null) ? "" : string.Format("From region {0} ({1}){2}", source.RegionName, source.RegionID, (source.RawServerURI == null) ? "" : " @ " + source.ServerURI) |
3810 | ); | 3985 | ); |
3811 | 3986 | ||
3987 | // m_log.DebugFormat("NewUserConnection stack {0}", Environment.StackTrace); | ||
3988 | |||
3812 | if (!LoginsEnabled) | 3989 | if (!LoginsEnabled) |
3813 | { | 3990 | { |
3814 | reason = "Logins Disabled"; | 3991 | reason = "Logins Disabled"; |
@@ -3936,7 +4113,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3936 | } | 4113 | } |
3937 | 4114 | ||
3938 | // TODO: can we remove this lock? | 4115 | // TODO: can we remove this lock? |
3939 | lock (acd) | 4116 | lock (m_newUserConnLock) |
3940 | { | 4117 | { |
3941 | if (sp != null && !sp.IsChildAgent) | 4118 | if (sp != null && !sp.IsChildAgent) |
3942 | { | 4119 | { |
@@ -3963,6 +4140,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
3963 | // We need the circuit data here for some of the subsequent checks. (groups, for example) | 4140 | // We need the circuit data here for some of the subsequent checks. (groups, for example) |
3964 | // If the checks fail, we remove the circuit. | 4141 | // If the checks fail, we remove the circuit. |
3965 | acd.teleportFlags = teleportFlags; | 4142 | acd.teleportFlags = teleportFlags; |
4143 | |||
4144 | // Remove any preexisting circuit - we don't want duplicates | ||
4145 | // This is a stab at preventing avatar "ghosting" | ||
4146 | if (vialogin) | ||
4147 | m_authenticateHandler.RemoveCircuit(acd.AgentID); | ||
4148 | |||
3966 | m_authenticateHandler.AddNewCircuit(acd.circuitcode, acd); | 4149 | m_authenticateHandler.AddNewCircuit(acd.circuitcode, acd); |
3967 | 4150 | ||
3968 | land = LandChannel.GetLandObject(acd.startpos.X, acd.startpos.Y); | 4151 | land = LandChannel.GetLandObject(acd.startpos.X, acd.startpos.Y); |
@@ -3970,6 +4153,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
3970 | // On login test land permisions | 4153 | // On login test land permisions |
3971 | if (vialogin) | 4154 | if (vialogin) |
3972 | { | 4155 | { |
4156 | IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>(); | ||
4157 | if (cache != null) | ||
4158 | cache.Remove(acd.firstname + " " + acd.lastname); | ||
3973 | if (land != null && !TestLandRestrictions(acd.AgentID, out reason, ref acd.startpos.X, ref acd.startpos.Y)) | 4159 | if (land != null && !TestLandRestrictions(acd.AgentID, out reason, ref acd.startpos.X, ref acd.startpos.Y)) |
3974 | { | 4160 | { |
3975 | m_authenticateHandler.RemoveCircuit(acd.circuitcode); | 4161 | m_authenticateHandler.RemoveCircuit(acd.circuitcode); |
@@ -4024,7 +4210,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4024 | if (CapsModule != null) | 4210 | if (CapsModule != null) |
4025 | { | 4211 | { |
4026 | CapsModule.SetAgentCapsSeeds(acd); | 4212 | CapsModule.SetAgentCapsSeeds(acd); |
4027 | CapsModule.CreateCaps(acd.AgentID); | 4213 | CapsModule.CreateCaps(acd.AgentID, acd.circuitcode); |
4028 | } | 4214 | } |
4029 | } | 4215 | } |
4030 | else | 4216 | else |
@@ -4037,15 +4223,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
4037 | { | 4223 | { |
4038 | m_log.DebugFormat( | 4224 | m_log.DebugFormat( |
4039 | "[SCENE]: Adjusting known seeds for existing agent {0} in {1}", | 4225 | "[SCENE]: Adjusting known seeds for existing agent {0} in {1}", |
4040 | acd.AgentID, RegionInfo.RegionName); | 4226 | acd.AgentID, RegionInfo.RegionName); |
4041 | |||
4042 | sp.AdjustKnownSeeds(); | ||
4043 | 4227 | ||
4044 | if (CapsModule != null) | 4228 | if (CapsModule != null) |
4045 | { | 4229 | { |
4046 | CapsModule.SetAgentCapsSeeds(acd); | 4230 | CapsModule.SetAgentCapsSeeds(acd); |
4047 | CapsModule.CreateCaps(acd.AgentID); | 4231 | CapsModule.CreateCaps(acd.AgentID, acd.circuitcode); |
4048 | } | 4232 | } |
4233 | |||
4234 | sp.AdjustKnownSeeds(); | ||
4049 | } | 4235 | } |
4050 | } | 4236 | } |
4051 | 4237 | ||
@@ -4055,6 +4241,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
4055 | CacheUserName(null, acd); | 4241 | CacheUserName(null, acd); |
4056 | } | 4242 | } |
4057 | 4243 | ||
4244 | if (CapsModule != null) | ||
4245 | { | ||
4246 | CapsModule.ActivateCaps(acd.circuitcode); | ||
4247 | } | ||
4248 | |||
4058 | if (vialogin) | 4249 | if (vialogin) |
4059 | { | 4250 | { |
4060 | // CleanDroppedAttachments(); | 4251 | // CleanDroppedAttachments(); |
@@ -4124,6 +4315,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
4124 | } | 4315 | } |
4125 | 4316 | ||
4126 | // Honor parcel landing type and position. | 4317 | // Honor parcel landing type and position. |
4318 | /* | ||
4319 | ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); | ||
4127 | if (land != null) | 4320 | if (land != null) |
4128 | { | 4321 | { |
4129 | if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) | 4322 | if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) |
@@ -4138,6 +4331,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4138 | } | 4331 | } |
4139 | } | 4332 | } |
4140 | } | 4333 | } |
4334 | */// This is now handled properly in ScenePresence.MakeRootAgent | ||
4141 | } | 4335 | } |
4142 | 4336 | ||
4143 | return true; | 4337 | return true; |
@@ -4162,12 +4356,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
4162 | { | 4356 | { |
4163 | if (posX < 0) | 4357 | if (posX < 0) |
4164 | posX = 0; | 4358 | posX = 0; |
4165 | else if (posX >= (float)RegionInfo.RegionSizeX) | 4359 | |
4166 | posX = (float)RegionInfo.RegionSizeX - 0.001f; | 4360 | else if (posX >= RegionInfo.RegionSizeX) |
4361 | posX = RegionInfo.RegionSizeX - 0.5f; | ||
4167 | if (posY < 0) | 4362 | if (posY < 0) |
4168 | posY = 0; | 4363 | posY = 0; |
4169 | else if (posY >= (float)RegionInfo.RegionSizeY) | 4364 | else if (posY >= RegionInfo.RegionSizeY) |
4170 | posY = (float)RegionInfo.RegionSizeY - 0.001f; | 4365 | posY = RegionInfo.RegionSizeY - 0.5f; |
4171 | 4366 | ||
4172 | reason = String.Empty; | 4367 | reason = String.Empty; |
4173 | if (Permissions.IsGod(agentID)) | 4368 | if (Permissions.IsGod(agentID)) |
@@ -4271,7 +4466,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
4271 | { | 4466 | { |
4272 | if (RegionInfo.EstateSettings != null) | 4467 | if (RegionInfo.EstateSettings != null) |
4273 | { | 4468 | { |
4274 | if (RegionInfo.EstateSettings.IsBanned(agent.AgentID)) | 4469 | int flags = GetUserFlags(agent.AgentID); |
4470 | if (RegionInfo.EstateSettings.IsBanned(agent.AgentID, flags)) | ||
4275 | { | 4471 | { |
4276 | m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", | 4472 | m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", |
4277 | agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); | 4473 | agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); |
@@ -4460,6 +4656,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
4460 | m_log.DebugFormat( | 4656 | m_log.DebugFormat( |
4461 | "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName); | 4657 | "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName); |
4462 | 4658 | ||
4659 | if (!LoginsEnabled) | ||
4660 | { | ||
4661 | // reason = "Logins Disabled"; | ||
4662 | m_log.DebugFormat( | ||
4663 | "[SCENE]: update for {0} in {1} refused: Logins Disabled", cAgentData.AgentID, RegionInfo.RegionName); | ||
4664 | return false; | ||
4665 | } | ||
4666 | // We have to wait until the viewer contacts this region after receiving EAC. | ||
4667 | // That calls AddNewClient, which finally creates the ScenePresence | ||
4668 | int flags = GetUserFlags(cAgentData.AgentID); | ||
4669 | if (RegionInfo.EstateSettings.IsBanned(cAgentData.AgentID, flags)) | ||
4670 | { | ||
4671 | m_log.DebugFormat("[SCENE]: Denying root agent entry to {0}: banned", cAgentData.AgentID); | ||
4672 | return false; | ||
4673 | } | ||
4674 | |||
4463 | // TODO: This check should probably be in QueryAccess(). | 4675 | // TODO: This check should probably be in QueryAccess(). |
4464 | ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, RegionInfo.RegionSizeX / 2, RegionInfo.RegionSizeY / 2); | 4676 | ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, RegionInfo.RegionSizeX / 2, RegionInfo.RegionSizeY / 2); |
4465 | if (nearestParcel == null) | 4677 | if (nearestParcel == null) |
@@ -4477,8 +4689,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
4477 | // a UseCircuitCode packet which in turn calls AddNewAgent which finally creates the ScenePresence. | 4689 | // a UseCircuitCode packet which in turn calls AddNewAgent which finally creates the ScenePresence. |
4478 | ScenePresence sp = WaitGetScenePresence(cAgentData.AgentID); | 4690 | ScenePresence sp = WaitGetScenePresence(cAgentData.AgentID); |
4479 | 4691 | ||
4480 | if (sp != null) | 4692 | if (sp != null) |
4481 | { | 4693 | { |
4694 | if (!sp.IsChildAgent) | ||
4695 | { | ||
4696 | m_log.WarnFormat("[SCENE]: Ignoring a child update on a root agent {0} {1} in {2}", | ||
4697 | sp.Name, sp.UUID, Name); | ||
4698 | return false; | ||
4699 | } | ||
4482 | if (cAgentData.SessionID != sp.ControllingClient.SessionId) | 4700 | if (cAgentData.SessionID != sp.ControllingClient.SessionId) |
4483 | { | 4701 | { |
4484 | m_log.WarnFormat( | 4702 | m_log.WarnFormat( |
@@ -4563,7 +4781,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4563 | /// <param name='agentID'></param> | 4781 | /// <param name='agentID'></param> |
4564 | protected virtual ScenePresence WaitGetScenePresence(UUID agentID) | 4782 | protected virtual ScenePresence WaitGetScenePresence(UUID agentID) |
4565 | { | 4783 | { |
4566 | int ntimes = 20; | 4784 | int ntimes = 30; |
4567 | ScenePresence sp = null; | 4785 | ScenePresence sp = null; |
4568 | while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0)) | 4786 | while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0)) |
4569 | Thread.Sleep(1000); | 4787 | Thread.Sleep(1000); |
@@ -4613,6 +4831,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
4613 | return false; | 4831 | return false; |
4614 | } | 4832 | } |
4615 | 4833 | ||
4834 | // public bool IncomingCloseAgent(UUID agentID) | ||
4835 | // { | ||
4836 | // return IncomingCloseAgent(agentID, false); | ||
4837 | // } | ||
4838 | |||
4839 | // public bool IncomingCloseChildAgent(UUID agentID) | ||
4840 | // { | ||
4841 | // return IncomingCloseAgent(agentID, true); | ||
4842 | // } | ||
4843 | |||
4616 | /// <summary> | 4844 | /// <summary> |
4617 | /// Tell a single client to prepare to close. | 4845 | /// Tell a single client to prepare to close. |
4618 | /// </summary> | 4846 | /// </summary> |
@@ -4675,6 +4903,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
4675 | 4903 | ||
4676 | if (sp == null) | 4904 | if (sp == null) |
4677 | { | 4905 | { |
4906 | // If there is no scene presence, we may be handling a dead | ||
4907 | // client. These can keep an avatar from reentering a region | ||
4908 | // and since they don't get cleaned up they will stick | ||
4909 | // around until region restart. So, if there is no SP, | ||
4910 | // remove the client as well. | ||
4911 | IClientAPI client = null; | ||
4912 | if (m_clientManager.TryGetValue(agentID, out client)) | ||
4913 | { | ||
4914 | m_clientManager.Remove(agentID); | ||
4915 | if (CapsModule != null) | ||
4916 | CapsModule.RemoveCaps(agentID, 0); | ||
4917 | m_log.DebugFormat( "[SCENE]: Dead client for agent ID {0} was cleaned up in {1}", agentID, Name); | ||
4918 | return true; | ||
4919 | } | ||
4678 | m_log.DebugFormat( | 4920 | m_log.DebugFormat( |
4679 | "[SCENE]: Called CloseClient() with agent ID {0} but no such presence is in {1}", | 4921 | "[SCENE]: Called CloseClient() with agent ID {0} but no such presence is in {1}", |
4680 | agentID, Name); | 4922 | agentID, Name); |
@@ -4709,7 +4951,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
4709 | sp.LifecycleState = ScenePresenceState.Removing; | 4951 | sp.LifecycleState = ScenePresenceState.Removing; |
4710 | } | 4952 | } |
4711 | 4953 | ||
4712 | sp.ControllingClient.Close(force); | 4954 | if (sp != null) |
4955 | { | ||
4956 | sp.ControllingClient.Close(force, force); | ||
4957 | return true; | ||
4958 | } | ||
4713 | 4959 | ||
4714 | return true; | 4960 | return true; |
4715 | } | 4961 | } |
@@ -4871,7 +5117,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
4871 | 5117 | ||
4872 | public LandData GetLandData(float x, float y) | 5118 | public LandData GetLandData(float x, float y) |
4873 | { | 5119 | { |
4874 | return LandChannel.GetLandObject(x, y).LandData; | 5120 | ILandObject parcel = LandChannel.GetLandObject(x, y); |
5121 | if (parcel == null) | ||
5122 | return null; | ||
5123 | return parcel.LandData; | ||
4875 | } | 5124 | } |
4876 | 5125 | ||
4877 | /// <summary> | 5126 | /// <summary> |
@@ -4887,7 +5136,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
4887 | public LandData GetLandData(uint x, uint y) | 5136 | public LandData GetLandData(uint x, uint y) |
4888 | { | 5137 | { |
4889 | m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y); | 5138 | m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y); |
4890 | return LandChannel.GetLandObject((int)x, (int)y).LandData; | 5139 | ILandObject parcel = LandChannel.GetLandObject((int)x, (int)y); |
5140 | if (parcel == null) | ||
5141 | return null; | ||
5142 | return parcel.LandData; | ||
4891 | } | 5143 | } |
4892 | 5144 | ||
4893 | #endregion | 5145 | #endregion |
@@ -5275,7 +5527,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
5275 | { | 5527 | { |
5276 | if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) | 5528 | if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) |
5277 | { | 5529 | { |
5278 | if (grp.RootPart.Expires <= DateTime.Now) | 5530 | if (grp.GetSittingAvatarsCount() == 0 && grp.RootPart.Expires <= DateTime.Now) |
5279 | DeleteSceneObject(grp, false); | 5531 | DeleteSceneObject(grp, false); |
5280 | } | 5532 | } |
5281 | } | 5533 | } |
@@ -5289,35 +5541,80 @@ namespace OpenSim.Region.Framework.Scenes | |||
5289 | SimulationDataService.RemoveObject(uuid, RegionInfo.RegionID); | 5541 | SimulationDataService.RemoveObject(uuid, RegionInfo.RegionID); |
5290 | } | 5542 | } |
5291 | 5543 | ||
5292 | public int GetHealth() | 5544 | public int GetHealth(out int flags, out string message) |
5293 | { | 5545 | { |
5294 | // Returns: | 5546 | // Returns: |
5295 | // 1 = sim is up and accepting http requests. The heartbeat has | 5547 | // 1 = sim is up and accepting http requests. The heartbeat has |
5296 | // stopped and the sim is probably locked up, but a remote | 5548 | // stopped and the sim is probably locked up, but a remote |
5297 | // admin restart may succeed | 5549 | // admin restart may succeed |
5298 | // | 5550 | // |
5299 | // 2 = Sim is up and the heartbeat is running. The sim is likely | 5551 | // 2 = Sim is up and the heartbeat is running. The sim is likely |
5300 | // usable for people within and logins _may_ work | 5552 | // usable for people within |
5553 | // | ||
5554 | // 3 = Sim is up and one packet thread is running. Sim is | ||
5555 | // unstable and will not accept new logins | ||
5301 | // | 5556 | // |
5302 | // 3 = We have seen a new user enter within the past 4 minutes | 5557 | // 4 = Sim is up and both packet threads are running. Sim is |
5558 | // likely usable | ||
5559 | // | ||
5560 | // 5 = We have seen a new user enter within the past 4 minutes | ||
5303 | // which can be seen as positive confirmation of sim health | 5561 | // which can be seen as positive confirmation of sim health |
5304 | // | 5562 | // |
5305 | int health = 1; // Start at 1, means we're up | 5563 | int health = 1; // Start at 1, means we're up |
5306 | 5564 | ||
5565 | flags = 0; | ||
5566 | message = String.Empty; | ||
5567 | |||
5568 | CheckHeartbeat(); | ||
5569 | |||
5570 | if (m_firstHeartbeat || (m_lastIncoming == 0 && m_lastOutgoing == 0)) | ||
5571 | { | ||
5572 | // We're still starting | ||
5573 | // 0 means "in startup", it can't happen another way, since | ||
5574 | // to get here, we must be able to accept http connections | ||
5575 | return 0; | ||
5576 | } | ||
5577 | |||
5307 | if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) < 1000) | 5578 | if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) < 1000) |
5308 | health += 1; | 5579 | { |
5580 | health+=1; | ||
5581 | flags |= 1; | ||
5582 | } | ||
5583 | |||
5584 | if (Util.EnvironmentTickCountSubtract(m_lastIncoming) < 1000) | ||
5585 | { | ||
5586 | health+=1; | ||
5587 | flags |= 2; | ||
5588 | } | ||
5589 | |||
5590 | if (Util.EnvironmentTickCountSubtract(m_lastOutgoing) < 1000) | ||
5591 | { | ||
5592 | health+=1; | ||
5593 | flags |= 4; | ||
5594 | } | ||
5309 | else | 5595 | else |
5596 | { | ||
5597 | int pid = System.Diagnostics.Process.GetCurrentProcess().Id; | ||
5598 | System.Diagnostics.Process proc = new System.Diagnostics.Process(); | ||
5599 | proc.EnableRaisingEvents=false; | ||
5600 | proc.StartInfo.FileName = "/bin/kill"; | ||
5601 | proc.StartInfo.Arguments = "-QUIT " + pid.ToString(); | ||
5602 | proc.Start(); | ||
5603 | proc.WaitForExit(); | ||
5604 | Thread.Sleep(1000); | ||
5605 | Environment.Exit(1); | ||
5606 | } | ||
5607 | |||
5608 | if (flags != 7) | ||
5310 | return health; | 5609 | return health; |
5311 | 5610 | ||
5312 | // A login in the last 4 mins? We can't be doing too badly | 5611 | // A login in the last 4 mins? We can't be doing too badly |
5313 | // | 5612 | // |
5314 | if ((Util.EnvironmentTickCountSubtract(m_LastLogin)) < 240000) | 5613 | if (Util.EnvironmentTickCountSubtract(m_LastLogin) < 240000) |
5315 | health++; | 5614 | health++; |
5316 | else | 5615 | else |
5317 | return health; | 5616 | return health; |
5318 | 5617 | ||
5319 | // CheckHeartbeat(); | ||
5320 | |||
5321 | return health; | 5618 | return health; |
5322 | } | 5619 | } |
5323 | 5620 | ||
@@ -5405,7 +5702,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
5405 | bool wasUsingPhysics = ((jointProxyObject.Flags & PrimFlags.Physics) != 0); | 5702 | bool wasUsingPhysics = ((jointProxyObject.Flags & PrimFlags.Physics) != 0); |
5406 | if (wasUsingPhysics) | 5703 | if (wasUsingPhysics) |
5407 | { | 5704 | { |
5408 | jointProxyObject.UpdatePrimFlags(false, false, true, false); // FIXME: possible deadlock here; check to make sure all the scene alterations set into motion here won't deadlock | 5705 | jointProxyObject.UpdatePrimFlags(false, false, true, false,false); // FIXME: possible deadlock here; check to make sure all the scene alterations set into motion here won't deadlock |
5409 | } | 5706 | } |
5410 | } | 5707 | } |
5411 | 5708 | ||
@@ -5508,14 +5805,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
5508 | return (((vsn.X * xdiff) + (vsn.Y * ydiff)) / (-1 * vsn.Z)) + p0.Z; | 5805 | return (((vsn.X * xdiff) + (vsn.Y * ydiff)) / (-1 * vsn.Z)) + p0.Z; |
5509 | } | 5806 | } |
5510 | 5807 | ||
5511 | // private void CheckHeartbeat() | 5808 | private void CheckHeartbeat() |
5512 | // { | 5809 | { |
5513 | // if (m_firstHeartbeat) | 5810 | if (m_firstHeartbeat) |
5514 | // return; | 5811 | return; |
5515 | // | 5812 | |
5516 | // if (Util.EnvironmentTickCountSubtract(m_lastFrameTick) > 2000) | 5813 | if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) > 5000) |
5517 | // StartTimer(); | 5814 | Start(); |
5518 | // } | 5815 | } |
5519 | 5816 | ||
5520 | public override ISceneObject DeserializeObject(string representation) | 5817 | public override ISceneObject DeserializeObject(string representation) |
5521 | { | 5818 | { |
@@ -5572,8 +5869,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
5572 | //Go to the edge, this happens in teleporting to a region with no available parcels | 5869 | //Go to the edge, this happens in teleporting to a region with no available parcels |
5573 | Vector3 nearestRegionEdgePoint = GetNearestRegionEdgePosition(avatar); | 5870 | Vector3 nearestRegionEdgePoint = GetNearestRegionEdgePosition(avatar); |
5574 | 5871 | ||
5575 | //m_log.Debug("They are really in a place they don't belong, sending them to: " + nearestRegionEdgePoint.ToString()); | 5872 | //Debug.WriteLine("They are really in a place they don't belong, sending them to: " + nearestRegionEdgePoint.ToString()); |
5576 | |||
5577 | return nearestRegionEdgePoint; | 5873 | return nearestRegionEdgePoint; |
5578 | } | 5874 | } |
5579 | 5875 | ||
@@ -5829,7 +6125,55 @@ namespace OpenSim.Region.Framework.Scenes | |||
5829 | mapModule.GenerateMaptile(); | 6125 | mapModule.GenerateMaptile(); |
5830 | } | 6126 | } |
5831 | 6127 | ||
5832 | private void RegenerateMaptileAndReregister(object sender, ElapsedEventArgs e) | 6128 | // public void CleanDroppedAttachments() |
6129 | // { | ||
6130 | // List<SceneObjectGroup> objectsToDelete = | ||
6131 | // new List<SceneObjectGroup>(); | ||
6132 | // | ||
6133 | // lock (m_cleaningAttachments) | ||
6134 | // { | ||
6135 | // ForEachSOG(delegate (SceneObjectGroup grp) | ||
6136 | // { | ||
6137 | // if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp))) | ||
6138 | // { | ||
6139 | // UUID agentID = grp.OwnerID; | ||
6140 | // if (agentID == UUID.Zero) | ||
6141 | // { | ||
6142 | // objectsToDelete.Add(grp); | ||
6143 | // return; | ||
6144 | // } | ||
6145 | // | ||
6146 | // ScenePresence sp = GetScenePresence(agentID); | ||
6147 | // if (sp == null) | ||
6148 | // { | ||
6149 | // objectsToDelete.Add(grp); | ||
6150 | // return; | ||
6151 | // } | ||
6152 | // } | ||
6153 | // }); | ||
6154 | // } | ||
6155 | // | ||
6156 | // foreach (SceneObjectGroup grp in objectsToDelete) | ||
6157 | // { | ||
6158 | // m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID); | ||
6159 | // DeleteSceneObject(grp, true); | ||
6160 | // } | ||
6161 | // } | ||
6162 | |||
6163 | public void ThreadAlive(int threadCode) | ||
6164 | { | ||
6165 | switch(threadCode) | ||
6166 | { | ||
6167 | case 1: // Incoming | ||
6168 | m_lastIncoming = Util.EnvironmentTickCount(); | ||
6169 | break; | ||
6170 | case 2: // Incoming | ||
6171 | m_lastOutgoing = Util.EnvironmentTickCount(); | ||
6172 | break; | ||
6173 | } | ||
6174 | } | ||
6175 | |||
6176 | public void RegenerateMaptileAndReregister(object sender, ElapsedEventArgs e) | ||
5833 | { | 6177 | { |
5834 | RegenerateMaptile(); | 6178 | RegenerateMaptile(); |
5835 | 6179 | ||
@@ -5995,7 +6339,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
5995 | return true; | 6339 | return true; |
5996 | } | 6340 | } |
5997 | 6341 | ||
5998 | /// <summary> | 6342 | public void StartTimerWatchdog() |
6343 | { | ||
6344 | m_timerWatchdog.Interval = 1000; | ||
6345 | m_timerWatchdog.Elapsed += TimerWatchdog; | ||
6346 | m_timerWatchdog.AutoReset = true; | ||
6347 | m_timerWatchdog.Start(); | ||
6348 | } | ||
6349 | |||
6350 | public void TimerWatchdog(object sender, ElapsedEventArgs e) | ||
6351 | { | ||
6352 | CheckHeartbeat(); | ||
6353 | } | ||
6354 | |||
5999 | /// This method deals with movement when an avatar is automatically moving (but this is distinct from the | 6355 | /// This method deals with movement when an avatar is automatically moving (but this is distinct from the |
6000 | /// autopilot that moves an avatar to a sit target!. | 6356 | /// autopilot that moves an avatar to a sit target!. |
6001 | /// </summary> | 6357 | /// </summary> |
@@ -6074,6 +6430,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
6074 | return m_SpawnPoint - 1; | 6430 | return m_SpawnPoint - 1; |
6075 | } | 6431 | } |
6076 | 6432 | ||
6433 | private void HandleGcCollect(string module, string[] args) | ||
6434 | { | ||
6435 | GC.Collect(); | ||
6436 | } | ||
6437 | |||
6077 | /// <summary> | 6438 | /// <summary> |
6078 | /// Wrappers to get physics modules retrieve assets. | 6439 | /// Wrappers to get physics modules retrieve assets. |
6079 | /// </summary> | 6440 | /// </summary> |