* 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
parent
c3061717d0
commit
b33da2538e
|
@ -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));
|
||||
|
||||
|
@ -86,19 +92,38 @@ namespace OpenSim.Framework
|
|||
// see IXmlSerializable
|
||||
public void WriteXml(XmlWriter writer)
|
||||
{
|
||||
foreach (TaskInventoryItem item in Values)
|
||||
lock (this)
|
||||
{
|
||||
tiiSerializer.Serialize(writer, item);
|
||||
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.
|
||||
|
@ -141,17 +166,7 @@ namespace OpenSim.Framework
|
|||
String.Empty,
|
||||
"lsltext",
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -88,13 +88,16 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
/// <param name="linkNum'>Link number for the part</param>
|
||||
public void ResetInventoryIDs()
|
||||
{
|
||||
IList<TaskInventoryItem> items = new List<TaskInventoryItem>(TaskInventory.Values);
|
||||
TaskInventory.Clear();
|
||||
|
||||
foreach (TaskInventoryItem item in items)
|
||||
{
|
||||
item.ResetIDs(UUID);
|
||||
TaskInventory.Add(item.ItemID, item);
|
||||
lock (TaskInventory)
|
||||
{
|
||||
IList<TaskInventoryItem> items = new List<TaskInventoryItem>(TaskInventory.Values);
|
||||
TaskInventory.Clear();
|
||||
|
||||
foreach (TaskInventoryItem item in items)
|
||||
{
|
||||
item.ResetIDs(UUID);
|
||||
TaskInventory.Add(item.ItemID, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,12 +106,15 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
/// </summary>
|
||||
public void StartScripts()
|
||||
{
|
||||
foreach (TaskInventoryItem item in m_taskInventory.Values)
|
||||
lock (m_taskInventory)
|
||||
{
|
||||
// XXX more hardcoding badness. Should be an enum in TaskInventoryItem
|
||||
if (10 == item.Type)
|
||||
foreach (TaskInventoryItem item in m_taskInventory.Values)
|
||||
{
|
||||
StartScript(item);
|
||||
// XXX more hardcoding badness. Should be an enum in TaskInventoryItem
|
||||
if (10 == item.Type)
|
||||
{
|
||||
StartScript(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -149,18 +155,20 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
/// </param>
|
||||
public void StartScript(LLUUID itemId)
|
||||
{
|
||||
if (m_taskInventory.ContainsKey(itemId))
|
||||
{
|
||||
StartScript(m_taskInventory[itemId]);
|
||||
}
|
||||
else
|
||||
{
|
||||
MainLog.Instance.Error(
|
||||
"PRIMINVENTORY",
|
||||
"Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}",
|
||||
itemId, Name, UUID);
|
||||
}
|
||||
|
||||
lock (m_taskInventory)
|
||||
{
|
||||
if (m_taskInventory.ContainsKey(itemId))
|
||||
{
|
||||
StartScript(m_taskInventory[itemId]);
|
||||
}
|
||||
else
|
||||
{
|
||||
MainLog.Instance.Error(
|
||||
"PRIMINVENTORY",
|
||||
"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;
|
||||
m_taskInventory.Add(item.ItemID, item);
|
||||
|
||||
lock (m_taskInventory)
|
||||
{
|
||||
m_taskInventory.Add(item.ItemID, item);
|
||||
}
|
||||
|
||||
m_inventorySerial++;
|
||||
}
|
||||
|
||||
|
@ -202,9 +215,12 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
/// <param name="items"></param>
|
||||
public void AddInventoryItems(ICollection<TaskInventoryItem> items)
|
||||
{
|
||||
foreach (TaskInventoryItem item in items)
|
||||
{
|
||||
m_taskInventory.Add(item.ItemID, item);
|
||||
lock (m_taskInventory)
|
||||
{
|
||||
foreach (TaskInventoryItem item in items)
|
||||
{
|
||||
m_taskInventory.Add(item.ItemID, item);
|
||||
}
|
||||
}
|
||||
|
||||
m_inventorySerial++;
|
||||
|
@ -217,16 +233,19 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
/// <returns>null if the item does not exist</returns>
|
||||
public TaskInventoryItem GetInventoryItem(LLUUID itemID)
|
||||
{
|
||||
if (m_taskInventory.ContainsKey(itemID))
|
||||
{
|
||||
return m_taskInventory[itemID];
|
||||
}
|
||||
else
|
||||
{
|
||||
MainLog.Instance.Error(
|
||||
"PRIMINVENTORY",
|
||||
"Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
|
||||
itemID, Name, UUID);
|
||||
lock (m_taskInventory)
|
||||
{
|
||||
if (m_taskInventory.ContainsKey(itemID))
|
||||
{
|
||||
return m_taskInventory[itemID];
|
||||
}
|
||||
else
|
||||
{
|
||||
MainLog.Instance.Error(
|
||||
"PRIMINVENTORY",
|
||||
"Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
|
||||
itemID, Name, UUID);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -240,20 +259,23 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
/// <returns>false if the item did not exist, true if the update occurred succesfully</returns>
|
||||
public bool UpdateInventoryItem(TaskInventoryItem item)
|
||||
{
|
||||
if (m_taskInventory.ContainsKey(item.ItemID))
|
||||
{
|
||||
m_taskInventory[item.ItemID] = item;
|
||||
m_inventorySerial++;
|
||||
|
||||
return true;
|
||||
lock (m_taskInventory)
|
||||
{
|
||||
if (m_taskInventory.ContainsKey(item.ItemID))
|
||||
{
|
||||
m_taskInventory[item.ItemID] = item;
|
||||
m_inventorySerial++;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
MainLog.Instance.Error(
|
||||
"PRIMINVENTORY",
|
||||
"Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
|
||||
item.ItemID, Name, UUID);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MainLog.Instance.Error(
|
||||
"PRIMINVENTORY",
|
||||
"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;
|
||||
}
|
||||
|
@ -266,21 +288,24 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
/// in this prim's inventory.</returns>
|
||||
public int RemoveInventoryItem(LLUUID itemID)
|
||||
{
|
||||
if (m_taskInventory.ContainsKey(itemID))
|
||||
{
|
||||
int type = m_taskInventory[itemID].InvType;
|
||||
m_taskInventory.Remove(itemID);
|
||||
m_inventorySerial++;
|
||||
|
||||
return type;
|
||||
lock (m_taskInventory)
|
||||
{
|
||||
if (m_taskInventory.ContainsKey(itemID))
|
||||
{
|
||||
int type = m_taskInventory[itemID].InvType;
|
||||
m_taskInventory.Remove(itemID);
|
||||
m_inventorySerial++;
|
||||
|
||||
return type;
|
||||
}
|
||||
else
|
||||
{
|
||||
MainLog.Instance.Error(
|
||||
"PRIMINVENTORY",
|
||||
"Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
|
||||
itemID, Name, UUID);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MainLog.Instance.Error(
|
||||
"PRIMINVENTORY",
|
||||
"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,32 +334,36 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
{
|
||||
byte[] fileData = new byte[0];
|
||||
InventoryStringBuilder invString = new InventoryStringBuilder(m_folderID, UUID);
|
||||
foreach (TaskInventoryItem item in m_taskInventory.Values)
|
||||
{
|
||||
invString.AddItemStart();
|
||||
invString.AddNameValueLine("item_id", item.ItemID.ToString());
|
||||
invString.AddNameValueLine("parent_id", item.ParentID.ToString());
|
||||
|
||||
invString.AddPermissionsStart();
|
||||
invString.AddNameValueLine("base_mask", "0x7FFFFFFF");
|
||||
invString.AddNameValueLine("owner_mask", "0x7FFFFFFF");
|
||||
invString.AddNameValueLine("group_mask", "0x7FFFFFFF");
|
||||
invString.AddNameValueLine("everyone_mask", "0x7FFFFFFF");
|
||||
invString.AddNameValueLine("next_owner_mask", "0x7FFFFFFF");
|
||||
invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
|
||||
invString.AddNameValueLine("owner_id", item.OwnerID.ToString());
|
||||
invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
|
||||
invString.AddNameValueLine("group_id", item.GroupID.ToString());
|
||||
invString.AddSectionEnd();
|
||||
|
||||
invString.AddNameValueLine("asset_id", item.AssetID.ToString());
|
||||
invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
|
||||
invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
|
||||
invString.AddNameValueLine("flags", "0x00");
|
||||
invString.AddNameValueLine("name", item.Name + "|");
|
||||
invString.AddNameValueLine("desc", item.Description + "|");
|
||||
invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
|
||||
invString.AddSectionEnd();
|
||||
|
||||
lock (m_taskInventory)
|
||||
{
|
||||
foreach (TaskInventoryItem item in m_taskInventory.Values)
|
||||
{
|
||||
invString.AddItemStart();
|
||||
invString.AddNameValueLine("item_id", item.ItemID.ToString());
|
||||
invString.AddNameValueLine("parent_id", item.ParentID.ToString());
|
||||
|
||||
invString.AddPermissionsStart();
|
||||
invString.AddNameValueLine("base_mask", "0x7FFFFFFF");
|
||||
invString.AddNameValueLine("owner_mask", "0x7FFFFFFF");
|
||||
invString.AddNameValueLine("group_mask", "0x7FFFFFFF");
|
||||
invString.AddNameValueLine("everyone_mask", "0x7FFFFFFF");
|
||||
invString.AddNameValueLine("next_owner_mask", "0x7FFFFFFF");
|
||||
invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
|
||||
invString.AddNameValueLine("owner_id", item.OwnerID.ToString());
|
||||
invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
|
||||
invString.AddNameValueLine("group_id", item.GroupID.ToString());
|
||||
invString.AddSectionEnd();
|
||||
|
||||
invString.AddNameValueLine("asset_id", item.AssetID.ToString());
|
||||
invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
|
||||
invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
|
||||
invString.AddNameValueLine("flags", "0x00");
|
||||
invString.AddNameValueLine("name", item.Name + "|");
|
||||
invString.AddNameValueLine("desc", item.Description + "|");
|
||||
invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
|
||||
invString.AddSectionEnd();
|
||||
}
|
||||
}
|
||||
|
||||
fileData = Helpers.StringToField(invString.BuildString);
|
||||
|
|
|
@ -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();
|
||||
|
@ -977,6 +977,10 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
dupe.ObjectSaleType = ObjectSaleType;
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue