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.cs1161
1 files changed, 743 insertions, 418 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index dce2247..05edd20 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,6 +932,22 @@ 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
935 m_sceneGraph = new SceneGraph(this);
936 m_sceneGraph.PhysicsScene = physicsScene;
937
938 // If the scene graph has an Unrecoverable error, restart this sim.
939 // Currently the only thing that causes it to happen is two kinds of specific
940 // Physics based crashes.
941 //
942 // Out of memory
943 // Operating system has killed the plugin
944 m_sceneGraph.UnRecoverableError
945 += () =>
946 {
947 m_log.ErrorFormat("[SCENE]: Restarting region {0} due to unrecoverable physics crash", Name);
948 RestartNow();
949 };
950
927 RegisterDefaultSceneEvents(); 951 RegisterDefaultSceneEvents();
928 952
929 // XXX: Don't set the public property since we don't want to activate here. This needs to be handled 953 // XXX: Don't set the public property since we don't want to activate here. This needs to be handled
@@ -945,6 +969,11 @@ namespace OpenSim.Region.Framework.Scenes
945 StartDisabled = startupConfig.GetBoolean("StartDisabled", false); 969 StartDisabled = startupConfig.GetBoolean("StartDisabled", false);
946 970
947 m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance", m_defaultDrawDistance); 971 m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance", m_defaultDrawDistance);
972 m_maxDrawDistance = startupConfig.GetFloat("MaxDrawDistance", m_maxDrawDistance);
973
974 if (m_defaultDrawDistance > m_maxDrawDistance)
975 m_defaultDrawDistance = m_maxDrawDistance;
976
948 UseBackup = startupConfig.GetBoolean("UseSceneBackup", UseBackup); 977 UseBackup = startupConfig.GetBoolean("UseSceneBackup", UseBackup);
949 if (!UseBackup) 978 if (!UseBackup)
950 m_log.InfoFormat("[SCENE]: Backup has been disabled for {0}", RegionInfo.RegionName); 979 m_log.InfoFormat("[SCENE]: Backup has been disabled for {0}", RegionInfo.RegionName);
@@ -956,9 +985,8 @@ namespace OpenSim.Region.Framework.Scenes
956 985
957 MaxUndoCount = startupConfig.GetInt("MaxPrimUndos", 20); 986 MaxUndoCount = startupConfig.GetInt("MaxPrimUndos", 20);
958 987
959 PhysicalPrims = startupConfig.GetBoolean("physical_prim", PhysicalPrims); 988 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true);
960 CollidablePrims = startupConfig.GetBoolean("collidable_prim", CollidablePrims); 989 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true);
961
962 m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys); 990 m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys);
963 if (RegionInfo.NonphysPrimMin > 0) 991 if (RegionInfo.NonphysPrimMin > 0)
964 { 992 {
@@ -978,11 +1006,24 @@ namespace OpenSim.Region.Framework.Scenes
978 } 1006 }
979 1007
980 m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys); 1008 m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys);
1009
981 if (RegionInfo.PhysPrimMax > 0) 1010 if (RegionInfo.PhysPrimMax > 0)
982 { 1011 {
983 m_maxPhys = RegionInfo.PhysPrimMax; 1012 m_maxPhys = RegionInfo.PhysPrimMax;
984 } 1013 }
985 1014
1015 m_linksetCapacity = startupConfig.GetInt("LinksetPrims", m_linksetCapacity);
1016 if (RegionInfo.LinksetCapacity > 0)
1017 {
1018 m_linksetCapacity = RegionInfo.LinksetCapacity;
1019 }
1020
1021 m_linksetPhysCapacity = startupConfig.GetInt("LinksetPhysPrims", m_linksetPhysCapacity);
1022
1023
1024 SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest");
1025 TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false);
1026
986 // Here, if clamping is requested in either global or 1027 // Here, if clamping is requested in either global or
987 // local config, it will be used 1028 // local config, it will be used
988 // 1029 //
@@ -992,13 +1033,7 @@ namespace OpenSim.Region.Framework.Scenes
992 m_clampPrimSize = true; 1033 m_clampPrimSize = true;
993 } 1034 }
994 1035
995 m_linksetCapacity = startupConfig.GetInt("LinksetPrims", m_linksetCapacity); 1036 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); 1037 m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries);
1003 m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings); 1038 m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings);
1004 m_dontPersistBefore = 1039 m_dontPersistBefore =
@@ -1009,11 +1044,11 @@ namespace OpenSim.Region.Framework.Scenes
1009 m_persistAfter *= 10000000; 1044 m_persistAfter *= 10000000;
1010 1045
1011 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); 1046 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
1012 1047 m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine);
1013 SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest");
1014 TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false);
1015 1048
1016 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); 1049 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
1050 m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion);
1051 CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false);
1017 1052
1018 string[] possibleMapConfigSections = new string[] { "Map", "Startup" }; 1053 string[] possibleMapConfigSections = new string[] { "Map", "Startup" };
1019 1054
@@ -1059,7 +1094,7 @@ namespace OpenSim.Region.Framework.Scenes
1059 1094
1060 if (grant.Length > 0) 1095 if (grant.Length > 0)
1061 { 1096 {
1062 foreach (string viewer in grant.Split('|')) 1097 foreach (string viewer in grant.Split(','))
1063 { 1098 {
1064 m_AllowedViewers.Add(viewer.Trim().ToLower()); 1099 m_AllowedViewers.Add(viewer.Trim().ToLower());
1065 } 1100 }
@@ -1075,14 +1110,13 @@ namespace OpenSim.Region.Framework.Scenes
1075 1110
1076 if (grant.Length > 0) 1111 if (grant.Length > 0)
1077 { 1112 {
1078 foreach (string viewer in grant.Split('|')) 1113 foreach (string viewer in grant.Split(','))
1079 { 1114 {
1080 m_BannedViewers.Add(viewer.Trim().ToLower()); 1115 m_BannedViewers.Add(viewer.Trim().ToLower());
1081 } 1116 }
1082 } 1117 }
1083 1118
1084 if (startupConfig.Contains("MinFrameTime")) 1119 MinFrameTime = startupConfig.GetFloat( "MinFrameTime", MinFrameTime);
1085 MinFrameTicks = (int)(startupConfig.GetFloat("MinFrameTime") * 1000);
1086 1120
1087 m_update_backup = startupConfig.GetInt("UpdateStorageEveryNFrames", m_update_backup); 1121 m_update_backup = startupConfig.GetInt("UpdateStorageEveryNFrames", m_update_backup);
1088 m_update_coarse_locations = startupConfig.GetInt("UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations); 1122 m_update_coarse_locations = startupConfig.GetInt("UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations);
@@ -1160,39 +1194,13 @@ namespace OpenSim.Region.Framework.Scenes
1160 1194
1161 #endregion Interest Management 1195 #endregion Interest Management
1162 1196
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 1197
1171 // Acquire the statistics section of the OpenSim.ini file located 1198 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 1199
1193 StatsReporter.OnSendStatsResult += SendSimStatsPackets; 1200 StatsReporter.OnSendStatsResult += SendSimStatsPackets;
1194 StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats; 1201 StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats;
1195 1202
1203 MainConsole.Instance.Commands.AddCommand("scene", false, "gc collect", "gc collect", "gc collect", "Cause the garbage collector to make a single pass", HandleGcCollect);
1196 } 1204 }
1197 1205
1198 public Scene(RegionInfo regInfo) 1206 public Scene(RegionInfo regInfo)
@@ -1215,13 +1223,36 @@ namespace OpenSim.Region.Framework.Scenes
1215 1223
1216 PhysicalPrims = true; 1224 PhysicalPrims = true;
1217 CollidablePrims = true; 1225 CollidablePrims = true;
1218 PhysicsEnabled = true; 1226 // this is done above acording to config
1227 // PhysicsEnabled = true;
1219 1228
1220 AllowAvatarCrossing = true; 1229 AllowAvatarCrossing = true;
1221 1230
1222 PeriodicBackup = true; 1231 PeriodicBackup = true;
1223 UseBackup = true; 1232 UseBackup = true;
1224 1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1225 IsReprioritizationEnabled = true; 1256 IsReprioritizationEnabled = true;
1226 UpdatePrioritizationScheme = UpdatePrioritizationSchemes.Time; 1257 UpdatePrioritizationScheme = UpdatePrioritizationSchemes.Time;
1227 ReprioritizationInterval = 5000; 1258 ReprioritizationInterval = 5000;
@@ -1235,6 +1266,7 @@ namespace OpenSim.Region.Framework.Scenes
1235 m_eventManager = new EventManager(); 1266 m_eventManager = new EventManager();
1236 1267
1237 m_permissions = new ScenePermissions(this); 1268 m_permissions = new ScenePermissions(this);
1269
1238 } 1270 }
1239 1271
1240 #endregion 1272 #endregion
@@ -1280,20 +1312,8 @@ namespace OpenSim.Region.Framework.Scenes
1280 { 1312 {
1281 if (RegionInfo.RegionHandle != otherRegion.RegionHandle) 1313 if (RegionInfo.RegionHandle != otherRegion.RegionHandle)
1282 { 1314 {
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 1315
1293 //m_log.InfoFormat("[SCENE]: (on region {0}): Region {1} up in coords {2}-{3}", 1316 if (isNeighborRegion(otherRegion))
1294 // RegionInfo.RegionName, otherRegion.RegionName, newRegionX, newRegionY);
1295
1296 if (!Util.IsOutsideView(dist, thisRegionX, newRegionX, thisRegionY, newRegionY))
1297 { 1317 {
1298 // Let the grid service module know, so this can be cached 1318 // Let the grid service module know, so this can be cached
1299 m_eventManager.TriggerOnRegionUp(otherRegion); 1319 m_eventManager.TriggerOnRegionUp(otherRegion);
@@ -1328,6 +1348,21 @@ namespace OpenSim.Region.Framework.Scenes
1328 } 1348 }
1329 } 1349 }
1330 1350
1351 public bool isNeighborRegion(GridRegion otherRegion)
1352 {
1353 int tmp = otherRegion.RegionLocX - (int)RegionInfo.WorldLocX; ;
1354
1355 if (tmp < -otherRegion.RegionSizeX && tmp > RegionInfo.RegionSizeX)
1356 return false;
1357
1358 tmp = otherRegion.RegionLocY - (int)RegionInfo.WorldLocY;
1359
1360 if (tmp < -otherRegion.RegionSizeY && tmp > RegionInfo.RegionSizeY)
1361 return false;
1362
1363 return true;
1364 }
1365
1331 public void AddNeighborRegion(RegionInfo region) 1366 public void AddNeighborRegion(RegionInfo region)
1332 { 1367 {
1333 lock (m_neighbours) 1368 lock (m_neighbours)
@@ -1459,8 +1494,11 @@ namespace OpenSim.Region.Framework.Scenes
1459 // Stop all client threads. 1494 // Stop all client threads.
1460 ForEachScenePresence(delegate(ScenePresence avatar) { CloseAgent(avatar.UUID, false); }); 1495 ForEachScenePresence(delegate(ScenePresence avatar) { CloseAgent(avatar.UUID, false); });
1461 1496
1462 m_log.Debug("[SCENE]: Persisting changed objects"); 1497 m_log.Debug("[SCENE]: TriggerSceneShuttingDown");
1463 EventManager.TriggerSceneShuttingDown(this); 1498 EventManager.TriggerSceneShuttingDown(this);
1499
1500 m_log.Debug("[SCENE]: Persisting changed objects");
1501
1464 Backup(false); 1502 Backup(false);
1465 m_sceneGraph.Close(); 1503 m_sceneGraph.Close();
1466 1504
@@ -1474,6 +1512,7 @@ namespace OpenSim.Region.Framework.Scenes
1474 // attempt to reference a null or disposed physics scene. 1512 // attempt to reference a null or disposed physics scene.
1475 if (PhysicsScene != null) 1513 if (PhysicsScene != null)
1476 { 1514 {
1515 m_log.Debug("[SCENE]: Dispose Physics");
1477 PhysicsScene phys = PhysicsScene; 1516 PhysicsScene phys = PhysicsScene;
1478 // remove the physics engine from both Scene and SceneGraph 1517 // remove the physics engine from both Scene and SceneGraph
1479 PhysicsScene = null; 1518 PhysicsScene = null;
@@ -1505,10 +1544,28 @@ namespace OpenSim.Region.Framework.Scenes
1505// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); 1544// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName);
1506 if (m_heartbeatThread != null) 1545 if (m_heartbeatThread != null)
1507 { 1546 {
1547 m_hbRestarts++;
1548 if(m_hbRestarts > 10)
1549 Environment.Exit(1);
1550 m_log.ErrorFormat("[SCENE]: Restarting heartbeat thread because it hasn't reported in in region {0}", RegionInfo.RegionName);
1551
1552//int pid = System.Diagnostics.Process.GetCurrentProcess().Id;
1553//System.Diagnostics.Process proc = new System.Diagnostics.Process();
1554//proc.EnableRaisingEvents=false;
1555//proc.StartInfo.FileName = "/bin/kill";
1556//proc.StartInfo.Arguments = "-QUIT " + pid.ToString();
1557//proc.Start();
1558//proc.WaitForExit();
1559//Thread.Sleep(1000);
1560//Environment.Exit(1);
1508 m_heartbeatThread.Abort(); 1561 m_heartbeatThread.Abort();
1562 Watchdog.AbortThread(m_heartbeatThread.ManagedThreadId);
1509 m_heartbeatThread = null; 1563 m_heartbeatThread = null;
1510 } 1564 }
1511 1565
1566// m_sceneGraph.PreparePhysicsSimulation();
1567
1568
1512 m_heartbeatThread 1569 m_heartbeatThread
1513 = WorkManager.StartThread( 1570 = WorkManager.StartThread(
1514 Heartbeat, string.Format("Heartbeat-({0})", RegionInfo.RegionName.Replace(" ", "_")), ThreadPriority.Normal, false, false); 1571 Heartbeat, string.Format("Heartbeat-({0})", RegionInfo.RegionName.Replace(" ", "_")), ThreadPriority.Normal, false, false);
@@ -1556,45 +1613,8 @@ namespace OpenSim.Region.Framework.Scenes
1556 1613
1557 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true; 1614 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
1558 m_lastFrameTick = Util.EnvironmentTickCount(); 1615 m_lastFrameTick = Util.EnvironmentTickCount();
1559 1616 Update(-1);
1560 if (UpdateOnTimer) 1617 }
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 1618
1599 private void Maintenance() 1619 private void Maintenance()
1600 { 1620 {
@@ -1663,24 +1683,24 @@ namespace OpenSim.Region.Framework.Scenes
1663 previousMaintenanceTick = m_lastMaintenanceTick; 1683 previousMaintenanceTick = m_lastMaintenanceTick;
1664 m_lastMaintenanceTick = Util.EnvironmentTickCount(); 1684 m_lastMaintenanceTick = Util.EnvironmentTickCount();
1665 runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc); 1685 runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc);
1666 runtc = MinMaintenanceTicks - runtc; 1686 runtc = (int)(MinMaintenanceTime * 1000) - runtc;
1667 1687
1668 if (runtc > 0) 1688 if (runtc > 0)
1669 m_maintenanceWaitEvent.WaitOne(runtc); 1689 m_maintenanceWaitEvent.WaitOne(runtc);
1670 1690
1671 // Optionally warn if a frame takes double the amount of time that it should. 1691 // Optionally warn if a frame takes double the amount of time that it should.
1672 if (DebugUpdates 1692 if (DebugUpdates
1673 && Util.EnvironmentTickCountSubtract( 1693 && Util.EnvironmentTickCountSubtract(
1674 m_lastMaintenanceTick, previousMaintenanceTick) > MinMaintenanceTicks * 2) 1694 m_lastMaintenanceTick, previousMaintenanceTick) > (int)(MinMaintenanceTime * 1000 * 2))
1675 m_log.WarnFormat( 1695 m_log.WarnFormat(
1676 "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}", 1696 "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}",
1677 Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick), 1697 Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick),
1678 MinMaintenanceTicks, 1698 MinMaintenanceTime * 1000,
1679 RegionInfo.RegionName); 1699 RegionInfo.RegionName);
1680 } 1700 }
1681 } 1701 }
1682 1702
1683 public override bool Update(int frames) 1703 public override void Update(int frames)
1684 { 1704 {
1685 long? endFrame = null; 1705 long? endFrame = null;
1686 1706
@@ -1688,119 +1708,76 @@ namespace OpenSim.Region.Framework.Scenes
1688 endFrame = Frame + frames; 1708 endFrame = Frame + frames;
1689 1709
1690 float physicsFPS = 0f; 1710 float physicsFPS = 0f;
1691 int previousFrameTick, tmpMS; 1711
1692 1712 int previousFrameTick;
1693 // These variables will be used to save the precise frame time using the 1713
1694 // Stopwatch class of Microsoft SDK; the times are recorded at the start 1714 double tmpMS;
1695 // and end of a particular section of code, and then used to calculate 1715 double tmpMS2;
1696 // the frame times, which are the sums of the sections for each given name 1716 double framestart;
1697 double preciseTotalFrameTime = 0.0; 1717 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 1718
1708 while (!m_shuttingDown && ((endFrame == null && Active) || Frame < endFrame)) 1719 while (!m_shuttingDown && ((endFrame == null && Active) || Frame < endFrame))
1709 { 1720 {
1721 framestart = Util.GetTimeStampMS();
1710 ++Frame; 1722 ++Frame;
1711 1723
1712 // m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName); 1724 // m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName);
1713 1725
1714 agentMS = eventMS = backupMS = terrainMS = landMS = spareMS = 0; 1726 agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0f;
1715 1727
1716 try 1728 try
1717 { 1729 {
1718 EventManager.TriggerRegionHeartbeatStart(this); 1730 EventManager.TriggerRegionHeartbeatStart(this);
1719 1731
1720 // Apply taints in terrain module to terrain in physics scene 1732 // Apply taints in terrain module to terrain in physics scene
1733
1734 tmpMS = Util.GetTimeStampMS();
1735
1736 if (Frame % 4 == 0)
1737 {
1738 CheckTerrainUpdates();
1739 }
1740
1721 if (Frame % m_update_terrain == 0) 1741 if (Frame % m_update_terrain == 0)
1722 { 1742 {
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(); 1743 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 } 1744 }
1743 1745
1744 // At several points inside the code there was a need to 1746 tmpMS2 = Util.GetTimeStampMS();
1745 // create a more precise measurement of time elapsed. This 1747 terrainMS = (float)(tmpMS2 - tmpMS);
1746 // led to the addition of variables that have a similar 1748 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 1749
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) 1750 if (PhysicsEnabled && Frame % m_update_physics == 0)
1759 m_sceneGraph.UpdatePreparePhysics(); 1751 m_sceneGraph.UpdatePreparePhysics();
1760 1752
1761 // Get the time it took to prepare the physics, this 1753 tmpMS2 = Util.GetTimeStampMS();
1762 // would report the most precise time that physics was 1754 physicsMS2 = (float)(tmpMS2 - tmpMS);
1763 // running on the machine and should the physics not be 1755 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 1756
1770 // Apply any pending avatar force input to the avatar's velocity 1757 // 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) 1758 if (Frame % m_update_entitymovement == 0)
1774 m_sceneGraph.UpdateScenePresenceMovement(); 1759 m_sceneGraph.UpdateScenePresenceMovement();
1775 1760
1776 // Get the simulation frame time that the avatar force input 1761 // Get the simulation frame time that the avatar force input
1777 // took 1762 // took
1778 simFrameStopwatch.Stop(); 1763 tmpMS2 = Util.GetTimeStampMS();
1779 preciseSimFrameTime += 1764 agentMS = (float)(tmpMS2 - tmpMS);
1780 simFrameStopwatch.Elapsed.TotalMilliseconds; 1765 tmpMS = tmpMS2;
1781 agentMS = Util.EnvironmentTickCountSubtract(tmpMS);
1782 1766
1783 // Perform the main physics update. This will do the actual work of moving objects and avatars according to their 1767 // Perform the main physics update. This will do the actual work of moving objects and avatars according to their
1784 // velocity 1768 // velocity
1785 tmpMS = Util.EnvironmentTickCount();
1786 physicsFrameStopwatch.Restart();
1787 if (Frame % m_update_physics == 0) 1769 if (Frame % m_update_physics == 0)
1788 { 1770 {
1789 if (PhysicsEnabled) 1771 if (PhysicsEnabled)
1790 physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameSeconds); 1772 physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime);
1791 1773
1792 if (SynchronizeScene != null) 1774 if (SynchronizeScene != null)
1793 SynchronizeScene(this); 1775 SynchronizeScene(this);
1794 } 1776 }
1795 1777
1796 // Add the main physics update time to the prepare physics time 1778 tmpMS2 = Util.GetTimeStampMS();
1797 physicsFrameStopwatch.Stop(); 1779 physicsMS = (float)(tmpMS2 - tmpMS);
1798 precisePhysicsFrameTime += physicsFrameStopwatch.Elapsed.TotalMilliseconds; 1780 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 1781
1805 // Check if any objects have reached their targets 1782 // Check if any objects have reached their targets
1806 CheckAtTargets(); 1783 CheckAtTargets();
@@ -1815,20 +1792,37 @@ namespace OpenSim.Region.Framework.Scenes
1815 if (Frame % m_update_presences == 0) 1792 if (Frame % m_update_presences == 0)
1816 m_sceneGraph.UpdatePresences(); 1793 m_sceneGraph.UpdatePresences();
1817 1794
1818 agentMS += Util.EnvironmentTickCountSubtract(tmpMS); 1795 tmpMS2 = Util.GetTimeStampMS();
1819 1796 agentMS += (float)(tmpMS2 - tmpMS);
1797 tmpMS = tmpMS2;
1798
1799 // Delete temp-on-rez stuff
1800 if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps)
1801 {
1802
1803 m_cleaningTemps = true;
1804 Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
1805 tmpMS2 = Util.GetTimeStampMS();
1806 tempOnRezMS = (float)(tmpMS2 - tmpMS); // bad.. counts the FireAndForget, not CleanTempObjects
1807 tmpMS = tmpMS2;
1808 }
1809
1820 if (Frame % m_update_events == 0) 1810 if (Frame % m_update_events == 0)
1821 { 1811 {
1822 tmpMS = Util.EnvironmentTickCount();
1823 UpdateEvents(); 1812 UpdateEvents();
1824 eventMS = Util.EnvironmentTickCountSubtract(tmpMS); 1813
1814 tmpMS2 = Util.GetTimeStampMS();
1815 eventMS = (float)(tmpMS2 - tmpMS);
1816 tmpMS = tmpMS2;
1825 } 1817 }
1826 1818
1827 if (PeriodicBackup && Frame % m_update_backup == 0) 1819 if (PeriodicBackup && Frame % m_update_backup == 0)
1828 { 1820 {
1829 tmpMS = Util.EnvironmentTickCount();
1830 UpdateStorageBackup(); 1821 UpdateStorageBackup();
1831 backupMS = Util.EnvironmentTickCountSubtract(tmpMS); 1822
1823 tmpMS2 = Util.GetTimeStampMS();
1824 backupMS = (float)(tmpMS2 - tmpMS);
1825 tmpMS = tmpMS2;
1832 } 1826 }
1833 1827
1834 //if (Frame % m_update_land == 0) 1828 //if (Frame % m_update_land == 0)
@@ -1885,79 +1879,58 @@ namespace OpenSim.Region.Framework.Scenes
1885 } 1879 }
1886 1880
1887 EventManager.TriggerRegionHeartbeatEnd(this); 1881 EventManager.TriggerRegionHeartbeatEnd(this);
1888 otherMS = eventMS + backupMS + terrainMS + landMS;
1889 1882
1890 // Get the elapsed time for the simulation frame 1883 Watchdog.UpdateThread();
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
1911 // Get the total frame time
1912 totalFrameStopwatch.Stop();
1913 preciseTotalFrameTime =
1914 totalFrameStopwatch.Elapsed.TotalMilliseconds;
1915 1884
1916 // Restart the stopwatch for the total time of the next frame 1885 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
1917 totalFrameStopwatch.Restart();
1918 1886
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); 1887 StatsReporter.AddPhysicsFPS(physicsFPS);
1926 StatsReporter.AddTimeDilation(TimeDilation); 1888 StatsReporter.AddTimeDilation(TimeDilation);
1927 StatsReporter.AddFPS(1); 1889 StatsReporter.AddFPS(1);
1928 1890
1929 StatsReporter.addFrameMS(frameMS);
1930 StatsReporter.addAgentMS(agentMS); 1891 StatsReporter.addAgentMS(agentMS);
1931 StatsReporter.addPhysicsMS(physicsMS + physicsMS2); 1892 StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
1932 StatsReporter.addOtherMS(otherMS); 1893 StatsReporter.addOtherMS(otherMS);
1933 StatsReporter.AddSpareMS(spareMS);
1934 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS()); 1894 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
1935 StatsReporter.AddScriptMS((int) GetAndResetScriptExecutionTime());
1936 1895
1937 // Send the correct time values to the stats reporter for the 1896
1938 // frame times 1897 tmpMS = Util.GetTimeStampMS();
1939 StatsReporter.addFrameTimeMilliseconds(preciseTotalFrameTime,
1940 preciseSimFrameTime, precisePhysicsFrameTime, 0.0);
1941 1898
1942 // Send the correct number of frames that the physics library 1899 previousFrameTick = m_lastFrameTick;
1943 // has processed to the stats reporter 1900 m_lastFrameTick = (int)(tmpMS + 0.5);
1944 StatsReporter.addPhysicsFrame(1);
1945 1901
1946 // Optionally warn if a frame takes double the amount of time that it should. 1902 // estimate sleep time
1903 tmpMS2 = tmpMS - framestart;
1904 tmpMS2 = (double)MinFrameTime * 1000.0D - tmpMS2;
1905
1906 m_firstHeartbeat = false;
1907
1908 // sleep if we can
1909 if (tmpMS2 > 0)
1910 Thread.Sleep((int)(tmpMS2 +0.5));
1911
1912 tmpMS2 = Util.GetTimeStampMS();
1913
1914 sleepMS = (float)(tmpMS2 - tmpMS);
1915 frameMS = (float)(tmpMS2 - framestart);
1916 StatsReporter.addSleepMS(sleepMS);
1917 StatsReporter.addFrameMS(frameMS);
1918
1919 // if (Frame%m_update_avatars == 0)
1920 // UpdateInWorldTime();
1921
1922 // Optionally warn if a frame takes double the amount of time that it should.
1947 if (DebugUpdates 1923 if (DebugUpdates
1948 && Util.EnvironmentTickCountSubtract( 1924 && Util.EnvironmentTickCountSubtract(
1949 m_lastFrameTick, previousFrameTick) > MinFrameTicks * 2) 1925 m_lastFrameTick, previousFrameTick) > (int)(MinFrameTime * 1000 * 2))
1926
1950 m_log.WarnFormat( 1927 m_log.WarnFormat(
1951 "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}", 1928 "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}",
1952 Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick), 1929 Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick),
1953 MinFrameTicks, 1930 MinFrameTime * 1000,
1931
1954 RegionInfo.RegionName); 1932 RegionInfo.RegionName);
1955 } 1933 }
1956
1957 // Finished updating scene frame, so stop the total frame's Stopwatch
1958 totalFrameStopwatch.Stop();
1959
1960 return spareMS >= 0;
1961 } 1934 }
1962 1935
1963 /// <summary> 1936 /// <summary>
@@ -1983,7 +1956,7 @@ namespace OpenSim.Region.Framework.Scenes
1983 public void AddGroupTarget(SceneObjectGroup grp) 1956 public void AddGroupTarget(SceneObjectGroup grp)
1984 { 1957 {
1985 lock (m_groupsWithTargets) 1958 lock (m_groupsWithTargets)
1986 m_groupsWithTargets[grp.UUID] = grp; 1959 m_groupsWithTargets[grp.UUID] = 0;
1987 } 1960 }
1988 1961
1989 public void RemoveGroupTarget(SceneObjectGroup grp) 1962 public void RemoveGroupTarget(SceneObjectGroup grp)
@@ -1994,18 +1967,24 @@ namespace OpenSim.Region.Framework.Scenes
1994 1967
1995 private void CheckAtTargets() 1968 private void CheckAtTargets()
1996 { 1969 {
1997 List<SceneObjectGroup> objs = null; 1970 List<UUID> objs = null;
1998 1971
1999 lock (m_groupsWithTargets) 1972 lock (m_groupsWithTargets)
2000 { 1973 {
2001 if (m_groupsWithTargets.Count != 0) 1974 if (m_groupsWithTargets.Count != 0)
2002 objs = new List<SceneObjectGroup>(m_groupsWithTargets.Values); 1975 objs = new List<UUID>(m_groupsWithTargets.Keys);
2003 } 1976 }
2004 1977
2005 if (objs != null) 1978 if (objs != null)
2006 { 1979 {
2007 foreach (SceneObjectGroup entry in objs) 1980 foreach (UUID entry in objs)
2008 entry.checkAtTargets(); 1981 {
1982 SceneObjectGroup grp = GetSceneObjectGroup(entry);
1983 if (grp == null)
1984 m_groupsWithTargets.Remove(entry);
1985 else
1986 grp.checkAtTargets();
1987 }
2009 } 1988 }
2010 } 1989 }
2011 1990
@@ -2029,6 +2008,11 @@ namespace OpenSim.Region.Framework.Scenes
2029 EventManager.TriggerTerrainTick(); 2008 EventManager.TriggerTerrainTick();
2030 } 2009 }
2031 2010
2011 private void CheckTerrainUpdates()
2012 {
2013 EventManager.TriggerTerrainCheckUpdates();
2014 }
2015
2032 /// <summary> 2016 /// <summary>
2033 /// Back up queued up changes 2017 /// Back up queued up changes
2034 /// </summary> 2018 /// </summary>
@@ -2080,7 +2064,7 @@ namespace OpenSim.Region.Framework.Scenes
2080 msg.fromAgentName = "Server"; 2064 msg.fromAgentName = "Server";
2081 msg.dialog = (byte)19; // Object msg 2065 msg.dialog = (byte)19; // Object msg
2082 msg.fromGroup = false; 2066 msg.fromGroup = false;
2083 msg.offline = (byte)0; 2067 msg.offline = (byte)1;
2084 msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID; 2068 msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID;
2085 msg.Position = Vector3.Zero; 2069 msg.Position = Vector3.Zero;
2086 msg.RegionID = RegionInfo.RegionID.Guid; 2070 msg.RegionID = RegionInfo.RegionID.Guid;
@@ -2316,7 +2300,7 @@ namespace OpenSim.Region.Framework.Scenes
2316 return PhysicsScene.SupportsRaycastWorldFiltered(); 2300 return PhysicsScene.SupportsRaycastWorldFiltered();
2317 } 2301 }
2318 2302
2319 public object RayCastFiltered(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter) 2303 public object RayCastFiltered(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter)
2320 { 2304 {
2321 if (PhysicsScene == null) 2305 if (PhysicsScene == null)
2322 return null; 2306 return null;
@@ -2338,14 +2322,24 @@ namespace OpenSim.Region.Framework.Scenes
2338 /// <returns></returns> 2322 /// <returns></returns>
2339 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter) 2323 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter)
2340 { 2324 {
2325
2326 float wheight = (float)RegionInfo.RegionSettings.WaterHeight;
2327 Vector3 wpos = Vector3.Zero;
2328 // Check for water surface intersection from above
2329 if ( (RayStart.Z > wheight) && (RayEnd.Z < wheight) )
2330 {
2331 float ratio = (RayStart.Z - wheight) / (RayStart.Z - RayEnd.Z);
2332 wpos.X = RayStart.X - (ratio * (RayStart.X - RayEnd.X));
2333 wpos.Y = RayStart.Y - (ratio * (RayStart.Y - RayEnd.Y));
2334 wpos.Z = wheight;
2335 }
2336
2341 Vector3 pos = Vector3.Zero; 2337 Vector3 pos = Vector3.Zero;
2342 if (RayEndIsIntersection == (byte)1) 2338 if (RayEndIsIntersection == (byte)1)
2343 { 2339 {
2344 pos = RayEnd; 2340 pos = RayEnd;
2345 return pos;
2346 } 2341 }
2347 2342 else if (RayTargetID != UUID.Zero)
2348 if (RayTargetID != UUID.Zero)
2349 { 2343 {
2350 SceneObjectPart target = GetSceneObjectPart(RayTargetID); 2344 SceneObjectPart target = GetSceneObjectPart(RayTargetID);
2351 2345
@@ -2390,13 +2384,10 @@ namespace OpenSim.Region.Framework.Scenes
2390 //pos.Z -= 0.25F; 2384 //pos.Z -= 0.25F;
2391 2385
2392 } 2386 }
2393
2394 return pos;
2395 } 2387 }
2396 else 2388 else
2397 { 2389 {
2398 // We don't have a target here, so we're going to raytrace all the objects in the scene. 2390 // We don't have a target here, so we're going to raytrace all the objects in the scene.
2399
2400 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false); 2391 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false);
2401 2392
2402 // Un-comment the following line to print the raytrace results to the console. 2393 // Un-comment the following line to print the raytrace results to the console.
@@ -2404,15 +2395,13 @@ namespace OpenSim.Region.Framework.Scenes
2404 2395
2405 if (ei.HitTF) 2396 if (ei.HitTF)
2406 { 2397 {
2407 pos = ei.ipoint; 2398 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
2408 } 2399 }
2409 else 2400 else
2410 { 2401 {
2411 // fall back to our stupid functionality 2402 // fall back to our stupid functionality
2412 pos = RayEnd; 2403 pos = RayEnd;
2413 } 2404 }
2414
2415 return pos;
2416 } 2405 }
2417 } 2406 }
2418 else 2407 else
@@ -2423,8 +2412,12 @@ namespace OpenSim.Region.Framework.Scenes
2423 //increase height so its above the ground. 2412 //increase height so its above the ground.
2424 //should be getting the normal of the ground at the rez point and using that? 2413 //should be getting the normal of the ground at the rez point and using that?
2425 pos.Z += scale.Z / 2f; 2414 pos.Z += scale.Z / 2f;
2426 return pos; 2415// return pos;
2427 } 2416 }
2417
2418 // check against posible water intercept
2419 if (wpos.Z > pos.Z) pos = wpos;
2420 return pos;
2428 } 2421 }
2429 2422
2430 2423
@@ -2515,12 +2508,12 @@ namespace OpenSim.Region.Framework.Scenes
2515 { 2508 {
2516 if (m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates)) 2509 if (m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates))
2517 { 2510 {
2511 sceneObject.IsDeleted = false;
2518 EventManager.TriggerObjectAddedToScene(sceneObject); 2512 EventManager.TriggerObjectAddedToScene(sceneObject);
2519 return true; 2513 return true;
2520 } 2514 }
2521 2515
2522 return false; 2516 return false;
2523
2524 } 2517 }
2525 2518
2526 /// <summary> 2519 /// <summary>
@@ -2612,6 +2605,15 @@ namespace OpenSim.Region.Framework.Scenes
2612 /// </summary> 2605 /// </summary>
2613 public void DeleteAllSceneObjects() 2606 public void DeleteAllSceneObjects()
2614 { 2607 {
2608 DeleteAllSceneObjects(false);
2609 }
2610
2611 /// <summary>
2612 /// Delete every object from the scene. This does not include attachments worn by avatars.
2613 /// </summary>
2614 public void DeleteAllSceneObjects(bool exceptNoCopy)
2615 {
2616 List<SceneObjectGroup> toReturn = new List<SceneObjectGroup>();
2615 lock (Entities) 2617 lock (Entities)
2616 { 2618 {
2617 EntityBase[] entities = Entities.GetEntities(); 2619 EntityBase[] entities = Entities.GetEntities();
@@ -2620,11 +2622,24 @@ namespace OpenSim.Region.Framework.Scenes
2620 if (e is SceneObjectGroup) 2622 if (e is SceneObjectGroup)
2621 { 2623 {
2622 SceneObjectGroup sog = (SceneObjectGroup)e; 2624 SceneObjectGroup sog = (SceneObjectGroup)e;
2623 if (!sog.IsAttachment) 2625 if (sog != null && !sog.IsAttachment)
2624 DeleteSceneObject((SceneObjectGroup)e, false); 2626 {
2627 if (!exceptNoCopy || ((sog.GetEffectivePermissions() & (uint)PermissionMask.Copy) != 0))
2628 {
2629 DeleteSceneObject((SceneObjectGroup)e, false);
2630 }
2631 else
2632 {
2633 toReturn.Add((SceneObjectGroup)e);
2634 }
2635 }
2625 } 2636 }
2626 } 2637 }
2627 } 2638 }
2639 if (toReturn.Count > 0)
2640 {
2641 returnObjects(toReturn.ToArray(), UUID.Zero);
2642 }
2628 } 2643 }
2629 2644
2630 /// <summary> 2645 /// <summary>
@@ -2655,6 +2670,14 @@ namespace OpenSim.Region.Framework.Scenes
2655 else 2670 else
2656 group.StopScriptInstances(); 2671 group.StopScriptInstances();
2657 2672
2673 List<UUID> avatars = group.GetSittingAvatars();
2674 foreach (UUID av in avatars)
2675 {
2676 ScenePresence p = GetScenePresence(av);
2677 if (p != null && p.ParentUUID == UUID.Zero)
2678 p.StandUp();
2679 }
2680
2658 SceneObjectPart[] partList = group.Parts; 2681 SceneObjectPart[] partList = group.Parts;
2659 2682
2660 foreach (SceneObjectPart part in partList) 2683 foreach (SceneObjectPart part in partList)
@@ -2682,6 +2705,8 @@ namespace OpenSim.Region.Framework.Scenes
2682 } 2705 }
2683 2706
2684 group.DeleteGroupFromScene(silent); 2707 group.DeleteGroupFromScene(silent);
2708 if (!silent)
2709 SendKillObject(new List<uint>() { group.LocalId });
2685 2710
2686 // m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); 2711 // m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
2687 } 2712 }
@@ -2718,6 +2743,11 @@ namespace OpenSim.Region.Framework.Scenes
2718 return false; 2743 return false;
2719 } 2744 }
2720 2745
2746
2747 public void updateScenePartGroup(SceneObjectPart part, SceneObjectGroup grp)
2748 {
2749 m_sceneGraph.updateScenePartGroup(part, grp);
2750 }
2721 /// <summary> 2751 /// <summary>
2722 /// Move the given scene object into a new region depending on which region its absolute position has moved 2752 /// Move the given scene object into a new region depending on which region its absolute position has moved
2723 /// into. 2753 /// into.
@@ -2783,17 +2813,11 @@ namespace OpenSim.Region.Framework.Scenes
2783 if (regionCombinerModule == null) 2813 if (regionCombinerModule == null)
2784 { 2814 {
2785 // Regular region. Just check for region size 2815 // Regular region. Just check for region size
2786 if (xx < RegionInfo.RegionSizeX && yy < RegionInfo.RegionSizeY) 2816 if (xx < RegionInfo.RegionSizeX && yy < RegionInfo.RegionSizeY )
2787 ret = true; 2817 ret = true;
2788 } 2818 }
2789 else
2790 {
2791 // 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);
2793 }
2794 2819
2795 return ret; 2820 return ret;
2796
2797 } 2821 }
2798 2822
2799 /// <summary> 2823 /// <summary>
@@ -2817,8 +2841,50 @@ namespace OpenSim.Region.Framework.Scenes
2817 return false; 2841 return false;
2818 } 2842 }
2819 2843
2820 if (!EntityTransferModule.HandleIncomingSceneObject(newObject, newPosition)) 2844 // If the user is banned, we won't let any of their objects
2845 // enter. Period.
2846 //
2847 if (RegionInfo.EstateSettings.IsBanned(newObject.OwnerID, 36))
2848 {
2849 m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", newObject.OwnerID);
2850 return false;
2851 }
2852
2853 if (newPosition != Vector3.Zero)
2854 newObject.RootPart.GroupPosition = newPosition;
2855
2856 if (!AddSceneObject(newObject))
2857 {
2858 m_log.DebugFormat(
2859 "[INTERREGION]: Problem adding scene object {0} in {1} ", newObject.UUID, RegionInfo.RegionName);
2821 return false; 2860 return false;
2861 }
2862
2863 if (!newObject.IsAttachment)
2864 {
2865 // FIXME: It would be better to never add the scene object at all rather than add it and then delete
2866 // it
2867 if (!Permissions.CanObjectEntry(newObject.UUID, true, newObject.AbsolutePosition))
2868 {
2869 // Deny non attachments based on parcel settings
2870 //
2871 m_log.Info("[INTERREGION]: Denied prim crossing because of parcel settings");
2872
2873 DeleteSceneObject(newObject, false);
2874
2875 return false;
2876 }
2877
2878 // For attachments, we need to wait until the agent is root
2879 // before we restart the scripts, or else some functions won't work.
2880 newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject));
2881 newObject.ResumeScripts();
2882
2883 // AddSceneObject already does this and doing it again messes
2884 // up region crossings, so don't.
2885 //if (newObject.RootPart.KeyframeMotion != null)
2886 // newObject.RootPart.KeyframeMotion.UpdateSceneObject(newObject);
2887 }
2822 2888
2823 // Do this as late as possible so that listeners have full access to the incoming object 2889 // Do this as late as possible so that listeners have full access to the incoming object
2824 EventManager.TriggerOnIncomingSceneObject(newObject); 2890 EventManager.TriggerOnIncomingSceneObject(newObject);
@@ -2835,6 +2901,23 @@ namespace OpenSim.Region.Framework.Scenes
2835 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns> 2901 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns>
2836 public bool AddSceneObject(SceneObjectGroup sceneObject) 2902 public bool AddSceneObject(SceneObjectGroup sceneObject)
2837 { 2903 {
2904 if (sceneObject.OwnerID == UUID.Zero)
2905 {
2906 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero", sceneObject.UUID);
2907 return false;
2908 }
2909
2910 // If the user is banned, we won't let any of their objects
2911 // enter. Period.
2912 //
2913 int flags = GetUserFlags(sceneObject.OwnerID);
2914 if (RegionInfo.EstateSettings.IsBanned(sceneObject.OwnerID, flags))
2915 {
2916 m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", sceneObject.OwnerID);
2917
2918 return false;
2919 }
2920
2838 // Force allocation of new LocalId 2921 // Force allocation of new LocalId
2839 // 2922 //
2840 SceneObjectPart[] parts = sceneObject.Parts; 2923 SceneObjectPart[] parts = sceneObject.Parts;
@@ -2871,22 +2954,62 @@ namespace OpenSim.Region.Framework.Scenes
2871 // information that this is due to a teleport/border cross rather than an ordinary attachment. 2954 // information that this is due to a teleport/border cross rather than an ordinary attachment.
2872 // We currently do this in Scene.MakeRootAgent() instead. 2955 // We currently do this in Scene.MakeRootAgent() instead.
2873 if (AttachmentsModule != null) 2956 if (AttachmentsModule != null)
2874 AttachmentsModule.AttachObject(sp, grp, 0, false, false, true); 2957 AttachmentsModule.AttachObject(sp, grp, 0, false, false, false, true);
2875 } 2958 }
2876 else 2959 else
2877 { 2960 {
2961 m_log.DebugFormat("[SCENE]: Attachment {0} arrived and scene presence was not found, setting to temp", sceneObject.UUID);
2878 RootPrim.RemFlag(PrimFlags.TemporaryOnRez); 2962 RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
2879 RootPrim.AddFlag(PrimFlags.TemporaryOnRez); 2963 RootPrim.AddFlag(PrimFlags.TemporaryOnRez);
2880 } 2964 }
2965 if (sceneObject.OwnerID == UUID.Zero)
2966 {
2967 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero after attachment processing. BUG!", sceneObject.UUID);
2968 return false;
2969 }
2881 } 2970 }
2882 else 2971 else
2883 { 2972 {
2973 if (sceneObject.OwnerID == UUID.Zero)
2974 {
2975 m_log.ErrorFormat("[SCENE]: Owner ID for non-attachment {0} was zero", sceneObject.UUID);
2976 return false;
2977 }
2884 AddRestoredSceneObject(sceneObject, true, false); 2978 AddRestoredSceneObject(sceneObject, true, false);
2885 } 2979 }
2886 2980
2887 return true; 2981 return true;
2888 } 2982 }
2889 2983
2984 private int GetStateSource(SceneObjectGroup sog)
2985 {
2986 ScenePresence sp = GetScenePresence(sog.OwnerID);
2987
2988 if (sp != null)
2989 return sp.GetStateSource();
2990
2991 return 2; // StateSource.PrimCrossing
2992 }
2993
2994 public int GetUserFlags(UUID user)
2995 {
2996 //Unfortunately the SP approach means that the value is cached until region is restarted
2997 /*
2998 ScenePresence sp;
2999 if (TryGetScenePresence(user, out sp))
3000 {
3001 return sp.UserFlags;
3002 }
3003 else
3004 {
3005 */
3006 UserAccount uac = UserAccountService.GetUserAccount(RegionInfo.ScopeID, user);
3007 if (uac == null)
3008 return 0;
3009 return uac.UserFlags;
3010 //}
3011 }
3012
2890 #endregion 3013 #endregion
2891 3014
2892 #region Add/Remove Avatar Methods 3015 #region Add/Remove Avatar Methods
@@ -2922,8 +3045,9 @@ namespace OpenSim.Region.Framework.Scenes
2922 vialogin 3045 vialogin
2923 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 3046 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0
2924 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 3047 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2925 3048
2926 // CheckHeartbeat(); 3049 CheckHeartbeat();
3050
2927 3051
2928 sp = GetScenePresence(client.AgentId); 3052 sp = GetScenePresence(client.AgentId);
2929 3053
@@ -2934,27 +3058,27 @@ namespace OpenSim.Region.Framework.Scenes
2934 if (sp == null) 3058 if (sp == null)
2935 { 3059 {
2936 m_log.DebugFormat( 3060 m_log.DebugFormat(
2937 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", 3061 "[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); 3062 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos,
2939 3063 ((TPFlags)aCircuit.teleportFlags).ToString());
2940 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type); 3064
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); 3065 m_clientManager.Add(client);
2954 SubscribeToClientEvents(client); 3066 SubscribeToClientEvents(client);
2955 m_eventManager.TriggerOnNewPresence(sp); 3067
3068 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2956 3069
2957 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags; 3070 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags;
3071
3072/* done in completMovement
3073 InventoryFolderBase cof = InventoryService.GetFolderForType(client.AgentId, (AssetType)46);
3074 if (cof == null)
3075 sp.COF = UUID.Zero;
3076 else
3077 sp.COF = cof.ID;
3078
3079 m_log.DebugFormat("[SCENE]: COF for {0} is {1}", client.AgentId, sp.COF);
3080 */
3081 m_eventManager.TriggerOnNewPresence(sp);
2958 } 3082 }
2959 else 3083 else
2960 { 3084 {
@@ -2963,7 +3087,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. 3087 // 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 3088 // But need to know what happens in the case where a ScenePresence is already present (and if this
2965 // actually occurs). 3089 // actually occurs).
2966 client.SceneAgent = sp; 3090
2967 3091
2968 m_log.WarnFormat( 3092 m_log.WarnFormat(
2969 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", 3093 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence",
@@ -2971,6 +3095,7 @@ namespace OpenSim.Region.Framework.Scenes
2971 3095
2972 reallyNew = false; 3096 reallyNew = false;
2973 } 3097 }
3098 client.SceneAgent = sp;
2974 3099
2975 // This is currently also being done earlier in NewUserConnection for real users to see if this 3100 // 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 3101 // resolves problems where HG agents are occasionally seen by others as "Unknown user" in chat and other
@@ -3089,19 +3214,15 @@ namespace OpenSim.Region.Framework.Scenes
3089 // and the scene presence and the client, if they exist 3214 // and the scene presence and the client, if they exist
3090 try 3215 try
3091 { 3216 {
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); 3217 ScenePresence sp = WaitGetScenePresence(agentID);
3218
3095 if (sp != null) 3219 if (sp != null)
3096 { 3220 {
3097 PresenceService.LogoutAgent(sp.ControllingClient.SessionId); 3221 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
3098 3222
3099 CloseAgent(sp.UUID, false); 3223 CloseAgent(sp.UUID, false);
3100 } 3224 }
3101 else 3225
3102 {
3103 m_log.WarnFormat("[SCENE]: Could not find scene presence for {0}", agentID);
3104 }
3105 // BANG! SLASH! 3226 // BANG! SLASH!
3106 m_authenticateHandler.RemoveCircuit(agentID); 3227 m_authenticateHandler.RemoveCircuit(agentID);
3107 3228
@@ -3138,7 +3259,7 @@ namespace OpenSim.Region.Framework.Scenes
3138 3259
3139 public virtual void SubscribeToClientTerrainEvents(IClientAPI client) 3260 public virtual void SubscribeToClientTerrainEvents(IClientAPI client)
3140 { 3261 {
3141 client.OnRegionHandShakeReply += SendLayerData; 3262// client.OnRegionHandShakeReply += SendLayerData;
3142 } 3263 }
3143 3264
3144 public virtual void SubscribeToClientPrimEvents(IClientAPI client) 3265 public virtual void SubscribeToClientPrimEvents(IClientAPI client)
@@ -3146,6 +3267,8 @@ namespace OpenSim.Region.Framework.Scenes
3146 client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimGroupPosition; 3267 client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimGroupPosition;
3147 client.OnUpdatePrimSinglePosition += m_sceneGraph.UpdatePrimSinglePosition; 3268 client.OnUpdatePrimSinglePosition += m_sceneGraph.UpdatePrimSinglePosition;
3148 3269
3270 client.onClientChangeObject += m_sceneGraph.ClientChangeObject;
3271
3149 client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimGroupRotation; 3272 client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimGroupRotation;
3150 client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimGroupRotation; 3273 client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimGroupRotation;
3151 client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation; 3274 client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation;
@@ -3202,6 +3325,7 @@ namespace OpenSim.Region.Framework.Scenes
3202 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory; 3325 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory;
3203 client.OnUpdateInventoryItem += UpdateInventoryItemAsset; 3326 client.OnUpdateInventoryItem += UpdateInventoryItemAsset;
3204 client.OnCopyInventoryItem += CopyInventoryItem; 3327 client.OnCopyInventoryItem += CopyInventoryItem;
3328 client.OnMoveItemsAndLeaveCopy += MoveInventoryItemsLeaveCopy;
3205 client.OnMoveInventoryItem += MoveInventoryItem; 3329 client.OnMoveInventoryItem += MoveInventoryItem;
3206 client.OnRemoveInventoryItem += RemoveInventoryItem; 3330 client.OnRemoveInventoryItem += RemoveInventoryItem;
3207 client.OnRemoveInventoryFolder += RemoveInventoryFolder; 3331 client.OnRemoveInventoryFolder += RemoveInventoryFolder;
@@ -3263,7 +3387,7 @@ namespace OpenSim.Region.Framework.Scenes
3263 3387
3264 public virtual void UnSubscribeToClientTerrainEvents(IClientAPI client) 3388 public virtual void UnSubscribeToClientTerrainEvents(IClientAPI client)
3265 { 3389 {
3266 client.OnRegionHandShakeReply -= SendLayerData; 3390// client.OnRegionHandShakeReply -= SendLayerData;
3267 } 3391 }
3268 3392
3269 public virtual void UnSubscribeToClientPrimEvents(IClientAPI client) 3393 public virtual void UnSubscribeToClientPrimEvents(IClientAPI client)
@@ -3271,6 +3395,8 @@ namespace OpenSim.Region.Framework.Scenes
3271 client.OnUpdatePrimGroupPosition -= m_sceneGraph.UpdatePrimGroupPosition; 3395 client.OnUpdatePrimGroupPosition -= m_sceneGraph.UpdatePrimGroupPosition;
3272 client.OnUpdatePrimSinglePosition -= m_sceneGraph.UpdatePrimSinglePosition; 3396 client.OnUpdatePrimSinglePosition -= m_sceneGraph.UpdatePrimSinglePosition;
3273 3397
3398 client.onClientChangeObject -= m_sceneGraph.ClientChangeObject;
3399
3274 client.OnUpdatePrimGroupRotation -= m_sceneGraph.UpdatePrimGroupRotation; 3400 client.OnUpdatePrimGroupRotation -= m_sceneGraph.UpdatePrimGroupRotation;
3275 client.OnUpdatePrimGroupMouseRotation -= m_sceneGraph.UpdatePrimGroupRotation; 3401 client.OnUpdatePrimGroupMouseRotation -= m_sceneGraph.UpdatePrimGroupRotation;
3276 client.OnUpdatePrimSingleRotation -= m_sceneGraph.UpdatePrimSingleRotation; 3402 client.OnUpdatePrimSingleRotation -= m_sceneGraph.UpdatePrimSingleRotation;
@@ -3428,16 +3554,14 @@ namespace OpenSim.Region.Framework.Scenes
3428 if (target != null && target2 != null) 3554 if (target != null && target2 != null)
3429 { 3555 {
3430 Vector3 direction = Vector3.Normalize(RayEnd - RayStart); 3556 Vector3 direction = Vector3.Normalize(RayEnd - RayStart);
3431 Vector3 AXOrigin = RayStart; 3557
3432 Vector3 AXdirection = direction;
3433
3434 pos = target2.AbsolutePosition; 3558 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()); 3559 //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 3560
3437 // TODO: Raytrace better here 3561 // TODO: Raytrace better here
3438 3562
3439 //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection)); 3563 //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection));
3440 Ray NewRay = new Ray(AXOrigin, AXdirection); 3564 Ray NewRay = new Ray(RayStart,direction);
3441 3565
3442 // Ray Trace against target here 3566 // Ray Trace against target here
3443 EntityIntersection ei = target2.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, CopyCenters); 3567 EntityIntersection ei = target2.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, CopyCenters);
@@ -3519,6 +3643,10 @@ namespace OpenSim.Region.Framework.Scenes
3519 /// <param name='closeChildAgents'> 3643 /// <param name='closeChildAgents'>
3520 /// Close the neighbour child agents associated with this client. 3644 /// Close the neighbour child agents associated with this client.
3521 /// </param> 3645 /// </param>
3646 ///
3647
3648 private object m_removeClientPrivLock = new Object();
3649
3522 public void RemoveClient(UUID agentID, bool closeChildAgents) 3650 public void RemoveClient(UUID agentID, bool closeChildAgents)
3523 { 3651 {
3524 AgentCircuitData acd = m_authenticateHandler.GetAgentCircuitData(agentID); 3652 AgentCircuitData acd = m_authenticateHandler.GetAgentCircuitData(agentID);
@@ -3535,8 +3663,8 @@ namespace OpenSim.Region.Framework.Scenes
3535 } 3663 }
3536 3664
3537 // TODO: Can we now remove this lock? 3665 // TODO: Can we now remove this lock?
3538 lock (acd) 3666 lock (m_removeClientPrivLock)
3539 { 3667 {
3540 bool isChildAgent = false; 3668 bool isChildAgent = false;
3541 3669
3542 ScenePresence avatar = GetScenePresence(agentID); 3670 ScenePresence avatar = GetScenePresence(agentID);
@@ -3580,8 +3708,8 @@ namespace OpenSim.Region.Framework.Scenes
3580 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop 3708 // 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 3709 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
3582 if (closeChildAgents && CapsModule != null) 3710 if (closeChildAgents && CapsModule != null)
3583 CapsModule.RemoveCaps(agentID); 3711 CapsModule.RemoveCaps(agentID, avatar.ControllingClient.CircuitCode);
3584 3712
3585 if (closeChildAgents && !isChildAgent) 3713 if (closeChildAgents && !isChildAgent)
3586 { 3714 {
3587 List<ulong> regions = avatar.KnownRegionHandles; 3715 List<ulong> regions = avatar.KnownRegionHandles;
@@ -3592,13 +3720,17 @@ namespace OpenSim.Region.Framework.Scenes
3592 } 3720 }
3593 3721
3594 m_eventManager.TriggerClientClosed(agentID, this); 3722 m_eventManager.TriggerClientClosed(agentID, this);
3723// m_log.Debug("[Scene]TriggerClientClosed done");
3595 m_eventManager.TriggerOnRemovePresence(agentID); 3724 m_eventManager.TriggerOnRemovePresence(agentID);
3596 3725// m_log.Debug("[Scene]TriggerOnRemovePresence done");
3726
3597 if (!isChildAgent) 3727 if (!isChildAgent)
3598 { 3728 {
3599 if (AttachmentsModule != null) 3729 if (AttachmentsModule != null)
3600 { 3730 {
3731// m_log.Debug("[Scene]DeRezAttachments");
3601 AttachmentsModule.DeRezAttachments(avatar); 3732 AttachmentsModule.DeRezAttachments(avatar);
3733// m_log.Debug("[Scene]DeRezAttachments done");
3602 } 3734 }
3603 3735
3604 ForEachClient( 3736 ForEachClient(
@@ -3612,7 +3744,11 @@ namespace OpenSim.Region.Framework.Scenes
3612 3744
3613 // It's possible for child agents to have transactions if changes are being made cross-border. 3745 // It's possible for child agents to have transactions if changes are being made cross-border.
3614 if (AgentTransactionsModule != null) 3746 if (AgentTransactionsModule != null)
3747 {
3748// m_log.Debug("[Scene]RemoveAgentAssetTransactions");
3615 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID); 3749 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
3750 }
3751 m_log.Debug("[Scene] The avatar has left the building");
3616 } 3752 }
3617 catch (Exception e) 3753 catch (Exception e)
3618 { 3754 {
@@ -3731,6 +3867,9 @@ namespace OpenSim.Region.Framework.Scenes
3731 /// or other applications where a full grid/Hypergrid presence may not be required.</param> 3867 /// 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 3868 /// <returns>True if the region accepts this agent. False if it does not. False will
3733 /// also return a reason.</returns> 3869 /// also return a reason.</returns>
3870 ///
3871 private object m_newUserConnLock = new object();
3872
3734 public bool NewUserConnection(AgentCircuitData acd, uint teleportFlags, GridRegion source, out string reason, bool requirePresenceLookup) 3873 public bool NewUserConnection(AgentCircuitData acd, uint teleportFlags, GridRegion source, out string reason, bool requirePresenceLookup)
3735 { 3874 {
3736 bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 || 3875 bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 ||
@@ -3764,6 +3903,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) 3903 (source == null) ? "" : string.Format("From region {0} ({1}){2}", source.RegionName, source.RegionID, (source.RawServerURI == null) ? "" : " @ " + source.ServerURI)
3765 ); 3904 );
3766 3905
3906// m_log.DebugFormat("NewUserConnection stack {0}", Environment.StackTrace);
3907
3767 if (!LoginsEnabled) 3908 if (!LoginsEnabled)
3768 { 3909 {
3769 reason = "Logins Disabled"; 3910 reason = "Logins Disabled";
@@ -3891,7 +4032,7 @@ namespace OpenSim.Region.Framework.Scenes
3891 } 4032 }
3892 4033
3893 // TODO: can we remove this lock? 4034 // TODO: can we remove this lock?
3894 lock (acd) 4035 lock (m_newUserConnLock)
3895 { 4036 {
3896 if (sp != null && !sp.IsChildAgent) 4037 if (sp != null && !sp.IsChildAgent)
3897 { 4038 {
@@ -3918,6 +4059,12 @@ namespace OpenSim.Region.Framework.Scenes
3918 // We need the circuit data here for some of the subsequent checks. (groups, for example) 4059 // We need the circuit data here for some of the subsequent checks. (groups, for example)
3919 // If the checks fail, we remove the circuit. 4060 // If the checks fail, we remove the circuit.
3920 acd.teleportFlags = teleportFlags; 4061 acd.teleportFlags = teleportFlags;
4062
4063 // Remove any preexisting circuit - we don't want duplicates
4064 // This is a stab at preventing avatar "ghosting"
4065 if (vialogin)
4066 m_authenticateHandler.RemoveCircuit(acd.AgentID);
4067
3921 m_authenticateHandler.AddNewCircuit(acd.circuitcode, acd); 4068 m_authenticateHandler.AddNewCircuit(acd.circuitcode, acd);
3922 4069
3923 land = LandChannel.GetLandObject(acd.startpos.X, acd.startpos.Y); 4070 land = LandChannel.GetLandObject(acd.startpos.X, acd.startpos.Y);
@@ -3925,6 +4072,9 @@ namespace OpenSim.Region.Framework.Scenes
3925 // On login test land permisions 4072 // On login test land permisions
3926 if (vialogin) 4073 if (vialogin)
3927 { 4074 {
4075 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
4076 if (cache != null)
4077 cache.Remove(acd.firstname + " " + acd.lastname);
3928 if (land != null && !TestLandRestrictions(acd.AgentID, out reason, ref acd.startpos.X, ref acd.startpos.Y)) 4078 if (land != null && !TestLandRestrictions(acd.AgentID, out reason, ref acd.startpos.X, ref acd.startpos.Y))
3929 { 4079 {
3930 m_authenticateHandler.RemoveCircuit(acd.circuitcode); 4080 m_authenticateHandler.RemoveCircuit(acd.circuitcode);
@@ -3979,7 +4129,7 @@ namespace OpenSim.Region.Framework.Scenes
3979 if (CapsModule != null) 4129 if (CapsModule != null)
3980 { 4130 {
3981 CapsModule.SetAgentCapsSeeds(acd); 4131 CapsModule.SetAgentCapsSeeds(acd);
3982 CapsModule.CreateCaps(acd.AgentID); 4132 CapsModule.CreateCaps(acd.AgentID, acd.circuitcode);
3983 } 4133 }
3984 } 4134 }
3985 else 4135 else
@@ -3992,15 +4142,15 @@ namespace OpenSim.Region.Framework.Scenes
3992 { 4142 {
3993 m_log.DebugFormat( 4143 m_log.DebugFormat(
3994 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}", 4144 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
3995 acd.AgentID, RegionInfo.RegionName); 4145 acd.AgentID, RegionInfo.RegionName);
3996
3997 sp.AdjustKnownSeeds();
3998 4146
3999 if (CapsModule != null) 4147 if (CapsModule != null)
4000 { 4148 {
4001 CapsModule.SetAgentCapsSeeds(acd); 4149 CapsModule.SetAgentCapsSeeds(acd);
4002 CapsModule.CreateCaps(acd.AgentID); 4150 CapsModule.CreateCaps(acd.AgentID, acd.circuitcode);
4003 } 4151 }
4152
4153 sp.AdjustKnownSeeds();
4004 } 4154 }
4005 } 4155 }
4006 4156
@@ -4010,6 +4160,11 @@ namespace OpenSim.Region.Framework.Scenes
4010 CacheUserName(null, acd); 4160 CacheUserName(null, acd);
4011 } 4161 }
4012 4162
4163 if (CapsModule != null)
4164 {
4165 CapsModule.ActivateCaps(acd.circuitcode);
4166 }
4167
4013 if (vialogin) 4168 if (vialogin)
4014 { 4169 {
4015// CleanDroppedAttachments(); 4170// CleanDroppedAttachments();
@@ -4079,6 +4234,8 @@ namespace OpenSim.Region.Framework.Scenes
4079 } 4234 }
4080 4235
4081 // Honor parcel landing type and position. 4236 // Honor parcel landing type and position.
4237 /*
4238 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
4082 if (land != null) 4239 if (land != null)
4083 { 4240 {
4084 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) 4241 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero)
@@ -4093,6 +4250,7 @@ namespace OpenSim.Region.Framework.Scenes
4093 } 4250 }
4094 } 4251 }
4095 } 4252 }
4253 */// This is now handled properly in ScenePresence.MakeRootAgent
4096 } 4254 }
4097 4255
4098 return true; 4256 return true;
@@ -4117,12 +4275,13 @@ namespace OpenSim.Region.Framework.Scenes
4117 { 4275 {
4118 if (posX < 0) 4276 if (posX < 0)
4119 posX = 0; 4277 posX = 0;
4120 else if (posX >= (float)RegionInfo.RegionSizeX) 4278
4121 posX = (float)RegionInfo.RegionSizeX - 0.001f; 4279 else if (posX >= RegionInfo.RegionSizeX)
4280 posX = RegionInfo.RegionSizeX - 0.5f;
4122 if (posY < 0) 4281 if (posY < 0)
4123 posY = 0; 4282 posY = 0;
4124 else if (posY >= (float)RegionInfo.RegionSizeY) 4283 else if (posY >= RegionInfo.RegionSizeY)
4125 posY = (float)RegionInfo.RegionSizeY - 0.001f; 4284 posY = RegionInfo.RegionSizeY - 0.5f;
4126 4285
4127 reason = String.Empty; 4286 reason = String.Empty;
4128 if (Permissions.IsGod(agentID)) 4287 if (Permissions.IsGod(agentID))
@@ -4226,7 +4385,8 @@ namespace OpenSim.Region.Framework.Scenes
4226 { 4385 {
4227 if (RegionInfo.EstateSettings != null) 4386 if (RegionInfo.EstateSettings != null)
4228 { 4387 {
4229 if (RegionInfo.EstateSettings.IsBanned(agent.AgentID)) 4388 int flags = GetUserFlags(agent.AgentID);
4389 if (RegionInfo.EstateSettings.IsBanned(agent.AgentID, flags))
4230 { 4390 {
4231 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", 4391 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); 4392 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
@@ -4415,6 +4575,22 @@ namespace OpenSim.Region.Framework.Scenes
4415 m_log.DebugFormat( 4575 m_log.DebugFormat(
4416 "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName); 4576 "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName);
4417 4577
4578 if (!LoginsEnabled)
4579 {
4580// reason = "Logins Disabled";
4581 m_log.DebugFormat(
4582 "[SCENE]: update for {0} in {1} refused: Logins Disabled", cAgentData.AgentID, RegionInfo.RegionName);
4583 return false;
4584 }
4585 // We have to wait until the viewer contacts this region after receiving EAC.
4586 // That calls AddNewClient, which finally creates the ScenePresence
4587 int flags = GetUserFlags(cAgentData.AgentID);
4588 if (RegionInfo.EstateSettings.IsBanned(cAgentData.AgentID, flags))
4589 {
4590 m_log.DebugFormat("[SCENE]: Denying root agent entry to {0}: banned", cAgentData.AgentID);
4591 return false;
4592 }
4593
4418 // TODO: This check should probably be in QueryAccess(). 4594 // TODO: This check should probably be in QueryAccess().
4419 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, RegionInfo.RegionSizeX / 2, RegionInfo.RegionSizeY / 2); 4595 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, RegionInfo.RegionSizeX / 2, RegionInfo.RegionSizeY / 2);
4420 if (nearestParcel == null) 4596 if (nearestParcel == null)
@@ -4432,8 +4608,14 @@ namespace OpenSim.Region.Framework.Scenes
4432 // a UseCircuitCode packet which in turn calls AddNewAgent which finally creates the ScenePresence. 4608 // a UseCircuitCode packet which in turn calls AddNewAgent which finally creates the ScenePresence.
4433 ScenePresence sp = WaitGetScenePresence(cAgentData.AgentID); 4609 ScenePresence sp = WaitGetScenePresence(cAgentData.AgentID);
4434 4610
4435 if (sp != null) 4611 if (sp != null)
4436 { 4612 {
4613 if (!sp.IsChildAgent)
4614 {
4615 m_log.WarnFormat("[SCENE]: Ignoring a child update on a root agent {0} {1} in {2}",
4616 sp.Name, sp.UUID, Name);
4617 return false;
4618 }
4437 if (cAgentData.SessionID != sp.ControllingClient.SessionId) 4619 if (cAgentData.SessionID != sp.ControllingClient.SessionId)
4438 { 4620 {
4439 m_log.WarnFormat( 4621 m_log.WarnFormat(
@@ -4518,7 +4700,7 @@ namespace OpenSim.Region.Framework.Scenes
4518 /// <param name='agentID'></param> 4700 /// <param name='agentID'></param>
4519 protected virtual ScenePresence WaitGetScenePresence(UUID agentID) 4701 protected virtual ScenePresence WaitGetScenePresence(UUID agentID)
4520 { 4702 {
4521 int ntimes = 20; 4703 int ntimes = 30;
4522 ScenePresence sp = null; 4704 ScenePresence sp = null;
4523 while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0)) 4705 while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0))
4524 Thread.Sleep(1000); 4706 Thread.Sleep(1000);
@@ -4568,6 +4750,16 @@ namespace OpenSim.Region.Framework.Scenes
4568 return false; 4750 return false;
4569 } 4751 }
4570 4752
4753// public bool IncomingCloseAgent(UUID agentID)
4754// {
4755// return IncomingCloseAgent(agentID, false);
4756// }
4757
4758// public bool IncomingCloseChildAgent(UUID agentID)
4759// {
4760// return IncomingCloseAgent(agentID, true);
4761// }
4762
4571 /// <summary> 4763 /// <summary>
4572 /// Tell a single client to prepare to close. 4764 /// Tell a single client to prepare to close.
4573 /// </summary> 4765 /// </summary>
@@ -4630,6 +4822,20 @@ namespace OpenSim.Region.Framework.Scenes
4630 4822
4631 if (sp == null) 4823 if (sp == null)
4632 { 4824 {
4825 // If there is no scene presence, we may be handling a dead
4826 // client. These can keep an avatar from reentering a region
4827 // and since they don't get cleaned up they will stick
4828 // around until region restart. So, if there is no SP,
4829 // remove the client as well.
4830 IClientAPI client = null;
4831 if (m_clientManager.TryGetValue(agentID, out client))
4832 {
4833 m_clientManager.Remove(agentID);
4834 if (CapsModule != null)
4835 CapsModule.RemoveCaps(agentID, 0);
4836 m_log.DebugFormat( "[SCENE]: Dead client for agent ID {0} was cleaned up in {1}", agentID, Name);
4837 return true;
4838 }
4633 m_log.DebugFormat( 4839 m_log.DebugFormat(
4634 "[SCENE]: Called CloseClient() with agent ID {0} but no such presence is in {1}", 4840 "[SCENE]: Called CloseClient() with agent ID {0} but no such presence is in {1}",
4635 agentID, Name); 4841 agentID, Name);
@@ -4664,7 +4870,11 @@ namespace OpenSim.Region.Framework.Scenes
4664 sp.LifecycleState = ScenePresenceState.Removing; 4870 sp.LifecycleState = ScenePresenceState.Removing;
4665 } 4871 }
4666 4872
4667 sp.ControllingClient.Close(force); 4873 if (sp != null)
4874 {
4875 sp.ControllingClient.Close(force, force);
4876 return true;
4877 }
4668 4878
4669 return true; 4879 return true;
4670 } 4880 }
@@ -4826,7 +5036,10 @@ namespace OpenSim.Region.Framework.Scenes
4826 5036
4827 public LandData GetLandData(float x, float y) 5037 public LandData GetLandData(float x, float y)
4828 { 5038 {
4829 return LandChannel.GetLandObject(x, y).LandData; 5039 ILandObject parcel = LandChannel.GetLandObject(x, y);
5040 if (parcel == null)
5041 return null;
5042 return parcel.LandData;
4830 } 5043 }
4831 5044
4832 /// <summary> 5045 /// <summary>
@@ -4842,7 +5055,10 @@ namespace OpenSim.Region.Framework.Scenes
4842 public LandData GetLandData(uint x, uint y) 5055 public LandData GetLandData(uint x, uint y)
4843 { 5056 {
4844 m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y); 5057 m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y);
4845 return LandChannel.GetLandObject((int)x, (int)y).LandData; 5058 ILandObject parcel = LandChannel.GetLandObject((int)x, (int)y);
5059 if (parcel == null)
5060 return null;
5061 return parcel.LandData;
4846 } 5062 }
4847 5063
4848 #endregion 5064 #endregion
@@ -5230,7 +5446,7 @@ namespace OpenSim.Region.Framework.Scenes
5230 { 5446 {
5231 if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) 5447 if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
5232 { 5448 {
5233 if (grp.RootPart.Expires <= DateTime.Now) 5449 if (grp.GetSittingAvatarsCount() == 0 && grp.RootPart.Expires <= DateTime.Now)
5234 DeleteSceneObject(grp, false); 5450 DeleteSceneObject(grp, false);
5235 } 5451 }
5236 } 5452 }
@@ -5244,35 +5460,80 @@ namespace OpenSim.Region.Framework.Scenes
5244 SimulationDataService.RemoveObject(uuid, RegionInfo.RegionID); 5460 SimulationDataService.RemoveObject(uuid, RegionInfo.RegionID);
5245 } 5461 }
5246 5462
5247 public int GetHealth() 5463 public int GetHealth(out int flags, out string message)
5248 { 5464 {
5249 // Returns: 5465 // Returns:
5250 // 1 = sim is up and accepting http requests. The heartbeat has 5466 // 1 = sim is up and accepting http requests. The heartbeat has
5251 // stopped and the sim is probably locked up, but a remote 5467 // stopped and the sim is probably locked up, but a remote
5252 // admin restart may succeed 5468 // admin restart may succeed
5253 // 5469 //
5254 // 2 = Sim is up and the heartbeat is running. The sim is likely 5470 // 2 = Sim is up and the heartbeat is running. The sim is likely
5255 // usable for people within and logins _may_ work 5471 // usable for people within
5256 // 5472 //
5257 // 3 = We have seen a new user enter within the past 4 minutes 5473 // 3 = Sim is up and one packet thread is running. Sim is
5474 // unstable and will not accept new logins
5475 //
5476 // 4 = Sim is up and both packet threads are running. Sim is
5477 // likely usable
5478 //
5479 // 5 = We have seen a new user enter within the past 4 minutes
5258 // which can be seen as positive confirmation of sim health 5480 // which can be seen as positive confirmation of sim health
5259 // 5481 //
5260 int health = 1; // Start at 1, means we're up 5482 int health = 1; // Start at 1, means we're up
5261 5483
5484 flags = 0;
5485 message = String.Empty;
5486
5487 CheckHeartbeat();
5488
5489 if (m_firstHeartbeat || (m_lastIncoming == 0 && m_lastOutgoing == 0))
5490 {
5491 // We're still starting
5492 // 0 means "in startup", it can't happen another way, since
5493 // to get here, we must be able to accept http connections
5494 return 0;
5495 }
5496
5262 if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) < 1000) 5497 if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) < 1000)
5263 health += 1; 5498 {
5499 health+=1;
5500 flags |= 1;
5501 }
5502
5503 if (Util.EnvironmentTickCountSubtract(m_lastIncoming) < 1000)
5504 {
5505 health+=1;
5506 flags |= 2;
5507 }
5508
5509 if (Util.EnvironmentTickCountSubtract(m_lastOutgoing) < 1000)
5510 {
5511 health+=1;
5512 flags |= 4;
5513 }
5264 else 5514 else
5515 {
5516int pid = System.Diagnostics.Process.GetCurrentProcess().Id;
5517System.Diagnostics.Process proc = new System.Diagnostics.Process();
5518proc.EnableRaisingEvents=false;
5519proc.StartInfo.FileName = "/bin/kill";
5520proc.StartInfo.Arguments = "-QUIT " + pid.ToString();
5521proc.Start();
5522proc.WaitForExit();
5523Thread.Sleep(1000);
5524Environment.Exit(1);
5525 }
5526
5527 if (flags != 7)
5265 return health; 5528 return health;
5266 5529
5267 // A login in the last 4 mins? We can't be doing too badly 5530 // A login in the last 4 mins? We can't be doing too badly
5268 // 5531 //
5269 if ((Util.EnvironmentTickCountSubtract(m_LastLogin)) < 240000) 5532 if (Util.EnvironmentTickCountSubtract(m_LastLogin) < 240000)
5270 health++; 5533 health++;
5271 else 5534 else
5272 return health; 5535 return health;
5273 5536
5274// CheckHeartbeat();
5275
5276 return health; 5537 return health;
5277 } 5538 }
5278 5539
@@ -5360,7 +5621,7 @@ namespace OpenSim.Region.Framework.Scenes
5360 bool wasUsingPhysics = ((jointProxyObject.Flags & PrimFlags.Physics) != 0); 5621 bool wasUsingPhysics = ((jointProxyObject.Flags & PrimFlags.Physics) != 0);
5361 if (wasUsingPhysics) 5622 if (wasUsingPhysics)
5362 { 5623 {
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 5624 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 } 5625 }
5365 } 5626 }
5366 5627
@@ -5463,14 +5724,14 @@ namespace OpenSim.Region.Framework.Scenes
5463 return (((vsn.X * xdiff) + (vsn.Y * ydiff)) / (-1 * vsn.Z)) + p0.Z; 5724 return (((vsn.X * xdiff) + (vsn.Y * ydiff)) / (-1 * vsn.Z)) + p0.Z;
5464 } 5725 }
5465 5726
5466// private void CheckHeartbeat() 5727 private void CheckHeartbeat()
5467// { 5728 {
5468// if (m_firstHeartbeat) 5729 if (m_firstHeartbeat)
5469// return; 5730 return;
5470// 5731
5471// if (Util.EnvironmentTickCountSubtract(m_lastFrameTick) > 2000) 5732 if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) > 5000)
5472// StartTimer(); 5733 Start();
5473// } 5734 }
5474 5735
5475 public override ISceneObject DeserializeObject(string representation) 5736 public override ISceneObject DeserializeObject(string representation)
5476 { 5737 {
@@ -5527,8 +5788,7 @@ namespace OpenSim.Region.Framework.Scenes
5527 //Go to the edge, this happens in teleporting to a region with no available parcels 5788 //Go to the edge, this happens in teleporting to a region with no available parcels
5528 Vector3 nearestRegionEdgePoint = GetNearestRegionEdgePosition(avatar); 5789 Vector3 nearestRegionEdgePoint = GetNearestRegionEdgePosition(avatar);
5529 5790
5530 //m_log.Debug("They are really in a place they don't belong, sending them to: " + nearestRegionEdgePoint.ToString()); 5791 //Debug.WriteLine("They are really in a place they don't belong, sending them to: " + nearestRegionEdgePoint.ToString());
5531
5532 return nearestRegionEdgePoint; 5792 return nearestRegionEdgePoint;
5533 } 5793 }
5534 5794
@@ -5784,7 +6044,55 @@ namespace OpenSim.Region.Framework.Scenes
5784 mapModule.GenerateMaptile(); 6044 mapModule.GenerateMaptile();
5785 } 6045 }
5786 6046
5787 private void RegenerateMaptileAndReregister(object sender, ElapsedEventArgs e) 6047// public void CleanDroppedAttachments()
6048// {
6049// List<SceneObjectGroup> objectsToDelete =
6050// new List<SceneObjectGroup>();
6051//
6052// lock (m_cleaningAttachments)
6053// {
6054// ForEachSOG(delegate (SceneObjectGroup grp)
6055// {
6056// if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp)))
6057// {
6058// UUID agentID = grp.OwnerID;
6059// if (agentID == UUID.Zero)
6060// {
6061// objectsToDelete.Add(grp);
6062// return;
6063// }
6064//
6065// ScenePresence sp = GetScenePresence(agentID);
6066// if (sp == null)
6067// {
6068// objectsToDelete.Add(grp);
6069// return;
6070// }
6071// }
6072// });
6073// }
6074//
6075// foreach (SceneObjectGroup grp in objectsToDelete)
6076// {
6077// m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID);
6078// DeleteSceneObject(grp, true);
6079// }
6080// }
6081
6082 public void ThreadAlive(int threadCode)
6083 {
6084 switch(threadCode)
6085 {
6086 case 1: // Incoming
6087 m_lastIncoming = Util.EnvironmentTickCount();
6088 break;
6089 case 2: // Incoming
6090 m_lastOutgoing = Util.EnvironmentTickCount();
6091 break;
6092 }
6093 }
6094
6095 public void RegenerateMaptileAndReregister(object sender, ElapsedEventArgs e)
5788 { 6096 {
5789 RegenerateMaptile(); 6097 RegenerateMaptile();
5790 6098
@@ -5950,7 +6258,19 @@ namespace OpenSim.Region.Framework.Scenes
5950 return true; 6258 return true;
5951 } 6259 }
5952 6260
5953 /// <summary> 6261 public void StartTimerWatchdog()
6262 {
6263 m_timerWatchdog.Interval = 1000;
6264 m_timerWatchdog.Elapsed += TimerWatchdog;
6265 m_timerWatchdog.AutoReset = true;
6266 m_timerWatchdog.Start();
6267 }
6268
6269 public void TimerWatchdog(object sender, ElapsedEventArgs e)
6270 {
6271 CheckHeartbeat();
6272 }
6273
5954 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the 6274 /// 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!. 6275 /// autopilot that moves an avatar to a sit target!.
5956 /// </summary> 6276 /// </summary>
@@ -6029,6 +6349,11 @@ namespace OpenSim.Region.Framework.Scenes
6029 return m_SpawnPoint - 1; 6349 return m_SpawnPoint - 1;
6030 } 6350 }
6031 6351
6352 private void HandleGcCollect(string module, string[] args)
6353 {
6354 GC.Collect();
6355 }
6356
6032 /// <summary> 6357 /// <summary>
6033 /// Wrappers to get physics modules retrieve assets. 6358 /// Wrappers to get physics modules retrieve assets.
6034 /// </summary> 6359 /// </summary>