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.cs503
1 files changed, 417 insertions, 86 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index f2b7014..935cac5 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -93,6 +93,7 @@ namespace OpenSim.Region.Framework.Scenes
93 // TODO: need to figure out how allow client agents but deny 93 // TODO: need to figure out how allow client agents but deny
94 // root agents when ACL denies access to root agent 94 // root agents when ACL denies access to root agent
95 public bool m_strictAccessControl = true; 95 public bool m_strictAccessControl = true;
96 public bool m_seeIntoBannedRegion = false;
96 public int MaxUndoCount = 5; 97 public int MaxUndoCount = 5;
97 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet; 98 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet;
98 public bool LoginLock = false; 99 public bool LoginLock = false;
@@ -108,12 +109,14 @@ namespace OpenSim.Region.Framework.Scenes
108 109
109 protected int m_splitRegionID; 110 protected int m_splitRegionID;
110 protected Timer m_restartWaitTimer = new Timer(); 111 protected Timer m_restartWaitTimer = new Timer();
112 protected Timer m_timerWatchdog = new Timer();
111 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); 113 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
112 protected List<RegionInfo> m_neighbours = new List<RegionInfo>(); 114 protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
113 protected string m_simulatorVersion = "OpenSimulator Server"; 115 protected string m_simulatorVersion = "OpenSimulator Server";
114 protected ModuleLoader m_moduleLoader; 116 protected ModuleLoader m_moduleLoader;
115 protected AgentCircuitManager m_authenticateHandler; 117 protected AgentCircuitManager m_authenticateHandler;
116 protected SceneCommunicationService m_sceneGridService; 118 protected SceneCommunicationService m_sceneGridService;
119 protected ISnmpModule m_snmpService = null;
117 120
118 protected ISimulationDataService m_SimulationDataService; 121 protected ISimulationDataService m_SimulationDataService;
119 protected IEstateDataService m_EstateDataService; 122 protected IEstateDataService m_EstateDataService;
@@ -170,7 +173,7 @@ namespace OpenSim.Region.Framework.Scenes
170 private int m_update_events = 1; 173 private int m_update_events = 1;
171 private int m_update_backup = 200; 174 private int m_update_backup = 200;
172 private int m_update_terrain = 50; 175 private int m_update_terrain = 50;
173// private int m_update_land = 1; 176 private int m_update_land = 10;
174 private int m_update_coarse_locations = 50; 177 private int m_update_coarse_locations = 50;
175 178
176 private int agentMS; 179 private int agentMS;
@@ -185,6 +188,7 @@ namespace OpenSim.Region.Framework.Scenes
185 private int landMS; 188 private int landMS;
186 private int lastCompletedFrame; 189 private int lastCompletedFrame;
187 190
191 public bool CombineRegions = false;
188 /// <summary> 192 /// <summary>
189 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched 193 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched
190 /// asynchronously from the update loop. 194 /// asynchronously from the update loop.
@@ -207,10 +211,12 @@ namespace OpenSim.Region.Framework.Scenes
207 private bool m_scripts_enabled = true; 211 private bool m_scripts_enabled = true;
208 private string m_defaultScriptEngine; 212 private string m_defaultScriptEngine;
209 private int m_LastLogin; 213 private int m_LastLogin;
210 private Thread HeartbeatThread; 214 private Thread HeartbeatThread = null;
211 private volatile bool shuttingdown; 215 private volatile bool shuttingdown;
212 216
213 private int m_lastUpdate; 217 private int m_lastUpdate;
218 private int m_lastIncoming;
219 private int m_lastOutgoing;
214 private bool m_firstHeartbeat = true; 220 private bool m_firstHeartbeat = true;
215 221
216 private object m_deleting_scene_object = new object(); 222 private object m_deleting_scene_object = new object();
@@ -258,6 +264,19 @@ namespace OpenSim.Region.Framework.Scenes
258 get { return m_sceneGridService; } 264 get { return m_sceneGridService; }
259 } 265 }
260 266
267 public ISnmpModule SnmpService
268 {
269 get
270 {
271 if (m_snmpService == null)
272 {
273 m_snmpService = RequestModuleInterface<ISnmpModule>();
274 }
275
276 return m_snmpService;
277 }
278 }
279
261 public ISimulationDataService SimulationDataService 280 public ISimulationDataService SimulationDataService
262 { 281 {
263 get 282 get
@@ -550,6 +569,9 @@ namespace OpenSim.Region.Framework.Scenes
550 m_EstateDataService = estateDataService; 569 m_EstateDataService = estateDataService;
551 m_regionHandle = m_regInfo.RegionHandle; 570 m_regionHandle = m_regInfo.RegionHandle;
552 m_regionName = m_regInfo.RegionName; 571 m_regionName = m_regInfo.RegionName;
572 m_lastUpdate = Util.EnvironmentTickCount();
573 m_lastIncoming = 0;
574 m_lastOutgoing = 0;
553 575
554 m_physicalPrim = physicalPrim; 576 m_physicalPrim = physicalPrim;
555 m_seeIntoRegionFromNeighbor = SeeIntoRegionFromNeighbor; 577 m_seeIntoRegionFromNeighbor = SeeIntoRegionFromNeighbor;
@@ -674,9 +696,10 @@ namespace OpenSim.Region.Framework.Scenes
674 //Animation states 696 //Animation states
675 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); 697 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
676 // TODO: Change default to true once the feature is supported 698 // TODO: Change default to true once the feature is supported
677 m_usePreJump = startupConfig.GetBoolean("enableprejump", false); 699 m_usePreJump = startupConfig.GetBoolean("enableprejump", true);
678
679 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys); 700 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
701
702 m_log.DebugFormat("[SCENE]: prejump is {0}", m_usePreJump ? "ON" : "OFF");
680 if (RegionInfo.NonphysPrimMax > 0) 703 if (RegionInfo.NonphysPrimMax > 0)
681 { 704 {
682 m_maxNonphys = RegionInfo.NonphysPrimMax; 705 m_maxNonphys = RegionInfo.NonphysPrimMax;
@@ -708,6 +731,7 @@ namespace OpenSim.Region.Framework.Scenes
708 m_persistAfter *= 10000000; 731 m_persistAfter *= 10000000;
709 732
710 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); 733 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
734 m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine);
711 735
712 IConfig packetConfig = m_config.Configs["PacketPool"]; 736 IConfig packetConfig = m_config.Configs["PacketPool"];
713 if (packetConfig != null) 737 if (packetConfig != null)
@@ -717,6 +741,8 @@ namespace OpenSim.Region.Framework.Scenes
717 } 741 }
718 742
719 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);
720 746
721 m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true); 747 m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true);
722 if (m_generateMaptiles) 748 if (m_generateMaptiles)
@@ -752,9 +778,9 @@ namespace OpenSim.Region.Framework.Scenes
752 m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain); 778 m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain);
753 m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning); 779 m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning);
754 } 780 }
755 catch 781 catch (Exception e)
756 { 782 {
757 m_log.Warn("[SCENE]: Failed to load StartupConfig"); 783 m_log.Error("[SCENE]: Failed to load StartupConfig: " + e.ToString());
758 } 784 }
759 785
760 #endregion Region Config 786 #endregion Region Config
@@ -1134,7 +1160,9 @@ namespace OpenSim.Region.Framework.Scenes
1134 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); 1160 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
1135 if (HeartbeatThread != null) 1161 if (HeartbeatThread != null)
1136 { 1162 {
1163 m_log.ErrorFormat("[SCENE]: Restarting heartbeat thread because it hasn't reported in in region {0}", RegionInfo.RegionName);
1137 HeartbeatThread.Abort(); 1164 HeartbeatThread.Abort();
1165 Watchdog.RemoveThread(HeartbeatThread.ManagedThreadId);
1138 HeartbeatThread = null; 1166 HeartbeatThread = null;
1139 } 1167 }
1140 m_lastUpdate = Util.EnvironmentTickCount(); 1168 m_lastUpdate = Util.EnvironmentTickCount();
@@ -1177,9 +1205,6 @@ namespace OpenSim.Region.Framework.Scenes
1177 { 1205 {
1178 while (!shuttingdown) 1206 while (!shuttingdown)
1179 Update(); 1207 Update();
1180
1181 m_lastUpdate = Util.EnvironmentTickCount();
1182 m_firstHeartbeat = false;
1183 } 1208 }
1184 catch (ThreadAbortException) 1209 catch (ThreadAbortException)
1185 { 1210 {
@@ -1277,6 +1302,13 @@ namespace OpenSim.Region.Framework.Scenes
1277 eventMS = Util.EnvironmentTickCountSubtract(evMS); ; 1302 eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
1278 } 1303 }
1279 1304
1305 // if (Frame % m_update_land == 0)
1306 // {
1307 // int ldMS = Util.EnvironmentTickCount();
1308 // UpdateLand();
1309 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1310 // }
1311
1280 if (Frame % m_update_backup == 0) 1312 if (Frame % m_update_backup == 0)
1281 { 1313 {
1282 int backMS = Util.EnvironmentTickCount(); 1314 int backMS = Util.EnvironmentTickCount();
@@ -1378,12 +1410,16 @@ namespace OpenSim.Region.Framework.Scenes
1378 maintc = Util.EnvironmentTickCountSubtract(maintc); 1410 maintc = Util.EnvironmentTickCountSubtract(maintc);
1379 maintc = (int)(MinFrameTime * 1000) - maintc; 1411 maintc = (int)(MinFrameTime * 1000) - maintc;
1380 1412
1413
1414 m_lastUpdate = Util.EnvironmentTickCount();
1415 m_firstHeartbeat = false;
1416
1381 if (maintc > 0) 1417 if (maintc > 0)
1382 Thread.Sleep(maintc); 1418 Thread.Sleep(maintc);
1383 1419
1384 // Tell the watchdog that this thread is still alive 1420 // Tell the watchdog that this thread is still alive
1385 Watchdog.UpdateThread(); 1421 Watchdog.UpdateThread();
1386 } 1422 }
1387 1423
1388 public void AddGroupTarget(SceneObjectGroup grp) 1424 public void AddGroupTarget(SceneObjectGroup grp)
1389 { 1425 {
@@ -1399,9 +1435,9 @@ namespace OpenSim.Region.Framework.Scenes
1399 1435
1400 private void CheckAtTargets() 1436 private void CheckAtTargets()
1401 { 1437 {
1402 Dictionary<UUID, SceneObjectGroup>.ValueCollection objs; 1438 List<SceneObjectGroup> objs = new List<SceneObjectGroup>();
1403 lock (m_groupsWithTargets) 1439 lock (m_groupsWithTargets)
1404 objs = m_groupsWithTargets.Values; 1440 objs = new List<SceneObjectGroup>(m_groupsWithTargets.Values);
1405 1441
1406 foreach (SceneObjectGroup entry in objs) 1442 foreach (SceneObjectGroup entry in objs)
1407 entry.checkAtTargets(); 1443 entry.checkAtTargets();
@@ -1721,14 +1757,24 @@ namespace OpenSim.Region.Framework.Scenes
1721 /// <returns></returns> 1757 /// <returns></returns>
1722 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter) 1758 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter)
1723 { 1759 {
1760
1761 float wheight = (float)RegionInfo.RegionSettings.WaterHeight;
1762 Vector3 wpos = Vector3.Zero;
1763 // Check for water surface intersection from above
1764 if ( (RayStart.Z > wheight) && (RayEnd.Z < wheight) )
1765 {
1766 float ratio = (RayStart.Z - wheight) / (RayStart.Z - RayEnd.Z);
1767 wpos.X = RayStart.X - (ratio * (RayStart.X - RayEnd.X));
1768 wpos.Y = RayStart.Y - (ratio * (RayStart.Y - RayEnd.Y));
1769 wpos.Z = wheight;
1770 }
1771
1724 Vector3 pos = Vector3.Zero; 1772 Vector3 pos = Vector3.Zero;
1725 if (RayEndIsIntersection == (byte)1) 1773 if (RayEndIsIntersection == (byte)1)
1726 { 1774 {
1727 pos = RayEnd; 1775 pos = RayEnd;
1728 return pos;
1729 } 1776 }
1730 1777 else if (RayTargetID != UUID.Zero)
1731 if (RayTargetID != UUID.Zero)
1732 { 1778 {
1733 SceneObjectPart target = GetSceneObjectPart(RayTargetID); 1779 SceneObjectPart target = GetSceneObjectPart(RayTargetID);
1734 1780
@@ -1750,7 +1796,7 @@ namespace OpenSim.Region.Framework.Scenes
1750 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter); 1796 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter);
1751 1797
1752 // Un-comment out the following line to Get Raytrace results printed to the console. 1798 // Un-comment out the following line to Get Raytrace results printed to the console.
1753 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); 1799 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
1754 float ScaleOffset = 0.5f; 1800 float ScaleOffset = 0.5f;
1755 1801
1756 // If we hit something 1802 // If we hit something
@@ -1773,13 +1819,10 @@ namespace OpenSim.Region.Framework.Scenes
1773 //pos.Z -= 0.25F; 1819 //pos.Z -= 0.25F;
1774 1820
1775 } 1821 }
1776
1777 return pos;
1778 } 1822 }
1779 else 1823 else
1780 { 1824 {
1781 // We don't have a target here, so we're going to raytrace all the objects in the scene. 1825 // We don't have a target here, so we're going to raytrace all the objects in the scene.
1782
1783 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false); 1826 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false);
1784 1827
1785 // Un-comment the following line to print the raytrace results to the console. 1828 // Un-comment the following line to print the raytrace results to the console.
@@ -1788,13 +1831,12 @@ namespace OpenSim.Region.Framework.Scenes
1788 if (ei.HitTF) 1831 if (ei.HitTF)
1789 { 1832 {
1790 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); 1833 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
1791 } else 1834 }
1835 else
1792 { 1836 {
1793 // fall back to our stupid functionality 1837 // fall back to our stupid functionality
1794 pos = RayEnd; 1838 pos = RayEnd;
1795 } 1839 }
1796
1797 return pos;
1798 } 1840 }
1799 } 1841 }
1800 else 1842 else
@@ -1805,8 +1847,12 @@ namespace OpenSim.Region.Framework.Scenes
1805 //increase height so its above the ground. 1847 //increase height so its above the ground.
1806 //should be getting the normal of the ground at the rez point and using that? 1848 //should be getting the normal of the ground at the rez point and using that?
1807 pos.Z += scale.Z / 2f; 1849 pos.Z += scale.Z / 2f;
1808 return pos; 1850// return pos;
1809 } 1851 }
1852
1853 // check against posible water intercept
1854 if (wpos.Z > pos.Z) pos = wpos;
1855 return pos;
1810 } 1856 }
1811 1857
1812 1858
@@ -1890,7 +1936,10 @@ namespace OpenSim.Region.Framework.Scenes
1890 public bool AddRestoredSceneObject( 1936 public bool AddRestoredSceneObject(
1891 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 1937 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
1892 { 1938 {
1893 return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); 1939 bool result = m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates);
1940 if (result)
1941 sceneObject.IsDeleted = false;
1942 return result;
1894 } 1943 }
1895 1944
1896 /// <summary> 1945 /// <summary>
@@ -1980,6 +2029,15 @@ namespace OpenSim.Region.Framework.Scenes
1980 /// </summary> 2029 /// </summary>
1981 public void DeleteAllSceneObjects() 2030 public void DeleteAllSceneObjects()
1982 { 2031 {
2032 DeleteAllSceneObjects(false);
2033 }
2034
2035 /// <summary>
2036 /// Delete every object from the scene. This does not include attachments worn by avatars.
2037 /// </summary>
2038 public void DeleteAllSceneObjects(bool exceptNoCopy)
2039 {
2040 List<SceneObjectGroup> toReturn = new List<SceneObjectGroup>();
1983 lock (Entities) 2041 lock (Entities)
1984 { 2042 {
1985 EntityBase[] entities = Entities.GetEntities(); 2043 EntityBase[] entities = Entities.GetEntities();
@@ -1988,11 +2046,24 @@ namespace OpenSim.Region.Framework.Scenes
1988 if (e is SceneObjectGroup) 2046 if (e is SceneObjectGroup)
1989 { 2047 {
1990 SceneObjectGroup sog = (SceneObjectGroup)e; 2048 SceneObjectGroup sog = (SceneObjectGroup)e;
1991 if (!sog.IsAttachment) 2049 if (sog != null && !sog.IsAttachment)
1992 DeleteSceneObject((SceneObjectGroup)e, false); 2050 {
2051 if (!exceptNoCopy || ((sog.GetEffectivePermissions() & (uint)PermissionMask.Copy) != 0))
2052 {
2053 DeleteSceneObject((SceneObjectGroup)e, false);
2054 }
2055 else
2056 {
2057 toReturn.Add((SceneObjectGroup)e);
2058 }
2059 }
1993 } 2060 }
1994 } 2061 }
1995 } 2062 }
2063 if (toReturn.Count > 0)
2064 {
2065 returnObjects(toReturn.ToArray(), UUID.Zero);
2066 }
1996 } 2067 }
1997 2068
1998 /// <summary> 2069 /// <summary>
@@ -2041,6 +2112,8 @@ namespace OpenSim.Region.Framework.Scenes
2041 } 2112 }
2042 2113
2043 group.DeleteGroupFromScene(silent); 2114 group.DeleteGroupFromScene(silent);
2115 if (!silent)
2116 SendKillObject(new List<uint>() { group.LocalId });
2044 2117
2045// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); 2118// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
2046 } 2119 }
@@ -2395,10 +2468,17 @@ namespace OpenSim.Region.Framework.Scenes
2395 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns> 2468 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns>
2396 public bool AddSceneObject(SceneObjectGroup sceneObject) 2469 public bool AddSceneObject(SceneObjectGroup sceneObject)
2397 { 2470 {
2471 if (sceneObject.OwnerID == UUID.Zero)
2472 {
2473 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero", sceneObject.UUID);
2474 return false;
2475 }
2476
2398 // If the user is banned, we won't let any of their objects 2477 // If the user is banned, we won't let any of their objects
2399 // enter. Period. 2478 // enter. Period.
2400 // 2479 //
2401 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID)) 2480 int flags = GetUserFlags(sceneObject.OwnerID);
2481 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID, flags))
2402 { 2482 {
2403 m_log.Info("[INTERREGION]: Denied prim crossing for " + 2483 m_log.Info("[INTERREGION]: Denied prim crossing for " +
2404 "banned avatar"); 2484 "banned avatar");
@@ -2445,12 +2525,23 @@ namespace OpenSim.Region.Framework.Scenes
2445 } 2525 }
2446 else 2526 else
2447 { 2527 {
2528 m_log.DebugFormat("[SCENE]: Attachment {0} arrived and scene presence was not found, setting to temp", sceneObject.UUID);
2448 RootPrim.RemFlag(PrimFlags.TemporaryOnRez); 2529 RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
2449 RootPrim.AddFlag(PrimFlags.TemporaryOnRez); 2530 RootPrim.AddFlag(PrimFlags.TemporaryOnRez);
2450 } 2531 }
2532 if (sceneObject.OwnerID == UUID.Zero)
2533 {
2534 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero after attachment processing. BUG!", sceneObject.UUID);
2535 return false;
2536 }
2451 } 2537 }
2452 else 2538 else
2453 { 2539 {
2540 if (sceneObject.OwnerID == UUID.Zero)
2541 {
2542 m_log.ErrorFormat("[SCENE]: Owner ID for non-attachment {0} was zero", sceneObject.UUID);
2543 return false;
2544 }
2454 AddRestoredSceneObject(sceneObject, true, false); 2545 AddRestoredSceneObject(sceneObject, true, false);
2455 2546
2456 if (!Permissions.CanObjectEntry(sceneObject.UUID, 2547 if (!Permissions.CanObjectEntry(sceneObject.UUID,
@@ -2480,6 +2571,24 @@ namespace OpenSim.Region.Framework.Scenes
2480 return 2; // StateSource.PrimCrossing 2571 return 2; // StateSource.PrimCrossing
2481 } 2572 }
2482 2573
2574 public int GetUserFlags(UUID user)
2575 {
2576 //Unfortunately the SP approach means that the value is cached until region is restarted
2577 /*
2578 ScenePresence sp;
2579 if (TryGetScenePresence(user, out sp))
2580 {
2581 return sp.UserFlags;
2582 }
2583 else
2584 {
2585 */
2586 UserAccount uac = UserAccountService.GetUserAccount(RegionInfo.ScopeID, user);
2587 if (uac == null)
2588 return 0;
2589 return uac.UserFlags;
2590 //}
2591 }
2483 #endregion 2592 #endregion
2484 2593
2485 #region Add/Remove Avatar Methods 2594 #region Add/Remove Avatar Methods
@@ -2501,6 +2610,7 @@ namespace OpenSim.Region.Framework.Scenes
2501 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2610 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2502 2611
2503 CheckHeartbeat(); 2612 CheckHeartbeat();
2613 ScenePresence presence;
2504 2614
2505 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here 2615 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here
2506 { 2616 {
@@ -2534,7 +2644,14 @@ namespace OpenSim.Region.Framework.Scenes
2534 2644
2535 EventManager.TriggerOnNewClient(client); 2645 EventManager.TriggerOnNewClient(client);
2536 if (vialogin) 2646 if (vialogin)
2647 {
2537 EventManager.TriggerOnClientLogin(client); 2648 EventManager.TriggerOnClientLogin(client);
2649
2650 // Send initial parcel data
2651 Vector3 pos = createdSp.AbsolutePosition;
2652 ILandObject land = LandChannel.GetLandObject(pos.X, pos.Y);
2653 land.SendLandUpdateToClient(client);
2654 }
2538 } 2655 }
2539 } 2656 }
2540 2657
@@ -2623,19 +2740,12 @@ namespace OpenSim.Region.Framework.Scenes
2623 // and the scene presence and the client, if they exist 2740 // and the scene presence and the client, if they exist
2624 try 2741 try
2625 { 2742 {
2626 // We need to wait for the client to make UDP contact first. 2743 ScenePresence sp = GetScenePresence(agentID);
2627 // It's the UDP contact that creates the scene presence 2744 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2628 ScenePresence sp = WaitGetScenePresence(agentID); 2745
2629 if (sp != null) 2746 if (sp != null)
2630 {
2631 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2632
2633 sp.ControllingClient.Close(); 2747 sp.ControllingClient.Close();
2634 } 2748
2635 else
2636 {
2637 m_log.WarnFormat("[SCENE]: Could not find scene presence for {0}", agentID);
2638 }
2639 // BANG! SLASH! 2749 // BANG! SLASH!
2640 m_authenticateHandler.RemoveCircuit(agentID); 2750 m_authenticateHandler.RemoveCircuit(agentID);
2641 2751
@@ -2735,6 +2845,7 @@ namespace OpenSim.Region.Framework.Scenes
2735 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory; 2845 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory;
2736 client.OnUpdateInventoryItem += UpdateInventoryItemAsset; 2846 client.OnUpdateInventoryItem += UpdateInventoryItemAsset;
2737 client.OnCopyInventoryItem += CopyInventoryItem; 2847 client.OnCopyInventoryItem += CopyInventoryItem;
2848 client.OnMoveItemsAndLeaveCopy += MoveInventoryItemsLeaveCopy;
2738 client.OnMoveInventoryItem += MoveInventoryItem; 2849 client.OnMoveInventoryItem += MoveInventoryItem;
2739 client.OnRemoveInventoryItem += RemoveInventoryItem; 2850 client.OnRemoveInventoryItem += RemoveInventoryItem;
2740 client.OnRemoveInventoryFolder += RemoveInventoryFolder; 2851 client.OnRemoveInventoryFolder += RemoveInventoryFolder;
@@ -2912,15 +3023,16 @@ namespace OpenSim.Region.Framework.Scenes
2912 /// </summary> 3023 /// </summary>
2913 /// <param name="agentId">The avatar's Unique ID</param> 3024 /// <param name="agentId">The avatar's Unique ID</param>
2914 /// <param name="client">The IClientAPI for the client</param> 3025 /// <param name="client">The IClientAPI for the client</param>
2915 public virtual void TeleportClientHome(UUID agentId, IClientAPI client) 3026 public virtual bool TeleportClientHome(UUID agentId, IClientAPI client)
2916 { 3027 {
2917 if (m_teleportModule != null) 3028 if (m_teleportModule != null)
2918 m_teleportModule.TeleportHome(agentId, client); 3029 return m_teleportModule.TeleportHome(agentId, client);
2919 else 3030 else
2920 { 3031 {
2921 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active"); 3032 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active");
2922 client.SendTeleportFailed("Unable to perform teleports on this simulator."); 3033 client.SendTeleportFailed("Unable to perform teleports on this simulator.");
2923 } 3034 }
3035 return false;
2924 } 3036 }
2925 3037
2926 /// <summary> 3038 /// <summary>
@@ -3012,6 +3124,16 @@ namespace OpenSim.Region.Framework.Scenes
3012 /// <param name="flags"></param> 3124 /// <param name="flags"></param>
3013 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags) 3125 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags)
3014 { 3126 {
3127 //Add half the avatar's height so that the user doesn't fall through prims
3128 ScenePresence presence;
3129 if (TryGetScenePresence(remoteClient.AgentId, out presence))
3130 {
3131 if (presence.Appearance != null)
3132 {
3133 position.Z = position.Z + (presence.Appearance.AvatarHeight / 2);
3134 }
3135 }
3136
3015 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt)) 3137 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt))
3016 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot. 3138 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot.
3017 m_dialogModule.SendAlertToUser(remoteClient, "Home position set."); 3139 m_dialogModule.SendAlertToUser(remoteClient, "Home position set.");
@@ -3080,8 +3202,9 @@ namespace OpenSim.Region.Framework.Scenes
3080 regions.Remove(RegionInfo.RegionHandle); 3202 regions.Remove(RegionInfo.RegionHandle);
3081 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3203 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3082 } 3204 }
3083 3205 m_log.Debug("[Scene] Beginning ClientClosed");
3084 m_eventManager.TriggerClientClosed(agentID, this); 3206 m_eventManager.TriggerClientClosed(agentID, this);
3207 m_log.Debug("[Scene] Finished ClientClosed");
3085 } 3208 }
3086 catch (NullReferenceException) 3209 catch (NullReferenceException)
3087 { 3210 {
@@ -3089,7 +3212,12 @@ namespace OpenSim.Region.Framework.Scenes
3089 // Avatar is already disposed :/ 3212 // Avatar is already disposed :/
3090 } 3213 }
3091 3214
3215 m_log.Debug("[Scene] Beginning OnRemovePresence");
3092 m_eventManager.TriggerOnRemovePresence(agentID); 3216 m_eventManager.TriggerOnRemovePresence(agentID);
3217 m_log.Debug("[Scene] Finished OnRemovePresence");
3218
3219 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3220 AttachmentsModule.SaveChangedAttachments(avatar);
3093 3221
3094 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc) 3222 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3095 AttachmentsModule.SaveChangedAttachments(avatar); 3223 AttachmentsModule.SaveChangedAttachments(avatar);
@@ -3098,7 +3226,7 @@ namespace OpenSim.Region.Framework.Scenes
3098 delegate(IClientAPI client) 3226 delegate(IClientAPI client)
3099 { 3227 {
3100 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3228 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3101 try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); } 3229 try { client.SendKillObject(avatar.RegionHandle, new List<uint>() { avatar.LocalId}); }
3102 catch (NullReferenceException) { } 3230 catch (NullReferenceException) { }
3103 }); 3231 });
3104 3232
@@ -3109,8 +3237,11 @@ namespace OpenSim.Region.Framework.Scenes
3109 } 3237 }
3110 3238
3111 // Remove the avatar from the scene 3239 // Remove the avatar from the scene
3240 m_log.Debug("[Scene] Begin RemoveScenePresence");
3112 m_sceneGraph.RemoveScenePresence(agentID); 3241 m_sceneGraph.RemoveScenePresence(agentID);
3242 m_log.Debug("[Scene] Finished RemoveScenePresence. Removing the client manager");
3113 m_clientManager.Remove(agentID); 3243 m_clientManager.Remove(agentID);
3244 m_log.Debug("[Scene] Removed the client manager. Firing avatar.close");
3114 3245
3115 try 3246 try
3116 { 3247 {
@@ -3124,9 +3255,10 @@ namespace OpenSim.Region.Framework.Scenes
3124 { 3255 {
3125 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString()); 3256 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString());
3126 } 3257 }
3127 3258 m_log.Debug("[Scene] Done. Firing RemoveCircuit");
3128 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3259 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
3129// CleanDroppedAttachments(); 3260// CleanDroppedAttachments();
3261 m_log.Debug("[Scene] The avatar has left the building");
3130 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 3262 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
3131 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); 3263 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
3132 } 3264 }
@@ -3157,19 +3289,24 @@ namespace OpenSim.Region.Framework.Scenes
3157 3289
3158 #region Entities 3290 #region Entities
3159 3291
3160 public void SendKillObject(uint localID) 3292 public void SendKillObject(List<uint> localIDs)
3161 { 3293 {
3162 SceneObjectPart part = GetSceneObjectPart(localID); 3294 List<uint> deleteIDs = new List<uint>();
3163 if (part != null) // It is a prim 3295
3296 foreach (uint localID in localIDs)
3164 { 3297 {
3165 if (!part.ParentGroup.IsDeleted) // Valid 3298 SceneObjectPart part = GetSceneObjectPart(localID);
3299 if (part != null) // It is a prim
3166 { 3300 {
3167 if (part.ParentGroup.RootPart != part) // Child part 3301 if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid
3168 return; 3302 {
3303 if (part.ParentGroup.RootPart != part) // Child part
3304 continue;
3305 }
3169 } 3306 }
3307 deleteIDs.Add(localID);
3170 } 3308 }
3171 3309 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, deleteIDs); });
3172 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); });
3173 } 3310 }
3174 3311
3175 #endregion 3312 #endregion
@@ -3187,7 +3324,6 @@ namespace OpenSim.Region.Framework.Scenes
3187 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate; 3324 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
3188 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar; 3325 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar;
3189 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid; 3326 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
3190 m_sceneGridService.KiPrimitive += SendKillObject;
3191 m_sceneGridService.OnGetLandData += GetLandData; 3327 m_sceneGridService.OnGetLandData += GetLandData;
3192 } 3328 }
3193 3329
@@ -3196,7 +3332,6 @@ namespace OpenSim.Region.Framework.Scenes
3196 /// </summary> 3332 /// </summary>
3197 public void UnRegisterRegionWithComms() 3333 public void UnRegisterRegionWithComms()
3198 { 3334 {
3199 m_sceneGridService.KiPrimitive -= SendKillObject;
3200 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid; 3335 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid;
3201 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar; 3336 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar;
3202 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate; 3337 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate;
@@ -3276,13 +3411,16 @@ namespace OpenSim.Region.Framework.Scenes
3276 sp = null; 3411 sp = null;
3277 } 3412 }
3278 3413
3279 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3280 3414
3281 //On login test land permisions 3415 //On login test land permisions
3282 if (vialogin) 3416 if (vialogin)
3283 { 3417 {
3284 if (land != null && !TestLandRestrictions(agent, land, out reason)) 3418 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
3419 if (cache != null)
3420 cache.Remove(agent.firstname + " " + agent.lastname);
3421 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3285 { 3422 {
3423 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString());
3286 return false; 3424 return false;
3287 } 3425 }
3288 } 3426 }
@@ -3305,8 +3443,13 @@ namespace OpenSim.Region.Framework.Scenes
3305 3443
3306 try 3444 try
3307 { 3445 {
3308 if (!AuthorizeUser(agent, out reason)) 3446 // Always check estate if this is a login. Always
3309 return false; 3447 // check if banned regions are to be blacked out.
3448 if (vialogin || (!m_seeIntoBannedRegion))
3449 {
3450 if (!AuthorizeUser(agent, out reason))
3451 return false;
3452 }
3310 } 3453 }
3311 catch (Exception e) 3454 catch (Exception e)
3312 { 3455 {
@@ -3408,6 +3551,8 @@ namespace OpenSim.Region.Framework.Scenes
3408 } 3551 }
3409 } 3552 }
3410 // Honor parcel landing type and position. 3553 // Honor parcel landing type and position.
3554 /*
3555 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3411 if (land != null) 3556 if (land != null)
3412 { 3557 {
3413 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) 3558 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero)
@@ -3415,26 +3560,34 @@ namespace OpenSim.Region.Framework.Scenes
3415 agent.startpos = land.LandData.UserLocation; 3560 agent.startpos = land.LandData.UserLocation;
3416 } 3561 }
3417 } 3562 }
3563 */// This is now handled properly in ScenePresence.MakeRootAgent
3418 } 3564 }
3419 3565
3420 return true; 3566 return true;
3421 } 3567 }
3422 3568
3423 private bool TestLandRestrictions(AgentCircuitData agent, ILandObject land, out string reason) 3569 private bool TestLandRestrictions(UUID agentID, out string reason, ref float posX, ref float posY)
3424 { 3570 {
3425 3571 reason = String.Empty;
3426 bool banned = land.IsBannedFromLand(agent.AgentID); 3572 if (Permissions.IsGod(agentID))
3427 bool restricted = land.IsRestrictedFromLand(agent.AgentID); 3573 return true;
3574
3575 ILandObject land = LandChannel.GetLandObject(posX, posY);
3576 if (land == null)
3577 return false;
3578
3579 bool banned = land.IsBannedFromLand(agentID);
3580 bool restricted = land.IsRestrictedFromLand(agentID);
3428 3581
3429 if (banned || restricted) 3582 if (banned || restricted)
3430 { 3583 {
3431 ILandObject nearestParcel = GetNearestAllowedParcel(agent.AgentID, agent.startpos.X, agent.startpos.Y); 3584 ILandObject nearestParcel = GetNearestAllowedParcel(agentID, posX, posY);
3432 if (nearestParcel != null) 3585 if (nearestParcel != null)
3433 { 3586 {
3434 //Move agent to nearest allowed 3587 //Move agent to nearest allowed
3435 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel); 3588 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel);
3436 agent.startpos.X = newPosition.X; 3589 posX = newPosition.X;
3437 agent.startpos.Y = newPosition.Y; 3590 posY = newPosition.Y;
3438 } 3591 }
3439 else 3592 else
3440 { 3593 {
@@ -3496,7 +3649,7 @@ namespace OpenSim.Region.Framework.Scenes
3496 3649
3497 if (!m_strictAccessControl) return true; 3650 if (!m_strictAccessControl) return true;
3498 if (Permissions.IsGod(agent.AgentID)) return true; 3651 if (Permissions.IsGod(agent.AgentID)) return true;
3499 3652
3500 if (AuthorizationService != null) 3653 if (AuthorizationService != null)
3501 { 3654 {
3502 if (!AuthorizationService.IsAuthorizedForRegion( 3655 if (!AuthorizationService.IsAuthorizedForRegion(
@@ -3504,14 +3657,14 @@ namespace OpenSim.Region.Framework.Scenes
3504 { 3657 {
3505 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region", 3658 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region",
3506 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3659 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
3507 3660
3508 return false; 3661 return false;
3509 } 3662 }
3510 } 3663 }
3511 3664
3512 if (m_regInfo.EstateSettings != null) 3665 if (m_regInfo.EstateSettings != null)
3513 { 3666 {
3514 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID)) 3667 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID,0))
3515 { 3668 {
3516 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", 3669 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
3517 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3670 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
@@ -3701,6 +3854,13 @@ namespace OpenSim.Region.Framework.Scenes
3701 3854
3702 // We have to wait until the viewer contacts this region after receiving EAC. 3855 // We have to wait until the viewer contacts this region after receiving EAC.
3703 // That calls AddNewClient, which finally creates the ScenePresence 3856 // That calls AddNewClient, which finally creates the ScenePresence
3857 int flags = GetUserFlags(cAgentData.AgentID);
3858 if (m_regInfo.EstateSettings.IsBanned(cAgentData.AgentID, flags))
3859 {
3860 m_log.DebugFormat("[SCENE]: Denying root agent entry to {0}: banned", cAgentData.AgentID);
3861 return false;
3862 }
3863
3704 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); 3864 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2);
3705 if (nearestParcel == null) 3865 if (nearestParcel == null)
3706 { 3866 {
@@ -3716,7 +3876,6 @@ namespace OpenSim.Region.Framework.Scenes
3716 return false; 3876 return false;
3717 } 3877 }
3718 3878
3719
3720 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 3879 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
3721 3880
3722 if (childAgentUpdate != null) 3881 if (childAgentUpdate != null)
@@ -3783,12 +3942,22 @@ namespace OpenSim.Region.Framework.Scenes
3783 return false; 3942 return false;
3784 } 3943 }
3785 3944
3945 public bool IncomingCloseAgent(UUID agentID)
3946 {
3947 return IncomingCloseAgent(agentID, false);
3948 }
3949
3950 public bool IncomingCloseChildAgent(UUID agentID)
3951 {
3952 return IncomingCloseAgent(agentID, true);
3953 }
3954
3786 /// <summary> 3955 /// <summary>
3787 /// Tell a single agent to disconnect from the region. 3956 /// Tell a single agent to disconnect from the region.
3788 /// </summary> 3957 /// </summary>
3789 /// <param name="regionHandle"></param>
3790 /// <param name="agentID"></param> 3958 /// <param name="agentID"></param>
3791 public bool IncomingCloseAgent(UUID agentID) 3959 /// <param name="childOnly"></param>
3960 public bool IncomingCloseAgent(UUID agentID, bool childOnly)
3792 { 3961 {
3793 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 3962 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
3794 3963
@@ -3800,7 +3969,7 @@ namespace OpenSim.Region.Framework.Scenes
3800 { 3969 {
3801 m_sceneGraph.removeUserCount(false); 3970 m_sceneGraph.removeUserCount(false);
3802 } 3971 }
3803 else 3972 else if (!childOnly)
3804 { 3973 {
3805 m_sceneGraph.removeUserCount(true); 3974 m_sceneGraph.removeUserCount(true);
3806 } 3975 }
@@ -3816,9 +3985,12 @@ namespace OpenSim.Region.Framework.Scenes
3816 } 3985 }
3817 else 3986 else
3818 presence.ControllingClient.SendShutdownConnectionNotice(); 3987 presence.ControllingClient.SendShutdownConnectionNotice();
3988 presence.ControllingClient.Close(false);
3989 }
3990 else if (!childOnly)
3991 {
3992 presence.ControllingClient.Close(true);
3819 } 3993 }
3820
3821 presence.ControllingClient.Close();
3822 return true; 3994 return true;
3823 } 3995 }
3824 3996
@@ -4433,34 +4605,66 @@ namespace OpenSim.Region.Framework.Scenes
4433 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID); 4605 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID);
4434 } 4606 }
4435 4607
4436 public int GetHealth() 4608 public int GetHealth(out int flags, out string message)
4437 { 4609 {
4438 // Returns: 4610 // Returns:
4439 // 1 = sim is up and accepting http requests. The heartbeat has 4611 // 1 = sim is up and accepting http requests. The heartbeat has
4440 // stopped and the sim is probably locked up, but a remote 4612 // stopped and the sim is probably locked up, but a remote
4441 // admin restart may succeed 4613 // admin restart may succeed
4442 // 4614 //
4443 // 2 = Sim is up and the heartbeat is running. The sim is likely 4615 // 2 = Sim is up and the heartbeat is running. The sim is likely
4444 // usable for people within and logins _may_ work 4616 // usable for people within
4445 // 4617 //
4446 // 3 = We have seen a new user enter within the past 4 minutes 4618 // 3 = Sim is up and one packet thread is running. Sim is
4619 // unstable and will not accept new logins
4620 //
4621 // 4 = Sim is up and both packet threads are running. Sim is
4622 // likely usable
4623 //
4624 // 5 = We have seen a new user enter within the past 4 minutes
4447 // which can be seen as positive confirmation of sim health 4625 // which can be seen as positive confirmation of sim health
4448 // 4626 //
4627
4628 flags = 0;
4629 message = String.Empty;
4630
4631 CheckHeartbeat();
4632
4633 if (m_firstHeartbeat || (m_lastIncoming == 0 && m_lastOutgoing == 0))
4634 {
4635 // We're still starting
4636 // 0 means "in startup", it can't happen another way, since
4637 // to get here, we must be able to accept http connections
4638 return 0;
4639 }
4640
4449 int health=1; // Start at 1, means we're up 4641 int health=1; // Start at 1, means we're up
4450 4642
4451 if ((Util.EnvironmentTickCountSubtract(m_lastUpdate)) < 1000) 4643 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) < 1000)
4644 {
4452 health+=1; 4645 health+=1;
4453 else 4646 flags |= 1;
4647 }
4648
4649 if (Util.EnvironmentTickCountSubtract(m_lastIncoming) < 1000)
4650 {
4651 health+=1;
4652 flags |= 2;
4653 }
4654
4655 if (Util.EnvironmentTickCountSubtract(m_lastOutgoing) < 1000)
4656 {
4657 health+=1;
4658 flags |= 4;
4659 }
4660
4661 if (flags != 7)
4454 return health; 4662 return health;
4455 4663
4456 // A login in the last 4 mins? We can't be doing too badly 4664 // A login in the last 4 mins? We can't be doing too badly
4457 // 4665 //
4458 if ((Util.EnvironmentTickCountSubtract(m_LastLogin)) < 240000) 4666 if (Util.EnvironmentTickCountSubtract(m_LastLogin) < 240000)
4459 health++; 4667 health++;
4460 else
4461 return health;
4462
4463 CheckHeartbeat();
4464 4668
4465 return health; 4669 return health;
4466 } 4670 }
@@ -4653,7 +4857,7 @@ namespace OpenSim.Region.Framework.Scenes
4653 if (m_firstHeartbeat) 4857 if (m_firstHeartbeat)
4654 return; 4858 return;
4655 4859
4656 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 2000) 4860 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 5000)
4657 StartTimer(); 4861 StartTimer();
4658 } 4862 }
4659 4863
@@ -5067,6 +5271,54 @@ namespace OpenSim.Region.Framework.Scenes
5067 } 5271 }
5068 } 5272 }
5069 5273
5274// public void CleanDroppedAttachments()
5275// {
5276// List<SceneObjectGroup> objectsToDelete =
5277// new List<SceneObjectGroup>();
5278//
5279// lock (m_cleaningAttachments)
5280// {
5281// ForEachSOG(delegate (SceneObjectGroup grp)
5282// {
5283// if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp)))
5284// {
5285// UUID agentID = grp.OwnerID;
5286// if (agentID == UUID.Zero)
5287// {
5288// objectsToDelete.Add(grp);
5289// return;
5290// }
5291//
5292// ScenePresence sp = GetScenePresence(agentID);
5293// if (sp == null)
5294// {
5295// objectsToDelete.Add(grp);
5296// return;
5297// }
5298// }
5299// });
5300// }
5301//
5302// foreach (SceneObjectGroup grp in objectsToDelete)
5303// {
5304// m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID);
5305// DeleteSceneObject(grp, true);
5306// }
5307// }
5308
5309 public void ThreadAlive(int threadCode)
5310 {
5311 switch(threadCode)
5312 {
5313 case 1: // Incoming
5314 m_lastIncoming = Util.EnvironmentTickCount();
5315 break;
5316 case 2: // Incoming
5317 m_lastOutgoing = Util.EnvironmentTickCount();
5318 break;
5319 }
5320 }
5321
5070 // This method is called across the simulation connector to 5322 // This method is called across the simulation connector to
5071 // determine if a given agent is allowed in this region 5323 // determine if a given agent is allowed in this region
5072 // AS A ROOT AGENT. Returning false here will prevent them 5324 // AS A ROOT AGENT. Returning false here will prevent them
@@ -5075,6 +5327,14 @@ namespace OpenSim.Region.Framework.Scenes
5075 // child agent creation, thereby emulating the SL behavior. 5327 // child agent creation, thereby emulating the SL behavior.
5076 public bool QueryAccess(UUID agentID, Vector3 position, out string reason) 5328 public bool QueryAccess(UUID agentID, Vector3 position, out string reason)
5077 { 5329 {
5330 reason = "You are banned from the region";
5331
5332 if (Permissions.IsGod(agentID))
5333 {
5334 reason = String.Empty;
5335 return true;
5336 }
5337
5078 int num = m_sceneGraph.GetNumberOfScenePresences(); 5338 int num = m_sceneGraph.GetNumberOfScenePresences();
5079 5339
5080 if (num >= RegionInfo.RegionSettings.AgentLimit) 5340 if (num >= RegionInfo.RegionSettings.AgentLimit)
@@ -5086,11 +5346,82 @@ namespace OpenSim.Region.Framework.Scenes
5086 } 5346 }
5087 } 5347 }
5088 5348
5349 ScenePresence presence = GetScenePresence(agentID);
5350 IClientAPI client = null;
5351 AgentCircuitData aCircuit = null;
5352
5353 if (presence != null)
5354 {
5355 client = presence.ControllingClient;
5356 if (client != null)
5357 aCircuit = client.RequestClientInfo();
5358 }
5359
5360 // We may be called before there is a presence or a client.
5361 // Fake AgentCircuitData to keep IAuthorizationModule smiling
5362 if (client == null)
5363 {
5364 aCircuit = new AgentCircuitData();
5365 aCircuit.AgentID = agentID;
5366 aCircuit.firstname = String.Empty;
5367 aCircuit.lastname = String.Empty;
5368 }
5369
5370 try
5371 {
5372 if (!AuthorizeUser(aCircuit, out reason))
5373 {
5374 // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID);
5375 return false;
5376 }
5377 }
5378 catch (Exception e)
5379 {
5380 m_log.DebugFormat("[SCENE]: Exception authorizing agent: {0} "+ e.StackTrace, e.Message);
5381 return false;
5382 }
5383
5384 if (position == Vector3.Zero) // Teleport
5385 {
5386 float posX = 128.0f;
5387 float posY = 128.0f;
5388
5389 if (!TestLandRestrictions(agentID, out reason, ref posX, ref posY))
5390 {
5391 // m_log.DebugFormat("[SCENE]: Denying {0} because they are banned on all parcels", agentID);
5392 return false;
5393 }
5394 }
5395 else // Walking
5396 {
5397 ILandObject land = LandChannel.GetLandObject(position.X, position.Y);
5398 if (land == null)
5399 return false;
5400
5401 bool banned = land.IsBannedFromLand(agentID);
5402 bool restricted = land.IsRestrictedFromLand(agentID);
5403
5404 if (banned || restricted)
5405 return false;
5406 }
5407
5089 reason = String.Empty; 5408 reason = String.Empty;
5090 return true; 5409 return true;
5091 } 5410 }
5092 5411
5093 /// <summary> 5412 public void StartTimerWatchdog()
5413 {
5414 m_timerWatchdog.Interval = 1000;
5415 m_timerWatchdog.Elapsed += TimerWatchdog;
5416 m_timerWatchdog.AutoReset = true;
5417 m_timerWatchdog.Start();
5418 }
5419
5420 public void TimerWatchdog(object sender, ElapsedEventArgs e)
5421 {
5422 CheckHeartbeat();
5423 }
5424
5094 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the 5425 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the
5095 /// autopilot that moves an avatar to a sit target!. 5426 /// autopilot that moves an avatar to a sit target!.
5096 /// </summary> 5427 /// </summary>