aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Scene.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs502
1 files changed, 417 insertions, 85 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 8a32e1d..53c9366 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -97,6 +97,7 @@ namespace OpenSim.Region.Framework.Scenes
97 // TODO: need to figure out how allow client agents but deny 97 // TODO: need to figure out how allow client agents but deny
98 // root agents when ACL denies access to root agent 98 // root agents when ACL denies access to root agent
99 public bool m_strictAccessControl = true; 99 public bool m_strictAccessControl = true;
100 public bool m_seeIntoBannedRegion = false;
100 public int MaxUndoCount = 5; 101 public int MaxUndoCount = 5;
101 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet; 102 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet;
102 public bool LoginLock = false; 103 public bool LoginLock = false;
@@ -112,12 +113,14 @@ namespace OpenSim.Region.Framework.Scenes
112 113
113 protected int m_splitRegionID; 114 protected int m_splitRegionID;
114 protected Timer m_restartWaitTimer = new Timer(); 115 protected Timer m_restartWaitTimer = new Timer();
116 protected Timer m_timerWatchdog = new Timer();
115 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); 117 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
116 protected List<RegionInfo> m_neighbours = new List<RegionInfo>(); 118 protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
117 protected string m_simulatorVersion = "OpenSimulator Server"; 119 protected string m_simulatorVersion = "OpenSimulator Server";
118 protected ModuleLoader m_moduleLoader; 120 protected ModuleLoader m_moduleLoader;
119 protected AgentCircuitManager m_authenticateHandler; 121 protected AgentCircuitManager m_authenticateHandler;
120 protected SceneCommunicationService m_sceneGridService; 122 protected SceneCommunicationService m_sceneGridService;
123 protected ISnmpModule m_snmpService = null;
121 124
122 protected ISimulationDataService m_SimulationDataService; 125 protected ISimulationDataService m_SimulationDataService;
123 protected IEstateDataService m_EstateDataService; 126 protected IEstateDataService m_EstateDataService;
@@ -174,7 +177,7 @@ namespace OpenSim.Region.Framework.Scenes
174 private int m_update_events = 1; 177 private int m_update_events = 1;
175 private int m_update_backup = 200; 178 private int m_update_backup = 200;
176 private int m_update_terrain = 50; 179 private int m_update_terrain = 50;
177// private int m_update_land = 1; 180 private int m_update_land = 10;
178 private int m_update_coarse_locations = 50; 181 private int m_update_coarse_locations = 50;
179 182
180 private int agentMS; 183 private int agentMS;
@@ -189,6 +192,7 @@ namespace OpenSim.Region.Framework.Scenes
189 private int landMS; 192 private int landMS;
190 private int lastCompletedFrame; 193 private int lastCompletedFrame;
191 194
195 public bool CombineRegions = false;
192 /// <summary> 196 /// <summary>
193 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched 197 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched
194 /// asynchronously from the update loop. 198 /// asynchronously from the update loop.
@@ -211,10 +215,12 @@ namespace OpenSim.Region.Framework.Scenes
211 private bool m_scripts_enabled = true; 215 private bool m_scripts_enabled = true;
212 private string m_defaultScriptEngine; 216 private string m_defaultScriptEngine;
213 private int m_LastLogin; 217 private int m_LastLogin;
214 private Thread HeartbeatThread; 218 private Thread HeartbeatThread = null;
215 private volatile bool shuttingdown; 219 private volatile bool shuttingdown;
216 220
217 private int m_lastUpdate; 221 private int m_lastUpdate;
222 private int m_lastIncoming;
223 private int m_lastOutgoing;
218 private bool m_firstHeartbeat = true; 224 private bool m_firstHeartbeat = true;
219 225
220 private object m_deleting_scene_object = new object(); 226 private object m_deleting_scene_object = new object();
@@ -262,6 +268,19 @@ namespace OpenSim.Region.Framework.Scenes
262 get { return m_sceneGridService; } 268 get { return m_sceneGridService; }
263 } 269 }
264 270
271 public ISnmpModule SnmpService
272 {
273 get
274 {
275 if (m_snmpService == null)
276 {
277 m_snmpService = RequestModuleInterface<ISnmpModule>();
278 }
279
280 return m_snmpService;
281 }
282 }
283
265 public ISimulationDataService SimulationDataService 284 public ISimulationDataService SimulationDataService
266 { 285 {
267 get 286 get
@@ -554,6 +573,9 @@ namespace OpenSim.Region.Framework.Scenes
554 m_EstateDataService = estateDataService; 573 m_EstateDataService = estateDataService;
555 m_regionHandle = m_regInfo.RegionHandle; 574 m_regionHandle = m_regInfo.RegionHandle;
556 m_regionName = m_regInfo.RegionName; 575 m_regionName = m_regInfo.RegionName;
576 m_lastUpdate = Util.EnvironmentTickCount();
577 m_lastIncoming = 0;
578 m_lastOutgoing = 0;
557 579
558 m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this); 580 m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this);
559 m_asyncSceneObjectDeleter.Enabled = true; 581 m_asyncSceneObjectDeleter.Enabled = true;
@@ -675,11 +697,13 @@ namespace OpenSim.Region.Framework.Scenes
675 //Animation states 697 //Animation states
676 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); 698 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
677 // TODO: Change default to true once the feature is supported 699 // TODO: Change default to true once the feature is supported
678 m_usePreJump = startupConfig.GetBoolean("enableprejump", false); 700 m_usePreJump = startupConfig.GetBoolean("enableprejump", true);
679 701
680 m_physicalPrim = startupConfig.GetBoolean("physical_prim", true); 702 m_physicalPrim = startupConfig.GetBoolean("physical_prim", true);
681 703
682 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys); 704 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
705
706 m_log.DebugFormat("[SCENE]: prejump is {0}", m_usePreJump ? "ON" : "OFF");
683 if (RegionInfo.NonphysPrimMax > 0) 707 if (RegionInfo.NonphysPrimMax > 0)
684 { 708 {
685 m_maxNonphys = RegionInfo.NonphysPrimMax; 709 m_maxNonphys = RegionInfo.NonphysPrimMax;
@@ -712,6 +736,7 @@ namespace OpenSim.Region.Framework.Scenes
712 m_persistAfter *= 10000000; 736 m_persistAfter *= 10000000;
713 737
714 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); 738 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
739 m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine);
715 740
716 IConfig packetConfig = m_config.Configs["PacketPool"]; 741 IConfig packetConfig = m_config.Configs["PacketPool"];
717 if (packetConfig != null) 742 if (packetConfig != null)
@@ -721,6 +746,8 @@ namespace OpenSim.Region.Framework.Scenes
721 } 746 }
722 747
723 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); 748 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
749 m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion);
750 CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false);
724 751
725 m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true); 752 m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true);
726 if (m_generateMaptiles) 753 if (m_generateMaptiles)
@@ -756,9 +783,9 @@ namespace OpenSim.Region.Framework.Scenes
756 m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain); 783 m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain);
757 m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning); 784 m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning);
758 } 785 }
759 catch 786 catch (Exception e)
760 { 787 {
761 m_log.Warn("[SCENE]: Failed to load StartupConfig"); 788 m_log.Error("[SCENE]: Failed to load StartupConfig: " + e.ToString());
762 } 789 }
763 790
764 #endregion Region Config 791 #endregion Region Config
@@ -1138,7 +1165,9 @@ namespace OpenSim.Region.Framework.Scenes
1138 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); 1165 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
1139 if (HeartbeatThread != null) 1166 if (HeartbeatThread != null)
1140 { 1167 {
1168 m_log.ErrorFormat("[SCENE]: Restarting heartbeat thread because it hasn't reported in in region {0}", RegionInfo.RegionName);
1141 HeartbeatThread.Abort(); 1169 HeartbeatThread.Abort();
1170 Watchdog.RemoveThread(HeartbeatThread.ManagedThreadId);
1142 HeartbeatThread = null; 1171 HeartbeatThread = null;
1143 } 1172 }
1144 m_lastUpdate = Util.EnvironmentTickCount(); 1173 m_lastUpdate = Util.EnvironmentTickCount();
@@ -1181,9 +1210,6 @@ namespace OpenSim.Region.Framework.Scenes
1181 { 1210 {
1182 while (!shuttingdown) 1211 while (!shuttingdown)
1183 Update(); 1212 Update();
1184
1185 m_lastUpdate = Util.EnvironmentTickCount();
1186 m_firstHeartbeat = false;
1187 } 1213 }
1188 catch (ThreadAbortException) 1214 catch (ThreadAbortException)
1189 { 1215 {
@@ -1281,6 +1307,13 @@ namespace OpenSim.Region.Framework.Scenes
1281 eventMS = Util.EnvironmentTickCountSubtract(evMS); ; 1307 eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
1282 } 1308 }
1283 1309
1310 // if (Frame % m_update_land == 0)
1311 // {
1312 // int ldMS = Util.EnvironmentTickCount();
1313 // UpdateLand();
1314 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1315 // }
1316
1284 if (Frame % m_update_backup == 0) 1317 if (Frame % m_update_backup == 0)
1285 { 1318 {
1286 int backMS = Util.EnvironmentTickCount(); 1319 int backMS = Util.EnvironmentTickCount();
@@ -1382,12 +1415,16 @@ namespace OpenSim.Region.Framework.Scenes
1382 maintc = Util.EnvironmentTickCountSubtract(maintc); 1415 maintc = Util.EnvironmentTickCountSubtract(maintc);
1383 maintc = (int)(MinFrameTime * 1000) - maintc; 1416 maintc = (int)(MinFrameTime * 1000) - maintc;
1384 1417
1418
1419 m_lastUpdate = Util.EnvironmentTickCount();
1420 m_firstHeartbeat = false;
1421
1385 if (maintc > 0) 1422 if (maintc > 0)
1386 Thread.Sleep(maintc); 1423 Thread.Sleep(maintc);
1387 1424
1388 // Tell the watchdog that this thread is still alive 1425 // Tell the watchdog that this thread is still alive
1389 Watchdog.UpdateThread(); 1426 Watchdog.UpdateThread();
1390 } 1427 }
1391 1428
1392 public void AddGroupTarget(SceneObjectGroup grp) 1429 public void AddGroupTarget(SceneObjectGroup grp)
1393 { 1430 {
@@ -1403,9 +1440,9 @@ namespace OpenSim.Region.Framework.Scenes
1403 1440
1404 private void CheckAtTargets() 1441 private void CheckAtTargets()
1405 { 1442 {
1406 Dictionary<UUID, SceneObjectGroup>.ValueCollection objs; 1443 List<SceneObjectGroup> objs = new List<SceneObjectGroup>();
1407 lock (m_groupsWithTargets) 1444 lock (m_groupsWithTargets)
1408 objs = m_groupsWithTargets.Values; 1445 objs = new List<SceneObjectGroup>(m_groupsWithTargets.Values);
1409 1446
1410 foreach (SceneObjectGroup entry in objs) 1447 foreach (SceneObjectGroup entry in objs)
1411 entry.checkAtTargets(); 1448 entry.checkAtTargets();
@@ -1725,14 +1762,24 @@ namespace OpenSim.Region.Framework.Scenes
1725 /// <returns></returns> 1762 /// <returns></returns>
1726 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter) 1763 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter)
1727 { 1764 {
1765
1766 float wheight = (float)RegionInfo.RegionSettings.WaterHeight;
1767 Vector3 wpos = Vector3.Zero;
1768 // Check for water surface intersection from above
1769 if ( (RayStart.Z > wheight) && (RayEnd.Z < wheight) )
1770 {
1771 float ratio = (RayStart.Z - wheight) / (RayStart.Z - RayEnd.Z);
1772 wpos.X = RayStart.X - (ratio * (RayStart.X - RayEnd.X));
1773 wpos.Y = RayStart.Y - (ratio * (RayStart.Y - RayEnd.Y));
1774 wpos.Z = wheight;
1775 }
1776
1728 Vector3 pos = Vector3.Zero; 1777 Vector3 pos = Vector3.Zero;
1729 if (RayEndIsIntersection == (byte)1) 1778 if (RayEndIsIntersection == (byte)1)
1730 { 1779 {
1731 pos = RayEnd; 1780 pos = RayEnd;
1732 return pos;
1733 } 1781 }
1734 1782 else if (RayTargetID != UUID.Zero)
1735 if (RayTargetID != UUID.Zero)
1736 { 1783 {
1737 SceneObjectPart target = GetSceneObjectPart(RayTargetID); 1784 SceneObjectPart target = GetSceneObjectPart(RayTargetID);
1738 1785
@@ -1754,7 +1801,7 @@ namespace OpenSim.Region.Framework.Scenes
1754 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter); 1801 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter);
1755 1802
1756 // Un-comment out the following line to Get Raytrace results printed to the console. 1803 // Un-comment out the following line to Get Raytrace results printed to the console.
1757 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); 1804 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
1758 float ScaleOffset = 0.5f; 1805 float ScaleOffset = 0.5f;
1759 1806
1760 // If we hit something 1807 // If we hit something
@@ -1777,13 +1824,10 @@ namespace OpenSim.Region.Framework.Scenes
1777 //pos.Z -= 0.25F; 1824 //pos.Z -= 0.25F;
1778 1825
1779 } 1826 }
1780
1781 return pos;
1782 } 1827 }
1783 else 1828 else
1784 { 1829 {
1785 // We don't have a target here, so we're going to raytrace all the objects in the scene. 1830 // We don't have a target here, so we're going to raytrace all the objects in the scene.
1786
1787 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false); 1831 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false);
1788 1832
1789 // Un-comment the following line to print the raytrace results to the console. 1833 // Un-comment the following line to print the raytrace results to the console.
@@ -1792,13 +1836,12 @@ namespace OpenSim.Region.Framework.Scenes
1792 if (ei.HitTF) 1836 if (ei.HitTF)
1793 { 1837 {
1794 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); 1838 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
1795 } else 1839 }
1840 else
1796 { 1841 {
1797 // fall back to our stupid functionality 1842 // fall back to our stupid functionality
1798 pos = RayEnd; 1843 pos = RayEnd;
1799 } 1844 }
1800
1801 return pos;
1802 } 1845 }
1803 } 1846 }
1804 else 1847 else
@@ -1809,8 +1852,12 @@ namespace OpenSim.Region.Framework.Scenes
1809 //increase height so its above the ground. 1852 //increase height so its above the ground.
1810 //should be getting the normal of the ground at the rez point and using that? 1853 //should be getting the normal of the ground at the rez point and using that?
1811 pos.Z += scale.Z / 2f; 1854 pos.Z += scale.Z / 2f;
1812 return pos; 1855// return pos;
1813 } 1856 }
1857
1858 // check against posible water intercept
1859 if (wpos.Z > pos.Z) pos = wpos;
1860 return pos;
1814 } 1861 }
1815 1862
1816 1863
@@ -1894,7 +1941,10 @@ namespace OpenSim.Region.Framework.Scenes
1894 public bool AddRestoredSceneObject( 1941 public bool AddRestoredSceneObject(
1895 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 1942 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
1896 { 1943 {
1897 return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); 1944 bool result = m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates);
1945 if (result)
1946 sceneObject.IsDeleted = false;
1947 return result;
1898 } 1948 }
1899 1949
1900 /// <summary> 1950 /// <summary>
@@ -1984,6 +2034,15 @@ namespace OpenSim.Region.Framework.Scenes
1984 /// </summary> 2034 /// </summary>
1985 public void DeleteAllSceneObjects() 2035 public void DeleteAllSceneObjects()
1986 { 2036 {
2037 DeleteAllSceneObjects(false);
2038 }
2039
2040 /// <summary>
2041 /// Delete every object from the scene. This does not include attachments worn by avatars.
2042 /// </summary>
2043 public void DeleteAllSceneObjects(bool exceptNoCopy)
2044 {
2045 List<SceneObjectGroup> toReturn = new List<SceneObjectGroup>();
1987 lock (Entities) 2046 lock (Entities)
1988 { 2047 {
1989 EntityBase[] entities = Entities.GetEntities(); 2048 EntityBase[] entities = Entities.GetEntities();
@@ -1992,11 +2051,24 @@ namespace OpenSim.Region.Framework.Scenes
1992 if (e is SceneObjectGroup) 2051 if (e is SceneObjectGroup)
1993 { 2052 {
1994 SceneObjectGroup sog = (SceneObjectGroup)e; 2053 SceneObjectGroup sog = (SceneObjectGroup)e;
1995 if (!sog.IsAttachment) 2054 if (sog != null && !sog.IsAttachment)
1996 DeleteSceneObject((SceneObjectGroup)e, false); 2055 {
2056 if (!exceptNoCopy || ((sog.GetEffectivePermissions() & (uint)PermissionMask.Copy) != 0))
2057 {
2058 DeleteSceneObject((SceneObjectGroup)e, false);
2059 }
2060 else
2061 {
2062 toReturn.Add((SceneObjectGroup)e);
2063 }
2064 }
1997 } 2065 }
1998 } 2066 }
1999 } 2067 }
2068 if (toReturn.Count > 0)
2069 {
2070 returnObjects(toReturn.ToArray(), UUID.Zero);
2071 }
2000 } 2072 }
2001 2073
2002 /// <summary> 2074 /// <summary>
@@ -2044,6 +2116,8 @@ namespace OpenSim.Region.Framework.Scenes
2044 } 2116 }
2045 2117
2046 group.DeleteGroupFromScene(silent); 2118 group.DeleteGroupFromScene(silent);
2119 if (!silent)
2120 SendKillObject(new List<uint>() { group.LocalId });
2047 2121
2048// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); 2122// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
2049 } 2123 }
@@ -2398,10 +2472,17 @@ namespace OpenSim.Region.Framework.Scenes
2398 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns> 2472 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns>
2399 public bool AddSceneObject(SceneObjectGroup sceneObject) 2473 public bool AddSceneObject(SceneObjectGroup sceneObject)
2400 { 2474 {
2475 if (sceneObject.OwnerID == UUID.Zero)
2476 {
2477 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero", sceneObject.UUID);
2478 return false;
2479 }
2480
2401 // If the user is banned, we won't let any of their objects 2481 // If the user is banned, we won't let any of their objects
2402 // enter. Period. 2482 // enter. Period.
2403 // 2483 //
2404 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID)) 2484 int flags = GetUserFlags(sceneObject.OwnerID);
2485 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID, flags))
2405 { 2486 {
2406 m_log.Info("[INTERREGION]: Denied prim crossing for " + 2487 m_log.Info("[INTERREGION]: Denied prim crossing for " +
2407 "banned avatar"); 2488 "banned avatar");
@@ -2448,12 +2529,23 @@ namespace OpenSim.Region.Framework.Scenes
2448 } 2529 }
2449 else 2530 else
2450 { 2531 {
2532 m_log.DebugFormat("[SCENE]: Attachment {0} arrived and scene presence was not found, setting to temp", sceneObject.UUID);
2451 RootPrim.RemFlag(PrimFlags.TemporaryOnRez); 2533 RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
2452 RootPrim.AddFlag(PrimFlags.TemporaryOnRez); 2534 RootPrim.AddFlag(PrimFlags.TemporaryOnRez);
2453 } 2535 }
2536 if (sceneObject.OwnerID == UUID.Zero)
2537 {
2538 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero after attachment processing. BUG!", sceneObject.UUID);
2539 return false;
2540 }
2454 } 2541 }
2455 else 2542 else
2456 { 2543 {
2544 if (sceneObject.OwnerID == UUID.Zero)
2545 {
2546 m_log.ErrorFormat("[SCENE]: Owner ID for non-attachment {0} was zero", sceneObject.UUID);
2547 return false;
2548 }
2457 AddRestoredSceneObject(sceneObject, true, false); 2549 AddRestoredSceneObject(sceneObject, true, false);
2458 2550
2459 if (!Permissions.CanObjectEntry(sceneObject.UUID, 2551 if (!Permissions.CanObjectEntry(sceneObject.UUID,
@@ -2483,6 +2575,24 @@ namespace OpenSim.Region.Framework.Scenes
2483 return 2; // StateSource.PrimCrossing 2575 return 2; // StateSource.PrimCrossing
2484 } 2576 }
2485 2577
2578 public int GetUserFlags(UUID user)
2579 {
2580 //Unfortunately the SP approach means that the value is cached until region is restarted
2581 /*
2582 ScenePresence sp;
2583 if (TryGetScenePresence(user, out sp))
2584 {
2585 return sp.UserFlags;
2586 }
2587 else
2588 {
2589 */
2590 UserAccount uac = UserAccountService.GetUserAccount(RegionInfo.ScopeID, user);
2591 if (uac == null)
2592 return 0;
2593 return uac.UserFlags;
2594 //}
2595 }
2486 #endregion 2596 #endregion
2487 2597
2488 #region Add/Remove Avatar Methods 2598 #region Add/Remove Avatar Methods
@@ -2504,6 +2614,7 @@ namespace OpenSim.Region.Framework.Scenes
2504 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2614 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2505 2615
2506 CheckHeartbeat(); 2616 CheckHeartbeat();
2617 ScenePresence presence;
2507 2618
2508 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here 2619 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here
2509 { 2620 {
@@ -2537,7 +2648,14 @@ namespace OpenSim.Region.Framework.Scenes
2537 2648
2538 EventManager.TriggerOnNewClient(client); 2649 EventManager.TriggerOnNewClient(client);
2539 if (vialogin) 2650 if (vialogin)
2651 {
2540 EventManager.TriggerOnClientLogin(client); 2652 EventManager.TriggerOnClientLogin(client);
2653
2654 // Send initial parcel data
2655 Vector3 pos = createdSp.AbsolutePosition;
2656 ILandObject land = LandChannel.GetLandObject(pos.X, pos.Y);
2657 land.SendLandUpdateToClient(client);
2658 }
2541 } 2659 }
2542 } 2660 }
2543 2661
@@ -2626,19 +2744,12 @@ namespace OpenSim.Region.Framework.Scenes
2626 // and the scene presence and the client, if they exist 2744 // and the scene presence and the client, if they exist
2627 try 2745 try
2628 { 2746 {
2629 // We need to wait for the client to make UDP contact first. 2747 ScenePresence sp = GetScenePresence(agentID);
2630 // It's the UDP contact that creates the scene presence 2748 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2631 ScenePresence sp = WaitGetScenePresence(agentID); 2749
2632 if (sp != null) 2750 if (sp != null)
2633 {
2634 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2635
2636 sp.ControllingClient.Close(); 2751 sp.ControllingClient.Close();
2637 } 2752
2638 else
2639 {
2640 m_log.WarnFormat("[SCENE]: Could not find scene presence for {0}", agentID);
2641 }
2642 // BANG! SLASH! 2753 // BANG! SLASH!
2643 m_authenticateHandler.RemoveCircuit(agentID); 2754 m_authenticateHandler.RemoveCircuit(agentID);
2644 2755
@@ -2738,6 +2849,7 @@ namespace OpenSim.Region.Framework.Scenes
2738 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory; 2849 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory;
2739 client.OnUpdateInventoryItem += UpdateInventoryItemAsset; 2850 client.OnUpdateInventoryItem += UpdateInventoryItemAsset;
2740 client.OnCopyInventoryItem += CopyInventoryItem; 2851 client.OnCopyInventoryItem += CopyInventoryItem;
2852 client.OnMoveItemsAndLeaveCopy += MoveInventoryItemsLeaveCopy;
2741 client.OnMoveInventoryItem += MoveInventoryItem; 2853 client.OnMoveInventoryItem += MoveInventoryItem;
2742 client.OnRemoveInventoryItem += RemoveInventoryItem; 2854 client.OnRemoveInventoryItem += RemoveInventoryItem;
2743 client.OnRemoveInventoryFolder += RemoveInventoryFolder; 2855 client.OnRemoveInventoryFolder += RemoveInventoryFolder;
@@ -2915,15 +3027,16 @@ namespace OpenSim.Region.Framework.Scenes
2915 /// </summary> 3027 /// </summary>
2916 /// <param name="agentId">The avatar's Unique ID</param> 3028 /// <param name="agentId">The avatar's Unique ID</param>
2917 /// <param name="client">The IClientAPI for the client</param> 3029 /// <param name="client">The IClientAPI for the client</param>
2918 public virtual void TeleportClientHome(UUID agentId, IClientAPI client) 3030 public virtual bool TeleportClientHome(UUID agentId, IClientAPI client)
2919 { 3031 {
2920 if (m_teleportModule != null) 3032 if (m_teleportModule != null)
2921 m_teleportModule.TeleportHome(agentId, client); 3033 return m_teleportModule.TeleportHome(agentId, client);
2922 else 3034 else
2923 { 3035 {
2924 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active"); 3036 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active");
2925 client.SendTeleportFailed("Unable to perform teleports on this simulator."); 3037 client.SendTeleportFailed("Unable to perform teleports on this simulator.");
2926 } 3038 }
3039 return false;
2927 } 3040 }
2928 3041
2929 /// <summary> 3042 /// <summary>
@@ -3015,6 +3128,16 @@ namespace OpenSim.Region.Framework.Scenes
3015 /// <param name="flags"></param> 3128 /// <param name="flags"></param>
3016 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags) 3129 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags)
3017 { 3130 {
3131 //Add half the avatar's height so that the user doesn't fall through prims
3132 ScenePresence presence;
3133 if (TryGetScenePresence(remoteClient.AgentId, out presence))
3134 {
3135 if (presence.Appearance != null)
3136 {
3137 position.Z = position.Z + (presence.Appearance.AvatarHeight / 2);
3138 }
3139 }
3140
3018 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt)) 3141 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt))
3019 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot. 3142 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot.
3020 m_dialogModule.SendAlertToUser(remoteClient, "Home position set."); 3143 m_dialogModule.SendAlertToUser(remoteClient, "Home position set.");
@@ -3083,8 +3206,9 @@ namespace OpenSim.Region.Framework.Scenes
3083 regions.Remove(RegionInfo.RegionHandle); 3206 regions.Remove(RegionInfo.RegionHandle);
3084 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3207 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3085 } 3208 }
3086 3209 m_log.Debug("[Scene] Beginning ClientClosed");
3087 m_eventManager.TriggerClientClosed(agentID, this); 3210 m_eventManager.TriggerClientClosed(agentID, this);
3211 m_log.Debug("[Scene] Finished ClientClosed");
3088 } 3212 }
3089 catch (NullReferenceException) 3213 catch (NullReferenceException)
3090 { 3214 {
@@ -3092,7 +3216,12 @@ namespace OpenSim.Region.Framework.Scenes
3092 // Avatar is already disposed :/ 3216 // Avatar is already disposed :/
3093 } 3217 }
3094 3218
3219 m_log.Debug("[Scene] Beginning OnRemovePresence");
3095 m_eventManager.TriggerOnRemovePresence(agentID); 3220 m_eventManager.TriggerOnRemovePresence(agentID);
3221 m_log.Debug("[Scene] Finished OnRemovePresence");
3222
3223 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3224 AttachmentsModule.SaveChangedAttachments(avatar);
3096 3225
3097 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc) 3226 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3098 AttachmentsModule.SaveChangedAttachments(avatar); 3227 AttachmentsModule.SaveChangedAttachments(avatar);
@@ -3101,7 +3230,7 @@ namespace OpenSim.Region.Framework.Scenes
3101 delegate(IClientAPI client) 3230 delegate(IClientAPI client)
3102 { 3231 {
3103 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3232 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3104 try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); } 3233 try { client.SendKillObject(avatar.RegionHandle, new List<uint>() { avatar.LocalId}); }
3105 catch (NullReferenceException) { } 3234 catch (NullReferenceException) { }
3106 }); 3235 });
3107 3236
@@ -3112,8 +3241,11 @@ namespace OpenSim.Region.Framework.Scenes
3112 } 3241 }
3113 3242
3114 // Remove the avatar from the scene 3243 // Remove the avatar from the scene
3244 m_log.Debug("[Scene] Begin RemoveScenePresence");
3115 m_sceneGraph.RemoveScenePresence(agentID); 3245 m_sceneGraph.RemoveScenePresence(agentID);
3246 m_log.Debug("[Scene] Finished RemoveScenePresence. Removing the client manager");
3116 m_clientManager.Remove(agentID); 3247 m_clientManager.Remove(agentID);
3248 m_log.Debug("[Scene] Removed the client manager. Firing avatar.close");
3117 3249
3118 try 3250 try
3119 { 3251 {
@@ -3127,9 +3259,10 @@ namespace OpenSim.Region.Framework.Scenes
3127 { 3259 {
3128 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString()); 3260 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString());
3129 } 3261 }
3130 3262 m_log.Debug("[Scene] Done. Firing RemoveCircuit");
3131 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3263 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
3132// CleanDroppedAttachments(); 3264// CleanDroppedAttachments();
3265 m_log.Debug("[Scene] The avatar has left the building");
3133 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 3266 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
3134 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); 3267 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
3135 } 3268 }
@@ -3160,19 +3293,24 @@ namespace OpenSim.Region.Framework.Scenes
3160 3293
3161 #region Entities 3294 #region Entities
3162 3295
3163 public void SendKillObject(uint localID) 3296 public void SendKillObject(List<uint> localIDs)
3164 { 3297 {
3165 SceneObjectPart part = GetSceneObjectPart(localID); 3298 List<uint> deleteIDs = new List<uint>();
3166 if (part != null) // It is a prim 3299
3300 foreach (uint localID in localIDs)
3167 { 3301 {
3168 if (!part.ParentGroup.IsDeleted) // Valid 3302 SceneObjectPart part = GetSceneObjectPart(localID);
3303 if (part != null) // It is a prim
3169 { 3304 {
3170 if (part.ParentGroup.RootPart != part) // Child part 3305 if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid
3171 return; 3306 {
3307 if (part.ParentGroup.RootPart != part) // Child part
3308 continue;
3309 }
3172 } 3310 }
3311 deleteIDs.Add(localID);
3173 } 3312 }
3174 3313 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, deleteIDs); });
3175 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); });
3176 } 3314 }
3177 3315
3178 #endregion 3316 #endregion
@@ -3190,7 +3328,6 @@ namespace OpenSim.Region.Framework.Scenes
3190 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate; 3328 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
3191 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar; 3329 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar;
3192 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid; 3330 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
3193 m_sceneGridService.KiPrimitive += SendKillObject;
3194 m_sceneGridService.OnGetLandData += GetLandData; 3331 m_sceneGridService.OnGetLandData += GetLandData;
3195 } 3332 }
3196 3333
@@ -3199,7 +3336,6 @@ namespace OpenSim.Region.Framework.Scenes
3199 /// </summary> 3336 /// </summary>
3200 public void UnRegisterRegionWithComms() 3337 public void UnRegisterRegionWithComms()
3201 { 3338 {
3202 m_sceneGridService.KiPrimitive -= SendKillObject;
3203 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid; 3339 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid;
3204 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar; 3340 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar;
3205 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate; 3341 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate;
@@ -3279,13 +3415,16 @@ namespace OpenSim.Region.Framework.Scenes
3279 sp = null; 3415 sp = null;
3280 } 3416 }
3281 3417
3282 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3283 3418
3284 //On login test land permisions 3419 //On login test land permisions
3285 if (vialogin) 3420 if (vialogin)
3286 { 3421 {
3287 if (land != null && !TestLandRestrictions(agent, land, out reason)) 3422 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
3423 if (cache != null)
3424 cache.Remove(agent.firstname + " " + agent.lastname);
3425 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3288 { 3426 {
3427 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString());
3289 return false; 3428 return false;
3290 } 3429 }
3291 } 3430 }
@@ -3308,8 +3447,13 @@ namespace OpenSim.Region.Framework.Scenes
3308 3447
3309 try 3448 try
3310 { 3449 {
3311 if (!AuthorizeUser(agent, out reason)) 3450 // Always check estate if this is a login. Always
3312 return false; 3451 // check if banned regions are to be blacked out.
3452 if (vialogin || (!m_seeIntoBannedRegion))
3453 {
3454 if (!AuthorizeUser(agent, out reason))
3455 return false;
3456 }
3313 } 3457 }
3314 catch (Exception e) 3458 catch (Exception e)
3315 { 3459 {
@@ -3411,6 +3555,8 @@ namespace OpenSim.Region.Framework.Scenes
3411 } 3555 }
3412 } 3556 }
3413 // Honor parcel landing type and position. 3557 // Honor parcel landing type and position.
3558 /*
3559 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3414 if (land != null) 3560 if (land != null)
3415 { 3561 {
3416 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) 3562 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero)
@@ -3418,26 +3564,34 @@ namespace OpenSim.Region.Framework.Scenes
3418 agent.startpos = land.LandData.UserLocation; 3564 agent.startpos = land.LandData.UserLocation;
3419 } 3565 }
3420 } 3566 }
3567 */// This is now handled properly in ScenePresence.MakeRootAgent
3421 } 3568 }
3422 3569
3423 return true; 3570 return true;
3424 } 3571 }
3425 3572
3426 private bool TestLandRestrictions(AgentCircuitData agent, ILandObject land, out string reason) 3573 private bool TestLandRestrictions(UUID agentID, out string reason, ref float posX, ref float posY)
3427 { 3574 {
3428 3575 reason = String.Empty;
3429 bool banned = land.IsBannedFromLand(agent.AgentID); 3576 if (Permissions.IsGod(agentID))
3430 bool restricted = land.IsRestrictedFromLand(agent.AgentID); 3577 return true;
3578
3579 ILandObject land = LandChannel.GetLandObject(posX, posY);
3580 if (land == null)
3581 return false;
3582
3583 bool banned = land.IsBannedFromLand(agentID);
3584 bool restricted = land.IsRestrictedFromLand(agentID);
3431 3585
3432 if (banned || restricted) 3586 if (banned || restricted)
3433 { 3587 {
3434 ILandObject nearestParcel = GetNearestAllowedParcel(agent.AgentID, agent.startpos.X, agent.startpos.Y); 3588 ILandObject nearestParcel = GetNearestAllowedParcel(agentID, posX, posY);
3435 if (nearestParcel != null) 3589 if (nearestParcel != null)
3436 { 3590 {
3437 //Move agent to nearest allowed 3591 //Move agent to nearest allowed
3438 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel); 3592 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel);
3439 agent.startpos.X = newPosition.X; 3593 posX = newPosition.X;
3440 agent.startpos.Y = newPosition.Y; 3594 posY = newPosition.Y;
3441 } 3595 }
3442 else 3596 else
3443 { 3597 {
@@ -3499,7 +3653,7 @@ namespace OpenSim.Region.Framework.Scenes
3499 3653
3500 if (!m_strictAccessControl) return true; 3654 if (!m_strictAccessControl) return true;
3501 if (Permissions.IsGod(agent.AgentID)) return true; 3655 if (Permissions.IsGod(agent.AgentID)) return true;
3502 3656
3503 if (AuthorizationService != null) 3657 if (AuthorizationService != null)
3504 { 3658 {
3505 if (!AuthorizationService.IsAuthorizedForRegion( 3659 if (!AuthorizationService.IsAuthorizedForRegion(
@@ -3507,14 +3661,14 @@ namespace OpenSim.Region.Framework.Scenes
3507 { 3661 {
3508 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region", 3662 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region",
3509 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3663 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
3510 3664
3511 return false; 3665 return false;
3512 } 3666 }
3513 } 3667 }
3514 3668
3515 if (m_regInfo.EstateSettings != null) 3669 if (m_regInfo.EstateSettings != null)
3516 { 3670 {
3517 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID)) 3671 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID,0))
3518 { 3672 {
3519 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", 3673 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
3520 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3674 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
@@ -3704,6 +3858,13 @@ namespace OpenSim.Region.Framework.Scenes
3704 3858
3705 // We have to wait until the viewer contacts this region after receiving EAC. 3859 // We have to wait until the viewer contacts this region after receiving EAC.
3706 // That calls AddNewClient, which finally creates the ScenePresence 3860 // That calls AddNewClient, which finally creates the ScenePresence
3861 int flags = GetUserFlags(cAgentData.AgentID);
3862 if (m_regInfo.EstateSettings.IsBanned(cAgentData.AgentID, flags))
3863 {
3864 m_log.DebugFormat("[SCENE]: Denying root agent entry to {0}: banned", cAgentData.AgentID);
3865 return false;
3866 }
3867
3707 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); 3868 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2);
3708 if (nearestParcel == null) 3869 if (nearestParcel == null)
3709 { 3870 {
@@ -3719,7 +3880,6 @@ namespace OpenSim.Region.Framework.Scenes
3719 return false; 3880 return false;
3720 } 3881 }
3721 3882
3722
3723 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 3883 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
3724 3884
3725 if (childAgentUpdate != null) 3885 if (childAgentUpdate != null)
@@ -3786,12 +3946,22 @@ namespace OpenSim.Region.Framework.Scenes
3786 return false; 3946 return false;
3787 } 3947 }
3788 3948
3949 public bool IncomingCloseAgent(UUID agentID)
3950 {
3951 return IncomingCloseAgent(agentID, false);
3952 }
3953
3954 public bool IncomingCloseChildAgent(UUID agentID)
3955 {
3956 return IncomingCloseAgent(agentID, true);
3957 }
3958
3789 /// <summary> 3959 /// <summary>
3790 /// Tell a single agent to disconnect from the region. 3960 /// Tell a single agent to disconnect from the region.
3791 /// </summary> 3961 /// </summary>
3792 /// <param name="regionHandle"></param>
3793 /// <param name="agentID"></param> 3962 /// <param name="agentID"></param>
3794 public bool IncomingCloseAgent(UUID agentID) 3963 /// <param name="childOnly"></param>
3964 public bool IncomingCloseAgent(UUID agentID, bool childOnly)
3795 { 3965 {
3796 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 3966 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
3797 3967
@@ -3803,7 +3973,7 @@ namespace OpenSim.Region.Framework.Scenes
3803 { 3973 {
3804 m_sceneGraph.removeUserCount(false); 3974 m_sceneGraph.removeUserCount(false);
3805 } 3975 }
3806 else 3976 else if (!childOnly)
3807 { 3977 {
3808 m_sceneGraph.removeUserCount(true); 3978 m_sceneGraph.removeUserCount(true);
3809 } 3979 }
@@ -3819,9 +3989,12 @@ namespace OpenSim.Region.Framework.Scenes
3819 } 3989 }
3820 else 3990 else
3821 presence.ControllingClient.SendShutdownConnectionNotice(); 3991 presence.ControllingClient.SendShutdownConnectionNotice();
3992 presence.ControllingClient.Close(false);
3993 }
3994 else if (!childOnly)
3995 {
3996 presence.ControllingClient.Close(true);
3822 } 3997 }
3823
3824 presence.ControllingClient.Close();
3825 return true; 3998 return true;
3826 } 3999 }
3827 4000
@@ -4436,34 +4609,66 @@ namespace OpenSim.Region.Framework.Scenes
4436 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID); 4609 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID);
4437 } 4610 }
4438 4611
4439 public int GetHealth() 4612 public int GetHealth(out int flags, out string message)
4440 { 4613 {
4441 // Returns: 4614 // Returns:
4442 // 1 = sim is up and accepting http requests. The heartbeat has 4615 // 1 = sim is up and accepting http requests. The heartbeat has
4443 // stopped and the sim is probably locked up, but a remote 4616 // stopped and the sim is probably locked up, but a remote
4444 // admin restart may succeed 4617 // admin restart may succeed
4445 // 4618 //
4446 // 2 = Sim is up and the heartbeat is running. The sim is likely 4619 // 2 = Sim is up and the heartbeat is running. The sim is likely
4447 // usable for people within and logins _may_ work 4620 // usable for people within
4448 // 4621 //
4449 // 3 = We have seen a new user enter within the past 4 minutes 4622 // 3 = Sim is up and one packet thread is running. Sim is
4623 // unstable and will not accept new logins
4624 //
4625 // 4 = Sim is up and both packet threads are running. Sim is
4626 // likely usable
4627 //
4628 // 5 = We have seen a new user enter within the past 4 minutes
4450 // which can be seen as positive confirmation of sim health 4629 // which can be seen as positive confirmation of sim health
4451 // 4630 //
4631
4632 flags = 0;
4633 message = String.Empty;
4634
4635 CheckHeartbeat();
4636
4637 if (m_firstHeartbeat || (m_lastIncoming == 0 && m_lastOutgoing == 0))
4638 {
4639 // We're still starting
4640 // 0 means "in startup", it can't happen another way, since
4641 // to get here, we must be able to accept http connections
4642 return 0;
4643 }
4644
4452 int health=1; // Start at 1, means we're up 4645 int health=1; // Start at 1, means we're up
4453 4646
4454 if ((Util.EnvironmentTickCountSubtract(m_lastUpdate)) < 1000) 4647 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) < 1000)
4648 {
4455 health+=1; 4649 health+=1;
4456 else 4650 flags |= 1;
4651 }
4652
4653 if (Util.EnvironmentTickCountSubtract(m_lastIncoming) < 1000)
4654 {
4655 health+=1;
4656 flags |= 2;
4657 }
4658
4659 if (Util.EnvironmentTickCountSubtract(m_lastOutgoing) < 1000)
4660 {
4661 health+=1;
4662 flags |= 4;
4663 }
4664
4665 if (flags != 7)
4457 return health; 4666 return health;
4458 4667
4459 // A login in the last 4 mins? We can't be doing too badly 4668 // A login in the last 4 mins? We can't be doing too badly
4460 // 4669 //
4461 if ((Util.EnvironmentTickCountSubtract(m_LastLogin)) < 240000) 4670 if (Util.EnvironmentTickCountSubtract(m_LastLogin) < 240000)
4462 health++; 4671 health++;
4463 else
4464 return health;
4465
4466 CheckHeartbeat();
4467 4672
4468 return health; 4673 return health;
4469 } 4674 }
@@ -4656,7 +4861,7 @@ namespace OpenSim.Region.Framework.Scenes
4656 if (m_firstHeartbeat) 4861 if (m_firstHeartbeat)
4657 return; 4862 return;
4658 4863
4659 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 2000) 4864 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 5000)
4660 StartTimer(); 4865 StartTimer();
4661 } 4866 }
4662 4867
@@ -5070,6 +5275,54 @@ namespace OpenSim.Region.Framework.Scenes
5070 } 5275 }
5071 } 5276 }
5072 5277
5278// public void CleanDroppedAttachments()
5279// {
5280// List<SceneObjectGroup> objectsToDelete =
5281// new List<SceneObjectGroup>();
5282//
5283// lock (m_cleaningAttachments)
5284// {
5285// ForEachSOG(delegate (SceneObjectGroup grp)
5286// {
5287// if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp)))
5288// {
5289// UUID agentID = grp.OwnerID;
5290// if (agentID == UUID.Zero)
5291// {
5292// objectsToDelete.Add(grp);
5293// return;
5294// }
5295//
5296// ScenePresence sp = GetScenePresence(agentID);
5297// if (sp == null)
5298// {
5299// objectsToDelete.Add(grp);
5300// return;
5301// }
5302// }
5303// });
5304// }
5305//
5306// foreach (SceneObjectGroup grp in objectsToDelete)
5307// {
5308// m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID);
5309// DeleteSceneObject(grp, true);
5310// }
5311// }
5312
5313 public void ThreadAlive(int threadCode)
5314 {
5315 switch(threadCode)
5316 {
5317 case 1: // Incoming
5318 m_lastIncoming = Util.EnvironmentTickCount();
5319 break;
5320 case 2: // Incoming
5321 m_lastOutgoing = Util.EnvironmentTickCount();
5322 break;
5323 }
5324 }
5325
5073 // This method is called across the simulation connector to 5326 // This method is called across the simulation connector to
5074 // determine if a given agent is allowed in this region 5327 // determine if a given agent is allowed in this region
5075 // AS A ROOT AGENT. Returning false here will prevent them 5328 // AS A ROOT AGENT. Returning false here will prevent them
@@ -5078,6 +5331,14 @@ namespace OpenSim.Region.Framework.Scenes
5078 // child agent creation, thereby emulating the SL behavior. 5331 // child agent creation, thereby emulating the SL behavior.
5079 public bool QueryAccess(UUID agentID, Vector3 position, out string reason) 5332 public bool QueryAccess(UUID agentID, Vector3 position, out string reason)
5080 { 5333 {
5334 reason = "You are banned from the region";
5335
5336 if (Permissions.IsGod(agentID))
5337 {
5338 reason = String.Empty;
5339 return true;
5340 }
5341
5081 int num = m_sceneGraph.GetNumberOfScenePresences(); 5342 int num = m_sceneGraph.GetNumberOfScenePresences();
5082 5343
5083 if (num >= RegionInfo.RegionSettings.AgentLimit) 5344 if (num >= RegionInfo.RegionSettings.AgentLimit)
@@ -5089,11 +5350,82 @@ namespace OpenSim.Region.Framework.Scenes
5089 } 5350 }
5090 } 5351 }
5091 5352
5353 ScenePresence presence = GetScenePresence(agentID);
5354 IClientAPI client = null;
5355 AgentCircuitData aCircuit = null;
5356
5357 if (presence != null)
5358 {
5359 client = presence.ControllingClient;
5360 if (client != null)
5361 aCircuit = client.RequestClientInfo();
5362 }
5363
5364 // We may be called before there is a presence or a client.
5365 // Fake AgentCircuitData to keep IAuthorizationModule smiling
5366 if (client == null)
5367 {
5368 aCircuit = new AgentCircuitData();
5369 aCircuit.AgentID = agentID;
5370 aCircuit.firstname = String.Empty;
5371 aCircuit.lastname = String.Empty;
5372 }
5373
5374 try
5375 {
5376 if (!AuthorizeUser(aCircuit, out reason))
5377 {
5378 // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID);
5379 return false;
5380 }
5381 }
5382 catch (Exception e)
5383 {
5384 m_log.DebugFormat("[SCENE]: Exception authorizing agent: {0} "+ e.StackTrace, e.Message);
5385 return false;
5386 }
5387
5388 if (position == Vector3.Zero) // Teleport
5389 {
5390 float posX = 128.0f;
5391 float posY = 128.0f;
5392
5393 if (!TestLandRestrictions(agentID, out reason, ref posX, ref posY))
5394 {
5395 // m_log.DebugFormat("[SCENE]: Denying {0} because they are banned on all parcels", agentID);
5396 return false;
5397 }
5398 }
5399 else // Walking
5400 {
5401 ILandObject land = LandChannel.GetLandObject(position.X, position.Y);
5402 if (land == null)
5403 return false;
5404
5405 bool banned = land.IsBannedFromLand(agentID);
5406 bool restricted = land.IsRestrictedFromLand(agentID);
5407
5408 if (banned || restricted)
5409 return false;
5410 }
5411
5092 reason = String.Empty; 5412 reason = String.Empty;
5093 return true; 5413 return true;
5094 } 5414 }
5095 5415
5096 /// <summary> 5416 public void StartTimerWatchdog()
5417 {
5418 m_timerWatchdog.Interval = 1000;
5419 m_timerWatchdog.Elapsed += TimerWatchdog;
5420 m_timerWatchdog.AutoReset = true;
5421 m_timerWatchdog.Start();
5422 }
5423
5424 public void TimerWatchdog(object sender, ElapsedEventArgs e)
5425 {
5426 CheckHeartbeat();
5427 }
5428
5097 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the 5429 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the
5098 /// autopilot that moves an avatar to a sit target!. 5430 /// autopilot that moves an avatar to a sit target!.
5099 /// </summary> 5431 /// </summary>