diff --git a/OpenSim/Addons/Groups/GroupsModule.cs b/OpenSim/Addons/Groups/GroupsModule.cs index 1e9f2b5297..aa5105ee83 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 0e5eaf218d..b9d64b15fd 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 8cb40e1f8e..58b7b00169 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 dba2872b31..316956b5fe 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 89fdf099b7..7d9f3b375f 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 53800bbf48..adf5c685cf 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 e5bf919e8e..9843f2e619 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 ac05a6ec4c..82154bcc9e 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 8d3c10d9e1..b7ae298626 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 c517a309c4..bd95ff09eb 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 6b1eb54620..d0e5d8668f 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 4ad500a8b7..1ce69276b4 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 63b8de0865..3a8d6b7738 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 returns = new List(); - 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 1a61771859..02d0e02988 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 0000000000..5763e0345e --- /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(config, + "allow_grid_gods", sections, false); + + // The owner of a region is a god in his region only. + m_regionOwnerIsGod = + Util.GetConfigVarFromSections(config, + "region_owner_is_god", sections, true); + + // Region managers are gods in the regions they manage. + m_regionManagerIsGod = + Util.GetConfigVarFromSections(config, + "region_manager_is_god", sections, false); + + // Parcel owners are gods in their own parcels only. + m_parcelOwnerIsGod = + Util.GetConfigVarFromSections(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(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(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 352bc05bf3..87c3049830 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 29e139bede..339f1b1c3b 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(); // 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 {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 {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 /// public void GrantGodlikePowers(UUID token, bool godStatus) { - int oldgodlevel = GodLevel; + if (isNPC) + return; - if (godStatus && !isNPC && m_scene.Permissions.IsGod(UUID)) - { - GodLevel = 200; - if(GodLevel < UserLevel) - GodLevel = UserLevel; - } - else - GodLevel = 0; - - 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 allpresences = m_scene.GetScenePresences(); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index f0de7d4de7..d52a1d53db 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 8f9ff034c2..92d6808f10 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 cec595d266..49e70bcd0b 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 d401ed8c6b..c7e7f89d4c 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 0203300154..616061d4a1 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 ;