From 85a9834ed84f33d3610499914fa3168a8eebce6d Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Sun, 10 Feb 2008 10:55:57 +0000 Subject: * A lot of ugly permissions updates. ** Created SendFullUpdateToAllClientsExcept(LLUUID) so that permission updates /appear/ to apply immediately ** Separated out the ObjectFlags and the Permission Flags. They're related but not the same ** Added a hack routine to add *back* the objectflags to the client flags because the client hates the way we're doing object permissions ** Updated the clientflags routine to properly tell the client when they can't edit admin objects (objects owned by the sim administrator) even when they're an estate manager(why? >.< argh!) ** Fixed a null sim administrator/estate manager/user from causing permissions to return false even when it should return true. ** Re-added ObjectModify hack to allow collaboration with the allow anyone to move checkbox until we get group permissions done. --- OpenSim/Region/Environment/PermissionManager.cs | 164 +++++++++++++++------ .../Region/Environment/Scenes/SceneObjectGroup.cs | 9 ++ .../Region/Environment/Scenes/SceneObjectPart.cs | 60 +++++++- 3 files changed, 182 insertions(+), 51 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Environment/PermissionManager.cs b/OpenSim/Region/Environment/PermissionManager.cs index 7cf89b0..5cd2b81 100644 --- a/OpenSim/Region/Environment/PermissionManager.cs +++ b/OpenSim/Region/Environment/PermissionManager.cs @@ -80,7 +80,13 @@ namespace OpenSim.Region.Environment return true; } - return m_scene.RegionInfo.MasterAvatarAssignedUUID == user; + // If there is no master avatar, return false + if (m_scene.RegionInfo.MasterAvatarAssignedUUID != null) + { + return m_scene.RegionInfo.MasterAvatarAssignedUUID == user; + } + + return false; } public virtual bool IsEstateManager(LLUUID user) @@ -89,13 +95,20 @@ namespace OpenSim.Region.Environment { return true; } - - LLUUID[] estatemanagers = m_scene.RegionInfo.EstateSettings.estateManagers; - for (int i = 0; i < estatemanagers.Length; i++) + if (user != null) { - if (estatemanagers[i] == user) - return true; + LLUUID[] estatemanagers = m_scene.RegionInfo.EstateSettings.estateManagers; + for (int i = 0; i < estatemanagers.Length; i++) + { + if (estatemanagers[i] == user) + return true; + } } + // The below is commented out because logically it happens anyway. It's left in for readability + //else + //{ + //return false; + //} return false; } @@ -153,6 +166,18 @@ namespace OpenSim.Region.Environment public virtual uint GenerateClientFlags(LLUUID user, LLUUID objID) { + + // Here's the way this works, + // ObjectFlags and Permission flags are two different enumerations + // ObjectFlags, however, tells the client to change what it will allow the user to do. + // So, that means that all of the permissions type ObjectFlags are /temporary/ and only + // supposed to be set when customizing the objectflags for the client. + + // These temporary objectflags get computed and added in this function based on the + // Permission mask that's appropriate! + // Outside of this method, they should never be added to objectflags! + // -teravus + if (!m_scene.Entities.ContainsKey(objID)) { return 0; @@ -170,10 +195,38 @@ namespace OpenSim.Region.Environment // the administrator object permissions to take effect. LLUUID objectOwner = task.OwnerID; - uint objectOwnerMask = task.RootPart.ObjectFlags; - objectOwnerMask = ApplyObjectModifyMasks(task.RootPart.OwnerMask, objectOwnerMask); + uint objflags = task.RootPart.ObjectFlags; + + + // Remove any of the objectFlags that are temporary. These will get added back if appropriate + // in the next bit of code + + objflags &= (uint)LLObject.ObjectFlags.ObjectCopy; // Tells client you can copy the object + objflags &= (uint)LLObject.ObjectFlags.ObjectModify; // tells client you can modify the object + objflags &= (uint)LLObject.ObjectFlags.ObjectMove; // tells client that you can move the object (only, no mod) + objflags &= (uint)LLObject.ObjectFlags.ObjectTransfer; // tells the client that you can /take/ the object if you don't own it + objflags &= (uint)LLObject.ObjectFlags.ObjectYouOwner; // Tells client that you're the owner of the object + objflags &= (uint)LLObject.ObjectFlags.ObjectYouOfficer; // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set + + + // Creating the three ObjectFlags options for this method to choose from. + bool tasklocked = task.GetLocked(); // more debug needed to apply this, so we're going to set this to false for now + tasklocked = false; - uint objectEveryoneMask = task.RootPart.ObjectFlags | task.RootPart.EveryoneMask; + uint objectOwnerMask = ApplyObjectModifyMasks(task.RootPart.OwnerMask, objflags, tasklocked); + objectOwnerMask = AddBackBrokenObjectProperties(task.RootPart, objectOwnerMask); + + objectOwnerMask |= (uint)LLObject.ObjectFlags.ObjectYouOwner; + + uint objectGroupMask = ApplyObjectModifyMasks(task.RootPart.GroupMask, objflags, tasklocked); + objectGroupMask = AddBackBrokenObjectProperties(task.RootPart,objectGroupMask); + + uint objectEveryoneMask = ApplyObjectModifyMasks(task.RootPart.EveryoneMask, objflags, tasklocked); + objectEveryoneMask = AddBackBrokenObjectProperties(task.RootPart,objectEveryoneMask); + + // Hack to allow collaboration until Groups and Group Permissions are implemented + if ((objectEveryoneMask & (uint)LLObject.ObjectFlags.ObjectMove) != 0) + objectEveryoneMask |= (uint)LLObject.ObjectFlags.ObjectModify; if (m_bypassPermissions) return objectOwnerMask; @@ -181,7 +234,6 @@ namespace OpenSim.Region.Environment // Object owners should be able to edit their own content if (user == objectOwner) { - objectOwnerMask |= (uint)LLObject.ObjectFlags.ObjectYouOwner; return objectOwnerMask; } @@ -189,58 +241,70 @@ namespace OpenSim.Region.Environment Land parcel = m_scene.LandManager.getLandObject(task.AbsolutePosition.X, task.AbsolutePosition.Y); if (parcel != null && parcel.landData.ownerID == user) return objectOwnerMask; - + + // Admin objects should not be editable by the above + if (IsAdministrator(objectOwner)) + return objectEveryoneMask; + // Estate users should be able to edit anything in the sim if (IsEstateManager(user)) return objectOwnerMask; - // Admin objects should not be editable by the above - if (IsAdministrator(taskOwner)) - return objectEveryoneMask; + // Admin should be able to edit anything in the sim (including admin objects) if (IsAdministrator(user)) return objectOwnerMask; - if (((objectEveryoneMask & PERM_MOVE) != 0) || ((objectEveryoneMask & PERM_COPY) != 0)) - { - if ((objectEveryoneMask & PERM_MOVE) != 0) - objectOwnerMask &= ~PERM_MOVE; - if ((objectEveryoneMask & PERM_COPY) != 0) - objectOwnerMask &= ~PERM_COPY; + return objectEveryoneMask; + } + private uint AddBackBrokenObjectProperties(SceneObjectPart task, uint objectmask) + { + if ((task.ObjectFlags & (uint)LLObject.ObjectFlags.Physics) != 0) + objectmask |= (uint)LLObject.ObjectFlags.Physics; - objectOwnerMask &= ~PERM_MODIFY; - objectOwnerMask &= ~PERM_TRANS; + if ((task.ObjectFlags & (uint)LLObject.ObjectFlags.Scripted) != 0) + objectmask |= (uint)LLObject.ObjectFlags.Scripted; - return objectOwnerMask; - } - return objectEveryoneMask; + if ((task.ObjectFlags & (uint)LLObject.ObjectFlags.TemporaryOnRez) != 0) + objectmask |= (uint)LLObject.ObjectFlags.TemporaryOnRez; + + if ((task.ObjectFlags & (uint)LLObject.ObjectFlags.Phantom) != 0) + objectmask |= (uint)LLObject.ObjectFlags.Phantom; + + return objectmask; } - private uint ApplyObjectModifyMasks(uint parentMask, uint objectOwnerMask) + private uint ApplyObjectModifyMasks(uint setPermissionMask, uint objectFlagsMask, bool locked) { - if ((parentMask & (uint)PermissionMask.Copy) != 0) + // We are adding the temporary objectflags to the object's objectflags based on the + // permission flag given. These change the F flags on the client. + if (!locked) { - objectOwnerMask |= (uint)LLObject.ObjectFlags.ObjectCopy; - } - if ((parentMask & (uint)PermissionMask.Move) != 0) - { - objectOwnerMask |= (uint)LLObject.ObjectFlags.ObjectMove; - } + if ((setPermissionMask & (uint)PermissionMask.Copy) != 0) + { + objectFlagsMask |= (uint)LLObject.ObjectFlags.ObjectCopy; + } - if ((parentMask & (uint)PermissionMask.Modify) != 0) - { - objectOwnerMask |= (uint)LLObject.ObjectFlags.ObjectModify; - } + if ((setPermissionMask & (uint)PermissionMask.Move) != 0) + { + objectFlagsMask |= (uint)LLObject.ObjectFlags.ObjectMove; + } - if ((parentMask & (uint)PermissionMask.Transfer) != 0) - { - objectOwnerMask |= (uint)LLObject.ObjectFlags.ObjectTransfer; + if ((setPermissionMask & (uint)PermissionMask.Modify) != 0) + { + objectFlagsMask |= (uint)LLObject.ObjectFlags.ObjectModify; + } + + if ((setPermissionMask & (uint)PermissionMask.Transfer) != 0) + { + objectFlagsMask |= (uint)LLObject.ObjectFlags.ObjectTransfer; + } } - return objectOwnerMask; + return objectFlagsMask; } protected virtual bool GenericObjectPermission(LLUUID currentUser, LLUUID objId) @@ -254,13 +318,14 @@ namespace OpenSim.Region.Environment } // If it's not an object, we cant edit it. - if (!(m_scene.Entities[objId] is SceneObjectGroup)) + if ((!(m_scene.Entities[objId] is SceneObjectGroup))) { return false; } - SceneObjectGroup group = (SceneObjectGroup) m_scene.Entities[objId]; - + + SceneObjectGroup group = (SceneObjectGroup)m_scene.Entities[objId]; + LLUUID objectOwner = group.OwnerID; // Object owners should be able to edit their own content @@ -323,13 +388,20 @@ namespace OpenSim.Region.Environment return false; } + // The client + // may request to edit linked parts, and therefore, it needs + // to also check for SceneObjectPart + // If it's not an object, we cant edit it. - if (!(m_scene.Entities[obj] is SceneObjectGroup)) + if ((!(m_scene.Entities[obj] is SceneObjectGroup))) { return false; } - SceneObjectGroup task = (SceneObjectGroup) m_scene.Entities[obj]; + + SceneObjectGroup task = (SceneObjectGroup)m_scene.Entities[obj]; + + LLUUID taskOwner = null; // Added this because at this point in time it wouldn't be wise for // the administrator object permissions to take effect. diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs index c204389..a14d869 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs @@ -60,6 +60,7 @@ namespace OpenSim.Region.Environment.Scenes /// since the group's last persistent backup /// public bool HasGroupChanged = false; + private bool m_locked = false; private LLVector3 lastPhysGroupPos; private LLQuaternion lastPhysGroupRot; @@ -1217,7 +1218,15 @@ namespace OpenSim.Region.Environment.Scenes part.UpdateExtraParam(type, inUse, data); } } + public bool GetLocked() + { + return m_locked; + } + public void SetLocked(bool val) + { + m_locked = val; + } /// /// /// diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs index 0a9d21a..8c25dfa 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs @@ -44,7 +44,19 @@ namespace OpenSim.Region.Environment.Scenes { // I don't really know where to put this except here. // Can't access the OpenSim.Region.ScriptEngine.Common.LSL_BaseClass.Changed constants - + [Flags] + public enum ExtraParamType + { + Something1 = 1, + Something2 = 2, + Something3 = 4, + Something4 = 8, + Flexible = 16, + Light = 32, + Sculpt = 48, + Something5 = 64, + Something6 = 128 + } [Flags] public enum Changed : uint { @@ -1166,6 +1178,15 @@ namespace OpenSim.Region.Environment.Scenes public void UpdatePrimFlags(ushort type, bool inUse, byte[] data) { + + + //m_log.Info("TSomething1:" + ((type & (ushort)ExtraParamType.Something1) == (ushort)ExtraParamType.Something1)); + //m_log.Info("TSomething2:" + ((type & (ushort)ExtraParamType.Something2) == (ushort)ExtraParamType.Something2)); + //m_log.Info("TSomething3:" + ((type & (ushort)ExtraParamType.Something3) == (ushort)ExtraParamType.Something3)); + //m_log.Info("TSomething4:" + ((type & (ushort)ExtraParamType.Something4) == (ushort)ExtraParamType.Something4)); + //m_log.Info("TSomething5:" + ((type & (ushort)ExtraParamType.Something5) == (ushort)ExtraParamType.Something5)); + //m_log.Info("TSomething6:" + ((type & (ushort)ExtraParamType.Something6) == (ushort)ExtraParamType.Something6)); + bool usePhysics = false; bool IsTemporary = false; bool IsPhantom = false; @@ -1173,7 +1194,7 @@ namespace OpenSim.Region.Environment.Scenes bool wasUsingPhysics = ((ObjectFlags & (uint) LLObject.ObjectFlags.Physics) != 0); //bool IsLocked = false; int i = 0; - + try { @@ -1579,7 +1600,7 @@ namespace OpenSim.Region.Environment.Scenes //EveryoneMask |= (uint)57344; } //ScheduleFullUpdate(); - SendFullUpdateToAllClients(); + SendFullUpdateToAllClientsExcept(AgentID); } //Field 16 = NextownerMask if (field == (byte) 16) @@ -1592,11 +1613,28 @@ namespace OpenSim.Region.Environment.Scenes { NextOwnerMask |= mask; } + SendFullUpdateToAllClientsExcept(AgentID); + } + + if (field == (byte)2) + { + if (addRemTF == (byte)0) + { + m_parentGroup.SetLocked(true); + //OwnerMask &= ~mask; + } + else + { + m_parentGroup.SetLocked(false); + //OwnerMask |= mask; + } SendFullUpdateToAllClients(); + } + } } - + #region Client Update Methods public void AddFullUpdateToAllAvatars() @@ -1607,7 +1645,19 @@ namespace OpenSim.Region.Environment.Scenes avatars[i].QueuePartForUpdate(this); } } - + public void SendFullUpdateToAllClientsExcept(LLUUID agentID) + { + List avatars = m_parentGroup.GetScenePresences(); + for (int i = 0; i < avatars.Count; i++) + { + // Ugly reference :( + if (avatars[i].UUID != agentID) + { + m_parentGroup.SendPartFullUpdate(avatars[i].ControllingClient, this, + avatars[i].GenerateClientFlags(UUID)); + } + } + } public void AddFullUpdateToAvatar(ScenePresence presence) { presence.QueuePartForUpdate(this); -- cgit v1.1