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.cs446
1 files changed, 360 insertions, 86 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index bcf668f..529dc9e 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -93,6 +93,7 @@ namespace OpenSim.Region.Framework.Scenes
93 // TODO: need to figure out how allow client agents but deny 93 // TODO: need to figure out how allow client agents but deny
94 // root agents when ACL denies access to root agent 94 // root agents when ACL denies access to root agent
95 public bool m_strictAccessControl = true; 95 public bool m_strictAccessControl = true;
96 public bool m_seeIntoBannedRegion = false;
96 public int MaxUndoCount = 5; 97 public int MaxUndoCount = 5;
97 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet; 98 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet;
98 public bool LoginLock = false; 99 public bool LoginLock = false;
@@ -108,12 +109,14 @@ namespace OpenSim.Region.Framework.Scenes
108 109
109 protected int m_splitRegionID; 110 protected int m_splitRegionID;
110 protected Timer m_restartWaitTimer = new Timer(); 111 protected Timer m_restartWaitTimer = new Timer();
112 protected Timer m_timerWatchdog = new Timer();
111 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); 113 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
112 protected List<RegionInfo> m_neighbours = new List<RegionInfo>(); 114 protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
113 protected string m_simulatorVersion = "OpenSimulator Server"; 115 protected string m_simulatorVersion = "OpenSimulator Server";
114 protected ModuleLoader m_moduleLoader; 116 protected ModuleLoader m_moduleLoader;
115 protected AgentCircuitManager m_authenticateHandler; 117 protected AgentCircuitManager m_authenticateHandler;
116 protected SceneCommunicationService m_sceneGridService; 118 protected SceneCommunicationService m_sceneGridService;
119 protected ISnmpModule m_snmpService = null;
117 120
118 protected ISimulationDataService m_SimulationDataService; 121 protected ISimulationDataService m_SimulationDataService;
119 protected IEstateDataService m_EstateDataService; 122 protected IEstateDataService m_EstateDataService;
@@ -180,7 +183,7 @@ namespace OpenSim.Region.Framework.Scenes
180 private int m_update_events = 1; 183 private int m_update_events = 1;
181 private int m_update_backup = 200; 184 private int m_update_backup = 200;
182 private int m_update_terrain = 50; 185 private int m_update_terrain = 50;
183// private int m_update_land = 1; 186 private int m_update_land = 10;
184 private int m_update_coarse_locations = 50; 187 private int m_update_coarse_locations = 50;
185 188
186 private int agentMS; 189 private int agentMS;
@@ -195,14 +198,17 @@ namespace OpenSim.Region.Framework.Scenes
195 private int landMS; 198 private int landMS;
196 private int lastCompletedFrame; 199 private int lastCompletedFrame;
197 200
201 public bool CombineRegions = false;
198 private bool m_physics_enabled = true; 202 private bool m_physics_enabled = true;
199 private bool m_scripts_enabled = true; 203 private bool m_scripts_enabled = true;
200 private string m_defaultScriptEngine; 204 private string m_defaultScriptEngine;
201 private int m_LastLogin; 205 private int m_LastLogin;
202 private Thread HeartbeatThread; 206 private Thread HeartbeatThread = null;
203 private volatile bool shuttingdown; 207 private volatile bool shuttingdown;
204 208
205 private int m_lastUpdate; 209 private int m_lastUpdate;
210 private int m_lastIncoming;
211 private int m_lastOutgoing;
206 private bool m_firstHeartbeat = true; 212 private bool m_firstHeartbeat = true;
207 213
208 private object m_deleting_scene_object = new object(); 214 private object m_deleting_scene_object = new object();
@@ -255,6 +261,19 @@ namespace OpenSim.Region.Framework.Scenes
255 get { return m_sceneGridService; } 261 get { return m_sceneGridService; }
256 } 262 }
257 263
264 public ISnmpModule SnmpService
265 {
266 get
267 {
268 if (m_snmpService == null)
269 {
270 m_snmpService = RequestModuleInterface<ISnmpModule>();
271 }
272
273 return m_snmpService;
274 }
275 }
276
258 public ISimulationDataService SimulationDataService 277 public ISimulationDataService SimulationDataService
259 { 278 {
260 get 279 get
@@ -583,7 +602,10 @@ namespace OpenSim.Region.Framework.Scenes
583 m_regInfo = regInfo; 602 m_regInfo = regInfo;
584 m_regionHandle = m_regInfo.RegionHandle; 603 m_regionHandle = m_regInfo.RegionHandle;
585 m_regionName = m_regInfo.RegionName; 604 m_regionName = m_regInfo.RegionName;
605 m_datastore = m_regInfo.DataStore;
586 m_lastUpdate = Util.EnvironmentTickCount(); 606 m_lastUpdate = Util.EnvironmentTickCount();
607 m_lastIncoming = 0;
608 m_lastOutgoing = 0;
587 609
588 m_physicalPrim = physicalPrim; 610 m_physicalPrim = physicalPrim;
589 m_seeIntoRegionFromNeighbor = SeeIntoRegionFromNeighbor; 611 m_seeIntoRegionFromNeighbor = SeeIntoRegionFromNeighbor;
@@ -715,9 +737,10 @@ namespace OpenSim.Region.Framework.Scenes
715 //Animation states 737 //Animation states
716 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); 738 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
717 // TODO: Change default to true once the feature is supported 739 // TODO: Change default to true once the feature is supported
718 m_usePreJump = startupConfig.GetBoolean("enableprejump", false); 740 m_usePreJump = startupConfig.GetBoolean("enableprejump", true);
719
720 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys); 741 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
742
743 m_log.DebugFormat("[SCENE]: prejump is {0}", m_usePreJump ? "ON" : "OFF");
721 if (RegionInfo.NonphysPrimMax > 0) 744 if (RegionInfo.NonphysPrimMax > 0)
722 { 745 {
723 m_maxNonphys = RegionInfo.NonphysPrimMax; 746 m_maxNonphys = RegionInfo.NonphysPrimMax;
@@ -749,6 +772,7 @@ namespace OpenSim.Region.Framework.Scenes
749 m_persistAfter *= 10000000; 772 m_persistAfter *= 10000000;
750 773
751 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); 774 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
775 m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine);
752 776
753 IConfig packetConfig = m_config.Configs["PacketPool"]; 777 IConfig packetConfig = m_config.Configs["PacketPool"];
754 if (packetConfig != null) 778 if (packetConfig != null)
@@ -758,6 +782,8 @@ namespace OpenSim.Region.Framework.Scenes
758 } 782 }
759 783
760 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); 784 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
785 m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion);
786 CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false);
761 787
762 m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true); 788 m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true);
763 if (m_generateMaptiles) 789 if (m_generateMaptiles)
@@ -782,9 +808,9 @@ namespace OpenSim.Region.Framework.Scenes
782 } 808 }
783 } 809 }
784 } 810 }
785 catch 811 catch (Exception e)
786 { 812 {
787 m_log.Warn("[SCENE]: Failed to load StartupConfig"); 813 m_log.Error("[SCENE]: Failed to load StartupConfig: " + e.ToString());
788 } 814 }
789 815
790 #endregion Region Config 816 #endregion Region Config
@@ -1160,7 +1186,9 @@ namespace OpenSim.Region.Framework.Scenes
1160 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); 1186 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
1161 if (HeartbeatThread != null) 1187 if (HeartbeatThread != null)
1162 { 1188 {
1189 m_log.ErrorFormat("[SCENE]: Restarting heartbeat thread because it hasn't reported in in region {0}", RegionInfo.RegionName);
1163 HeartbeatThread.Abort(); 1190 HeartbeatThread.Abort();
1191 Watchdog.RemoveThread(HeartbeatThread.ManagedThreadId);
1164 HeartbeatThread = null; 1192 HeartbeatThread = null;
1165 } 1193 }
1166 m_lastUpdate = Util.EnvironmentTickCount(); 1194 m_lastUpdate = Util.EnvironmentTickCount();
@@ -1203,9 +1231,6 @@ namespace OpenSim.Region.Framework.Scenes
1203 { 1231 {
1204 while (!shuttingdown) 1232 while (!shuttingdown)
1205 Update(); 1233 Update();
1206
1207 m_lastUpdate = Util.EnvironmentTickCount();
1208 m_firstHeartbeat = false;
1209 } 1234 }
1210 catch (ThreadAbortException) 1235 catch (ThreadAbortException)
1211 { 1236 {
@@ -1304,6 +1329,13 @@ namespace OpenSim.Region.Framework.Scenes
1304 eventMS = Util.EnvironmentTickCountSubtract(evMS); ; 1329 eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
1305 } 1330 }
1306 1331
1332 // if (Frame % m_update_land == 0)
1333 // {
1334 // int ldMS = Util.EnvironmentTickCount();
1335 // UpdateLand();
1336 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1337 // }
1338
1307 if (Frame % m_update_backup == 0) 1339 if (Frame % m_update_backup == 0)
1308 { 1340 {
1309 int backMS = Util.EnvironmentTickCount(); 1341 int backMS = Util.EnvironmentTickCount();
@@ -1405,12 +1437,16 @@ namespace OpenSim.Region.Framework.Scenes
1405 maintc = Util.EnvironmentTickCountSubtract(maintc); 1437 maintc = Util.EnvironmentTickCountSubtract(maintc);
1406 maintc = (int)(m_minFrameTimespan * 1000) - maintc; 1438 maintc = (int)(m_minFrameTimespan * 1000) - maintc;
1407 1439
1440
1441 m_lastUpdate = Util.EnvironmentTickCount();
1442 m_firstHeartbeat = false;
1443
1408 if (maintc > 0) 1444 if (maintc > 0)
1409 Thread.Sleep(maintc); 1445 Thread.Sleep(maintc);
1410 1446
1411 // Tell the watchdog that this thread is still alive 1447 // Tell the watchdog that this thread is still alive
1412 Watchdog.UpdateThread(); 1448 Watchdog.UpdateThread();
1413 } 1449 }
1414 1450
1415 public void AddGroupTarget(SceneObjectGroup grp) 1451 public void AddGroupTarget(SceneObjectGroup grp)
1416 { 1452 {
@@ -1426,9 +1462,9 @@ namespace OpenSim.Region.Framework.Scenes
1426 1462
1427 private void CheckAtTargets() 1463 private void CheckAtTargets()
1428 { 1464 {
1429 Dictionary<UUID, SceneObjectGroup>.ValueCollection objs; 1465 List<SceneObjectGroup> objs = new List<SceneObjectGroup>();
1430 lock (m_groupsWithTargets) 1466 lock (m_groupsWithTargets)
1431 objs = m_groupsWithTargets.Values; 1467 objs = new List<SceneObjectGroup>(m_groupsWithTargets.Values);
1432 1468
1433 foreach (SceneObjectGroup entry in objs) 1469 foreach (SceneObjectGroup entry in objs)
1434 entry.checkAtTargets(); 1470 entry.checkAtTargets();
@@ -1748,14 +1784,24 @@ namespace OpenSim.Region.Framework.Scenes
1748 /// <returns></returns> 1784 /// <returns></returns>
1749 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter) 1785 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter)
1750 { 1786 {
1787
1788 float wheight = (float)RegionInfo.RegionSettings.WaterHeight;
1789 Vector3 wpos = Vector3.Zero;
1790 // Check for water surface intersection from above
1791 if ( (RayStart.Z > wheight) && (RayEnd.Z < wheight) )
1792 {
1793 float ratio = (RayStart.Z - wheight) / (RayStart.Z - RayEnd.Z);
1794 wpos.X = RayStart.X - (ratio * (RayStart.X - RayEnd.X));
1795 wpos.Y = RayStart.Y - (ratio * (RayStart.Y - RayEnd.Y));
1796 wpos.Z = wheight;
1797 }
1798
1751 Vector3 pos = Vector3.Zero; 1799 Vector3 pos = Vector3.Zero;
1752 if (RayEndIsIntersection == (byte)1) 1800 if (RayEndIsIntersection == (byte)1)
1753 { 1801 {
1754 pos = RayEnd; 1802 pos = RayEnd;
1755 return pos;
1756 } 1803 }
1757 1804 else if (RayTargetID != UUID.Zero)
1758 if (RayTargetID != UUID.Zero)
1759 { 1805 {
1760 SceneObjectPart target = GetSceneObjectPart(RayTargetID); 1806 SceneObjectPart target = GetSceneObjectPart(RayTargetID);
1761 1807
@@ -1777,7 +1823,7 @@ namespace OpenSim.Region.Framework.Scenes
1777 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter); 1823 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter);
1778 1824
1779 // Un-comment out the following line to Get Raytrace results printed to the console. 1825 // Un-comment out the following line to Get Raytrace results printed to the console.
1780 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); 1826 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
1781 float ScaleOffset = 0.5f; 1827 float ScaleOffset = 0.5f;
1782 1828
1783 // If we hit something 1829 // If we hit something
@@ -1800,13 +1846,10 @@ namespace OpenSim.Region.Framework.Scenes
1800 //pos.Z -= 0.25F; 1846 //pos.Z -= 0.25F;
1801 1847
1802 } 1848 }
1803
1804 return pos;
1805 } 1849 }
1806 else 1850 else
1807 { 1851 {
1808 // We don't have a target here, so we're going to raytrace all the objects in the scene. 1852 // We don't have a target here, so we're going to raytrace all the objects in the scene.
1809
1810 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false); 1853 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false);
1811 1854
1812 // Un-comment the following line to print the raytrace results to the console. 1855 // Un-comment the following line to print the raytrace results to the console.
@@ -1815,13 +1858,12 @@ namespace OpenSim.Region.Framework.Scenes
1815 if (ei.HitTF) 1858 if (ei.HitTF)
1816 { 1859 {
1817 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); 1860 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
1818 } else 1861 }
1862 else
1819 { 1863 {
1820 // fall back to our stupid functionality 1864 // fall back to our stupid functionality
1821 pos = RayEnd; 1865 pos = RayEnd;
1822 } 1866 }
1823
1824 return pos;
1825 } 1867 }
1826 } 1868 }
1827 else 1869 else
@@ -1832,8 +1874,12 @@ namespace OpenSim.Region.Framework.Scenes
1832 //increase height so its above the ground. 1874 //increase height so its above the ground.
1833 //should be getting the normal of the ground at the rez point and using that? 1875 //should be getting the normal of the ground at the rez point and using that?
1834 pos.Z += scale.Z / 2f; 1876 pos.Z += scale.Z / 2f;
1835 return pos; 1877// return pos;
1836 } 1878 }
1879
1880 // check against posible water intercept
1881 if (wpos.Z > pos.Z) pos = wpos;
1882 return pos;
1837 } 1883 }
1838 1884
1839 1885
@@ -1917,7 +1963,10 @@ namespace OpenSim.Region.Framework.Scenes
1917 public bool AddRestoredSceneObject( 1963 public bool AddRestoredSceneObject(
1918 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 1964 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
1919 { 1965 {
1920 return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); 1966 bool result = m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates);
1967 if (result)
1968 sceneObject.IsDeleted = false;
1969 return result;
1921 } 1970 }
1922 1971
1923 /// <summary> 1972 /// <summary>
@@ -2007,6 +2056,15 @@ namespace OpenSim.Region.Framework.Scenes
2007 /// </summary> 2056 /// </summary>
2008 public void DeleteAllSceneObjects() 2057 public void DeleteAllSceneObjects()
2009 { 2058 {
2059 DeleteAllSceneObjects(false);
2060 }
2061
2062 /// <summary>
2063 /// Delete every object from the scene. This does not include attachments worn by avatars.
2064 /// </summary>
2065 public void DeleteAllSceneObjects(bool exceptNoCopy)
2066 {
2067 List<SceneObjectGroup> toReturn = new List<SceneObjectGroup>();
2010 lock (Entities) 2068 lock (Entities)
2011 { 2069 {
2012 EntityBase[] entities = Entities.GetEntities(); 2070 EntityBase[] entities = Entities.GetEntities();
@@ -2015,11 +2073,24 @@ namespace OpenSim.Region.Framework.Scenes
2015 if (e is SceneObjectGroup) 2073 if (e is SceneObjectGroup)
2016 { 2074 {
2017 SceneObjectGroup sog = (SceneObjectGroup)e; 2075 SceneObjectGroup sog = (SceneObjectGroup)e;
2018 if (!sog.IsAttachment) 2076 if (sog != null && !sog.IsAttachment)
2019 DeleteSceneObject((SceneObjectGroup)e, false); 2077 {
2078 if (!exceptNoCopy || ((sog.GetEffectivePermissions() & (uint)PermissionMask.Copy) != 0))
2079 {
2080 DeleteSceneObject((SceneObjectGroup)e, false);
2081 }
2082 else
2083 {
2084 toReturn.Add((SceneObjectGroup)e);
2085 }
2086 }
2020 } 2087 }
2021 } 2088 }
2022 } 2089 }
2090 if (toReturn.Count > 0)
2091 {
2092 returnObjects(toReturn.ToArray(), UUID.Zero);
2093 }
2023 } 2094 }
2024 2095
2025 /// <summary> 2096 /// <summary>
@@ -2068,6 +2139,8 @@ namespace OpenSim.Region.Framework.Scenes
2068 } 2139 }
2069 2140
2070 group.DeleteGroupFromScene(silent); 2141 group.DeleteGroupFromScene(silent);
2142 if (!silent)
2143 SendKillObject(new List<uint>() { group.LocalId });
2071 2144
2072// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); 2145// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
2073 } 2146 }
@@ -2422,10 +2495,17 @@ namespace OpenSim.Region.Framework.Scenes
2422 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns> 2495 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns>
2423 public bool AddSceneObject(SceneObjectGroup sceneObject) 2496 public bool AddSceneObject(SceneObjectGroup sceneObject)
2424 { 2497 {
2498 if (sceneObject.OwnerID == UUID.Zero)
2499 {
2500 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero", sceneObject.UUID);
2501 return false;
2502 }
2503
2425 // If the user is banned, we won't let any of their objects 2504 // If the user is banned, we won't let any of their objects
2426 // enter. Period. 2505 // enter. Period.
2427 // 2506 //
2428 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID)) 2507 int flags = GetUserFlags(sceneObject.OwnerID);
2508 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID, flags))
2429 { 2509 {
2430 m_log.Info("[INTERREGION]: Denied prim crossing for " + 2510 m_log.Info("[INTERREGION]: Denied prim crossing for " +
2431 "banned avatar"); 2511 "banned avatar");
@@ -2472,12 +2552,23 @@ namespace OpenSim.Region.Framework.Scenes
2472 } 2552 }
2473 else 2553 else
2474 { 2554 {
2555 m_log.DebugFormat("[SCENE]: Attachment {0} arrived and scene presence was not found, setting to temp", sceneObject.UUID);
2475 RootPrim.RemFlag(PrimFlags.TemporaryOnRez); 2556 RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
2476 RootPrim.AddFlag(PrimFlags.TemporaryOnRez); 2557 RootPrim.AddFlag(PrimFlags.TemporaryOnRez);
2477 } 2558 }
2559 if (sceneObject.OwnerID == UUID.Zero)
2560 {
2561 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero after attachment processing. BUG!", sceneObject.UUID);
2562 return false;
2563 }
2478 } 2564 }
2479 else 2565 else
2480 { 2566 {
2567 if (sceneObject.OwnerID == UUID.Zero)
2568 {
2569 m_log.ErrorFormat("[SCENE]: Owner ID for non-attachment {0} was zero", sceneObject.UUID);
2570 return false;
2571 }
2481 AddRestoredSceneObject(sceneObject, true, false); 2572 AddRestoredSceneObject(sceneObject, true, false);
2482 2573
2483 if (!Permissions.CanObjectEntry(sceneObject.UUID, 2574 if (!Permissions.CanObjectEntry(sceneObject.UUID,
@@ -2507,6 +2598,24 @@ namespace OpenSim.Region.Framework.Scenes
2507 return 2; // StateSource.PrimCrossing 2598 return 2; // StateSource.PrimCrossing
2508 } 2599 }
2509 2600
2601 public int GetUserFlags(UUID user)
2602 {
2603 //Unfortunately the SP approach means that the value is cached until region is restarted
2604 /*
2605 ScenePresence sp;
2606 if (TryGetScenePresence(user, out sp))
2607 {
2608 return sp.UserFlags;
2609 }
2610 else
2611 {
2612 */
2613 UserAccount uac = UserAccountService.GetUserAccount(RegionInfo.ScopeID, user);
2614 if (uac == null)
2615 return 0;
2616 return uac.UserFlags;
2617 //}
2618 }
2510 #endregion 2619 #endregion
2511 2620
2512 #region Add/Remove Avatar Methods 2621 #region Add/Remove Avatar Methods
@@ -2528,6 +2637,7 @@ namespace OpenSim.Region.Framework.Scenes
2528 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2637 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2529 2638
2530 CheckHeartbeat(); 2639 CheckHeartbeat();
2640 ScenePresence presence;
2531 2641
2532 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here 2642 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here
2533 { 2643 {
@@ -2561,7 +2671,14 @@ namespace OpenSim.Region.Framework.Scenes
2561 2671
2562 EventManager.TriggerOnNewClient(client); 2672 EventManager.TriggerOnNewClient(client);
2563 if (vialogin) 2673 if (vialogin)
2674 {
2564 EventManager.TriggerOnClientLogin(client); 2675 EventManager.TriggerOnClientLogin(client);
2676
2677 // Send initial parcel data
2678 Vector3 pos = createdSp.AbsolutePosition;
2679 ILandObject land = LandChannel.GetLandObject(pos.X, pos.Y);
2680 land.SendLandUpdateToClient(client);
2681 }
2565 } 2682 }
2566 } 2683 }
2567 2684
@@ -2650,19 +2767,12 @@ namespace OpenSim.Region.Framework.Scenes
2650 // and the scene presence and the client, if they exist 2767 // and the scene presence and the client, if they exist
2651 try 2768 try
2652 { 2769 {
2653 // We need to wait for the client to make UDP contact first. 2770 ScenePresence sp = GetScenePresence(agentID);
2654 // It's the UDP contact that creates the scene presence 2771 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2655 ScenePresence sp = WaitGetScenePresence(agentID); 2772
2656 if (sp != null) 2773 if (sp != null)
2657 {
2658 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2659
2660 sp.ControllingClient.Close(); 2774 sp.ControllingClient.Close();
2661 } 2775
2662 else
2663 {
2664 m_log.WarnFormat("[SCENE]: Could not find scene presence for {0}", agentID);
2665 }
2666 // BANG! SLASH! 2776 // BANG! SLASH!
2667 m_authenticateHandler.RemoveCircuit(agentID); 2777 m_authenticateHandler.RemoveCircuit(agentID);
2668 2778
@@ -2762,6 +2872,7 @@ namespace OpenSim.Region.Framework.Scenes
2762 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory; 2872 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory;
2763 client.OnUpdateInventoryItem += UpdateInventoryItemAsset; 2873 client.OnUpdateInventoryItem += UpdateInventoryItemAsset;
2764 client.OnCopyInventoryItem += CopyInventoryItem; 2874 client.OnCopyInventoryItem += CopyInventoryItem;
2875 client.OnMoveItemsAndLeaveCopy += MoveInventoryItemsLeaveCopy;
2765 client.OnMoveInventoryItem += MoveInventoryItem; 2876 client.OnMoveInventoryItem += MoveInventoryItem;
2766 client.OnRemoveInventoryItem += RemoveInventoryItem; 2877 client.OnRemoveInventoryItem += RemoveInventoryItem;
2767 client.OnRemoveInventoryFolder += RemoveInventoryFolder; 2878 client.OnRemoveInventoryFolder += RemoveInventoryFolder;
@@ -2939,15 +3050,16 @@ namespace OpenSim.Region.Framework.Scenes
2939 /// </summary> 3050 /// </summary>
2940 /// <param name="agentId">The avatar's Unique ID</param> 3051 /// <param name="agentId">The avatar's Unique ID</param>
2941 /// <param name="client">The IClientAPI for the client</param> 3052 /// <param name="client">The IClientAPI for the client</param>
2942 public virtual void TeleportClientHome(UUID agentId, IClientAPI client) 3053 public virtual bool TeleportClientHome(UUID agentId, IClientAPI client)
2943 { 3054 {
2944 if (m_teleportModule != null) 3055 if (m_teleportModule != null)
2945 m_teleportModule.TeleportHome(agentId, client); 3056 return m_teleportModule.TeleportHome(agentId, client);
2946 else 3057 else
2947 { 3058 {
2948 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active"); 3059 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active");
2949 client.SendTeleportFailed("Unable to perform teleports on this simulator."); 3060 client.SendTeleportFailed("Unable to perform teleports on this simulator.");
2950 } 3061 }
3062 return false;
2951 } 3063 }
2952 3064
2953 /// <summary> 3065 /// <summary>
@@ -3039,6 +3151,16 @@ namespace OpenSim.Region.Framework.Scenes
3039 /// <param name="flags"></param> 3151 /// <param name="flags"></param>
3040 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags) 3152 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags)
3041 { 3153 {
3154 //Add half the avatar's height so that the user doesn't fall through prims
3155 ScenePresence presence;
3156 if (TryGetScenePresence(remoteClient.AgentId, out presence))
3157 {
3158 if (presence.Appearance != null)
3159 {
3160 position.Z = position.Z + (presence.Appearance.AvatarHeight / 2);
3161 }
3162 }
3163
3042 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt)) 3164 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt))
3043 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot. 3165 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot.
3044 m_dialogModule.SendAlertToUser(remoteClient, "Home position set."); 3166 m_dialogModule.SendAlertToUser(remoteClient, "Home position set.");
@@ -3107,8 +3229,9 @@ namespace OpenSim.Region.Framework.Scenes
3107 regions.Remove(RegionInfo.RegionHandle); 3229 regions.Remove(RegionInfo.RegionHandle);
3108 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3230 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3109 } 3231 }
3110 3232 m_log.Debug("[Scene] Beginning ClientClosed");
3111 m_eventManager.TriggerClientClosed(agentID, this); 3233 m_eventManager.TriggerClientClosed(agentID, this);
3234 m_log.Debug("[Scene] Finished ClientClosed");
3112 } 3235 }
3113 catch (NullReferenceException) 3236 catch (NullReferenceException)
3114 { 3237 {
@@ -3116,7 +3239,12 @@ namespace OpenSim.Region.Framework.Scenes
3116 // Avatar is already disposed :/ 3239 // Avatar is already disposed :/
3117 } 3240 }
3118 3241
3242 m_log.Debug("[Scene] Beginning OnRemovePresence");
3119 m_eventManager.TriggerOnRemovePresence(agentID); 3243 m_eventManager.TriggerOnRemovePresence(agentID);
3244 m_log.Debug("[Scene] Finished OnRemovePresence");
3245
3246 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3247 AttachmentsModule.SaveChangedAttachments(avatar);
3120 3248
3121 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc) 3249 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3122 AttachmentsModule.SaveChangedAttachments(avatar); 3250 AttachmentsModule.SaveChangedAttachments(avatar);
@@ -3125,7 +3253,7 @@ namespace OpenSim.Region.Framework.Scenes
3125 delegate(IClientAPI client) 3253 delegate(IClientAPI client)
3126 { 3254 {
3127 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3255 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3128 try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); } 3256 try { client.SendKillObject(avatar.RegionHandle, new List<uint>() { avatar.LocalId}); }
3129 catch (NullReferenceException) { } 3257 catch (NullReferenceException) { }
3130 }); 3258 });
3131 3259
@@ -3136,8 +3264,11 @@ namespace OpenSim.Region.Framework.Scenes
3136 } 3264 }
3137 3265
3138 // Remove the avatar from the scene 3266 // Remove the avatar from the scene
3267 m_log.Debug("[Scene] Begin RemoveScenePresence");
3139 m_sceneGraph.RemoveScenePresence(agentID); 3268 m_sceneGraph.RemoveScenePresence(agentID);
3269 m_log.Debug("[Scene] Finished RemoveScenePresence. Removing the client manager");
3140 m_clientManager.Remove(agentID); 3270 m_clientManager.Remove(agentID);
3271 m_log.Debug("[Scene] Removed the client manager. Firing avatar.close");
3141 3272
3142 try 3273 try
3143 { 3274 {
@@ -3151,9 +3282,10 @@ namespace OpenSim.Region.Framework.Scenes
3151 { 3282 {
3152 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString()); 3283 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString());
3153 } 3284 }
3154 3285 m_log.Debug("[Scene] Done. Firing RemoveCircuit");
3155 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3286 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
3156// CleanDroppedAttachments(); 3287// CleanDroppedAttachments();
3288 m_log.Debug("[Scene] The avatar has left the building");
3157 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 3289 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
3158 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); 3290 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
3159 } 3291 }
@@ -3184,19 +3316,24 @@ namespace OpenSim.Region.Framework.Scenes
3184 3316
3185 #region Entities 3317 #region Entities
3186 3318
3187 public void SendKillObject(uint localID) 3319 public void SendKillObject(List<uint> localIDs)
3188 { 3320 {
3189 SceneObjectPart part = GetSceneObjectPart(localID); 3321 List<uint> deleteIDs = new List<uint>();
3190 if (part != null) // It is a prim 3322
3323 foreach (uint localID in localIDs)
3191 { 3324 {
3192 if (!part.ParentGroup.IsDeleted) // Valid 3325 SceneObjectPart part = GetSceneObjectPart(localID);
3326 if (part != null) // It is a prim
3193 { 3327 {
3194 if (part.ParentGroup.RootPart != part) // Child part 3328 if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid
3195 return; 3329 {
3330 if (part.ParentGroup.RootPart != part) // Child part
3331 continue;
3332 }
3196 } 3333 }
3334 deleteIDs.Add(localID);
3197 } 3335 }
3198 3336 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, deleteIDs); });
3199 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); });
3200 } 3337 }
3201 3338
3202 #endregion 3339 #endregion
@@ -3214,7 +3351,6 @@ namespace OpenSim.Region.Framework.Scenes
3214 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate; 3351 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
3215 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar; 3352 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar;
3216 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid; 3353 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
3217 m_sceneGridService.KiPrimitive += SendKillObject;
3218 m_sceneGridService.OnGetLandData += GetLandData; 3354 m_sceneGridService.OnGetLandData += GetLandData;
3219 } 3355 }
3220 3356
@@ -3223,7 +3359,6 @@ namespace OpenSim.Region.Framework.Scenes
3223 /// </summary> 3359 /// </summary>
3224 public void UnRegisterRegionWithComms() 3360 public void UnRegisterRegionWithComms()
3225 { 3361 {
3226 m_sceneGridService.KiPrimitive -= SendKillObject;
3227 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid; 3362 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid;
3228 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar; 3363 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar;
3229 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate; 3364 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate;
@@ -3303,13 +3438,16 @@ namespace OpenSim.Region.Framework.Scenes
3303 sp = null; 3438 sp = null;
3304 } 3439 }
3305 3440
3306 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3307 3441
3308 //On login test land permisions 3442 //On login test land permisions
3309 if (vialogin) 3443 if (vialogin)
3310 { 3444 {
3311 if (land != null && !TestLandRestrictions(agent, land, out reason)) 3445 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
3446 if (cache != null)
3447 cache.Remove(agent.firstname + " " + agent.lastname);
3448 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3312 { 3449 {
3450 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString());
3313 return false; 3451 return false;
3314 } 3452 }
3315 } 3453 }
@@ -3332,8 +3470,13 @@ namespace OpenSim.Region.Framework.Scenes
3332 3470
3333 try 3471 try
3334 { 3472 {
3335 if (!AuthorizeUser(agent, out reason)) 3473 // Always check estate if this is a login. Always
3336 return false; 3474 // check if banned regions are to be blacked out.
3475 if (vialogin || (!m_seeIntoBannedRegion))
3476 {
3477 if (!AuthorizeUser(agent, out reason))
3478 return false;
3479 }
3337 } 3480 }
3338 catch (Exception e) 3481 catch (Exception e)
3339 { 3482 {
@@ -3435,6 +3578,8 @@ namespace OpenSim.Region.Framework.Scenes
3435 } 3578 }
3436 } 3579 }
3437 // Honor parcel landing type and position. 3580 // Honor parcel landing type and position.
3581 /*
3582 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3438 if (land != null) 3583 if (land != null)
3439 { 3584 {
3440 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) 3585 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero)
@@ -3442,26 +3587,34 @@ namespace OpenSim.Region.Framework.Scenes
3442 agent.startpos = land.LandData.UserLocation; 3587 agent.startpos = land.LandData.UserLocation;
3443 } 3588 }
3444 } 3589 }
3590 */// This is now handled properly in ScenePresence.MakeRootAgent
3445 } 3591 }
3446 3592
3447 return true; 3593 return true;
3448 } 3594 }
3449 3595
3450 private bool TestLandRestrictions(AgentCircuitData agent, ILandObject land, out string reason) 3596 private bool TestLandRestrictions(UUID agentID, out string reason, ref float posX, ref float posY)
3451 { 3597 {
3452 3598 reason = String.Empty;
3453 bool banned = land.IsBannedFromLand(agent.AgentID); 3599 if (Permissions.IsGod(agentID))
3454 bool restricted = land.IsRestrictedFromLand(agent.AgentID); 3600 return true;
3601
3602 ILandObject land = LandChannel.GetLandObject(posX, posY);
3603 if (land == null)
3604 return false;
3605
3606 bool banned = land.IsBannedFromLand(agentID);
3607 bool restricted = land.IsRestrictedFromLand(agentID);
3455 3608
3456 if (banned || restricted) 3609 if (banned || restricted)
3457 { 3610 {
3458 ILandObject nearestParcel = GetNearestAllowedParcel(agent.AgentID, agent.startpos.X, agent.startpos.Y); 3611 ILandObject nearestParcel = GetNearestAllowedParcel(agentID, posX, posY);
3459 if (nearestParcel != null) 3612 if (nearestParcel != null)
3460 { 3613 {
3461 //Move agent to nearest allowed 3614 //Move agent to nearest allowed
3462 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel); 3615 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel);
3463 agent.startpos.X = newPosition.X; 3616 posX = newPosition.X;
3464 agent.startpos.Y = newPosition.Y; 3617 posY = newPosition.Y;
3465 } 3618 }
3466 else 3619 else
3467 { 3620 {
@@ -3523,7 +3676,7 @@ namespace OpenSim.Region.Framework.Scenes
3523 3676
3524 if (!m_strictAccessControl) return true; 3677 if (!m_strictAccessControl) return true;
3525 if (Permissions.IsGod(agent.AgentID)) return true; 3678 if (Permissions.IsGod(agent.AgentID)) return true;
3526 3679
3527 if (AuthorizationService != null) 3680 if (AuthorizationService != null)
3528 { 3681 {
3529 if (!AuthorizationService.IsAuthorizedForRegion( 3682 if (!AuthorizationService.IsAuthorizedForRegion(
@@ -3531,14 +3684,14 @@ namespace OpenSim.Region.Framework.Scenes
3531 { 3684 {
3532 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region", 3685 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region",
3533 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3686 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
3534 3687
3535 return false; 3688 return false;
3536 } 3689 }
3537 } 3690 }
3538 3691
3539 if (m_regInfo.EstateSettings != null) 3692 if (m_regInfo.EstateSettings != null)
3540 { 3693 {
3541 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID)) 3694 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID,0))
3542 { 3695 {
3543 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", 3696 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
3544 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3697 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
@@ -3728,6 +3881,13 @@ namespace OpenSim.Region.Framework.Scenes
3728 3881
3729 // We have to wait until the viewer contacts this region after receiving EAC. 3882 // We have to wait until the viewer contacts this region after receiving EAC.
3730 // That calls AddNewClient, which finally creates the ScenePresence 3883 // That calls AddNewClient, which finally creates the ScenePresence
3884 int flags = GetUserFlags(cAgentData.AgentID);
3885 if (m_regInfo.EstateSettings.IsBanned(cAgentData.AgentID, flags))
3886 {
3887 m_log.DebugFormat("[SCENE]: Denying root agent entry to {0}: banned", cAgentData.AgentID);
3888 return false;
3889 }
3890
3731 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); 3891 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2);
3732 if (nearestParcel == null) 3892 if (nearestParcel == null)
3733 { 3893 {
@@ -3743,7 +3903,6 @@ namespace OpenSim.Region.Framework.Scenes
3743 return false; 3903 return false;
3744 } 3904 }
3745 3905
3746
3747 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 3906 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
3748 3907
3749 if (childAgentUpdate != null) 3908 if (childAgentUpdate != null)
@@ -3810,12 +3969,22 @@ namespace OpenSim.Region.Framework.Scenes
3810 return false; 3969 return false;
3811 } 3970 }
3812 3971
3972 public bool IncomingCloseAgent(UUID agentID)
3973 {
3974 return IncomingCloseAgent(agentID, false);
3975 }
3976
3977 public bool IncomingCloseChildAgent(UUID agentID)
3978 {
3979 return IncomingCloseAgent(agentID, true);
3980 }
3981
3813 /// <summary> 3982 /// <summary>
3814 /// Tell a single agent to disconnect from the region. 3983 /// Tell a single agent to disconnect from the region.
3815 /// </summary> 3984 /// </summary>
3816 /// <param name="regionHandle"></param>
3817 /// <param name="agentID"></param> 3985 /// <param name="agentID"></param>
3818 public bool IncomingCloseAgent(UUID agentID) 3986 /// <param name="childOnly"></param>
3987 public bool IncomingCloseAgent(UUID agentID, bool childOnly)
3819 { 3988 {
3820 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 3989 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
3821 3990
@@ -3827,7 +3996,7 @@ namespace OpenSim.Region.Framework.Scenes
3827 { 3996 {
3828 m_sceneGraph.removeUserCount(false); 3997 m_sceneGraph.removeUserCount(false);
3829 } 3998 }
3830 else 3999 else if (!childOnly)
3831 { 4000 {
3832 m_sceneGraph.removeUserCount(true); 4001 m_sceneGraph.removeUserCount(true);
3833 } 4002 }
@@ -3843,9 +4012,12 @@ namespace OpenSim.Region.Framework.Scenes
3843 } 4012 }
3844 else 4013 else
3845 presence.ControllingClient.SendShutdownConnectionNotice(); 4014 presence.ControllingClient.SendShutdownConnectionNotice();
4015 presence.ControllingClient.Close(false);
4016 }
4017 else if (!childOnly)
4018 {
4019 presence.ControllingClient.Close(true);
3846 } 4020 }
3847
3848 presence.ControllingClient.Close();
3849 return true; 4021 return true;
3850 } 4022 }
3851 4023
@@ -4460,34 +4632,66 @@ namespace OpenSim.Region.Framework.Scenes
4460 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID); 4632 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID);
4461 } 4633 }
4462 4634
4463 public int GetHealth() 4635 public int GetHealth(out int flags, out string message)
4464 { 4636 {
4465 // Returns: 4637 // Returns:
4466 // 1 = sim is up and accepting http requests. The heartbeat has 4638 // 1 = sim is up and accepting http requests. The heartbeat has
4467 // stopped and the sim is probably locked up, but a remote 4639 // stopped and the sim is probably locked up, but a remote
4468 // admin restart may succeed 4640 // admin restart may succeed
4469 // 4641 //
4470 // 2 = Sim is up and the heartbeat is running. The sim is likely 4642 // 2 = Sim is up and the heartbeat is running. The sim is likely
4471 // usable for people within and logins _may_ work 4643 // usable for people within
4644 //
4645 // 3 = Sim is up and one packet thread is running. Sim is
4646 // unstable and will not accept new logins
4647 //
4648 // 4 = Sim is up and both packet threads are running. Sim is
4649 // likely usable
4472 // 4650 //
4473 // 3 = We have seen a new user enter within the past 4 minutes 4651 // 5 = We have seen a new user enter within the past 4 minutes
4474 // which can be seen as positive confirmation of sim health 4652 // which can be seen as positive confirmation of sim health
4475 // 4653 //
4654
4655 flags = 0;
4656 message = String.Empty;
4657
4658 CheckHeartbeat();
4659
4660 if (m_firstHeartbeat || (m_lastIncoming == 0 && m_lastOutgoing == 0))
4661 {
4662 // We're still starting
4663 // 0 means "in startup", it can't happen another way, since
4664 // to get here, we must be able to accept http connections
4665 return 0;
4666 }
4667
4476 int health=1; // Start at 1, means we're up 4668 int health=1; // Start at 1, means we're up
4477 4669
4478 if ((Util.EnvironmentTickCountSubtract(m_lastUpdate)) < 1000) 4670 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) < 1000)
4671 {
4479 health+=1; 4672 health+=1;
4480 else 4673 flags |= 1;
4674 }
4675
4676 if (Util.EnvironmentTickCountSubtract(m_lastIncoming) < 1000)
4677 {
4678 health+=1;
4679 flags |= 2;
4680 }
4681
4682 if (Util.EnvironmentTickCountSubtract(m_lastOutgoing) < 1000)
4683 {
4684 health+=1;
4685 flags |= 4;
4686 }
4687
4688 if (flags != 7)
4481 return health; 4689 return health;
4482 4690
4483 // A login in the last 4 mins? We can't be doing too badly 4691 // A login in the last 4 mins? We can't be doing too badly
4484 // 4692 //
4485 if ((Util.EnvironmentTickCountSubtract(m_LastLogin)) < 240000) 4693 if (Util.EnvironmentTickCountSubtract(m_LastLogin) < 240000)
4486 health++; 4694 health++;
4487 else
4488 return health;
4489
4490 CheckHeartbeat();
4491 4695
4492 return health; 4696 return health;
4493 } 4697 }
@@ -4680,7 +4884,7 @@ namespace OpenSim.Region.Framework.Scenes
4680 if (m_firstHeartbeat) 4884 if (m_firstHeartbeat)
4681 return; 4885 return;
4682 4886
4683 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 2000) 4887 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 5000)
4684 StartTimer(); 4888 StartTimer();
4685 } 4889 }
4686 4890
@@ -5129,6 +5333,19 @@ namespace OpenSim.Region.Framework.Scenes
5129// } 5333// }
5130// } 5334// }
5131 5335
5336 public void ThreadAlive(int threadCode)
5337 {
5338 switch(threadCode)
5339 {
5340 case 1: // Incoming
5341 m_lastIncoming = Util.EnvironmentTickCount();
5342 break;
5343 case 2: // Incoming
5344 m_lastOutgoing = Util.EnvironmentTickCount();
5345 break;
5346 }
5347 }
5348
5132 // This method is called across the simulation connector to 5349 // This method is called across the simulation connector to
5133 // determine if a given agent is allowed in this region 5350 // determine if a given agent is allowed in this region
5134 // AS A ROOT AGENT. Returning false here will prevent them 5351 // AS A ROOT AGENT. Returning false here will prevent them
@@ -5137,6 +5354,14 @@ namespace OpenSim.Region.Framework.Scenes
5137 // child agent creation, thereby emulating the SL behavior. 5354 // child agent creation, thereby emulating the SL behavior.
5138 public bool QueryAccess(UUID agentID, Vector3 position, out string reason) 5355 public bool QueryAccess(UUID agentID, Vector3 position, out string reason)
5139 { 5356 {
5357 reason = "You are banned from the region";
5358
5359 if (Permissions.IsGod(agentID))
5360 {
5361 reason = String.Empty;
5362 return true;
5363 }
5364
5140 int num = m_sceneGraph.GetNumberOfScenePresences(); 5365 int num = m_sceneGraph.GetNumberOfScenePresences();
5141 5366
5142 if (num >= RegionInfo.RegionSettings.AgentLimit) 5367 if (num >= RegionInfo.RegionSettings.AgentLimit)
@@ -5148,11 +5373,60 @@ namespace OpenSim.Region.Framework.Scenes
5148 } 5373 }
5149 } 5374 }
5150 5375
5376 try
5377 {
5378 if (!AuthorizeUser(GetScenePresence(agentID).ControllingClient.RequestClientInfo(), out reason))
5379 {
5380 // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID);
5381 return false;
5382 }
5383 }
5384 catch
5385 {
5386 return false;
5387 }
5388
5389 if (position == Vector3.Zero) // Teleport
5390 {
5391 float posX = 128.0f;
5392 float posY = 128.0f;
5393
5394 if (!TestLandRestrictions(agentID, out reason, ref posX, ref posY))
5395 {
5396 // m_log.DebugFormat("[SCENE]: Denying {0} because they are banned on all parcels", agentID);
5397 return false;
5398 }
5399 }
5400 else // Walking
5401 {
5402 ILandObject land = LandChannel.GetLandObject(position.X, position.Y);
5403 if (land == null)
5404 return false;
5405
5406 bool banned = land.IsBannedFromLand(agentID);
5407 bool restricted = land.IsRestrictedFromLand(agentID);
5408
5409 if (banned || restricted)
5410 return false;
5411 }
5412
5151 reason = String.Empty; 5413 reason = String.Empty;
5152 return true; 5414 return true;
5153 } 5415 }
5154 5416
5155 /// <summary> 5417 public void StartTimerWatchdog()
5418 {
5419 m_timerWatchdog.Interval = 1000;
5420 m_timerWatchdog.Elapsed += TimerWatchdog;
5421 m_timerWatchdog.AutoReset = true;
5422 m_timerWatchdog.Start();
5423 }
5424
5425 public void TimerWatchdog(object sender, ElapsedEventArgs e)
5426 {
5427 CheckHeartbeat();
5428 }
5429
5156 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the 5430 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the
5157 /// autopilot that moves an avatar to a sit target!. 5431 /// autopilot that moves an avatar to a sit target!.
5158 /// </summary> 5432 /// </summary>