Refactored setting permissions when rezzing items: use the same function when rezzing from user inventory and prim inventory.

Also, fixed a bug: when rezzing a coalesced object from a prim's inventory, apply the coalesced object's name and description only to the first sub-object; not to all the objects in the coalescence. (This was already done correctly when rezzing from a user's inventory.)
master-beforevarregion
Oren Hurvitz 2013-11-04 19:28:24 +02:00 committed by Justin Clark-Casey (justincc)
parent 0155d42b80
commit 13f31fdf85
5 changed files with 159 additions and 93 deletions

View File

@ -0,0 +1,68 @@
/*
* 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.Collections.Generic;
using System.Reflection;
using System.Text;
using log4net;
namespace OpenSim.Framework
{
public static class PermissionsUtil
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Logs permissions flags. Useful when debugging permission problems.
/// </summary>
/// <param name="message"></param>
public static void LogPermissions(String name, String message, uint basePerm, uint curPerm, uint nextPerm)
{
m_log.DebugFormat("Permissions of \"{0}\" at \"{1}\": Base {2} ({3:X4}), Current {4} ({5:X4}), NextOwner {6} ({7:X4})",
name, message,
PermissionsToString(basePerm), basePerm, PermissionsToString(curPerm), curPerm, PermissionsToString(nextPerm), nextPerm);
}
/// <summary>
/// Converts a permissions bit-mask to a string (e.g., "MCT").
/// </summary>
private static string PermissionsToString(uint perms)
{
string str = "";
if ((perms & (int)PermissionMask.Modify) != 0)
str += "M";
if ((perms & (int)PermissionMask.Copy) != 0)
str += "C";
if ((perms & (int)PermissionMask.Transfer) != 0)
str += "T";
if (str == "")
str = ".";
return str;
}
}
}

View File

@ -512,10 +512,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
item.EveryOnePermissions = so.RootPart.EveryoneMask & so.RootPart.NextOwnerMask; item.EveryOnePermissions = so.RootPart.EveryoneMask & so.RootPart.NextOwnerMask;
item.GroupPermissions = so.RootPart.GroupMask & so.RootPart.NextOwnerMask; item.GroupPermissions = so.RootPart.GroupMask & so.RootPart.NextOwnerMask;
// Magic number badness. Maybe this deserves an enum. // apply next owner perms on rez
// bit 4 (16) is the "Slam" bit, it means treat as passed item.CurrentPermissions |= SceneObjectGroup.SLAM;
// and apply next owner perms on rez
item.CurrentPermissions |= 16; // Slam!
} }
else else
{ {
@ -809,11 +807,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint; group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint;
} }
foreach (SceneObjectPart part in group.Parts) if (item == null)
{ {
// Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset. // Change ownership. Normally this is done in DoPreRezWhenFromItem(), but in this case we must do it here.
part.LastOwnerID = part.OwnerID; foreach (SceneObjectPart part in group.Parts)
part.OwnerID = remoteClient.AgentId; {
// Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset.
part.LastOwnerID = part.OwnerID;
part.OwnerID = remoteClient.AgentId;
}
} }
if (!attachment) if (!attachment)
@ -969,44 +971,19 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
// "[INVENTORY ACCESS MODULE]: rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}", // "[INVENTORY ACCESS MODULE]: rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}",
// rootPart.OwnerID, item.Owner, item.CurrentPermissions); // rootPart.OwnerID, item.Owner, item.CurrentPermissions);
if ((rootPart.OwnerID != item.Owner) || if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & SceneObjectGroup.SLAM) != 0)
(item.CurrentPermissions & 16) != 0)
{ {
//Need to kill the for sale here //Need to kill the for sale here
rootPart.ObjectSaleType = 0; rootPart.ObjectSaleType = 0;
rootPart.SalePrice = 10; rootPart.SalePrice = 10;
if (m_Scene.Permissions.PropagatePermissions())
{
foreach (SceneObjectPart part in so.Parts)
{
if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
{
part.EveryoneMask = item.EveryOnePermissions;
part.NextOwnerMask = item.NextPermissions;
}
part.GroupMask = 0; // DO NOT propagate here
}
so.ApplyNextOwnerPermissions();
}
} }
foreach (SceneObjectPart part in so.Parts) foreach (SceneObjectPart part in so.Parts)
{ {
part.FromUserInventoryItemID = fromUserInventoryItemId; part.FromUserInventoryItemID = fromUserInventoryItemId;
part.ApplyPermissionsOnRez(item, true, m_Scene);
if ((part.OwnerID != item.Owner) ||
(item.CurrentPermissions & 16) != 0)
{
part.Inventory.ChangeInventoryOwner(item.Owner);
part.GroupMask = 0; // DO NOT propagate here
}
part.EveryoneMask = item.EveryOnePermissions;
part.NextOwnerMask = item.NextPermissions;
} }
rootPart.TrimPermissions(); rootPart.TrimPermissions();
if (isAttachment) if (isAttachment)

View File

@ -109,6 +109,9 @@ namespace OpenSim.Region.Framework.Scenes
STATUS_ROTATE_Z = 0x008, STATUS_ROTATE_Z = 0x008,
} }
// This flag has the same purpose as InventoryItemFlags.ObjectSlamPerm
public static readonly uint SLAM = 16;
// private PrimCountTaintedDelegate handlerPrimCountTainted = null; // private PrimCountTaintedDelegate handlerPrimCountTainted = null;
/// <summary> /// <summary>

View File

@ -4800,6 +4800,64 @@ namespace OpenSim.Region.Framework.Scenes
{ {
ParentGroup.AddScriptLPS(count); ParentGroup.AddScriptLPS(count);
} }
/// <summary>
/// Sets a prim's owner and permissions when it's rezzed.
/// </summary>
/// <param name="item">The inventory item from which the item was rezzed</param>
/// <param name="userInventory">True: the item is being rezzed from the user's inventory. False: from a prim's inventory.</param>
/// <param name="scene">The scene the prim is being rezzed into</param>
public void ApplyPermissionsOnRez(InventoryItemBase item, bool userInventory, Scene scene)
{
if ((OwnerID != item.Owner) || ((item.CurrentPermissions & SceneObjectGroup.SLAM) != 0) || ((item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0))
{
if (scene.Permissions.PropagatePermissions())
{
if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
{
// Apply the item's permissions to the object
//LogPermissions("Before applying item permissions");
if (userInventory)
{
EveryoneMask = item.EveryOnePermissions;
NextOwnerMask = item.NextPermissions;
}
else
{
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
EveryoneMask = item.EveryOnePermissions;
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
NextOwnerMask = item.NextPermissions;
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
GroupMask = item.GroupPermissions;
}
//LogPermissions("After applying item permissions");
}
}
GroupMask = 0; // DO NOT propagate here
}
if (OwnerID != item.Owner)
{
//LogPermissions("Before ApplyNextOwnerPermissions");
ApplyNextOwnerPermissions();
//LogPermissions("After ApplyNextOwnerPermissions");
LastOwnerID = OwnerID;
OwnerID = item.Owner;
Inventory.ChangeInventoryOwner(item.Owner);
}
}
/// <summary>
/// Logs the prim's permissions. Useful when debugging permission problems.
/// </summary>
/// <param name="message"></param>
private void LogPermissions(String message)
{
PermissionsUtil.LogPermissions(Name, message, BaseMask, OwnerMask, NextOwnerMask);
}
public void ApplyNextOwnerPermissions() public void ApplyNextOwnerPermissions()
{ {

View File

@ -764,48 +764,27 @@ namespace OpenSim.Region.Framework.Scenes
// Since renaming the item in the inventory does not affect the name stored // Since renaming the item in the inventory does not affect the name stored
// in the serialization, transfer the correct name from the inventory to the // in the serialization, transfer the correct name from the inventory to the
// object itself before we rez. // object itself before we rez.
rootPart.Name = item.Name; // Only do these for the first object if we are rezzing a coalescence.
rootPart.Description = item.Description; if (i == 0)
{
SceneObjectPart[] partList = group.Parts; rootPart.Name = item.Name;
rootPart.Description = item.Description;
}
group.SetGroup(m_part.GroupID, null); group.SetGroup(m_part.GroupID, null);
// TODO: Remove magic number badness foreach (SceneObjectPart part in group.Parts)
if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number
{ {
if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions()) // Convert between InventoryItem classes. You can never have too many similar but slightly different classes :)
{ InventoryItemBase dest = new InventoryItemBase(item.ItemID, item.OwnerID);
foreach (SceneObjectPart part in partList) dest.BasePermissions = item.BasePermissions;
{ dest.CurrentPermissions = item.CurrentPermissions;
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) dest.EveryOnePermissions = item.EveryonePermissions;
part.EveryoneMask = item.EveryonePermissions; dest.GroupPermissions = item.GroupPermissions;
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) dest.NextPermissions = item.NextPermissions;
part.NextOwnerMask = item.NextPermissions; dest.Flags = item.Flags;
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
part.GroupMask = item.GroupPermissions;
}
group.ApplyNextOwnerPermissions(); part.ApplyPermissionsOnRez(dest, false, m_part.ParentGroup.Scene);
}
}
foreach (SceneObjectPart part in partList)
{
// TODO: Remove magic number badness
if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number
{
part.LastOwnerID = part.OwnerID;
part.OwnerID = item.OwnerID;
part.Inventory.ChangeInventoryOwner(item.OwnerID);
}
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
part.EveryoneMask = item.EveryonePermissions;
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
part.NextOwnerMask = item.NextPermissions;
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
part.GroupMask = item.GroupPermissions;
} }
rootPart.TrimPermissions(); rootPart.TrimPermissions();
@ -1130,25 +1109,6 @@ namespace OpenSim.Region.Framework.Scenes
mask &= ~((uint)PermissionMask.Transfer >> 13); mask &= ~((uint)PermissionMask.Transfer >> 13);
if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
mask &= ~((uint)PermissionMask.Modify >> 13); mask &= ~((uint)PermissionMask.Modify >> 13);
if (item.InvType != (int)InventoryType.Object)
{
if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
mask &= ~((uint)PermissionMask.Copy >> 13);
if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
mask &= ~((uint)PermissionMask.Transfer >> 13);
if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
mask &= ~((uint)PermissionMask.Modify >> 13);
}
else
{
if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
mask &= ~((uint)PermissionMask.Copy >> 13);
if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
mask &= ~((uint)PermissionMask.Transfer >> 13);
if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
mask &= ~((uint)PermissionMask.Modify >> 13);
}
if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
mask &= ~(uint)PermissionMask.Copy; mask &= ~(uint)PermissionMask.Copy;