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.cs504
1 files changed, 418 insertions, 86 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index dff43fd..cd5ac6c 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -96,6 +96,7 @@ namespace OpenSim.Region.Framework.Scenes
96 // TODO: need to figure out how allow client agents but deny 96 // TODO: need to figure out how allow client agents but deny
97 // root agents when ACL denies access to root agent 97 // root agents when ACL denies access to root agent
98 public bool m_strictAccessControl = true; 98 public bool m_strictAccessControl = true;
99 public bool m_seeIntoBannedRegion = false;
99 public int MaxUndoCount = 5; 100 public int MaxUndoCount = 5;
100 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet; 101 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet;
101 public bool LoginLock = false; 102 public bool LoginLock = false;
@@ -111,12 +112,14 @@ namespace OpenSim.Region.Framework.Scenes
111 112
112 protected int m_splitRegionID; 113 protected int m_splitRegionID;
113 protected Timer m_restartWaitTimer = new Timer(); 114 protected Timer m_restartWaitTimer = new Timer();
115 protected Timer m_timerWatchdog = new Timer();
114 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); 116 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
115 protected List<RegionInfo> m_neighbours = new List<RegionInfo>(); 117 protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
116 protected string m_simulatorVersion = "OpenSimulator Server"; 118 protected string m_simulatorVersion = "OpenSimulator Server";
117 protected ModuleLoader m_moduleLoader; 119 protected ModuleLoader m_moduleLoader;
118 protected AgentCircuitManager m_authenticateHandler; 120 protected AgentCircuitManager m_authenticateHandler;
119 protected SceneCommunicationService m_sceneGridService; 121 protected SceneCommunicationService m_sceneGridService;
122 protected ISnmpModule m_snmpService = null;
120 123
121 protected ISimulationDataService m_SimulationDataService; 124 protected ISimulationDataService m_SimulationDataService;
122 protected IEstateDataService m_EstateDataService; 125 protected IEstateDataService m_EstateDataService;
@@ -168,7 +171,7 @@ namespace OpenSim.Region.Framework.Scenes
168 private int m_update_events = 1; 171 private int m_update_events = 1;
169 private int m_update_backup = 200; 172 private int m_update_backup = 200;
170 private int m_update_terrain = 50; 173 private int m_update_terrain = 50;
171// private int m_update_land = 1; 174 private int m_update_land = 10;
172 private int m_update_coarse_locations = 50; 175 private int m_update_coarse_locations = 50;
173 176
174 private int agentMS; 177 private int agentMS;
@@ -183,6 +186,7 @@ namespace OpenSim.Region.Framework.Scenes
183 private int landMS; 186 private int landMS;
184 private int lastCompletedFrame; 187 private int lastCompletedFrame;
185 188
189 public bool CombineRegions = false;
186 /// <summary> 190 /// <summary>
187 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched 191 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched
188 /// asynchronously from the update loop. 192 /// asynchronously from the update loop.
@@ -205,10 +209,12 @@ namespace OpenSim.Region.Framework.Scenes
205 private bool m_scripts_enabled = true; 209 private bool m_scripts_enabled = true;
206 private string m_defaultScriptEngine; 210 private string m_defaultScriptEngine;
207 private int m_LastLogin; 211 private int m_LastLogin;
208 private Thread HeartbeatThread; 212 private Thread HeartbeatThread = null;
209 private volatile bool shuttingdown; 213 private volatile bool shuttingdown;
210 214
211 private int m_lastUpdate; 215 private int m_lastUpdate;
216 private int m_lastIncoming;
217 private int m_lastOutgoing;
212 private bool m_firstHeartbeat = true; 218 private bool m_firstHeartbeat = true;
213 219
214 private object m_deleting_scene_object = new object(); 220 private object m_deleting_scene_object = new object();
@@ -256,6 +262,19 @@ namespace OpenSim.Region.Framework.Scenes
256 get { return m_sceneGridService; } 262 get { return m_sceneGridService; }
257 } 263 }
258 264
265 public ISnmpModule SnmpService
266 {
267 get
268 {
269 if (m_snmpService == null)
270 {
271 m_snmpService = RequestModuleInterface<ISnmpModule>();
272 }
273
274 return m_snmpService;
275 }
276 }
277
259 public ISimulationDataService SimulationDataService 278 public ISimulationDataService SimulationDataService
260 { 279 {
261 get 280 get
@@ -537,6 +556,9 @@ namespace OpenSim.Region.Framework.Scenes
537 m_EstateDataService = estateDataService; 556 m_EstateDataService = estateDataService;
538 m_regionHandle = m_regInfo.RegionHandle; 557 m_regionHandle = m_regInfo.RegionHandle;
539 m_regionName = m_regInfo.RegionName; 558 m_regionName = m_regInfo.RegionName;
559 m_lastUpdate = Util.EnvironmentTickCount();
560 m_lastIncoming = 0;
561 m_lastOutgoing = 0;
540 562
541 m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this); 563 m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this);
542 m_asyncSceneObjectDeleter.Enabled = true; 564 m_asyncSceneObjectDeleter.Enabled = true;
@@ -650,11 +672,13 @@ namespace OpenSim.Region.Framework.Scenes
650 //Animation states 672 //Animation states
651 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); 673 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
652 // TODO: Change default to true once the feature is supported 674 // TODO: Change default to true once the feature is supported
653 m_usePreJump = startupConfig.GetBoolean("enableprejump", false); 675 m_usePreJump = startupConfig.GetBoolean("enableprejump", true);
654 676
655 m_physicalPrim = startupConfig.GetBoolean("physical_prim", true); 677 m_physicalPrim = startupConfig.GetBoolean("physical_prim", true);
656 678
657 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys); 679 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
680
681 m_log.DebugFormat("[SCENE]: prejump is {0}", m_usePreJump ? "ON" : "OFF");
658 if (RegionInfo.NonphysPrimMax > 0) 682 if (RegionInfo.NonphysPrimMax > 0)
659 { 683 {
660 m_maxNonphys = RegionInfo.NonphysPrimMax; 684 m_maxNonphys = RegionInfo.NonphysPrimMax;
@@ -686,6 +710,7 @@ namespace OpenSim.Region.Framework.Scenes
686 m_persistAfter *= 10000000; 710 m_persistAfter *= 10000000;
687 711
688 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); 712 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
713 m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine);
689 714
690 IConfig packetConfig = m_config.Configs["PacketPool"]; 715 IConfig packetConfig = m_config.Configs["PacketPool"];
691 if (packetConfig != null) 716 if (packetConfig != null)
@@ -695,6 +720,8 @@ namespace OpenSim.Region.Framework.Scenes
695 } 720 }
696 721
697 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); 722 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
723 m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion);
724 CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false);
698 725
699 m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true); 726 m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true);
700 if (m_generateMaptiles) 727 if (m_generateMaptiles)
@@ -730,9 +757,9 @@ namespace OpenSim.Region.Framework.Scenes
730 m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain); 757 m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain);
731 m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning); 758 m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning);
732 } 759 }
733 catch 760 catch (Exception e)
734 { 761 {
735 m_log.Warn("[SCENE]: Failed to load StartupConfig"); 762 m_log.Error("[SCENE]: Failed to load StartupConfig: " + e.ToString());
736 } 763 }
737 764
738 #endregion Region Config 765 #endregion Region Config
@@ -1143,7 +1170,9 @@ namespace OpenSim.Region.Framework.Scenes
1143 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); 1170 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
1144 if (HeartbeatThread != null) 1171 if (HeartbeatThread != null)
1145 { 1172 {
1173 m_log.ErrorFormat("[SCENE]: Restarting heartbeat thread because it hasn't reported in in region {0}", RegionInfo.RegionName);
1146 HeartbeatThread.Abort(); 1174 HeartbeatThread.Abort();
1175 Watchdog.AbortThread(HeartbeatThread.ManagedThreadId);
1147 HeartbeatThread = null; 1176 HeartbeatThread = null;
1148 } 1177 }
1149 m_lastUpdate = Util.EnvironmentTickCount(); 1178 m_lastUpdate = Util.EnvironmentTickCount();
@@ -1186,9 +1215,6 @@ namespace OpenSim.Region.Framework.Scenes
1186 { 1215 {
1187 while (!shuttingdown) 1216 while (!shuttingdown)
1188 Update(); 1217 Update();
1189
1190 m_lastUpdate = Util.EnvironmentTickCount();
1191 m_firstHeartbeat = false;
1192 } 1218 }
1193 catch (ThreadAbortException) 1219 catch (ThreadAbortException)
1194 { 1220 {
@@ -1286,6 +1312,13 @@ namespace OpenSim.Region.Framework.Scenes
1286 eventMS = Util.EnvironmentTickCountSubtract(evMS); ; 1312 eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
1287 } 1313 }
1288 1314
1315 // if (Frame % m_update_land == 0)
1316 // {
1317 // int ldMS = Util.EnvironmentTickCount();
1318 // UpdateLand();
1319 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1320 // }
1321
1289 if (Frame % m_update_backup == 0) 1322 if (Frame % m_update_backup == 0)
1290 { 1323 {
1291 int backMS = Util.EnvironmentTickCount(); 1324 int backMS = Util.EnvironmentTickCount();
@@ -1387,12 +1420,16 @@ namespace OpenSim.Region.Framework.Scenes
1387 maintc = Util.EnvironmentTickCountSubtract(maintc); 1420 maintc = Util.EnvironmentTickCountSubtract(maintc);
1388 maintc = (int)(MinFrameTime * 1000) - maintc; 1421 maintc = (int)(MinFrameTime * 1000) - maintc;
1389 1422
1423
1424 m_lastUpdate = Util.EnvironmentTickCount();
1425 m_firstHeartbeat = false;
1426
1390 if (maintc > 0) 1427 if (maintc > 0)
1391 Thread.Sleep(maintc); 1428 Thread.Sleep(maintc);
1392 1429
1393 // Tell the watchdog that this thread is still alive 1430 // Tell the watchdog that this thread is still alive
1394 Watchdog.UpdateThread(); 1431 Watchdog.UpdateThread();
1395 } 1432 }
1396 1433
1397 public void AddGroupTarget(SceneObjectGroup grp) 1434 public void AddGroupTarget(SceneObjectGroup grp)
1398 { 1435 {
@@ -1408,9 +1445,9 @@ namespace OpenSim.Region.Framework.Scenes
1408 1445
1409 private void CheckAtTargets() 1446 private void CheckAtTargets()
1410 { 1447 {
1411 Dictionary<UUID, SceneObjectGroup>.ValueCollection objs; 1448 List<SceneObjectGroup> objs = new List<SceneObjectGroup>();
1412 lock (m_groupsWithTargets) 1449 lock (m_groupsWithTargets)
1413 objs = m_groupsWithTargets.Values; 1450 objs = new List<SceneObjectGroup>(m_groupsWithTargets.Values);
1414 1451
1415 foreach (SceneObjectGroup entry in objs) 1452 foreach (SceneObjectGroup entry in objs)
1416 entry.checkAtTargets(); 1453 entry.checkAtTargets();
@@ -1494,7 +1531,7 @@ namespace OpenSim.Region.Framework.Scenes
1494 msg.fromAgentName = "Server"; 1531 msg.fromAgentName = "Server";
1495 msg.dialog = (byte)19; // Object msg 1532 msg.dialog = (byte)19; // Object msg
1496 msg.fromGroup = false; 1533 msg.fromGroup = false;
1497 msg.offline = (byte)0; 1534 msg.offline = (byte)1;
1498 msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID; 1535 msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID;
1499 msg.Position = Vector3.Zero; 1536 msg.Position = Vector3.Zero;
1500 msg.RegionID = RegionInfo.RegionID.Guid; 1537 msg.RegionID = RegionInfo.RegionID.Guid;
@@ -1729,14 +1766,24 @@ namespace OpenSim.Region.Framework.Scenes
1729 /// <returns></returns> 1766 /// <returns></returns>
1730 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter) 1767 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter)
1731 { 1768 {
1769
1770 float wheight = (float)RegionInfo.RegionSettings.WaterHeight;
1771 Vector3 wpos = Vector3.Zero;
1772 // Check for water surface intersection from above
1773 if ( (RayStart.Z > wheight) && (RayEnd.Z < wheight) )
1774 {
1775 float ratio = (RayStart.Z - wheight) / (RayStart.Z - RayEnd.Z);
1776 wpos.X = RayStart.X - (ratio * (RayStart.X - RayEnd.X));
1777 wpos.Y = RayStart.Y - (ratio * (RayStart.Y - RayEnd.Y));
1778 wpos.Z = wheight;
1779 }
1780
1732 Vector3 pos = Vector3.Zero; 1781 Vector3 pos = Vector3.Zero;
1733 if (RayEndIsIntersection == (byte)1) 1782 if (RayEndIsIntersection == (byte)1)
1734 { 1783 {
1735 pos = RayEnd; 1784 pos = RayEnd;
1736 return pos;
1737 } 1785 }
1738 1786 else if (RayTargetID != UUID.Zero)
1739 if (RayTargetID != UUID.Zero)
1740 { 1787 {
1741 SceneObjectPart target = GetSceneObjectPart(RayTargetID); 1788 SceneObjectPart target = GetSceneObjectPart(RayTargetID);
1742 1789
@@ -1758,7 +1805,7 @@ namespace OpenSim.Region.Framework.Scenes
1758 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter); 1805 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter);
1759 1806
1760 // Un-comment out the following line to Get Raytrace results printed to the console. 1807 // Un-comment out the following line to Get Raytrace results printed to the console.
1761 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); 1808 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
1762 float ScaleOffset = 0.5f; 1809 float ScaleOffset = 0.5f;
1763 1810
1764 // If we hit something 1811 // If we hit something
@@ -1781,13 +1828,10 @@ namespace OpenSim.Region.Framework.Scenes
1781 //pos.Z -= 0.25F; 1828 //pos.Z -= 0.25F;
1782 1829
1783 } 1830 }
1784
1785 return pos;
1786 } 1831 }
1787 else 1832 else
1788 { 1833 {
1789 // We don't have a target here, so we're going to raytrace all the objects in the scene. 1834 // We don't have a target here, so we're going to raytrace all the objects in the scene.
1790
1791 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false); 1835 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false);
1792 1836
1793 // Un-comment the following line to print the raytrace results to the console. 1837 // Un-comment the following line to print the raytrace results to the console.
@@ -1796,13 +1840,12 @@ namespace OpenSim.Region.Framework.Scenes
1796 if (ei.HitTF) 1840 if (ei.HitTF)
1797 { 1841 {
1798 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); 1842 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
1799 } else 1843 }
1844 else
1800 { 1845 {
1801 // fall back to our stupid functionality 1846 // fall back to our stupid functionality
1802 pos = RayEnd; 1847 pos = RayEnd;
1803 } 1848 }
1804
1805 return pos;
1806 } 1849 }
1807 } 1850 }
1808 else 1851 else
@@ -1813,8 +1856,12 @@ namespace OpenSim.Region.Framework.Scenes
1813 //increase height so its above the ground. 1856 //increase height so its above the ground.
1814 //should be getting the normal of the ground at the rez point and using that? 1857 //should be getting the normal of the ground at the rez point and using that?
1815 pos.Z += scale.Z / 2f; 1858 pos.Z += scale.Z / 2f;
1816 return pos; 1859// return pos;
1817 } 1860 }
1861
1862 // check against posible water intercept
1863 if (wpos.Z > pos.Z) pos = wpos;
1864 return pos;
1818 } 1865 }
1819 1866
1820 1867
@@ -1898,7 +1945,10 @@ namespace OpenSim.Region.Framework.Scenes
1898 public bool AddRestoredSceneObject( 1945 public bool AddRestoredSceneObject(
1899 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 1946 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
1900 { 1947 {
1901 return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); 1948 bool result = m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates);
1949 if (result)
1950 sceneObject.IsDeleted = false;
1951 return result;
1902 } 1952 }
1903 1953
1904 /// <summary> 1954 /// <summary>
@@ -1988,6 +2038,15 @@ namespace OpenSim.Region.Framework.Scenes
1988 /// </summary> 2038 /// </summary>
1989 public void DeleteAllSceneObjects() 2039 public void DeleteAllSceneObjects()
1990 { 2040 {
2041 DeleteAllSceneObjects(false);
2042 }
2043
2044 /// <summary>
2045 /// Delete every object from the scene. This does not include attachments worn by avatars.
2046 /// </summary>
2047 public void DeleteAllSceneObjects(bool exceptNoCopy)
2048 {
2049 List<SceneObjectGroup> toReturn = new List<SceneObjectGroup>();
1991 lock (Entities) 2050 lock (Entities)
1992 { 2051 {
1993 EntityBase[] entities = Entities.GetEntities(); 2052 EntityBase[] entities = Entities.GetEntities();
@@ -1996,11 +2055,24 @@ namespace OpenSim.Region.Framework.Scenes
1996 if (e is SceneObjectGroup) 2055 if (e is SceneObjectGroup)
1997 { 2056 {
1998 SceneObjectGroup sog = (SceneObjectGroup)e; 2057 SceneObjectGroup sog = (SceneObjectGroup)e;
1999 if (!sog.IsAttachment) 2058 if (sog != null && !sog.IsAttachment)
2000 DeleteSceneObject((SceneObjectGroup)e, false); 2059 {
2060 if (!exceptNoCopy || ((sog.GetEffectivePermissions() & (uint)PermissionMask.Copy) != 0))
2061 {
2062 DeleteSceneObject((SceneObjectGroup)e, false);
2063 }
2064 else
2065 {
2066 toReturn.Add((SceneObjectGroup)e);
2067 }
2068 }
2001 } 2069 }
2002 } 2070 }
2003 } 2071 }
2072 if (toReturn.Count > 0)
2073 {
2074 returnObjects(toReturn.ToArray(), UUID.Zero);
2075 }
2004 } 2076 }
2005 2077
2006 /// <summary> 2078 /// <summary>
@@ -2048,6 +2120,8 @@ namespace OpenSim.Region.Framework.Scenes
2048 } 2120 }
2049 2121
2050 group.DeleteGroupFromScene(silent); 2122 group.DeleteGroupFromScene(silent);
2123 if (!silent)
2124 SendKillObject(new List<uint>() { group.LocalId });
2051 2125
2052// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); 2126// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
2053 } 2127 }
@@ -2402,10 +2476,17 @@ namespace OpenSim.Region.Framework.Scenes
2402 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns> 2476 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns>
2403 public bool AddSceneObject(SceneObjectGroup sceneObject) 2477 public bool AddSceneObject(SceneObjectGroup sceneObject)
2404 { 2478 {
2479 if (sceneObject.OwnerID == UUID.Zero)
2480 {
2481 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero", sceneObject.UUID);
2482 return false;
2483 }
2484
2405 // If the user is banned, we won't let any of their objects 2485 // If the user is banned, we won't let any of their objects
2406 // enter. Period. 2486 // enter. Period.
2407 // 2487 //
2408 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID)) 2488 int flags = GetUserFlags(sceneObject.OwnerID);
2489 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID, flags))
2409 { 2490 {
2410 m_log.Info("[INTERREGION]: Denied prim crossing for " + 2491 m_log.Info("[INTERREGION]: Denied prim crossing for " +
2411 "banned avatar"); 2492 "banned avatar");
@@ -2452,12 +2533,23 @@ namespace OpenSim.Region.Framework.Scenes
2452 } 2533 }
2453 else 2534 else
2454 { 2535 {
2536 m_log.DebugFormat("[SCENE]: Attachment {0} arrived and scene presence was not found, setting to temp", sceneObject.UUID);
2455 RootPrim.RemFlag(PrimFlags.TemporaryOnRez); 2537 RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
2456 RootPrim.AddFlag(PrimFlags.TemporaryOnRez); 2538 RootPrim.AddFlag(PrimFlags.TemporaryOnRez);
2457 } 2539 }
2540 if (sceneObject.OwnerID == UUID.Zero)
2541 {
2542 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero after attachment processing. BUG!", sceneObject.UUID);
2543 return false;
2544 }
2458 } 2545 }
2459 else 2546 else
2460 { 2547 {
2548 if (sceneObject.OwnerID == UUID.Zero)
2549 {
2550 m_log.ErrorFormat("[SCENE]: Owner ID for non-attachment {0} was zero", sceneObject.UUID);
2551 return false;
2552 }
2461 AddRestoredSceneObject(sceneObject, true, false); 2553 AddRestoredSceneObject(sceneObject, true, false);
2462 2554
2463 if (!Permissions.CanObjectEntry(sceneObject.UUID, 2555 if (!Permissions.CanObjectEntry(sceneObject.UUID,
@@ -2487,6 +2579,24 @@ namespace OpenSim.Region.Framework.Scenes
2487 return 2; // StateSource.PrimCrossing 2579 return 2; // StateSource.PrimCrossing
2488 } 2580 }
2489 2581
2582 public int GetUserFlags(UUID user)
2583 {
2584 //Unfortunately the SP approach means that the value is cached until region is restarted
2585 /*
2586 ScenePresence sp;
2587 if (TryGetScenePresence(user, out sp))
2588 {
2589 return sp.UserFlags;
2590 }
2591 else
2592 {
2593 */
2594 UserAccount uac = UserAccountService.GetUserAccount(RegionInfo.ScopeID, user);
2595 if (uac == null)
2596 return 0;
2597 return uac.UserFlags;
2598 //}
2599 }
2490 #endregion 2600 #endregion
2491 2601
2492 #region Add/Remove Avatar Methods 2602 #region Add/Remove Avatar Methods
@@ -2508,6 +2618,7 @@ namespace OpenSim.Region.Framework.Scenes
2508 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2618 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2509 2619
2510 CheckHeartbeat(); 2620 CheckHeartbeat();
2621 ScenePresence presence;
2511 2622
2512 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here 2623 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here
2513 { 2624 {
@@ -2543,7 +2654,14 @@ namespace OpenSim.Region.Framework.Scenes
2543 2654
2544 EventManager.TriggerOnNewClient(client); 2655 EventManager.TriggerOnNewClient(client);
2545 if (vialogin) 2656 if (vialogin)
2657 {
2546 EventManager.TriggerOnClientLogin(client); 2658 EventManager.TriggerOnClientLogin(client);
2659
2660 // Send initial parcel data
2661 Vector3 pos = createdSp.AbsolutePosition;
2662 ILandObject land = LandChannel.GetLandObject(pos.X, pos.Y);
2663 land.SendLandUpdateToClient(client);
2664 }
2547 } 2665 }
2548 } 2666 }
2549 2667
@@ -2632,19 +2750,12 @@ namespace OpenSim.Region.Framework.Scenes
2632 // and the scene presence and the client, if they exist 2750 // and the scene presence and the client, if they exist
2633 try 2751 try
2634 { 2752 {
2635 // We need to wait for the client to make UDP contact first. 2753 ScenePresence sp = GetScenePresence(agentID);
2636 // It's the UDP contact that creates the scene presence 2754 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2637 ScenePresence sp = WaitGetScenePresence(agentID); 2755
2638 if (sp != null) 2756 if (sp != null)
2639 {
2640 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2641
2642 sp.ControllingClient.Close(); 2757 sp.ControllingClient.Close();
2643 } 2758
2644 else
2645 {
2646 m_log.WarnFormat("[SCENE]: Could not find scene presence for {0}", agentID);
2647 }
2648 // BANG! SLASH! 2759 // BANG! SLASH!
2649 m_authenticateHandler.RemoveCircuit(agentID); 2760 m_authenticateHandler.RemoveCircuit(agentID);
2650 2761
@@ -2744,6 +2855,7 @@ namespace OpenSim.Region.Framework.Scenes
2744 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory; 2855 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory;
2745 client.OnUpdateInventoryItem += UpdateInventoryItemAsset; 2856 client.OnUpdateInventoryItem += UpdateInventoryItemAsset;
2746 client.OnCopyInventoryItem += CopyInventoryItem; 2857 client.OnCopyInventoryItem += CopyInventoryItem;
2858 client.OnMoveItemsAndLeaveCopy += MoveInventoryItemsLeaveCopy;
2747 client.OnMoveInventoryItem += MoveInventoryItem; 2859 client.OnMoveInventoryItem += MoveInventoryItem;
2748 client.OnRemoveInventoryItem += RemoveInventoryItem; 2860 client.OnRemoveInventoryItem += RemoveInventoryItem;
2749 client.OnRemoveInventoryFolder += RemoveInventoryFolder; 2861 client.OnRemoveInventoryFolder += RemoveInventoryFolder;
@@ -2921,15 +3033,16 @@ namespace OpenSim.Region.Framework.Scenes
2921 /// </summary> 3033 /// </summary>
2922 /// <param name="agentId">The avatar's Unique ID</param> 3034 /// <param name="agentId">The avatar's Unique ID</param>
2923 /// <param name="client">The IClientAPI for the client</param> 3035 /// <param name="client">The IClientAPI for the client</param>
2924 public virtual void TeleportClientHome(UUID agentId, IClientAPI client) 3036 public virtual bool TeleportClientHome(UUID agentId, IClientAPI client)
2925 { 3037 {
2926 if (m_teleportModule != null) 3038 if (m_teleportModule != null)
2927 m_teleportModule.TeleportHome(agentId, client); 3039 return m_teleportModule.TeleportHome(agentId, client);
2928 else 3040 else
2929 { 3041 {
2930 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active"); 3042 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active");
2931 client.SendTeleportFailed("Unable to perform teleports on this simulator."); 3043 client.SendTeleportFailed("Unable to perform teleports on this simulator.");
2932 } 3044 }
3045 return false;
2933 } 3046 }
2934 3047
2935 /// <summary> 3048 /// <summary>
@@ -3021,6 +3134,16 @@ namespace OpenSim.Region.Framework.Scenes
3021 /// <param name="flags"></param> 3134 /// <param name="flags"></param>
3022 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags) 3135 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags)
3023 { 3136 {
3137 //Add half the avatar's height so that the user doesn't fall through prims
3138 ScenePresence presence;
3139 if (TryGetScenePresence(remoteClient.AgentId, out presence))
3140 {
3141 if (presence.Appearance != null)
3142 {
3143 position.Z = position.Z + (presence.Appearance.AvatarHeight / 2);
3144 }
3145 }
3146
3024 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt)) 3147 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt))
3025 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot. 3148 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot.
3026 m_dialogModule.SendAlertToUser(remoteClient, "Home position set."); 3149 m_dialogModule.SendAlertToUser(remoteClient, "Home position set.");
@@ -3089,8 +3212,9 @@ namespace OpenSim.Region.Framework.Scenes
3089 regions.Remove(RegionInfo.RegionHandle); 3212 regions.Remove(RegionInfo.RegionHandle);
3090 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3213 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3091 } 3214 }
3092 3215 m_log.Debug("[Scene] Beginning ClientClosed");
3093 m_eventManager.TriggerClientClosed(agentID, this); 3216 m_eventManager.TriggerClientClosed(agentID, this);
3217 m_log.Debug("[Scene] Finished ClientClosed");
3094 } 3218 }
3095 catch (NullReferenceException) 3219 catch (NullReferenceException)
3096 { 3220 {
@@ -3098,7 +3222,12 @@ namespace OpenSim.Region.Framework.Scenes
3098 // Avatar is already disposed :/ 3222 // Avatar is already disposed :/
3099 } 3223 }
3100 3224
3225 m_log.Debug("[Scene] Beginning OnRemovePresence");
3101 m_eventManager.TriggerOnRemovePresence(agentID); 3226 m_eventManager.TriggerOnRemovePresence(agentID);
3227 m_log.Debug("[Scene] Finished OnRemovePresence");
3228
3229 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3230 AttachmentsModule.SaveChangedAttachments(avatar);
3102 3231
3103 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc) 3232 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3104 AttachmentsModule.SaveChangedAttachments(avatar); 3233 AttachmentsModule.SaveChangedAttachments(avatar);
@@ -3107,7 +3236,7 @@ namespace OpenSim.Region.Framework.Scenes
3107 delegate(IClientAPI client) 3236 delegate(IClientAPI client)
3108 { 3237 {
3109 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3238 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3110 try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); } 3239 try { client.SendKillObject(avatar.RegionHandle, new List<uint>() { avatar.LocalId}); }
3111 catch (NullReferenceException) { } 3240 catch (NullReferenceException) { }
3112 }); 3241 });
3113 3242
@@ -3118,8 +3247,11 @@ namespace OpenSim.Region.Framework.Scenes
3118 } 3247 }
3119 3248
3120 // Remove the avatar from the scene 3249 // Remove the avatar from the scene
3250 m_log.Debug("[Scene] Begin RemoveScenePresence");
3121 m_sceneGraph.RemoveScenePresence(agentID); 3251 m_sceneGraph.RemoveScenePresence(agentID);
3252 m_log.Debug("[Scene] Finished RemoveScenePresence. Removing the client manager");
3122 m_clientManager.Remove(agentID); 3253 m_clientManager.Remove(agentID);
3254 m_log.Debug("[Scene] Removed the client manager. Firing avatar.close");
3123 3255
3124 try 3256 try
3125 { 3257 {
@@ -3133,9 +3265,10 @@ namespace OpenSim.Region.Framework.Scenes
3133 { 3265 {
3134 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString()); 3266 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString());
3135 } 3267 }
3136 3268 m_log.Debug("[Scene] Done. Firing RemoveCircuit");
3137 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3269 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
3138// CleanDroppedAttachments(); 3270// CleanDroppedAttachments();
3271 m_log.Debug("[Scene] The avatar has left the building");
3139 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 3272 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
3140 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); 3273 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
3141 } 3274 }
@@ -3166,19 +3299,24 @@ namespace OpenSim.Region.Framework.Scenes
3166 3299
3167 #region Entities 3300 #region Entities
3168 3301
3169 public void SendKillObject(uint localID) 3302 public void SendKillObject(List<uint> localIDs)
3170 { 3303 {
3171 SceneObjectPart part = GetSceneObjectPart(localID); 3304 List<uint> deleteIDs = new List<uint>();
3172 if (part != null) // It is a prim 3305
3306 foreach (uint localID in localIDs)
3173 { 3307 {
3174 if (!part.ParentGroup.IsDeleted) // Valid 3308 SceneObjectPart part = GetSceneObjectPart(localID);
3309 if (part != null) // It is a prim
3175 { 3310 {
3176 if (part.ParentGroup.RootPart != part) // Child part 3311 if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid
3177 return; 3312 {
3313 if (part.ParentGroup.RootPart != part) // Child part
3314 continue;
3315 }
3178 } 3316 }
3317 deleteIDs.Add(localID);
3179 } 3318 }
3180 3319 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, deleteIDs); });
3181 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); });
3182 } 3320 }
3183 3321
3184 #endregion 3322 #endregion
@@ -3196,7 +3334,6 @@ namespace OpenSim.Region.Framework.Scenes
3196 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate; 3334 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
3197 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar; 3335 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar;
3198 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid; 3336 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
3199 m_sceneGridService.KiPrimitive += SendKillObject;
3200 m_sceneGridService.OnGetLandData += GetLandData; 3337 m_sceneGridService.OnGetLandData += GetLandData;
3201 } 3338 }
3202 3339
@@ -3205,7 +3342,6 @@ namespace OpenSim.Region.Framework.Scenes
3205 /// </summary> 3342 /// </summary>
3206 public void UnRegisterRegionWithComms() 3343 public void UnRegisterRegionWithComms()
3207 { 3344 {
3208 m_sceneGridService.KiPrimitive -= SendKillObject;
3209 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid; 3345 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid;
3210 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar; 3346 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar;
3211 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate; 3347 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate;
@@ -3285,13 +3421,16 @@ namespace OpenSim.Region.Framework.Scenes
3285 sp = null; 3421 sp = null;
3286 } 3422 }
3287 3423
3288 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3289 3424
3290 //On login test land permisions 3425 //On login test land permisions
3291 if (vialogin) 3426 if (vialogin)
3292 { 3427 {
3293 if (land != null && !TestLandRestrictions(agent, land, out reason)) 3428 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
3429 if (cache != null)
3430 cache.Remove(agent.firstname + " " + agent.lastname);
3431 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3294 { 3432 {
3433 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString());
3295 return false; 3434 return false;
3296 } 3435 }
3297 } 3436 }
@@ -3314,8 +3453,13 @@ namespace OpenSim.Region.Framework.Scenes
3314 3453
3315 try 3454 try
3316 { 3455 {
3317 if (!AuthorizeUser(agent, out reason)) 3456 // Always check estate if this is a login. Always
3318 return false; 3457 // check if banned regions are to be blacked out.
3458 if (vialogin || (!m_seeIntoBannedRegion))
3459 {
3460 if (!AuthorizeUser(agent, out reason))
3461 return false;
3462 }
3319 } 3463 }
3320 catch (Exception e) 3464 catch (Exception e)
3321 { 3465 {
@@ -3417,6 +3561,8 @@ namespace OpenSim.Region.Framework.Scenes
3417 } 3561 }
3418 } 3562 }
3419 // Honor parcel landing type and position. 3563 // Honor parcel landing type and position.
3564 /*
3565 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3420 if (land != null) 3566 if (land != null)
3421 { 3567 {
3422 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) 3568 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero)
@@ -3424,26 +3570,34 @@ namespace OpenSim.Region.Framework.Scenes
3424 agent.startpos = land.LandData.UserLocation; 3570 agent.startpos = land.LandData.UserLocation;
3425 } 3571 }
3426 } 3572 }
3573 */// This is now handled properly in ScenePresence.MakeRootAgent
3427 } 3574 }
3428 3575
3429 return true; 3576 return true;
3430 } 3577 }
3431 3578
3432 private bool TestLandRestrictions(AgentCircuitData agent, ILandObject land, out string reason) 3579 private bool TestLandRestrictions(UUID agentID, out string reason, ref float posX, ref float posY)
3433 { 3580 {
3434 3581 reason = String.Empty;
3435 bool banned = land.IsBannedFromLand(agent.AgentID); 3582 if (Permissions.IsGod(agentID))
3436 bool restricted = land.IsRestrictedFromLand(agent.AgentID); 3583 return true;
3584
3585 ILandObject land = LandChannel.GetLandObject(posX, posY);
3586 if (land == null)
3587 return false;
3588
3589 bool banned = land.IsBannedFromLand(agentID);
3590 bool restricted = land.IsRestrictedFromLand(agentID);
3437 3591
3438 if (banned || restricted) 3592 if (banned || restricted)
3439 { 3593 {
3440 ILandObject nearestParcel = GetNearestAllowedParcel(agent.AgentID, agent.startpos.X, agent.startpos.Y); 3594 ILandObject nearestParcel = GetNearestAllowedParcel(agentID, posX, posY);
3441 if (nearestParcel != null) 3595 if (nearestParcel != null)
3442 { 3596 {
3443 //Move agent to nearest allowed 3597 //Move agent to nearest allowed
3444 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel); 3598 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel);
3445 agent.startpos.X = newPosition.X; 3599 posX = newPosition.X;
3446 agent.startpos.Y = newPosition.Y; 3600 posY = newPosition.Y;
3447 } 3601 }
3448 else 3602 else
3449 { 3603 {
@@ -3505,7 +3659,7 @@ namespace OpenSim.Region.Framework.Scenes
3505 3659
3506 if (!m_strictAccessControl) return true; 3660 if (!m_strictAccessControl) return true;
3507 if (Permissions.IsGod(agent.AgentID)) return true; 3661 if (Permissions.IsGod(agent.AgentID)) return true;
3508 3662
3509 if (AuthorizationService != null) 3663 if (AuthorizationService != null)
3510 { 3664 {
3511 if (!AuthorizationService.IsAuthorizedForRegion( 3665 if (!AuthorizationService.IsAuthorizedForRegion(
@@ -3513,14 +3667,14 @@ namespace OpenSim.Region.Framework.Scenes
3513 { 3667 {
3514 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region", 3668 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region",
3515 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3669 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
3516 3670
3517 return false; 3671 return false;
3518 } 3672 }
3519 } 3673 }
3520 3674
3521 if (m_regInfo.EstateSettings != null) 3675 if (m_regInfo.EstateSettings != null)
3522 { 3676 {
3523 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID)) 3677 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID,0))
3524 { 3678 {
3525 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", 3679 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
3526 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3680 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
@@ -3710,6 +3864,13 @@ namespace OpenSim.Region.Framework.Scenes
3710 3864
3711 // We have to wait until the viewer contacts this region after receiving EAC. 3865 // We have to wait until the viewer contacts this region after receiving EAC.
3712 // That calls AddNewClient, which finally creates the ScenePresence 3866 // That calls AddNewClient, which finally creates the ScenePresence
3867 int flags = GetUserFlags(cAgentData.AgentID);
3868 if (m_regInfo.EstateSettings.IsBanned(cAgentData.AgentID, flags))
3869 {
3870 m_log.DebugFormat("[SCENE]: Denying root agent entry to {0}: banned", cAgentData.AgentID);
3871 return false;
3872 }
3873
3713 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); 3874 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2);
3714 if (nearestParcel == null) 3875 if (nearestParcel == null)
3715 { 3876 {
@@ -3725,7 +3886,6 @@ namespace OpenSim.Region.Framework.Scenes
3725 return false; 3886 return false;
3726 } 3887 }
3727 3888
3728
3729 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 3889 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
3730 3890
3731 if (childAgentUpdate != null) 3891 if (childAgentUpdate != null)
@@ -3792,12 +3952,22 @@ namespace OpenSim.Region.Framework.Scenes
3792 return false; 3952 return false;
3793 } 3953 }
3794 3954
3955 public bool IncomingCloseAgent(UUID agentID)
3956 {
3957 return IncomingCloseAgent(agentID, false);
3958 }
3959
3960 public bool IncomingCloseChildAgent(UUID agentID)
3961 {
3962 return IncomingCloseAgent(agentID, true);
3963 }
3964
3795 /// <summary> 3965 /// <summary>
3796 /// Tell a single agent to disconnect from the region. 3966 /// Tell a single agent to disconnect from the region.
3797 /// </summary> 3967 /// </summary>
3798 /// <param name="regionHandle"></param>
3799 /// <param name="agentID"></param> 3968 /// <param name="agentID"></param>
3800 public bool IncomingCloseAgent(UUID agentID) 3969 /// <param name="childOnly"></param>
3970 public bool IncomingCloseAgent(UUID agentID, bool childOnly)
3801 { 3971 {
3802 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 3972 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
3803 3973
@@ -3809,7 +3979,7 @@ namespace OpenSim.Region.Framework.Scenes
3809 { 3979 {
3810 m_sceneGraph.removeUserCount(false); 3980 m_sceneGraph.removeUserCount(false);
3811 } 3981 }
3812 else 3982 else if (!childOnly)
3813 { 3983 {
3814 m_sceneGraph.removeUserCount(true); 3984 m_sceneGraph.removeUserCount(true);
3815 } 3985 }
@@ -3825,9 +3995,12 @@ namespace OpenSim.Region.Framework.Scenes
3825 } 3995 }
3826 else 3996 else
3827 presence.ControllingClient.SendShutdownConnectionNotice(); 3997 presence.ControllingClient.SendShutdownConnectionNotice();
3998 presence.ControllingClient.Close(false);
3999 }
4000 else if (!childOnly)
4001 {
4002 presence.ControllingClient.Close(true);
3828 } 4003 }
3829
3830 presence.ControllingClient.Close();
3831 return true; 4004 return true;
3832 } 4005 }
3833 4006
@@ -4428,34 +4601,66 @@ namespace OpenSim.Region.Framework.Scenes
4428 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID); 4601 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID);
4429 } 4602 }
4430 4603
4431 public int GetHealth() 4604 public int GetHealth(out int flags, out string message)
4432 { 4605 {
4433 // Returns: 4606 // Returns:
4434 // 1 = sim is up and accepting http requests. The heartbeat has 4607 // 1 = sim is up and accepting http requests. The heartbeat has
4435 // stopped and the sim is probably locked up, but a remote 4608 // stopped and the sim is probably locked up, but a remote
4436 // admin restart may succeed 4609 // admin restart may succeed
4437 // 4610 //
4438 // 2 = Sim is up and the heartbeat is running. The sim is likely 4611 // 2 = Sim is up and the heartbeat is running. The sim is likely
4439 // usable for people within and logins _may_ work 4612 // usable for people within
4440 // 4613 //
4441 // 3 = We have seen a new user enter within the past 4 minutes 4614 // 3 = Sim is up and one packet thread is running. Sim is
4615 // unstable and will not accept new logins
4616 //
4617 // 4 = Sim is up and both packet threads are running. Sim is
4618 // likely usable
4619 //
4620 // 5 = We have seen a new user enter within the past 4 minutes
4442 // which can be seen as positive confirmation of sim health 4621 // which can be seen as positive confirmation of sim health
4443 // 4622 //
4623
4624 flags = 0;
4625 message = String.Empty;
4626
4627 CheckHeartbeat();
4628
4629 if (m_firstHeartbeat || (m_lastIncoming == 0 && m_lastOutgoing == 0))
4630 {
4631 // We're still starting
4632 // 0 means "in startup", it can't happen another way, since
4633 // to get here, we must be able to accept http connections
4634 return 0;
4635 }
4636
4444 int health=1; // Start at 1, means we're up 4637 int health=1; // Start at 1, means we're up
4445 4638
4446 if ((Util.EnvironmentTickCountSubtract(m_lastUpdate)) < 1000) 4639 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) < 1000)
4640 {
4447 health+=1; 4641 health+=1;
4448 else 4642 flags |= 1;
4643 }
4644
4645 if (Util.EnvironmentTickCountSubtract(m_lastIncoming) < 1000)
4646 {
4647 health+=1;
4648 flags |= 2;
4649 }
4650
4651 if (Util.EnvironmentTickCountSubtract(m_lastOutgoing) < 1000)
4652 {
4653 health+=1;
4654 flags |= 4;
4655 }
4656
4657 if (flags != 7)
4449 return health; 4658 return health;
4450 4659
4451 // A login in the last 4 mins? We can't be doing too badly 4660 // A login in the last 4 mins? We can't be doing too badly
4452 // 4661 //
4453 if ((Util.EnvironmentTickCountSubtract(m_LastLogin)) < 240000) 4662 if (Util.EnvironmentTickCountSubtract(m_LastLogin) < 240000)
4454 health++; 4663 health++;
4455 else
4456 return health;
4457
4458 CheckHeartbeat();
4459 4664
4460 return health; 4665 return health;
4461 } 4666 }
@@ -4648,7 +4853,7 @@ namespace OpenSim.Region.Framework.Scenes
4648 if (m_firstHeartbeat) 4853 if (m_firstHeartbeat)
4649 return; 4854 return;
4650 4855
4651 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 2000) 4856 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 5000)
4652 StartTimer(); 4857 StartTimer();
4653 } 4858 }
4654 4859
@@ -5062,6 +5267,54 @@ namespace OpenSim.Region.Framework.Scenes
5062 } 5267 }
5063 } 5268 }
5064 5269
5270// public void CleanDroppedAttachments()
5271// {
5272// List<SceneObjectGroup> objectsToDelete =
5273// new List<SceneObjectGroup>();
5274//
5275// lock (m_cleaningAttachments)
5276// {
5277// ForEachSOG(delegate (SceneObjectGroup grp)
5278// {
5279// if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp)))
5280// {
5281// UUID agentID = grp.OwnerID;
5282// if (agentID == UUID.Zero)
5283// {
5284// objectsToDelete.Add(grp);
5285// return;
5286// }
5287//
5288// ScenePresence sp = GetScenePresence(agentID);
5289// if (sp == null)
5290// {
5291// objectsToDelete.Add(grp);
5292// return;
5293// }
5294// }
5295// });
5296// }
5297//
5298// foreach (SceneObjectGroup grp in objectsToDelete)
5299// {
5300// m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID);
5301// DeleteSceneObject(grp, true);
5302// }
5303// }
5304
5305 public void ThreadAlive(int threadCode)
5306 {
5307 switch(threadCode)
5308 {
5309 case 1: // Incoming
5310 m_lastIncoming = Util.EnvironmentTickCount();
5311 break;
5312 case 2: // Incoming
5313 m_lastOutgoing = Util.EnvironmentTickCount();
5314 break;
5315 }
5316 }
5317
5065 // This method is called across the simulation connector to 5318 // This method is called across the simulation connector to
5066 // determine if a given agent is allowed in this region 5319 // determine if a given agent is allowed in this region
5067 // AS A ROOT AGENT. Returning false here will prevent them 5320 // AS A ROOT AGENT. Returning false here will prevent them
@@ -5070,6 +5323,14 @@ namespace OpenSim.Region.Framework.Scenes
5070 // child agent creation, thereby emulating the SL behavior. 5323 // child agent creation, thereby emulating the SL behavior.
5071 public bool QueryAccess(UUID agentID, Vector3 position, out string reason) 5324 public bool QueryAccess(UUID agentID, Vector3 position, out string reason)
5072 { 5325 {
5326 reason = "You are banned from the region";
5327
5328 if (Permissions.IsGod(agentID))
5329 {
5330 reason = String.Empty;
5331 return true;
5332 }
5333
5073 int num = m_sceneGraph.GetNumberOfScenePresences(); 5334 int num = m_sceneGraph.GetNumberOfScenePresences();
5074 5335
5075 if (num >= RegionInfo.RegionSettings.AgentLimit) 5336 if (num >= RegionInfo.RegionSettings.AgentLimit)
@@ -5081,11 +5342,82 @@ namespace OpenSim.Region.Framework.Scenes
5081 } 5342 }
5082 } 5343 }
5083 5344
5345 ScenePresence presence = GetScenePresence(agentID);
5346 IClientAPI client = null;
5347 AgentCircuitData aCircuit = null;
5348
5349 if (presence != null)
5350 {
5351 client = presence.ControllingClient;
5352 if (client != null)
5353 aCircuit = client.RequestClientInfo();
5354 }
5355
5356 // We may be called before there is a presence or a client.
5357 // Fake AgentCircuitData to keep IAuthorizationModule smiling
5358 if (client == null)
5359 {
5360 aCircuit = new AgentCircuitData();
5361 aCircuit.AgentID = agentID;
5362 aCircuit.firstname = String.Empty;
5363 aCircuit.lastname = String.Empty;
5364 }
5365
5366 try
5367 {
5368 if (!AuthorizeUser(aCircuit, out reason))
5369 {
5370 // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID);
5371 return false;
5372 }
5373 }
5374 catch (Exception e)
5375 {
5376 m_log.DebugFormat("[SCENE]: Exception authorizing agent: {0} "+ e.StackTrace, e.Message);
5377 return false;
5378 }
5379
5380 if (position == Vector3.Zero) // Teleport
5381 {
5382 float posX = 128.0f;
5383 float posY = 128.0f;
5384
5385 if (!TestLandRestrictions(agentID, out reason, ref posX, ref posY))
5386 {
5387 // m_log.DebugFormat("[SCENE]: Denying {0} because they are banned on all parcels", agentID);
5388 return false;
5389 }
5390 }
5391 else // Walking
5392 {
5393 ILandObject land = LandChannel.GetLandObject(position.X, position.Y);
5394 if (land == null)
5395 return false;
5396
5397 bool banned = land.IsBannedFromLand(agentID);
5398 bool restricted = land.IsRestrictedFromLand(agentID);
5399
5400 if (banned || restricted)
5401 return false;
5402 }
5403
5084 reason = String.Empty; 5404 reason = String.Empty;
5085 return true; 5405 return true;
5086 } 5406 }
5087 5407
5088 /// <summary> 5408 public void StartTimerWatchdog()
5409 {
5410 m_timerWatchdog.Interval = 1000;
5411 m_timerWatchdog.Elapsed += TimerWatchdog;
5412 m_timerWatchdog.AutoReset = true;
5413 m_timerWatchdog.Start();
5414 }
5415
5416 public void TimerWatchdog(object sender, ElapsedEventArgs e)
5417 {
5418 CheckHeartbeat();
5419 }
5420
5089 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the 5421 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the
5090 /// autopilot that moves an avatar to a sit target!. 5422 /// autopilot that moves an avatar to a sit target!.
5091 /// </summary> 5423 /// </summary>