* Fix mantis 345 - it is now possible to duplicate prims directly in the region again without breakage

* This includes their inventories
* Also, this revision properly synchronizes prim inventory crud.
ThreadPoolClientBranch
Justin Clarke Casey 2008-01-16 20:27:12 +00:00
parent c3061717d0
commit b33da2538e
5 changed files with 179 additions and 112 deletions

View File

@ -36,7 +36,13 @@ using System;
namespace OpenSim.Framework
{
public class TaskInventoryDictionary : Dictionary<LLUUID, TaskInventoryItem>, IXmlSerializable
/// <summary>
/// A dictionary for task inventory.
///
/// This class is not thread safe. Callers must synchronize on Dictionary methods.
/// </summary>
public class TaskInventoryDictionary : Dictionary<LLUUID, TaskInventoryItem>,
ICloneable, IXmlSerializable
{
private static XmlSerializer tiiSerializer = new XmlSerializer(typeof(TaskInventoryItem));
@ -85,20 +91,39 @@ namespace OpenSim.Framework
// see IXmlSerializable
public void WriteXml(XmlWriter writer)
{
lock (this)
{
foreach (TaskInventoryItem item in Values)
{
tiiSerializer.Serialize(writer, item);
}
}
//tiiSerializer.Serialize(writer, Values);
}
// see ICloneable
public Object Clone()
{
TaskInventoryDictionary clone = new TaskInventoryDictionary();
lock (this)
{
foreach (LLUUID uuid in Keys)
{
clone.Add(uuid, (TaskInventoryItem)this[uuid].Clone());
}
}
return clone;
}
}
/// <summary>
/// Represents an item in a task inventory
/// </summary>
public class TaskInventoryItem
public class TaskInventoryItem : ICloneable
{
/// <summary>
/// XXX This should really be factored out into some constants class.
@ -143,16 +168,6 @@ namespace OpenSim.Framework
String.Empty
};
/// <summary>
/// Reset the LLUUIDs for this item.
/// </summary>
/// <param name="partID">The new part ID to which this item belongs</param>
public void ResetIDs(LLUUID partID)
{
ItemID = LLUUID.Random();
ParentPartID = partID;
}
public LLUUID ItemID = LLUUID.Zero;
public LLUUID ParentID = LLUUID.Zero; //parent folder id
@ -175,5 +190,21 @@ namespace OpenSim.Framework
public uint CreationDate = 0;
public LLUUID ParentPartID = LLUUID.Zero;
/// <summary>
/// Reset the LLUUIDs for this item.
/// </summary>
/// <param name="partID">The new part ID to which this item belongs</param>
public void ResetIDs(LLUUID partID)
{
ItemID = LLUUID.Random();
ParentPartID = partID;
}
// See ICloneable
public Object Clone()
{
return MemberwiseClone();
}
}
}

View File

@ -928,17 +928,22 @@ namespace OpenSim.Region.Environment.Scenes
{
SceneObjectGroup copy = originPrim.Copy(AgentID, GroupID);
copy.AbsolutePosition = copy.AbsolutePosition + offset;
copy.ResetIDs();
lock (Entities)
{
Entities.Add(copy.UUID, copy);
}
m_numPrim++;
copy.StartScripts();
copy.ScheduleGroupForFullUpdate();
}
}
else
{
MainLog.Instance.Warn("client", "Attempted to duplicate nonexistant prim");
MainLog.Instance.Warn("SCENE", "Attempted to duplicate nonexistant prim id {0}", GroupID);
}
}

View File

@ -572,9 +572,8 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="part"></param>
public void CopyRootPart(SceneObjectPart part, LLUUID cAgentID, LLUUID cGroupID)
{
SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID);
SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count);
newPart.SetParent(this);
newPart.LinkNum = m_parts.Count;
m_parts.Add(newPart.UUID, newPart);
SetPartAsRoot(newPart);
}
@ -602,9 +601,8 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="part"></param>
public void CopyPart(SceneObjectPart part, LLUUID cAgentID, LLUUID cGroupID)
{
SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID);
SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count);
newPart.SetParent(this);
newPart.LinkNum = m_parts.Count;
m_parts.Add(newPart.UUID, newPart);
SetPartAsNonRoot(newPart);
}

View File

@ -87,6 +87,8 @@ namespace OpenSim.Region.Environment.Scenes
/// </summary>
/// <param name="linkNum'>Link number for the part</param>
public void ResetInventoryIDs()
{
lock (TaskInventory)
{
IList<TaskInventoryItem> items = new List<TaskInventoryItem>(TaskInventory.Values);
TaskInventory.Clear();
@ -97,11 +99,14 @@ namespace OpenSim.Region.Environment.Scenes
TaskInventory.Add(item.ItemID, item);
}
}
}
/// <summary>
/// Start all the scripts contained in this prim's inventory
/// </summary>
public void StartScripts()
{
lock (m_taskInventory)
{
foreach (TaskInventoryItem item in m_taskInventory.Values)
{
@ -112,6 +117,7 @@ namespace OpenSim.Region.Environment.Scenes
}
}
}
}
/// <summary>
/// Start a script which is in this prim's inventory.
@ -148,6 +154,8 @@ namespace OpenSim.Region.Environment.Scenes
/// A <see cref="LLUUID"/>
/// </param>
public void StartScript(LLUUID itemId)
{
lock (m_taskInventory)
{
if (m_taskInventory.ContainsKey(itemId))
{
@ -160,7 +168,7 @@ namespace OpenSim.Region.Environment.Scenes
"Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}",
itemId, Name, UUID);
}
}
}
/// <summary>
@ -191,7 +199,12 @@ namespace OpenSim.Region.Environment.Scenes
item.ParentID = m_folderID;
item.CreationDate = 1000;
item.ParentPartID = UUID;
lock (m_taskInventory)
{
m_taskInventory.Add(item.ItemID, item);
}
m_inventorySerial++;
}
@ -201,11 +214,14 @@ namespace OpenSim.Region.Environment.Scenes
/// </summary>
/// <param name="items"></param>
public void AddInventoryItems(ICollection<TaskInventoryItem> items)
{
lock (m_taskInventory)
{
foreach (TaskInventoryItem item in items)
{
m_taskInventory.Add(item.ItemID, item);
}
}
m_inventorySerial++;
}
@ -216,6 +232,8 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="itemID"></param>
/// <returns>null if the item does not exist</returns>
public TaskInventoryItem GetInventoryItem(LLUUID itemID)
{
lock (m_taskInventory)
{
if (m_taskInventory.ContainsKey(itemID))
{
@ -228,6 +246,7 @@ namespace OpenSim.Region.Environment.Scenes
"Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
itemID, Name, UUID);
}
}
return null;
}
@ -239,6 +258,8 @@ namespace OpenSim.Region.Environment.Scenes
/// in this prim's inventory.</param>
/// <returns>false if the item did not exist, true if the update occurred succesfully</returns>
public bool UpdateInventoryItem(TaskInventoryItem item)
{
lock (m_taskInventory)
{
if (m_taskInventory.ContainsKey(item.ItemID))
{
@ -254,6 +275,7 @@ namespace OpenSim.Region.Environment.Scenes
"Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
item.ItemID, Name, UUID);
}
}
return false;
}
@ -265,6 +287,8 @@ namespace OpenSim.Region.Environment.Scenes
/// <returns>Numeric asset type of the item removed. Returns -1 if the item did not exist
/// in this prim's inventory.</returns>
public int RemoveInventoryItem(LLUUID itemID)
{
lock (m_taskInventory)
{
if (m_taskInventory.ContainsKey(itemID))
{
@ -281,6 +305,7 @@ namespace OpenSim.Region.Environment.Scenes
"Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
itemID, Name, UUID);
}
}
return -1;
}
@ -309,6 +334,9 @@ namespace OpenSim.Region.Environment.Scenes
{
byte[] fileData = new byte[0];
InventoryStringBuilder invString = new InventoryStringBuilder(m_folderID, UUID);
lock (m_taskInventory)
{
foreach (TaskInventoryItem item in m_taskInventory.Values)
{
invString.AddItemStart();
@ -336,6 +364,7 @@ namespace OpenSim.Region.Environment.Scenes
invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
invString.AddSectionEnd();
}
}
fileData = Helpers.StringToField(invString.BuildString);

View File

@ -952,10 +952,10 @@ namespace OpenSim.Region.Environment.Scenes
#region Copying
/// <summary>
///
/// Duplicates this part.
/// </summary>
/// <returns></returns>
public SceneObjectPart Copy(uint localID, LLUUID AgentID, LLUUID GroupID)
public SceneObjectPart Copy(uint localID, LLUUID AgentID, LLUUID GroupID, int linkNum)
{
SceneObjectPart dupe = (SceneObjectPart) MemberwiseClone();
dupe.m_shape = m_shape.Copy();
@ -978,6 +978,10 @@ namespace OpenSim.Region.Environment.Scenes
dupe.SalePrice = SalePrice;
dupe.Category = Category;
dupe.TaskInventory = (TaskInventoryDictionary)dupe.TaskInventory.Clone();
dupe.ResetIDs(linkNum);
// This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
dupe.LastOwnerID = ObjectOwner;