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