Merge branch 'master' into httptests

UbitUmarov [2017-01-06 01:09:42]
Merge branch 'master' into httptests
Filename
OpenSim/Addons/Groups/GroupsModule.cs
OpenSim/Framework/ChildAgentDataUpdate.cs
OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs
OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
OpenSim/Region/Framework/Scenes/GodController.cs
OpenSim/Region/Framework/Scenes/Scene.cs
OpenSim/Region/Framework/Scenes/ScenePresence.cs
OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
bin/OpenSimDefaults.ini
diff --git a/OpenSim/Addons/Groups/GroupsModule.cs b/OpenSim/Addons/Groups/GroupsModule.cs
index 1e9f2b5..aa5105e 100644
--- a/OpenSim/Addons/Groups/GroupsModule.cs
+++ b/OpenSim/Addons/Groups/GroupsModule.cs
@@ -756,7 +756,7 @@ namespace OpenSim.Groups

             if (avatar != null)
             {
-                if (avatar.UserLevel < m_levelGroupCreate)
+                if (avatar.GodController.UserLevel < m_levelGroupCreate)
                 {
                     remoteClient.SendCreateGroupReply(UUID.Zero, false, String.Format("Insufficient permissions to create a group. Requires level {0}", m_levelGroupCreate));
                     return UUID.Zero;
diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs
index 0e5eaf2..b9d64b1 100644
--- a/OpenSim/Framework/ChildAgentDataUpdate.cs
+++ b/OpenSim/Framework/ChildAgentDataUpdate.cs
@@ -89,6 +89,8 @@ namespace OpenSim.Framework
         public Vector3 AtAxis;
         public Vector3 LeftAxis;
         public Vector3 UpAxis;
+        //public int GodLevel;
+        public OSD GodData = new OSDMap();
         public bool ChangedGrid;

         // This probably shouldn't be here
@@ -116,6 +118,13 @@ namespace OpenSim.Framework

             args["far"] = OSD.FromReal(Far);
             args["changed_grid"] = OSD.FromBoolean(ChangedGrid);
+            //args["god_level"] = OSD.FromString(GodLevel.ToString());
+            args["god_data"] = GodData;
+            OSDMap g = (OSDMap)GodData;
+            // Set legacy value
+            // TODO: remove after 0.9 is superseded
+            if (g.ContainsKey("ViewerUiIsGod"))
+                args["god_level"] = g["ViewerUiIsGod"].AsBoolean() ? 200 : 0;;

             if ((Throttles != null) && (Throttles.Length > 0))
                 args["throttles"] = OSD.FromBinary(Throttles);
@@ -174,6 +183,11 @@ namespace OpenSim.Framework
             if (args["changed_grid"] != null)
                 ChangedGrid = args["changed_grid"].AsBoolean();

+            //if (args["god_level"] != null)
+            //    Int32.TryParse(args["god_level"].AsString(), out GodLevel);
+            if (args["god_data"] != null)
+                GodData = args["god_data"];
+
             if (args["far"] != null)
                 Far = (float)(args["far"].AsReal());

@@ -348,7 +362,8 @@ namespace OpenSim.Framework
         public Quaternion BodyRotation;
         public uint ControlFlags;
         public float EnergyLevel;
-        public Byte GodLevel;
+        public OSD GodData = new OSDMap();
+        //public Byte GodLevel;
         public bool AlwaysRun;
         public UUID PreyAgent;
         public Byte AgentAccess;
@@ -422,7 +437,11 @@ namespace OpenSim.Framework
             args["control_flags"] = OSD.FromString(ControlFlags.ToString());

             args["energy_level"] = OSD.FromReal(EnergyLevel);
-            args["god_level"] = OSD.FromString(GodLevel.ToString());
+            //args["god_level"] = OSD.FromString(GodLevel.ToString());
+            args["god_data"] = GodData;
+            OSDMap g = (OSDMap)GodData;
+            if (g.ContainsKey("ViewerUiIsGod"))
+                args["god_level"] = g["ViewerUiIsGod"].AsBoolean() ? 200 : 0;;
             args["always_run"] = OSD.FromBoolean(AlwaysRun);
             args["prey_agent"] = OSD.FromUUID(PreyAgent);
             args["agent_access"] = OSD.FromString(AgentAccess.ToString());
@@ -600,8 +619,11 @@ namespace OpenSim.Framework
             if (args["energy_level"] != null)
                 EnergyLevel = (float)(args["energy_level"].AsReal());

-            if (args["god_level"] != null)
-                Byte.TryParse(args["god_level"].AsString(), out GodLevel);
+            //if (args["god_level"] != null)
+            //    Byte.TryParse(args["god_level"].AsString(), out GodLevel);
+
+            if (args["god_data"] != null)
+                GodData = args["god_data"];

             if (args["always_run"] != null)
                 AlwaysRun = args["always_run"].AsBoolean();
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index 8cb40e1..58b7b00 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -537,7 +537,7 @@ namespace OpenSim.Region.ClientStack.Linden
                 // check user level
                 if (avatar != null)
                 {
-                    if (avatar.UserLevel < m_levelUpload)
+                    if (avatar.GodController.UserLevel < m_levelUpload)
                     {
                         LLSDAssetUploadError resperror = new LLSDAssetUploadError();
                         resperror.message = "Insufficient permissions to upload";
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index dba2872..316956b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -11455,7 +11455,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                 ScenePresence p;
                 if (scene.TryGetScenePresence(sender.AgentId, out p))
                 {
-                    if (p.GodLevel >= 200)
+                    if (p.GodController.GodLevel >= 200)
                     {
                         groupProfileReply.GroupData.OpenEnrollment = true;
                         groupProfileReply.GroupData.MembershipFee = 0;
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
index 89fdf09..7d9f3b3 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
@@ -255,7 +255,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
                 // check user level
                 if (avatar != null)
                 {
-                    if (avatar.UserLevel < m_levelUpload)
+                    if (avatar.GodController.UserLevel < m_levelUpload)
                     {
                         remoteClient.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
                         return;
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
index 53800bb..adf5c68 100644
--- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
@@ -229,7 +229,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
                     fromPos = avatar.AbsolutePosition;
                     fromName = avatar.Name;
                     fromID = c.Sender.AgentId;
-                    if (avatar.GodLevel >= 200)
+                    if (avatar.GodController.GodLevel >= 200)
                     { // let gods speak to outside or things may get confusing
                         fromNamePrefix = m_adminPrefix;
                         checkParcelHide = false;
@@ -305,7 +305,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
                     {
                         if (checkParcelHide)
                         {
-                            if (sourceParcelID != Presencecheck.LandData.GlobalID && presence.GodLevel < 200)
+                            if (sourceParcelID != Presencecheck.LandData.GlobalID && presence.GodController.GodLevel < 200)
                                 return;
                         }
                         if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true)
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs
index e5bf919..9843f2e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs
@@ -118,7 +118,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
                 // If we're in god mode, we reverse the meaning. Offer
                 // calling card becomes "Take a calling card" for that
                 // person, no matter if they agree or not.
-                if (sp.GodLevel >= 200)
+                if (sp.GodController.GodLevel >= 200)
                 {
                     CreateCallingCard(client.AgentId, destID, UUID.Zero, true);
                     return;
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
index ac05a6e..82154bc 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
@@ -141,7 +141,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
                     if (avatar == null)
                         return;

-                    if (avatar.UserLevel < m_levelHGFriends)
+                    if (avatar.GodController.UserLevel < m_levelHGFriends)
                     {
                         client.SendAgentAlertMessage("Unable to send friendship invitation to foreigner. Insufficient permissions.", false);
                         return;
@@ -844,4 +844,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
             return false;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
index 8d3c10d..b7ae298 100644
--- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
@@ -173,7 +173,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods

             sp.GrantGodlikePowers(token, godLike);

-            if (godLike && sp.GodLevel < 200 && DialogModule != null)
+            if (godLike && sp.GodController.GodLevel < 200 && DialogModule != null)
                DialogModule.SendAlertToUser(agentID, "Request for god powers denied");
         }

@@ -194,14 +194,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
             int godlevel = 200;
             // update level so higher gods can kick lower ones
             ScenePresence god = m_scene.GetScenePresence(godID);
-            if(god != null && god.GodLevel > godlevel)
-                godlevel =  god.GodLevel;
+            if(god != null && god.GodController.GodLevel > godlevel)
+                godlevel =  god.GodController.GodLevel;

             if(agentID == ALL_AGENTS)
             {
                 m_scene.ForEachRootScenePresence(delegate(ScenePresence p)
                     {
-                        if (p.UUID != godID && godlevel > p.GodLevel)
+                        if (p.UUID != godID && godlevel > p.GodController.GodLevel)
                             doKickmodes(godID, p, kickflags, reason);
                     });
                 return;
@@ -224,7 +224,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
                 return;
             }

-            if (godlevel <= sp.GodLevel) // no god wars
+            if (godlevel <= sp.GodController.GodLevel) // no god wars
                 return;

             if(sp.UUID == godID)
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
index c517a30..bd95ff0 100644
--- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
@@ -169,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure

             GridInstantMessage m;

-            if (scene.Permissions.IsAdministrator(client.AgentId) && presence.GodLevel >= 200 && (!scene.Permissions.IsAdministrator(targetid)))
+            if (scene.Permissions.IsAdministrator(client.AgentId) && presence.GodController.GodLevel >= 200 && (!scene.Permissions.IsAdministrator(targetid)))
             {
                 m = new GridInstantMessage(scene, client.AgentId,
                         client.FirstName+" "+client.LastName, targetid,
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 6b1eb54..d0e5d86 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -2077,6 +2077,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
                 agentpos.Position = sp.AbsolutePosition;
                 agentpos.Velocity = sp.Velocity;
                 agentpos.RegionHandle = currentRegionHandler;
+                //agentpos.GodLevel = sp.GodLevel;
+                agentpos.GodData = sp.GodController.State();
                 agentpos.Throttles = spClient.GetThrottlesPacked(1);
                 //            agentpos.ChildrenCapSeeds = seeds;

diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index 4ad500a..1ce6927 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -272,7 +272,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
             {
                 // this user is going to another grid
                 // for local users, check if HyperGrid teleport is allowed, based on user level
-                if (Scene.UserManagementModule.IsLocalGridUser(sp.UUID) && sp.UserLevel < m_levelHGTeleport)
+                if (Scene.UserManagementModule.IsLocalGridUser(sp.UUID) && sp.GodController.UserLevel < m_levelHGTeleport)
                 {
                     m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unable to HG teleport agent due to insufficient UserLevel.");
                     reason = "Hypergrid teleport not allowed";
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 63b8de0..3a8d6b7 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -1977,7 +1977,7 @@ namespace OpenSim.Region.CoreModules.World.Land
             ScenePresence SP;
             ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out SP);
             List<SceneObjectGroup> returns = new List<SceneObjectGroup>();
-            if (SP.UserLevel != 0)
+            if (SP.GodController.UserLevel != 0)
             {
                 if (flags == 0) //All parcels, scripted or not
                 {
@@ -2043,7 +2043,7 @@ namespace OpenSim.Region.CoreModules.World.Land
             ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out parcelManager);
             System.Threading.Timer Timer;

-            if (targetAvatar.UserLevel == 0)
+            if (targetAvatar.GodController.UserLevel == 0)
             {
                 ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y);
                 if (!((Scene)client.Scene).Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze, true))
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 1a61771..02d0e02 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -547,7 +547,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
             {
                 ScenePresence sp = m_scene.GetScenePresence(user);
                 if (sp != null)
-                    return (sp.UserLevel >= 200);
+                    return (sp.GodController.UserLevel >= 200);

                 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, user);
                 if (account != null)
diff --git a/OpenSim/Region/Framework/Scenes/GodController.cs b/OpenSim/Region/Framework/Scenes/GodController.cs
new file mode 100644
index 0000000..5763e03
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/GodController.cs
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Xml;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Threading;
+using System.Timers;
+using Timer = System.Timers.Timer;
+using OpenMetaverse;
+using OpenMetaverse.StructuredData;
+using log4net;
+using Nini.Config;
+using OpenSim.Framework;
+using OpenSim.Framework.Client;
+using OpenSim.Framework.Monitoring;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Region.Framework.Scenes.Types;
+using OpenSim.Services.Interfaces;
+
+namespace OpenSim.Region.Framework.Scenes
+{
+    public class GodController
+    {
+        ScenePresence m_scenePresence;
+        Scene m_scene;
+        protected bool m_allowGridGods;
+        protected bool m_regionOwnerIsGod;
+        protected bool m_regionManagerIsGod;
+        protected bool m_parcelOwnerIsGod;
+        protected bool m_forceGodModeAlwaysOn;
+        protected bool m_allowGodActionsWithoutGodMode;
+
+        protected bool m_viewerUiIsGod = false;
+
+        protected int m_userLevel = 0;
+
+        public GodController(Scene scene, ScenePresence sp)
+        {
+            m_scene = scene;
+            m_scenePresence = sp;
+
+            IConfigSource config = scene.Config;
+
+            string[] sections = new string[] { "Startup", "Permissions" };
+
+            // God level is based on UserLevel. Gods will have that
+            // level grid-wide. Others may become god locally but grid
+            // gods are god everywhere.
+            m_allowGridGods =
+                    Util.GetConfigVarFromSections<bool>(config,
+                    "allow_grid_gods", sections, false);
+
+            // The owner of a region is a god in his region only.
+            m_regionOwnerIsGod =
+                    Util.GetConfigVarFromSections<bool>(config,
+                    "region_owner_is_god", sections, true);
+
+            // Region managers are gods in the regions they manage.
+            m_regionManagerIsGod =
+                    Util.GetConfigVarFromSections<bool>(config,
+                    "region_manager_is_god", sections, false);
+
+            // Parcel owners are gods in their own parcels only.
+            m_parcelOwnerIsGod =
+                    Util.GetConfigVarFromSections<bool>(config,
+                    "parcel_owner_is_god", sections, false);
+
+            // God mode should be turned on in the viewer whenever
+            // the user has god rights somewhere. They may choose
+            // to turn it off again, though.
+            m_forceGodModeAlwaysOn =
+                    Util.GetConfigVarFromSections<bool>(config,
+                    "automatic_gods", sections, false);
+
+            // The user can execute any and all god functions, as
+            // permitted by the viewer UI, without actually "godding
+            // up". This is the default state in 0.8.2.
+            m_allowGodActionsWithoutGodMode =
+                    Util.GetConfigVarFromSections<bool>(config,
+                    "implicit_gods", sections, false);
+
+        }
+
+        protected bool CanBeGod()
+        {
+            bool canBeGod = false;
+
+            if (m_allowGridGods && m_userLevel > 0)
+                canBeGod = true;
+
+            if (m_regionOwnerIsGod && m_scene.RegionInfo.EstateSettings.IsEstateOwner(m_scenePresence.UUID))
+                canBeGod = true;
+
+            if (m_regionManagerIsGod && m_scene.Permissions.IsEstateManager(m_scenePresence.UUID))
+                canBeGod = true;
+
+            if (!canBeGod && m_parcelOwnerIsGod) // Skip expensive check if we're already god!
+            {
+                Vector3 pos = m_scenePresence.AbsolutePosition;
+                ILandObject parcel = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
+                if (parcel != null && parcel.LandData.OwnerID == m_scenePresence.UUID)
+                    canBeGod = true;
+            }
+
+            return canBeGod;
+        }
+
+        protected void SyncViewerState()
+        {
+            bool canBeGod = CanBeGod();
+
+            bool shoudBeGod = m_forceGodModeAlwaysOn ? canBeGod : (m_viewerUiIsGod && canBeGod);
+
+            int godLevel = m_allowGridGods ? m_userLevel : 200;
+            if (!shoudBeGod)
+                godLevel = 0;
+
+            if (m_viewerUiIsGod != shoudBeGod)
+            {
+                m_scenePresence.ControllingClient.SendAdminResponse(UUID.Zero, (uint)godLevel);
+                m_viewerUiIsGod = shoudBeGod;
+            }
+        }
+
+        public bool RequestGodMode(bool god)
+        {
+            if (!god)
+            {
+                if (m_viewerUiIsGod)
+                    m_scenePresence.ControllingClient.SendAdminResponse(UUID.Zero, 0);
+
+                m_viewerUiIsGod = false;
+
+                return true;
+            }
+
+            if (!CanBeGod())
+                return false;
+
+            int godLevel = m_allowGridGods ? m_userLevel : 200;
+
+            if (!m_viewerUiIsGod)
+                m_scenePresence.ControllingClient.SendAdminResponse(UUID.Zero, (uint)godLevel);
+
+            m_viewerUiIsGod = true;
+
+            return true;
+        }
+
+        public OSD State()
+        {
+            OSDMap godMap = new OSDMap(2);
+
+            godMap.Add("ViewerUiIsGod", OSD.FromBoolean(m_viewerUiIsGod));
+
+            return godMap;
+        }
+
+        public void SetState(OSD state)
+        {
+            OSDMap s = (OSDMap)state;
+
+            if (s.ContainsKey("ViewerUiIsGod"))
+                m_viewerUiIsGod = s["ViewerUiIsGod"].AsBoolean();
+
+            SyncViewerState();
+        }
+
+        public int UserLevel
+        {
+            get { return m_userLevel; }
+            set { m_userLevel = UserLevel; }
+        }
+
+        public int GodLevel
+        {
+            get
+            {
+                int godLevel = m_allowGridGods ? m_userLevel : 200;
+                if (!m_viewerUiIsGod)
+                    godLevel = 0;
+
+                return godLevel;
+            }
+        }
+
+        public int EffectiveLevel
+        {
+            get
+            {
+                int godLevel = m_allowGridGods ? m_userLevel : 200;
+                if (m_viewerUiIsGod)
+                    return godLevel;
+
+                if (m_allowGodActionsWithoutGodMode && CanBeGod())
+                    return godLevel;
+
+                return 0;
+            }
+        }
+    }
+}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 352bc05..87c3049 100755
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1207,7 +1207,6 @@ namespace OpenSim.Region.Framework.Scenes

             #endregion Interest Management

-
             StatsReporter = new SimStatsReporter(this);

             StatsReporter.OnSendStatsResult += SendSimStatsPackets;
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 29e139b..339f1b1 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -501,21 +501,7 @@ namespace OpenSim.Region.Framework.Scenes
             get { return m_invulnerable; }
         }

-        private int m_userLevel;
-
-        public int UserLevel
-        {
-            get { return m_userLevel; }
-            private set { m_userLevel = value; }
-        }
-
-        private int m_godLevel;
-
-        public int GodLevel
-        {
-            get { return m_godLevel; }
-            private set { m_godLevel = value; }
-        }
+        public GodController GodController { get; private set; }

         private ulong m_rootRegionHandle;
         private Vector3 m_rootRegionPosition = new Vector3();
@@ -1059,6 +1045,8 @@ namespace OpenSim.Region.Framework.Scenes
         public ScenePresence(
             IClientAPI client, Scene world, AvatarAppearance appearance, PresenceType type)
         {
+            GodController = new GodController(world, this);
+
             m_scene = world;
             AttachmentsSyncLock = new Object();
             AllowMovement = true;
@@ -1085,7 +1073,7 @@ namespace OpenSim.Region.Framework.Scenes
                 m_userFlags = 0;

             if (account != null)
-                UserLevel = account.UserLevel;
+                GodController.UserLevel = account.UserLevel;

  //           IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
  //           if (gm != null)
@@ -2113,18 +2101,15 @@ namespace OpenSim.Region.Framework.Scenes

                 m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts));

-
-                if(m_teleportFlags > 0)  //sanity check
-                    gotCrossUpdate = false;
+                if(m_teleportFlags > 0)
+                {
+                    gotCrossUpdate = false; // sanity check
+                    Thread.Sleep(500);  // let viewers catch us
+                }

                 if(!gotCrossUpdate)
                     RotateToLookAt(look);

-
-// start sending terrain patchs
-                if (!gotCrossUpdate && !isNPC)
-                    Scene.SendLayerData(ControllingClient);
-
                 // HG
                 bool isHGTP = (m_teleportFlags & TeleportFlags.ViaHGLogin) != 0;
                 if(isHGTP)
@@ -2133,6 +2118,12 @@ namespace OpenSim.Region.Framework.Scenes
                     m_log.DebugFormat("[CompleteMovement] HG");
                 }

+                if(!IsChildAgent && !isNPC)
+
+// start sending terrain patchs
+                if (!gotCrossUpdate && !isNPC)
+                    Scene.SendLayerData(ControllingClient);
+
                 m_previusParcelHide = false;
                 m_previusParcelUUID = UUID.Zero;
                 m_currentParcelHide = false;
@@ -2201,7 +2192,7 @@ namespace OpenSim.Region.Framework.Scenes
                             if (p == this)
                                 continue;

-                            if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
+                            if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodController.GodLevel < 200)
                                 continue;

                             SendAppearanceToAgentNF(p);
@@ -2251,7 +2242,7 @@ namespace OpenSim.Region.Framework.Scenes
                                     continue;
                                 }

-                                if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
+                                if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodController.GodLevel < 200)
                                     continue;

                                 SendAttachmentsToAgentNF(p);
@@ -3867,7 +3858,7 @@ namespace OpenSim.Region.Framework.Scenes
             if (!remoteClient.IsActive)
                 return;

-            if (ParcelHideThisAvatar && p.currentParcelUUID != currentParcelUUID && p.GodLevel < 200)
+            if (ParcelHideThisAvatar && p.currentParcelUUID != currentParcelUUID && p.GodController.GodLevel < 200)
                 return;

             //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity);
@@ -3977,7 +3968,7 @@ namespace OpenSim.Region.Framework.Scenes
                 // get the avatar, then a kill if can't see it
                 p.SendInitialAvatarDataToAgent(this);

-                if (p.ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && GodLevel < 200)
+                if (p.ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && GodController.GodLevel < 200)
                     return;

                 p.SendAppearanceToAgentNF(this);
@@ -4025,7 +4016,7 @@ namespace OpenSim.Region.Framework.Scenes
             foreach (ScenePresence p in presences)
             {
                 p.ControllingClient.SendAvatarDataImmediate(this);
-                if (p != this && ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
+                if (p != this && ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodController.GodLevel < 200)
                     // either just kill the object
                     // p.ControllingClient.SendKillObject(new List<uint> {LocalId});
                     // or also attachments viewer may still know about
@@ -4038,7 +4029,7 @@ namespace OpenSim.Region.Framework.Scenes
         public void SendInitialAvatarDataToAgent(ScenePresence p)
         {
             p.ControllingClient.SendAvatarDataImmediate(this);
-            if (p != this && ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
+            if (p != this && ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodController.GodLevel < 200)
                     // either just kill the object
                     // p.ControllingClient.SendKillObject(new List<uint> {LocalId});
                     // or also attachments viewer may still know about
@@ -4052,7 +4043,7 @@ namespace OpenSim.Region.Framework.Scenes
         public void SendAvatarDataToAgent(ScenePresence avatar)
         {
             //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAgent from {0} ({1}) to {2} ({3})", Name, UUID, avatar.Name, avatar.UUID);
-            if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID && avatar.GodLevel < 200)
+            if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID && avatar.GodController.GodLevel < 200)
                 return;
             avatar.ControllingClient.SendAvatarDataImmediate(this);
         }
@@ -4097,7 +4088,7 @@ namespace OpenSim.Region.Framework.Scenes
         {
             //            m_log.DebugFormat(
             //                "[SCENE PRESENCE]: Sending appearance data from {0} {1} to {2} {3}", Name, m_uuid, avatar.Name, avatar.UUID);
-            if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID && avatar.GodLevel < 200)
+            if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID && avatar.GodController.GodLevel < 200)
                 return;
             SendAppearanceToAgentNF(avatar);
         }
@@ -4113,7 +4104,7 @@ namespace OpenSim.Region.Framework.Scenes
             if (IsChildAgent || Animator == null)
                 return;

-            if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
+            if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodController.GodLevel < 200)
                 return;

             Animator.SendAnimPackToClient(p.ControllingClient);
@@ -4124,7 +4115,7 @@ namespace OpenSim.Region.Framework.Scenes
             if (IsChildAgent)
                 return;

-            if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
+            if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodController.GodLevel < 200)
                 return;

             p.ControllingClient.SendAnimations(animations, seqs, ControllingClient.AgentId, objectIDs);
@@ -4149,7 +4140,7 @@ namespace OpenSim.Region.Framework.Scenes

             m_scene.ForEachScenePresence(delegate(ScenePresence p)
             {
-                if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
+                if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodController.GodLevel < 200)
                     return;
                 p.ControllingClient.SendAnimations(animations, seqs, ControllingClient.AgentId, objectIDs);
             });
@@ -4262,6 +4253,7 @@ namespace OpenSim.Region.Framework.Scenes
                         agentpos.Position = AbsolutePosition;
                         agentpos.Velocity = Velocity;
                         agentpos.RegionHandle = RegionHandle;
+                        agentpos.GodData = GodController.State();
                         agentpos.Throttles = ControllingClient.GetThrottlesPacked(1);

                         // Let's get this out of the update loop
@@ -4510,20 +4502,12 @@ namespace OpenSim.Region.Framework.Scenes
         /// </summary>
         public void GrantGodlikePowers(UUID token, bool godStatus)
         {
-            int oldgodlevel = GodLevel;
-
-            if (godStatus && !isNPC && m_scene.Permissions.IsGod(UUID))
-            {
-                GodLevel = 200;
-                if(GodLevel < UserLevel)
-                    GodLevel = UserLevel;
-            }
-            else
-                GodLevel = 0;
+            if (isNPC)
+                return;

-            ControllingClient.SendAdminResponse(token, (uint)GodLevel);
-            if(oldgodlevel != GodLevel)
-                parcelGodCheck(m_currentParcelUUID, GodLevel >= 200);
+            bool success = GodController.RequestGodMode(godStatus);
+            if (success && godStatus)
+                parcelGodCheck(m_currentParcelUUID, GodController.GodLevel >= 200);
         }

         #region Child Agent Updates
@@ -4554,6 +4538,8 @@ namespace OpenSim.Region.Framework.Scenes
             if (!IsChildAgent)
                 return;

+            GodController.SetState(cAgentData.GodData);
+
             RegionHandle = cAgentData.RegionHandle;

             //m_log.Debug("   >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY);
@@ -4628,11 +4614,6 @@ namespace OpenSim.Region.Framework.Scenes
             cAgent.BodyRotation = Rotation;
             cAgent.ControlFlags = (uint)m_AgentControlFlags;

-            if (GodLevel > 200 && m_scene.Permissions.IsGod(cAgent.AgentID))
-                cAgent.GodLevel = (byte)GodLevel;
-            else
-                cAgent.GodLevel = (byte) 0;
-
             cAgent.AlwaysRun = SetAlwaysRun;

             // make clear we want the all thing
@@ -4693,6 +4674,8 @@ namespace OpenSim.Region.Framework.Scenes
 //                "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()",
 //                Name, m_scene.RegionInfo.RegionName, m_callbackURI);

+            GodController.SetState(cAgent.GodData);
+
             m_pos = cAgent.Position;
             m_velocity = cAgent.Velocity;
             CameraPosition = cAgent.Center;
@@ -4729,11 +4712,6 @@ namespace OpenSim.Region.Framework.Scenes
             Rotation = cAgent.BodyRotation;
             m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags;

-            if (cAgent.GodLevel >200 && m_scene.Permissions.IsGod(cAgent.AgentID))
-                GodLevel = cAgent.GodLevel;
-            else
-                GodLevel = 0;
-
             SetAlwaysRun = cAgent.AlwaysRun;

             Appearance = new AvatarAppearance(cAgent.Appearance);
@@ -4963,7 +4941,7 @@ namespace OpenSim.Region.Framework.Scenes
             RaiseCollisionScriptEvents(coldata);

             // Gods do not take damage and Invulnerable is set depending on parcel/region flags
-            if (Invulnerable || GodLevel > 0)
+            if (Invulnerable || GodController.GodLevel > 0)
                 return;

             // The following may be better in the ICombatModule
@@ -5248,7 +5226,7 @@ namespace OpenSim.Region.Framework.Scenes
                         if (p != this && sog.HasPrivateAttachmentPoint)
                             return;

-                        if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
+                        if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodController.GodLevel < 200)
                             return;

                         SendTerseUpdateToAgentNF(p);
@@ -5362,7 +5340,7 @@ namespace OpenSim.Region.Framework.Scenes
                 if (p == this)
                     continue;

-                if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
+                if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodController.GodLevel < 200)
                     continue;

                 p.ControllingClient.SendEntityUpdate(rootpart, rootflag);
@@ -5421,7 +5399,7 @@ namespace OpenSim.Region.Framework.Scenes
                 if (p == this)
                     continue;

-                if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
+                if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodController.GodLevel < 200)
                     continue;

                 p.ControllingClient.SendEntityUpdate(rootpart, flag);
@@ -5471,7 +5449,7 @@ namespace OpenSim.Region.Framework.Scenes
                 if (p == this)
                     continue;

-                if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
+                if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodController.GodLevel < 200)
                     continue;

                 p.ControllingClient.SendEntityUpdate(part, flag);
@@ -5512,7 +5490,7 @@ namespace OpenSim.Region.Framework.Scenes
             {
                 if (p == this)
                     continue;
-                if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200)
+                if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodController.GodLevel < 200)
                     continue;

                 p.ControllingClient.SendEntityUpdate(part, flag);
@@ -6150,7 +6128,7 @@ namespace OpenSim.Region.Framework.Scenes
                     // the TP point. This behaviour mimics agni.
                     if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
                         land.LandData.UserLocation != Vector3.Zero &&
-                        GodLevel < 200 &&
+                        GodController.GodLevel < 200 &&
                         ((land.LandData.OwnerID != m_uuid &&
                           !m_scene.Permissions.IsGod(m_uuid) &&
                           !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) ||
@@ -6175,7 +6153,7 @@ namespace OpenSim.Region.Framework.Scenes
             string reason;

             // dont mess with gods
-            if(GodLevel >=  200 || m_scene.Permissions.IsGod(m_uuid))
+            if(GodController.GodLevel >=  200 || m_scene.Permissions.IsGod(m_uuid))
                 return true;

             // respect region owner and managers
@@ -6523,7 +6501,7 @@ namespace OpenSim.Region.Framework.Scenes
                             continue;

                         // those not on parcel dont see me
-                        if (currentParcelID != p.currentParcelUUID && p.GodLevel < 200)
+                        if (currentParcelID != p.currentParcelUUID && p.GodController.GodLevel < 200)
                         {
                             killsToSendto.Add(p); // they dont see me
                         }
@@ -6549,9 +6527,9 @@ namespace OpenSim.Region.Framework.Scenes
                             // only those on previus parcel need receive kills
                             if (previusParcelID == p.currentParcelUUID)
                             {
-                                if(p.GodLevel < 200)
+                                if(p.GodController.GodLevel < 200)
                                     killsToSendto.Add(p); // they dont see me
-                                if(GodLevel < 200)
+                                if(GodController.GodLevel < 200)
                                     killsToSendme.Add(p);  // i dont see them
                             }
                             // only those on new parcel need see
@@ -6573,7 +6551,7 @@ namespace OpenSim.Region.Framework.Scenes
                                 continue;

                             // those not on new parcel dont see me
-                            if (currentParcelID != p.currentParcelUUID && p.GodLevel < 200)
+                            if (currentParcelID != p.currentParcelUUID && p.GodController.GodLevel < 200)
                             {
                                 killsToSendto.Add(p); // they dont see me
                             }
@@ -6599,7 +6577,7 @@ namespace OpenSim.Region.Framework.Scenes
                             if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive)
                                 continue;
                             // only those old parcel need kills
-                            if (previusParcelID == p.currentParcelUUID && GodLevel < 200)
+                            if (previusParcelID == p.currentParcelUUID && GodController.GodLevel < 200)
                             {
                                 killsToSendme.Add(p);  // i dont see them
                             }
@@ -6662,7 +6640,7 @@ namespace OpenSim.Region.Framework.Scenes
                 if (Scene.AttachmentsModule != null)
                     Scene.AttachmentsModule.DeleteAttachmentsFromScene(this, true);

-                if (!ParcelHideThisAvatar || GodLevel >= 200)
+                if (!ParcelHideThisAvatar || GodController.GodLevel >= 200)
                     return;

                 List<ScenePresence> allpresences = m_scene.GetScenePresences();
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
index f0de7d4..d52a1d5 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
@@ -877,7 +877,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups

             if (avatar != null)
             {
-                if (avatar.UserLevel < m_levelGroupCreate)
+                if (avatar.GodController.UserLevel < m_levelGroupCreate)
                 {
                     remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have insufficient permissions to create a group.");
                     return UUID.Zero;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 8f9ff03..92d6808 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -4977,7 +4977,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
                 if (presence != null && presence.PresenceType != PresenceType.Npc)
                 {
                     // agent must not be a god
-                    if (presence.UserLevel >= 200) return;
+                    if (presence.GodController.UserLevel >= 200) return;

                     // agent must be over the owners land
                     if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
@@ -5029,7 +5029,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
                     else
                     {
                         // agent must not be a god
-                        if (presence.GodLevel >= 200) return;
+                        if (presence.GodController.GodLevel >= 200) return;

                         // agent must be over the owners land
                         ILandObject agentLand = World.LandChannel.GetLandObject(presence.AbsolutePosition);
@@ -5256,7 +5256,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
                     return;

                 // Pushee is in GodMode this pushing object isn't owned by them
-                if (avatar.GodLevel > 0 && m_host.OwnerID != targetID)
+                if (avatar.GodController.GodLevel > 0 && m_host.OwnerID != targetID)
                     return;

                 pusheeav = avatar;
@@ -6687,7 +6687,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
                 delegate (ScenePresence ssp)
                 {
                     // Gods are not listed in SL
-                    if (!ssp.IsDeleted && ssp.GodLevel == 0.0 && !ssp.IsChildAgent)
+                    if (!ssp.IsDeleted && ssp.GodController.GodLevel == 0.0 && !ssp.IsChildAgent)
                     {
                         if (!regionWide)
                         {
@@ -14484,91 +14484,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             return contacts.ToArray();
         }

-        private ContactResult? GroundIntersection2(Vector3 rayStart, Vector3 rayEnd)
-        {
-            // get work copies
-            float sx = rayStart.X;
-            float ex = rayEnd.X;
-            float sy = rayStart.Y;
-            float ey = rayEnd.Y;
-
-            float dx = ex - sx;
-            float dy = ey - sy;
-
-            // region size info
-            float rsx =  World.RegionInfo.RegionSizeX;
-
-            float tmp;
-
-            // region bounds
-            if(sx < 0)
-            {
-                if(ex < 0) // totally outside
-                    return null;
-                if(dx <= 0) // out and going away
-                    return null;
-                else if(ex >= rsx)
-                    ex = rsx - 0.001f;
-                tmp = -sx / dx;
-                sy += dy * dx;
-                sx = 0;
-            }
-            else if(sx >= rsx)
-            {
-                if(ex >= rsx)  // totally outside
-                    return null;
-                if(dx >= 0) // out and going away
-                    return null;
-                else if(ex < 0)
-                    ex = 0;
-                tmp = (rsx - sx) / dx;
-                sy += dy * dx;
-                sx = rsx - 0.001f;
-            }
-
-            float rsy =  World.RegionInfo.RegionSizeY;
-            if(sy < 0)
-            {
-                if(dy <= 0) // out and going away
-                    return null;
-                else if(ey >= rsy)
-                    ey = rsy - 0.001f;
-                tmp = -sy / dy;
-                sx += dy * dx;
-                sy = 0;
-            }
-            else if(sy >= rsy)
-            {
-                if(dy >= 0) // out and going away
-                    return null;
-                else if(ey < 0)
-                    ey = 0;
-                tmp = (rsy - sy) / dy;
-                sx += dy * dx;
-                sy = rsy - 0.001f;
-            }
-
-            if(sx < 0 || sx >= rsx)
-                return null;
-
-            float sz = rayStart.Z;
-            float ez = rayEnd.Z;
-            float dz = ez - sz;
-
-            float dist = dx * dx + dy * dy + dz * dz;
-            if(dist < 0.001)
-                return null;
-            dist = (float)Math.Sqrt(dist);
-            tmp = 1.0f / dist;
-            Vector3 rayn = new Vector3(dx * tmp, dy * tmp, dz * tmp);
-
-            ContactResult? result = null;
-
-
-
-            return result;
-        }
-
         private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
         {
             double[,] heightfield = World.Heightmap.GetDoubles();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
index cec595d..49e70bc 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
@@ -721,7 +721,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             {
                 ScenePresence sp = World.GetScenePresence(m_host.OwnerID);

-                if (sp == null || sp.GodLevel < 200)
+                if (sp == null || sp.GodController.GodLevel < 200)
                 {
                     LSShoutError("lsSetWindlightScene can only be used by estate managers or owners.");
                     return 0;
@@ -768,7 +768,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             {
                 ScenePresence sp = World.GetScenePresence(m_host.OwnerID);

-                if (sp == null || sp.GodLevel < 200)
+                if (sp == null || sp.GodController.GodLevel < 200)
                 {
                     LSShoutError("lsSetWindlightScene can only be used by estate managers or owners.");
                     return;
@@ -799,7 +799,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             {
                 ScenePresence sp = World.GetScenePresence(m_host.OwnerID);

-                if (sp == null || sp.GodLevel < 200)
+                if (sp == null || sp.GodController.GodLevel < 200)
                 {
                     LSShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners.");
                     return 0;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index d401ed8..c7e7f89 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -540,7 +540,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
                     }
                 }

-                if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0)
+                if (presence.IsDeleted || presence.IsChildAgent || presence.GodController.GodLevel > 0.0)
                     return;

                 // if the object the script is in is attached and the avatar is the owner
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini
index 0203300..616061d 100644
--- a/bin/OpenSimDefaults.ini
+++ b/bin/OpenSimDefaults.ini
@@ -487,6 +487,16 @@
     ; you really do not want this...
     ;parcel_owner_is_god = false

+    ; God mode should be turned on in the viewer whenever
+    ; the user has god rights somewhere. They may choose
+    ; to turn it off again, though.
+    automatic_gods = false
+
+    ; The user can execute any and all god functions, as
+    ; permitted by the viewer UI, without actually "godding
+    ; up". This is the default state in 0.8.2.
+    implicit_gods = true
+
     ; Control user types that are allowed to create new scripts
     ; Only enforced if serviceside_object_permissions is true
     ;
ViewGit