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 894d8d2..6a11353 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;
@@ -169,7 +172,7 @@ namespace OpenSim.Region.Framework.Scenes
169 private int m_update_events = 1; 172 private int m_update_events = 1;
170 private int m_update_backup = 200; 173 private int m_update_backup = 200;
171 private int m_update_terrain = 50; 174 private int m_update_terrain = 50;
172// private int m_update_land = 1; 175 private int m_update_land = 10;
173 private int m_update_coarse_locations = 50; 176 private int m_update_coarse_locations = 50;
174 177
175 private int agentMS; 178 private int agentMS;
@@ -184,6 +187,7 @@ namespace OpenSim.Region.Framework.Scenes
184 private int landMS; 187 private int landMS;
185 private int lastCompletedFrame; 188 private int lastCompletedFrame;
186 189
190 public bool CombineRegions = false;
187 /// <summary> 191 /// <summary>
188 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched 192 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched
189 /// asynchronously from the update loop. 193 /// asynchronously from the update loop.
@@ -206,10 +210,12 @@ namespace OpenSim.Region.Framework.Scenes
206 private bool m_scripts_enabled = true; 210 private bool m_scripts_enabled = true;
207 private string m_defaultScriptEngine; 211 private string m_defaultScriptEngine;
208 private int m_LastLogin; 212 private int m_LastLogin;
209 private Thread HeartbeatThread; 213 private Thread HeartbeatThread = null;
210 private volatile bool shuttingdown; 214 private volatile bool shuttingdown;
211 215
212 private int m_lastUpdate; 216 private int m_lastUpdate;
217 private int m_lastIncoming;
218 private int m_lastOutgoing;
213 private bool m_firstHeartbeat = true; 219 private bool m_firstHeartbeat = true;
214 220
215 private object m_deleting_scene_object = new object(); 221 private object m_deleting_scene_object = new object();
@@ -257,6 +263,19 @@ namespace OpenSim.Region.Framework.Scenes
257 get { return m_sceneGridService; } 263 get { return m_sceneGridService; }
258 } 264 }
259 265
266 public ISnmpModule SnmpService
267 {
268 get
269 {
270 if (m_snmpService == null)
271 {
272 m_snmpService = RequestModuleInterface<ISnmpModule>();
273 }
274
275 return m_snmpService;
276 }
277 }
278
260 public ISimulationDataService SimulationDataService 279 public ISimulationDataService SimulationDataService
261 { 280 {
262 get 281 get
@@ -549,6 +568,9 @@ namespace OpenSim.Region.Framework.Scenes
549 m_EstateDataService = estateDataService; 568 m_EstateDataService = estateDataService;
550 m_regionHandle = m_regInfo.RegionHandle; 569 m_regionHandle = m_regInfo.RegionHandle;
551 m_regionName = m_regInfo.RegionName; 570 m_regionName = m_regInfo.RegionName;
571 m_lastUpdate = Util.EnvironmentTickCount();
572 m_lastIncoming = 0;
573 m_lastOutgoing = 0;
552 574
553 m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this); 575 m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this);
554 m_asyncSceneObjectDeleter.Enabled = true; 576 m_asyncSceneObjectDeleter.Enabled = true;
@@ -670,11 +692,13 @@ namespace OpenSim.Region.Framework.Scenes
670 //Animation states 692 //Animation states
671 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); 693 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
672 // TODO: Change default to true once the feature is supported 694 // TODO: Change default to true once the feature is supported
673 m_usePreJump = startupConfig.GetBoolean("enableprejump", false); 695 m_usePreJump = startupConfig.GetBoolean("enableprejump", true);
674 696
675 m_physicalPrim = startupConfig.GetBoolean("physical_prim", true); 697 m_physicalPrim = startupConfig.GetBoolean("physical_prim", true);
676 698
677 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys); 699 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
700
701 m_log.DebugFormat("[SCENE]: prejump is {0}", m_usePreJump ? "ON" : "OFF");
678 if (RegionInfo.NonphysPrimMax > 0) 702 if (RegionInfo.NonphysPrimMax > 0)
679 { 703 {
680 m_maxNonphys = RegionInfo.NonphysPrimMax; 704 m_maxNonphys = RegionInfo.NonphysPrimMax;
@@ -707,6 +731,7 @@ namespace OpenSim.Region.Framework.Scenes
707 m_persistAfter *= 10000000; 731 m_persistAfter *= 10000000;
708 732
709 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); 733 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
734 m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine);
710 735
711 IConfig packetConfig = m_config.Configs["PacketPool"]; 736 IConfig packetConfig = m_config.Configs["PacketPool"];
712 if (packetConfig != null) 737 if (packetConfig != null)
@@ -716,6 +741,8 @@ namespace OpenSim.Region.Framework.Scenes
716 } 741 }
717 742
718 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); 743 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
744 m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion);
745 CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false);
719 746
720 m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true); 747 m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true);
721 if (m_generateMaptiles) 748 if (m_generateMaptiles)
@@ -751,9 +778,9 @@ namespace OpenSim.Region.Framework.Scenes
751 m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain); 778 m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain);
752 m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning); 779 m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning);
753 } 780 }
754 catch 781 catch (Exception e)
755 { 782 {
756 m_log.Warn("[SCENE]: Failed to load StartupConfig"); 783 m_log.Error("[SCENE]: Failed to load StartupConfig: " + e.ToString());
757 } 784 }
758 785
759 #endregion Region Config 786 #endregion Region Config
@@ -1174,7 +1201,9 @@ namespace OpenSim.Region.Framework.Scenes
1174 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); 1201 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
1175 if (HeartbeatThread != null) 1202 if (HeartbeatThread != null)
1176 { 1203 {
1204 m_log.ErrorFormat("[SCENE]: Restarting heartbeat thread because it hasn't reported in in region {0}", RegionInfo.RegionName);
1177 HeartbeatThread.Abort(); 1205 HeartbeatThread.Abort();
1206 Watchdog.RemoveThread(HeartbeatThread.ManagedThreadId);
1178 HeartbeatThread = null; 1207 HeartbeatThread = null;
1179 } 1208 }
1180 m_lastUpdate = Util.EnvironmentTickCount(); 1209 m_lastUpdate = Util.EnvironmentTickCount();
@@ -1217,9 +1246,6 @@ namespace OpenSim.Region.Framework.Scenes
1217 { 1246 {
1218 while (!shuttingdown) 1247 while (!shuttingdown)
1219 Update(); 1248 Update();
1220
1221 m_lastUpdate = Util.EnvironmentTickCount();
1222 m_firstHeartbeat = false;
1223 } 1249 }
1224 catch (ThreadAbortException) 1250 catch (ThreadAbortException)
1225 { 1251 {
@@ -1319,6 +1345,13 @@ namespace OpenSim.Region.Framework.Scenes
1319 eventMS = Util.EnvironmentTickCountSubtract(evMS); ; 1345 eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
1320 } 1346 }
1321 1347
1348 // if (Frame % m_update_land == 0)
1349 // {
1350 // int ldMS = Util.EnvironmentTickCount();
1351 // UpdateLand();
1352 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1353 // }
1354
1322 if (Frame % m_update_backup == 0) 1355 if (Frame % m_update_backup == 0)
1323 { 1356 {
1324 int backMS = Util.EnvironmentTickCount(); 1357 int backMS = Util.EnvironmentTickCount();
@@ -1420,12 +1453,16 @@ namespace OpenSim.Region.Framework.Scenes
1420 maintc = Util.EnvironmentTickCountSubtract(maintc); 1453 maintc = Util.EnvironmentTickCountSubtract(maintc);
1421 maintc = (int)(MinFrameTime * 1000) - maintc; 1454 maintc = (int)(MinFrameTime * 1000) - maintc;
1422 1455
1456
1457 m_lastUpdate = Util.EnvironmentTickCount();
1458 m_firstHeartbeat = false;
1459
1423 if (maintc > 0) 1460 if (maintc > 0)
1424 Thread.Sleep(maintc); 1461 Thread.Sleep(maintc);
1425 1462
1426 // Tell the watchdog that this thread is still alive 1463 // Tell the watchdog that this thread is still alive
1427 Watchdog.UpdateThread(); 1464 Watchdog.UpdateThread();
1428 } 1465 }
1429 1466
1430 public void AddGroupTarget(SceneObjectGroup grp) 1467 public void AddGroupTarget(SceneObjectGroup grp)
1431 { 1468 {
@@ -1441,9 +1478,9 @@ namespace OpenSim.Region.Framework.Scenes
1441 1478
1442 private void CheckAtTargets() 1479 private void CheckAtTargets()
1443 { 1480 {
1444 Dictionary<UUID, SceneObjectGroup>.ValueCollection objs; 1481 List<SceneObjectGroup> objs = new List<SceneObjectGroup>();
1445 lock (m_groupsWithTargets) 1482 lock (m_groupsWithTargets)
1446 objs = m_groupsWithTargets.Values; 1483 objs = new List<SceneObjectGroup>(m_groupsWithTargets.Values);
1447 1484
1448 foreach (SceneObjectGroup entry in objs) 1485 foreach (SceneObjectGroup entry in objs)
1449 entry.checkAtTargets(); 1486 entry.checkAtTargets();
@@ -1763,14 +1800,24 @@ namespace OpenSim.Region.Framework.Scenes
1763 /// <returns></returns> 1800 /// <returns></returns>
1764 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter) 1801 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter)
1765 { 1802 {
1803
1804 float wheight = (float)RegionInfo.RegionSettings.WaterHeight;
1805 Vector3 wpos = Vector3.Zero;
1806 // Check for water surface intersection from above
1807 if ( (RayStart.Z > wheight) && (RayEnd.Z < wheight) )
1808 {
1809 float ratio = (RayStart.Z - wheight) / (RayStart.Z - RayEnd.Z);
1810 wpos.X = RayStart.X - (ratio * (RayStart.X - RayEnd.X));
1811 wpos.Y = RayStart.Y - (ratio * (RayStart.Y - RayEnd.Y));
1812 wpos.Z = wheight;
1813 }
1814
1766 Vector3 pos = Vector3.Zero; 1815 Vector3 pos = Vector3.Zero;
1767 if (RayEndIsIntersection == (byte)1) 1816 if (RayEndIsIntersection == (byte)1)
1768 { 1817 {
1769 pos = RayEnd; 1818 pos = RayEnd;
1770 return pos;
1771 } 1819 }
1772 1820 else if (RayTargetID != UUID.Zero)
1773 if (RayTargetID != UUID.Zero)
1774 { 1821 {
1775 SceneObjectPart target = GetSceneObjectPart(RayTargetID); 1822 SceneObjectPart target = GetSceneObjectPart(RayTargetID);
1776 1823
@@ -1792,7 +1839,7 @@ namespace OpenSim.Region.Framework.Scenes
1792 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter); 1839 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter);
1793 1840
1794 // Un-comment out the following line to Get Raytrace results printed to the console. 1841 // Un-comment out the following line to Get Raytrace results printed to the console.
1795 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); 1842 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
1796 float ScaleOffset = 0.5f; 1843 float ScaleOffset = 0.5f;
1797 1844
1798 // If we hit something 1845 // If we hit something
@@ -1815,13 +1862,10 @@ namespace OpenSim.Region.Framework.Scenes
1815 //pos.Z -= 0.25F; 1862 //pos.Z -= 0.25F;
1816 1863
1817 } 1864 }
1818
1819 return pos;
1820 } 1865 }
1821 else 1866 else
1822 { 1867 {
1823 // We don't have a target here, so we're going to raytrace all the objects in the scene. 1868 // We don't have a target here, so we're going to raytrace all the objects in the scene.
1824
1825 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false); 1869 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false);
1826 1870
1827 // Un-comment the following line to print the raytrace results to the console. 1871 // Un-comment the following line to print the raytrace results to the console.
@@ -1830,13 +1874,12 @@ namespace OpenSim.Region.Framework.Scenes
1830 if (ei.HitTF) 1874 if (ei.HitTF)
1831 { 1875 {
1832 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); 1876 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
1833 } else 1877 }
1878 else
1834 { 1879 {
1835 // fall back to our stupid functionality 1880 // fall back to our stupid functionality
1836 pos = RayEnd; 1881 pos = RayEnd;
1837 } 1882 }
1838
1839 return pos;
1840 } 1883 }
1841 } 1884 }
1842 else 1885 else
@@ -1847,8 +1890,12 @@ namespace OpenSim.Region.Framework.Scenes
1847 //increase height so its above the ground. 1890 //increase height so its above the ground.
1848 //should be getting the normal of the ground at the rez point and using that? 1891 //should be getting the normal of the ground at the rez point and using that?
1849 pos.Z += scale.Z / 2f; 1892 pos.Z += scale.Z / 2f;
1850 return pos; 1893// return pos;
1851 } 1894 }
1895
1896 // check against posible water intercept
1897 if (wpos.Z > pos.Z) pos = wpos;
1898 return pos;
1852 } 1899 }
1853 1900
1854 1901
@@ -1932,7 +1979,10 @@ namespace OpenSim.Region.Framework.Scenes
1932 public bool AddRestoredSceneObject( 1979 public bool AddRestoredSceneObject(
1933 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 1980 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
1934 { 1981 {
1935 return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); 1982 bool result = m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates);
1983 if (result)
1984 sceneObject.IsDeleted = false;
1985 return result;
1936 } 1986 }
1937 1987
1938 /// <summary> 1988 /// <summary>
@@ -2022,6 +2072,15 @@ namespace OpenSim.Region.Framework.Scenes
2022 /// </summary> 2072 /// </summary>
2023 public void DeleteAllSceneObjects() 2073 public void DeleteAllSceneObjects()
2024 { 2074 {
2075 DeleteAllSceneObjects(false);
2076 }
2077
2078 /// <summary>
2079 /// Delete every object from the scene. This does not include attachments worn by avatars.
2080 /// </summary>
2081 public void DeleteAllSceneObjects(bool exceptNoCopy)
2082 {
2083 List<SceneObjectGroup> toReturn = new List<SceneObjectGroup>();
2025 lock (Entities) 2084 lock (Entities)
2026 { 2085 {
2027 EntityBase[] entities = Entities.GetEntities(); 2086 EntityBase[] entities = Entities.GetEntities();
@@ -2030,11 +2089,24 @@ namespace OpenSim.Region.Framework.Scenes
2030 if (e is SceneObjectGroup) 2089 if (e is SceneObjectGroup)
2031 { 2090 {
2032 SceneObjectGroup sog = (SceneObjectGroup)e; 2091 SceneObjectGroup sog = (SceneObjectGroup)e;
2033 if (!sog.IsAttachment) 2092 if (sog != null && !sog.IsAttachment)
2034 DeleteSceneObject((SceneObjectGroup)e, false); 2093 {
2094 if (!exceptNoCopy || ((sog.GetEffectivePermissions() & (uint)PermissionMask.Copy) != 0))
2095 {
2096 DeleteSceneObject((SceneObjectGroup)e, false);
2097 }
2098 else
2099 {
2100 toReturn.Add((SceneObjectGroup)e);
2101 }
2102 }
2035 } 2103 }
2036 } 2104 }
2037 } 2105 }
2106 if (toReturn.Count > 0)
2107 {
2108 returnObjects(toReturn.ToArray(), UUID.Zero);
2109 }
2038 } 2110 }
2039 2111
2040 /// <summary> 2112 /// <summary>
@@ -2082,6 +2154,8 @@ namespace OpenSim.Region.Framework.Scenes
2082 } 2154 }
2083 2155
2084 group.DeleteGroupFromScene(silent); 2156 group.DeleteGroupFromScene(silent);
2157 if (!silent)
2158 SendKillObject(new List<uint>() { group.LocalId });
2085 2159
2086// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); 2160// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
2087 } 2161 }
@@ -2436,10 +2510,17 @@ namespace OpenSim.Region.Framework.Scenes
2436 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns> 2510 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns>
2437 public bool AddSceneObject(SceneObjectGroup sceneObject) 2511 public bool AddSceneObject(SceneObjectGroup sceneObject)
2438 { 2512 {
2513 if (sceneObject.OwnerID == UUID.Zero)
2514 {
2515 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero", sceneObject.UUID);
2516 return false;
2517 }
2518
2439 // If the user is banned, we won't let any of their objects 2519 // If the user is banned, we won't let any of their objects
2440 // enter. Period. 2520 // enter. Period.
2441 // 2521 //
2442 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID)) 2522 int flags = GetUserFlags(sceneObject.OwnerID);
2523 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID, flags))
2443 { 2524 {
2444 m_log.Info("[INTERREGION]: Denied prim crossing for " + 2525 m_log.Info("[INTERREGION]: Denied prim crossing for " +
2445 "banned avatar"); 2526 "banned avatar");
@@ -2486,12 +2567,23 @@ namespace OpenSim.Region.Framework.Scenes
2486 } 2567 }
2487 else 2568 else
2488 { 2569 {
2570 m_log.DebugFormat("[SCENE]: Attachment {0} arrived and scene presence was not found, setting to temp", sceneObject.UUID);
2489 RootPrim.RemFlag(PrimFlags.TemporaryOnRez); 2571 RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
2490 RootPrim.AddFlag(PrimFlags.TemporaryOnRez); 2572 RootPrim.AddFlag(PrimFlags.TemporaryOnRez);
2491 } 2573 }
2574 if (sceneObject.OwnerID == UUID.Zero)
2575 {
2576 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero after attachment processing. BUG!", sceneObject.UUID);
2577 return false;
2578 }
2492 } 2579 }
2493 else 2580 else
2494 { 2581 {
2582 if (sceneObject.OwnerID == UUID.Zero)
2583 {
2584 m_log.ErrorFormat("[SCENE]: Owner ID for non-attachment {0} was zero", sceneObject.UUID);
2585 return false;
2586 }
2495 AddRestoredSceneObject(sceneObject, true, false); 2587 AddRestoredSceneObject(sceneObject, true, false);
2496 2588
2497 if (!Permissions.CanObjectEntry(sceneObject.UUID, 2589 if (!Permissions.CanObjectEntry(sceneObject.UUID,
@@ -2521,6 +2613,24 @@ namespace OpenSim.Region.Framework.Scenes
2521 return 2; // StateSource.PrimCrossing 2613 return 2; // StateSource.PrimCrossing
2522 } 2614 }
2523 2615
2616 public int GetUserFlags(UUID user)
2617 {
2618 //Unfortunately the SP approach means that the value is cached until region is restarted
2619 /*
2620 ScenePresence sp;
2621 if (TryGetScenePresence(user, out sp))
2622 {
2623 return sp.UserFlags;
2624 }
2625 else
2626 {
2627 */
2628 UserAccount uac = UserAccountService.GetUserAccount(RegionInfo.ScopeID, user);
2629 if (uac == null)
2630 return 0;
2631 return uac.UserFlags;
2632 //}
2633 }
2524 #endregion 2634 #endregion
2525 2635
2526 #region Add/Remove Avatar Methods 2636 #region Add/Remove Avatar Methods
@@ -2542,6 +2652,7 @@ namespace OpenSim.Region.Framework.Scenes
2542 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2652 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2543 2653
2544 CheckHeartbeat(); 2654 CheckHeartbeat();
2655 ScenePresence presence;
2545 2656
2546 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here 2657 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here
2547 { 2658 {
@@ -2575,7 +2686,14 @@ namespace OpenSim.Region.Framework.Scenes
2575 2686
2576 EventManager.TriggerOnNewClient(client); 2687 EventManager.TriggerOnNewClient(client);
2577 if (vialogin) 2688 if (vialogin)
2689 {
2578 EventManager.TriggerOnClientLogin(client); 2690 EventManager.TriggerOnClientLogin(client);
2691
2692 // Send initial parcel data
2693 Vector3 pos = createdSp.AbsolutePosition;
2694 ILandObject land = LandChannel.GetLandObject(pos.X, pos.Y);
2695 land.SendLandUpdateToClient(client);
2696 }
2579 } 2697 }
2580 } 2698 }
2581 2699
@@ -2664,19 +2782,12 @@ namespace OpenSim.Region.Framework.Scenes
2664 // and the scene presence and the client, if they exist 2782 // and the scene presence and the client, if they exist
2665 try 2783 try
2666 { 2784 {
2667 // We need to wait for the client to make UDP contact first. 2785 ScenePresence sp = GetScenePresence(agentID);
2668 // It's the UDP contact that creates the scene presence 2786 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2669 ScenePresence sp = WaitGetScenePresence(agentID); 2787
2670 if (sp != null) 2788 if (sp != null)
2671 {
2672 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2673
2674 sp.ControllingClient.Close(); 2789 sp.ControllingClient.Close();
2675 } 2790
2676 else
2677 {
2678 m_log.WarnFormat("[SCENE]: Could not find scene presence for {0}", agentID);
2679 }
2680 // BANG! SLASH! 2791 // BANG! SLASH!
2681 m_authenticateHandler.RemoveCircuit(agentID); 2792 m_authenticateHandler.RemoveCircuit(agentID);
2682 2793
@@ -2776,6 +2887,7 @@ namespace OpenSim.Region.Framework.Scenes
2776 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory; 2887 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory;
2777 client.OnUpdateInventoryItem += UpdateInventoryItemAsset; 2888 client.OnUpdateInventoryItem += UpdateInventoryItemAsset;
2778 client.OnCopyInventoryItem += CopyInventoryItem; 2889 client.OnCopyInventoryItem += CopyInventoryItem;
2890 client.OnMoveItemsAndLeaveCopy += MoveInventoryItemsLeaveCopy;
2779 client.OnMoveInventoryItem += MoveInventoryItem; 2891 client.OnMoveInventoryItem += MoveInventoryItem;
2780 client.OnRemoveInventoryItem += RemoveInventoryItem; 2892 client.OnRemoveInventoryItem += RemoveInventoryItem;
2781 client.OnRemoveInventoryFolder += RemoveInventoryFolder; 2893 client.OnRemoveInventoryFolder += RemoveInventoryFolder;
@@ -2953,15 +3065,16 @@ namespace OpenSim.Region.Framework.Scenes
2953 /// </summary> 3065 /// </summary>
2954 /// <param name="agentId">The avatar's Unique ID</param> 3066 /// <param name="agentId">The avatar's Unique ID</param>
2955 /// <param name="client">The IClientAPI for the client</param> 3067 /// <param name="client">The IClientAPI for the client</param>
2956 public virtual void TeleportClientHome(UUID agentId, IClientAPI client) 3068 public virtual bool TeleportClientHome(UUID agentId, IClientAPI client)
2957 { 3069 {
2958 if (m_teleportModule != null) 3070 if (m_teleportModule != null)
2959 m_teleportModule.TeleportHome(agentId, client); 3071 return m_teleportModule.TeleportHome(agentId, client);
2960 else 3072 else
2961 { 3073 {
2962 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active"); 3074 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active");
2963 client.SendTeleportFailed("Unable to perform teleports on this simulator."); 3075 client.SendTeleportFailed("Unable to perform teleports on this simulator.");
2964 } 3076 }
3077 return false;
2965 } 3078 }
2966 3079
2967 /// <summary> 3080 /// <summary>
@@ -3053,6 +3166,16 @@ namespace OpenSim.Region.Framework.Scenes
3053 /// <param name="flags"></param> 3166 /// <param name="flags"></param>
3054 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags) 3167 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags)
3055 { 3168 {
3169 //Add half the avatar's height so that the user doesn't fall through prims
3170 ScenePresence presence;
3171 if (TryGetScenePresence(remoteClient.AgentId, out presence))
3172 {
3173 if (presence.Appearance != null)
3174 {
3175 position.Z = position.Z + (presence.Appearance.AvatarHeight / 2);
3176 }
3177 }
3178
3056 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt)) 3179 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt))
3057 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot. 3180 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot.
3058 m_dialogModule.SendAlertToUser(remoteClient, "Home position set."); 3181 m_dialogModule.SendAlertToUser(remoteClient, "Home position set.");
@@ -3121,8 +3244,9 @@ namespace OpenSim.Region.Framework.Scenes
3121 regions.Remove(RegionInfo.RegionHandle); 3244 regions.Remove(RegionInfo.RegionHandle);
3122 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3245 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3123 } 3246 }
3124 3247 m_log.Debug("[Scene] Beginning ClientClosed");
3125 m_eventManager.TriggerClientClosed(agentID, this); 3248 m_eventManager.TriggerClientClosed(agentID, this);
3249 m_log.Debug("[Scene] Finished ClientClosed");
3126 } 3250 }
3127 catch (NullReferenceException) 3251 catch (NullReferenceException)
3128 { 3252 {
@@ -3130,7 +3254,12 @@ namespace OpenSim.Region.Framework.Scenes
3130 // Avatar is already disposed :/ 3254 // Avatar is already disposed :/
3131 } 3255 }
3132 3256
3257 m_log.Debug("[Scene] Beginning OnRemovePresence");
3133 m_eventManager.TriggerOnRemovePresence(agentID); 3258 m_eventManager.TriggerOnRemovePresence(agentID);
3259 m_log.Debug("[Scene] Finished OnRemovePresence");
3260
3261 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3262 AttachmentsModule.SaveChangedAttachments(avatar);
3134 3263
3135 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc) 3264 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3136 AttachmentsModule.SaveChangedAttachments(avatar); 3265 AttachmentsModule.SaveChangedAttachments(avatar);
@@ -3139,7 +3268,7 @@ namespace OpenSim.Region.Framework.Scenes
3139 delegate(IClientAPI client) 3268 delegate(IClientAPI client)
3140 { 3269 {
3141 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3270 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3142 try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); } 3271 try { client.SendKillObject(avatar.RegionHandle, new List<uint>() { avatar.LocalId}); }
3143 catch (NullReferenceException) { } 3272 catch (NullReferenceException) { }
3144 }); 3273 });
3145 3274
@@ -3150,8 +3279,11 @@ namespace OpenSim.Region.Framework.Scenes
3150 } 3279 }
3151 3280
3152 // Remove the avatar from the scene 3281 // Remove the avatar from the scene
3282 m_log.Debug("[Scene] Begin RemoveScenePresence");
3153 m_sceneGraph.RemoveScenePresence(agentID); 3283 m_sceneGraph.RemoveScenePresence(agentID);
3284 m_log.Debug("[Scene] Finished RemoveScenePresence. Removing the client manager");
3154 m_clientManager.Remove(agentID); 3285 m_clientManager.Remove(agentID);
3286 m_log.Debug("[Scene] Removed the client manager. Firing avatar.close");
3155 3287
3156 try 3288 try
3157 { 3289 {
@@ -3165,9 +3297,10 @@ namespace OpenSim.Region.Framework.Scenes
3165 { 3297 {
3166 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString()); 3298 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString());
3167 } 3299 }
3168 3300 m_log.Debug("[Scene] Done. Firing RemoveCircuit");
3169 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3301 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
3170// CleanDroppedAttachments(); 3302// CleanDroppedAttachments();
3303 m_log.Debug("[Scene] The avatar has left the building");
3171 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 3304 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
3172 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); 3305 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
3173 } 3306 }
@@ -3198,19 +3331,24 @@ namespace OpenSim.Region.Framework.Scenes
3198 3331
3199 #region Entities 3332 #region Entities
3200 3333
3201 public void SendKillObject(uint localID) 3334 public void SendKillObject(List<uint> localIDs)
3202 { 3335 {
3203 SceneObjectPart part = GetSceneObjectPart(localID); 3336 List<uint> deleteIDs = new List<uint>();
3204 if (part != null) // It is a prim 3337
3338 foreach (uint localID in localIDs)
3205 { 3339 {
3206 if (!part.ParentGroup.IsDeleted) // Valid 3340 SceneObjectPart part = GetSceneObjectPart(localID);
3341 if (part != null) // It is a prim
3207 { 3342 {
3208 if (part.ParentGroup.RootPart != part) // Child part 3343 if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid
3209 return; 3344 {
3345 if (part.ParentGroup.RootPart != part) // Child part
3346 continue;
3347 }
3210 } 3348 }
3349 deleteIDs.Add(localID);
3211 } 3350 }
3212 3351 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, deleteIDs); });
3213 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); });
3214 } 3352 }
3215 3353
3216 #endregion 3354 #endregion
@@ -3228,7 +3366,6 @@ namespace OpenSim.Region.Framework.Scenes
3228 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate; 3366 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
3229 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar; 3367 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar;
3230 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid; 3368 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
3231 m_sceneGridService.KiPrimitive += SendKillObject;
3232 m_sceneGridService.OnGetLandData += GetLandData; 3369 m_sceneGridService.OnGetLandData += GetLandData;
3233 } 3370 }
3234 3371
@@ -3237,7 +3374,6 @@ namespace OpenSim.Region.Framework.Scenes
3237 /// </summary> 3374 /// </summary>
3238 public void UnRegisterRegionWithComms() 3375 public void UnRegisterRegionWithComms()
3239 { 3376 {
3240 m_sceneGridService.KiPrimitive -= SendKillObject;
3241 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid; 3377 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid;
3242 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar; 3378 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar;
3243 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate; 3379 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate;
@@ -3317,13 +3453,16 @@ namespace OpenSim.Region.Framework.Scenes
3317 sp = null; 3453 sp = null;
3318 } 3454 }
3319 3455
3320 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3321 3456
3322 //On login test land permisions 3457 //On login test land permisions
3323 if (vialogin) 3458 if (vialogin)
3324 { 3459 {
3325 if (land != null && !TestLandRestrictions(agent, land, out reason)) 3460 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
3461 if (cache != null)
3462 cache.Remove(agent.firstname + " " + agent.lastname);
3463 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3326 { 3464 {
3465 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString());
3327 return false; 3466 return false;
3328 } 3467 }
3329 } 3468 }
@@ -3346,8 +3485,13 @@ namespace OpenSim.Region.Framework.Scenes
3346 3485
3347 try 3486 try
3348 { 3487 {
3349 if (!AuthorizeUser(agent, out reason)) 3488 // Always check estate if this is a login. Always
3350 return false; 3489 // check if banned regions are to be blacked out.
3490 if (vialogin || (!m_seeIntoBannedRegion))
3491 {
3492 if (!AuthorizeUser(agent, out reason))
3493 return false;
3494 }
3351 } 3495 }
3352 catch (Exception e) 3496 catch (Exception e)
3353 { 3497 {
@@ -3449,6 +3593,8 @@ namespace OpenSim.Region.Framework.Scenes
3449 } 3593 }
3450 } 3594 }
3451 // Honor parcel landing type and position. 3595 // Honor parcel landing type and position.
3596 /*
3597 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3452 if (land != null) 3598 if (land != null)
3453 { 3599 {
3454 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) 3600 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero)
@@ -3456,26 +3602,34 @@ namespace OpenSim.Region.Framework.Scenes
3456 agent.startpos = land.LandData.UserLocation; 3602 agent.startpos = land.LandData.UserLocation;
3457 } 3603 }
3458 } 3604 }
3605 */// This is now handled properly in ScenePresence.MakeRootAgent
3459 } 3606 }
3460 3607
3461 return true; 3608 return true;
3462 } 3609 }
3463 3610
3464 private bool TestLandRestrictions(AgentCircuitData agent, ILandObject land, out string reason) 3611 private bool TestLandRestrictions(UUID agentID, out string reason, ref float posX, ref float posY)
3465 { 3612 {
3466 3613 reason = String.Empty;
3467 bool banned = land.IsBannedFromLand(agent.AgentID); 3614 if (Permissions.IsGod(agentID))
3468 bool restricted = land.IsRestrictedFromLand(agent.AgentID); 3615 return true;
3616
3617 ILandObject land = LandChannel.GetLandObject(posX, posY);
3618 if (land == null)
3619 return false;
3620
3621 bool banned = land.IsBannedFromLand(agentID);
3622 bool restricted = land.IsRestrictedFromLand(agentID);
3469 3623
3470 if (banned || restricted) 3624 if (banned || restricted)
3471 { 3625 {
3472 ILandObject nearestParcel = GetNearestAllowedParcel(agent.AgentID, agent.startpos.X, agent.startpos.Y); 3626 ILandObject nearestParcel = GetNearestAllowedParcel(agentID, posX, posY);
3473 if (nearestParcel != null) 3627 if (nearestParcel != null)
3474 { 3628 {
3475 //Move agent to nearest allowed 3629 //Move agent to nearest allowed
3476 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel); 3630 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel);
3477 agent.startpos.X = newPosition.X; 3631 posX = newPosition.X;
3478 agent.startpos.Y = newPosition.Y; 3632 posY = newPosition.Y;
3479 } 3633 }
3480 else 3634 else
3481 { 3635 {
@@ -3537,7 +3691,7 @@ namespace OpenSim.Region.Framework.Scenes
3537 3691
3538 if (!m_strictAccessControl) return true; 3692 if (!m_strictAccessControl) return true;
3539 if (Permissions.IsGod(agent.AgentID)) return true; 3693 if (Permissions.IsGod(agent.AgentID)) return true;
3540 3694
3541 if (AuthorizationService != null) 3695 if (AuthorizationService != null)
3542 { 3696 {
3543 if (!AuthorizationService.IsAuthorizedForRegion( 3697 if (!AuthorizationService.IsAuthorizedForRegion(
@@ -3545,14 +3699,14 @@ namespace OpenSim.Region.Framework.Scenes
3545 { 3699 {
3546 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region", 3700 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region",
3547 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3701 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
3548 3702
3549 return false; 3703 return false;
3550 } 3704 }
3551 } 3705 }
3552 3706
3553 if (m_regInfo.EstateSettings != null) 3707 if (m_regInfo.EstateSettings != null)
3554 { 3708 {
3555 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID)) 3709 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID,0))
3556 { 3710 {
3557 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", 3711 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
3558 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3712 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
@@ -3742,6 +3896,13 @@ namespace OpenSim.Region.Framework.Scenes
3742 3896
3743 // We have to wait until the viewer contacts this region after receiving EAC. 3897 // We have to wait until the viewer contacts this region after receiving EAC.
3744 // That calls AddNewClient, which finally creates the ScenePresence 3898 // That calls AddNewClient, which finally creates the ScenePresence
3899 int flags = GetUserFlags(cAgentData.AgentID);
3900 if (m_regInfo.EstateSettings.IsBanned(cAgentData.AgentID, flags))
3901 {
3902 m_log.DebugFormat("[SCENE]: Denying root agent entry to {0}: banned", cAgentData.AgentID);
3903 return false;
3904 }
3905
3745 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); 3906 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2);
3746 if (nearestParcel == null) 3907 if (nearestParcel == null)
3747 { 3908 {
@@ -3757,7 +3918,6 @@ namespace OpenSim.Region.Framework.Scenes
3757 return false; 3918 return false;
3758 } 3919 }
3759 3920
3760
3761 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 3921 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
3762 3922
3763 if (childAgentUpdate != null) 3923 if (childAgentUpdate != null)
@@ -3824,12 +3984,22 @@ namespace OpenSim.Region.Framework.Scenes
3824 return false; 3984 return false;
3825 } 3985 }
3826 3986
3987 public bool IncomingCloseAgent(UUID agentID)
3988 {
3989 return IncomingCloseAgent(agentID, false);
3990 }
3991
3992 public bool IncomingCloseChildAgent(UUID agentID)
3993 {
3994 return IncomingCloseAgent(agentID, true);
3995 }
3996
3827 /// <summary> 3997 /// <summary>
3828 /// Tell a single agent to disconnect from the region. 3998 /// Tell a single agent to disconnect from the region.
3829 /// </summary> 3999 /// </summary>
3830 /// <param name="regionHandle"></param>
3831 /// <param name="agentID"></param> 4000 /// <param name="agentID"></param>
3832 public bool IncomingCloseAgent(UUID agentID) 4001 /// <param name="childOnly"></param>
4002 public bool IncomingCloseAgent(UUID agentID, bool childOnly)
3833 { 4003 {
3834 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 4004 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
3835 4005
@@ -3841,7 +4011,7 @@ namespace OpenSim.Region.Framework.Scenes
3841 { 4011 {
3842 m_sceneGraph.removeUserCount(false); 4012 m_sceneGraph.removeUserCount(false);
3843 } 4013 }
3844 else 4014 else if (!childOnly)
3845 { 4015 {
3846 m_sceneGraph.removeUserCount(true); 4016 m_sceneGraph.removeUserCount(true);
3847 } 4017 }
@@ -3857,9 +4027,12 @@ namespace OpenSim.Region.Framework.Scenes
3857 } 4027 }
3858 else 4028 else
3859 presence.ControllingClient.SendShutdownConnectionNotice(); 4029 presence.ControllingClient.SendShutdownConnectionNotice();
4030 presence.ControllingClient.Close(false);
4031 }
4032 else if (!childOnly)
4033 {
4034 presence.ControllingClient.Close(true);
3860 } 4035 }
3861
3862 presence.ControllingClient.Close();
3863 return true; 4036 return true;
3864 } 4037 }
3865 4038
@@ -4474,34 +4647,66 @@ namespace OpenSim.Region.Framework.Scenes
4474 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID); 4647 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID);
4475 } 4648 }
4476 4649
4477 public int GetHealth() 4650 public int GetHealth(out int flags, out string message)
4478 { 4651 {
4479 // Returns: 4652 // Returns:
4480 // 1 = sim is up and accepting http requests. The heartbeat has 4653 // 1 = sim is up and accepting http requests. The heartbeat has
4481 // stopped and the sim is probably locked up, but a remote 4654 // stopped and the sim is probably locked up, but a remote
4482 // admin restart may succeed 4655 // admin restart may succeed
4483 // 4656 //
4484 // 2 = Sim is up and the heartbeat is running. The sim is likely 4657 // 2 = Sim is up and the heartbeat is running. The sim is likely
4485 // usable for people within and logins _may_ work 4658 // usable for people within
4486 // 4659 //
4487 // 3 = We have seen a new user enter within the past 4 minutes 4660 // 3 = Sim is up and one packet thread is running. Sim is
4661 // unstable and will not accept new logins
4662 //
4663 // 4 = Sim is up and both packet threads are running. Sim is
4664 // likely usable
4665 //
4666 // 5 = We have seen a new user enter within the past 4 minutes
4488 // which can be seen as positive confirmation of sim health 4667 // which can be seen as positive confirmation of sim health
4489 // 4668 //
4669
4670 flags = 0;
4671 message = String.Empty;
4672
4673 CheckHeartbeat();
4674
4675 if (m_firstHeartbeat || (m_lastIncoming == 0 && m_lastOutgoing == 0))
4676 {
4677 // We're still starting
4678 // 0 means "in startup", it can't happen another way, since
4679 // to get here, we must be able to accept http connections
4680 return 0;
4681 }
4682
4490 int health=1; // Start at 1, means we're up 4683 int health=1; // Start at 1, means we're up
4491 4684
4492 if ((Util.EnvironmentTickCountSubtract(m_lastUpdate)) < 1000) 4685 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) < 1000)
4686 {
4493 health+=1; 4687 health+=1;
4494 else 4688 flags |= 1;
4689 }
4690
4691 if (Util.EnvironmentTickCountSubtract(m_lastIncoming) < 1000)
4692 {
4693 health+=1;
4694 flags |= 2;
4695 }
4696
4697 if (Util.EnvironmentTickCountSubtract(m_lastOutgoing) < 1000)
4698 {
4699 health+=1;
4700 flags |= 4;
4701 }
4702
4703 if (flags != 7)
4495 return health; 4704 return health;
4496 4705
4497 // A login in the last 4 mins? We can't be doing too badly 4706 // A login in the last 4 mins? We can't be doing too badly
4498 // 4707 //
4499 if ((Util.EnvironmentTickCountSubtract(m_LastLogin)) < 240000) 4708 if (Util.EnvironmentTickCountSubtract(m_LastLogin) < 240000)
4500 health++; 4709 health++;
4501 else
4502 return health;
4503
4504 CheckHeartbeat();
4505 4710
4506 return health; 4711 return health;
4507 } 4712 }
@@ -4694,7 +4899,7 @@ namespace OpenSim.Region.Framework.Scenes
4694 if (m_firstHeartbeat) 4899 if (m_firstHeartbeat)
4695 return; 4900 return;
4696 4901
4697 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 2000) 4902 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 5000)
4698 StartTimer(); 4903 StartTimer();
4699 } 4904 }
4700 4905
@@ -5108,6 +5313,54 @@ namespace OpenSim.Region.Framework.Scenes
5108 } 5313 }
5109 } 5314 }
5110 5315
5316// public void CleanDroppedAttachments()
5317// {
5318// List<SceneObjectGroup> objectsToDelete =
5319// new List<SceneObjectGroup>();
5320//
5321// lock (m_cleaningAttachments)
5322// {
5323// ForEachSOG(delegate (SceneObjectGroup grp)
5324// {
5325// if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp)))
5326// {
5327// UUID agentID = grp.OwnerID;
5328// if (agentID == UUID.Zero)
5329// {
5330// objectsToDelete.Add(grp);
5331// return;
5332// }
5333//
5334// ScenePresence sp = GetScenePresence(agentID);
5335// if (sp == null)
5336// {
5337// objectsToDelete.Add(grp);
5338// return;
5339// }
5340// }
5341// });
5342// }
5343//
5344// foreach (SceneObjectGroup grp in objectsToDelete)
5345// {
5346// m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID);
5347// DeleteSceneObject(grp, true);
5348// }
5349// }
5350
5351 public void ThreadAlive(int threadCode)
5352 {
5353 switch(threadCode)
5354 {
5355 case 1: // Incoming
5356 m_lastIncoming = Util.EnvironmentTickCount();
5357 break;
5358 case 2: // Incoming
5359 m_lastOutgoing = Util.EnvironmentTickCount();
5360 break;
5361 }
5362 }
5363
5111 // This method is called across the simulation connector to 5364 // This method is called across the simulation connector to
5112 // determine if a given agent is allowed in this region 5365 // determine if a given agent is allowed in this region
5113 // AS A ROOT AGENT. Returning false here will prevent them 5366 // AS A ROOT AGENT. Returning false here will prevent them
@@ -5116,6 +5369,14 @@ namespace OpenSim.Region.Framework.Scenes
5116 // child agent creation, thereby emulating the SL behavior. 5369 // child agent creation, thereby emulating the SL behavior.
5117 public bool QueryAccess(UUID agentID, Vector3 position, out string reason) 5370 public bool QueryAccess(UUID agentID, Vector3 position, out string reason)
5118 { 5371 {
5372 reason = "You are banned from the region";
5373
5374 if (Permissions.IsGod(agentID))
5375 {
5376 reason = String.Empty;
5377 return true;
5378 }
5379
5119 int num = m_sceneGraph.GetNumberOfScenePresences(); 5380 int num = m_sceneGraph.GetNumberOfScenePresences();
5120 5381
5121 if (num >= RegionInfo.RegionSettings.AgentLimit) 5382 if (num >= RegionInfo.RegionSettings.AgentLimit)
@@ -5127,11 +5388,82 @@ namespace OpenSim.Region.Framework.Scenes
5127 } 5388 }
5128 } 5389 }
5129 5390
5391 ScenePresence presence = GetScenePresence(agentID);
5392 IClientAPI client = null;
5393 AgentCircuitData aCircuit = null;
5394
5395 if (presence != null)
5396 {
5397 client = presence.ControllingClient;
5398 if (client != null)
5399 aCircuit = client.RequestClientInfo();
5400 }
5401
5402 // We may be called before there is a presence or a client.
5403 // Fake AgentCircuitData to keep IAuthorizationModule smiling
5404 if (client == null)
5405 {
5406 aCircuit = new AgentCircuitData();
5407 aCircuit.AgentID = agentID;
5408 aCircuit.firstname = String.Empty;
5409 aCircuit.lastname = String.Empty;
5410 }
5411
5412 try
5413 {
5414 if (!AuthorizeUser(aCircuit, out reason))
5415 {
5416 // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID);
5417 return false;
5418 }
5419 }
5420 catch (Exception e)
5421 {
5422 m_log.DebugFormat("[SCENE]: Exception authorizing agent: {0} "+ e.StackTrace, e.Message);
5423 return false;
5424 }
5425
5426 if (position == Vector3.Zero) // Teleport
5427 {
5428 float posX = 128.0f;
5429 float posY = 128.0f;
5430
5431 if (!TestLandRestrictions(agentID, out reason, ref posX, ref posY))
5432 {
5433 // m_log.DebugFormat("[SCENE]: Denying {0} because they are banned on all parcels", agentID);
5434 return false;
5435 }
5436 }
5437 else // Walking
5438 {
5439 ILandObject land = LandChannel.GetLandObject(position.X, position.Y);
5440 if (land == null)
5441 return false;
5442
5443 bool banned = land.IsBannedFromLand(agentID);
5444 bool restricted = land.IsRestrictedFromLand(agentID);
5445
5446 if (banned || restricted)
5447 return false;
5448 }
5449
5130 reason = String.Empty; 5450 reason = String.Empty;
5131 return true; 5451 return true;
5132 } 5452 }
5133 5453
5134 /// <summary> 5454 public void StartTimerWatchdog()
5455 {
5456 m_timerWatchdog.Interval = 1000;
5457 m_timerWatchdog.Elapsed += TimerWatchdog;
5458 m_timerWatchdog.AutoReset = true;
5459 m_timerWatchdog.Start();
5460 }
5461
5462 public void TimerWatchdog(object sender, ElapsedEventArgs e)
5463 {
5464 CheckHeartbeat();
5465 }
5466
5135 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the 5467 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the
5136 /// autopilot that moves an avatar to a sit target!. 5468 /// autopilot that moves an avatar to a sit target!.
5137 /// </summary> 5469 /// </summary>