diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs')
-rwxr-xr-x | OpenSim/Region/Framework/Scenes/Scene.cs | 1315 |
1 files changed, 838 insertions, 477 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index dce2247..dddc31a 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -60,8 +60,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
60 | { | 60 | { |
61 | private const long DEFAULT_MIN_TIME_FOR_PERSISTENCE = 60L; | 61 | private const long DEFAULT_MIN_TIME_FOR_PERSISTENCE = 60L; |
62 | private const long DEFAULT_MAX_TIME_FOR_PERSISTENCE = 600L; | 62 | private const long DEFAULT_MAX_TIME_FOR_PERSISTENCE = 600L; |
63 | 63 | ||
64 | public const int m_defaultNumberFramesStored = 10; | ||
65 | 64 | ||
66 | public delegate void SynchronizeSceneHandler(Scene scene); | 65 | public delegate void SynchronizeSceneHandler(Scene scene); |
67 | 66 | ||
@@ -104,9 +103,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
104 | /// <summary> | 103 | /// <summary> |
105 | /// If false then physical objects are disabled, though collisions will continue as normal. | 104 | /// If false then physical objects are disabled, though collisions will continue as normal. |
106 | /// </summary> | 105 | /// </summary> |
107 | public bool PhysicsEnabled | 106 | |
108 | { | 107 | public bool PhysicsEnabled |
109 | get | 108 | { |
109 | get | ||
110 | { | 110 | { |
111 | return m_physicsEnabled; | 111 | return m_physicsEnabled; |
112 | } | 112 | } |
@@ -215,7 +215,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
215 | /// <summary> | 215 | /// <summary> |
216 | /// Maximum value of the size of a physical prim in each axis | 216 | /// Maximum value of the size of a physical prim in each axis |
217 | /// </summary> | 217 | /// </summary> |
218 | public float m_maxPhys = 64; | 218 | public float m_maxPhys = 10; |
219 | 219 | ||
220 | /// <summary> | 220 | /// <summary> |
221 | /// Max prims an object will hold | 221 | /// Max prims an object will hold |
@@ -227,10 +227,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
227 | public bool m_allowScriptCrossings = true; | 227 | public bool m_allowScriptCrossings = true; |
228 | 228 | ||
229 | /// <summary> | 229 | /// <summary> |
230 | |||
230 | /// Can avatars cross from and to this region? | 231 | /// Can avatars cross from and to this region? |
231 | /// </summary> | 232 | /// </summary> |
232 | public bool AllowAvatarCrossing { get; set; } | 233 | public bool AllowAvatarCrossing { get; set; } |
233 | 234 | ||
235 | /// Max prims an Physical object will hold | ||
236 | /// </summary> | ||
237 | /// | ||
238 | public int m_linksetPhysCapacity = 0; | ||
239 | |||
234 | public bool m_useFlySlow; | 240 | public bool m_useFlySlow; |
235 | public bool m_useTrashOnDelete = true; | 241 | public bool m_useTrashOnDelete = true; |
236 | 242 | ||
@@ -264,20 +270,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
264 | /// </summary> | 270 | /// </summary> |
265 | public int ChildTerseUpdatePeriod { get; set; } | 271 | public int ChildTerseUpdatePeriod { get; set; } |
266 | 272 | ||
267 | protected float m_defaultDrawDistance = 255.0f; | 273 | protected float m_defaultDrawDistance = 255f; |
268 | public float DefaultDrawDistance | 274 | public float DefaultDrawDistance |
269 | { | 275 | { |
270 | // get { return m_defaultDrawDistance; } | 276 | get { return m_defaultDrawDistance; } |
271 | get | 277 | } |
272 | { | ||
273 | if (RegionInfo != null) | ||
274 | { | ||
275 | float largestDimension = Math.Max(RegionInfo.RegionSizeX, RegionInfo.RegionSizeY); | ||
276 | m_defaultDrawDistance = Math.Max(m_defaultDrawDistance, largestDimension); | ||
277 | 278 | ||
278 | } | 279 | protected float m_maxDrawDistance = 512.0f; |
279 | return m_defaultDrawDistance; | 280 | // protected float m_maxDrawDistance = 256.0f; |
280 | } | 281 | public float MaxDrawDistance |
282 | { | ||
283 | get { return m_maxDrawDistance; } | ||
281 | } | 284 | } |
282 | 285 | ||
283 | private List<string> m_AllowedViewers = new List<string>(); | 286 | private List<string> m_AllowedViewers = new List<string>(); |
@@ -286,8 +289,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
286 | // TODO: need to figure out how allow client agents but deny | 289 | // TODO: need to figure out how allow client agents but deny |
287 | // root agents when ACL denies access to root agent | 290 | // root agents when ACL denies access to root agent |
288 | public bool m_strictAccessControl = true; | 291 | public bool m_strictAccessControl = true; |
289 | 292 | public bool m_seeIntoBannedRegion = false; | |
290 | public int MaxUndoCount { get; set; } | 293 | public int MaxUndoCount = 5; |
291 | 294 | ||
292 | public bool SeeIntoRegion { get; set; } | 295 | public bool SeeIntoRegion { get; set; } |
293 | 296 | ||
@@ -305,11 +308,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
305 | 308 | ||
306 | protected int m_splitRegionID; | 309 | protected int m_splitRegionID; |
307 | protected Timer m_restartWaitTimer = new Timer(); | 310 | protected Timer m_restartWaitTimer = new Timer(); |
311 | protected Timer m_timerWatchdog = new Timer(); | ||
308 | protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); | 312 | protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); |
309 | protected List<RegionInfo> m_neighbours = new List<RegionInfo>(); | 313 | protected List<RegionInfo> m_neighbours = new List<RegionInfo>(); |
310 | protected string m_simulatorVersion = "OpenSimulator Server"; | 314 | protected string m_simulatorVersion = "OpenSimulator Server"; |
311 | protected AgentCircuitManager m_authenticateHandler; | 315 | protected AgentCircuitManager m_authenticateHandler; |
312 | protected SceneCommunicationService m_sceneGridService; | 316 | protected SceneCommunicationService m_sceneGridService; |
317 | protected ISnmpModule m_snmpService = null; | ||
313 | 318 | ||
314 | protected ISimulationDataService m_SimulationDataService; | 319 | protected ISimulationDataService m_SimulationDataService; |
315 | protected IEstateDataService m_EstateDataService; | 320 | protected IEstateDataService m_EstateDataService; |
@@ -338,17 +343,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
338 | private Dictionary<string, string> m_extraSettings; | 343 | private Dictionary<string, string> m_extraSettings; |
339 | 344 | ||
340 | /// <summary> | 345 | /// <summary> |
341 | /// If true then the next time the scene loop is activated, updates will be performed by firing of a timer | ||
342 | /// rather than on a single thread that sleeps. | ||
343 | /// </summary> | ||
344 | public bool UpdateOnTimer { get; set; } | ||
345 | |||
346 | /// <summary> | ||
347 | /// Only used if we are updating scene on a timer rather than sleeping a thread. | ||
348 | /// </summary> | ||
349 | private Timer m_sceneUpdateTimer; | ||
350 | |||
351 | /// <summary> | ||
352 | /// Current scene frame number | 346 | /// Current scene frame number |
353 | /// </summary> | 347 | /// </summary> |
354 | public uint Frame | 348 | public uint Frame |
@@ -363,23 +357,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
363 | public uint MaintenanceRun { get; private set; } | 357 | public uint MaintenanceRun { get; private set; } |
364 | 358 | ||
365 | /// <summary> | 359 | /// <summary> |
366 | /// The minimum length of time in milliseconds that will be taken for a scene frame. If the frame takes less time then we | 360 | /// The minimum length of time in seconds that will be taken for a scene frame. If the frame takes less time then we |
367 | /// will sleep for the remaining period. | 361 | /// will sleep for the remaining period. |
368 | /// </summary> | 362 | /// </summary> |
369 | /// <remarks> | 363 | /// <remarks> |
370 | /// One can tweak this number to experiment. One current effect of reducing it is to make avatar animations | 364 | /// One can tweak this number to experiment. One current effect of reducing it is to make avatar animations |
371 | /// occur too quickly (viewer 1) or with even more slide (viewer 2). | 365 | /// occur too quickly (viewer 1) or with even more slide (viewer 2). |
372 | /// </remarks> | 366 | /// </remarks> |
373 | public int MinFrameTicks | 367 | public float MinFrameTime { get; private set; } |
374 | { | ||
375 | get { return m_minFrameTicks; } | ||
376 | private set | ||
377 | { | ||
378 | m_minFrameTicks = value; | ||
379 | MinFrameSeconds = (float)m_minFrameTicks / 1000; | ||
380 | } | ||
381 | } | ||
382 | private int m_minFrameTicks; | ||
383 | 368 | ||
384 | /// <summary> | 369 | /// <summary> |
385 | /// The minimum length of time in seconds that will be taken for a scene frame. | 370 | /// The minimum length of time in seconds that will be taken for a scene frame. |
@@ -387,17 +372,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
387 | /// <remarks> | 372 | /// <remarks> |
388 | /// Always derived from MinFrameTicks. | 373 | /// Always derived from MinFrameTicks. |
389 | /// </remarks> | 374 | /// </remarks> |
390 | public float MinFrameSeconds { get; private set; } | 375 | public float MinMaintenanceTime { get; private set; } |
391 | |||
392 | /// <summary> | ||
393 | /// The minimum length of time in milliseconds that will be taken for a scene frame. If the frame takes less time then we | ||
394 | /// will sleep for the remaining period. | ||
395 | /// </summary> | ||
396 | /// <remarks> | ||
397 | /// One can tweak this number to experiment. One current effect of reducing it is to make avatar animations | ||
398 | /// occur too quickly (viewer 1) or with even more slide (viewer 2). | ||
399 | /// </remarks> | ||
400 | public int MinMaintenanceTicks { get; set; } | ||
401 | 376 | ||
402 | private int m_update_physics = 1; | 377 | private int m_update_physics = 1; |
403 | private int m_update_entitymovement = 1; | 378 | private int m_update_entitymovement = 1; |
@@ -405,22 +380,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
405 | private int m_update_presences = 1; // Update scene presence movements | 380 | private int m_update_presences = 1; // Update scene presence movements |
406 | private int m_update_events = 1; | 381 | private int m_update_events = 1; |
407 | private int m_update_backup = 200; | 382 | private int m_update_backup = 200; |
408 | private int m_update_terrain = 50; | 383 | |
409 | // private int m_update_land = 1; | 384 | private int m_update_terrain = 1000; |
385 | private int m_update_land = 10; | ||
386 | |||
410 | private int m_update_coarse_locations = 50; | 387 | private int m_update_coarse_locations = 50; |
411 | private int m_update_temp_cleaning = 180; | 388 | private int m_update_temp_cleaning = 180; |
412 | 389 | ||
413 | private int agentMS; | 390 | private float agentMS; |
414 | private int frameMS; | 391 | private float frameMS; |
415 | private int physicsMS2; | 392 | private float physicsMS2; |
416 | private int physicsMS; | 393 | private float physicsMS; |
417 | private int otherMS; | 394 | private float otherMS; |
418 | private int tempOnRezMS; | 395 | private float tempOnRezMS; |
419 | private int eventMS; | 396 | private float eventMS; |
420 | private int backupMS; | 397 | private float backupMS; |
421 | private int terrainMS; | 398 | private float terrainMS; |
422 | private int landMS; | 399 | private float landMS; |
423 | private int spareMS; | ||
424 | 400 | ||
425 | // A temporary configuration flag to enable using FireAndForget to process | 401 | // A temporary configuration flag to enable using FireAndForget to process |
426 | // collisions from the physics engine. There is a problem with collisions | 402 | // collisions from the physics engine. There is a problem with collisions |
@@ -438,6 +414,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
438 | /// </summary> | 414 | /// </summary> |
439 | private int m_lastFrameTick; | 415 | private int m_lastFrameTick; |
440 | 416 | ||
417 | public bool CombineRegions = false; | ||
441 | /// <summary> | 418 | /// <summary> |
442 | /// Tick at which the last maintenance run occurred. | 419 | /// Tick at which the last maintenance run occurred. |
443 | /// </summary> | 420 | /// </summary> |
@@ -469,7 +446,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
469 | private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing | 446 | private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing |
470 | private volatile bool m_backingup; | 447 | private volatile bool m_backingup; |
471 | private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>(); | 448 | private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>(); |
472 | private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>(); | 449 | private Dictionary<UUID, int> m_groupsWithTargets = new Dictionary<UUID, int>(); |
473 | 450 | ||
474 | private string m_defaultScriptEngine; | 451 | private string m_defaultScriptEngine; |
475 | 452 | ||
@@ -484,6 +461,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
484 | /// </summary> | 461 | /// </summary> |
485 | private int m_LastLogin; | 462 | private int m_LastLogin; |
486 | 463 | ||
464 | private int m_lastIncoming; | ||
465 | private int m_lastOutgoing; | ||
466 | private int m_hbRestarts = 0; | ||
467 | |||
468 | |||
487 | /// <summary> | 469 | /// <summary> |
488 | /// Thread that runs the scene loop. | 470 | /// Thread that runs the scene loop. |
489 | /// </summary> | 471 | /// </summary> |
@@ -532,6 +514,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
532 | public bool IsRunning { get { return m_isRunning; } } | 514 | public bool IsRunning { get { return m_isRunning; } } |
533 | private volatile bool m_isRunning; | 515 | private volatile bool m_isRunning; |
534 | 516 | ||
517 | // private int m_lastUpdate; | ||
518 | private bool m_firstHeartbeat = true; | ||
519 | |||
520 | private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time; | ||
521 | private bool m_reprioritizationEnabled = true; | ||
522 | private double m_reprioritizationInterval = 5000.0; | ||
523 | private double m_rootReprioritizationDistance = 10.0; | ||
524 | private double m_childReprioritizationDistance = 20.0; | ||
525 | |||
526 | |||
535 | private Timer m_mapGenerationTimer = new Timer(); | 527 | private Timer m_mapGenerationTimer = new Timer(); |
536 | private bool m_generateMaptiles; | 528 | private bool m_generateMaptiles; |
537 | 529 | ||
@@ -563,6 +555,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
563 | get { return m_sceneGridService; } | 555 | get { return m_sceneGridService; } |
564 | } | 556 | } |
565 | 557 | ||
558 | public ISnmpModule SnmpService | ||
559 | { | ||
560 | get | ||
561 | { | ||
562 | if (m_snmpService == null) | ||
563 | { | ||
564 | m_snmpService = RequestModuleInterface<ISnmpModule>(); | ||
565 | } | ||
566 | |||
567 | return m_snmpService; | ||
568 | } | ||
569 | } | ||
570 | |||
566 | public ISimulationDataService SimulationDataService | 571 | public ISimulationDataService SimulationDataService |
567 | { | 572 | { |
568 | get | 573 | get |
@@ -769,15 +774,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
769 | get { return m_capsModule; } | 774 | get { return m_capsModule; } |
770 | } | 775 | } |
771 | 776 | ||
772 | public int MonitorFrameTime { get { return frameMS; } } | 777 | public int MonitorFrameTime { get { return (int)frameMS; } } |
773 | public int MonitorPhysicsUpdateTime { get { return physicsMS; } } | 778 | public int MonitorPhysicsUpdateTime { get { return (int)physicsMS; } } |
774 | public int MonitorPhysicsSyncTime { get { return physicsMS2; } } | 779 | public int MonitorPhysicsSyncTime { get { return (int)physicsMS2; } } |
775 | public int MonitorOtherTime { get { return otherMS; } } | 780 | public int MonitorOtherTime { get { return (int)otherMS; } } |
776 | public int MonitorTempOnRezTime { get { return tempOnRezMS; } } | 781 | public int MonitorTempOnRezTime { get { return (int)tempOnRezMS; } } |
777 | public int MonitorEventTime { get { return eventMS; } } // This may need to be divided into each event? | 782 | public int MonitorEventTime { get { return (int)eventMS; } } // This may need to be divided into each event? |
778 | public int MonitorBackupTime { get { return backupMS; } } | 783 | public int MonitorBackupTime { get { return (int)backupMS; } } |
779 | public int MonitorTerrainTime { get { return terrainMS; } } | 784 | public int MonitorTerrainTime { get { return (int)terrainMS; } } |
780 | public int MonitorLandTime { get { return landMS; } } | 785 | public int MonitorLandTime { get { return (int)landMS; } } |
781 | public int MonitorLastFrameTick { get { return m_lastFrameTick; } } | 786 | public int MonitorLastFrameTick { get { return m_lastFrameTick; } } |
782 | 787 | ||
783 | public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get; set; } | 788 | public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get; set; } |
@@ -855,8 +860,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
855 | : this(regInfo) | 860 | : this(regInfo) |
856 | { | 861 | { |
857 | m_config = config; | 862 | m_config = config; |
858 | MinFrameTicks = 89; | 863 | MinFrameTime = 0.089f; |
859 | MinMaintenanceTicks = 1000; | 864 | MinMaintenanceTime = 1; |
860 | SeeIntoRegion = true; | 865 | SeeIntoRegion = true; |
861 | 866 | ||
862 | Random random = new Random(); | 867 | Random random = new Random(); |
@@ -867,6 +872,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
867 | m_SimulationDataService = simDataService; | 872 | m_SimulationDataService = simDataService; |
868 | m_EstateDataService = estateDataService; | 873 | m_EstateDataService = estateDataService; |
869 | 874 | ||
875 | m_lastIncoming = 0; | ||
876 | m_lastOutgoing = 0; | ||
877 | |||
870 | m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this); | 878 | m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this); |
871 | m_asyncSceneObjectDeleter.Enabled = true; | 879 | m_asyncSceneObjectDeleter.Enabled = true; |
872 | 880 | ||
@@ -924,7 +932,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
924 | EventManager.OnLandObjectRemoved += | 932 | EventManager.OnLandObjectRemoved += |
925 | new EventManager.LandObjectRemoved(simDataService.RemoveLandObject); | 933 | new EventManager.LandObjectRemoved(simDataService.RemoveLandObject); |
926 | 934 | ||
927 | RegisterDefaultSceneEvents(); | 935 | RegisterDefaultSceneEvents(); |
928 | 936 | ||
929 | // XXX: Don't set the public property since we don't want to activate here. This needs to be handled | 937 | // XXX: Don't set the public property since we don't want to activate here. This needs to be handled |
930 | // better in the future. | 938 | // better in the future. |
@@ -945,6 +953,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
945 | StartDisabled = startupConfig.GetBoolean("StartDisabled", false); | 953 | StartDisabled = startupConfig.GetBoolean("StartDisabled", false); |
946 | 954 | ||
947 | m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance", m_defaultDrawDistance); | 955 | m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance", m_defaultDrawDistance); |
956 | m_maxDrawDistance = startupConfig.GetFloat("MaxDrawDistance", m_maxDrawDistance); | ||
957 | |||
958 | if (m_defaultDrawDistance > m_maxDrawDistance) | ||
959 | m_defaultDrawDistance = m_maxDrawDistance; | ||
960 | |||
948 | UseBackup = startupConfig.GetBoolean("UseSceneBackup", UseBackup); | 961 | UseBackup = startupConfig.GetBoolean("UseSceneBackup", UseBackup); |
949 | if (!UseBackup) | 962 | if (!UseBackup) |
950 | m_log.InfoFormat("[SCENE]: Backup has been disabled for {0}", RegionInfo.RegionName); | 963 | m_log.InfoFormat("[SCENE]: Backup has been disabled for {0}", RegionInfo.RegionName); |
@@ -956,9 +969,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
956 | 969 | ||
957 | MaxUndoCount = startupConfig.GetInt("MaxPrimUndos", 20); | 970 | MaxUndoCount = startupConfig.GetInt("MaxPrimUndos", 20); |
958 | 971 | ||
959 | PhysicalPrims = startupConfig.GetBoolean("physical_prim", PhysicalPrims); | 972 | PhysicalPrims = startupConfig.GetBoolean("physical_prim", true); |
960 | CollidablePrims = startupConfig.GetBoolean("collidable_prim", CollidablePrims); | 973 | CollidablePrims = startupConfig.GetBoolean("collidable_prim", true); |
961 | |||
962 | m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys); | 974 | m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys); |
963 | if (RegionInfo.NonphysPrimMin > 0) | 975 | if (RegionInfo.NonphysPrimMin > 0) |
964 | { | 976 | { |
@@ -978,11 +990,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
978 | } | 990 | } |
979 | 991 | ||
980 | m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys); | 992 | m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys); |
993 | |||
981 | if (RegionInfo.PhysPrimMax > 0) | 994 | if (RegionInfo.PhysPrimMax > 0) |
982 | { | 995 | { |
983 | m_maxPhys = RegionInfo.PhysPrimMax; | 996 | m_maxPhys = RegionInfo.PhysPrimMax; |
984 | } | 997 | } |
985 | 998 | ||
999 | m_linksetCapacity = startupConfig.GetInt("LinksetPrims", m_linksetCapacity); | ||
1000 | if (RegionInfo.LinksetCapacity > 0) | ||
1001 | { | ||
1002 | m_linksetCapacity = RegionInfo.LinksetCapacity; | ||
1003 | } | ||
1004 | |||
1005 | m_linksetPhysCapacity = startupConfig.GetInt("LinksetPhysPrims", m_linksetPhysCapacity); | ||
1006 | |||
1007 | |||
1008 | SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest"); | ||
1009 | TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false); | ||
1010 | |||
986 | // Here, if clamping is requested in either global or | 1011 | // Here, if clamping is requested in either global or |
987 | // local config, it will be used | 1012 | // local config, it will be used |
988 | // | 1013 | // |
@@ -992,13 +1017,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
992 | m_clampPrimSize = true; | 1017 | m_clampPrimSize = true; |
993 | } | 1018 | } |
994 | 1019 | ||
995 | m_linksetCapacity = startupConfig.GetInt("LinksetPrims", m_linksetCapacity); | 1020 | m_useTrashOnDelete = startupConfig.GetBoolean("UseTrashOnDelete",m_useTrashOnDelete); |
996 | if (RegionInfo.LinksetCapacity > 0) | ||
997 | { | ||
998 | m_linksetCapacity = RegionInfo.LinksetCapacity; | ||
999 | } | ||
1000 | |||
1001 | m_useTrashOnDelete = startupConfig.GetBoolean("UseTrashOnDelete", m_useTrashOnDelete); | ||
1002 | m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries); | 1021 | m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries); |
1003 | m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings); | 1022 | m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings); |
1004 | m_dontPersistBefore = | 1023 | m_dontPersistBefore = |
@@ -1009,11 +1028,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1009 | m_persistAfter *= 10000000; | 1028 | m_persistAfter *= 10000000; |
1010 | 1029 | ||
1011 | m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); | 1030 | m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); |
1012 | 1031 | m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine); | |
1013 | SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest"); | ||
1014 | TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false); | ||
1015 | 1032 | ||
1016 | m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); | 1033 | m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); |
1034 | m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion); | ||
1035 | CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false); | ||
1017 | 1036 | ||
1018 | string[] possibleMapConfigSections = new string[] { "Map", "Startup" }; | 1037 | string[] possibleMapConfigSections = new string[] { "Map", "Startup" }; |
1019 | 1038 | ||
@@ -1059,7 +1078,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1059 | 1078 | ||
1060 | if (grant.Length > 0) | 1079 | if (grant.Length > 0) |
1061 | { | 1080 | { |
1062 | foreach (string viewer in grant.Split('|')) | 1081 | foreach (string viewer in grant.Split(',')) |
1063 | { | 1082 | { |
1064 | m_AllowedViewers.Add(viewer.Trim().ToLower()); | 1083 | m_AllowedViewers.Add(viewer.Trim().ToLower()); |
1065 | } | 1084 | } |
@@ -1075,14 +1094,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1075 | 1094 | ||
1076 | if (grant.Length > 0) | 1095 | if (grant.Length > 0) |
1077 | { | 1096 | { |
1078 | foreach (string viewer in grant.Split('|')) | 1097 | foreach (string viewer in grant.Split(',')) |
1079 | { | 1098 | { |
1080 | m_BannedViewers.Add(viewer.Trim().ToLower()); | 1099 | m_BannedViewers.Add(viewer.Trim().ToLower()); |
1081 | } | 1100 | } |
1082 | } | 1101 | } |
1083 | 1102 | ||
1084 | if (startupConfig.Contains("MinFrameTime")) | 1103 | MinFrameTime = startupConfig.GetFloat( "MinFrameTime", MinFrameTime); |
1085 | MinFrameTicks = (int)(startupConfig.GetFloat("MinFrameTime") * 1000); | ||
1086 | 1104 | ||
1087 | m_update_backup = startupConfig.GetInt("UpdateStorageEveryNFrames", m_update_backup); | 1105 | m_update_backup = startupConfig.GetInt("UpdateStorageEveryNFrames", m_update_backup); |
1088 | m_update_coarse_locations = startupConfig.GetInt("UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations); | 1106 | m_update_coarse_locations = startupConfig.GetInt("UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations); |
@@ -1160,39 +1178,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1160 | 1178 | ||
1161 | #endregion Interest Management | 1179 | #endregion Interest Management |
1162 | 1180 | ||
1163 | // The timer used by the Stopwatch class depends on the system hardware and operating system; inform | ||
1164 | // if the timer is based on a high-resolution performance counter or based on the system timer; | ||
1165 | // the performance counter will provide a more precise time than the system timer | ||
1166 | if (Stopwatch.IsHighResolution) | ||
1167 | m_log.InfoFormat("[SCENE]: Using high-resolution performance counter for statistics."); | ||
1168 | else | ||
1169 | m_log.InfoFormat("[SCENE]: Using system timer for statistics."); | ||
1170 | 1181 | ||
1171 | // Acquire the statistics section of the OpenSim.ini file located | 1182 | StatsReporter = new SimStatsReporter(this); |
1172 | // in the bin directory | ||
1173 | IConfig statisticsConfig = m_config.Configs["Statistics"]; | ||
1174 | |||
1175 | // Confirm that the statistics section existed in the configuration | ||
1176 | // file | ||
1177 | if (statisticsConfig != null) | ||
1178 | { | ||
1179 | // Create the StatsReporter using the number of frames to store | ||
1180 | // for the frame time statistics, or 10 frames if the config | ||
1181 | // file doesn't contain a value | ||
1182 | StatsReporter = new SimStatsReporter(this, | ||
1183 | statisticsConfig.GetInt("NumberOfFrames", | ||
1184 | m_defaultNumberFramesStored)); | ||
1185 | } | ||
1186 | else | ||
1187 | { | ||
1188 | // Create a StatsReporter with the current scene and a default | ||
1189 | // 10 frames stored for the frame time statistics | ||
1190 | StatsReporter = new SimStatsReporter(this); | ||
1191 | } | ||
1192 | 1183 | ||
1193 | StatsReporter.OnSendStatsResult += SendSimStatsPackets; | 1184 | StatsReporter.OnSendStatsResult += SendSimStatsPackets; |
1194 | StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats; | 1185 | StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats; |
1195 | 1186 | ||
1196 | } | 1187 | } |
1197 | 1188 | ||
1198 | public Scene(RegionInfo regInfo) | 1189 | public Scene(RegionInfo regInfo) |
@@ -1235,6 +1226,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1235 | m_eventManager = new EventManager(); | 1226 | m_eventManager = new EventManager(); |
1236 | 1227 | ||
1237 | m_permissions = new ScenePermissions(this); | 1228 | m_permissions = new ScenePermissions(this); |
1229 | |||
1238 | } | 1230 | } |
1239 | 1231 | ||
1240 | #endregion | 1232 | #endregion |
@@ -1280,20 +1272,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1280 | { | 1272 | { |
1281 | if (RegionInfo.RegionHandle != otherRegion.RegionHandle) | 1273 | if (RegionInfo.RegionHandle != otherRegion.RegionHandle) |
1282 | { | 1274 | { |
1283 | //// If these are cast to INT because long + negative values + abs returns invalid data | ||
1284 | //int resultX = Math.Abs((int)xcell - (int)RegionInfo.RegionLocX); | ||
1285 | //int resultY = Math.Abs((int)ycell - (int)RegionInfo.RegionLocY); | ||
1286 | //if (resultX <= 1 && resultY <= 1) | ||
1287 | float dist = (float)Math.Max(DefaultDrawDistance, | ||
1288 | (float)Math.Max(RegionInfo.RegionSizeX, RegionInfo.RegionSizeY)); | ||
1289 | uint newRegionX, newRegionY, thisRegionX, thisRegionY; | ||
1290 | Util.RegionHandleToRegionLoc(otherRegion.RegionHandle, out newRegionX, out newRegionY); | ||
1291 | Util.RegionHandleToRegionLoc(RegionInfo.RegionHandle, out thisRegionX, out thisRegionY); | ||
1292 | 1275 | ||
1293 | //m_log.InfoFormat("[SCENE]: (on region {0}): Region {1} up in coords {2}-{3}", | 1276 | if (isNeighborRegion(otherRegion)) |
1294 | // RegionInfo.RegionName, otherRegion.RegionName, newRegionX, newRegionY); | ||
1295 | |||
1296 | if (!Util.IsOutsideView(dist, thisRegionX, newRegionX, thisRegionY, newRegionY)) | ||
1297 | { | 1277 | { |
1298 | // Let the grid service module know, so this can be cached | 1278 | // Let the grid service module know, so this can be cached |
1299 | m_eventManager.TriggerOnRegionUp(otherRegion); | 1279 | m_eventManager.TriggerOnRegionUp(otherRegion); |
@@ -1328,6 +1308,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1328 | } | 1308 | } |
1329 | } | 1309 | } |
1330 | 1310 | ||
1311 | public bool isNeighborRegion(GridRegion otherRegion) | ||
1312 | { | ||
1313 | int tmp = otherRegion.RegionLocX - (int)RegionInfo.WorldLocX; ; | ||
1314 | |||
1315 | if (tmp < -otherRegion.RegionSizeX && tmp > RegionInfo.RegionSizeX) | ||
1316 | return false; | ||
1317 | |||
1318 | tmp = otherRegion.RegionLocY - (int)RegionInfo.WorldLocY; | ||
1319 | |||
1320 | if (tmp < -otherRegion.RegionSizeY && tmp > RegionInfo.RegionSizeY) | ||
1321 | return false; | ||
1322 | |||
1323 | return true; | ||
1324 | } | ||
1325 | |||
1331 | public void AddNeighborRegion(RegionInfo region) | 1326 | public void AddNeighborRegion(RegionInfo region) |
1332 | { | 1327 | { |
1333 | lock (m_neighbours) | 1328 | lock (m_neighbours) |
@@ -1459,8 +1454,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1459 | // Stop all client threads. | 1454 | // Stop all client threads. |
1460 | ForEachScenePresence(delegate(ScenePresence avatar) { CloseAgent(avatar.UUID, false); }); | 1455 | ForEachScenePresence(delegate(ScenePresence avatar) { CloseAgent(avatar.UUID, false); }); |
1461 | 1456 | ||
1462 | m_log.Debug("[SCENE]: Persisting changed objects"); | 1457 | m_log.Debug("[SCENE]: TriggerSceneShuttingDown"); |
1463 | EventManager.TriggerSceneShuttingDown(this); | 1458 | EventManager.TriggerSceneShuttingDown(this); |
1459 | |||
1460 | m_log.Debug("[SCENE]: Persisting changed objects"); | ||
1461 | |||
1464 | Backup(false); | 1462 | Backup(false); |
1465 | m_sceneGraph.Close(); | 1463 | m_sceneGraph.Close(); |
1466 | 1464 | ||
@@ -1474,6 +1472,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1474 | // attempt to reference a null or disposed physics scene. | 1472 | // attempt to reference a null or disposed physics scene. |
1475 | if (PhysicsScene != null) | 1473 | if (PhysicsScene != null) |
1476 | { | 1474 | { |
1475 | m_log.Debug("[SCENE]: Dispose Physics"); | ||
1477 | PhysicsScene phys = PhysicsScene; | 1476 | PhysicsScene phys = PhysicsScene; |
1478 | // remove the physics engine from both Scene and SceneGraph | 1477 | // remove the physics engine from both Scene and SceneGraph |
1479 | PhysicsScene = null; | 1478 | PhysicsScene = null; |
@@ -1505,10 +1504,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
1505 | // m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); | 1504 | // m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); |
1506 | if (m_heartbeatThread != null) | 1505 | if (m_heartbeatThread != null) |
1507 | { | 1506 | { |
1507 | m_hbRestarts++; | ||
1508 | if(m_hbRestarts > 10) | ||
1509 | Environment.Exit(1); | ||
1510 | m_log.ErrorFormat("[SCENE]: Restarting heartbeat thread because it hasn't reported in in region {0}", RegionInfo.RegionName); | ||
1511 | |||
1512 | //int pid = System.Diagnostics.Process.GetCurrentProcess().Id; | ||
1513 | //System.Diagnostics.Process proc = new System.Diagnostics.Process(); | ||
1514 | //proc.EnableRaisingEvents=false; | ||
1515 | //proc.StartInfo.FileName = "/bin/kill"; | ||
1516 | //proc.StartInfo.Arguments = "-QUIT " + pid.ToString(); | ||
1517 | //proc.Start(); | ||
1518 | //proc.WaitForExit(); | ||
1519 | //Thread.Sleep(1000); | ||
1520 | //Environment.Exit(1); | ||
1508 | m_heartbeatThread.Abort(); | 1521 | m_heartbeatThread.Abort(); |
1522 | Watchdog.AbortThread(m_heartbeatThread.ManagedThreadId); | ||
1509 | m_heartbeatThread = null; | 1523 | m_heartbeatThread = null; |
1510 | } | 1524 | } |
1511 | 1525 | ||
1526 | // tell physics to finish building actor | ||
1527 | m_sceneGraph.ProcessPhysicsPreSimulation(); | ||
1528 | |||
1512 | m_heartbeatThread | 1529 | m_heartbeatThread |
1513 | = WorkManager.StartThread( | 1530 | = WorkManager.StartThread( |
1514 | Heartbeat, string.Format("Heartbeat-({0})", RegionInfo.RegionName.Replace(" ", "_")), ThreadPriority.Normal, false, false); | 1531 | Heartbeat, string.Format("Heartbeat-({0})", RegionInfo.RegionName.Replace(" ", "_")), ThreadPriority.Normal, false, false); |
@@ -1556,45 +1573,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1556 | 1573 | ||
1557 | Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true; | 1574 | Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true; |
1558 | m_lastFrameTick = Util.EnvironmentTickCount(); | 1575 | m_lastFrameTick = Util.EnvironmentTickCount(); |
1559 | 1576 | Update(-1); | |
1560 | if (UpdateOnTimer) | 1577 | } |
1561 | { | ||
1562 | m_sceneUpdateTimer = new Timer(MinFrameTicks); | ||
1563 | m_sceneUpdateTimer.AutoReset = true; | ||
1564 | m_sceneUpdateTimer.Elapsed += Update; | ||
1565 | m_sceneUpdateTimer.Start(); | ||
1566 | } | ||
1567 | else | ||
1568 | { | ||
1569 | Thread.CurrentThread.Priority = ThreadPriority.Highest; | ||
1570 | Update(-1); | ||
1571 | Watchdog.RemoveThread(); | ||
1572 | m_isRunning = false; | ||
1573 | } | ||
1574 | } | ||
1575 | |||
1576 | private volatile bool m_isTimerUpdateRunning; | ||
1577 | |||
1578 | private void Update(object sender, ElapsedEventArgs e) | ||
1579 | { | ||
1580 | if (m_isTimerUpdateRunning) | ||
1581 | return; | ||
1582 | |||
1583 | m_isTimerUpdateRunning = true; | ||
1584 | |||
1585 | // If the last frame did not complete on time, then immediately start the next update on the same thread | ||
1586 | // and ignore further timed updates until we have a frame that had spare time. | ||
1587 | while (!Update(1) && Active) { } | ||
1588 | |||
1589 | if (!Active || m_shuttingDown) | ||
1590 | { | ||
1591 | m_sceneUpdateTimer.Stop(); | ||
1592 | m_sceneUpdateTimer = null; | ||
1593 | m_isRunning = false; | ||
1594 | } | ||
1595 | |||
1596 | m_isTimerUpdateRunning = false; | ||
1597 | } | ||
1598 | 1578 | ||
1599 | private void Maintenance() | 1579 | private void Maintenance() |
1600 | { | 1580 | { |
@@ -1663,24 +1643,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
1663 | previousMaintenanceTick = m_lastMaintenanceTick; | 1643 | previousMaintenanceTick = m_lastMaintenanceTick; |
1664 | m_lastMaintenanceTick = Util.EnvironmentTickCount(); | 1644 | m_lastMaintenanceTick = Util.EnvironmentTickCount(); |
1665 | runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc); | 1645 | runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc); |
1666 | runtc = MinMaintenanceTicks - runtc; | 1646 | runtc = (int)(MinMaintenanceTime * 1000) - runtc; |
1667 | 1647 | ||
1668 | if (runtc > 0) | 1648 | if (runtc > 0) |
1669 | m_maintenanceWaitEvent.WaitOne(runtc); | 1649 | m_maintenanceWaitEvent.WaitOne(runtc); |
1670 | 1650 | ||
1671 | // Optionally warn if a frame takes double the amount of time that it should. | 1651 | // Optionally warn if a frame takes double the amount of time that it should. |
1672 | if (DebugUpdates | 1652 | if (DebugUpdates |
1673 | && Util.EnvironmentTickCountSubtract( | 1653 | && Util.EnvironmentTickCountSubtract( |
1674 | m_lastMaintenanceTick, previousMaintenanceTick) > MinMaintenanceTicks * 2) | 1654 | m_lastMaintenanceTick, previousMaintenanceTick) > (int)(MinMaintenanceTime * 1000 * 2)) |
1675 | m_log.WarnFormat( | 1655 | m_log.WarnFormat( |
1676 | "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}", | 1656 | "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}", |
1677 | Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick), | 1657 | Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick), |
1678 | MinMaintenanceTicks, | 1658 | MinMaintenanceTime * 1000, |
1679 | RegionInfo.RegionName); | 1659 | RegionInfo.RegionName); |
1680 | } | 1660 | } |
1681 | } | 1661 | } |
1682 | 1662 | ||
1683 | public override bool Update(int frames) | 1663 | public override void Update(int frames) |
1684 | { | 1664 | { |
1685 | long? endFrame = null; | 1665 | long? endFrame = null; |
1686 | 1666 | ||
@@ -1688,119 +1668,76 @@ namespace OpenSim.Region.Framework.Scenes | |||
1688 | endFrame = Frame + frames; | 1668 | endFrame = Frame + frames; |
1689 | 1669 | ||
1690 | float physicsFPS = 0f; | 1670 | float physicsFPS = 0f; |
1691 | int previousFrameTick, tmpMS; | 1671 | |
1692 | 1672 | int previousFrameTick; | |
1693 | // These variables will be used to save the precise frame time using the | 1673 | |
1694 | // Stopwatch class of Microsoft SDK; the times are recorded at the start | 1674 | double tmpMS; |
1695 | // and end of a particular section of code, and then used to calculate | 1675 | double tmpMS2; |
1696 | // the frame times, which are the sums of the sections for each given name | 1676 | double framestart; |
1697 | double preciseTotalFrameTime = 0.0; | 1677 | float sleepMS; |
1698 | double preciseSimFrameTime = 0.0; | ||
1699 | double precisePhysicsFrameTime = 0.0; | ||
1700 | Stopwatch totalFrameStopwatch = new Stopwatch(); | ||
1701 | Stopwatch simFrameStopwatch = new Stopwatch(); | ||
1702 | Stopwatch physicsFrameStopwatch = new Stopwatch(); | ||
1703 | |||
1704 | // Begin the stopwatch to keep track of the time that the frame | ||
1705 | // started running to determine how long the frame took to complete | ||
1706 | totalFrameStopwatch.Start(); | ||
1707 | 1678 | ||
1708 | while (!m_shuttingDown && ((endFrame == null && Active) || Frame < endFrame)) | 1679 | while (!m_shuttingDown && ((endFrame == null && Active) || Frame < endFrame)) |
1709 | { | 1680 | { |
1681 | framestart = Util.GetTimeStampMS(); | ||
1710 | ++Frame; | 1682 | ++Frame; |
1711 | 1683 | ||
1712 | // m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName); | 1684 | // m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName); |
1713 | 1685 | ||
1714 | agentMS = eventMS = backupMS = terrainMS = landMS = spareMS = 0; | 1686 | agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0f; |
1715 | 1687 | ||
1716 | try | 1688 | try |
1717 | { | 1689 | { |
1718 | EventManager.TriggerRegionHeartbeatStart(this); | 1690 | EventManager.TriggerRegionHeartbeatStart(this); |
1719 | 1691 | ||
1720 | // Apply taints in terrain module to terrain in physics scene | 1692 | // Apply taints in terrain module to terrain in physics scene |
1693 | |||
1694 | tmpMS = Util.GetTimeStampMS(); | ||
1695 | |||
1696 | if (Frame % 4 == 0) | ||
1697 | { | ||
1698 | CheckTerrainUpdates(); | ||
1699 | } | ||
1700 | |||
1721 | if (Frame % m_update_terrain == 0) | 1701 | if (Frame % m_update_terrain == 0) |
1722 | { | 1702 | { |
1723 | // At several points inside the code there was a need to | ||
1724 | // create a more precise measurement of time elapsed. | ||
1725 | // This led to the addition of variables that have a | ||
1726 | // similar function and thus remain tightly connected to | ||
1727 | // their original counterparts. However, the original | ||
1728 | // code is not receiving comments from our group because | ||
1729 | // we don't feel right modifying the code to that degree | ||
1730 | // at this point in time, the precise values all begin | ||
1731 | // with the keyword precise | ||
1732 | tmpMS = Util.EnvironmentTickCount(); | ||
1733 | simFrameStopwatch.Start(); | ||
1734 | UpdateTerrain(); | 1703 | UpdateTerrain(); |
1735 | |||
1736 | // Get the simulation frame time that the avatar force | ||
1737 | // input took | ||
1738 | simFrameStopwatch.Stop(); | ||
1739 | preciseSimFrameTime = | ||
1740 | simFrameStopwatch.Elapsed.TotalMilliseconds; | ||
1741 | terrainMS = Util.EnvironmentTickCountSubtract(tmpMS); | ||
1742 | } | 1704 | } |
1743 | 1705 | ||
1744 | // At several points inside the code there was a need to | 1706 | tmpMS2 = Util.GetTimeStampMS(); |
1745 | // create a more precise measurement of time elapsed. This | 1707 | terrainMS = (float)(tmpMS2 - tmpMS); |
1746 | // led to the addition of variables that have a similar | 1708 | tmpMS = tmpMS2; |
1747 | // function and thus remain tightly connected to their | ||
1748 | // original counterparts. However, the original code is | ||
1749 | // not receiving comments from our group because we don't | ||
1750 | // feel right modifying the code to that degree at this | ||
1751 | // point in time, the precise values all begin with the | ||
1752 | // keyword precise | ||
1753 | 1709 | ||
1754 | tmpMS = Util.EnvironmentTickCount(); | ||
1755 | |||
1756 | // Begin the stopwatch to track the time to prepare physics | ||
1757 | physicsFrameStopwatch.Start(); | ||
1758 | if (PhysicsEnabled && Frame % m_update_physics == 0) | 1710 | if (PhysicsEnabled && Frame % m_update_physics == 0) |
1759 | m_sceneGraph.UpdatePreparePhysics(); | 1711 | m_sceneGraph.UpdatePreparePhysics(); |
1760 | 1712 | ||
1761 | // Get the time it took to prepare the physics, this | 1713 | tmpMS2 = Util.GetTimeStampMS(); |
1762 | // would report the most precise time that physics was | 1714 | physicsMS2 = (float)(tmpMS2 - tmpMS); |
1763 | // running on the machine and should the physics not be | 1715 | tmpMS = tmpMS2; |
1764 | // enabled will report the time it took to check if physics | ||
1765 | // was enabled | ||
1766 | physicsFrameStopwatch.Stop(); | ||
1767 | precisePhysicsFrameTime = physicsFrameStopwatch.Elapsed.TotalMilliseconds; | ||
1768 | physicsMS2 = Util.EnvironmentTickCountSubtract(tmpMS); | ||
1769 | 1716 | ||
1770 | // Apply any pending avatar force input to the avatar's velocity | 1717 | // Apply any pending avatar force input to the avatar's velocity |
1771 | tmpMS = Util.EnvironmentTickCount(); | ||
1772 | simFrameStopwatch.Restart(); | ||
1773 | if (Frame % m_update_entitymovement == 0) | 1718 | if (Frame % m_update_entitymovement == 0) |
1774 | m_sceneGraph.UpdateScenePresenceMovement(); | 1719 | m_sceneGraph.UpdateScenePresenceMovement(); |
1775 | 1720 | ||
1776 | // Get the simulation frame time that the avatar force input | 1721 | // Get the simulation frame time that the avatar force input |
1777 | // took | 1722 | // took |
1778 | simFrameStopwatch.Stop(); | 1723 | tmpMS2 = Util.GetTimeStampMS(); |
1779 | preciseSimFrameTime += | 1724 | agentMS = (float)(tmpMS2 - tmpMS); |
1780 | simFrameStopwatch.Elapsed.TotalMilliseconds; | 1725 | tmpMS = tmpMS2; |
1781 | agentMS = Util.EnvironmentTickCountSubtract(tmpMS); | ||
1782 | 1726 | ||
1783 | // Perform the main physics update. This will do the actual work of moving objects and avatars according to their | 1727 | // Perform the main physics update. This will do the actual work of moving objects and avatars according to their |
1784 | // velocity | 1728 | // velocity |
1785 | tmpMS = Util.EnvironmentTickCount(); | ||
1786 | physicsFrameStopwatch.Restart(); | ||
1787 | if (Frame % m_update_physics == 0) | 1729 | if (Frame % m_update_physics == 0) |
1788 | { | 1730 | { |
1789 | if (PhysicsEnabled) | 1731 | if (PhysicsEnabled) |
1790 | physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameSeconds); | 1732 | physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime); |
1791 | 1733 | ||
1792 | if (SynchronizeScene != null) | 1734 | if (SynchronizeScene != null) |
1793 | SynchronizeScene(this); | 1735 | SynchronizeScene(this); |
1794 | } | 1736 | } |
1795 | 1737 | ||
1796 | // Add the main physics update time to the prepare physics time | 1738 | tmpMS2 = Util.GetTimeStampMS(); |
1797 | physicsFrameStopwatch.Stop(); | 1739 | physicsMS = (float)(tmpMS2 - tmpMS); |
1798 | precisePhysicsFrameTime += physicsFrameStopwatch.Elapsed.TotalMilliseconds; | 1740 | tmpMS = tmpMS2; |
1799 | physicsMS = Util.EnvironmentTickCountSubtract(tmpMS); | ||
1800 | |||
1801 | // Start the stopwatch for the remainder of the simulation | ||
1802 | simFrameStopwatch.Restart(); | ||
1803 | tmpMS = Util.EnvironmentTickCount(); | ||
1804 | 1741 | ||
1805 | // Check if any objects have reached their targets | 1742 | // Check if any objects have reached their targets |
1806 | CheckAtTargets(); | 1743 | CheckAtTargets(); |
@@ -1815,20 +1752,37 @@ namespace OpenSim.Region.Framework.Scenes | |||
1815 | if (Frame % m_update_presences == 0) | 1752 | if (Frame % m_update_presences == 0) |
1816 | m_sceneGraph.UpdatePresences(); | 1753 | m_sceneGraph.UpdatePresences(); |
1817 | 1754 | ||
1818 | agentMS += Util.EnvironmentTickCountSubtract(tmpMS); | 1755 | tmpMS2 = Util.GetTimeStampMS(); |
1819 | 1756 | agentMS += (float)(tmpMS2 - tmpMS); | |
1757 | tmpMS = tmpMS2; | ||
1758 | |||
1759 | // Delete temp-on-rez stuff | ||
1760 | if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps) | ||
1761 | { | ||
1762 | |||
1763 | m_cleaningTemps = true; | ||
1764 | Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; }); | ||
1765 | tmpMS2 = Util.GetTimeStampMS(); | ||
1766 | tempOnRezMS = (float)(tmpMS2 - tmpMS); // bad.. counts the FireAndForget, not CleanTempObjects | ||
1767 | tmpMS = tmpMS2; | ||
1768 | } | ||
1769 | |||
1820 | if (Frame % m_update_events == 0) | 1770 | if (Frame % m_update_events == 0) |
1821 | { | 1771 | { |
1822 | tmpMS = Util.EnvironmentTickCount(); | ||
1823 | UpdateEvents(); | 1772 | UpdateEvents(); |
1824 | eventMS = Util.EnvironmentTickCountSubtract(tmpMS); | 1773 | |
1774 | tmpMS2 = Util.GetTimeStampMS(); | ||
1775 | eventMS = (float)(tmpMS2 - tmpMS); | ||
1776 | tmpMS = tmpMS2; | ||
1825 | } | 1777 | } |
1826 | 1778 | ||
1827 | if (PeriodicBackup && Frame % m_update_backup == 0) | 1779 | if (PeriodicBackup && Frame % m_update_backup == 0) |
1828 | { | 1780 | { |
1829 | tmpMS = Util.EnvironmentTickCount(); | ||
1830 | UpdateStorageBackup(); | 1781 | UpdateStorageBackup(); |
1831 | backupMS = Util.EnvironmentTickCountSubtract(tmpMS); | 1782 | |
1783 | tmpMS2 = Util.GetTimeStampMS(); | ||
1784 | backupMS = (float)(tmpMS2 - tmpMS); | ||
1785 | tmpMS = tmpMS2; | ||
1832 | } | 1786 | } |
1833 | 1787 | ||
1834 | //if (Frame % m_update_land == 0) | 1788 | //if (Frame % m_update_land == 0) |
@@ -1885,79 +1839,58 @@ namespace OpenSim.Region.Framework.Scenes | |||
1885 | } | 1839 | } |
1886 | 1840 | ||
1887 | EventManager.TriggerRegionHeartbeatEnd(this); | 1841 | EventManager.TriggerRegionHeartbeatEnd(this); |
1888 | otherMS = eventMS + backupMS + terrainMS + landMS; | ||
1889 | |||
1890 | // Get the elapsed time for the simulation frame | ||
1891 | simFrameStopwatch.Stop(); | ||
1892 | preciseSimFrameTime += | ||
1893 | simFrameStopwatch.Elapsed.TotalMilliseconds; | ||
1894 | |||
1895 | if (!UpdateOnTimer) | ||
1896 | { | ||
1897 | Watchdog.UpdateThread(); | ||
1898 | |||
1899 | spareMS = MinFrameTicks - Util.EnvironmentTickCountSubtract(m_lastFrameTick); | ||
1900 | |||
1901 | if (spareMS > 0) | ||
1902 | m_updateWaitEvent.WaitOne(spareMS); | ||
1903 | else | ||
1904 | spareMS = 0; | ||
1905 | } | ||
1906 | else | ||
1907 | { | ||
1908 | spareMS = Math.Max(0, MinFrameTicks - physicsMS2 - agentMS - physicsMS - otherMS); | ||
1909 | } | ||
1910 | 1842 | ||
1911 | // Get the total frame time | 1843 | Watchdog.UpdateThread(); |
1912 | totalFrameStopwatch.Stop(); | ||
1913 | preciseTotalFrameTime = | ||
1914 | totalFrameStopwatch.Elapsed.TotalMilliseconds; | ||
1915 | 1844 | ||
1916 | // Restart the stopwatch for the total time of the next frame | 1845 | otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS; |
1917 | totalFrameStopwatch.Restart(); | ||
1918 | 1846 | ||
1919 | previousFrameTick = m_lastFrameTick; | ||
1920 | frameMS = Util.EnvironmentTickCountSubtract(m_lastFrameTick); | ||
1921 | m_lastFrameTick = Util.EnvironmentTickCount(); | ||
1922 | |||
1923 | // if (Frame%m_update_avatars == 0) | ||
1924 | // UpdateInWorldTime(); | ||
1925 | StatsReporter.AddPhysicsFPS(physicsFPS); | 1847 | StatsReporter.AddPhysicsFPS(physicsFPS); |
1926 | StatsReporter.AddTimeDilation(TimeDilation); | 1848 | StatsReporter.AddTimeDilation(TimeDilation); |
1927 | StatsReporter.AddFPS(1); | 1849 | StatsReporter.AddFPS(1); |
1928 | 1850 | ||
1929 | StatsReporter.addFrameMS(frameMS); | ||
1930 | StatsReporter.addAgentMS(agentMS); | 1851 | StatsReporter.addAgentMS(agentMS); |
1931 | StatsReporter.addPhysicsMS(physicsMS + physicsMS2); | 1852 | StatsReporter.addPhysicsMS(physicsMS + physicsMS2); |
1932 | StatsReporter.addOtherMS(otherMS); | 1853 | StatsReporter.addOtherMS(otherMS); |
1933 | StatsReporter.AddSpareMS(spareMS); | ||
1934 | StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS()); | 1854 | StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS()); |
1935 | StatsReporter.AddScriptMS((int) GetAndResetScriptExecutionTime()); | ||
1936 | 1855 | ||
1937 | // Send the correct time values to the stats reporter for the | 1856 | |
1938 | // frame times | 1857 | tmpMS = Util.GetTimeStampMS(); |
1939 | StatsReporter.addFrameTimeMilliseconds(preciseTotalFrameTime, | ||
1940 | preciseSimFrameTime, precisePhysicsFrameTime, 0.0); | ||
1941 | 1858 | ||
1942 | // Send the correct number of frames that the physics library | 1859 | previousFrameTick = m_lastFrameTick; |
1943 | // has processed to the stats reporter | 1860 | m_lastFrameTick = (int)(tmpMS + 0.5); |
1944 | StatsReporter.addPhysicsFrame(1); | ||
1945 | 1861 | ||
1946 | // Optionally warn if a frame takes double the amount of time that it should. | 1862 | // estimate sleep time |
1863 | tmpMS2 = tmpMS - framestart; | ||
1864 | tmpMS2 = (double)MinFrameTime * 1000.0D - tmpMS2; | ||
1865 | |||
1866 | m_firstHeartbeat = false; | ||
1867 | |||
1868 | // sleep if we can | ||
1869 | if (tmpMS2 > 0) | ||
1870 | Thread.Sleep((int)(tmpMS2 +0.5)); | ||
1871 | |||
1872 | tmpMS2 = Util.GetTimeStampMS(); | ||
1873 | |||
1874 | sleepMS = (float)(tmpMS2 - tmpMS); | ||
1875 | frameMS = (float)(tmpMS2 - framestart); | ||
1876 | StatsReporter.addSleepMS(sleepMS); | ||
1877 | StatsReporter.addFrameMS(frameMS); | ||
1878 | |||
1879 | // if (Frame%m_update_avatars == 0) | ||
1880 | // UpdateInWorldTime(); | ||
1881 | |||
1882 | // Optionally warn if a frame takes double the amount of time that it should. | ||
1947 | if (DebugUpdates | 1883 | if (DebugUpdates |
1948 | && Util.EnvironmentTickCountSubtract( | 1884 | && Util.EnvironmentTickCountSubtract( |
1949 | m_lastFrameTick, previousFrameTick) > MinFrameTicks * 2) | 1885 | m_lastFrameTick, previousFrameTick) > (int)(MinFrameTime * 1000 * 2)) |
1886 | |||
1950 | m_log.WarnFormat( | 1887 | m_log.WarnFormat( |
1951 | "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}", | 1888 | "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}", |
1952 | Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick), | 1889 | Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick), |
1953 | MinFrameTicks, | 1890 | MinFrameTime * 1000, |
1891 | |||
1954 | RegionInfo.RegionName); | 1892 | RegionInfo.RegionName); |
1955 | } | 1893 | } |
1956 | |||
1957 | // Finished updating scene frame, so stop the total frame's Stopwatch | ||
1958 | totalFrameStopwatch.Stop(); | ||
1959 | |||
1960 | return spareMS >= 0; | ||
1961 | } | 1894 | } |
1962 | 1895 | ||
1963 | /// <summary> | 1896 | /// <summary> |
@@ -1966,24 +1899,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
1966 | /// <param name="ticks">Elapsed Stopwatch ticks</param> | 1899 | /// <param name="ticks">Elapsed Stopwatch ticks</param> |
1967 | public void AddScriptExecutionTime(long ticks) | 1900 | public void AddScriptExecutionTime(long ticks) |
1968 | { | 1901 | { |
1902 | StatsReporter.addScriptEvents(1); | ||
1969 | Interlocked.Add(ref m_scriptExecutionTime, ticks); | 1903 | Interlocked.Add(ref m_scriptExecutionTime, ticks); |
1970 | } | 1904 | } |
1971 | 1905 | ||
1972 | /// <summary> | 1906 | /// <summary> |
1973 | /// Returns the total execution time of all the scripts in the region since the last frame | 1907 | /// Returns the total execution time of all the scripts in the region since the last call |
1974 | /// (in milliseconds), and clears the value in preparation for the next frame. | 1908 | /// (in milliseconds), and clears the value in preparation for the next call. |
1975 | /// </summary> | 1909 | /// </summary> |
1976 | /// <returns>Time in milliseconds</returns> | 1910 | /// <returns>Time in milliseconds</returns> |
1977 | private long GetAndResetScriptExecutionTime() | 1911 | |
1912 | // Warning: this is now called from StatsReporter, and can't be shared | ||
1913 | |||
1914 | public long GetAndResetScriptExecutionTime() | ||
1978 | { | 1915 | { |
1979 | long ticks = Interlocked.Exchange(ref m_scriptExecutionTime, 0); | 1916 | long ticks = Interlocked.Exchange(ref m_scriptExecutionTime, 0); |
1980 | return (ticks * 1000) / Stopwatch.Frequency; | 1917 | return (ticks * 1000L) / Stopwatch.Frequency; |
1981 | } | 1918 | } |
1982 | 1919 | ||
1983 | public void AddGroupTarget(SceneObjectGroup grp) | 1920 | public void AddGroupTarget(SceneObjectGroup grp) |
1984 | { | 1921 | { |
1985 | lock (m_groupsWithTargets) | 1922 | lock (m_groupsWithTargets) |
1986 | m_groupsWithTargets[grp.UUID] = grp; | 1923 | m_groupsWithTargets[grp.UUID] = 0; |
1987 | } | 1924 | } |
1988 | 1925 | ||
1989 | public void RemoveGroupTarget(SceneObjectGroup grp) | 1926 | public void RemoveGroupTarget(SceneObjectGroup grp) |
@@ -1994,18 +1931,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
1994 | 1931 | ||
1995 | private void CheckAtTargets() | 1932 | private void CheckAtTargets() |
1996 | { | 1933 | { |
1997 | List<SceneObjectGroup> objs = null; | 1934 | List<UUID> objs = null; |
1998 | 1935 | ||
1999 | lock (m_groupsWithTargets) | 1936 | lock (m_groupsWithTargets) |
2000 | { | 1937 | { |
2001 | if (m_groupsWithTargets.Count != 0) | 1938 | if (m_groupsWithTargets.Count != 0) |
2002 | objs = new List<SceneObjectGroup>(m_groupsWithTargets.Values); | 1939 | objs = new List<UUID>(m_groupsWithTargets.Keys); |
2003 | } | 1940 | } |
2004 | 1941 | ||
2005 | if (objs != null) | 1942 | if (objs != null) |
2006 | { | 1943 | { |
2007 | foreach (SceneObjectGroup entry in objs) | 1944 | foreach (UUID entry in objs) |
2008 | entry.checkAtTargets(); | 1945 | { |
1946 | SceneObjectGroup grp = GetSceneObjectGroup(entry); | ||
1947 | if (grp == null) | ||
1948 | m_groupsWithTargets.Remove(entry); | ||
1949 | else | ||
1950 | grp.checkAtTargets(); | ||
1951 | } | ||
2009 | } | 1952 | } |
2010 | } | 1953 | } |
2011 | 1954 | ||
@@ -2029,6 +1972,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
2029 | EventManager.TriggerTerrainTick(); | 1972 | EventManager.TriggerTerrainTick(); |
2030 | } | 1973 | } |
2031 | 1974 | ||
1975 | private void CheckTerrainUpdates() | ||
1976 | { | ||
1977 | EventManager.TriggerTerrainCheckUpdates(); | ||
1978 | } | ||
1979 | |||
2032 | /// <summary> | 1980 | /// <summary> |
2033 | /// Back up queued up changes | 1981 | /// Back up queued up changes |
2034 | /// </summary> | 1982 | /// </summary> |
@@ -2080,7 +2028,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2080 | msg.fromAgentName = "Server"; | 2028 | msg.fromAgentName = "Server"; |
2081 | msg.dialog = (byte)19; // Object msg | 2029 | msg.dialog = (byte)19; // Object msg |
2082 | msg.fromGroup = false; | 2030 | msg.fromGroup = false; |
2083 | msg.offline = (byte)0; | 2031 | msg.offline = (byte)1; |
2084 | msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID; | 2032 | msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID; |
2085 | msg.Position = Vector3.Zero; | 2033 | msg.Position = Vector3.Zero; |
2086 | msg.RegionID = RegionInfo.RegionID.Guid; | 2034 | msg.RegionID = RegionInfo.RegionID.Guid; |
@@ -2232,7 +2180,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2232 | //// stored in the GridService, because that's what the world map module uses | 2180 | //// stored in the GridService, because that's what the world map module uses |
2233 | //// to send the map image UUIDs (of other regions) to the viewer... | 2181 | //// to send the map image UUIDs (of other regions) to the viewer... |
2234 | if (m_generateMaptiles) | 2182 | if (m_generateMaptiles) |
2235 | RegenerateMaptile(); | 2183 | RegenerateMaptile(); |
2236 | 2184 | ||
2237 | GridRegion region = new GridRegion(RegionInfo); | 2185 | GridRegion region = new GridRegion(RegionInfo); |
2238 | string error = GridService.RegisterRegion(RegionInfo.ScopeID, region); | 2186 | string error = GridService.RegisterRegion(RegionInfo.ScopeID, region); |
@@ -2316,7 +2264,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2316 | return PhysicsScene.SupportsRaycastWorldFiltered(); | 2264 | return PhysicsScene.SupportsRaycastWorldFiltered(); |
2317 | } | 2265 | } |
2318 | 2266 | ||
2319 | public object RayCastFiltered(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter) | 2267 | public object RayCastFiltered(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter) |
2320 | { | 2268 | { |
2321 | if (PhysicsScene == null) | 2269 | if (PhysicsScene == null) |
2322 | return null; | 2270 | return null; |
@@ -2338,93 +2286,166 @@ namespace OpenSim.Region.Framework.Scenes | |||
2338 | /// <returns></returns> | 2286 | /// <returns></returns> |
2339 | public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter) | 2287 | public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter) |
2340 | { | 2288 | { |
2341 | Vector3 pos = Vector3.Zero; | ||
2342 | if (RayEndIsIntersection == (byte)1) | ||
2343 | { | ||
2344 | pos = RayEnd; | ||
2345 | return pos; | ||
2346 | } | ||
2347 | 2289 | ||
2348 | if (RayTargetID != UUID.Zero) | 2290 | Vector3 dir = RayEnd - RayStart; |
2291 | |||
2292 | float wheight = (float)RegionInfo.RegionSettings.WaterHeight; | ||
2293 | Vector3 wpos = Vector3.Zero; | ||
2294 | // Check for water surface intersection from above | ||
2295 | if ((RayStart.Z > wheight) && (RayEnd.Z < wheight)) | ||
2349 | { | 2296 | { |
2350 | SceneObjectPart target = GetSceneObjectPart(RayTargetID); | 2297 | float ratio = (wheight - RayStart.Z) / dir.Z; |
2298 | wpos.X = RayStart.X + (ratio * dir.X); | ||
2299 | wpos.Y = RayStart.Y + (ratio * dir.Y); | ||
2300 | wpos.Z = wheight; | ||
2301 | } | ||
2351 | 2302 | ||
2352 | Vector3 direction = Vector3.Normalize(RayEnd - RayStart); | 2303 | Vector3 pos = Vector3.Zero; |
2353 | Vector3 AXOrigin = RayStart; | ||
2354 | Vector3 AXdirection = direction; | ||
2355 | 2304 | ||
2356 | if (target != null) | 2305 | if (RayEndIsIntersection != (byte)1) |
2306 | { | ||
2307 | float dist = dir.Length(); | ||
2308 | if (dist != 0) | ||
2357 | { | 2309 | { |
2358 | pos = target.AbsolutePosition; | 2310 | Vector3 direction = dir * (1 / dist); |
2359 | //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()); | ||
2360 | 2311 | ||
2361 | // TODO: Raytrace better here | 2312 | dist += 1.0f; |
2362 | 2313 | ||
2363 | //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection)); | 2314 | if (SupportsRayCastFiltered()) |
2364 | Ray NewRay = new Ray(AXOrigin, AXdirection); | 2315 | { |
2316 | RayFilterFlags rayfilter = RayFilterFlags.BackFaceCull; | ||
2317 | rayfilter |= RayFilterFlags.land; | ||
2318 | rayfilter |= RayFilterFlags.physical; | ||
2319 | rayfilter |= RayFilterFlags.nonphysical; | ||
2320 | rayfilter |= RayFilterFlags.LSLPhantom; // ubODE will only see volume detectors | ||
2321 | |||
2322 | // get some more contacts ??? | ||
2323 | int physcount = 4; | ||
2324 | |||
2325 | List<ContactResult> physresults = | ||
2326 | (List<ContactResult>)RayCastFiltered(RayStart, direction, dist, physcount, rayfilter); | ||
2327 | if (physresults != null && physresults.Count > 0) | ||
2328 | { | ||
2329 | // look for terrain ? | ||
2330 | if(RayTargetID == UUID.Zero) | ||
2331 | { | ||
2332 | foreach (ContactResult r in physresults) | ||
2333 | { | ||
2334 | if (r.ConsumerID == 0) | ||
2335 | { | ||
2336 | pos = r.Normal * scale; | ||
2337 | pos *= 0.5f; | ||
2338 | pos = r.Pos + pos; | ||
2339 | |||
2340 | if (wpos.Z > pos.Z) pos = wpos; | ||
2341 | return pos; | ||
2342 | } | ||
2343 | } | ||
2344 | } | ||
2345 | else | ||
2346 | { | ||
2347 | foreach (ContactResult r in physresults) | ||
2348 | { | ||
2349 | SceneObjectPart part = GetSceneObjectPart(r.ConsumerID); | ||
2350 | if (part == null) | ||
2351 | continue; | ||
2352 | if (part.UUID == RayTargetID) | ||
2353 | { | ||
2354 | pos = r.Normal * scale; | ||
2355 | pos *= 0.5f; | ||
2356 | pos = r.Pos + pos; | ||
2357 | |||
2358 | if (wpos.Z > pos.Z) pos = wpos; | ||
2359 | return pos; | ||
2360 | } | ||
2361 | } | ||
2362 | } | ||
2363 | // else the first we got | ||
2364 | pos = physresults[0].Normal * scale; | ||
2365 | pos *= 0.5f; | ||
2366 | pos = physresults[0].Pos + pos; | ||
2367 | |||
2368 | if (wpos.Z > pos.Z) | ||
2369 | pos = wpos; | ||
2370 | return pos; | ||
2371 | } | ||
2365 | 2372 | ||
2366 | // Ray Trace against target here | 2373 | } |
2367 | EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter); | 2374 | if (RayTargetID != UUID.Zero) |
2375 | { | ||
2376 | SceneObjectPart target = GetSceneObjectPart(RayTargetID); | ||
2368 | 2377 | ||
2369 | // Un-comment out the following line to Get Raytrace results printed to the console. | 2378 | Ray NewRay = new Ray(RayStart, direction); |
2370 | // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); | ||
2371 | float ScaleOffset = 0.5f; | ||
2372 | 2379 | ||
2373 | // If we hit something | 2380 | if (target != null) |
2374 | if (ei.HitTF) | 2381 | { |
2375 | { | 2382 | pos = target.AbsolutePosition; |
2376 | Vector3 scaleComponent = ei.AAfaceNormal; | ||
2377 | if (scaleComponent.X != 0) ScaleOffset = scale.X; | ||
2378 | if (scaleComponent.Y != 0) ScaleOffset = scale.Y; | ||
2379 | if (scaleComponent.Z != 0) ScaleOffset = scale.Z; | ||
2380 | ScaleOffset = Math.Abs(ScaleOffset); | ||
2381 | Vector3 intersectionpoint = ei.ipoint; | ||
2382 | Vector3 normal = ei.normal; | ||
2383 | // Set the position to the intersection point | ||
2384 | Vector3 offset = (normal * (ScaleOffset / 2f)); | ||
2385 | pos = (intersectionpoint + offset); | ||
2386 | |||
2387 | //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 | ||
2388 | //And in cases when we weren't rezzing from inventory we were re-adding the 0.25 straight after calling this method | ||
2389 | // Un-offset the prim (it gets offset later by the consumer method) | ||
2390 | //pos.Z -= 0.25F; | ||
2391 | 2383 | ||
2392 | } | 2384 | // Ray Trace against target here |
2385 | EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter); | ||
2393 | 2386 | ||
2394 | return pos; | 2387 | // Un-comment out the following line to Get Raytrace results printed to the console. |
2395 | } | 2388 | // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); |
2396 | else | 2389 | float ScaleOffset = 0.5f; |
2397 | { | ||
2398 | // We don't have a target here, so we're going to raytrace all the objects in the scene. | ||
2399 | 2390 | ||
2400 | EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false); | 2391 | // If we hit something |
2392 | if (ei.HitTF) | ||
2393 | { | ||
2394 | Vector3 scaleComponent = ei.AAfaceNormal; | ||
2395 | if (scaleComponent.X != 0) ScaleOffset = scale.X; | ||
2396 | if (scaleComponent.Y != 0) ScaleOffset = scale.Y; | ||
2397 | if (scaleComponent.Z != 0) ScaleOffset = scale.Z; | ||
2398 | ScaleOffset = Math.Abs(ScaleOffset); | ||
2399 | Vector3 intersectionpoint = ei.ipoint; | ||
2400 | Vector3 normal = ei.normal; | ||
2401 | // Set the position to the intersection point | ||
2402 | Vector3 offset = (normal * (ScaleOffset / 2f)); | ||
2403 | pos = (intersectionpoint + offset); | ||
2404 | |||
2405 | //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 | ||
2406 | //And in cases when we weren't rezzing from inventory we were re-adding the 0.25 straight after calling this method | ||
2407 | // Un-offset the prim (it gets offset later by the consumer method) | ||
2408 | //pos.Z -= 0.25F; | ||
2409 | |||
2410 | if (wpos.Z > pos.Z) pos = wpos; | ||
2411 | return pos; | ||
2412 | } | ||
2413 | } | ||
2414 | else | ||
2415 | { | ||
2416 | // We don't have a target here, so we're going to raytrace all the objects in the scene. | ||
2417 | EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(NewRay, true, false); | ||
2401 | 2418 | ||
2402 | // Un-comment the following line to print the raytrace results to the console. | 2419 | // Un-comment the following line to print the raytrace results to the console. |
2403 | //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); | 2420 | //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); |
2404 | 2421 | ||
2405 | if (ei.HitTF) | 2422 | if (ei.HitTF) |
2406 | { | 2423 | { |
2407 | pos = ei.ipoint; | 2424 | pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); |
2408 | } | 2425 | } |
2409 | else | 2426 | else |
2410 | { | 2427 | { |
2411 | // fall back to our stupid functionality | 2428 | // fall back to our stupid functionality |
2412 | pos = RayEnd; | 2429 | pos = RayEnd; |
2413 | } | 2430 | } |
2414 | 2431 | ||
2415 | return pos; | 2432 | if (wpos.Z > pos.Z) pos = wpos; |
2433 | return pos; | ||
2434 | } | ||
2435 | } | ||
2416 | } | 2436 | } |
2417 | } | 2437 | } |
2418 | else | ||
2419 | { | ||
2420 | // fall back to our stupid functionality | ||
2421 | pos = RayEnd; | ||
2422 | 2438 | ||
2423 | //increase height so its above the ground. | 2439 | // fall back to our stupid functionality |
2424 | //should be getting the normal of the ground at the rez point and using that? | 2440 | pos = RayEnd; |
2425 | pos.Z += scale.Z / 2f; | 2441 | |
2426 | return pos; | 2442 | //increase height so its above the ground. |
2427 | } | 2443 | //should be getting the normal of the ground at the rez point and using that? |
2444 | pos.Z += scale.Z / 2f; | ||
2445 | // return pos; | ||
2446 | // check against posible water intercept | ||
2447 | if (wpos.Z > pos.Z) pos = wpos; | ||
2448 | return pos; | ||
2428 | } | 2449 | } |
2429 | 2450 | ||
2430 | 2451 | ||
@@ -2515,12 +2536,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2515 | { | 2536 | { |
2516 | if (m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates)) | 2537 | if (m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates)) |
2517 | { | 2538 | { |
2539 | sceneObject.IsDeleted = false; | ||
2518 | EventManager.TriggerObjectAddedToScene(sceneObject); | 2540 | EventManager.TriggerObjectAddedToScene(sceneObject); |
2519 | return true; | 2541 | return true; |
2520 | } | 2542 | } |
2521 | 2543 | ||
2522 | return false; | 2544 | return false; |
2523 | |||
2524 | } | 2545 | } |
2525 | 2546 | ||
2526 | /// <summary> | 2547 | /// <summary> |
@@ -2612,6 +2633,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
2612 | /// </summary> | 2633 | /// </summary> |
2613 | public void DeleteAllSceneObjects() | 2634 | public void DeleteAllSceneObjects() |
2614 | { | 2635 | { |
2636 | DeleteAllSceneObjects(false); | ||
2637 | } | ||
2638 | |||
2639 | /// <summary> | ||
2640 | /// Delete every object from the scene. This does not include attachments worn by avatars. | ||
2641 | /// </summary> | ||
2642 | public void DeleteAllSceneObjects(bool exceptNoCopy) | ||
2643 | { | ||
2644 | List<SceneObjectGroup> toReturn = new List<SceneObjectGroup>(); | ||
2615 | lock (Entities) | 2645 | lock (Entities) |
2616 | { | 2646 | { |
2617 | EntityBase[] entities = Entities.GetEntities(); | 2647 | EntityBase[] entities = Entities.GetEntities(); |
@@ -2620,11 +2650,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
2620 | if (e is SceneObjectGroup) | 2650 | if (e is SceneObjectGroup) |
2621 | { | 2651 | { |
2622 | SceneObjectGroup sog = (SceneObjectGroup)e; | 2652 | SceneObjectGroup sog = (SceneObjectGroup)e; |
2623 | if (!sog.IsAttachment) | 2653 | if (sog != null && !sog.IsAttachment) |
2624 | DeleteSceneObject((SceneObjectGroup)e, false); | 2654 | { |
2655 | if (!exceptNoCopy || ((sog.GetEffectivePermissions() & (uint)PermissionMask.Copy) != 0)) | ||
2656 | { | ||
2657 | DeleteSceneObject((SceneObjectGroup)e, false); | ||
2658 | } | ||
2659 | else | ||
2660 | { | ||
2661 | toReturn.Add((SceneObjectGroup)e); | ||
2662 | } | ||
2663 | } | ||
2625 | } | 2664 | } |
2626 | } | 2665 | } |
2627 | } | 2666 | } |
2667 | if (toReturn.Count > 0) | ||
2668 | { | ||
2669 | returnObjects(toReturn.ToArray(), UUID.Zero); | ||
2670 | } | ||
2628 | } | 2671 | } |
2629 | 2672 | ||
2630 | /// <summary> | 2673 | /// <summary> |
@@ -2655,6 +2698,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2655 | else | 2698 | else |
2656 | group.StopScriptInstances(); | 2699 | group.StopScriptInstances(); |
2657 | 2700 | ||
2701 | List<ScenePresence> avatars = group.GetSittingAvatars(); | ||
2702 | foreach (ScenePresence av in avatars) | ||
2703 | { | ||
2704 | if(av.ParentUUID == UUID.Zero) | ||
2705 | av.StandUp(); | ||
2706 | } | ||
2707 | |||
2658 | SceneObjectPart[] partList = group.Parts; | 2708 | SceneObjectPart[] partList = group.Parts; |
2659 | 2709 | ||
2660 | foreach (SceneObjectPart part in partList) | 2710 | foreach (SceneObjectPart part in partList) |
@@ -2682,6 +2732,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2682 | } | 2732 | } |
2683 | 2733 | ||
2684 | group.DeleteGroupFromScene(silent); | 2734 | group.DeleteGroupFromScene(silent); |
2735 | if (!silent) | ||
2736 | SendKillObject(new List<uint>() { group.LocalId }); | ||
2685 | 2737 | ||
2686 | // m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); | 2738 | // m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); |
2687 | } | 2739 | } |
@@ -2718,6 +2770,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2718 | return false; | 2770 | return false; |
2719 | } | 2771 | } |
2720 | 2772 | ||
2773 | |||
2774 | public void updateScenePartGroup(SceneObjectPart part, SceneObjectGroup grp) | ||
2775 | { | ||
2776 | m_sceneGraph.updateScenePartGroup(part, grp); | ||
2777 | } | ||
2778 | |||
2779 | /* not in use, outdate by async method | ||
2721 | /// <summary> | 2780 | /// <summary> |
2722 | /// Move the given scene object into a new region depending on which region its absolute position has moved | 2781 | /// Move the given scene object into a new region depending on which region its absolute position has moved |
2723 | /// into. | 2782 | /// into. |
@@ -2766,6 +2825,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2766 | if (EntityTransferModule != null) | 2825 | if (EntityTransferModule != null) |
2767 | EntityTransferModule.Cross(grp, attemptedPosition, silent); | 2826 | EntityTransferModule.Cross(grp, attemptedPosition, silent); |
2768 | } | 2827 | } |
2828 | */ | ||
2769 | 2829 | ||
2770 | // Simple test to see if a position is in the current region. | 2830 | // Simple test to see if a position is in the current region. |
2771 | // This test is mostly used to see if a region crossing is necessary. | 2831 | // This test is mostly used to see if a region crossing is necessary. |
@@ -2783,7 +2843,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2783 | if (regionCombinerModule == null) | 2843 | if (regionCombinerModule == null) |
2784 | { | 2844 | { |
2785 | // Regular region. Just check for region size | 2845 | // Regular region. Just check for region size |
2786 | if (xx < RegionInfo.RegionSizeX && yy < RegionInfo.RegionSizeY) | 2846 | if (xx < RegionInfo.RegionSizeX && yy < RegionInfo.RegionSizeY ) |
2787 | ret = true; | 2847 | ret = true; |
2788 | } | 2848 | } |
2789 | else | 2849 | else |
@@ -2791,9 +2851,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2791 | // We're in a mega-region so see if we are still in that larger region | 2851 | // We're in a mega-region so see if we are still in that larger region |
2792 | ret = regionCombinerModule.PositionIsInMegaregion(this.RegionInfo.RegionID, xx, yy); | 2852 | ret = regionCombinerModule.PositionIsInMegaregion(this.RegionInfo.RegionID, xx, yy); |
2793 | } | 2853 | } |
2794 | |||
2795 | return ret; | 2854 | return ret; |
2796 | |||
2797 | } | 2855 | } |
2798 | 2856 | ||
2799 | /// <summary> | 2857 | /// <summary> |
@@ -2817,8 +2875,52 @@ namespace OpenSim.Region.Framework.Scenes | |||
2817 | return false; | 2875 | return false; |
2818 | } | 2876 | } |
2819 | 2877 | ||
2820 | if (!EntityTransferModule.HandleIncomingSceneObject(newObject, newPosition)) | 2878 | // If the user is banned, we won't let any of their objects |
2879 | // enter. Period. | ||
2880 | // | ||
2881 | if (RegionInfo.EstateSettings.IsBanned(newObject.OwnerID, 36)) | ||
2882 | { | ||
2883 | m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", newObject.OwnerID); | ||
2884 | return false; | ||
2885 | } | ||
2886 | |||
2887 | if (newPosition != Vector3.Zero) | ||
2888 | newObject.RootPart.GroupPosition = newPosition; | ||
2889 | |||
2890 | if (!AddSceneObject(newObject)) | ||
2891 | { | ||
2892 | m_log.DebugFormat( | ||
2893 | "[INTERREGION]: Problem adding scene object {0} in {1} ", newObject.UUID, RegionInfo.RegionName); | ||
2821 | return false; | 2894 | return false; |
2895 | } | ||
2896 | |||
2897 | if (!newObject.IsAttachment) | ||
2898 | { | ||
2899 | // FIXME: It would be better to never add the scene object at all rather than add it and then delete | ||
2900 | // it | ||
2901 | if (!Permissions.CanObjectEntry(newObject.UUID, true, newObject.AbsolutePosition)) | ||
2902 | { | ||
2903 | // Deny non attachments based on parcel settings | ||
2904 | // | ||
2905 | m_log.Info("[INTERREGION]: Denied prim crossing because of parcel settings"); | ||
2906 | |||
2907 | DeleteSceneObject(newObject, false); | ||
2908 | |||
2909 | return false; | ||
2910 | } | ||
2911 | |||
2912 | // For attachments, we need to wait until the agent is root | ||
2913 | // before we restart the scripts, or else some functions won't work. | ||
2914 | newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); | ||
2915 | newObject.ResumeScripts(); | ||
2916 | |||
2917 | // AddSceneObject already does this and doing it again messes | ||
2918 | // up region crossings, so don't. | ||
2919 | //if (newObject.RootPart.KeyframeMotion != null) | ||
2920 | // newObject.RootPart.KeyframeMotion.UpdateSceneObject(newObject); | ||
2921 | } | ||
2922 | |||
2923 | |||
2822 | 2924 | ||
2823 | // Do this as late as possible so that listeners have full access to the incoming object | 2925 | // Do this as late as possible so that listeners have full access to the incoming object |
2824 | EventManager.TriggerOnIncomingSceneObject(newObject); | 2926 | EventManager.TriggerOnIncomingSceneObject(newObject); |
@@ -2835,6 +2937,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
2835 | /// <returns>True if the SceneObjectGroup was added, False if it was not</returns> | 2937 | /// <returns>True if the SceneObjectGroup was added, False if it was not</returns> |
2836 | public bool AddSceneObject(SceneObjectGroup sceneObject) | 2938 | public bool AddSceneObject(SceneObjectGroup sceneObject) |
2837 | { | 2939 | { |
2940 | if (sceneObject.OwnerID == UUID.Zero) | ||
2941 | { | ||
2942 | m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero", sceneObject.UUID); | ||
2943 | return false; | ||
2944 | } | ||
2945 | |||
2946 | // If the user is banned, we won't let any of their objects | ||
2947 | // enter. Period. | ||
2948 | // | ||
2949 | int flags = GetUserFlags(sceneObject.OwnerID); | ||
2950 | if (RegionInfo.EstateSettings.IsBanned(sceneObject.OwnerID, flags)) | ||
2951 | { | ||
2952 | m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", sceneObject.OwnerID); | ||
2953 | |||
2954 | return false; | ||
2955 | } | ||
2956 | |||
2838 | // Force allocation of new LocalId | 2957 | // Force allocation of new LocalId |
2839 | // | 2958 | // |
2840 | SceneObjectPart[] parts = sceneObject.Parts; | 2959 | SceneObjectPart[] parts = sceneObject.Parts; |
@@ -2871,22 +2990,62 @@ namespace OpenSim.Region.Framework.Scenes | |||
2871 | // information that this is due to a teleport/border cross rather than an ordinary attachment. | 2990 | // information that this is due to a teleport/border cross rather than an ordinary attachment. |
2872 | // We currently do this in Scene.MakeRootAgent() instead. | 2991 | // We currently do this in Scene.MakeRootAgent() instead. |
2873 | if (AttachmentsModule != null) | 2992 | if (AttachmentsModule != null) |
2874 | AttachmentsModule.AttachObject(sp, grp, 0, false, false, true); | 2993 | AttachmentsModule.AttachObject(sp, grp, 0, false, false, false, true); |
2875 | } | 2994 | } |
2876 | else | 2995 | else |
2877 | { | 2996 | { |
2997 | m_log.DebugFormat("[SCENE]: Attachment {0} arrived and scene presence was not found, setting to temp", sceneObject.UUID); | ||
2878 | RootPrim.RemFlag(PrimFlags.TemporaryOnRez); | 2998 | RootPrim.RemFlag(PrimFlags.TemporaryOnRez); |
2879 | RootPrim.AddFlag(PrimFlags.TemporaryOnRez); | 2999 | RootPrim.AddFlag(PrimFlags.TemporaryOnRez); |
2880 | } | 3000 | } |
3001 | if (sceneObject.OwnerID == UUID.Zero) | ||
3002 | { | ||
3003 | m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero after attachment processing. BUG!", sceneObject.UUID); | ||
3004 | return false; | ||
3005 | } | ||
2881 | } | 3006 | } |
2882 | else | 3007 | else |
2883 | { | 3008 | { |
3009 | if (sceneObject.OwnerID == UUID.Zero) | ||
3010 | { | ||
3011 | m_log.ErrorFormat("[SCENE]: Owner ID for non-attachment {0} was zero", sceneObject.UUID); | ||
3012 | return false; | ||
3013 | } | ||
2884 | AddRestoredSceneObject(sceneObject, true, false); | 3014 | AddRestoredSceneObject(sceneObject, true, false); |
2885 | } | 3015 | } |
2886 | 3016 | ||
2887 | return true; | 3017 | return true; |
2888 | } | 3018 | } |
2889 | 3019 | ||
3020 | private int GetStateSource(SceneObjectGroup sog) | ||
3021 | { | ||
3022 | ScenePresence sp = GetScenePresence(sog.OwnerID); | ||
3023 | |||
3024 | if (sp != null) | ||
3025 | return sp.GetStateSource(); | ||
3026 | |||
3027 | return 2; // StateSource.PrimCrossing | ||
3028 | } | ||
3029 | |||
3030 | public int GetUserFlags(UUID user) | ||
3031 | { | ||
3032 | //Unfortunately the SP approach means that the value is cached until region is restarted | ||
3033 | /* | ||
3034 | ScenePresence sp; | ||
3035 | if (TryGetScenePresence(user, out sp)) | ||
3036 | { | ||
3037 | return sp.UserFlags; | ||
3038 | } | ||
3039 | else | ||
3040 | { | ||
3041 | */ | ||
3042 | UserAccount uac = UserAccountService.GetUserAccount(RegionInfo.ScopeID, user); | ||
3043 | if (uac == null) | ||
3044 | return 0; | ||
3045 | return uac.UserFlags; | ||
3046 | //} | ||
3047 | } | ||
3048 | |||
2890 | #endregion | 3049 | #endregion |
2891 | 3050 | ||
2892 | #region Add/Remove Avatar Methods | 3051 | #region Add/Remove Avatar Methods |
@@ -2922,8 +3081,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2922 | vialogin | 3081 | vialogin |
2923 | = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 | 3082 | = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 |
2924 | || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; | 3083 | || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; |
2925 | 3084 | ||
2926 | // CheckHeartbeat(); | 3085 | CheckHeartbeat(); |
3086 | |||
2927 | 3087 | ||
2928 | sp = GetScenePresence(client.AgentId); | 3088 | sp = GetScenePresence(client.AgentId); |
2929 | 3089 | ||
@@ -2934,27 +3094,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
2934 | if (sp == null) | 3094 | if (sp == null) |
2935 | { | 3095 | { |
2936 | m_log.DebugFormat( | 3096 | m_log.DebugFormat( |
2937 | "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", | 3097 | "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}, tpflags: {4}", |
2938 | client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); | 3098 | client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos, |
2939 | 3099 | ((TPFlags)aCircuit.teleportFlags).ToString()); | |
2940 | sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type); | 3100 | |
2941 | |||
2942 | // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the | ||
2943 | // client is for a root or child agent. | ||
2944 | // We must also set this before adding the client to the client manager so that an exception later on | ||
2945 | // does not leave a client manager entry without the scene agent set, which will cause other code | ||
2946 | // to fail since any entry in the client manager should have a ScenePresence | ||
2947 | // | ||
2948 | // XXX: This may be better set for a new client before that client is added to the client manager. | ||
2949 | // But need to know what happens in the case where a ScenePresence is already present (and if this | ||
2950 | // actually occurs). | ||
2951 | client.SceneAgent = sp; | ||
2952 | |||
2953 | m_clientManager.Add(client); | 3101 | m_clientManager.Add(client); |
2954 | SubscribeToClientEvents(client); | 3102 | SubscribeToClientEvents(client); |
2955 | m_eventManager.TriggerOnNewPresence(sp); | 3103 | |
3104 | sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type); | ||
2956 | 3105 | ||
2957 | sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags; | 3106 | sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags; |
3107 | |||
3108 | /* done in completMovement | ||
3109 | InventoryFolderBase cof = InventoryService.GetFolderForType(client.AgentId, (AssetType)46); | ||
3110 | if (cof == null) | ||
3111 | sp.COF = UUID.Zero; | ||
3112 | else | ||
3113 | sp.COF = cof.ID; | ||
3114 | |||
3115 | m_log.DebugFormat("[SCENE]: COF for {0} is {1}", client.AgentId, sp.COF); | ||
3116 | */ | ||
3117 | m_eventManager.TriggerOnNewPresence(sp); | ||
2958 | } | 3118 | } |
2959 | else | 3119 | else |
2960 | { | 3120 | { |
@@ -2963,7 +3123,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2963 | // XXX: This may be better set for a new client before that client is added to the client manager. | 3123 | // XXX: This may be better set for a new client before that client is added to the client manager. |
2964 | // But need to know what happens in the case where a ScenePresence is already present (and if this | 3124 | // But need to know what happens in the case where a ScenePresence is already present (and if this |
2965 | // actually occurs). | 3125 | // actually occurs). |
2966 | client.SceneAgent = sp; | 3126 | |
2967 | 3127 | ||
2968 | m_log.WarnFormat( | 3128 | m_log.WarnFormat( |
2969 | "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", | 3129 | "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", |
@@ -2971,6 +3131,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2971 | 3131 | ||
2972 | reallyNew = false; | 3132 | reallyNew = false; |
2973 | } | 3133 | } |
3134 | client.SceneAgent = sp; | ||
2974 | 3135 | ||
2975 | // This is currently also being done earlier in NewUserConnection for real users to see if this | 3136 | // This is currently also being done earlier in NewUserConnection for real users to see if this |
2976 | // resolves problems where HG agents are occasionally seen by others as "Unknown user" in chat and other | 3137 | // resolves problems where HG agents are occasionally seen by others as "Unknown user" in chat and other |
@@ -3089,19 +3250,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
3089 | // and the scene presence and the client, if they exist | 3250 | // and the scene presence and the client, if they exist |
3090 | try | 3251 | try |
3091 | { | 3252 | { |
3092 | // We need to wait for the client to make UDP contact first. | ||
3093 | // It's the UDP contact that creates the scene presence | ||
3094 | ScenePresence sp = WaitGetScenePresence(agentID); | 3253 | ScenePresence sp = WaitGetScenePresence(agentID); |
3254 | |||
3095 | if (sp != null) | 3255 | if (sp != null) |
3096 | { | 3256 | { |
3097 | PresenceService.LogoutAgent(sp.ControllingClient.SessionId); | 3257 | PresenceService.LogoutAgent(sp.ControllingClient.SessionId); |
3098 | 3258 | ||
3099 | CloseAgent(sp.UUID, false); | 3259 | CloseAgent(sp.UUID, false); |
3100 | } | 3260 | } |
3101 | else | 3261 | |
3102 | { | ||
3103 | m_log.WarnFormat("[SCENE]: Could not find scene presence for {0}", agentID); | ||
3104 | } | ||
3105 | // BANG! SLASH! | 3262 | // BANG! SLASH! |
3106 | m_authenticateHandler.RemoveCircuit(agentID); | 3263 | m_authenticateHandler.RemoveCircuit(agentID); |
3107 | 3264 | ||
@@ -3138,7 +3295,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3138 | 3295 | ||
3139 | public virtual void SubscribeToClientTerrainEvents(IClientAPI client) | 3296 | public virtual void SubscribeToClientTerrainEvents(IClientAPI client) |
3140 | { | 3297 | { |
3141 | client.OnRegionHandShakeReply += SendLayerData; | 3298 | // client.OnRegionHandShakeReply += SendLayerData; |
3142 | } | 3299 | } |
3143 | 3300 | ||
3144 | public virtual void SubscribeToClientPrimEvents(IClientAPI client) | 3301 | public virtual void SubscribeToClientPrimEvents(IClientAPI client) |
@@ -3146,6 +3303,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3146 | client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimGroupPosition; | 3303 | client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimGroupPosition; |
3147 | client.OnUpdatePrimSinglePosition += m_sceneGraph.UpdatePrimSinglePosition; | 3304 | client.OnUpdatePrimSinglePosition += m_sceneGraph.UpdatePrimSinglePosition; |
3148 | 3305 | ||
3306 | client.onClientChangeObject += m_sceneGraph.ClientChangeObject; | ||
3307 | |||
3149 | client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimGroupRotation; | 3308 | client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimGroupRotation; |
3150 | client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimGroupRotation; | 3309 | client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimGroupRotation; |
3151 | client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation; | 3310 | client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation; |
@@ -3202,6 +3361,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3202 | client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory; | 3361 | client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory; |
3203 | client.OnUpdateInventoryItem += UpdateInventoryItemAsset; | 3362 | client.OnUpdateInventoryItem += UpdateInventoryItemAsset; |
3204 | client.OnCopyInventoryItem += CopyInventoryItem; | 3363 | client.OnCopyInventoryItem += CopyInventoryItem; |
3364 | client.OnMoveItemsAndLeaveCopy += MoveInventoryItemsLeaveCopy; | ||
3205 | client.OnMoveInventoryItem += MoveInventoryItem; | 3365 | client.OnMoveInventoryItem += MoveInventoryItem; |
3206 | client.OnRemoveInventoryItem += RemoveInventoryItem; | 3366 | client.OnRemoveInventoryItem += RemoveInventoryItem; |
3207 | client.OnRemoveInventoryFolder += RemoveInventoryFolder; | 3367 | client.OnRemoveInventoryFolder += RemoveInventoryFolder; |
@@ -3263,7 +3423,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3263 | 3423 | ||
3264 | public virtual void UnSubscribeToClientTerrainEvents(IClientAPI client) | 3424 | public virtual void UnSubscribeToClientTerrainEvents(IClientAPI client) |
3265 | { | 3425 | { |
3266 | client.OnRegionHandShakeReply -= SendLayerData; | 3426 | // client.OnRegionHandShakeReply -= SendLayerData; |
3267 | } | 3427 | } |
3268 | 3428 | ||
3269 | public virtual void UnSubscribeToClientPrimEvents(IClientAPI client) | 3429 | public virtual void UnSubscribeToClientPrimEvents(IClientAPI client) |
@@ -3271,6 +3431,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3271 | client.OnUpdatePrimGroupPosition -= m_sceneGraph.UpdatePrimGroupPosition; | 3431 | client.OnUpdatePrimGroupPosition -= m_sceneGraph.UpdatePrimGroupPosition; |
3272 | client.OnUpdatePrimSinglePosition -= m_sceneGraph.UpdatePrimSinglePosition; | 3432 | client.OnUpdatePrimSinglePosition -= m_sceneGraph.UpdatePrimSinglePosition; |
3273 | 3433 | ||
3434 | client.onClientChangeObject -= m_sceneGraph.ClientChangeObject; | ||
3435 | |||
3274 | client.OnUpdatePrimGroupRotation -= m_sceneGraph.UpdatePrimGroupRotation; | 3436 | client.OnUpdatePrimGroupRotation -= m_sceneGraph.UpdatePrimGroupRotation; |
3275 | client.OnUpdatePrimGroupMouseRotation -= m_sceneGraph.UpdatePrimGroupRotation; | 3437 | client.OnUpdatePrimGroupMouseRotation -= m_sceneGraph.UpdatePrimGroupRotation; |
3276 | client.OnUpdatePrimSingleRotation -= m_sceneGraph.UpdatePrimSingleRotation; | 3438 | client.OnUpdatePrimSingleRotation -= m_sceneGraph.UpdatePrimSingleRotation; |
@@ -3428,16 +3590,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
3428 | if (target != null && target2 != null) | 3590 | if (target != null && target2 != null) |
3429 | { | 3591 | { |
3430 | Vector3 direction = Vector3.Normalize(RayEnd - RayStart); | 3592 | Vector3 direction = Vector3.Normalize(RayEnd - RayStart); |
3431 | Vector3 AXOrigin = RayStart; | 3593 | |
3432 | Vector3 AXdirection = direction; | ||
3433 | |||
3434 | pos = target2.AbsolutePosition; | 3594 | pos = target2.AbsolutePosition; |
3435 | //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()); | 3595 | //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()); |
3436 | 3596 | ||
3437 | // TODO: Raytrace better here | 3597 | // TODO: Raytrace better here |
3438 | 3598 | ||
3439 | //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection)); | 3599 | //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection)); |
3440 | Ray NewRay = new Ray(AXOrigin, AXdirection); | 3600 | Ray NewRay = new Ray(RayStart,direction); |
3441 | 3601 | ||
3442 | // Ray Trace against target here | 3602 | // Ray Trace against target here |
3443 | EntityIntersection ei = target2.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, CopyCenters); | 3603 | EntityIntersection ei = target2.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, CopyCenters); |
@@ -3519,6 +3679,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3519 | /// <param name='closeChildAgents'> | 3679 | /// <param name='closeChildAgents'> |
3520 | /// Close the neighbour child agents associated with this client. | 3680 | /// Close the neighbour child agents associated with this client. |
3521 | /// </param> | 3681 | /// </param> |
3682 | /// | ||
3683 | |||
3684 | private object m_removeClientPrivLock = new Object(); | ||
3685 | |||
3522 | public void RemoveClient(UUID agentID, bool closeChildAgents) | 3686 | public void RemoveClient(UUID agentID, bool closeChildAgents) |
3523 | { | 3687 | { |
3524 | AgentCircuitData acd = m_authenticateHandler.GetAgentCircuitData(agentID); | 3688 | AgentCircuitData acd = m_authenticateHandler.GetAgentCircuitData(agentID); |
@@ -3535,8 +3699,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3535 | } | 3699 | } |
3536 | 3700 | ||
3537 | // TODO: Can we now remove this lock? | 3701 | // TODO: Can we now remove this lock? |
3538 | lock (acd) | 3702 | lock (m_removeClientPrivLock) |
3539 | { | 3703 | { |
3540 | bool isChildAgent = false; | 3704 | bool isChildAgent = false; |
3541 | 3705 | ||
3542 | ScenePresence avatar = GetScenePresence(agentID); | 3706 | ScenePresence avatar = GetScenePresence(agentID); |
@@ -3580,8 +3744,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3580 | // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop | 3744 | // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop |
3581 | // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI | 3745 | // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI |
3582 | if (closeChildAgents && CapsModule != null) | 3746 | if (closeChildAgents && CapsModule != null) |
3583 | CapsModule.RemoveCaps(agentID); | 3747 | CapsModule.RemoveCaps(agentID, avatar.ControllingClient.CircuitCode); |
3584 | 3748 | ||
3585 | if (closeChildAgents && !isChildAgent) | 3749 | if (closeChildAgents && !isChildAgent) |
3586 | { | 3750 | { |
3587 | List<ulong> regions = avatar.KnownRegionHandles; | 3751 | List<ulong> regions = avatar.KnownRegionHandles; |
@@ -3592,13 +3756,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
3592 | } | 3756 | } |
3593 | 3757 | ||
3594 | m_eventManager.TriggerClientClosed(agentID, this); | 3758 | m_eventManager.TriggerClientClosed(agentID, this); |
3759 | // m_log.Debug("[Scene]TriggerClientClosed done"); | ||
3595 | m_eventManager.TriggerOnRemovePresence(agentID); | 3760 | m_eventManager.TriggerOnRemovePresence(agentID); |
3596 | 3761 | // m_log.Debug("[Scene]TriggerOnRemovePresence done"); | |
3762 | |||
3597 | if (!isChildAgent) | 3763 | if (!isChildAgent) |
3598 | { | 3764 | { |
3599 | if (AttachmentsModule != null) | 3765 | if (AttachmentsModule != null) |
3600 | { | 3766 | { |
3767 | // m_log.Debug("[Scene]DeRezAttachments"); | ||
3601 | AttachmentsModule.DeRezAttachments(avatar); | 3768 | AttachmentsModule.DeRezAttachments(avatar); |
3769 | // m_log.Debug("[Scene]DeRezAttachments done"); | ||
3602 | } | 3770 | } |
3603 | 3771 | ||
3604 | ForEachClient( | 3772 | ForEachClient( |
@@ -3612,7 +3780,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
3612 | 3780 | ||
3613 | // It's possible for child agents to have transactions if changes are being made cross-border. | 3781 | // It's possible for child agents to have transactions if changes are being made cross-border. |
3614 | if (AgentTransactionsModule != null) | 3782 | if (AgentTransactionsModule != null) |
3783 | { | ||
3784 | // m_log.Debug("[Scene]RemoveAgentAssetTransactions"); | ||
3615 | AgentTransactionsModule.RemoveAgentAssetTransactions(agentID); | 3785 | AgentTransactionsModule.RemoveAgentAssetTransactions(agentID); |
3786 | } | ||
3787 | m_log.Debug("[Scene] The avatar has left the building"); | ||
3616 | } | 3788 | } |
3617 | catch (Exception e) | 3789 | catch (Exception e) |
3618 | { | 3790 | { |
@@ -3731,6 +3903,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
3731 | /// or other applications where a full grid/Hypergrid presence may not be required.</param> | 3903 | /// or other applications where a full grid/Hypergrid presence may not be required.</param> |
3732 | /// <returns>True if the region accepts this agent. False if it does not. False will | 3904 | /// <returns>True if the region accepts this agent. False if it does not. False will |
3733 | /// also return a reason.</returns> | 3905 | /// also return a reason.</returns> |
3906 | /// | ||
3907 | private object m_newUserConnLock = new object(); | ||
3908 | |||
3734 | public bool NewUserConnection(AgentCircuitData acd, uint teleportFlags, GridRegion source, out string reason, bool requirePresenceLookup) | 3909 | public bool NewUserConnection(AgentCircuitData acd, uint teleportFlags, GridRegion source, out string reason, bool requirePresenceLookup) |
3735 | { | 3910 | { |
3736 | bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 || | 3911 | bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 || |
@@ -3764,6 +3939,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3764 | (source == null) ? "" : string.Format("From region {0} ({1}){2}", source.RegionName, source.RegionID, (source.RawServerURI == null) ? "" : " @ " + source.ServerURI) | 3939 | (source == null) ? "" : string.Format("From region {0} ({1}){2}", source.RegionName, source.RegionID, (source.RawServerURI == null) ? "" : " @ " + source.ServerURI) |
3765 | ); | 3940 | ); |
3766 | 3941 | ||
3942 | // m_log.DebugFormat("NewUserConnection stack {0}", Environment.StackTrace); | ||
3943 | |||
3767 | if (!LoginsEnabled) | 3944 | if (!LoginsEnabled) |
3768 | { | 3945 | { |
3769 | reason = "Logins Disabled"; | 3946 | reason = "Logins Disabled"; |
@@ -3891,7 +4068,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3891 | } | 4068 | } |
3892 | 4069 | ||
3893 | // TODO: can we remove this lock? | 4070 | // TODO: can we remove this lock? |
3894 | lock (acd) | 4071 | lock (m_newUserConnLock) |
3895 | { | 4072 | { |
3896 | if (sp != null && !sp.IsChildAgent) | 4073 | if (sp != null && !sp.IsChildAgent) |
3897 | { | 4074 | { |
@@ -3918,6 +4095,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
3918 | // We need the circuit data here for some of the subsequent checks. (groups, for example) | 4095 | // We need the circuit data here for some of the subsequent checks. (groups, for example) |
3919 | // If the checks fail, we remove the circuit. | 4096 | // If the checks fail, we remove the circuit. |
3920 | acd.teleportFlags = teleportFlags; | 4097 | acd.teleportFlags = teleportFlags; |
4098 | |||
4099 | // Remove any preexisting circuit - we don't want duplicates | ||
4100 | // This is a stab at preventing avatar "ghosting" | ||
4101 | if (vialogin) | ||
4102 | m_authenticateHandler.RemoveCircuit(acd.AgentID); | ||
4103 | |||
3921 | m_authenticateHandler.AddNewCircuit(acd.circuitcode, acd); | 4104 | m_authenticateHandler.AddNewCircuit(acd.circuitcode, acd); |
3922 | 4105 | ||
3923 | land = LandChannel.GetLandObject(acd.startpos.X, acd.startpos.Y); | 4106 | land = LandChannel.GetLandObject(acd.startpos.X, acd.startpos.Y); |
@@ -3925,6 +4108,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
3925 | // On login test land permisions | 4108 | // On login test land permisions |
3926 | if (vialogin) | 4109 | if (vialogin) |
3927 | { | 4110 | { |
4111 | IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>(); | ||
4112 | if (cache != null) | ||
4113 | cache.Remove(acd.firstname + " " + acd.lastname); | ||
3928 | if (land != null && !TestLandRestrictions(acd.AgentID, out reason, ref acd.startpos.X, ref acd.startpos.Y)) | 4114 | if (land != null && !TestLandRestrictions(acd.AgentID, out reason, ref acd.startpos.X, ref acd.startpos.Y)) |
3929 | { | 4115 | { |
3930 | m_authenticateHandler.RemoveCircuit(acd.circuitcode); | 4116 | m_authenticateHandler.RemoveCircuit(acd.circuitcode); |
@@ -3979,7 +4165,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3979 | if (CapsModule != null) | 4165 | if (CapsModule != null) |
3980 | { | 4166 | { |
3981 | CapsModule.SetAgentCapsSeeds(acd); | 4167 | CapsModule.SetAgentCapsSeeds(acd); |
3982 | CapsModule.CreateCaps(acd.AgentID); | 4168 | CapsModule.CreateCaps(acd.AgentID, acd.circuitcode); |
3983 | } | 4169 | } |
3984 | } | 4170 | } |
3985 | else | 4171 | else |
@@ -3992,15 +4178,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
3992 | { | 4178 | { |
3993 | m_log.DebugFormat( | 4179 | m_log.DebugFormat( |
3994 | "[SCENE]: Adjusting known seeds for existing agent {0} in {1}", | 4180 | "[SCENE]: Adjusting known seeds for existing agent {0} in {1}", |
3995 | acd.AgentID, RegionInfo.RegionName); | 4181 | acd.AgentID, RegionInfo.RegionName); |
3996 | |||
3997 | sp.AdjustKnownSeeds(); | ||
3998 | 4182 | ||
3999 | if (CapsModule != null) | 4183 | if (CapsModule != null) |
4000 | { | 4184 | { |
4001 | CapsModule.SetAgentCapsSeeds(acd); | 4185 | CapsModule.SetAgentCapsSeeds(acd); |
4002 | CapsModule.CreateCaps(acd.AgentID); | 4186 | CapsModule.CreateCaps(acd.AgentID, acd.circuitcode); |
4003 | } | 4187 | } |
4188 | |||
4189 | sp.AdjustKnownSeeds(); | ||
4004 | } | 4190 | } |
4005 | } | 4191 | } |
4006 | 4192 | ||
@@ -4010,6 +4196,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
4010 | CacheUserName(null, acd); | 4196 | CacheUserName(null, acd); |
4011 | } | 4197 | } |
4012 | 4198 | ||
4199 | if (CapsModule != null) | ||
4200 | { | ||
4201 | CapsModule.ActivateCaps(acd.circuitcode); | ||
4202 | } | ||
4203 | |||
4013 | if (vialogin) | 4204 | if (vialogin) |
4014 | { | 4205 | { |
4015 | // CleanDroppedAttachments(); | 4206 | // CleanDroppedAttachments(); |
@@ -4079,6 +4270,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
4079 | } | 4270 | } |
4080 | 4271 | ||
4081 | // Honor parcel landing type and position. | 4272 | // Honor parcel landing type and position. |
4273 | /* | ||
4274 | ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); | ||
4082 | if (land != null) | 4275 | if (land != null) |
4083 | { | 4276 | { |
4084 | if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) | 4277 | if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) |
@@ -4093,6 +4286,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4093 | } | 4286 | } |
4094 | } | 4287 | } |
4095 | } | 4288 | } |
4289 | */// This is now handled properly in ScenePresence.MakeRootAgent | ||
4096 | } | 4290 | } |
4097 | 4291 | ||
4098 | return true; | 4292 | return true; |
@@ -4117,12 +4311,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
4117 | { | 4311 | { |
4118 | if (posX < 0) | 4312 | if (posX < 0) |
4119 | posX = 0; | 4313 | posX = 0; |
4120 | else if (posX >= (float)RegionInfo.RegionSizeX) | 4314 | |
4121 | posX = (float)RegionInfo.RegionSizeX - 0.001f; | 4315 | else if (posX >= RegionInfo.RegionSizeX) |
4316 | posX = RegionInfo.RegionSizeX - 0.5f; | ||
4122 | if (posY < 0) | 4317 | if (posY < 0) |
4123 | posY = 0; | 4318 | posY = 0; |
4124 | else if (posY >= (float)RegionInfo.RegionSizeY) | 4319 | else if (posY >= RegionInfo.RegionSizeY) |
4125 | posY = (float)RegionInfo.RegionSizeY - 0.001f; | 4320 | posY = RegionInfo.RegionSizeY - 0.5f; |
4126 | 4321 | ||
4127 | reason = String.Empty; | 4322 | reason = String.Empty; |
4128 | if (Permissions.IsGod(agentID)) | 4323 | if (Permissions.IsGod(agentID)) |
@@ -4226,7 +4421,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
4226 | { | 4421 | { |
4227 | if (RegionInfo.EstateSettings != null) | 4422 | if (RegionInfo.EstateSettings != null) |
4228 | { | 4423 | { |
4229 | if (RegionInfo.EstateSettings.IsBanned(agent.AgentID)) | 4424 | int flags = GetUserFlags(agent.AgentID); |
4425 | if (RegionInfo.EstateSettings.IsBanned(agent.AgentID, flags)) | ||
4230 | { | 4426 | { |
4231 | m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", | 4427 | m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", |
4232 | agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); | 4428 | agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); |
@@ -4415,6 +4611,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
4415 | m_log.DebugFormat( | 4611 | m_log.DebugFormat( |
4416 | "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName); | 4612 | "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName); |
4417 | 4613 | ||
4614 | if (!LoginsEnabled) | ||
4615 | { | ||
4616 | // reason = "Logins Disabled"; | ||
4617 | m_log.DebugFormat( | ||
4618 | "[SCENE]: update for {0} in {1} refused: Logins Disabled", cAgentData.AgentID, RegionInfo.RegionName); | ||
4619 | return false; | ||
4620 | } | ||
4621 | // We have to wait until the viewer contacts this region after receiving EAC. | ||
4622 | // That calls AddNewClient, which finally creates the ScenePresence | ||
4623 | int flags = GetUserFlags(cAgentData.AgentID); | ||
4624 | if (RegionInfo.EstateSettings.IsBanned(cAgentData.AgentID, flags)) | ||
4625 | { | ||
4626 | m_log.DebugFormat("[SCENE]: Denying root agent entry to {0}: banned", cAgentData.AgentID); | ||
4627 | return false; | ||
4628 | } | ||
4629 | |||
4418 | // TODO: This check should probably be in QueryAccess(). | 4630 | // TODO: This check should probably be in QueryAccess(). |
4419 | ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, RegionInfo.RegionSizeX / 2, RegionInfo.RegionSizeY / 2); | 4631 | ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, RegionInfo.RegionSizeX / 2, RegionInfo.RegionSizeY / 2); |
4420 | if (nearestParcel == null) | 4632 | if (nearestParcel == null) |
@@ -4432,8 +4644,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
4432 | // a UseCircuitCode packet which in turn calls AddNewAgent which finally creates the ScenePresence. | 4644 | // a UseCircuitCode packet which in turn calls AddNewAgent which finally creates the ScenePresence. |
4433 | ScenePresence sp = WaitGetScenePresence(cAgentData.AgentID); | 4645 | ScenePresence sp = WaitGetScenePresence(cAgentData.AgentID); |
4434 | 4646 | ||
4435 | if (sp != null) | 4647 | if (sp != null) |
4436 | { | 4648 | { |
4649 | if (!sp.IsChildAgent) | ||
4650 | { | ||
4651 | m_log.WarnFormat("[SCENE]: Ignoring a child update on a root agent {0} {1} in {2}", | ||
4652 | sp.Name, sp.UUID, Name); | ||
4653 | return false; | ||
4654 | } | ||
4437 | if (cAgentData.SessionID != sp.ControllingClient.SessionId) | 4655 | if (cAgentData.SessionID != sp.ControllingClient.SessionId) |
4438 | { | 4656 | { |
4439 | m_log.WarnFormat( | 4657 | m_log.WarnFormat( |
@@ -4518,7 +4736,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4518 | /// <param name='agentID'></param> | 4736 | /// <param name='agentID'></param> |
4519 | protected virtual ScenePresence WaitGetScenePresence(UUID agentID) | 4737 | protected virtual ScenePresence WaitGetScenePresence(UUID agentID) |
4520 | { | 4738 | { |
4521 | int ntimes = 20; | 4739 | int ntimes = 30; |
4522 | ScenePresence sp = null; | 4740 | ScenePresence sp = null; |
4523 | while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0)) | 4741 | while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0)) |
4524 | Thread.Sleep(1000); | 4742 | Thread.Sleep(1000); |
@@ -4568,6 +4786,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
4568 | return false; | 4786 | return false; |
4569 | } | 4787 | } |
4570 | 4788 | ||
4789 | // public bool IncomingCloseAgent(UUID agentID) | ||
4790 | // { | ||
4791 | // return IncomingCloseAgent(agentID, false); | ||
4792 | // } | ||
4793 | |||
4794 | // public bool IncomingCloseChildAgent(UUID agentID) | ||
4795 | // { | ||
4796 | // return IncomingCloseAgent(agentID, true); | ||
4797 | // } | ||
4798 | |||
4571 | /// <summary> | 4799 | /// <summary> |
4572 | /// Tell a single client to prepare to close. | 4800 | /// Tell a single client to prepare to close. |
4573 | /// </summary> | 4801 | /// </summary> |
@@ -4630,6 +4858,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
4630 | 4858 | ||
4631 | if (sp == null) | 4859 | if (sp == null) |
4632 | { | 4860 | { |
4861 | // If there is no scene presence, we may be handling a dead | ||
4862 | // client. These can keep an avatar from reentering a region | ||
4863 | // and since they don't get cleaned up they will stick | ||
4864 | // around until region restart. So, if there is no SP, | ||
4865 | // remove the client as well. | ||
4866 | IClientAPI client = null; | ||
4867 | if (m_clientManager.TryGetValue(agentID, out client)) | ||
4868 | { | ||
4869 | m_clientManager.Remove(agentID); | ||
4870 | if (CapsModule != null) | ||
4871 | CapsModule.RemoveCaps(agentID, 0); | ||
4872 | m_log.DebugFormat( "[SCENE]: Dead client for agent ID {0} was cleaned up in {1}", agentID, Name); | ||
4873 | return true; | ||
4874 | } | ||
4633 | m_log.DebugFormat( | 4875 | m_log.DebugFormat( |
4634 | "[SCENE]: Called CloseClient() with agent ID {0} but no such presence is in {1}", | 4876 | "[SCENE]: Called CloseClient() with agent ID {0} but no such presence is in {1}", |
4635 | agentID, Name); | 4877 | agentID, Name); |
@@ -4664,7 +4906,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
4664 | sp.LifecycleState = ScenePresenceState.Removing; | 4906 | sp.LifecycleState = ScenePresenceState.Removing; |
4665 | } | 4907 | } |
4666 | 4908 | ||
4667 | sp.ControllingClient.Close(force); | 4909 | if (sp != null) |
4910 | { | ||
4911 | sp.ControllingClient.Close(force, force); | ||
4912 | return true; | ||
4913 | } | ||
4668 | 4914 | ||
4669 | return true; | 4915 | return true; |
4670 | } | 4916 | } |
@@ -4826,7 +5072,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
4826 | 5072 | ||
4827 | public LandData GetLandData(float x, float y) | 5073 | public LandData GetLandData(float x, float y) |
4828 | { | 5074 | { |
4829 | return LandChannel.GetLandObject(x, y).LandData; | 5075 | ILandObject parcel = LandChannel.GetLandObject(x, y); |
5076 | if (parcel == null) | ||
5077 | return null; | ||
5078 | return parcel.LandData; | ||
4830 | } | 5079 | } |
4831 | 5080 | ||
4832 | /// <summary> | 5081 | /// <summary> |
@@ -4842,7 +5091,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
4842 | public LandData GetLandData(uint x, uint y) | 5091 | public LandData GetLandData(uint x, uint y) |
4843 | { | 5092 | { |
4844 | m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y); | 5093 | m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y); |
4845 | return LandChannel.GetLandObject((int)x, (int)y).LandData; | 5094 | ILandObject parcel = LandChannel.GetLandObject((int)x, (int)y); |
5095 | if (parcel == null) | ||
5096 | return null; | ||
5097 | return parcel.LandData; | ||
4846 | } | 5098 | } |
4847 | 5099 | ||
4848 | #endregion | 5100 | #endregion |
@@ -5230,7 +5482,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
5230 | { | 5482 | { |
5231 | if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) | 5483 | if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) |
5232 | { | 5484 | { |
5233 | if (grp.RootPart.Expires <= DateTime.Now) | 5485 | if (grp.GetSittingAvatarsCount() == 0 && grp.RootPart.Expires <= DateTime.Now) |
5234 | DeleteSceneObject(grp, false); | 5486 | DeleteSceneObject(grp, false); |
5235 | } | 5487 | } |
5236 | } | 5488 | } |
@@ -5244,35 +5496,80 @@ namespace OpenSim.Region.Framework.Scenes | |||
5244 | SimulationDataService.RemoveObject(uuid, RegionInfo.RegionID); | 5496 | SimulationDataService.RemoveObject(uuid, RegionInfo.RegionID); |
5245 | } | 5497 | } |
5246 | 5498 | ||
5247 | public int GetHealth() | 5499 | public int GetHealth(out int flags, out string message) |
5248 | { | 5500 | { |
5249 | // Returns: | 5501 | // Returns: |
5250 | // 1 = sim is up and accepting http requests. The heartbeat has | 5502 | // 1 = sim is up and accepting http requests. The heartbeat has |
5251 | // stopped and the sim is probably locked up, but a remote | 5503 | // stopped and the sim is probably locked up, but a remote |
5252 | // admin restart may succeed | 5504 | // admin restart may succeed |
5253 | // | 5505 | // |
5254 | // 2 = Sim is up and the heartbeat is running. The sim is likely | 5506 | // 2 = Sim is up and the heartbeat is running. The sim is likely |
5255 | // usable for people within and logins _may_ work | 5507 | // usable for people within |
5508 | // | ||
5509 | // 3 = Sim is up and one packet thread is running. Sim is | ||
5510 | // unstable and will not accept new logins | ||
5511 | // | ||
5512 | // 4 = Sim is up and both packet threads are running. Sim is | ||
5513 | // likely usable | ||
5256 | // | 5514 | // |
5257 | // 3 = We have seen a new user enter within the past 4 minutes | 5515 | // 5 = We have seen a new user enter within the past 4 minutes |
5258 | // which can be seen as positive confirmation of sim health | 5516 | // which can be seen as positive confirmation of sim health |
5259 | // | 5517 | // |
5260 | int health = 1; // Start at 1, means we're up | 5518 | int health = 1; // Start at 1, means we're up |
5261 | 5519 | ||
5520 | flags = 0; | ||
5521 | message = String.Empty; | ||
5522 | |||
5523 | CheckHeartbeat(); | ||
5524 | |||
5525 | if (m_firstHeartbeat || (m_lastIncoming == 0 && m_lastOutgoing == 0)) | ||
5526 | { | ||
5527 | // We're still starting | ||
5528 | // 0 means "in startup", it can't happen another way, since | ||
5529 | // to get here, we must be able to accept http connections | ||
5530 | return 0; | ||
5531 | } | ||
5532 | |||
5262 | if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) < 1000) | 5533 | if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) < 1000) |
5263 | health += 1; | 5534 | { |
5535 | health+=1; | ||
5536 | flags |= 1; | ||
5537 | } | ||
5538 | |||
5539 | if (Util.EnvironmentTickCountSubtract(m_lastIncoming) < 1000) | ||
5540 | { | ||
5541 | health+=1; | ||
5542 | flags |= 2; | ||
5543 | } | ||
5544 | |||
5545 | if (Util.EnvironmentTickCountSubtract(m_lastOutgoing) < 1000) | ||
5546 | { | ||
5547 | health+=1; | ||
5548 | flags |= 4; | ||
5549 | } | ||
5264 | else | 5550 | else |
5551 | { | ||
5552 | int pid = System.Diagnostics.Process.GetCurrentProcess().Id; | ||
5553 | System.Diagnostics.Process proc = new System.Diagnostics.Process(); | ||
5554 | proc.EnableRaisingEvents=false; | ||
5555 | proc.StartInfo.FileName = "/bin/kill"; | ||
5556 | proc.StartInfo.Arguments = "-QUIT " + pid.ToString(); | ||
5557 | proc.Start(); | ||
5558 | proc.WaitForExit(); | ||
5559 | Thread.Sleep(1000); | ||
5560 | Environment.Exit(1); | ||
5561 | } | ||
5562 | |||
5563 | if (flags != 7) | ||
5265 | return health; | 5564 | return health; |
5266 | 5565 | ||
5267 | // A login in the last 4 mins? We can't be doing too badly | 5566 | // A login in the last 4 mins? We can't be doing too badly |
5268 | // | 5567 | // |
5269 | if ((Util.EnvironmentTickCountSubtract(m_LastLogin)) < 240000) | 5568 | if (Util.EnvironmentTickCountSubtract(m_LastLogin) < 240000) |
5270 | health++; | 5569 | health++; |
5271 | else | 5570 | else |
5272 | return health; | 5571 | return health; |
5273 | 5572 | ||
5274 | // CheckHeartbeat(); | ||
5275 | |||
5276 | return health; | 5573 | return health; |
5277 | } | 5574 | } |
5278 | 5575 | ||
@@ -5360,7 +5657,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
5360 | bool wasUsingPhysics = ((jointProxyObject.Flags & PrimFlags.Physics) != 0); | 5657 | bool wasUsingPhysics = ((jointProxyObject.Flags & PrimFlags.Physics) != 0); |
5361 | if (wasUsingPhysics) | 5658 | if (wasUsingPhysics) |
5362 | { | 5659 | { |
5363 | 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 | 5660 | 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 |
5364 | } | 5661 | } |
5365 | } | 5662 | } |
5366 | 5663 | ||
@@ -5463,14 +5760,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
5463 | return (((vsn.X * xdiff) + (vsn.Y * ydiff)) / (-1 * vsn.Z)) + p0.Z; | 5760 | return (((vsn.X * xdiff) + (vsn.Y * ydiff)) / (-1 * vsn.Z)) + p0.Z; |
5464 | } | 5761 | } |
5465 | 5762 | ||
5466 | // private void CheckHeartbeat() | 5763 | private void CheckHeartbeat() |
5467 | // { | 5764 | { |
5468 | // if (m_firstHeartbeat) | 5765 | if (m_firstHeartbeat) |
5469 | // return; | 5766 | return; |
5470 | // | 5767 | |
5471 | // if (Util.EnvironmentTickCountSubtract(m_lastFrameTick) > 2000) | 5768 | if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) > 5000) |
5472 | // StartTimer(); | 5769 | Start(); |
5473 | // } | 5770 | } |
5474 | 5771 | ||
5475 | public override ISceneObject DeserializeObject(string representation) | 5772 | public override ISceneObject DeserializeObject(string representation) |
5476 | { | 5773 | { |
@@ -5527,8 +5824,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
5527 | //Go to the edge, this happens in teleporting to a region with no available parcels | 5824 | //Go to the edge, this happens in teleporting to a region with no available parcels |
5528 | Vector3 nearestRegionEdgePoint = GetNearestRegionEdgePosition(avatar); | 5825 | Vector3 nearestRegionEdgePoint = GetNearestRegionEdgePosition(avatar); |
5529 | 5826 | ||
5530 | //m_log.Debug("They are really in a place they don't belong, sending them to: " + nearestRegionEdgePoint.ToString()); | 5827 | //Debug.WriteLine("They are really in a place they don't belong, sending them to: " + nearestRegionEdgePoint.ToString()); |
5531 | |||
5532 | return nearestRegionEdgePoint; | 5828 | return nearestRegionEdgePoint; |
5533 | } | 5829 | } |
5534 | 5830 | ||
@@ -5784,7 +6080,55 @@ namespace OpenSim.Region.Framework.Scenes | |||
5784 | mapModule.GenerateMaptile(); | 6080 | mapModule.GenerateMaptile(); |
5785 | } | 6081 | } |
5786 | 6082 | ||
5787 | private void RegenerateMaptileAndReregister(object sender, ElapsedEventArgs e) | 6083 | // public void CleanDroppedAttachments() |
6084 | // { | ||
6085 | // List<SceneObjectGroup> objectsToDelete = | ||
6086 | // new List<SceneObjectGroup>(); | ||
6087 | // | ||
6088 | // lock (m_cleaningAttachments) | ||
6089 | // { | ||
6090 | // ForEachSOG(delegate (SceneObjectGroup grp) | ||
6091 | // { | ||
6092 | // if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp))) | ||
6093 | // { | ||
6094 | // UUID agentID = grp.OwnerID; | ||
6095 | // if (agentID == UUID.Zero) | ||
6096 | // { | ||
6097 | // objectsToDelete.Add(grp); | ||
6098 | // return; | ||
6099 | // } | ||
6100 | // | ||
6101 | // ScenePresence sp = GetScenePresence(agentID); | ||
6102 | // if (sp == null) | ||
6103 | // { | ||
6104 | // objectsToDelete.Add(grp); | ||
6105 | // return; | ||
6106 | // } | ||
6107 | // } | ||
6108 | // }); | ||
6109 | // } | ||
6110 | // | ||
6111 | // foreach (SceneObjectGroup grp in objectsToDelete) | ||
6112 | // { | ||
6113 | // m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID); | ||
6114 | // DeleteSceneObject(grp, true); | ||
6115 | // } | ||
6116 | // } | ||
6117 | |||
6118 | public void ThreadAlive(int threadCode) | ||
6119 | { | ||
6120 | switch(threadCode) | ||
6121 | { | ||
6122 | case 1: // Incoming | ||
6123 | m_lastIncoming = Util.EnvironmentTickCount(); | ||
6124 | break; | ||
6125 | case 2: // Incoming | ||
6126 | m_lastOutgoing = Util.EnvironmentTickCount(); | ||
6127 | break; | ||
6128 | } | ||
6129 | } | ||
6130 | |||
6131 | public void RegenerateMaptileAndReregister(object sender, ElapsedEventArgs e) | ||
5788 | { | 6132 | { |
5789 | RegenerateMaptile(); | 6133 | RegenerateMaptile(); |
5790 | 6134 | ||
@@ -5950,7 +6294,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
5950 | return true; | 6294 | return true; |
5951 | } | 6295 | } |
5952 | 6296 | ||
5953 | /// <summary> | 6297 | public void StartTimerWatchdog() |
6298 | { | ||
6299 | m_timerWatchdog.Interval = 1000; | ||
6300 | m_timerWatchdog.Elapsed += TimerWatchdog; | ||
6301 | m_timerWatchdog.AutoReset = true; | ||
6302 | m_timerWatchdog.Start(); | ||
6303 | } | ||
6304 | |||
6305 | public void TimerWatchdog(object sender, ElapsedEventArgs e) | ||
6306 | { | ||
6307 | CheckHeartbeat(); | ||
6308 | } | ||
6309 | |||
5954 | /// This method deals with movement when an avatar is automatically moving (but this is distinct from the | 6310 | /// This method deals with movement when an avatar is automatically moving (but this is distinct from the |
5955 | /// autopilot that moves an avatar to a sit target!. | 6311 | /// autopilot that moves an avatar to a sit target!. |
5956 | /// </summary> | 6312 | /// </summary> |
@@ -6029,6 +6385,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
6029 | return m_SpawnPoint - 1; | 6385 | return m_SpawnPoint - 1; |
6030 | } | 6386 | } |
6031 | 6387 | ||
6388 | private void HandleGcCollect(string module, string[] args) | ||
6389 | { | ||
6390 | GC.Collect(); | ||
6391 | } | ||
6392 | |||
6032 | /// <summary> | 6393 | /// <summary> |
6033 | /// Wrappers to get physics modules retrieve assets. | 6394 | /// Wrappers to get physics modules retrieve assets. |
6034 | /// </summary> | 6395 | /// </summary> |