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