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 2c24c0f..63ac5f6 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -93,6 +93,7 @@ namespace OpenSim.Region.Framework.Scenes
93 // TODO: need to figure out how allow client agents but deny 93 // TODO: need to figure out how allow client agents but deny
94 // root agents when ACL denies access to root agent 94 // root agents when ACL denies access to root agent
95 public bool m_strictAccessControl = true; 95 public bool m_strictAccessControl = true;
96 public bool m_seeIntoBannedRegion = false;
96 public int MaxUndoCount = 5; 97 public int MaxUndoCount = 5;
97 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet; 98 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet;
98 public bool LoginLock = false; 99 public bool LoginLock = false;
@@ -108,12 +109,14 @@ namespace OpenSim.Region.Framework.Scenes
108 109
109 protected int m_splitRegionID; 110 protected int m_splitRegionID;
110 protected Timer m_restartWaitTimer = new Timer(); 111 protected Timer m_restartWaitTimer = new Timer();
112 protected Timer m_timerWatchdog = new Timer();
111 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); 113 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
112 protected List<RegionInfo> m_neighbours = new List<RegionInfo>(); 114 protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
113 protected string m_simulatorVersion = "OpenSimulator Server"; 115 protected string m_simulatorVersion = "OpenSimulator Server";
114 protected ModuleLoader m_moduleLoader; 116 protected ModuleLoader m_moduleLoader;
115 protected AgentCircuitManager m_authenticateHandler; 117 protected AgentCircuitManager m_authenticateHandler;
116 protected SceneCommunicationService m_sceneGridService; 118 protected SceneCommunicationService m_sceneGridService;
119 protected ISnmpModule m_snmpService = null;
117 120
118 protected ISimulationDataService m_SimulationDataService; 121 protected ISimulationDataService m_SimulationDataService;
119 protected IEstateDataService m_EstateDataService; 122 protected IEstateDataService m_EstateDataService;
@@ -180,7 +183,7 @@ namespace OpenSim.Region.Framework.Scenes
180 private int m_update_events = 1; 183 private int m_update_events = 1;
181 private int m_update_backup = 200; 184 private int m_update_backup = 200;
182 private int m_update_terrain = 50; 185 private int m_update_terrain = 50;
183// private int m_update_land = 1; 186 private int m_update_land = 10;
184 private int m_update_coarse_locations = 50; 187 private int m_update_coarse_locations = 50;
185 188
186 private int agentMS; 189 private int agentMS;
@@ -195,14 +198,17 @@ namespace OpenSim.Region.Framework.Scenes
195 private int landMS; 198 private int landMS;
196 private int lastCompletedFrame; 199 private int lastCompletedFrame;
197 200
201 public bool CombineRegions = false;
198 private bool m_physics_enabled = true; 202 private bool m_physics_enabled = true;
199 private bool m_scripts_enabled = true; 203 private bool m_scripts_enabled = true;
200 private string m_defaultScriptEngine; 204 private string m_defaultScriptEngine;
201 private int m_LastLogin; 205 private int m_LastLogin;
202 private Thread HeartbeatThread; 206 private Thread HeartbeatThread = null;
203 private volatile bool shuttingdown; 207 private volatile bool shuttingdown;
204 208
205 private int m_lastUpdate; 209 private int m_lastUpdate;
210 private int m_lastIncoming;
211 private int m_lastOutgoing;
206 private bool m_firstHeartbeat = true; 212 private bool m_firstHeartbeat = true;
207 213
208 private object m_deleting_scene_object = new object(); 214 private object m_deleting_scene_object = new object();
@@ -254,6 +260,19 @@ namespace OpenSim.Region.Framework.Scenes
254 get { return m_sceneGridService; } 260 get { return m_sceneGridService; }
255 } 261 }
256 262
263 public ISnmpModule SnmpService
264 {
265 get
266 {
267 if (m_snmpService == null)
268 {
269 m_snmpService = RequestModuleInterface<ISnmpModule>();
270 }
271
272 return m_snmpService;
273 }
274 }
275
257 public ISimulationDataService SimulationDataService 276 public ISimulationDataService SimulationDataService
258 { 277 {
259 get 278 get
@@ -569,7 +588,10 @@ namespace OpenSim.Region.Framework.Scenes
569 m_regInfo = regInfo; 588 m_regInfo = regInfo;
570 m_regionHandle = m_regInfo.RegionHandle; 589 m_regionHandle = m_regInfo.RegionHandle;
571 m_regionName = m_regInfo.RegionName; 590 m_regionName = m_regInfo.RegionName;
591 m_datastore = m_regInfo.DataStore;
572 m_lastUpdate = Util.EnvironmentTickCount(); 592 m_lastUpdate = Util.EnvironmentTickCount();
593 m_lastIncoming = 0;
594 m_lastOutgoing = 0;
573 595
574 m_physicalPrim = physicalPrim; 596 m_physicalPrim = physicalPrim;
575 m_seeIntoRegionFromNeighbor = SeeIntoRegionFromNeighbor; 597 m_seeIntoRegionFromNeighbor = SeeIntoRegionFromNeighbor;
@@ -701,9 +723,10 @@ namespace OpenSim.Region.Framework.Scenes
701 //Animation states 723 //Animation states
702 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); 724 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
703 // TODO: Change default to true once the feature is supported 725 // TODO: Change default to true once the feature is supported
704 m_usePreJump = startupConfig.GetBoolean("enableprejump", false); 726 m_usePreJump = startupConfig.GetBoolean("enableprejump", true);
705
706 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys); 727 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
728
729 m_log.DebugFormat("[SCENE]: prejump is {0}", m_usePreJump ? "ON" : "OFF");
707 if (RegionInfo.NonphysPrimMax > 0) 730 if (RegionInfo.NonphysPrimMax > 0)
708 { 731 {
709 m_maxNonphys = RegionInfo.NonphysPrimMax; 732 m_maxNonphys = RegionInfo.NonphysPrimMax;
@@ -735,6 +758,7 @@ namespace OpenSim.Region.Framework.Scenes
735 m_persistAfter *= 10000000; 758 m_persistAfter *= 10000000;
736 759
737 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); 760 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
761 m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine);
738 762
739 IConfig packetConfig = m_config.Configs["PacketPool"]; 763 IConfig packetConfig = m_config.Configs["PacketPool"];
740 if (packetConfig != null) 764 if (packetConfig != null)
@@ -744,6 +768,8 @@ namespace OpenSim.Region.Framework.Scenes
744 } 768 }
745 769
746 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); 770 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
771 m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion);
772 CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false);
747 773
748 m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true); 774 m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true);
749 if (m_generateMaptiles) 775 if (m_generateMaptiles)
@@ -768,9 +794,9 @@ namespace OpenSim.Region.Framework.Scenes
768 } 794 }
769 } 795 }
770 } 796 }
771 catch 797 catch (Exception e)
772 { 798 {
773 m_log.Warn("[SCENE]: Failed to load StartupConfig"); 799 m_log.Error("[SCENE]: Failed to load StartupConfig: " + e.ToString());
774 } 800 }
775 801
776 #endregion Region Config 802 #endregion Region Config
@@ -1146,7 +1172,9 @@ namespace OpenSim.Region.Framework.Scenes
1146 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); 1172 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
1147 if (HeartbeatThread != null) 1173 if (HeartbeatThread != null)
1148 { 1174 {
1175 m_log.ErrorFormat("[SCENE]: Restarting heartbeat thread because it hasn't reported in in region {0}", RegionInfo.RegionName);
1149 HeartbeatThread.Abort(); 1176 HeartbeatThread.Abort();
1177 Watchdog.RemoveThread(HeartbeatThread.ManagedThreadId);
1150 HeartbeatThread = null; 1178 HeartbeatThread = null;
1151 } 1179 }
1152 m_lastUpdate = Util.EnvironmentTickCount(); 1180 m_lastUpdate = Util.EnvironmentTickCount();
@@ -1189,9 +1217,6 @@ namespace OpenSim.Region.Framework.Scenes
1189 { 1217 {
1190 while (!shuttingdown) 1218 while (!shuttingdown)
1191 Update(); 1219 Update();
1192
1193 m_lastUpdate = Util.EnvironmentTickCount();
1194 m_firstHeartbeat = false;
1195 } 1220 }
1196 catch (ThreadAbortException) 1221 catch (ThreadAbortException)
1197 { 1222 {
@@ -1290,6 +1315,13 @@ namespace OpenSim.Region.Framework.Scenes
1290 eventMS = Util.EnvironmentTickCountSubtract(evMS); ; 1315 eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
1291 } 1316 }
1292 1317
1318 // if (Frame % m_update_land == 0)
1319 // {
1320 // int ldMS = Util.EnvironmentTickCount();
1321 // UpdateLand();
1322 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1323 // }
1324
1293 if (Frame % m_update_backup == 0) 1325 if (Frame % m_update_backup == 0)
1294 { 1326 {
1295 int backMS = Util.EnvironmentTickCount(); 1327 int backMS = Util.EnvironmentTickCount();
@@ -1391,12 +1423,16 @@ namespace OpenSim.Region.Framework.Scenes
1391 maintc = Util.EnvironmentTickCountSubtract(maintc); 1423 maintc = Util.EnvironmentTickCountSubtract(maintc);
1392 maintc = (int)(m_minFrameTimespan * 1000) - maintc; 1424 maintc = (int)(m_minFrameTimespan * 1000) - maintc;
1393 1425
1426
1427 m_lastUpdate = Util.EnvironmentTickCount();
1428 m_firstHeartbeat = false;
1429
1394 if (maintc > 0) 1430 if (maintc > 0)
1395 Thread.Sleep(maintc); 1431 Thread.Sleep(maintc);
1396 1432
1397 // Tell the watchdog that this thread is still alive 1433 // Tell the watchdog that this thread is still alive
1398 Watchdog.UpdateThread(); 1434 Watchdog.UpdateThread();
1399 } 1435 }
1400 1436
1401 public void AddGroupTarget(SceneObjectGroup grp) 1437 public void AddGroupTarget(SceneObjectGroup grp)
1402 { 1438 {
@@ -1412,9 +1448,9 @@ namespace OpenSim.Region.Framework.Scenes
1412 1448
1413 private void CheckAtTargets() 1449 private void CheckAtTargets()
1414 { 1450 {
1415 Dictionary<UUID, SceneObjectGroup>.ValueCollection objs; 1451 List<SceneObjectGroup> objs = new List<SceneObjectGroup>();
1416 lock (m_groupsWithTargets) 1452 lock (m_groupsWithTargets)
1417 objs = m_groupsWithTargets.Values; 1453 objs = new List<SceneObjectGroup>(m_groupsWithTargets.Values);
1418 1454
1419 foreach (SceneObjectGroup entry in objs) 1455 foreach (SceneObjectGroup entry in objs)
1420 entry.checkAtTargets(); 1456 entry.checkAtTargets();
@@ -1734,14 +1770,24 @@ namespace OpenSim.Region.Framework.Scenes
1734 /// <returns></returns> 1770 /// <returns></returns>
1735 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter) 1771 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter)
1736 { 1772 {
1773
1774 float wheight = (float)RegionInfo.RegionSettings.WaterHeight;
1775 Vector3 wpos = Vector3.Zero;
1776 // Check for water surface intersection from above
1777 if ( (RayStart.Z > wheight) && (RayEnd.Z < wheight) )
1778 {
1779 float ratio = (RayStart.Z - wheight) / (RayStart.Z - RayEnd.Z);
1780 wpos.X = RayStart.X - (ratio * (RayStart.X - RayEnd.X));
1781 wpos.Y = RayStart.Y - (ratio * (RayStart.Y - RayEnd.Y));
1782 wpos.Z = wheight;
1783 }
1784
1737 Vector3 pos = Vector3.Zero; 1785 Vector3 pos = Vector3.Zero;
1738 if (RayEndIsIntersection == (byte)1) 1786 if (RayEndIsIntersection == (byte)1)
1739 { 1787 {
1740 pos = RayEnd; 1788 pos = RayEnd;
1741 return pos;
1742 } 1789 }
1743 1790 else if (RayTargetID != UUID.Zero)
1744 if (RayTargetID != UUID.Zero)
1745 { 1791 {
1746 SceneObjectPart target = GetSceneObjectPart(RayTargetID); 1792 SceneObjectPart target = GetSceneObjectPart(RayTargetID);
1747 1793
@@ -1763,7 +1809,7 @@ namespace OpenSim.Region.Framework.Scenes
1763 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter); 1809 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter);
1764 1810
1765 // Un-comment out the following line to Get Raytrace results printed to the console. 1811 // Un-comment out the following line to Get Raytrace results printed to the console.
1766 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); 1812 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
1767 float ScaleOffset = 0.5f; 1813 float ScaleOffset = 0.5f;
1768 1814
1769 // If we hit something 1815 // If we hit something
@@ -1786,13 +1832,10 @@ namespace OpenSim.Region.Framework.Scenes
1786 //pos.Z -= 0.25F; 1832 //pos.Z -= 0.25F;
1787 1833
1788 } 1834 }
1789
1790 return pos;
1791 } 1835 }
1792 else 1836 else
1793 { 1837 {
1794 // We don't have a target here, so we're going to raytrace all the objects in the scene. 1838 // We don't have a target here, so we're going to raytrace all the objects in the scene.
1795
1796 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false); 1839 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false);
1797 1840
1798 // Un-comment the following line to print the raytrace results to the console. 1841 // Un-comment the following line to print the raytrace results to the console.
@@ -1801,13 +1844,12 @@ namespace OpenSim.Region.Framework.Scenes
1801 if (ei.HitTF) 1844 if (ei.HitTF)
1802 { 1845 {
1803 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); 1846 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
1804 } else 1847 }
1848 else
1805 { 1849 {
1806 // fall back to our stupid functionality 1850 // fall back to our stupid functionality
1807 pos = RayEnd; 1851 pos = RayEnd;
1808 } 1852 }
1809
1810 return pos;
1811 } 1853 }
1812 } 1854 }
1813 else 1855 else
@@ -1818,8 +1860,12 @@ namespace OpenSim.Region.Framework.Scenes
1818 //increase height so its above the ground. 1860 //increase height so its above the ground.
1819 //should be getting the normal of the ground at the rez point and using that? 1861 //should be getting the normal of the ground at the rez point and using that?
1820 pos.Z += scale.Z / 2f; 1862 pos.Z += scale.Z / 2f;
1821 return pos; 1863// return pos;
1822 } 1864 }
1865
1866 // check against posible water intercept
1867 if (wpos.Z > pos.Z) pos = wpos;
1868 return pos;
1823 } 1869 }
1824 1870
1825 1871
@@ -1903,7 +1949,10 @@ namespace OpenSim.Region.Framework.Scenes
1903 public bool AddRestoredSceneObject( 1949 public bool AddRestoredSceneObject(
1904 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 1950 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
1905 { 1951 {
1906 return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); 1952 bool result = m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates);
1953 if (result)
1954 sceneObject.IsDeleted = false;
1955 return result;
1907 } 1956 }
1908 1957
1909 /// <summary> 1958 /// <summary>
@@ -1993,6 +2042,15 @@ namespace OpenSim.Region.Framework.Scenes
1993 /// </summary> 2042 /// </summary>
1994 public void DeleteAllSceneObjects() 2043 public void DeleteAllSceneObjects()
1995 { 2044 {
2045 DeleteAllSceneObjects(false);
2046 }
2047
2048 /// <summary>
2049 /// Delete every object from the scene. This does not include attachments worn by avatars.
2050 /// </summary>
2051 public void DeleteAllSceneObjects(bool exceptNoCopy)
2052 {
2053 List<SceneObjectGroup> toReturn = new List<SceneObjectGroup>();
1996 lock (Entities) 2054 lock (Entities)
1997 { 2055 {
1998 EntityBase[] entities = Entities.GetEntities(); 2056 EntityBase[] entities = Entities.GetEntities();
@@ -2001,11 +2059,24 @@ namespace OpenSim.Region.Framework.Scenes
2001 if (e is SceneObjectGroup) 2059 if (e is SceneObjectGroup)
2002 { 2060 {
2003 SceneObjectGroup sog = (SceneObjectGroup)e; 2061 SceneObjectGroup sog = (SceneObjectGroup)e;
2004 if (!sog.IsAttachment) 2062 if (sog != null && !sog.IsAttachment)
2005 DeleteSceneObject((SceneObjectGroup)e, false); 2063 {
2064 if (!exceptNoCopy || ((sog.GetEffectivePermissions() & (uint)PermissionMask.Copy) != 0))
2065 {
2066 DeleteSceneObject((SceneObjectGroup)e, false);
2067 }
2068 else
2069 {
2070 toReturn.Add((SceneObjectGroup)e);
2071 }
2072 }
2006 } 2073 }
2007 } 2074 }
2008 } 2075 }
2076 if (toReturn.Count > 0)
2077 {
2078 returnObjects(toReturn.ToArray(), UUID.Zero);
2079 }
2009 } 2080 }
2010 2081
2011 /// <summary> 2082 /// <summary>
@@ -2054,6 +2125,8 @@ namespace OpenSim.Region.Framework.Scenes
2054 } 2125 }
2055 2126
2056 group.DeleteGroupFromScene(silent); 2127 group.DeleteGroupFromScene(silent);
2128 if (!silent)
2129 SendKillObject(new List<uint>() { group.LocalId });
2057 2130
2058// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); 2131// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
2059 } 2132 }
@@ -2408,10 +2481,17 @@ namespace OpenSim.Region.Framework.Scenes
2408 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns> 2481 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns>
2409 public bool AddSceneObject(SceneObjectGroup sceneObject) 2482 public bool AddSceneObject(SceneObjectGroup sceneObject)
2410 { 2483 {
2484 if (sceneObject.OwnerID == UUID.Zero)
2485 {
2486 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero", sceneObject.UUID);
2487 return false;
2488 }
2489
2411 // If the user is banned, we won't let any of their objects 2490 // If the user is banned, we won't let any of their objects
2412 // enter. Period. 2491 // enter. Period.
2413 // 2492 //
2414 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID)) 2493 int flags = GetUserFlags(sceneObject.OwnerID);
2494 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID, flags))
2415 { 2495 {
2416 m_log.Info("[INTERREGION]: Denied prim crossing for " + 2496 m_log.Info("[INTERREGION]: Denied prim crossing for " +
2417 "banned avatar"); 2497 "banned avatar");
@@ -2458,12 +2538,23 @@ namespace OpenSim.Region.Framework.Scenes
2458 } 2538 }
2459 else 2539 else
2460 { 2540 {
2541 m_log.DebugFormat("[SCENE]: Attachment {0} arrived and scene presence was not found, setting to temp", sceneObject.UUID);
2461 RootPrim.RemFlag(PrimFlags.TemporaryOnRez); 2542 RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
2462 RootPrim.AddFlag(PrimFlags.TemporaryOnRez); 2543 RootPrim.AddFlag(PrimFlags.TemporaryOnRez);
2463 } 2544 }
2545 if (sceneObject.OwnerID == UUID.Zero)
2546 {
2547 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero after attachment processing. BUG!", sceneObject.UUID);
2548 return false;
2549 }
2464 } 2550 }
2465 else 2551 else
2466 { 2552 {
2553 if (sceneObject.OwnerID == UUID.Zero)
2554 {
2555 m_log.ErrorFormat("[SCENE]: Owner ID for non-attachment {0} was zero", sceneObject.UUID);
2556 return false;
2557 }
2467 AddRestoredSceneObject(sceneObject, true, false); 2558 AddRestoredSceneObject(sceneObject, true, false);
2468 2559
2469 if (!Permissions.CanObjectEntry(sceneObject.UUID, 2560 if (!Permissions.CanObjectEntry(sceneObject.UUID,
@@ -2493,6 +2584,24 @@ namespace OpenSim.Region.Framework.Scenes
2493 return 2; // StateSource.PrimCrossing 2584 return 2; // StateSource.PrimCrossing
2494 } 2585 }
2495 2586
2587 public int GetUserFlags(UUID user)
2588 {
2589 //Unfortunately the SP approach means that the value is cached until region is restarted
2590 /*
2591 ScenePresence sp;
2592 if (TryGetScenePresence(user, out sp))
2593 {
2594 return sp.UserFlags;
2595 }
2596 else
2597 {
2598 */
2599 UserAccount uac = UserAccountService.GetUserAccount(RegionInfo.ScopeID, user);
2600 if (uac == null)
2601 return 0;
2602 return uac.UserFlags;
2603 //}
2604 }
2496 #endregion 2605 #endregion
2497 2606
2498 #region Add/Remove Avatar Methods 2607 #region Add/Remove Avatar Methods
@@ -2514,6 +2623,7 @@ namespace OpenSim.Region.Framework.Scenes
2514 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2623 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2515 2624
2516 CheckHeartbeat(); 2625 CheckHeartbeat();
2626 ScenePresence presence;
2517 2627
2518 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here 2628 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here
2519 { 2629 {
@@ -2547,7 +2657,14 @@ namespace OpenSim.Region.Framework.Scenes
2547 2657
2548 EventManager.TriggerOnNewClient(client); 2658 EventManager.TriggerOnNewClient(client);
2549 if (vialogin) 2659 if (vialogin)
2660 {
2550 EventManager.TriggerOnClientLogin(client); 2661 EventManager.TriggerOnClientLogin(client);
2662
2663 // Send initial parcel data
2664 Vector3 pos = createdSp.AbsolutePosition;
2665 ILandObject land = LandChannel.GetLandObject(pos.X, pos.Y);
2666 land.SendLandUpdateToClient(client);
2667 }
2551 } 2668 }
2552 } 2669 }
2553 2670
@@ -2636,19 +2753,12 @@ namespace OpenSim.Region.Framework.Scenes
2636 // and the scene presence and the client, if they exist 2753 // and the scene presence and the client, if they exist
2637 try 2754 try
2638 { 2755 {
2639 // We need to wait for the client to make UDP contact first. 2756 ScenePresence sp = GetScenePresence(agentID);
2640 // It's the UDP contact that creates the scene presence 2757 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2641 ScenePresence sp = WaitGetScenePresence(agentID); 2758
2642 if (sp != null) 2759 if (sp != null)
2643 {
2644 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2645
2646 sp.ControllingClient.Close(); 2760 sp.ControllingClient.Close();
2647 } 2761
2648 else
2649 {
2650 m_log.WarnFormat("[SCENE]: Could not find scene presence for {0}", agentID);
2651 }
2652 // BANG! SLASH! 2762 // BANG! SLASH!
2653 m_authenticateHandler.RemoveCircuit(agentID); 2763 m_authenticateHandler.RemoveCircuit(agentID);
2654 2764
@@ -2748,6 +2858,7 @@ namespace OpenSim.Region.Framework.Scenes
2748 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory; 2858 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory;
2749 client.OnUpdateInventoryItem += UpdateInventoryItemAsset; 2859 client.OnUpdateInventoryItem += UpdateInventoryItemAsset;
2750 client.OnCopyInventoryItem += CopyInventoryItem; 2860 client.OnCopyInventoryItem += CopyInventoryItem;
2861 client.OnMoveItemsAndLeaveCopy += MoveInventoryItemsLeaveCopy;
2751 client.OnMoveInventoryItem += MoveInventoryItem; 2862 client.OnMoveInventoryItem += MoveInventoryItem;
2752 client.OnRemoveInventoryItem += RemoveInventoryItem; 2863 client.OnRemoveInventoryItem += RemoveInventoryItem;
2753 client.OnRemoveInventoryFolder += RemoveInventoryFolder; 2864 client.OnRemoveInventoryFolder += RemoveInventoryFolder;
@@ -2925,15 +3036,16 @@ namespace OpenSim.Region.Framework.Scenes
2925 /// </summary> 3036 /// </summary>
2926 /// <param name="agentId">The avatar's Unique ID</param> 3037 /// <param name="agentId">The avatar's Unique ID</param>
2927 /// <param name="client">The IClientAPI for the client</param> 3038 /// <param name="client">The IClientAPI for the client</param>
2928 public virtual void TeleportClientHome(UUID agentId, IClientAPI client) 3039 public virtual bool TeleportClientHome(UUID agentId, IClientAPI client)
2929 { 3040 {
2930 if (m_teleportModule != null) 3041 if (m_teleportModule != null)
2931 m_teleportModule.TeleportHome(agentId, client); 3042 return m_teleportModule.TeleportHome(agentId, client);
2932 else 3043 else
2933 { 3044 {
2934 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active"); 3045 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active");
2935 client.SendTeleportFailed("Unable to perform teleports on this simulator."); 3046 client.SendTeleportFailed("Unable to perform teleports on this simulator.");
2936 } 3047 }
3048 return false;
2937 } 3049 }
2938 3050
2939 /// <summary> 3051 /// <summary>
@@ -3025,6 +3137,16 @@ namespace OpenSim.Region.Framework.Scenes
3025 /// <param name="flags"></param> 3137 /// <param name="flags"></param>
3026 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags) 3138 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags)
3027 { 3139 {
3140 //Add half the avatar's height so that the user doesn't fall through prims
3141 ScenePresence presence;
3142 if (TryGetScenePresence(remoteClient.AgentId, out presence))
3143 {
3144 if (presence.Appearance != null)
3145 {
3146 position.Z = position.Z + (presence.Appearance.AvatarHeight / 2);
3147 }
3148 }
3149
3028 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt)) 3150 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt))
3029 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot. 3151 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot.
3030 m_dialogModule.SendAlertToUser(remoteClient, "Home position set."); 3152 m_dialogModule.SendAlertToUser(remoteClient, "Home position set.");
@@ -3093,8 +3215,9 @@ namespace OpenSim.Region.Framework.Scenes
3093 regions.Remove(RegionInfo.RegionHandle); 3215 regions.Remove(RegionInfo.RegionHandle);
3094 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3216 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3095 } 3217 }
3096 3218 m_log.Debug("[Scene] Beginning ClientClosed");
3097 m_eventManager.TriggerClientClosed(agentID, this); 3219 m_eventManager.TriggerClientClosed(agentID, this);
3220 m_log.Debug("[Scene] Finished ClientClosed");
3098 } 3221 }
3099 catch (NullReferenceException) 3222 catch (NullReferenceException)
3100 { 3223 {
@@ -3102,7 +3225,12 @@ namespace OpenSim.Region.Framework.Scenes
3102 // Avatar is already disposed :/ 3225 // Avatar is already disposed :/
3103 } 3226 }
3104 3227
3228 m_log.Debug("[Scene] Beginning OnRemovePresence");
3105 m_eventManager.TriggerOnRemovePresence(agentID); 3229 m_eventManager.TriggerOnRemovePresence(agentID);
3230 m_log.Debug("[Scene] Finished OnRemovePresence");
3231
3232 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3233 AttachmentsModule.SaveChangedAttachments(avatar);
3106 3234
3107 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc) 3235 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3108 AttachmentsModule.SaveChangedAttachments(avatar); 3236 AttachmentsModule.SaveChangedAttachments(avatar);
@@ -3111,7 +3239,7 @@ namespace OpenSim.Region.Framework.Scenes
3111 delegate(IClientAPI client) 3239 delegate(IClientAPI client)
3112 { 3240 {
3113 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3241 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3114 try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); } 3242 try { client.SendKillObject(avatar.RegionHandle, new List<uint>() { avatar.LocalId}); }
3115 catch (NullReferenceException) { } 3243 catch (NullReferenceException) { }
3116 }); 3244 });
3117 3245
@@ -3122,8 +3250,11 @@ namespace OpenSim.Region.Framework.Scenes
3122 } 3250 }
3123 3251
3124 // Remove the avatar from the scene 3252 // Remove the avatar from the scene
3253 m_log.Debug("[Scene] Begin RemoveScenePresence");
3125 m_sceneGraph.RemoveScenePresence(agentID); 3254 m_sceneGraph.RemoveScenePresence(agentID);
3255 m_log.Debug("[Scene] Finished RemoveScenePresence. Removing the client manager");
3126 m_clientManager.Remove(agentID); 3256 m_clientManager.Remove(agentID);
3257 m_log.Debug("[Scene] Removed the client manager. Firing avatar.close");
3127 3258
3128 try 3259 try
3129 { 3260 {
@@ -3137,9 +3268,10 @@ namespace OpenSim.Region.Framework.Scenes
3137 { 3268 {
3138 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString()); 3269 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString());
3139 } 3270 }
3140 3271 m_log.Debug("[Scene] Done. Firing RemoveCircuit");
3141 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3272 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
3142// CleanDroppedAttachments(); 3273// CleanDroppedAttachments();
3274 m_log.Debug("[Scene] The avatar has left the building");
3143 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 3275 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
3144 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); 3276 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
3145 } 3277 }
@@ -3170,19 +3302,24 @@ namespace OpenSim.Region.Framework.Scenes
3170 3302
3171 #region Entities 3303 #region Entities
3172 3304
3173 public void SendKillObject(uint localID) 3305 public void SendKillObject(List<uint> localIDs)
3174 { 3306 {
3175 SceneObjectPart part = GetSceneObjectPart(localID); 3307 List<uint> deleteIDs = new List<uint>();
3176 if (part != null) // It is a prim 3308
3309 foreach (uint localID in localIDs)
3177 { 3310 {
3178 if (!part.ParentGroup.IsDeleted) // Valid 3311 SceneObjectPart part = GetSceneObjectPart(localID);
3312 if (part != null) // It is a prim
3179 { 3313 {
3180 if (part.ParentGroup.RootPart != part) // Child part 3314 if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid
3181 return; 3315 {
3316 if (part.ParentGroup.RootPart != part) // Child part
3317 continue;
3318 }
3182 } 3319 }
3320 deleteIDs.Add(localID);
3183 } 3321 }
3184 3322 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, deleteIDs); });
3185 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); });
3186 } 3323 }
3187 3324
3188 #endregion 3325 #endregion
@@ -3200,7 +3337,6 @@ namespace OpenSim.Region.Framework.Scenes
3200 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate; 3337 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
3201 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar; 3338 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar;
3202 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid; 3339 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
3203 m_sceneGridService.KiPrimitive += SendKillObject;
3204 m_sceneGridService.OnGetLandData += GetLandData; 3340 m_sceneGridService.OnGetLandData += GetLandData;
3205 } 3341 }
3206 3342
@@ -3209,7 +3345,6 @@ namespace OpenSim.Region.Framework.Scenes
3209 /// </summary> 3345 /// </summary>
3210 public void UnRegisterRegionWithComms() 3346 public void UnRegisterRegionWithComms()
3211 { 3347 {
3212 m_sceneGridService.KiPrimitive -= SendKillObject;
3213 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid; 3348 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid;
3214 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar; 3349 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar;
3215 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate; 3350 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate;
@@ -3289,13 +3424,16 @@ namespace OpenSim.Region.Framework.Scenes
3289 sp = null; 3424 sp = null;
3290 } 3425 }
3291 3426
3292 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3293 3427
3294 //On login test land permisions 3428 //On login test land permisions
3295 if (vialogin) 3429 if (vialogin)
3296 { 3430 {
3297 if (land != null && !TestLandRestrictions(agent, land, out reason)) 3431 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
3432 if (cache != null)
3433 cache.Remove(agent.firstname + " " + agent.lastname);
3434 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3298 { 3435 {
3436 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString());
3299 return false; 3437 return false;
3300 } 3438 }
3301 } 3439 }
@@ -3318,8 +3456,13 @@ namespace OpenSim.Region.Framework.Scenes
3318 3456
3319 try 3457 try
3320 { 3458 {
3321 if (!AuthorizeUser(agent, out reason)) 3459 // Always check estate if this is a login. Always
3322 return false; 3460 // check if banned regions are to be blacked out.
3461 if (vialogin || (!m_seeIntoBannedRegion))
3462 {
3463 if (!AuthorizeUser(agent, out reason))
3464 return false;
3465 }
3323 } 3466 }
3324 catch (Exception e) 3467 catch (Exception e)
3325 { 3468 {
@@ -3421,6 +3564,8 @@ namespace OpenSim.Region.Framework.Scenes
3421 } 3564 }
3422 } 3565 }
3423 // Honor parcel landing type and position. 3566 // Honor parcel landing type and position.
3567 /*
3568 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3424 if (land != null) 3569 if (land != null)
3425 { 3570 {
3426 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) 3571 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero)
@@ -3428,26 +3573,34 @@ namespace OpenSim.Region.Framework.Scenes
3428 agent.startpos = land.LandData.UserLocation; 3573 agent.startpos = land.LandData.UserLocation;
3429 } 3574 }
3430 } 3575 }
3576 */// This is now handled properly in ScenePresence.MakeRootAgent
3431 } 3577 }
3432 3578
3433 return true; 3579 return true;
3434 } 3580 }
3435 3581
3436 private bool TestLandRestrictions(AgentCircuitData agent, ILandObject land, out string reason) 3582 private bool TestLandRestrictions(UUID agentID, out string reason, ref float posX, ref float posY)
3437 { 3583 {
3438 3584 reason = String.Empty;
3439 bool banned = land.IsBannedFromLand(agent.AgentID); 3585 if (Permissions.IsGod(agentID))
3440 bool restricted = land.IsRestrictedFromLand(agent.AgentID); 3586 return true;
3587
3588 ILandObject land = LandChannel.GetLandObject(posX, posY);
3589 if (land == null)
3590 return false;
3591
3592 bool banned = land.IsBannedFromLand(agentID);
3593 bool restricted = land.IsRestrictedFromLand(agentID);
3441 3594
3442 if (banned || restricted) 3595 if (banned || restricted)
3443 { 3596 {
3444 ILandObject nearestParcel = GetNearestAllowedParcel(agent.AgentID, agent.startpos.X, agent.startpos.Y); 3597 ILandObject nearestParcel = GetNearestAllowedParcel(agentID, posX, posY);
3445 if (nearestParcel != null) 3598 if (nearestParcel != null)
3446 { 3599 {
3447 //Move agent to nearest allowed 3600 //Move agent to nearest allowed
3448 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel); 3601 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel);
3449 agent.startpos.X = newPosition.X; 3602 posX = newPosition.X;
3450 agent.startpos.Y = newPosition.Y; 3603 posY = newPosition.Y;
3451 } 3604 }
3452 else 3605 else
3453 { 3606 {
@@ -3509,7 +3662,7 @@ namespace OpenSim.Region.Framework.Scenes
3509 3662
3510 if (!m_strictAccessControl) return true; 3663 if (!m_strictAccessControl) return true;
3511 if (Permissions.IsGod(agent.AgentID)) return true; 3664 if (Permissions.IsGod(agent.AgentID)) return true;
3512 3665
3513 if (AuthorizationService != null) 3666 if (AuthorizationService != null)
3514 { 3667 {
3515 if (!AuthorizationService.IsAuthorizedForRegion( 3668 if (!AuthorizationService.IsAuthorizedForRegion(
@@ -3517,14 +3670,14 @@ namespace OpenSim.Region.Framework.Scenes
3517 { 3670 {
3518 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region", 3671 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region",
3519 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3672 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
3520 3673
3521 return false; 3674 return false;
3522 } 3675 }
3523 } 3676 }
3524 3677
3525 if (m_regInfo.EstateSettings != null) 3678 if (m_regInfo.EstateSettings != null)
3526 { 3679 {
3527 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID)) 3680 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID,0))
3528 { 3681 {
3529 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", 3682 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
3530 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3683 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
@@ -3714,6 +3867,13 @@ namespace OpenSim.Region.Framework.Scenes
3714 3867
3715 // We have to wait until the viewer contacts this region after receiving EAC. 3868 // We have to wait until the viewer contacts this region after receiving EAC.
3716 // That calls AddNewClient, which finally creates the ScenePresence 3869 // That calls AddNewClient, which finally creates the ScenePresence
3870 int flags = GetUserFlags(cAgentData.AgentID);
3871 if (m_regInfo.EstateSettings.IsBanned(cAgentData.AgentID, flags))
3872 {
3873 m_log.DebugFormat("[SCENE]: Denying root agent entry to {0}: banned", cAgentData.AgentID);
3874 return false;
3875 }
3876
3717 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); 3877 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2);
3718 if (nearestParcel == null) 3878 if (nearestParcel == null)
3719 { 3879 {
@@ -3729,7 +3889,6 @@ namespace OpenSim.Region.Framework.Scenes
3729 return false; 3889 return false;
3730 } 3890 }
3731 3891
3732
3733 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 3892 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
3734 3893
3735 if (childAgentUpdate != null) 3894 if (childAgentUpdate != null)
@@ -3796,12 +3955,22 @@ namespace OpenSim.Region.Framework.Scenes
3796 return false; 3955 return false;
3797 } 3956 }
3798 3957
3958 public bool IncomingCloseAgent(UUID agentID)
3959 {
3960 return IncomingCloseAgent(agentID, false);
3961 }
3962
3963 public bool IncomingCloseChildAgent(UUID agentID)
3964 {
3965 return IncomingCloseAgent(agentID, true);
3966 }
3967
3799 /// <summary> 3968 /// <summary>
3800 /// Tell a single agent to disconnect from the region. 3969 /// Tell a single agent to disconnect from the region.
3801 /// </summary> 3970 /// </summary>
3802 /// <param name="regionHandle"></param>
3803 /// <param name="agentID"></param> 3971 /// <param name="agentID"></param>
3804 public bool IncomingCloseAgent(UUID agentID) 3972 /// <param name="childOnly"></param>
3973 public bool IncomingCloseAgent(UUID agentID, bool childOnly)
3805 { 3974 {
3806 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 3975 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
3807 3976
@@ -3813,7 +3982,7 @@ namespace OpenSim.Region.Framework.Scenes
3813 { 3982 {
3814 m_sceneGraph.removeUserCount(false); 3983 m_sceneGraph.removeUserCount(false);
3815 } 3984 }
3816 else 3985 else if (!childOnly)
3817 { 3986 {
3818 m_sceneGraph.removeUserCount(true); 3987 m_sceneGraph.removeUserCount(true);
3819 } 3988 }
@@ -3829,9 +3998,12 @@ namespace OpenSim.Region.Framework.Scenes
3829 } 3998 }
3830 else 3999 else
3831 presence.ControllingClient.SendShutdownConnectionNotice(); 4000 presence.ControllingClient.SendShutdownConnectionNotice();
4001 presence.ControllingClient.Close(false);
4002 }
4003 else if (!childOnly)
4004 {
4005 presence.ControllingClient.Close(true);
3832 } 4006 }
3833
3834 presence.ControllingClient.Close();
3835 return true; 4007 return true;
3836 } 4008 }
3837 4009
@@ -4446,34 +4618,66 @@ namespace OpenSim.Region.Framework.Scenes
4446 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID); 4618 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID);
4447 } 4619 }
4448 4620
4449 public int GetHealth() 4621 public int GetHealth(out int flags, out string message)
4450 { 4622 {
4451 // Returns: 4623 // Returns:
4452 // 1 = sim is up and accepting http requests. The heartbeat has 4624 // 1 = sim is up and accepting http requests. The heartbeat has
4453 // stopped and the sim is probably locked up, but a remote 4625 // stopped and the sim is probably locked up, but a remote
4454 // admin restart may succeed 4626 // admin restart may succeed
4455 // 4627 //
4456 // 2 = Sim is up and the heartbeat is running. The sim is likely 4628 // 2 = Sim is up and the heartbeat is running. The sim is likely
4457 // usable for people within and logins _may_ work 4629 // usable for people within
4458 // 4630 //
4459 // 3 = We have seen a new user enter within the past 4 minutes 4631 // 3 = Sim is up and one packet thread is running. Sim is
4632 // unstable and will not accept new logins
4633 //
4634 // 4 = Sim is up and both packet threads are running. Sim is
4635 // likely usable
4636 //
4637 // 5 = We have seen a new user enter within the past 4 minutes
4460 // which can be seen as positive confirmation of sim health 4638 // which can be seen as positive confirmation of sim health
4461 // 4639 //
4640
4641 flags = 0;
4642 message = String.Empty;
4643
4644 CheckHeartbeat();
4645
4646 if (m_firstHeartbeat || (m_lastIncoming == 0 && m_lastOutgoing == 0))
4647 {
4648 // We're still starting
4649 // 0 means "in startup", it can't happen another way, since
4650 // to get here, we must be able to accept http connections
4651 return 0;
4652 }
4653
4462 int health=1; // Start at 1, means we're up 4654 int health=1; // Start at 1, means we're up
4463 4655
4464 if ((Util.EnvironmentTickCountSubtract(m_lastUpdate)) < 1000) 4656 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) < 1000)
4657 {
4465 health+=1; 4658 health+=1;
4466 else 4659 flags |= 1;
4660 }
4661
4662 if (Util.EnvironmentTickCountSubtract(m_lastIncoming) < 1000)
4663 {
4664 health+=1;
4665 flags |= 2;
4666 }
4667
4668 if (Util.EnvironmentTickCountSubtract(m_lastOutgoing) < 1000)
4669 {
4670 health+=1;
4671 flags |= 4;
4672 }
4673
4674 if (flags != 7)
4467 return health; 4675 return health;
4468 4676
4469 // A login in the last 4 mins? We can't be doing too badly 4677 // A login in the last 4 mins? We can't be doing too badly
4470 // 4678 //
4471 if ((Util.EnvironmentTickCountSubtract(m_LastLogin)) < 240000) 4679 if (Util.EnvironmentTickCountSubtract(m_LastLogin) < 240000)
4472 health++; 4680 health++;
4473 else
4474 return health;
4475
4476 CheckHeartbeat();
4477 4681
4478 return health; 4682 return health;
4479 } 4683 }
@@ -4666,7 +4870,7 @@ namespace OpenSim.Region.Framework.Scenes
4666 if (m_firstHeartbeat) 4870 if (m_firstHeartbeat)
4667 return; 4871 return;
4668 4872
4669 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 2000) 4873 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 5000)
4670 StartTimer(); 4874 StartTimer();
4671 } 4875 }
4672 4876
@@ -5080,6 +5284,54 @@ namespace OpenSim.Region.Framework.Scenes
5080 } 5284 }
5081 } 5285 }
5082 5286
5287// public void CleanDroppedAttachments()
5288// {
5289// List<SceneObjectGroup> objectsToDelete =
5290// new List<SceneObjectGroup>();
5291//
5292// lock (m_cleaningAttachments)
5293// {
5294// ForEachSOG(delegate (SceneObjectGroup grp)
5295// {
5296// if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp)))
5297// {
5298// UUID agentID = grp.OwnerID;
5299// if (agentID == UUID.Zero)
5300// {
5301// objectsToDelete.Add(grp);
5302// return;
5303// }
5304//
5305// ScenePresence sp = GetScenePresence(agentID);
5306// if (sp == null)
5307// {
5308// objectsToDelete.Add(grp);
5309// return;
5310// }
5311// }
5312// });
5313// }
5314//
5315// foreach (SceneObjectGroup grp in objectsToDelete)
5316// {
5317// m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID);
5318// DeleteSceneObject(grp, true);
5319// }
5320// }
5321
5322 public void ThreadAlive(int threadCode)
5323 {
5324 switch(threadCode)
5325 {
5326 case 1: // Incoming
5327 m_lastIncoming = Util.EnvironmentTickCount();
5328 break;
5329 case 2: // Incoming
5330 m_lastOutgoing = Util.EnvironmentTickCount();
5331 break;
5332 }
5333 }
5334
5083 // This method is called across the simulation connector to 5335 // This method is called across the simulation connector to
5084 // determine if a given agent is allowed in this region 5336 // determine if a given agent is allowed in this region
5085 // AS A ROOT AGENT. Returning false here will prevent them 5337 // AS A ROOT AGENT. Returning false here will prevent them
@@ -5088,6 +5340,14 @@ namespace OpenSim.Region.Framework.Scenes
5088 // child agent creation, thereby emulating the SL behavior. 5340 // child agent creation, thereby emulating the SL behavior.
5089 public bool QueryAccess(UUID agentID, Vector3 position, out string reason) 5341 public bool QueryAccess(UUID agentID, Vector3 position, out string reason)
5090 { 5342 {
5343 reason = "You are banned from the region";
5344
5345 if (Permissions.IsGod(agentID))
5346 {
5347 reason = String.Empty;
5348 return true;
5349 }
5350
5091 int num = m_sceneGraph.GetNumberOfScenePresences(); 5351 int num = m_sceneGraph.GetNumberOfScenePresences();
5092 5352
5093 if (num >= RegionInfo.RegionSettings.AgentLimit) 5353 if (num >= RegionInfo.RegionSettings.AgentLimit)
@@ -5099,11 +5359,82 @@ namespace OpenSim.Region.Framework.Scenes
5099 } 5359 }
5100 } 5360 }
5101 5361
5362 ScenePresence presence = GetScenePresence(agentID);
5363 IClientAPI client = null;
5364 AgentCircuitData aCircuit = null;
5365
5366 if (presence != null)
5367 {
5368 client = presence.ControllingClient;
5369 if (client != null)
5370 aCircuit = client.RequestClientInfo();
5371 }
5372
5373 // We may be called before there is a presence or a client.
5374 // Fake AgentCircuitData to keep IAuthorizationModule smiling
5375 if (client == null)
5376 {
5377 aCircuit = new AgentCircuitData();
5378 aCircuit.AgentID = agentID;
5379 aCircuit.firstname = String.Empty;
5380 aCircuit.lastname = String.Empty;
5381 }
5382
5383 try
5384 {
5385 if (!AuthorizeUser(aCircuit, out reason))
5386 {
5387 // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID);
5388 return false;
5389 }
5390 }
5391 catch (Exception e)
5392 {
5393 m_log.DebugFormat("[SCENE]: Exception authorizing agent: {0} "+ e.StackTrace, e.Message);
5394 return false;
5395 }
5396
5397 if (position == Vector3.Zero) // Teleport
5398 {
5399 float posX = 128.0f;
5400 float posY = 128.0f;
5401
5402 if (!TestLandRestrictions(agentID, out reason, ref posX, ref posY))
5403 {
5404 // m_log.DebugFormat("[SCENE]: Denying {0} because they are banned on all parcels", agentID);
5405 return false;
5406 }
5407 }
5408 else // Walking
5409 {
5410 ILandObject land = LandChannel.GetLandObject(position.X, position.Y);
5411 if (land == null)
5412 return false;
5413
5414 bool banned = land.IsBannedFromLand(agentID);
5415 bool restricted = land.IsRestrictedFromLand(agentID);
5416
5417 if (banned || restricted)
5418 return false;
5419 }
5420
5102 reason = String.Empty; 5421 reason = String.Empty;
5103 return true; 5422 return true;
5104 } 5423 }
5105 5424
5106 /// <summary> 5425 public void StartTimerWatchdog()
5426 {
5427 m_timerWatchdog.Interval = 1000;
5428 m_timerWatchdog.Elapsed += TimerWatchdog;
5429 m_timerWatchdog.AutoReset = true;
5430 m_timerWatchdog.Start();
5431 }
5432
5433 public void TimerWatchdog(object sender, ElapsedEventArgs e)
5434 {
5435 CheckHeartbeat();
5436 }
5437
5107 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the 5438 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the
5108 /// autopilot that moves an avatar to a sit target!. 5439 /// autopilot that moves an avatar to a sit target!.
5109 /// </summary> 5440 /// </summary>