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 b1755ac..cd4b14d 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
@@ -1161,7 +1187,9 @@ namespace OpenSim.Region.Framework.Scenes
1161 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); 1187 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
1162 if (HeartbeatThread != null) 1188 if (HeartbeatThread != null)
1163 { 1189 {
1190 m_log.ErrorFormat("[SCENE]: Restarting heartbeat thread because it hasn't reported in in region {0}", RegionInfo.RegionName);
1164 HeartbeatThread.Abort(); 1191 HeartbeatThread.Abort();
1192 Watchdog.RemoveThread(HeartbeatThread.ManagedThreadId);
1165 HeartbeatThread = null; 1193 HeartbeatThread = null;
1166 } 1194 }
1167 m_lastUpdate = Util.EnvironmentTickCount(); 1195 m_lastUpdate = Util.EnvironmentTickCount();
@@ -1204,9 +1232,6 @@ namespace OpenSim.Region.Framework.Scenes
1204 { 1232 {
1205 while (!shuttingdown) 1233 while (!shuttingdown)
1206 Update(); 1234 Update();
1207
1208 m_lastUpdate = Util.EnvironmentTickCount();
1209 m_firstHeartbeat = false;
1210 } 1235 }
1211 catch (ThreadAbortException) 1236 catch (ThreadAbortException)
1212 { 1237 {
@@ -1305,6 +1330,13 @@ namespace OpenSim.Region.Framework.Scenes
1305 eventMS = Util.EnvironmentTickCountSubtract(evMS); ; 1330 eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
1306 } 1331 }
1307 1332
1333 // if (Frame % m_update_land == 0)
1334 // {
1335 // int ldMS = Util.EnvironmentTickCount();
1336 // UpdateLand();
1337 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1338 // }
1339
1308 if (Frame % m_update_backup == 0) 1340 if (Frame % m_update_backup == 0)
1309 { 1341 {
1310 int backMS = Util.EnvironmentTickCount(); 1342 int backMS = Util.EnvironmentTickCount();
@@ -1406,12 +1438,16 @@ namespace OpenSim.Region.Framework.Scenes
1406 maintc = Util.EnvironmentTickCountSubtract(maintc); 1438 maintc = Util.EnvironmentTickCountSubtract(maintc);
1407 maintc = (int)(m_minFrameTimespan * 1000) - maintc; 1439 maintc = (int)(m_minFrameTimespan * 1000) - maintc;
1408 1440
1441
1442 m_lastUpdate = Util.EnvironmentTickCount();
1443 m_firstHeartbeat = false;
1444
1409 if (maintc > 0) 1445 if (maintc > 0)
1410 Thread.Sleep(maintc); 1446 Thread.Sleep(maintc);
1411 1447
1412 // Tell the watchdog that this thread is still alive 1448 // Tell the watchdog that this thread is still alive
1413 Watchdog.UpdateThread(); 1449 Watchdog.UpdateThread();
1414 } 1450 }
1415 1451
1416 public void AddGroupTarget(SceneObjectGroup grp) 1452 public void AddGroupTarget(SceneObjectGroup grp)
1417 { 1453 {
@@ -1427,9 +1463,9 @@ namespace OpenSim.Region.Framework.Scenes
1427 1463
1428 private void CheckAtTargets() 1464 private void CheckAtTargets()
1429 { 1465 {
1430 Dictionary<UUID, SceneObjectGroup>.ValueCollection objs; 1466 List<SceneObjectGroup> objs = new List<SceneObjectGroup>();
1431 lock (m_groupsWithTargets) 1467 lock (m_groupsWithTargets)
1432 objs = m_groupsWithTargets.Values; 1468 objs = new List<SceneObjectGroup>(m_groupsWithTargets.Values);
1433 1469
1434 foreach (SceneObjectGroup entry in objs) 1470 foreach (SceneObjectGroup entry in objs)
1435 entry.checkAtTargets(); 1471 entry.checkAtTargets();
@@ -1749,14 +1785,24 @@ namespace OpenSim.Region.Framework.Scenes
1749 /// <returns></returns> 1785 /// <returns></returns>
1750 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter) 1786 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter)
1751 { 1787 {
1788
1789 float wheight = (float)RegionInfo.RegionSettings.WaterHeight;
1790 Vector3 wpos = Vector3.Zero;
1791 // Check for water surface intersection from above
1792 if ( (RayStart.Z > wheight) && (RayEnd.Z < wheight) )
1793 {
1794 float ratio = (RayStart.Z - wheight) / (RayStart.Z - RayEnd.Z);
1795 wpos.X = RayStart.X - (ratio * (RayStart.X - RayEnd.X));
1796 wpos.Y = RayStart.Y - (ratio * (RayStart.Y - RayEnd.Y));
1797 wpos.Z = wheight;
1798 }
1799
1752 Vector3 pos = Vector3.Zero; 1800 Vector3 pos = Vector3.Zero;
1753 if (RayEndIsIntersection == (byte)1) 1801 if (RayEndIsIntersection == (byte)1)
1754 { 1802 {
1755 pos = RayEnd; 1803 pos = RayEnd;
1756 return pos;
1757 } 1804 }
1758 1805 else if (RayTargetID != UUID.Zero)
1759 if (RayTargetID != UUID.Zero)
1760 { 1806 {
1761 SceneObjectPart target = GetSceneObjectPart(RayTargetID); 1807 SceneObjectPart target = GetSceneObjectPart(RayTargetID);
1762 1808
@@ -1778,7 +1824,7 @@ namespace OpenSim.Region.Framework.Scenes
1778 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter); 1824 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter);
1779 1825
1780 // Un-comment out the following line to Get Raytrace results printed to the console. 1826 // Un-comment out the following line to Get Raytrace results printed to the console.
1781 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); 1827 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
1782 float ScaleOffset = 0.5f; 1828 float ScaleOffset = 0.5f;
1783 1829
1784 // If we hit something 1830 // If we hit something
@@ -1801,13 +1847,10 @@ namespace OpenSim.Region.Framework.Scenes
1801 //pos.Z -= 0.25F; 1847 //pos.Z -= 0.25F;
1802 1848
1803 } 1849 }
1804
1805 return pos;
1806 } 1850 }
1807 else 1851 else
1808 { 1852 {
1809 // We don't have a target here, so we're going to raytrace all the objects in the scene. 1853 // We don't have a target here, so we're going to raytrace all the objects in the scene.
1810
1811 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false); 1854 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false);
1812 1855
1813 // Un-comment the following line to print the raytrace results to the console. 1856 // Un-comment the following line to print the raytrace results to the console.
@@ -1816,13 +1859,12 @@ namespace OpenSim.Region.Framework.Scenes
1816 if (ei.HitTF) 1859 if (ei.HitTF)
1817 { 1860 {
1818 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); 1861 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
1819 } else 1862 }
1863 else
1820 { 1864 {
1821 // fall back to our stupid functionality 1865 // fall back to our stupid functionality
1822 pos = RayEnd; 1866 pos = RayEnd;
1823 } 1867 }
1824
1825 return pos;
1826 } 1868 }
1827 } 1869 }
1828 else 1870 else
@@ -1833,8 +1875,12 @@ namespace OpenSim.Region.Framework.Scenes
1833 //increase height so its above the ground. 1875 //increase height so its above the ground.
1834 //should be getting the normal of the ground at the rez point and using that? 1876 //should be getting the normal of the ground at the rez point and using that?
1835 pos.Z += scale.Z / 2f; 1877 pos.Z += scale.Z / 2f;
1836 return pos; 1878// return pos;
1837 } 1879 }
1880
1881 // check against posible water intercept
1882 if (wpos.Z > pos.Z) pos = wpos;
1883 return pos;
1838 } 1884 }
1839 1885
1840 1886
@@ -1918,7 +1964,10 @@ namespace OpenSim.Region.Framework.Scenes
1918 public bool AddRestoredSceneObject( 1964 public bool AddRestoredSceneObject(
1919 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 1965 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
1920 { 1966 {
1921 return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); 1967 bool result = m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates);
1968 if (result)
1969 sceneObject.IsDeleted = false;
1970 return result;
1922 } 1971 }
1923 1972
1924 /// <summary> 1973 /// <summary>
@@ -2008,6 +2057,15 @@ namespace OpenSim.Region.Framework.Scenes
2008 /// </summary> 2057 /// </summary>
2009 public void DeleteAllSceneObjects() 2058 public void DeleteAllSceneObjects()
2010 { 2059 {
2060 DeleteAllSceneObjects(false);
2061 }
2062
2063 /// <summary>
2064 /// Delete every object from the scene. This does not include attachments worn by avatars.
2065 /// </summary>
2066 public void DeleteAllSceneObjects(bool exceptNoCopy)
2067 {
2068 List<SceneObjectGroup> toReturn = new List<SceneObjectGroup>();
2011 lock (Entities) 2069 lock (Entities)
2012 { 2070 {
2013 EntityBase[] entities = Entities.GetEntities(); 2071 EntityBase[] entities = Entities.GetEntities();
@@ -2016,11 +2074,24 @@ namespace OpenSim.Region.Framework.Scenes
2016 if (e is SceneObjectGroup) 2074 if (e is SceneObjectGroup)
2017 { 2075 {
2018 SceneObjectGroup sog = (SceneObjectGroup)e; 2076 SceneObjectGroup sog = (SceneObjectGroup)e;
2019 if (!sog.IsAttachment) 2077 if (sog != null && !sog.IsAttachment)
2020 DeleteSceneObject((SceneObjectGroup)e, false); 2078 {
2079 if (!exceptNoCopy || ((sog.GetEffectivePermissions() & (uint)PermissionMask.Copy) != 0))
2080 {
2081 DeleteSceneObject((SceneObjectGroup)e, false);
2082 }
2083 else
2084 {
2085 toReturn.Add((SceneObjectGroup)e);
2086 }
2087 }
2021 } 2088 }
2022 } 2089 }
2023 } 2090 }
2091 if (toReturn.Count > 0)
2092 {
2093 returnObjects(toReturn.ToArray(), UUID.Zero);
2094 }
2024 } 2095 }
2025 2096
2026 /// <summary> 2097 /// <summary>
@@ -2069,6 +2140,8 @@ namespace OpenSim.Region.Framework.Scenes
2069 } 2140 }
2070 2141
2071 group.DeleteGroupFromScene(silent); 2142 group.DeleteGroupFromScene(silent);
2143 if (!silent)
2144 SendKillObject(new List<uint>() { group.LocalId });
2072 2145
2073// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); 2146// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
2074 } 2147 }
@@ -2423,10 +2496,17 @@ namespace OpenSim.Region.Framework.Scenes
2423 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns> 2496 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns>
2424 public bool AddSceneObject(SceneObjectGroup sceneObject) 2497 public bool AddSceneObject(SceneObjectGroup sceneObject)
2425 { 2498 {
2499 if (sceneObject.OwnerID == UUID.Zero)
2500 {
2501 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero", sceneObject.UUID);
2502 return false;
2503 }
2504
2426 // If the user is banned, we won't let any of their objects 2505 // If the user is banned, we won't let any of their objects
2427 // enter. Period. 2506 // enter. Period.
2428 // 2507 //
2429 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID)) 2508 int flags = GetUserFlags(sceneObject.OwnerID);
2509 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID, flags))
2430 { 2510 {
2431 m_log.Info("[INTERREGION]: Denied prim crossing for " + 2511 m_log.Info("[INTERREGION]: Denied prim crossing for " +
2432 "banned avatar"); 2512 "banned avatar");
@@ -2473,12 +2553,23 @@ namespace OpenSim.Region.Framework.Scenes
2473 } 2553 }
2474 else 2554 else
2475 { 2555 {
2556 m_log.DebugFormat("[SCENE]: Attachment {0} arrived and scene presence was not found, setting to temp", sceneObject.UUID);
2476 RootPrim.RemFlag(PrimFlags.TemporaryOnRez); 2557 RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
2477 RootPrim.AddFlag(PrimFlags.TemporaryOnRez); 2558 RootPrim.AddFlag(PrimFlags.TemporaryOnRez);
2478 } 2559 }
2560 if (sceneObject.OwnerID == UUID.Zero)
2561 {
2562 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero after attachment processing. BUG!", sceneObject.UUID);
2563 return false;
2564 }
2479 } 2565 }
2480 else 2566 else
2481 { 2567 {
2568 if (sceneObject.OwnerID == UUID.Zero)
2569 {
2570 m_log.ErrorFormat("[SCENE]: Owner ID for non-attachment {0} was zero", sceneObject.UUID);
2571 return false;
2572 }
2482 AddRestoredSceneObject(sceneObject, true, false); 2573 AddRestoredSceneObject(sceneObject, true, false);
2483 2574
2484 if (!Permissions.CanObjectEntry(sceneObject.UUID, 2575 if (!Permissions.CanObjectEntry(sceneObject.UUID,
@@ -2508,6 +2599,24 @@ namespace OpenSim.Region.Framework.Scenes
2508 return 2; // StateSource.PrimCrossing 2599 return 2; // StateSource.PrimCrossing
2509 } 2600 }
2510 2601
2602 public int GetUserFlags(UUID user)
2603 {
2604 //Unfortunately the SP approach means that the value is cached until region is restarted
2605 /*
2606 ScenePresence sp;
2607 if (TryGetScenePresence(user, out sp))
2608 {
2609 return sp.UserFlags;
2610 }
2611 else
2612 {
2613 */
2614 UserAccount uac = UserAccountService.GetUserAccount(RegionInfo.ScopeID, user);
2615 if (uac == null)
2616 return 0;
2617 return uac.UserFlags;
2618 //}
2619 }
2511 #endregion 2620 #endregion
2512 2621
2513 #region Add/Remove Avatar Methods 2622 #region Add/Remove Avatar Methods
@@ -2529,6 +2638,7 @@ namespace OpenSim.Region.Framework.Scenes
2529 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2638 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2530 2639
2531 CheckHeartbeat(); 2640 CheckHeartbeat();
2641 ScenePresence presence;
2532 2642
2533 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here 2643 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here
2534 { 2644 {
@@ -2562,7 +2672,14 @@ namespace OpenSim.Region.Framework.Scenes
2562 2672
2563 EventManager.TriggerOnNewClient(client); 2673 EventManager.TriggerOnNewClient(client);
2564 if (vialogin) 2674 if (vialogin)
2675 {
2565 EventManager.TriggerOnClientLogin(client); 2676 EventManager.TriggerOnClientLogin(client);
2677
2678 // Send initial parcel data
2679 Vector3 pos = createdSp.AbsolutePosition;
2680 ILandObject land = LandChannel.GetLandObject(pos.X, pos.Y);
2681 land.SendLandUpdateToClient(client);
2682 }
2566 } 2683 }
2567 } 2684 }
2568 2685
@@ -2651,19 +2768,12 @@ namespace OpenSim.Region.Framework.Scenes
2651 // and the scene presence and the client, if they exist 2768 // and the scene presence and the client, if they exist
2652 try 2769 try
2653 { 2770 {
2654 // We need to wait for the client to make UDP contact first. 2771 ScenePresence sp = GetScenePresence(agentID);
2655 // It's the UDP contact that creates the scene presence 2772 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2656 ScenePresence sp = WaitGetScenePresence(agentID); 2773
2657 if (sp != null) 2774 if (sp != null)
2658 {
2659 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2660
2661 sp.ControllingClient.Close(); 2775 sp.ControllingClient.Close();
2662 } 2776
2663 else
2664 {
2665 m_log.WarnFormat("[SCENE]: Could not find scene presence for {0}", agentID);
2666 }
2667 // BANG! SLASH! 2777 // BANG! SLASH!
2668 m_authenticateHandler.RemoveCircuit(agentID); 2778 m_authenticateHandler.RemoveCircuit(agentID);
2669 2779
@@ -2763,6 +2873,7 @@ namespace OpenSim.Region.Framework.Scenes
2763 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory; 2873 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory;
2764 client.OnUpdateInventoryItem += UpdateInventoryItemAsset; 2874 client.OnUpdateInventoryItem += UpdateInventoryItemAsset;
2765 client.OnCopyInventoryItem += CopyInventoryItem; 2875 client.OnCopyInventoryItem += CopyInventoryItem;
2876 client.OnMoveItemsAndLeaveCopy += MoveInventoryItemsLeaveCopy;
2766 client.OnMoveInventoryItem += MoveInventoryItem; 2877 client.OnMoveInventoryItem += MoveInventoryItem;
2767 client.OnRemoveInventoryItem += RemoveInventoryItem; 2878 client.OnRemoveInventoryItem += RemoveInventoryItem;
2768 client.OnRemoveInventoryFolder += RemoveInventoryFolder; 2879 client.OnRemoveInventoryFolder += RemoveInventoryFolder;
@@ -2940,15 +3051,16 @@ namespace OpenSim.Region.Framework.Scenes
2940 /// </summary> 3051 /// </summary>
2941 /// <param name="agentId">The avatar's Unique ID</param> 3052 /// <param name="agentId">The avatar's Unique ID</param>
2942 /// <param name="client">The IClientAPI for the client</param> 3053 /// <param name="client">The IClientAPI for the client</param>
2943 public virtual void TeleportClientHome(UUID agentId, IClientAPI client) 3054 public virtual bool TeleportClientHome(UUID agentId, IClientAPI client)
2944 { 3055 {
2945 if (m_teleportModule != null) 3056 if (m_teleportModule != null)
2946 m_teleportModule.TeleportHome(agentId, client); 3057 return m_teleportModule.TeleportHome(agentId, client);
2947 else 3058 else
2948 { 3059 {
2949 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active"); 3060 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active");
2950 client.SendTeleportFailed("Unable to perform teleports on this simulator."); 3061 client.SendTeleportFailed("Unable to perform teleports on this simulator.");
2951 } 3062 }
3063 return false;
2952 } 3064 }
2953 3065
2954 /// <summary> 3066 /// <summary>
@@ -3040,6 +3152,16 @@ namespace OpenSim.Region.Framework.Scenes
3040 /// <param name="flags"></param> 3152 /// <param name="flags"></param>
3041 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags) 3153 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags)
3042 { 3154 {
3155 //Add half the avatar's height so that the user doesn't fall through prims
3156 ScenePresence presence;
3157 if (TryGetScenePresence(remoteClient.AgentId, out presence))
3158 {
3159 if (presence.Appearance != null)
3160 {
3161 position.Z = position.Z + (presence.Appearance.AvatarHeight / 2);
3162 }
3163 }
3164
3043 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt)) 3165 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt))
3044 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot. 3166 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot.
3045 m_dialogModule.SendAlertToUser(remoteClient, "Home position set."); 3167 m_dialogModule.SendAlertToUser(remoteClient, "Home position set.");
@@ -3114,8 +3236,9 @@ namespace OpenSim.Region.Framework.Scenes
3114 regions.Remove(RegionInfo.RegionHandle); 3236 regions.Remove(RegionInfo.RegionHandle);
3115 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3237 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3116 } 3238 }
3117 3239 m_log.Debug("[Scene] Beginning ClientClosed");
3118 m_eventManager.TriggerClientClosed(agentID, this); 3240 m_eventManager.TriggerClientClosed(agentID, this);
3241 m_log.Debug("[Scene] Finished ClientClosed");
3119 } 3242 }
3120 catch (NullReferenceException) 3243 catch (NullReferenceException)
3121 { 3244 {
@@ -3123,7 +3246,12 @@ namespace OpenSim.Region.Framework.Scenes
3123 // Avatar is already disposed :/ 3246 // Avatar is already disposed :/
3124 } 3247 }
3125 3248
3249 m_log.Debug("[Scene] Beginning OnRemovePresence");
3126 m_eventManager.TriggerOnRemovePresence(agentID); 3250 m_eventManager.TriggerOnRemovePresence(agentID);
3251 m_log.Debug("[Scene] Finished OnRemovePresence");
3252
3253 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3254 AttachmentsModule.SaveChangedAttachments(avatar);
3127 3255
3128 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc) 3256 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3129 AttachmentsModule.SaveChangedAttachments(avatar); 3257 AttachmentsModule.SaveChangedAttachments(avatar);
@@ -3132,7 +3260,7 @@ namespace OpenSim.Region.Framework.Scenes
3132 delegate(IClientAPI client) 3260 delegate(IClientAPI client)
3133 { 3261 {
3134 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3262 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3135 try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); } 3263 try { client.SendKillObject(avatar.RegionHandle, new List<uint>() { avatar.LocalId}); }
3136 catch (NullReferenceException) { } 3264 catch (NullReferenceException) { }
3137 }); 3265 });
3138 3266
@@ -3143,8 +3271,11 @@ namespace OpenSim.Region.Framework.Scenes
3143 } 3271 }
3144 3272
3145 // Remove the avatar from the scene 3273 // Remove the avatar from the scene
3274 m_log.Debug("[Scene] Begin RemoveScenePresence");
3146 m_sceneGraph.RemoveScenePresence(agentID); 3275 m_sceneGraph.RemoveScenePresence(agentID);
3276 m_log.Debug("[Scene] Finished RemoveScenePresence. Removing the client manager");
3147 m_clientManager.Remove(agentID); 3277 m_clientManager.Remove(agentID);
3278 m_log.Debug("[Scene] Removed the client manager. Firing avatar.close");
3148 3279
3149 try 3280 try
3150 { 3281 {
@@ -3158,9 +3289,10 @@ namespace OpenSim.Region.Framework.Scenes
3158 { 3289 {
3159 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString()); 3290 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString());
3160 } 3291 }
3161 3292 m_log.Debug("[Scene] Done. Firing RemoveCircuit");
3162 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3293 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
3163// CleanDroppedAttachments(); 3294// CleanDroppedAttachments();
3295 m_log.Debug("[Scene] The avatar has left the building");
3164 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 3296 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
3165 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); 3297 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
3166 } 3298 }
@@ -3191,19 +3323,24 @@ namespace OpenSim.Region.Framework.Scenes
3191 3323
3192 #region Entities 3324 #region Entities
3193 3325
3194 public void SendKillObject(uint localID) 3326 public void SendKillObject(List<uint> localIDs)
3195 { 3327 {
3196 SceneObjectPart part = GetSceneObjectPart(localID); 3328 List<uint> deleteIDs = new List<uint>();
3197 if (part != null) // It is a prim 3329
3330 foreach (uint localID in localIDs)
3198 { 3331 {
3199 if (!part.ParentGroup.IsDeleted) // Valid 3332 SceneObjectPart part = GetSceneObjectPart(localID);
3333 if (part != null) // It is a prim
3200 { 3334 {
3201 if (part.ParentGroup.RootPart != part) // Child part 3335 if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid
3202 return; 3336 {
3337 if (part.ParentGroup.RootPart != part) // Child part
3338 continue;
3339 }
3203 } 3340 }
3341 deleteIDs.Add(localID);
3204 } 3342 }
3205 3343 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, deleteIDs); });
3206 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); });
3207 } 3344 }
3208 3345
3209 #endregion 3346 #endregion
@@ -3221,7 +3358,6 @@ namespace OpenSim.Region.Framework.Scenes
3221 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate; 3358 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
3222 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar; 3359 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar;
3223 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid; 3360 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
3224 m_sceneGridService.KiPrimitive += SendKillObject;
3225 m_sceneGridService.OnGetLandData += GetLandData; 3361 m_sceneGridService.OnGetLandData += GetLandData;
3226 } 3362 }
3227 3363
@@ -3230,7 +3366,6 @@ namespace OpenSim.Region.Framework.Scenes
3230 /// </summary> 3366 /// </summary>
3231 public void UnRegisterRegionWithComms() 3367 public void UnRegisterRegionWithComms()
3232 { 3368 {
3233 m_sceneGridService.KiPrimitive -= SendKillObject;
3234 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid; 3369 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid;
3235 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar; 3370 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar;
3236 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate; 3371 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate;
@@ -3310,13 +3445,16 @@ namespace OpenSim.Region.Framework.Scenes
3310 sp = null; 3445 sp = null;
3311 } 3446 }
3312 3447
3313 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3314 3448
3315 //On login test land permisions 3449 //On login test land permisions
3316 if (vialogin) 3450 if (vialogin)
3317 { 3451 {
3318 if (land != null && !TestLandRestrictions(agent, land, out reason)) 3452 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
3453 if (cache != null)
3454 cache.Remove(agent.firstname + " " + agent.lastname);
3455 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3319 { 3456 {
3457 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString());
3320 return false; 3458 return false;
3321 } 3459 }
3322 } 3460 }
@@ -3339,8 +3477,13 @@ namespace OpenSim.Region.Framework.Scenes
3339 3477
3340 try 3478 try
3341 { 3479 {
3342 if (!AuthorizeUser(agent, out reason)) 3480 // Always check estate if this is a login. Always
3343 return false; 3481 // check if banned regions are to be blacked out.
3482 if (vialogin || (!m_seeIntoBannedRegion))
3483 {
3484 if (!AuthorizeUser(agent, out reason))
3485 return false;
3486 }
3344 } 3487 }
3345 catch (Exception e) 3488 catch (Exception e)
3346 { 3489 {
@@ -3442,6 +3585,8 @@ namespace OpenSim.Region.Framework.Scenes
3442 } 3585 }
3443 } 3586 }
3444 // Honor parcel landing type and position. 3587 // Honor parcel landing type and position.
3588 /*
3589 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3445 if (land != null) 3590 if (land != null)
3446 { 3591 {
3447 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) 3592 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero)
@@ -3449,26 +3594,34 @@ namespace OpenSim.Region.Framework.Scenes
3449 agent.startpos = land.LandData.UserLocation; 3594 agent.startpos = land.LandData.UserLocation;
3450 } 3595 }
3451 } 3596 }
3597 */// This is now handled properly in ScenePresence.MakeRootAgent
3452 } 3598 }
3453 3599
3454 return true; 3600 return true;
3455 } 3601 }
3456 3602
3457 private bool TestLandRestrictions(AgentCircuitData agent, ILandObject land, out string reason) 3603 private bool TestLandRestrictions(UUID agentID, out string reason, ref float posX, ref float posY)
3458 { 3604 {
3459 3605 reason = String.Empty;
3460 bool banned = land.IsBannedFromLand(agent.AgentID); 3606 if (Permissions.IsGod(agentID))
3461 bool restricted = land.IsRestrictedFromLand(agent.AgentID); 3607 return true;
3608
3609 ILandObject land = LandChannel.GetLandObject(posX, posY);
3610 if (land == null)
3611 return false;
3612
3613 bool banned = land.IsBannedFromLand(agentID);
3614 bool restricted = land.IsRestrictedFromLand(agentID);
3462 3615
3463 if (banned || restricted) 3616 if (banned || restricted)
3464 { 3617 {
3465 ILandObject nearestParcel = GetNearestAllowedParcel(agent.AgentID, agent.startpos.X, agent.startpos.Y); 3618 ILandObject nearestParcel = GetNearestAllowedParcel(agentID, posX, posY);
3466 if (nearestParcel != null) 3619 if (nearestParcel != null)
3467 { 3620 {
3468 //Move agent to nearest allowed 3621 //Move agent to nearest allowed
3469 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel); 3622 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel);
3470 agent.startpos.X = newPosition.X; 3623 posX = newPosition.X;
3471 agent.startpos.Y = newPosition.Y; 3624 posY = newPosition.Y;
3472 } 3625 }
3473 else 3626 else
3474 { 3627 {
@@ -3530,7 +3683,7 @@ namespace OpenSim.Region.Framework.Scenes
3530 3683
3531 if (!m_strictAccessControl) return true; 3684 if (!m_strictAccessControl) return true;
3532 if (Permissions.IsGod(agent.AgentID)) return true; 3685 if (Permissions.IsGod(agent.AgentID)) return true;
3533 3686
3534 if (AuthorizationService != null) 3687 if (AuthorizationService != null)
3535 { 3688 {
3536 if (!AuthorizationService.IsAuthorizedForRegion( 3689 if (!AuthorizationService.IsAuthorizedForRegion(
@@ -3538,14 +3691,14 @@ namespace OpenSim.Region.Framework.Scenes
3538 { 3691 {
3539 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region", 3692 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region",
3540 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3693 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
3541 3694
3542 return false; 3695 return false;
3543 } 3696 }
3544 } 3697 }
3545 3698
3546 if (m_regInfo.EstateSettings != null) 3699 if (m_regInfo.EstateSettings != null)
3547 { 3700 {
3548 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID)) 3701 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID,0))
3549 { 3702 {
3550 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", 3703 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
3551 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3704 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
@@ -3735,6 +3888,13 @@ namespace OpenSim.Region.Framework.Scenes
3735 3888
3736 // We have to wait until the viewer contacts this region after receiving EAC. 3889 // We have to wait until the viewer contacts this region after receiving EAC.
3737 // That calls AddNewClient, which finally creates the ScenePresence 3890 // That calls AddNewClient, which finally creates the ScenePresence
3891 int flags = GetUserFlags(cAgentData.AgentID);
3892 if (m_regInfo.EstateSettings.IsBanned(cAgentData.AgentID, flags))
3893 {
3894 m_log.DebugFormat("[SCENE]: Denying root agent entry to {0}: banned", cAgentData.AgentID);
3895 return false;
3896 }
3897
3738 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); 3898 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2);
3739 if (nearestParcel == null) 3899 if (nearestParcel == null)
3740 { 3900 {
@@ -3750,7 +3910,6 @@ namespace OpenSim.Region.Framework.Scenes
3750 return false; 3910 return false;
3751 } 3911 }
3752 3912
3753
3754 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 3913 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
3755 3914
3756 if (childAgentUpdate != null) 3915 if (childAgentUpdate != null)
@@ -3817,12 +3976,22 @@ namespace OpenSim.Region.Framework.Scenes
3817 return false; 3976 return false;
3818 } 3977 }
3819 3978
3979 public bool IncomingCloseAgent(UUID agentID)
3980 {
3981 return IncomingCloseAgent(agentID, false);
3982 }
3983
3984 public bool IncomingCloseChildAgent(UUID agentID)
3985 {
3986 return IncomingCloseAgent(agentID, true);
3987 }
3988
3820 /// <summary> 3989 /// <summary>
3821 /// Tell a single agent to disconnect from the region. 3990 /// Tell a single agent to disconnect from the region.
3822 /// </summary> 3991 /// </summary>
3823 /// <param name="regionHandle"></param>
3824 /// <param name="agentID"></param> 3992 /// <param name="agentID"></param>
3825 public bool IncomingCloseAgent(UUID agentID) 3993 /// <param name="childOnly"></param>
3994 public bool IncomingCloseAgent(UUID agentID, bool childOnly)
3826 { 3995 {
3827 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 3996 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
3828 3997
@@ -3834,7 +4003,7 @@ namespace OpenSim.Region.Framework.Scenes
3834 { 4003 {
3835 m_sceneGraph.removeUserCount(false); 4004 m_sceneGraph.removeUserCount(false);
3836 } 4005 }
3837 else 4006 else if (!childOnly)
3838 { 4007 {
3839 m_sceneGraph.removeUserCount(true); 4008 m_sceneGraph.removeUserCount(true);
3840 } 4009 }
@@ -3850,9 +4019,12 @@ namespace OpenSim.Region.Framework.Scenes
3850 } 4019 }
3851 else 4020 else
3852 presence.ControllingClient.SendShutdownConnectionNotice(); 4021 presence.ControllingClient.SendShutdownConnectionNotice();
4022 presence.ControllingClient.Close(false);
4023 }
4024 else if (!childOnly)
4025 {
4026 presence.ControllingClient.Close(true);
3853 } 4027 }
3854
3855 presence.ControllingClient.Close();
3856 return true; 4028 return true;
3857 } 4029 }
3858 4030
@@ -4467,34 +4639,66 @@ namespace OpenSim.Region.Framework.Scenes
4467 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID); 4639 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID);
4468 } 4640 }
4469 4641
4470 public int GetHealth() 4642 public int GetHealth(out int flags, out string message)
4471 { 4643 {
4472 // Returns: 4644 // Returns:
4473 // 1 = sim is up and accepting http requests. The heartbeat has 4645 // 1 = sim is up and accepting http requests. The heartbeat has
4474 // stopped and the sim is probably locked up, but a remote 4646 // stopped and the sim is probably locked up, but a remote
4475 // admin restart may succeed 4647 // admin restart may succeed
4476 // 4648 //
4477 // 2 = Sim is up and the heartbeat is running. The sim is likely 4649 // 2 = Sim is up and the heartbeat is running. The sim is likely
4478 // usable for people within and logins _may_ work 4650 // usable for people within
4651 //
4652 // 3 = Sim is up and one packet thread is running. Sim is
4653 // unstable and will not accept new logins
4654 //
4655 // 4 = Sim is up and both packet threads are running. Sim is
4656 // likely usable
4479 // 4657 //
4480 // 3 = We have seen a new user enter within the past 4 minutes 4658 // 5 = We have seen a new user enter within the past 4 minutes
4481 // which can be seen as positive confirmation of sim health 4659 // which can be seen as positive confirmation of sim health
4482 // 4660 //
4661
4662 flags = 0;
4663 message = String.Empty;
4664
4665 CheckHeartbeat();
4666
4667 if (m_firstHeartbeat || (m_lastIncoming == 0 && m_lastOutgoing == 0))
4668 {
4669 // We're still starting
4670 // 0 means "in startup", it can't happen another way, since
4671 // to get here, we must be able to accept http connections
4672 return 0;
4673 }
4674
4483 int health=1; // Start at 1, means we're up 4675 int health=1; // Start at 1, means we're up
4484 4676
4485 if ((Util.EnvironmentTickCountSubtract(m_lastUpdate)) < 1000) 4677 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) < 1000)
4678 {
4486 health+=1; 4679 health+=1;
4487 else 4680 flags |= 1;
4681 }
4682
4683 if (Util.EnvironmentTickCountSubtract(m_lastIncoming) < 1000)
4684 {
4685 health+=1;
4686 flags |= 2;
4687 }
4688
4689 if (Util.EnvironmentTickCountSubtract(m_lastOutgoing) < 1000)
4690 {
4691 health+=1;
4692 flags |= 4;
4693 }
4694
4695 if (flags != 7)
4488 return health; 4696 return health;
4489 4697
4490 // A login in the last 4 mins? We can't be doing too badly 4698 // A login in the last 4 mins? We can't be doing too badly
4491 // 4699 //
4492 if ((Util.EnvironmentTickCountSubtract(m_LastLogin)) < 240000) 4700 if (Util.EnvironmentTickCountSubtract(m_LastLogin) < 240000)
4493 health++; 4701 health++;
4494 else
4495 return health;
4496
4497 CheckHeartbeat();
4498 4702
4499 return health; 4703 return health;
4500 } 4704 }
@@ -4687,7 +4891,7 @@ namespace OpenSim.Region.Framework.Scenes
4687 if (m_firstHeartbeat) 4891 if (m_firstHeartbeat)
4688 return; 4892 return;
4689 4893
4690 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 2000) 4894 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 5000)
4691 StartTimer(); 4895 StartTimer();
4692 } 4896 }
4693 4897
@@ -5136,6 +5340,19 @@ namespace OpenSim.Region.Framework.Scenes
5136// } 5340// }
5137// } 5341// }
5138 5342
5343 public void ThreadAlive(int threadCode)
5344 {
5345 switch(threadCode)
5346 {
5347 case 1: // Incoming
5348 m_lastIncoming = Util.EnvironmentTickCount();
5349 break;
5350 case 2: // Incoming
5351 m_lastOutgoing = Util.EnvironmentTickCount();
5352 break;
5353 }
5354 }
5355
5139 // This method is called across the simulation connector to 5356 // This method is called across the simulation connector to
5140 // determine if a given agent is allowed in this region 5357 // determine if a given agent is allowed in this region
5141 // AS A ROOT AGENT. Returning false here will prevent them 5358 // AS A ROOT AGENT. Returning false here will prevent them
@@ -5144,6 +5361,14 @@ namespace OpenSim.Region.Framework.Scenes
5144 // child agent creation, thereby emulating the SL behavior. 5361 // child agent creation, thereby emulating the SL behavior.
5145 public bool QueryAccess(UUID agentID, Vector3 position, out string reason) 5362 public bool QueryAccess(UUID agentID, Vector3 position, out string reason)
5146 { 5363 {
5364 reason = "You are banned from the region";
5365
5366 if (Permissions.IsGod(agentID))
5367 {
5368 reason = String.Empty;
5369 return true;
5370 }
5371
5147 int num = m_sceneGraph.GetNumberOfScenePresences(); 5372 int num = m_sceneGraph.GetNumberOfScenePresences();
5148 5373
5149 if (num >= RegionInfo.RegionSettings.AgentLimit) 5374 if (num >= RegionInfo.RegionSettings.AgentLimit)
@@ -5155,11 +5380,60 @@ namespace OpenSim.Region.Framework.Scenes
5155 } 5380 }
5156 } 5381 }
5157 5382
5383 try
5384 {
5385 if (!AuthorizeUser(GetScenePresence(agentID).ControllingClient.RequestClientInfo(), out reason))
5386 {
5387 // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID);
5388 return false;
5389 }
5390 }
5391 catch
5392 {
5393 return false;
5394 }
5395
5396 if (position == Vector3.Zero) // Teleport
5397 {
5398 float posX = 128.0f;
5399 float posY = 128.0f;
5400
5401 if (!TestLandRestrictions(agentID, out reason, ref posX, ref posY))
5402 {
5403 // m_log.DebugFormat("[SCENE]: Denying {0} because they are banned on all parcels", agentID);
5404 return false;
5405 }
5406 }
5407 else // Walking
5408 {
5409 ILandObject land = LandChannel.GetLandObject(position.X, position.Y);
5410 if (land == null)
5411 return false;
5412
5413 bool banned = land.IsBannedFromLand(agentID);
5414 bool restricted = land.IsRestrictedFromLand(agentID);
5415
5416 if (banned || restricted)
5417 return false;
5418 }
5419
5158 reason = String.Empty; 5420 reason = String.Empty;
5159 return true; 5421 return true;
5160 } 5422 }
5161 5423
5162 /// <summary> 5424 public void StartTimerWatchdog()
5425 {
5426 m_timerWatchdog.Interval = 1000;
5427 m_timerWatchdog.Elapsed += TimerWatchdog;
5428 m_timerWatchdog.AutoReset = true;
5429 m_timerWatchdog.Start();
5430 }
5431
5432 public void TimerWatchdog(object sender, ElapsedEventArgs e)
5433 {
5434 CheckHeartbeat();
5435 }
5436
5163 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the 5437 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the
5164 /// autopilot that moves an avatar to a sit target!. 5438 /// autopilot that moves an avatar to a sit target!.
5165 /// </summary> 5439 /// </summary>