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.cs511
1 files changed, 383 insertions, 128 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 1a6a70b..fe111ff 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 public bool LoginsDisabled = true; 98 public bool LoginsDisabled = true;
98 public bool LoadingPrims; 99 public bool LoadingPrims;
@@ -111,6 +112,7 @@ namespace OpenSim.Region.Framework.Scenes
111 protected ModuleLoader m_moduleLoader; 112 protected ModuleLoader m_moduleLoader;
112 protected AgentCircuitManager m_authenticateHandler; 113 protected AgentCircuitManager m_authenticateHandler;
113 protected SceneCommunicationService m_sceneGridService; 114 protected SceneCommunicationService m_sceneGridService;
115 protected ISnmpModule m_snmpService = null;
114 116
115 protected ISimulationDataService m_SimulationDataService; 117 protected ISimulationDataService m_SimulationDataService;
116 protected IEstateDataService m_EstateDataService; 118 protected IEstateDataService m_EstateDataService;
@@ -167,7 +169,7 @@ namespace OpenSim.Region.Framework.Scenes
167 private int m_update_events = 1; 169 private int m_update_events = 1;
168 private int m_update_backup = 200; 170 private int m_update_backup = 200;
169 private int m_update_terrain = 50; 171 private int m_update_terrain = 50;
170// private int m_update_land = 1; 172 private int m_update_land = 10;
171 private int m_update_coarse_locations = 50; 173 private int m_update_coarse_locations = 50;
172 174
173 private int frameMS; 175 private int frameMS;
@@ -181,6 +183,7 @@ namespace OpenSim.Region.Framework.Scenes
181 private int landMS; 183 private int landMS;
182 private int lastCompletedFrame; 184 private int lastCompletedFrame;
183 185
186 public bool CombineRegions = false;
184 private bool m_physics_enabled = true; 187 private bool m_physics_enabled = true;
185 private bool m_scripts_enabled = true; 188 private bool m_scripts_enabled = true;
186 private string m_defaultScriptEngine; 189 private string m_defaultScriptEngine;
@@ -189,6 +192,8 @@ namespace OpenSim.Region.Framework.Scenes
189 private volatile bool shuttingdown; 192 private volatile bool shuttingdown;
190 193
191 private int m_lastUpdate; 194 private int m_lastUpdate;
195 private int m_lastIncoming;
196 private int m_lastOutgoing;
192 private bool m_firstHeartbeat = true; 197 private bool m_firstHeartbeat = true;
193 198
194 private object m_deleting_scene_object = new object(); 199 private object m_deleting_scene_object = new object();
@@ -240,6 +245,19 @@ namespace OpenSim.Region.Framework.Scenes
240 get { return m_sceneGridService; } 245 get { return m_sceneGridService; }
241 } 246 }
242 247
248 public ISnmpModule SnmpService
249 {
250 get
251 {
252 if (m_snmpService == null)
253 {
254 m_snmpService = RequestModuleInterface<ISnmpModule>();
255 }
256
257 return m_snmpService;
258 }
259 }
260
243 public ISimulationDataService SimulationDataService 261 public ISimulationDataService SimulationDataService
244 { 262 {
245 get 263 get
@@ -565,6 +583,8 @@ namespace OpenSim.Region.Framework.Scenes
565 m_regionName = m_regInfo.RegionName; 583 m_regionName = m_regInfo.RegionName;
566 m_datastore = m_regInfo.DataStore; 584 m_datastore = m_regInfo.DataStore;
567 m_lastUpdate = Util.EnvironmentTickCount(); 585 m_lastUpdate = Util.EnvironmentTickCount();
586 m_lastIncoming = 0;
587 m_lastOutgoing = 0;
568 588
569 m_physicalPrim = physicalPrim; 589 m_physicalPrim = physicalPrim;
570 m_seeIntoRegionFromNeighbor = SeeIntoRegionFromNeighbor; 590 m_seeIntoRegionFromNeighbor = SeeIntoRegionFromNeighbor;
@@ -578,6 +598,8 @@ namespace OpenSim.Region.Framework.Scenes
578 #region Region Settings 598 #region Region Settings
579 599
580 // Load region settings 600 // Load region settings
601 m_regInfo.WindlightSettings = SimulationDataService.LoadRegionWindlightSettings(m_regInfo.RegionID);
602
581 m_regInfo.RegionSettings = simDataService.LoadRegionSettings(m_regInfo.RegionID); 603 m_regInfo.RegionSettings = simDataService.LoadRegionSettings(m_regInfo.RegionID);
582 if (estateDataService != null) 604 if (estateDataService != null)
583 m_regInfo.EstateSettings = estateDataService.LoadEstateSettings(m_regInfo.RegionID, false); 605 m_regInfo.EstateSettings = estateDataService.LoadEstateSettings(m_regInfo.RegionID, false);
@@ -639,9 +661,10 @@ namespace OpenSim.Region.Framework.Scenes
639 //Animation states 661 //Animation states
640 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); 662 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
641 // TODO: Change default to true once the feature is supported 663 // TODO: Change default to true once the feature is supported
642 m_usePreJump = startupConfig.GetBoolean("enableprejump", false); 664 m_usePreJump = startupConfig.GetBoolean("enableprejump", true);
643
644 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys); 665 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
666
667 m_log.DebugFormat("[SCENE]: prejump is {0}", m_usePreJump ? "ON" : "OFF");
645 if (RegionInfo.NonphysPrimMax > 0) 668 if (RegionInfo.NonphysPrimMax > 0)
646 { 669 {
647 m_maxNonphys = RegionInfo.NonphysPrimMax; 670 m_maxNonphys = RegionInfo.NonphysPrimMax;
@@ -673,6 +696,7 @@ namespace OpenSim.Region.Framework.Scenes
673 m_persistAfter *= 10000000; 696 m_persistAfter *= 10000000;
674 697
675 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); 698 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
699 m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine);
676 700
677 IConfig packetConfig = m_config.Configs["PacketPool"]; 701 IConfig packetConfig = m_config.Configs["PacketPool"];
678 if (packetConfig != null) 702 if (packetConfig != null)
@@ -682,6 +706,8 @@ namespace OpenSim.Region.Framework.Scenes
682 } 706 }
683 707
684 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); 708 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
709 m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion);
710 CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false);
685 711
686 m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true); 712 m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true);
687 if (m_generateMaptiles) 713 if (m_generateMaptiles)
@@ -706,9 +732,9 @@ namespace OpenSim.Region.Framework.Scenes
706 } 732 }
707 } 733 }
708 } 734 }
709 catch 735 catch (Exception e)
710 { 736 {
711 m_log.Warn("[SCENE]: Failed to load StartupConfig"); 737 m_log.Error("[SCENE]: Failed to load StartupConfig: " + e.ToString());
712 } 738 }
713 739
714 #endregion Region Config 740 #endregion Region Config
@@ -1079,7 +1105,9 @@ namespace OpenSim.Region.Framework.Scenes
1079 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); 1105 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
1080 if (HeartbeatThread != null) 1106 if (HeartbeatThread != null)
1081 { 1107 {
1108 m_log.ErrorFormat("[SCENE]: Restarting heartbeat thread because it hasn't reported in in region {0}", RegionInfo.RegionName);
1082 HeartbeatThread.Abort(); 1109 HeartbeatThread.Abort();
1110 Watchdog.RemoveThread(HeartbeatThread.ManagedThreadId);
1083 HeartbeatThread = null; 1111 HeartbeatThread = null;
1084 } 1112 }
1085 m_lastUpdate = Util.EnvironmentTickCount(); 1113 m_lastUpdate = Util.EnvironmentTickCount();
@@ -1203,9 +1231,6 @@ namespace OpenSim.Region.Framework.Scenes
1203 { 1231 {
1204 while (!shuttingdown) 1232 while (!shuttingdown)
1205 Update(); 1233 Update();
1206
1207 m_lastUpdate = Util.EnvironmentTickCount();
1208 m_firstHeartbeat = false;
1209 } 1234 }
1210 catch (ThreadAbortException) 1235 catch (ThreadAbortException)
1211 { 1236 {
@@ -1312,12 +1337,12 @@ namespace OpenSim.Region.Framework.Scenes
1312 terrainMS = Util.EnvironmentTickCountSubtract(terMS); 1337 terrainMS = Util.EnvironmentTickCountSubtract(terMS);
1313 } 1338 }
1314 1339
1315 //if (Frame % m_update_land == 0) 1340 if (Frame % m_update_land == 0)
1316 //{ 1341 {
1317 // int ldMS = Util.EnvironmentTickCount(); 1342 int ldMS = Util.EnvironmentTickCount();
1318 // UpdateLand(); 1343 UpdateLand();
1319 // landMS = Util.EnvironmentTickCountSubtract(ldMS); 1344 landMS = Util.EnvironmentTickCountSubtract(ldMS);
1320 //} 1345 }
1321 1346
1322 frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS); 1347 frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS);
1323 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS; 1348 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
@@ -1383,12 +1408,16 @@ namespace OpenSim.Region.Framework.Scenes
1383 maintc = Util.EnvironmentTickCountSubtract(maintc); 1408 maintc = Util.EnvironmentTickCountSubtract(maintc);
1384 maintc = (int)(m_timespan * 1000) - maintc; 1409 maintc = (int)(m_timespan * 1000) - maintc;
1385 1410
1411
1412 m_lastUpdate = Util.EnvironmentTickCount();
1413 m_firstHeartbeat = false;
1414
1386 if (maintc > 0) 1415 if (maintc > 0)
1387 Thread.Sleep(maintc); 1416 Thread.Sleep(maintc);
1388 1417
1389 // Tell the watchdog that this thread is still alive 1418 // Tell the watchdog that this thread is still alive
1390 Watchdog.UpdateThread(); 1419 Watchdog.UpdateThread();
1391 } 1420 }
1392 1421
1393 public void AddGroupTarget(SceneObjectGroup grp) 1422 public void AddGroupTarget(SceneObjectGroup grp)
1394 { 1423 {
@@ -1404,9 +1433,9 @@ namespace OpenSim.Region.Framework.Scenes
1404 1433
1405 private void CheckAtTargets() 1434 private void CheckAtTargets()
1406 { 1435 {
1407 Dictionary<UUID, SceneObjectGroup>.ValueCollection objs; 1436 List<SceneObjectGroup> objs = new List<SceneObjectGroup>();
1408 lock (m_groupsWithTargets) 1437 lock (m_groupsWithTargets)
1409 objs = m_groupsWithTargets.Values; 1438 objs = new List<SceneObjectGroup>(m_groupsWithTargets.Values);
1410 1439
1411 foreach (SceneObjectGroup entry in objs) 1440 foreach (SceneObjectGroup entry in objs)
1412 entry.checkAtTargets(); 1441 entry.checkAtTargets();
@@ -1740,14 +1769,24 @@ namespace OpenSim.Region.Framework.Scenes
1740 /// <returns></returns> 1769 /// <returns></returns>
1741 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter) 1770 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter)
1742 { 1771 {
1772
1773 float wheight = (float)RegionInfo.RegionSettings.WaterHeight;
1774 Vector3 wpos = Vector3.Zero;
1775 // Check for water surface intersection from above
1776 if ( (RayStart.Z > wheight) && (RayEnd.Z < wheight) )
1777 {
1778 float ratio = (RayStart.Z - wheight) / (RayStart.Z - RayEnd.Z);
1779 wpos.X = RayStart.X - (ratio * (RayStart.X - RayEnd.X));
1780 wpos.Y = RayStart.Y - (ratio * (RayStart.Y - RayEnd.Y));
1781 wpos.Z = wheight;
1782 }
1783
1743 Vector3 pos = Vector3.Zero; 1784 Vector3 pos = Vector3.Zero;
1744 if (RayEndIsIntersection == (byte)1) 1785 if (RayEndIsIntersection == (byte)1)
1745 { 1786 {
1746 pos = RayEnd; 1787 pos = RayEnd;
1747 return pos;
1748 } 1788 }
1749 1789 else if (RayTargetID != UUID.Zero)
1750 if (RayTargetID != UUID.Zero)
1751 { 1790 {
1752 SceneObjectPart target = GetSceneObjectPart(RayTargetID); 1791 SceneObjectPart target = GetSceneObjectPart(RayTargetID);
1753 1792
@@ -1769,7 +1808,7 @@ namespace OpenSim.Region.Framework.Scenes
1769 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter); 1808 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter);
1770 1809
1771 // Un-comment out the following line to Get Raytrace results printed to the console. 1810 // Un-comment out the following line to Get Raytrace results printed to the console.
1772 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); 1811 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
1773 float ScaleOffset = 0.5f; 1812 float ScaleOffset = 0.5f;
1774 1813
1775 // If we hit something 1814 // If we hit something
@@ -1792,13 +1831,10 @@ namespace OpenSim.Region.Framework.Scenes
1792 //pos.Z -= 0.25F; 1831 //pos.Z -= 0.25F;
1793 1832
1794 } 1833 }
1795
1796 return pos;
1797 } 1834 }
1798 else 1835 else
1799 { 1836 {
1800 // We don't have a target here, so we're going to raytrace all the objects in the scene. 1837 // We don't have a target here, so we're going to raytrace all the objects in the scene.
1801
1802 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false); 1838 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false);
1803 1839
1804 // Un-comment the following line to print the raytrace results to the console. 1840 // Un-comment the following line to print the raytrace results to the console.
@@ -1807,13 +1843,12 @@ namespace OpenSim.Region.Framework.Scenes
1807 if (ei.HitTF) 1843 if (ei.HitTF)
1808 { 1844 {
1809 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); 1845 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
1810 } else 1846 }
1847 else
1811 { 1848 {
1812 // fall back to our stupid functionality 1849 // fall back to our stupid functionality
1813 pos = RayEnd; 1850 pos = RayEnd;
1814 } 1851 }
1815
1816 return pos;
1817 } 1852 }
1818 } 1853 }
1819 else 1854 else
@@ -1824,8 +1859,12 @@ namespace OpenSim.Region.Framework.Scenes
1824 //increase height so its above the ground. 1859 //increase height so its above the ground.
1825 //should be getting the normal of the ground at the rez point and using that? 1860 //should be getting the normal of the ground at the rez point and using that?
1826 pos.Z += scale.Z / 2f; 1861 pos.Z += scale.Z / 2f;
1827 return pos; 1862// return pos;
1828 } 1863 }
1864
1865 // check against posible water intercept
1866 if (wpos.Z > pos.Z) pos = wpos;
1867 return pos;
1829 } 1868 }
1830 1869
1831 1870
@@ -1905,7 +1944,10 @@ namespace OpenSim.Region.Framework.Scenes
1905 public bool AddRestoredSceneObject( 1944 public bool AddRestoredSceneObject(
1906 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 1945 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
1907 { 1946 {
1908 return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); 1947 bool result = m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates);
1948 if (result)
1949 sceneObject.IsDeleted = false;
1950 return result;
1909 } 1951 }
1910 1952
1911 /// <summary> 1953 /// <summary>
@@ -1982,6 +2024,15 @@ namespace OpenSim.Region.Framework.Scenes
1982 /// </summary> 2024 /// </summary>
1983 public void DeleteAllSceneObjects() 2025 public void DeleteAllSceneObjects()
1984 { 2026 {
2027 DeleteAllSceneObjects(false);
2028 }
2029
2030 /// <summary>
2031 /// Delete every object from the scene. This does not include attachments worn by avatars.
2032 /// </summary>
2033 public void DeleteAllSceneObjects(bool exceptNoCopy)
2034 {
2035 List<SceneObjectGroup> toReturn = new List<SceneObjectGroup>();
1985 lock (Entities) 2036 lock (Entities)
1986 { 2037 {
1987 EntityBase[] entities = Entities.GetEntities(); 2038 EntityBase[] entities = Entities.GetEntities();
@@ -1990,11 +2041,24 @@ namespace OpenSim.Region.Framework.Scenes
1990 if (e is SceneObjectGroup) 2041 if (e is SceneObjectGroup)
1991 { 2042 {
1992 SceneObjectGroup sog = (SceneObjectGroup)e; 2043 SceneObjectGroup sog = (SceneObjectGroup)e;
1993 if (!sog.IsAttachment) 2044 if (sog != null && !sog.IsAttachment)
1994 DeleteSceneObject((SceneObjectGroup)e, false); 2045 {
2046 if (!exceptNoCopy || ((sog.GetEffectivePermissions() & (uint)PermissionMask.Copy) != 0))
2047 {
2048 DeleteSceneObject((SceneObjectGroup)e, false);
2049 }
2050 else
2051 {
2052 toReturn.Add((SceneObjectGroup)e);
2053 }
2054 }
1995 } 2055 }
1996 } 2056 }
1997 } 2057 }
2058 if (toReturn.Count > 0)
2059 {
2060 returnObjects(toReturn.ToArray(), UUID.Zero);
2061 }
1998 } 2062 }
1999 2063
2000 /// <summary> 2064 /// <summary>
@@ -2043,6 +2107,8 @@ namespace OpenSim.Region.Framework.Scenes
2043 } 2107 }
2044 2108
2045 group.DeleteGroupFromScene(silent); 2109 group.DeleteGroupFromScene(silent);
2110 if (!silent)
2111 SendKillObject(new List<uint>() { group.LocalId });
2046 2112
2047// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); 2113// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
2048 } 2114 }
@@ -2373,10 +2439,17 @@ namespace OpenSim.Region.Framework.Scenes
2373 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns> 2439 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns>
2374 public bool AddSceneObject(SceneObjectGroup sceneObject) 2440 public bool AddSceneObject(SceneObjectGroup sceneObject)
2375 { 2441 {
2442 if (sceneObject.OwnerID == UUID.Zero)
2443 {
2444 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero", sceneObject.UUID);
2445 return false;
2446 }
2447
2376 // If the user is banned, we won't let any of their objects 2448 // If the user is banned, we won't let any of their objects
2377 // enter. Period. 2449 // enter. Period.
2378 // 2450 //
2379 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID)) 2451 int flags = GetUserFlags(sceneObject.OwnerID);
2452 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID, flags))
2380 { 2453 {
2381 m_log.Info("[INTERREGION]: Denied prim crossing for " + 2454 m_log.Info("[INTERREGION]: Denied prim crossing for " +
2382 "banned avatar"); 2455 "banned avatar");
@@ -2420,15 +2493,28 @@ namespace OpenSim.Region.Framework.Scenes
2420 2493
2421 if (AttachmentsModule != null) 2494 if (AttachmentsModule != null)
2422 AttachmentsModule.AttachObject(sp.ControllingClient, grp, 0, false); 2495 AttachmentsModule.AttachObject(sp.ControllingClient, grp, 0, false);
2496
2497 m_log.DebugFormat("[SCENE]: Attachment {0} arrived and scene presence was found, attaching", sceneObject.UUID);
2423 } 2498 }
2424 else 2499 else
2425 { 2500 {
2501 m_log.DebugFormat("[SCENE]: Attachment {0} arrived and scene presence was not found, setting to temp", sceneObject.UUID);
2426 RootPrim.RemFlag(PrimFlags.TemporaryOnRez); 2502 RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
2427 RootPrim.AddFlag(PrimFlags.TemporaryOnRez); 2503 RootPrim.AddFlag(PrimFlags.TemporaryOnRez);
2428 } 2504 }
2505 if (sceneObject.OwnerID == UUID.Zero)
2506 {
2507 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero after attachment processing. BUG!", sceneObject.UUID);
2508 return false;
2509 }
2429 } 2510 }
2430 else 2511 else
2431 { 2512 {
2513 if (sceneObject.OwnerID == UUID.Zero)
2514 {
2515 m_log.ErrorFormat("[SCENE]: Owner ID for non-attachment {0} was zero", sceneObject.UUID);
2516 return false;
2517 }
2432 AddRestoredSceneObject(sceneObject, true, false); 2518 AddRestoredSceneObject(sceneObject, true, false);
2433 2519
2434 if (!Permissions.CanObjectEntry(sceneObject.UUID, 2520 if (!Permissions.CanObjectEntry(sceneObject.UUID,
@@ -2467,6 +2553,24 @@ namespace OpenSim.Region.Framework.Scenes
2467 return 2; // StateSource.PrimCrossing 2553 return 2; // StateSource.PrimCrossing
2468 } 2554 }
2469 2555
2556 public int GetUserFlags(UUID user)
2557 {
2558 //Unfortunately the SP approach means that the value is cached until region is restarted
2559 /*
2560 ScenePresence sp;
2561 if (TryGetScenePresence(user, out sp))
2562 {
2563 return sp.UserFlags;
2564 }
2565 else
2566 {
2567 */
2568 UserAccount uac = UserAccountService.GetUserAccount(RegionInfo.ScopeID, user);
2569 if (uac == null)
2570 return 0;
2571 return uac.UserFlags;
2572 //}
2573 }
2470 #endregion 2574 #endregion
2471 2575
2472 #region Add/Remove Avatar Methods 2576 #region Add/Remove Avatar Methods
@@ -2487,6 +2591,7 @@ namespace OpenSim.Region.Framework.Scenes
2487 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2591 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2488 2592
2489 CheckHeartbeat(); 2593 CheckHeartbeat();
2594 ScenePresence presence;
2490 2595
2491 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here 2596 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here
2492 { 2597 {
@@ -2510,12 +2615,19 @@ namespace OpenSim.Region.Framework.Scenes
2510 } 2615 }
2511 } 2616 }
2512 2617
2513 if (GetScenePresence(client.AgentId) != null) 2618 if (TryGetScenePresence(client.AgentId, out presence))
2514 { 2619 {
2515 m_LastLogin = Util.EnvironmentTickCount(); 2620 m_LastLogin = Util.EnvironmentTickCount();
2516 EventManager.TriggerOnNewClient(client); 2621 EventManager.TriggerOnNewClient(client);
2517 if (vialogin) 2622 if (vialogin)
2623 {
2518 EventManager.TriggerOnClientLogin(client); 2624 EventManager.TriggerOnClientLogin(client);
2625
2626 // Send initial parcel data
2627 Vector3 pos = presence.AbsolutePosition;
2628 ILandObject land = LandChannel.GetLandObject(pos.X, pos.Y);
2629 land.SendLandUpdateToClient(presence.ControllingClient);
2630 }
2519 } 2631 }
2520 } 2632 }
2521 2633
@@ -2566,19 +2678,12 @@ namespace OpenSim.Region.Framework.Scenes
2566 // and the scene presence and the client, if they exist 2678 // and the scene presence and the client, if they exist
2567 try 2679 try
2568 { 2680 {
2569 // We need to wait for the client to make UDP contact first. 2681 ScenePresence sp = GetScenePresence(agentID);
2570 // It's the UDP contact that creates the scene presence 2682 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2571 ScenePresence sp = WaitGetScenePresence(agentID); 2683
2572 if (sp != null) 2684 if (sp != null)
2573 {
2574 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2575
2576 sp.ControllingClient.Close(); 2685 sp.ControllingClient.Close();
2577 } 2686
2578 else
2579 {
2580 m_log.WarnFormat("[SCENE]: Could not find scene presence for {0}", agentID);
2581 }
2582 // BANG! SLASH! 2687 // BANG! SLASH!
2583 m_authenticateHandler.RemoveCircuit(agentID); 2688 m_authenticateHandler.RemoveCircuit(agentID);
2584 2689
@@ -2678,6 +2783,7 @@ namespace OpenSim.Region.Framework.Scenes
2678 client.OnFetchInventory += HandleFetchInventory; 2783 client.OnFetchInventory += HandleFetchInventory;
2679 client.OnUpdateInventoryItem += UpdateInventoryItemAsset; 2784 client.OnUpdateInventoryItem += UpdateInventoryItemAsset;
2680 client.OnCopyInventoryItem += CopyInventoryItem; 2785 client.OnCopyInventoryItem += CopyInventoryItem;
2786 client.OnMoveItemsAndLeaveCopy += MoveInventoryItemsLeaveCopy;
2681 client.OnMoveInventoryItem += MoveInventoryItem; 2787 client.OnMoveInventoryItem += MoveInventoryItem;
2682 client.OnRemoveInventoryItem += RemoveInventoryItem; 2788 client.OnRemoveInventoryItem += RemoveInventoryItem;
2683 client.OnRemoveInventoryFolder += RemoveInventoryFolder; 2789 client.OnRemoveInventoryFolder += RemoveInventoryFolder;
@@ -2856,15 +2962,16 @@ namespace OpenSim.Region.Framework.Scenes
2856 /// </summary> 2962 /// </summary>
2857 /// <param name="agentId">The avatar's Unique ID</param> 2963 /// <param name="agentId">The avatar's Unique ID</param>
2858 /// <param name="client">The IClientAPI for the client</param> 2964 /// <param name="client">The IClientAPI for the client</param>
2859 public virtual void TeleportClientHome(UUID agentId, IClientAPI client) 2965 public virtual bool TeleportClientHome(UUID agentId, IClientAPI client)
2860 { 2966 {
2861 if (m_teleportModule != null) 2967 if (m_teleportModule != null)
2862 m_teleportModule.TeleportHome(agentId, client); 2968 return m_teleportModule.TeleportHome(agentId, client);
2863 else 2969 else
2864 { 2970 {
2865 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active"); 2971 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active");
2866 client.SendTeleportFailed("Unable to perform teleports on this simulator."); 2972 client.SendTeleportFailed("Unable to perform teleports on this simulator.");
2867 } 2973 }
2974 return false;
2868 } 2975 }
2869 2976
2870 /// <summary> 2977 /// <summary>
@@ -2963,6 +3070,16 @@ namespace OpenSim.Region.Framework.Scenes
2963 /// <param name="flags"></param> 3070 /// <param name="flags"></param>
2964 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags) 3071 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags)
2965 { 3072 {
3073 //Add half the avatar's height so that the user doesn't fall through prims
3074 ScenePresence presence;
3075 if (TryGetScenePresence(remoteClient.AgentId, out presence))
3076 {
3077 if (presence.Appearance != null)
3078 {
3079 position.Z = position.Z + (presence.Appearance.AvatarHeight / 2);
3080 }
3081 }
3082
2966 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt)) 3083 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt))
2967 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot. 3084 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot.
2968 m_dialogModule.SendAlertToUser(remoteClient, "Home position set."); 3085 m_dialogModule.SendAlertToUser(remoteClient, "Home position set.");
@@ -3039,7 +3156,9 @@ namespace OpenSim.Region.Framework.Scenes
3039 regions.Remove(RegionInfo.RegionHandle); 3156 regions.Remove(RegionInfo.RegionHandle);
3040 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3157 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3041 } 3158 }
3159 m_log.Debug("[Scene] Beginning ClientClosed");
3042 m_eventManager.TriggerClientClosed(agentID, this); 3160 m_eventManager.TriggerClientClosed(agentID, this);
3161 m_log.Debug("[Scene] Finished ClientClosed");
3043 } 3162 }
3044 catch (NullReferenceException) 3163 catch (NullReferenceException)
3045 { 3164 {
@@ -3047,7 +3166,12 @@ namespace OpenSim.Region.Framework.Scenes
3047 // Avatar is already disposed :/ 3166 // Avatar is already disposed :/
3048 } 3167 }
3049 3168
3169 m_log.Debug("[Scene] Beginning OnRemovePresence");
3050 m_eventManager.TriggerOnRemovePresence(agentID); 3170 m_eventManager.TriggerOnRemovePresence(agentID);
3171 m_log.Debug("[Scene] Finished OnRemovePresence");
3172
3173 if (avatar != null && (!avatar.IsChildAgent))
3174 avatar.SaveChangedAttachments();
3051 3175
3052 if (avatar != null && (!avatar.IsChildAgent)) 3176 if (avatar != null && (!avatar.IsChildAgent))
3053 avatar.SaveChangedAttachments(); 3177 avatar.SaveChangedAttachments();
@@ -3056,7 +3180,7 @@ namespace OpenSim.Region.Framework.Scenes
3056 delegate(IClientAPI client) 3180 delegate(IClientAPI client)
3057 { 3181 {
3058 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3182 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3059 try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); } 3183 try { client.SendKillObject(avatar.RegionHandle, new List<uint>() { avatar.LocalId}); }
3060 catch (NullReferenceException) { } 3184 catch (NullReferenceException) { }
3061 }); 3185 });
3062 3186
@@ -3067,8 +3191,11 @@ namespace OpenSim.Region.Framework.Scenes
3067 } 3191 }
3068 3192
3069 // Remove the avatar from the scene 3193 // Remove the avatar from the scene
3194 m_log.Debug("[Scene] Begin RemoveScenePresence");
3070 m_sceneGraph.RemoveScenePresence(agentID); 3195 m_sceneGraph.RemoveScenePresence(agentID);
3196 m_log.Debug("[Scene] Finished RemoveScenePresence. Removing the client manager");
3071 m_clientManager.Remove(agentID); 3197 m_clientManager.Remove(agentID);
3198 m_log.Debug("[Scene] Removed the client manager. Firing avatar.close");
3072 3199
3073 try 3200 try
3074 { 3201 {
@@ -3082,9 +3209,10 @@ namespace OpenSim.Region.Framework.Scenes
3082 { 3209 {
3083 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString()); 3210 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString());
3084 } 3211 }
3085 3212 m_log.Debug("[Scene] Done. Firing RemoveCircuit");
3086 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3213 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
3087 CleanDroppedAttachments(); 3214 CleanDroppedAttachments();
3215 m_log.Debug("[Scene] The avatar has left the building");
3088 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 3216 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
3089 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); 3217 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
3090 } 3218 }
@@ -3115,18 +3243,24 @@ namespace OpenSim.Region.Framework.Scenes
3115 3243
3116 #region Entities 3244 #region Entities
3117 3245
3118 public void SendKillObject(uint localID) 3246 public void SendKillObject(List<uint> localIDs)
3119 { 3247 {
3120 SceneObjectPart part = GetSceneObjectPart(localID); 3248 List<uint> deleteIDs = new List<uint>();
3121 if (part != null) // It is a prim 3249
3250 foreach (uint localID in localIDs)
3122 { 3251 {
3123 if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid 3252 SceneObjectPart part = GetSceneObjectPart(localID);
3253 if (part != null) // It is a prim
3124 { 3254 {
3125 if (part.ParentGroup.RootPart != part) // Child part 3255 if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid
3126 return; 3256 {
3257 if (part.ParentGroup.RootPart != part) // Child part
3258 continue;
3259 }
3127 } 3260 }
3261 deleteIDs.Add(localID);
3128 } 3262 }
3129 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); }); 3263 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, deleteIDs); });
3130 } 3264 }
3131 3265
3132 #endregion 3266 #endregion
@@ -3144,7 +3278,6 @@ namespace OpenSim.Region.Framework.Scenes
3144 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate; 3278 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
3145 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar; 3279 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar;
3146 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid; 3280 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
3147 m_sceneGridService.KiPrimitive += SendKillObject;
3148 m_sceneGridService.OnGetLandData += GetLandData; 3281 m_sceneGridService.OnGetLandData += GetLandData;
3149 } 3282 }
3150 3283
@@ -3153,7 +3286,6 @@ namespace OpenSim.Region.Framework.Scenes
3153 /// </summary> 3286 /// </summary>
3154 public void UnRegisterRegionWithComms() 3287 public void UnRegisterRegionWithComms()
3155 { 3288 {
3156 m_sceneGridService.KiPrimitive -= SendKillObject;
3157 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid; 3289 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid;
3158 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar; 3290 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar;
3159 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate; 3291 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate;
@@ -3233,13 +3365,16 @@ namespace OpenSim.Region.Framework.Scenes
3233 sp = null; 3365 sp = null;
3234 } 3366 }
3235 3367
3236 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3237 3368
3238 //On login test land permisions 3369 //On login test land permisions
3239 if (vialogin) 3370 if (vialogin)
3240 { 3371 {
3241 if (land != null && !TestLandRestrictions(agent, land, out reason)) 3372 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
3373 if (cache != null)
3374 cache.Remove(agent.firstname + " " + agent.lastname);
3375 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3242 { 3376 {
3377 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString());
3243 return false; 3378 return false;
3244 } 3379 }
3245 } 3380 }
@@ -3262,8 +3397,13 @@ namespace OpenSim.Region.Framework.Scenes
3262 3397
3263 try 3398 try
3264 { 3399 {
3265 if (!AuthorizeUser(agent, out reason)) 3400 // Always check estate if this is a login. Always
3266 return false; 3401 // check if banned regions are to be blacked out.
3402 if (vialogin || (!m_seeIntoBannedRegion))
3403 {
3404 if (!AuthorizeUser(agent.AgentID, out reason))
3405 return false;
3406 }
3267 } 3407 }
3268 catch (Exception e) 3408 catch (Exception e)
3269 { 3409 {
@@ -3366,6 +3506,8 @@ namespace OpenSim.Region.Framework.Scenes
3366 } 3506 }
3367 } 3507 }
3368 // Honor parcel landing type and position. 3508 // Honor parcel landing type and position.
3509 /*
3510 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3369 if (land != null) 3511 if (land != null)
3370 { 3512 {
3371 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) 3513 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero)
@@ -3373,26 +3515,32 @@ namespace OpenSim.Region.Framework.Scenes
3373 agent.startpos = land.LandData.UserLocation; 3515 agent.startpos = land.LandData.UserLocation;
3374 } 3516 }
3375 } 3517 }
3518 */// This is now handled properly in ScenePresence.MakeRootAgent
3376 } 3519 }
3377 3520
3378 return true; 3521 return true;
3379 } 3522 }
3380 3523
3381 private bool TestLandRestrictions(AgentCircuitData agent, ILandObject land, out string reason) 3524 private bool TestLandRestrictions(UUID agentID, out string reason, ref float posX, ref float posY)
3382 { 3525 {
3383 3526 reason = String.Empty;
3384 bool banned = land.IsBannedFromLand(agent.AgentID); 3527
3385 bool restricted = land.IsRestrictedFromLand(agent.AgentID); 3528 ILandObject land = LandChannel.GetLandObject(posX, posY);
3529 if (land == null)
3530 return false;
3531
3532 bool banned = land.IsBannedFromLand(agentID);
3533 bool restricted = land.IsRestrictedFromLand(agentID);
3386 3534
3387 if (banned || restricted) 3535 if (banned || restricted)
3388 { 3536 {
3389 ILandObject nearestParcel = GetNearestAllowedParcel(agent.AgentID, agent.startpos.X, agent.startpos.Y); 3537 ILandObject nearestParcel = GetNearestAllowedParcel(agentID, posX, posY);
3390 if (nearestParcel != null) 3538 if (nearestParcel != null)
3391 { 3539 {
3392 //Move agent to nearest allowed 3540 //Move agent to nearest allowed
3393 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel); 3541 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel);
3394 agent.startpos.X = newPosition.X; 3542 posX = newPosition.X;
3395 agent.startpos.Y = newPosition.Y; 3543 posY = newPosition.Y;
3396 } 3544 }
3397 else 3545 else
3398 { 3546 {
@@ -3448,19 +3596,19 @@ namespace OpenSim.Region.Framework.Scenes
3448 /// <param name="reason">outputs the reason to this string</param> 3596 /// <param name="reason">outputs the reason to this string</param>
3449 /// <returns>True if the region accepts this agent. False if it does not. False will 3597 /// <returns>True if the region accepts this agent. False if it does not. False will
3450 /// also return a reason.</returns> 3598 /// also return a reason.</returns>
3451 protected virtual bool AuthorizeUser(AgentCircuitData agent, out string reason) 3599 protected virtual bool AuthorizeUser(UUID agentID, out string reason)
3452 { 3600 {
3453 reason = String.Empty; 3601 reason = String.Empty;
3454 3602
3455 if (!m_strictAccessControl) return true; 3603 if (!m_strictAccessControl) return true;
3456 if (Permissions.IsGod(agent.AgentID)) return true; 3604 if (Permissions.IsGod(agentID)) return true;
3457 3605
3458 if (AuthorizationService != null) 3606 if (AuthorizationService != null)
3459 { 3607 {
3460 if (!AuthorizationService.IsAuthorizedForRegion(agent.AgentID.ToString(), RegionInfo.RegionID.ToString(),out reason)) 3608 if (!AuthorizationService.IsAuthorizedForRegion(agentID.ToString(), RegionInfo.RegionID.ToString(),out reason))
3461 { 3609 {
3462 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region", 3610 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} at {1} because the user does not have access to the region",
3463 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3611 agentID, RegionInfo.RegionName);
3464 //reason = String.Format("You are not currently on the access list for {0}",RegionInfo.RegionName); 3612 //reason = String.Format("You are not currently on the access list for {0}",RegionInfo.RegionName);
3465 return false; 3613 return false;
3466 } 3614 }
@@ -3468,10 +3616,26 @@ namespace OpenSim.Region.Framework.Scenes
3468 3616
3469 if (m_regInfo.EstateSettings != null) 3617 if (m_regInfo.EstateSettings != null)
3470 { 3618 {
3471 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID)) 3619 int flags = GetUserFlags(agentID);
3620 if (m_regInfo.EstateSettings.IsBanned(agentID, flags))
3472 { 3621 {
3473 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", 3622 //Add some more info to help users
3474 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3623 if (!m_regInfo.EstateSettings.IsBanned(agentID, 32))
3624 {
3625 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} at {1} because the region requires age verification",
3626 agentID, RegionInfo.RegionName);
3627 reason = String.Format("Denied access to region {0}: Region requires age verification", RegionInfo.RegionName);
3628 return false;
3629 }
3630 if (!m_regInfo.EstateSettings.IsBanned(agentID, 4))
3631 {
3632 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} {1} because the region requires payment info on file",
3633 agentID, RegionInfo.RegionName);
3634 reason = String.Format("Denied access to region {0}: Region requires payment info on file", RegionInfo.RegionName);
3635 return false;
3636 }
3637 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} at {3} because the user is on the banlist",
3638 agentID, RegionInfo.RegionName);
3475 reason = String.Format("Denied access to region {0}: You have been banned from that region.", 3639 reason = String.Format("Denied access to region {0}: You have been banned from that region.",
3476 RegionInfo.RegionName); 3640 RegionInfo.RegionName);
3477 return false; 3641 return false;
@@ -3488,7 +3652,7 @@ namespace OpenSim.Region.Framework.Scenes
3488 if (groupsModule != null) 3652 if (groupsModule != null)
3489 { 3653 {
3490 GroupMembershipData[] GroupMembership = 3654 GroupMembershipData[] GroupMembership =
3491 groupsModule.GetMembershipData(agent.AgentID); 3655 groupsModule.GetMembershipData(agentID);
3492 3656
3493 if (GroupMembership != null) 3657 if (GroupMembership != null)
3494 { 3658 {
@@ -3517,44 +3681,16 @@ namespace OpenSim.Region.Framework.Scenes
3517 m_log.ErrorFormat("[CONNECTION BEGIN]: EstateGroups is null!"); 3681 m_log.ErrorFormat("[CONNECTION BEGIN]: EstateGroups is null!");
3518 3682
3519 if (!m_regInfo.EstateSettings.PublicAccess && 3683 if (!m_regInfo.EstateSettings.PublicAccess &&
3520 !m_regInfo.EstateSettings.HasAccess(agent.AgentID) && 3684 !m_regInfo.EstateSettings.HasAccess(agentID) &&
3521 !groupAccess) 3685 !groupAccess)
3522 { 3686 {
3523 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate", 3687 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} at {1} because the user does not have access to the estate",
3524 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3688 agentID, RegionInfo.RegionName);
3525 reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.", 3689 reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.",
3526 RegionInfo.RegionName); 3690 RegionInfo.RegionName);
3527 return false; 3691 return false;
3528 } 3692 }
3529 3693
3530 // TODO: estate/region settings are not properly hooked up
3531 // to ILandObject.isRestrictedFromLand()
3532 // if (null != LandChannel)
3533 // {
3534 // // region seems to have local Id of 1
3535 // ILandObject land = LandChannel.GetLandObject(1);
3536 // if (null != land)
3537 // {
3538 // if (land.isBannedFromLand(agent.AgentID))
3539 // {
3540 // m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user has been banned from land",
3541 // agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
3542 // reason = String.Format("Denied access to private region {0}: You are banned from that region.",
3543 // RegionInfo.RegionName);
3544 // return false;
3545 // }
3546
3547 // if (land.isRestrictedFromLand(agent.AgentID))
3548 // {
3549 // m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region",
3550 // agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
3551 // reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.",
3552 // RegionInfo.RegionName);
3553 // return false;
3554 // }
3555 // }
3556 // }
3557
3558 return true; 3694 return true;
3559 } 3695 }
3560 3696
@@ -3658,6 +3794,13 @@ namespace OpenSim.Region.Framework.Scenes
3658 3794
3659 // We have to wait until the viewer contacts this region after receiving EAC. 3795 // We have to wait until the viewer contacts this region after receiving EAC.
3660 // That calls AddNewClient, which finally creates the ScenePresence 3796 // That calls AddNewClient, which finally creates the ScenePresence
3797 int flags = GetUserFlags(cAgentData.AgentID);
3798 if (m_regInfo.EstateSettings.IsBanned(cAgentData.AgentID, flags))
3799 {
3800 m_log.DebugFormat("[SCENE]: Denying root agent entry to {0}: banned", cAgentData.AgentID);
3801 return false;
3802 }
3803
3661 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); 3804 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2);
3662 if (nearestParcel == null) 3805 if (nearestParcel == null)
3663 { 3806 {
@@ -3665,6 +3808,14 @@ namespace OpenSim.Region.Framework.Scenes
3665 return false; 3808 return false;
3666 } 3809 }
3667 3810
3811 int num = m_sceneGraph.GetNumberOfScenePresences();
3812
3813 if (num >= RegionInfo.RegionSettings.AgentLimit)
3814 {
3815 if (!Permissions.IsAdministrator(cAgentData.AgentID))
3816 return false;
3817 }
3818
3668 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 3819 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
3669 3820
3670 if (childAgentUpdate != null) 3821 if (childAgentUpdate != null)
@@ -3731,12 +3882,22 @@ namespace OpenSim.Region.Framework.Scenes
3731 return false; 3882 return false;
3732 } 3883 }
3733 3884
3885 public bool IncomingCloseAgent(UUID agentID)
3886 {
3887 return IncomingCloseAgent(agentID, false);
3888 }
3889
3890 public bool IncomingCloseChildAgent(UUID agentID)
3891 {
3892 return IncomingCloseAgent(agentID, true);
3893 }
3894
3734 /// <summary> 3895 /// <summary>
3735 /// Tell a single agent to disconnect from the region. 3896 /// Tell a single agent to disconnect from the region.
3736 /// </summary> 3897 /// </summary>
3737 /// <param name="regionHandle"></param>
3738 /// <param name="agentID"></param> 3898 /// <param name="agentID"></param>
3739 public bool IncomingCloseAgent(UUID agentID) 3899 /// <param name="childOnly"></param>
3900 public bool IncomingCloseAgent(UUID agentID, bool childOnly)
3740 { 3901 {
3741 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 3902 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
3742 3903
@@ -3748,7 +3909,7 @@ namespace OpenSim.Region.Framework.Scenes
3748 { 3909 {
3749 m_sceneGraph.removeUserCount(false); 3910 m_sceneGraph.removeUserCount(false);
3750 } 3911 }
3751 else 3912 else if (!childOnly)
3752 { 3913 {
3753 m_sceneGraph.removeUserCount(true); 3914 m_sceneGraph.removeUserCount(true);
3754 } 3915 }
@@ -3764,9 +3925,12 @@ namespace OpenSim.Region.Framework.Scenes
3764 } 3925 }
3765 else 3926 else
3766 presence.ControllingClient.SendShutdownConnectionNotice(); 3927 presence.ControllingClient.SendShutdownConnectionNotice();
3928 presence.ControllingClient.Close(false);
3929 }
3930 else if (!childOnly)
3931 {
3932 presence.ControllingClient.Close(true);
3767 } 3933 }
3768
3769 presence.ControllingClient.Close();
3770 return true; 3934 return true;
3771 } 3935 }
3772 3936
@@ -4376,34 +4540,66 @@ namespace OpenSim.Region.Framework.Scenes
4376 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID); 4540 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID);
4377 } 4541 }
4378 4542
4379 public int GetHealth() 4543 public int GetHealth(out int flags, out string message)
4380 { 4544 {
4381 // Returns: 4545 // Returns:
4382 // 1 = sim is up and accepting http requests. The heartbeat has 4546 // 1 = sim is up and accepting http requests. The heartbeat has
4383 // stopped and the sim is probably locked up, but a remote 4547 // stopped and the sim is probably locked up, but a remote
4384 // admin restart may succeed 4548 // admin restart may succeed
4385 // 4549 //
4386 // 2 = Sim is up and the heartbeat is running. The sim is likely 4550 // 2 = Sim is up and the heartbeat is running. The sim is likely
4387 // usable for people within and logins _may_ work 4551 // usable for people within
4552 //
4553 // 3 = Sim is up and one packet thread is running. Sim is
4554 // unstable and will not accept new logins
4555 //
4556 // 4 = Sim is up and both packet threads are running. Sim is
4557 // likely usable
4388 // 4558 //
4389 // 3 = We have seen a new user enter within the past 4 minutes 4559 // 5 = We have seen a new user enter within the past 4 minutes
4390 // which can be seen as positive confirmation of sim health 4560 // which can be seen as positive confirmation of sim health
4391 // 4561 //
4562
4563 flags = 0;
4564 message = String.Empty;
4565
4566 CheckHeartbeat();
4567
4568 if (m_firstHeartbeat || (m_lastIncoming == 0 && m_lastOutgoing == 0))
4569 {
4570 // We're still starting
4571 // 0 means "in startup", it can't happen another way, since
4572 // to get here, we must be able to accept http connections
4573 return 0;
4574 }
4575
4392 int health=1; // Start at 1, means we're up 4576 int health=1; // Start at 1, means we're up
4393 4577
4394 if ((Util.EnvironmentTickCountSubtract(m_lastUpdate)) < 1000) 4578 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) < 1000)
4579 {
4580 health+=1;
4581 flags |= 1;
4582 }
4583
4584 if (Util.EnvironmentTickCountSubtract(m_lastIncoming) < 1000)
4585 {
4395 health+=1; 4586 health+=1;
4396 else 4587 flags |= 2;
4588 }
4589
4590 if (Util.EnvironmentTickCountSubtract(m_lastOutgoing) < 1000)
4591 {
4592 health+=1;
4593 flags |= 4;
4594 }
4595
4596 if (flags != 7)
4397 return health; 4597 return health;
4398 4598
4399 // A login in the last 4 mins? We can't be doing too badly 4599 // A login in the last 4 mins? We can't be doing too badly
4400 // 4600 //
4401 if ((Util.EnvironmentTickCountSubtract(m_LastLogin)) < 240000) 4601 if (Util.EnvironmentTickCountSubtract(m_LastLogin) < 240000)
4402 health++; 4602 health++;
4403 else
4404 return health;
4405
4406 CheckHeartbeat();
4407 4603
4408 return health; 4604 return health;
4409 } 4605 }
@@ -4596,7 +4792,7 @@ namespace OpenSim.Region.Framework.Scenes
4596 if (m_firstHeartbeat) 4792 if (m_firstHeartbeat)
4597 return; 4793 return;
4598 4794
4599 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 2000) 4795 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 10000)
4600 StartTimer(); 4796 StartTimer();
4601 } 4797 }
4602 4798
@@ -4854,8 +5050,17 @@ namespace OpenSim.Region.Framework.Scenes
4854 { 5050 {
4855 float ominX, ominY, ominZ, omaxX, omaxY, omaxZ; 5051 float ominX, ominY, ominZ, omaxX, omaxY, omaxZ;
4856 5052
5053 Vector3 vec = g.AbsolutePosition;
5054
4857 g.GetAxisAlignedBoundingBoxRaw(out ominX, out omaxX, out ominY, out omaxY, out ominZ, out omaxZ); 5055 g.GetAxisAlignedBoundingBoxRaw(out ominX, out omaxX, out ominY, out omaxY, out ominZ, out omaxZ);
4858 5056
5057 ominX += vec.X;
5058 omaxX += vec.X;
5059 ominY += vec.Y;
5060 omaxY += vec.Y;
5061 ominZ += vec.Z;
5062 omaxZ += vec.Z;
5063
4859 if (minX > ominX) 5064 if (minX > ominX)
4860 minX = ominX; 5065 minX = ominX;
4861 if (minY > ominY) 5066 if (minY > ominY)
@@ -4925,10 +5130,28 @@ namespace OpenSim.Region.Framework.Scenes
4925 }); 5130 });
4926 } 5131 }
4927 5132
4928 foreach (SceneObjectGroup grp in objectsToDelete) 5133 if (objectsToDelete.Count > 0)
4929 { 5134 {
4930 m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID); 5135 m_log.DebugFormat("[SCENE]: Starting delete of {0} dropped attachments", objectsToDelete.Count);
4931 DeleteSceneObject(grp, true); 5136 foreach (SceneObjectGroup grp in objectsToDelete)
5137 {
5138 m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID);
5139 DeleteSceneObject(grp, true);
5140 }
5141 m_log.Debug("[SCENE]: Finished dropped attachment deletion");
5142 }
5143 }
5144
5145 public void ThreadAlive(int threadCode)
5146 {
5147 switch(threadCode)
5148 {
5149 case 1: // Incoming
5150 m_lastIncoming = Util.EnvironmentTickCount();
5151 break;
5152 case 2: // Incoming
5153 m_lastOutgoing = Util.EnvironmentTickCount();
5154 break;
4932 } 5155 }
4933 } 5156 }
4934 5157
@@ -4940,6 +5163,38 @@ namespace OpenSim.Region.Framework.Scenes
4940 // child agent creation, thereby emulating the SL behavior. 5163 // child agent creation, thereby emulating the SL behavior.
4941 public bool QueryAccess(UUID agentID, Vector3 position, out string reason) 5164 public bool QueryAccess(UUID agentID, Vector3 position, out string reason)
4942 { 5165 {
5166 reason = "You are banned from the region";
5167
5168 if (!AuthorizeUser(agentID, out reason))
5169 {
5170 // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID);
5171 return false;
5172 }
5173
5174 if (position == Vector3.Zero) // Teleport
5175 {
5176 float posX = 128.0f;
5177 float posY = 128.0f;
5178
5179 if (!TestLandRestrictions(agentID, out reason, ref posX, ref posY))
5180 {
5181 // m_log.DebugFormat("[SCENE]: Denying {0} because they are banned on all parcels", agentID);
5182 return false;
5183 }
5184 }
5185 else // Walking
5186 {
5187 ILandObject land = LandChannel.GetLandObject(position.X, position.Y);
5188 if (land == null)
5189 return false;
5190
5191 bool banned = land.IsBannedFromLand(agentID);
5192 bool restricted = land.IsRestrictedFromLand(agentID);
5193
5194 if (banned || restricted)
5195 return false;
5196 }
5197
4943 reason = String.Empty; 5198 reason = String.Empty;
4944 return true; 5199 return true;
4945 } 5200 }