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