aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Scene.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs502
1 files changed, 417 insertions, 85 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 086de53..c162519 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -96,6 +96,7 @@ namespace OpenSim.Region.Framework.Scenes
96 // TODO: need to figure out how allow client agents but deny 96 // TODO: need to figure out how allow client agents but deny
97 // root agents when ACL denies access to root agent 97 // root agents when ACL denies access to root agent
98 public bool m_strictAccessControl = true; 98 public bool m_strictAccessControl = true;
99 public bool m_seeIntoBannedRegion = false;
99 public int MaxUndoCount = 5; 100 public int MaxUndoCount = 5;
100 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet; 101 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet;
101 public bool LoginLock = false; 102 public bool LoginLock = false;
@@ -111,12 +112,14 @@ namespace OpenSim.Region.Framework.Scenes
111 112
112 protected int m_splitRegionID; 113 protected int m_splitRegionID;
113 protected Timer m_restartWaitTimer = new Timer(); 114 protected Timer m_restartWaitTimer = new Timer();
115 protected Timer m_timerWatchdog = new Timer();
114 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); 116 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
115 protected List<RegionInfo> m_neighbours = new List<RegionInfo>(); 117 protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
116 protected string m_simulatorVersion = "OpenSimulator Server"; 118 protected string m_simulatorVersion = "OpenSimulator Server";
117 protected ModuleLoader m_moduleLoader; 119 protected ModuleLoader m_moduleLoader;
118 protected AgentCircuitManager m_authenticateHandler; 120 protected AgentCircuitManager m_authenticateHandler;
119 protected SceneCommunicationService m_sceneGridService; 121 protected SceneCommunicationService m_sceneGridService;
122 protected ISnmpModule m_snmpService = null;
120 123
121 protected ISimulationDataService m_SimulationDataService; 124 protected ISimulationDataService m_SimulationDataService;
122 protected IEstateDataService m_EstateDataService; 125 protected IEstateDataService m_EstateDataService;
@@ -168,7 +171,7 @@ namespace OpenSim.Region.Framework.Scenes
168 private int m_update_events = 1; 171 private int m_update_events = 1;
169 private int m_update_backup = 200; 172 private int m_update_backup = 200;
170 private int m_update_terrain = 50; 173 private int m_update_terrain = 50;
171// private int m_update_land = 1; 174 private int m_update_land = 10;
172 private int m_update_coarse_locations = 50; 175 private int m_update_coarse_locations = 50;
173 176
174 private int agentMS; 177 private int agentMS;
@@ -183,6 +186,7 @@ namespace OpenSim.Region.Framework.Scenes
183 private int landMS; 186 private int landMS;
184 private int lastCompletedFrame; 187 private int lastCompletedFrame;
185 188
189 public bool CombineRegions = false;
186 /// <summary> 190 /// <summary>
187 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched 191 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched
188 /// asynchronously from the update loop. 192 /// asynchronously from the update loop.
@@ -205,10 +209,12 @@ namespace OpenSim.Region.Framework.Scenes
205 private bool m_scripts_enabled = true; 209 private bool m_scripts_enabled = true;
206 private string m_defaultScriptEngine; 210 private string m_defaultScriptEngine;
207 private int m_LastLogin; 211 private int m_LastLogin;
208 private Thread HeartbeatThread; 212 private Thread HeartbeatThread = null;
209 private volatile bool shuttingdown; 213 private volatile bool shuttingdown;
210 214
211 private int m_lastUpdate; 215 private int m_lastUpdate;
216 private int m_lastIncoming;
217 private int m_lastOutgoing;
212 private bool m_firstHeartbeat = true; 218 private bool m_firstHeartbeat = true;
213 219
214 private object m_deleting_scene_object = new object(); 220 private object m_deleting_scene_object = new object();
@@ -256,6 +262,19 @@ namespace OpenSim.Region.Framework.Scenes
256 get { return m_sceneGridService; } 262 get { return m_sceneGridService; }
257 } 263 }
258 264
265 public ISnmpModule SnmpService
266 {
267 get
268 {
269 if (m_snmpService == null)
270 {
271 m_snmpService = RequestModuleInterface<ISnmpModule>();
272 }
273
274 return m_snmpService;
275 }
276 }
277
259 public ISimulationDataService SimulationDataService 278 public ISimulationDataService SimulationDataService
260 { 279 {
261 get 280 get
@@ -542,6 +561,9 @@ namespace OpenSim.Region.Framework.Scenes
542 m_EstateDataService = estateDataService; 561 m_EstateDataService = estateDataService;
543 m_regionHandle = m_regInfo.RegionHandle; 562 m_regionHandle = m_regInfo.RegionHandle;
544 m_regionName = m_regInfo.RegionName; 563 m_regionName = m_regInfo.RegionName;
564 m_lastUpdate = Util.EnvironmentTickCount();
565 m_lastIncoming = 0;
566 m_lastOutgoing = 0;
545 567
546 m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this); 568 m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this);
547 m_asyncSceneObjectDeleter.Enabled = true; 569 m_asyncSceneObjectDeleter.Enabled = true;
@@ -655,11 +677,13 @@ namespace OpenSim.Region.Framework.Scenes
655 //Animation states 677 //Animation states
656 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); 678 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
657 // TODO: Change default to true once the feature is supported 679 // TODO: Change default to true once the feature is supported
658 m_usePreJump = startupConfig.GetBoolean("enableprejump", false); 680 m_usePreJump = startupConfig.GetBoolean("enableprejump", true);
659 681
660 m_physicalPrim = startupConfig.GetBoolean("physical_prim", true); 682 m_physicalPrim = startupConfig.GetBoolean("physical_prim", true);
661 683
662 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys); 684 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
685
686 m_log.DebugFormat("[SCENE]: prejump is {0}", m_usePreJump ? "ON" : "OFF");
663 if (RegionInfo.NonphysPrimMax > 0) 687 if (RegionInfo.NonphysPrimMax > 0)
664 { 688 {
665 m_maxNonphys = RegionInfo.NonphysPrimMax; 689 m_maxNonphys = RegionInfo.NonphysPrimMax;
@@ -691,6 +715,7 @@ namespace OpenSim.Region.Framework.Scenes
691 m_persistAfter *= 10000000; 715 m_persistAfter *= 10000000;
692 716
693 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); 717 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
718 m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine);
694 719
695 IConfig packetConfig = m_config.Configs["PacketPool"]; 720 IConfig packetConfig = m_config.Configs["PacketPool"];
696 if (packetConfig != null) 721 if (packetConfig != null)
@@ -700,6 +725,8 @@ namespace OpenSim.Region.Framework.Scenes
700 } 725 }
701 726
702 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); 727 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
728 m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion);
729 CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false);
703 730
704 m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true); 731 m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true);
705 if (m_generateMaptiles) 732 if (m_generateMaptiles)
@@ -735,9 +762,9 @@ namespace OpenSim.Region.Framework.Scenes
735 m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain); 762 m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain);
736 m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning); 763 m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning);
737 } 764 }
738 catch 765 catch (Exception e)
739 { 766 {
740 m_log.Warn("[SCENE]: Failed to load StartupConfig"); 767 m_log.Error("[SCENE]: Failed to load StartupConfig: " + e.ToString());
741 } 768 }
742 769
743 #endregion Region Config 770 #endregion Region Config
@@ -1148,7 +1175,9 @@ namespace OpenSim.Region.Framework.Scenes
1148 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); 1175 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
1149 if (HeartbeatThread != null) 1176 if (HeartbeatThread != null)
1150 { 1177 {
1178 m_log.ErrorFormat("[SCENE]: Restarting heartbeat thread because it hasn't reported in in region {0}", RegionInfo.RegionName);
1151 HeartbeatThread.Abort(); 1179 HeartbeatThread.Abort();
1180 Watchdog.AbortThread(HeartbeatThread.ManagedThreadId);
1152 HeartbeatThread = null; 1181 HeartbeatThread = null;
1153 } 1182 }
1154 m_lastUpdate = Util.EnvironmentTickCount(); 1183 m_lastUpdate = Util.EnvironmentTickCount();
@@ -1191,9 +1220,6 @@ namespace OpenSim.Region.Framework.Scenes
1191 { 1220 {
1192 while (!shuttingdown) 1221 while (!shuttingdown)
1193 Update(); 1222 Update();
1194
1195 m_lastUpdate = Util.EnvironmentTickCount();
1196 m_firstHeartbeat = false;
1197 } 1223 }
1198 catch (ThreadAbortException) 1224 catch (ThreadAbortException)
1199 { 1225 {
@@ -1291,6 +1317,13 @@ namespace OpenSim.Region.Framework.Scenes
1291 eventMS = Util.EnvironmentTickCountSubtract(evMS); ; 1317 eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
1292 } 1318 }
1293 1319
1320 // if (Frame % m_update_land == 0)
1321 // {
1322 // int ldMS = Util.EnvironmentTickCount();
1323 // UpdateLand();
1324 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1325 // }
1326
1294 if (Frame % m_update_backup == 0) 1327 if (Frame % m_update_backup == 0)
1295 { 1328 {
1296 int backMS = Util.EnvironmentTickCount(); 1329 int backMS = Util.EnvironmentTickCount();
@@ -1392,12 +1425,16 @@ namespace OpenSim.Region.Framework.Scenes
1392 maintc = Util.EnvironmentTickCountSubtract(maintc); 1425 maintc = Util.EnvironmentTickCountSubtract(maintc);
1393 maintc = (int)(MinFrameTime * 1000) - maintc; 1426 maintc = (int)(MinFrameTime * 1000) - maintc;
1394 1427
1428
1429 m_lastUpdate = Util.EnvironmentTickCount();
1430 m_firstHeartbeat = false;
1431
1395 if (maintc > 0) 1432 if (maintc > 0)
1396 Thread.Sleep(maintc); 1433 Thread.Sleep(maintc);
1397 1434
1398 // Tell the watchdog that this thread is still alive 1435 // Tell the watchdog that this thread is still alive
1399 Watchdog.UpdateThread(); 1436 Watchdog.UpdateThread();
1400 } 1437 }
1401 1438
1402 public void AddGroupTarget(SceneObjectGroup grp) 1439 public void AddGroupTarget(SceneObjectGroup grp)
1403 { 1440 {
@@ -1413,9 +1450,9 @@ namespace OpenSim.Region.Framework.Scenes
1413 1450
1414 private void CheckAtTargets() 1451 private void CheckAtTargets()
1415 { 1452 {
1416 Dictionary<UUID, SceneObjectGroup>.ValueCollection objs; 1453 List<SceneObjectGroup> objs = new List<SceneObjectGroup>();
1417 lock (m_groupsWithTargets) 1454 lock (m_groupsWithTargets)
1418 objs = m_groupsWithTargets.Values; 1455 objs = new List<SceneObjectGroup>(m_groupsWithTargets.Values);
1419 1456
1420 foreach (SceneObjectGroup entry in objs) 1457 foreach (SceneObjectGroup entry in objs)
1421 entry.checkAtTargets(); 1458 entry.checkAtTargets();
@@ -1734,14 +1771,24 @@ namespace OpenSim.Region.Framework.Scenes
1734 /// <returns></returns> 1771 /// <returns></returns>
1735 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter) 1772 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter)
1736 { 1773 {
1774
1775 float wheight = (float)RegionInfo.RegionSettings.WaterHeight;
1776 Vector3 wpos = Vector3.Zero;
1777 // Check for water surface intersection from above
1778 if ( (RayStart.Z > wheight) && (RayEnd.Z < wheight) )
1779 {
1780 float ratio = (RayStart.Z - wheight) / (RayStart.Z - RayEnd.Z);
1781 wpos.X = RayStart.X - (ratio * (RayStart.X - RayEnd.X));
1782 wpos.Y = RayStart.Y - (ratio * (RayStart.Y - RayEnd.Y));
1783 wpos.Z = wheight;
1784 }
1785
1737 Vector3 pos = Vector3.Zero; 1786 Vector3 pos = Vector3.Zero;
1738 if (RayEndIsIntersection == (byte)1) 1787 if (RayEndIsIntersection == (byte)1)
1739 { 1788 {
1740 pos = RayEnd; 1789 pos = RayEnd;
1741 return pos;
1742 } 1790 }
1743 1791 else if (RayTargetID != UUID.Zero)
1744 if (RayTargetID != UUID.Zero)
1745 { 1792 {
1746 SceneObjectPart target = GetSceneObjectPart(RayTargetID); 1793 SceneObjectPart target = GetSceneObjectPart(RayTargetID);
1747 1794
@@ -1763,7 +1810,7 @@ namespace OpenSim.Region.Framework.Scenes
1763 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter); 1810 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter);
1764 1811
1765 // Un-comment out the following line to Get Raytrace results printed to the console. 1812 // Un-comment out the following line to Get Raytrace results printed to the console.
1766 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); 1813 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
1767 float ScaleOffset = 0.5f; 1814 float ScaleOffset = 0.5f;
1768 1815
1769 // If we hit something 1816 // If we hit something
@@ -1786,13 +1833,10 @@ namespace OpenSim.Region.Framework.Scenes
1786 //pos.Z -= 0.25F; 1833 //pos.Z -= 0.25F;
1787 1834
1788 } 1835 }
1789
1790 return pos;
1791 } 1836 }
1792 else 1837 else
1793 { 1838 {
1794 // We don't have a target here, so we're going to raytrace all the objects in the scene. 1839 // We don't have a target here, so we're going to raytrace all the objects in the scene.
1795
1796 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false); 1840 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false);
1797 1841
1798 // Un-comment the following line to print the raytrace results to the console. 1842 // Un-comment the following line to print the raytrace results to the console.
@@ -1801,13 +1845,12 @@ namespace OpenSim.Region.Framework.Scenes
1801 if (ei.HitTF) 1845 if (ei.HitTF)
1802 { 1846 {
1803 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); 1847 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
1804 } else 1848 }
1849 else
1805 { 1850 {
1806 // fall back to our stupid functionality 1851 // fall back to our stupid functionality
1807 pos = RayEnd; 1852 pos = RayEnd;
1808 } 1853 }
1809
1810 return pos;
1811 } 1854 }
1812 } 1855 }
1813 else 1856 else
@@ -1818,8 +1861,12 @@ namespace OpenSim.Region.Framework.Scenes
1818 //increase height so its above the ground. 1861 //increase height so its above the ground.
1819 //should be getting the normal of the ground at the rez point and using that? 1862 //should be getting the normal of the ground at the rez point and using that?
1820 pos.Z += scale.Z / 2f; 1863 pos.Z += scale.Z / 2f;
1821 return pos; 1864// return pos;
1822 } 1865 }
1866
1867 // check against posible water intercept
1868 if (wpos.Z > pos.Z) pos = wpos;
1869 return pos;
1823 } 1870 }
1824 1871
1825 1872
@@ -1903,7 +1950,10 @@ namespace OpenSim.Region.Framework.Scenes
1903 public bool AddRestoredSceneObject( 1950 public bool AddRestoredSceneObject(
1904 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 1951 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
1905 { 1952 {
1906 return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); 1953 bool result = m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates);
1954 if (result)
1955 sceneObject.IsDeleted = false;
1956 return result;
1907 } 1957 }
1908 1958
1909 /// <summary> 1959 /// <summary>
@@ -1993,6 +2043,15 @@ namespace OpenSim.Region.Framework.Scenes
1993 /// </summary> 2043 /// </summary>
1994 public void DeleteAllSceneObjects() 2044 public void DeleteAllSceneObjects()
1995 { 2045 {
2046 DeleteAllSceneObjects(false);
2047 }
2048
2049 /// <summary>
2050 /// Delete every object from the scene. This does not include attachments worn by avatars.
2051 /// </summary>
2052 public void DeleteAllSceneObjects(bool exceptNoCopy)
2053 {
2054 List<SceneObjectGroup> toReturn = new List<SceneObjectGroup>();
1996 lock (Entities) 2055 lock (Entities)
1997 { 2056 {
1998 EntityBase[] entities = Entities.GetEntities(); 2057 EntityBase[] entities = Entities.GetEntities();
@@ -2001,11 +2060,24 @@ namespace OpenSim.Region.Framework.Scenes
2001 if (e is SceneObjectGroup) 2060 if (e is SceneObjectGroup)
2002 { 2061 {
2003 SceneObjectGroup sog = (SceneObjectGroup)e; 2062 SceneObjectGroup sog = (SceneObjectGroup)e;
2004 if (!sog.IsAttachment) 2063 if (sog != null && !sog.IsAttachment)
2005 DeleteSceneObject((SceneObjectGroup)e, false); 2064 {
2065 if (!exceptNoCopy || ((sog.GetEffectivePermissions() & (uint)PermissionMask.Copy) != 0))
2066 {
2067 DeleteSceneObject((SceneObjectGroup)e, false);
2068 }
2069 else
2070 {
2071 toReturn.Add((SceneObjectGroup)e);
2072 }
2073 }
2006 } 2074 }
2007 } 2075 }
2008 } 2076 }
2077 if (toReturn.Count > 0)
2078 {
2079 returnObjects(toReturn.ToArray(), UUID.Zero);
2080 }
2009 } 2081 }
2010 2082
2011 /// <summary> 2083 /// <summary>
@@ -2053,6 +2125,8 @@ namespace OpenSim.Region.Framework.Scenes
2053 } 2125 }
2054 2126
2055 group.DeleteGroupFromScene(silent); 2127 group.DeleteGroupFromScene(silent);
2128 if (!silent)
2129 SendKillObject(new List<uint>() { group.LocalId });
2056 2130
2057// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); 2131// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
2058 } 2132 }
@@ -2407,10 +2481,17 @@ namespace OpenSim.Region.Framework.Scenes
2407 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns> 2481 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns>
2408 public bool AddSceneObject(SceneObjectGroup sceneObject) 2482 public bool AddSceneObject(SceneObjectGroup sceneObject)
2409 { 2483 {
2484 if (sceneObject.OwnerID == UUID.Zero)
2485 {
2486 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero", sceneObject.UUID);
2487 return false;
2488 }
2489
2410 // If the user is banned, we won't let any of their objects 2490 // If the user is banned, we won't let any of their objects
2411 // enter. Period. 2491 // enter. Period.
2412 // 2492 //
2413 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID)) 2493 int flags = GetUserFlags(sceneObject.OwnerID);
2494 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID, flags))
2414 { 2495 {
2415 m_log.Info("[INTERREGION]: Denied prim crossing for " + 2496 m_log.Info("[INTERREGION]: Denied prim crossing for " +
2416 "banned avatar"); 2497 "banned avatar");
@@ -2457,12 +2538,23 @@ namespace OpenSim.Region.Framework.Scenes
2457 } 2538 }
2458 else 2539 else
2459 { 2540 {
2541 m_log.DebugFormat("[SCENE]: Attachment {0} arrived and scene presence was not found, setting to temp", sceneObject.UUID);
2460 RootPrim.RemFlag(PrimFlags.TemporaryOnRez); 2542 RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
2461 RootPrim.AddFlag(PrimFlags.TemporaryOnRez); 2543 RootPrim.AddFlag(PrimFlags.TemporaryOnRez);
2462 } 2544 }
2545 if (sceneObject.OwnerID == UUID.Zero)
2546 {
2547 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero after attachment processing. BUG!", sceneObject.UUID);
2548 return false;
2549 }
2463 } 2550 }
2464 else 2551 else
2465 { 2552 {
2553 if (sceneObject.OwnerID == UUID.Zero)
2554 {
2555 m_log.ErrorFormat("[SCENE]: Owner ID for non-attachment {0} was zero", sceneObject.UUID);
2556 return false;
2557 }
2466 AddRestoredSceneObject(sceneObject, true, false); 2558 AddRestoredSceneObject(sceneObject, true, false);
2467 2559
2468 if (!Permissions.CanObjectEntry(sceneObject.UUID, 2560 if (!Permissions.CanObjectEntry(sceneObject.UUID,
@@ -2492,6 +2584,24 @@ namespace OpenSim.Region.Framework.Scenes
2492 return 2; // StateSource.PrimCrossing 2584 return 2; // StateSource.PrimCrossing
2493 } 2585 }
2494 2586
2587 public int GetUserFlags(UUID user)
2588 {
2589 //Unfortunately the SP approach means that the value is cached until region is restarted
2590 /*
2591 ScenePresence sp;
2592 if (TryGetScenePresence(user, out sp))
2593 {
2594 return sp.UserFlags;
2595 }
2596 else
2597 {
2598 */
2599 UserAccount uac = UserAccountService.GetUserAccount(RegionInfo.ScopeID, user);
2600 if (uac == null)
2601 return 0;
2602 return uac.UserFlags;
2603 //}
2604 }
2495 #endregion 2605 #endregion
2496 2606
2497 #region Add/Remove Avatar Methods 2607 #region Add/Remove Avatar Methods
@@ -2513,6 +2623,7 @@ namespace OpenSim.Region.Framework.Scenes
2513 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2623 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2514 2624
2515 CheckHeartbeat(); 2625 CheckHeartbeat();
2626 ScenePresence presence;
2516 2627
2517 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here 2628 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here
2518 { 2629 {
@@ -2548,7 +2659,14 @@ namespace OpenSim.Region.Framework.Scenes
2548 2659
2549 EventManager.TriggerOnNewClient(client); 2660 EventManager.TriggerOnNewClient(client);
2550 if (vialogin) 2661 if (vialogin)
2662 {
2551 EventManager.TriggerOnClientLogin(client); 2663 EventManager.TriggerOnClientLogin(client);
2664
2665 // Send initial parcel data
2666 Vector3 pos = createdSp.AbsolutePosition;
2667 ILandObject land = LandChannel.GetLandObject(pos.X, pos.Y);
2668 land.SendLandUpdateToClient(client);
2669 }
2552 } 2670 }
2553 } 2671 }
2554 2672
@@ -2637,19 +2755,12 @@ namespace OpenSim.Region.Framework.Scenes
2637 // and the scene presence and the client, if they exist 2755 // and the scene presence and the client, if they exist
2638 try 2756 try
2639 { 2757 {
2640 // We need to wait for the client to make UDP contact first. 2758 ScenePresence sp = GetScenePresence(agentID);
2641 // It's the UDP contact that creates the scene presence 2759 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2642 ScenePresence sp = WaitGetScenePresence(agentID); 2760
2643 if (sp != null) 2761 if (sp != null)
2644 {
2645 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2646
2647 sp.ControllingClient.Close(); 2762 sp.ControllingClient.Close();
2648 } 2763
2649 else
2650 {
2651 m_log.WarnFormat("[SCENE]: Could not find scene presence for {0}", agentID);
2652 }
2653 // BANG! SLASH! 2764 // BANG! SLASH!
2654 m_authenticateHandler.RemoveCircuit(agentID); 2765 m_authenticateHandler.RemoveCircuit(agentID);
2655 2766
@@ -2749,6 +2860,7 @@ namespace OpenSim.Region.Framework.Scenes
2749 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory; 2860 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory;
2750 client.OnUpdateInventoryItem += UpdateInventoryItemAsset; 2861 client.OnUpdateInventoryItem += UpdateInventoryItemAsset;
2751 client.OnCopyInventoryItem += CopyInventoryItem; 2862 client.OnCopyInventoryItem += CopyInventoryItem;
2863 client.OnMoveItemsAndLeaveCopy += MoveInventoryItemsLeaveCopy;
2752 client.OnMoveInventoryItem += MoveInventoryItem; 2864 client.OnMoveInventoryItem += MoveInventoryItem;
2753 client.OnRemoveInventoryItem += RemoveInventoryItem; 2865 client.OnRemoveInventoryItem += RemoveInventoryItem;
2754 client.OnRemoveInventoryFolder += RemoveInventoryFolder; 2866 client.OnRemoveInventoryFolder += RemoveInventoryFolder;
@@ -2926,15 +3038,16 @@ namespace OpenSim.Region.Framework.Scenes
2926 /// </summary> 3038 /// </summary>
2927 /// <param name="agentId">The avatar's Unique ID</param> 3039 /// <param name="agentId">The avatar's Unique ID</param>
2928 /// <param name="client">The IClientAPI for the client</param> 3040 /// <param name="client">The IClientAPI for the client</param>
2929 public virtual void TeleportClientHome(UUID agentId, IClientAPI client) 3041 public virtual bool TeleportClientHome(UUID agentId, IClientAPI client)
2930 { 3042 {
2931 if (m_teleportModule != null) 3043 if (m_teleportModule != null)
2932 m_teleportModule.TeleportHome(agentId, client); 3044 return m_teleportModule.TeleportHome(agentId, client);
2933 else 3045 else
2934 { 3046 {
2935 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active"); 3047 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active");
2936 client.SendTeleportFailed("Unable to perform teleports on this simulator."); 3048 client.SendTeleportFailed("Unable to perform teleports on this simulator.");
2937 } 3049 }
3050 return false;
2938 } 3051 }
2939 3052
2940 /// <summary> 3053 /// <summary>
@@ -3026,6 +3139,16 @@ namespace OpenSim.Region.Framework.Scenes
3026 /// <param name="flags"></param> 3139 /// <param name="flags"></param>
3027 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags) 3140 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags)
3028 { 3141 {
3142 //Add half the avatar's height so that the user doesn't fall through prims
3143 ScenePresence presence;
3144 if (TryGetScenePresence(remoteClient.AgentId, out presence))
3145 {
3146 if (presence.Appearance != null)
3147 {
3148 position.Z = position.Z + (presence.Appearance.AvatarHeight / 2);
3149 }
3150 }
3151
3029 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt)) 3152 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt))
3030 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot. 3153 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot.
3031 m_dialogModule.SendAlertToUser(remoteClient, "Home position set."); 3154 m_dialogModule.SendAlertToUser(remoteClient, "Home position set.");
@@ -3094,8 +3217,9 @@ namespace OpenSim.Region.Framework.Scenes
3094 regions.Remove(RegionInfo.RegionHandle); 3217 regions.Remove(RegionInfo.RegionHandle);
3095 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3218 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3096 } 3219 }
3097 3220 m_log.Debug("[Scene] Beginning ClientClosed");
3098 m_eventManager.TriggerClientClosed(agentID, this); 3221 m_eventManager.TriggerClientClosed(agentID, this);
3222 m_log.Debug("[Scene] Finished ClientClosed");
3099 } 3223 }
3100 catch (NullReferenceException) 3224 catch (NullReferenceException)
3101 { 3225 {
@@ -3103,7 +3227,12 @@ namespace OpenSim.Region.Framework.Scenes
3103 // Avatar is already disposed :/ 3227 // Avatar is already disposed :/
3104 } 3228 }
3105 3229
3230 m_log.Debug("[Scene] Beginning OnRemovePresence");
3106 m_eventManager.TriggerOnRemovePresence(agentID); 3231 m_eventManager.TriggerOnRemovePresence(agentID);
3232 m_log.Debug("[Scene] Finished OnRemovePresence");
3233
3234 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3235 AttachmentsModule.SaveChangedAttachments(avatar);
3107 3236
3108 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc) 3237 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3109 AttachmentsModule.SaveChangedAttachments(avatar); 3238 AttachmentsModule.SaveChangedAttachments(avatar);
@@ -3112,7 +3241,7 @@ namespace OpenSim.Region.Framework.Scenes
3112 delegate(IClientAPI client) 3241 delegate(IClientAPI client)
3113 { 3242 {
3114 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3243 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3115 try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); } 3244 try { client.SendKillObject(avatar.RegionHandle, new List<uint>() { avatar.LocalId}); }
3116 catch (NullReferenceException) { } 3245 catch (NullReferenceException) { }
3117 }); 3246 });
3118 3247
@@ -3123,8 +3252,11 @@ namespace OpenSim.Region.Framework.Scenes
3123 } 3252 }
3124 3253
3125 // Remove the avatar from the scene 3254 // Remove the avatar from the scene
3255 m_log.Debug("[Scene] Begin RemoveScenePresence");
3126 m_sceneGraph.RemoveScenePresence(agentID); 3256 m_sceneGraph.RemoveScenePresence(agentID);
3257 m_log.Debug("[Scene] Finished RemoveScenePresence. Removing the client manager");
3127 m_clientManager.Remove(agentID); 3258 m_clientManager.Remove(agentID);
3259 m_log.Debug("[Scene] Removed the client manager. Firing avatar.close");
3128 3260
3129 try 3261 try
3130 { 3262 {
@@ -3138,9 +3270,10 @@ namespace OpenSim.Region.Framework.Scenes
3138 { 3270 {
3139 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString()); 3271 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString());
3140 } 3272 }
3141 3273 m_log.Debug("[Scene] Done. Firing RemoveCircuit");
3142 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3274 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
3143// CleanDroppedAttachments(); 3275// CleanDroppedAttachments();
3276 m_log.Debug("[Scene] The avatar has left the building");
3144 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 3277 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
3145 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); 3278 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
3146 } 3279 }
@@ -3171,19 +3304,24 @@ namespace OpenSim.Region.Framework.Scenes
3171 3304
3172 #region Entities 3305 #region Entities
3173 3306
3174 public void SendKillObject(uint localID) 3307 public void SendKillObject(List<uint> localIDs)
3175 { 3308 {
3176 SceneObjectPart part = GetSceneObjectPart(localID); 3309 List<uint> deleteIDs = new List<uint>();
3177 if (part != null) // It is a prim 3310
3311 foreach (uint localID in localIDs)
3178 { 3312 {
3179 if (!part.ParentGroup.IsDeleted) // Valid 3313 SceneObjectPart part = GetSceneObjectPart(localID);
3314 if (part != null) // It is a prim
3180 { 3315 {
3181 if (part.ParentGroup.RootPart != part) // Child part 3316 if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid
3182 return; 3317 {
3318 if (part.ParentGroup.RootPart != part) // Child part
3319 continue;
3320 }
3183 } 3321 }
3322 deleteIDs.Add(localID);
3184 } 3323 }
3185 3324 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, deleteIDs); });
3186 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); });
3187 } 3325 }
3188 3326
3189 #endregion 3327 #endregion
@@ -3201,7 +3339,6 @@ namespace OpenSim.Region.Framework.Scenes
3201 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate; 3339 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
3202 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar; 3340 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar;
3203 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid; 3341 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
3204 m_sceneGridService.KiPrimitive += SendKillObject;
3205 m_sceneGridService.OnGetLandData += GetLandData; 3342 m_sceneGridService.OnGetLandData += GetLandData;
3206 } 3343 }
3207 3344
@@ -3210,7 +3347,6 @@ namespace OpenSim.Region.Framework.Scenes
3210 /// </summary> 3347 /// </summary>
3211 public void UnRegisterRegionWithComms() 3348 public void UnRegisterRegionWithComms()
3212 { 3349 {
3213 m_sceneGridService.KiPrimitive -= SendKillObject;
3214 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid; 3350 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid;
3215 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar; 3351 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar;
3216 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate; 3352 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate;
@@ -3290,13 +3426,16 @@ namespace OpenSim.Region.Framework.Scenes
3290 sp = null; 3426 sp = null;
3291 } 3427 }
3292 3428
3293 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3294 3429
3295 //On login test land permisions 3430 //On login test land permisions
3296 if (vialogin) 3431 if (vialogin)
3297 { 3432 {
3298 if (land != null && !TestLandRestrictions(agent, land, out reason)) 3433 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
3434 if (cache != null)
3435 cache.Remove(agent.firstname + " " + agent.lastname);
3436 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3299 { 3437 {
3438 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString());
3300 return false; 3439 return false;
3301 } 3440 }
3302 } 3441 }
@@ -3319,8 +3458,13 @@ namespace OpenSim.Region.Framework.Scenes
3319 3458
3320 try 3459 try
3321 { 3460 {
3322 if (!AuthorizeUser(agent, out reason)) 3461 // Always check estate if this is a login. Always
3323 return false; 3462 // check if banned regions are to be blacked out.
3463 if (vialogin || (!m_seeIntoBannedRegion))
3464 {
3465 if (!AuthorizeUser(agent, out reason))
3466 return false;
3467 }
3324 } 3468 }
3325 catch (Exception e) 3469 catch (Exception e)
3326 { 3470 {
@@ -3422,6 +3566,8 @@ namespace OpenSim.Region.Framework.Scenes
3422 } 3566 }
3423 } 3567 }
3424 // Honor parcel landing type and position. 3568 // Honor parcel landing type and position.
3569 /*
3570 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3425 if (land != null) 3571 if (land != null)
3426 { 3572 {
3427 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) 3573 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero)
@@ -3429,26 +3575,34 @@ namespace OpenSim.Region.Framework.Scenes
3429 agent.startpos = land.LandData.UserLocation; 3575 agent.startpos = land.LandData.UserLocation;
3430 } 3576 }
3431 } 3577 }
3578 */// This is now handled properly in ScenePresence.MakeRootAgent
3432 } 3579 }
3433 3580
3434 return true; 3581 return true;
3435 } 3582 }
3436 3583
3437 private bool TestLandRestrictions(AgentCircuitData agent, ILandObject land, out string reason) 3584 private bool TestLandRestrictions(UUID agentID, out string reason, ref float posX, ref float posY)
3438 { 3585 {
3439 3586 reason = String.Empty;
3440 bool banned = land.IsBannedFromLand(agent.AgentID); 3587 if (Permissions.IsGod(agentID))
3441 bool restricted = land.IsRestrictedFromLand(agent.AgentID); 3588 return true;
3589
3590 ILandObject land = LandChannel.GetLandObject(posX, posY);
3591 if (land == null)
3592 return false;
3593
3594 bool banned = land.IsBannedFromLand(agentID);
3595 bool restricted = land.IsRestrictedFromLand(agentID);
3442 3596
3443 if (banned || restricted) 3597 if (banned || restricted)
3444 { 3598 {
3445 ILandObject nearestParcel = GetNearestAllowedParcel(agent.AgentID, agent.startpos.X, agent.startpos.Y); 3599 ILandObject nearestParcel = GetNearestAllowedParcel(agentID, posX, posY);
3446 if (nearestParcel != null) 3600 if (nearestParcel != null)
3447 { 3601 {
3448 //Move agent to nearest allowed 3602 //Move agent to nearest allowed
3449 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel); 3603 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel);
3450 agent.startpos.X = newPosition.X; 3604 posX = newPosition.X;
3451 agent.startpos.Y = newPosition.Y; 3605 posY = newPosition.Y;
3452 } 3606 }
3453 else 3607 else
3454 { 3608 {
@@ -3510,7 +3664,7 @@ namespace OpenSim.Region.Framework.Scenes
3510 3664
3511 if (!m_strictAccessControl) return true; 3665 if (!m_strictAccessControl) return true;
3512 if (Permissions.IsGod(agent.AgentID)) return true; 3666 if (Permissions.IsGod(agent.AgentID)) return true;
3513 3667
3514 if (AuthorizationService != null) 3668 if (AuthorizationService != null)
3515 { 3669 {
3516 if (!AuthorizationService.IsAuthorizedForRegion( 3670 if (!AuthorizationService.IsAuthorizedForRegion(
@@ -3518,14 +3672,14 @@ namespace OpenSim.Region.Framework.Scenes
3518 { 3672 {
3519 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region", 3673 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region",
3520 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3674 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
3521 3675
3522 return false; 3676 return false;
3523 } 3677 }
3524 } 3678 }
3525 3679
3526 if (m_regInfo.EstateSettings != null) 3680 if (m_regInfo.EstateSettings != null)
3527 { 3681 {
3528 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID)) 3682 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID,0))
3529 { 3683 {
3530 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", 3684 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
3531 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3685 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
@@ -3715,6 +3869,13 @@ namespace OpenSim.Region.Framework.Scenes
3715 3869
3716 // We have to wait until the viewer contacts this region after receiving EAC. 3870 // We have to wait until the viewer contacts this region after receiving EAC.
3717 // That calls AddNewClient, which finally creates the ScenePresence 3871 // That calls AddNewClient, which finally creates the ScenePresence
3872 int flags = GetUserFlags(cAgentData.AgentID);
3873 if (m_regInfo.EstateSettings.IsBanned(cAgentData.AgentID, flags))
3874 {
3875 m_log.DebugFormat("[SCENE]: Denying root agent entry to {0}: banned", cAgentData.AgentID);
3876 return false;
3877 }
3878
3718 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); 3879 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2);
3719 if (nearestParcel == null) 3880 if (nearestParcel == null)
3720 { 3881 {
@@ -3730,7 +3891,6 @@ namespace OpenSim.Region.Framework.Scenes
3730 return false; 3891 return false;
3731 } 3892 }
3732 3893
3733
3734 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 3894 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
3735 3895
3736 if (childAgentUpdate != null) 3896 if (childAgentUpdate != null)
@@ -3797,12 +3957,22 @@ namespace OpenSim.Region.Framework.Scenes
3797 return false; 3957 return false;
3798 } 3958 }
3799 3959
3960 public bool IncomingCloseAgent(UUID agentID)
3961 {
3962 return IncomingCloseAgent(agentID, false);
3963 }
3964
3965 public bool IncomingCloseChildAgent(UUID agentID)
3966 {
3967 return IncomingCloseAgent(agentID, true);
3968 }
3969
3800 /// <summary> 3970 /// <summary>
3801 /// Tell a single agent to disconnect from the region. 3971 /// Tell a single agent to disconnect from the region.
3802 /// </summary> 3972 /// </summary>
3803 /// <param name="regionHandle"></param>
3804 /// <param name="agentID"></param> 3973 /// <param name="agentID"></param>
3805 public bool IncomingCloseAgent(UUID agentID) 3974 /// <param name="childOnly"></param>
3975 public bool IncomingCloseAgent(UUID agentID, bool childOnly)
3806 { 3976 {
3807 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 3977 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
3808 3978
@@ -3814,7 +3984,7 @@ namespace OpenSim.Region.Framework.Scenes
3814 { 3984 {
3815 m_sceneGraph.removeUserCount(false); 3985 m_sceneGraph.removeUserCount(false);
3816 } 3986 }
3817 else 3987 else if (!childOnly)
3818 { 3988 {
3819 m_sceneGraph.removeUserCount(true); 3989 m_sceneGraph.removeUserCount(true);
3820 } 3990 }
@@ -3830,9 +4000,12 @@ namespace OpenSim.Region.Framework.Scenes
3830 } 4000 }
3831 else 4001 else
3832 presence.ControllingClient.SendShutdownConnectionNotice(); 4002 presence.ControllingClient.SendShutdownConnectionNotice();
4003 presence.ControllingClient.Close(false);
4004 }
4005 else if (!childOnly)
4006 {
4007 presence.ControllingClient.Close(true);
3833 } 4008 }
3834
3835 presence.ControllingClient.Close();
3836 return true; 4009 return true;
3837 } 4010 }
3838 4011
@@ -4433,34 +4606,66 @@ namespace OpenSim.Region.Framework.Scenes
4433 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID); 4606 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID);
4434 } 4607 }
4435 4608
4436 public int GetHealth() 4609 public int GetHealth(out int flags, out string message)
4437 { 4610 {
4438 // Returns: 4611 // Returns:
4439 // 1 = sim is up and accepting http requests. The heartbeat has 4612 // 1 = sim is up and accepting http requests. The heartbeat has
4440 // stopped and the sim is probably locked up, but a remote 4613 // stopped and the sim is probably locked up, but a remote
4441 // admin restart may succeed 4614 // admin restart may succeed
4442 // 4615 //
4443 // 2 = Sim is up and the heartbeat is running. The sim is likely 4616 // 2 = Sim is up and the heartbeat is running. The sim is likely
4444 // usable for people within and logins _may_ work 4617 // usable for people within
4445 // 4618 //
4446 // 3 = We have seen a new user enter within the past 4 minutes 4619 // 3 = Sim is up and one packet thread is running. Sim is
4620 // unstable and will not accept new logins
4621 //
4622 // 4 = Sim is up and both packet threads are running. Sim is
4623 // likely usable
4624 //
4625 // 5 = We have seen a new user enter within the past 4 minutes
4447 // which can be seen as positive confirmation of sim health 4626 // which can be seen as positive confirmation of sim health
4448 // 4627 //
4628
4629 flags = 0;
4630 message = String.Empty;
4631
4632 CheckHeartbeat();
4633
4634 if (m_firstHeartbeat || (m_lastIncoming == 0 && m_lastOutgoing == 0))
4635 {
4636 // We're still starting
4637 // 0 means "in startup", it can't happen another way, since
4638 // to get here, we must be able to accept http connections
4639 return 0;
4640 }
4641
4449 int health=1; // Start at 1, means we're up 4642 int health=1; // Start at 1, means we're up
4450 4643
4451 if ((Util.EnvironmentTickCountSubtract(m_lastUpdate)) < 1000) 4644 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) < 1000)
4645 {
4452 health+=1; 4646 health+=1;
4453 else 4647 flags |= 1;
4648 }
4649
4650 if (Util.EnvironmentTickCountSubtract(m_lastIncoming) < 1000)
4651 {
4652 health+=1;
4653 flags |= 2;
4654 }
4655
4656 if (Util.EnvironmentTickCountSubtract(m_lastOutgoing) < 1000)
4657 {
4658 health+=1;
4659 flags |= 4;
4660 }
4661
4662 if (flags != 7)
4454 return health; 4663 return health;
4455 4664
4456 // A login in the last 4 mins? We can't be doing too badly 4665 // A login in the last 4 mins? We can't be doing too badly
4457 // 4666 //
4458 if ((Util.EnvironmentTickCountSubtract(m_LastLogin)) < 240000) 4667 if (Util.EnvironmentTickCountSubtract(m_LastLogin) < 240000)
4459 health++; 4668 health++;
4460 else
4461 return health;
4462
4463 CheckHeartbeat();
4464 4669
4465 return health; 4670 return health;
4466 } 4671 }
@@ -4653,7 +4858,7 @@ namespace OpenSim.Region.Framework.Scenes
4653 if (m_firstHeartbeat) 4858 if (m_firstHeartbeat)
4654 return; 4859 return;
4655 4860
4656 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 2000) 4861 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 5000)
4657 StartTimer(); 4862 StartTimer();
4658 } 4863 }
4659 4864
@@ -5067,6 +5272,54 @@ namespace OpenSim.Region.Framework.Scenes
5067 } 5272 }
5068 } 5273 }
5069 5274
5275// public void CleanDroppedAttachments()
5276// {
5277// List<SceneObjectGroup> objectsToDelete =
5278// new List<SceneObjectGroup>();
5279//
5280// lock (m_cleaningAttachments)
5281// {
5282// ForEachSOG(delegate (SceneObjectGroup grp)
5283// {
5284// if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp)))
5285// {
5286// UUID agentID = grp.OwnerID;
5287// if (agentID == UUID.Zero)
5288// {
5289// objectsToDelete.Add(grp);
5290// return;
5291// }
5292//
5293// ScenePresence sp = GetScenePresence(agentID);
5294// if (sp == null)
5295// {
5296// objectsToDelete.Add(grp);
5297// return;
5298// }
5299// }
5300// });
5301// }
5302//
5303// foreach (SceneObjectGroup grp in objectsToDelete)
5304// {
5305// m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID);
5306// DeleteSceneObject(grp, true);
5307// }
5308// }
5309
5310 public void ThreadAlive(int threadCode)
5311 {
5312 switch(threadCode)
5313 {
5314 case 1: // Incoming
5315 m_lastIncoming = Util.EnvironmentTickCount();
5316 break;
5317 case 2: // Incoming
5318 m_lastOutgoing = Util.EnvironmentTickCount();
5319 break;
5320 }
5321 }
5322
5070 // This method is called across the simulation connector to 5323 // This method is called across the simulation connector to
5071 // determine if a given agent is allowed in this region 5324 // determine if a given agent is allowed in this region
5072 // AS A ROOT AGENT. Returning false here will prevent them 5325 // AS A ROOT AGENT. Returning false here will prevent them
@@ -5075,6 +5328,14 @@ namespace OpenSim.Region.Framework.Scenes
5075 // child agent creation, thereby emulating the SL behavior. 5328 // child agent creation, thereby emulating the SL behavior.
5076 public bool QueryAccess(UUID agentID, Vector3 position, out string reason) 5329 public bool QueryAccess(UUID agentID, Vector3 position, out string reason)
5077 { 5330 {
5331 reason = "You are banned from the region";
5332
5333 if (Permissions.IsGod(agentID))
5334 {
5335 reason = String.Empty;
5336 return true;
5337 }
5338
5078 int num = m_sceneGraph.GetNumberOfScenePresences(); 5339 int num = m_sceneGraph.GetNumberOfScenePresences();
5079 5340
5080 if (num >= RegionInfo.RegionSettings.AgentLimit) 5341 if (num >= RegionInfo.RegionSettings.AgentLimit)
@@ -5086,11 +5347,82 @@ namespace OpenSim.Region.Framework.Scenes
5086 } 5347 }
5087 } 5348 }
5088 5349
5350 ScenePresence presence = GetScenePresence(agentID);
5351 IClientAPI client = null;
5352 AgentCircuitData aCircuit = null;
5353
5354 if (presence != null)
5355 {
5356 client = presence.ControllingClient;
5357 if (client != null)
5358 aCircuit = client.RequestClientInfo();
5359 }
5360
5361 // We may be called before there is a presence or a client.
5362 // Fake AgentCircuitData to keep IAuthorizationModule smiling
5363 if (client == null)
5364 {
5365 aCircuit = new AgentCircuitData();
5366 aCircuit.AgentID = agentID;
5367 aCircuit.firstname = String.Empty;
5368 aCircuit.lastname = String.Empty;
5369 }
5370
5371 try
5372 {
5373 if (!AuthorizeUser(aCircuit, out reason))
5374 {
5375 // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID);
5376 return false;
5377 }
5378 }
5379 catch (Exception e)
5380 {
5381 m_log.DebugFormat("[SCENE]: Exception authorizing agent: {0} "+ e.StackTrace, e.Message);
5382 return false;
5383 }
5384
5385 if (position == Vector3.Zero) // Teleport
5386 {
5387 float posX = 128.0f;
5388 float posY = 128.0f;
5389
5390 if (!TestLandRestrictions(agentID, out reason, ref posX, ref posY))
5391 {
5392 // m_log.DebugFormat("[SCENE]: Denying {0} because they are banned on all parcels", agentID);
5393 return false;
5394 }
5395 }
5396 else // Walking
5397 {
5398 ILandObject land = LandChannel.GetLandObject(position.X, position.Y);
5399 if (land == null)
5400 return false;
5401
5402 bool banned = land.IsBannedFromLand(agentID);
5403 bool restricted = land.IsRestrictedFromLand(agentID);
5404
5405 if (banned || restricted)
5406 return false;
5407 }
5408
5089 reason = String.Empty; 5409 reason = String.Empty;
5090 return true; 5410 return true;
5091 } 5411 }
5092 5412
5093 /// <summary> 5413 public void StartTimerWatchdog()
5414 {
5415 m_timerWatchdog.Interval = 1000;
5416 m_timerWatchdog.Elapsed += TimerWatchdog;
5417 m_timerWatchdog.AutoReset = true;
5418 m_timerWatchdog.Start();
5419 }
5420
5421 public void TimerWatchdog(object sender, ElapsedEventArgs e)
5422 {
5423 CheckHeartbeat();
5424 }
5425
5094 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the 5426 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the
5095 /// autopilot that moves an avatar to a sit target!. 5427 /// autopilot that moves an avatar to a sit target!.
5096 /// </summary> 5428 /// </summary>