Implement taking of coalesced objects.
WARNING!!!!! You can TAKE them, but you can't REZ them again. Only the first of the contained objects will rez, the rest is inaccessible until rezzing them is implemented. Also, rotations are not explicitly stored. This MAY work. Or not.0.7.1-dev
parent
e8e940e33e
commit
b385d4aa03
|
@ -28,6 +28,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Xml;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
|
@ -205,11 +206,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID,
|
public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID,
|
||||||
List<SceneObjectGroup> objectGroups, IClientAPI remoteClient)
|
List<SceneObjectGroup> objectGroups, IClientAPI remoteClient)
|
||||||
{
|
{
|
||||||
// HACK: This is only working for lists containing a single item!
|
|
||||||
// It's just a hack to make this WIP compile and run. Nothing
|
|
||||||
// currently calls this with multiple items.
|
|
||||||
UUID ret = UUID.Zero;
|
UUID ret = UUID.Zero;
|
||||||
|
|
||||||
|
// The following code groups the SOG's by owner. No objects
|
||||||
|
// belonging to different people can be coalesced, for obvious
|
||||||
|
// reasons.
|
||||||
Dictionary<UUID, List<SceneObjectGroup>> deletes =
|
Dictionary<UUID, List<SceneObjectGroup>> deletes =
|
||||||
new Dictionary<UUID, List<SceneObjectGroup>>();
|
new Dictionary<UUID, List<SceneObjectGroup>>();
|
||||||
|
|
||||||
|
@ -221,20 +222,19 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
deletes[g.OwnerID].Add(g);
|
deletes[g.OwnerID].Add(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (List<SceneObjectGroup> objlist in deletes.Values)
|
// This is pethod scoped and will be returned. It will be the
|
||||||
{
|
// last created asset id
|
||||||
foreach (SceneObjectGroup g in objlist)
|
|
||||||
ret = DeleteToInventory(action, folderID, g, remoteClient);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
private UUID DeleteToInventory(DeRezAction action, UUID folderID,
|
|
||||||
SceneObjectGroup objectGroup, IClientAPI remoteClient)
|
|
||||||
{
|
|
||||||
UUID assetID = UUID.Zero;
|
UUID assetID = UUID.Zero;
|
||||||
|
|
||||||
|
// Each iteration is really a separate asset being created,
|
||||||
|
// with distinct destinations as well.
|
||||||
|
foreach (List<SceneObjectGroup> objlist in deletes.Values)
|
||||||
|
{
|
||||||
|
Dictionary<UUID, string> xmlStrings =
|
||||||
|
new Dictionary<UUID, string>();
|
||||||
|
|
||||||
|
foreach (SceneObjectGroup objectGroup in objlist)
|
||||||
|
{
|
||||||
Vector3 inventoryStoredPosition = new Vector3
|
Vector3 inventoryStoredPosition = new Vector3
|
||||||
(((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
|
(((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
|
||||||
? 250
|
? 250
|
||||||
|
@ -247,12 +247,77 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
|
|
||||||
Vector3 originalPosition = objectGroup.AbsolutePosition;
|
Vector3 originalPosition = objectGroup.AbsolutePosition;
|
||||||
|
|
||||||
|
// Restore attachment data after trip through the sim
|
||||||
|
if (objectGroup.RootPart.AttachPoint > 0)
|
||||||
|
inventoryStoredPosition = objectGroup.RootPart.AttachOffset;
|
||||||
|
objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint;
|
||||||
|
|
||||||
objectGroup.AbsolutePosition = inventoryStoredPosition;
|
objectGroup.AbsolutePosition = inventoryStoredPosition;
|
||||||
|
|
||||||
|
// Make sure all bits but the ones we want are clear
|
||||||
|
// on take.
|
||||||
|
// This will be applied to the current perms, so
|
||||||
|
// it will do what we want.
|
||||||
|
objectGroup.RootPart.NextOwnerMask &=
|
||||||
|
((uint)PermissionMask.Copy |
|
||||||
|
(uint)PermissionMask.Transfer |
|
||||||
|
(uint)PermissionMask.Modify);
|
||||||
|
objectGroup.RootPart.NextOwnerMask |=
|
||||||
|
(uint)PermissionMask.Move;
|
||||||
|
|
||||||
string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup);
|
string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup);
|
||||||
|
|
||||||
objectGroup.AbsolutePosition = originalPosition;
|
objectGroup.AbsolutePosition = originalPosition;
|
||||||
|
|
||||||
|
xmlStrings[objectGroup.UUID] = sceneObjectXml;
|
||||||
|
}
|
||||||
|
|
||||||
|
string itemXml;
|
||||||
|
|
||||||
|
if (objlist.Count > 1)
|
||||||
|
{
|
||||||
|
float minX, minY, minZ;
|
||||||
|
float maxX, maxY, maxZ;
|
||||||
|
|
||||||
|
Vector3[] offsets = m_Scene.GetCombinedBoundingBox(objlist,
|
||||||
|
out minX, out maxX, out minY, out maxY,
|
||||||
|
out minZ, out maxZ);
|
||||||
|
|
||||||
|
// CreateWrapper
|
||||||
|
XmlDocument itemDoc = new XmlDocument();
|
||||||
|
XmlElement root = itemDoc.CreateElement("", "CoalescedObject", "");
|
||||||
|
itemDoc.AppendChild(root);
|
||||||
|
|
||||||
|
// Embed the offsets into the group XML
|
||||||
|
for ( int i = 0 ; i < objlist.Count ; i++ )
|
||||||
|
{
|
||||||
|
XmlDocument doc = new XmlDocument();
|
||||||
|
SceneObjectGroup g = objlist[i];
|
||||||
|
doc.LoadXml(xmlStrings[g.UUID]);
|
||||||
|
XmlElement e = (XmlElement)doc.SelectSingleNode("/SceneObjectGroup");
|
||||||
|
e.SetAttribute("offsetx", offsets[i].X.ToString());
|
||||||
|
e.SetAttribute("offsety", offsets[i].Y.ToString());
|
||||||
|
e.SetAttribute("offsetz", offsets[i].Z.ToString());
|
||||||
|
|
||||||
|
XmlNode objectNode = itemDoc.ImportNode(e, true);
|
||||||
|
root.AppendChild(objectNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
float sizeX = maxX - minX;
|
||||||
|
float sizeY = maxY - minY;
|
||||||
|
float sizeZ = maxZ - minZ;
|
||||||
|
|
||||||
|
root.SetAttribute("x", sizeX.ToString());
|
||||||
|
root.SetAttribute("y", sizeY.ToString());
|
||||||
|
root.SetAttribute("z", sizeZ.ToString());
|
||||||
|
|
||||||
|
itemXml = itemDoc.InnerXml;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
itemXml = xmlStrings[objlist[0].UUID];
|
||||||
|
}
|
||||||
|
|
||||||
// Get the user info of the item destination
|
// Get the user info of the item destination
|
||||||
//
|
//
|
||||||
UUID userID = UUID.Zero;
|
UUID userID = UUID.Zero;
|
||||||
|
@ -273,7 +338,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
// All returns / deletes go to the object owner
|
// All returns / deletes go to the object owner
|
||||||
//
|
//
|
||||||
|
|
||||||
userID = objectGroup.RootPart.OwnerID;
|
userID = objlist[0].RootPart.OwnerID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userID == UUID.Zero) // Can't proceed
|
if (userID == UUID.Zero) // Can't proceed
|
||||||
|
@ -292,7 +357,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
|
|
||||||
if (DeRezAction.SaveToExistingUserInventoryItem == action)
|
if (DeRezAction.SaveToExistingUserInventoryItem == action)
|
||||||
{
|
{
|
||||||
item = new InventoryItemBase(objectGroup.RootPart.FromUserInventoryItemID, userID);
|
item = new InventoryItemBase(objlist[0].RootPart.FromUserInventoryItemID, userID);
|
||||||
item = m_Scene.InventoryService.GetItem(item);
|
item = m_Scene.InventoryService.GetItem(item);
|
||||||
|
|
||||||
//item = userInfo.RootFolder.FindItem(
|
//item = userInfo.RootFolder.FindItem(
|
||||||
|
@ -302,7 +367,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
{
|
{
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.",
|
"[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.",
|
||||||
objectGroup.Name, objectGroup.UUID);
|
objlist[0].Name, objlist[0].UUID);
|
||||||
return UUID.Zero;
|
return UUID.Zero;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -315,7 +380,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
// Deleting someone else's item
|
// Deleting someone else's item
|
||||||
//
|
//
|
||||||
if (remoteClient == null ||
|
if (remoteClient == null ||
|
||||||
objectGroup.OwnerID != remoteClient.AgentId)
|
objlist[0].OwnerID != remoteClient.AgentId)
|
||||||
{
|
{
|
||||||
|
|
||||||
folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
|
folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
|
||||||
|
@ -344,7 +409,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (remoteClient == null ||
|
if (remoteClient == null ||
|
||||||
objectGroup.OwnerID != remoteClient.AgentId)
|
objlist[0].OwnerID != remoteClient.AgentId)
|
||||||
{
|
{
|
||||||
// Taking copy of another person's item. Take to
|
// Taking copy of another person's item. Take to
|
||||||
// Objects folder.
|
// Objects folder.
|
||||||
|
@ -365,9 +430,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
//
|
//
|
||||||
if (action == DeRezAction.Take || action == DeRezAction.TakeCopy)
|
if (action == DeRezAction.Take || action == DeRezAction.TakeCopy)
|
||||||
{
|
{
|
||||||
if (objectGroup.RootPart.FromFolderID != UUID.Zero)
|
if (objlist[0].RootPart.FromFolderID != UUID.Zero)
|
||||||
{
|
{
|
||||||
InventoryFolderBase f = new InventoryFolderBase(objectGroup.RootPart.FromFolderID, userID);
|
InventoryFolderBase f = new InventoryFolderBase(objlist[0].RootPart.FromFolderID, userID);
|
||||||
folder = m_Scene.InventoryService.GetFolder(f);
|
folder = m_Scene.InventoryService.GetFolder(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -383,20 +448,25 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
}
|
}
|
||||||
|
|
||||||
item = new InventoryItemBase();
|
item = new InventoryItemBase();
|
||||||
item.CreatorId = objectGroup.RootPart.CreatorID.ToString();
|
// Can't know creator is the same, so null it in inventory
|
||||||
item.CreatorData = objectGroup.RootPart.CreatorData;
|
if (objlist.Count > 1)
|
||||||
|
item.CreatorId = UUID.Zero.ToString();
|
||||||
|
else
|
||||||
|
item.CreatorId = objlist[0].RootPart.CreatorID.ToString();
|
||||||
item.ID = UUID.Random();
|
item.ID = UUID.Random();
|
||||||
item.InvType = (int)InventoryType.Object;
|
item.InvType = (int)InventoryType.Object;
|
||||||
item.Folder = folder.ID;
|
item.Folder = folder.ID;
|
||||||
item.Owner = userID;
|
item.Owner = userID;
|
||||||
|
if (objlist.Count > 1)
|
||||||
|
item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetBase asset = CreateAsset(
|
AssetBase asset = CreateAsset(
|
||||||
objectGroup.GetPartName(objectGroup.RootPart.LocalId),
|
objlist[0].GetPartName(objlist[0].RootPart.LocalId),
|
||||||
objectGroup.GetPartDescription(objectGroup.RootPart.LocalId),
|
objlist[0].GetPartDescription(objlist[0].RootPart.LocalId),
|
||||||
(sbyte)AssetType.Object,
|
(sbyte)AssetType.Object,
|
||||||
Utils.StringToBytes(sceneObjectXml),
|
Utils.StringToBytes(itemXml),
|
||||||
objectGroup.OwnerID.ToString());
|
objlist[0].OwnerID.ToString());
|
||||||
m_Scene.AssetService.Store(asset);
|
m_Scene.AssetService.Store(asset);
|
||||||
assetID = asset.FullID;
|
assetID = asset.FullID;
|
||||||
|
|
||||||
|
@ -409,9 +479,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
{
|
{
|
||||||
item.AssetID = asset.FullID;
|
item.AssetID = asset.FullID;
|
||||||
|
|
||||||
if (remoteClient != null && (remoteClient.AgentId != objectGroup.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions())
|
uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7;
|
||||||
|
foreach (SceneObjectGroup grp in objlist)
|
||||||
|
effectivePerms &= grp.GetEffectivePermissions();
|
||||||
|
effectivePerms |= (uint)PermissionMask.Move;
|
||||||
|
|
||||||
|
if (remoteClient != null && (remoteClient.AgentId != objlist[0].RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions())
|
||||||
{
|
{
|
||||||
uint perms = objectGroup.GetEffectivePermissions();
|
uint perms = effectivePerms;
|
||||||
uint nextPerms = (perms & 7) << 13;
|
uint nextPerms = (perms & 7) << 13;
|
||||||
if ((nextPerms & (uint)PermissionMask.Copy) == 0)
|
if ((nextPerms & (uint)PermissionMask.Copy) == 0)
|
||||||
perms &= ~(uint)PermissionMask.Copy;
|
perms &= ~(uint)PermissionMask.Copy;
|
||||||
|
@ -420,32 +495,24 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
if ((nextPerms & (uint)PermissionMask.Modify) == 0)
|
if ((nextPerms & (uint)PermissionMask.Modify) == 0)
|
||||||
perms &= ~(uint)PermissionMask.Modify;
|
perms &= ~(uint)PermissionMask.Modify;
|
||||||
|
|
||||||
// Make sure all bits but the ones we want are clear
|
item.BasePermissions = perms & objlist[0].RootPart.NextOwnerMask;
|
||||||
// on take.
|
|
||||||
// This will be applied to the current perms, so
|
|
||||||
// it will do what we want.
|
|
||||||
objectGroup.RootPart.NextOwnerMask &=
|
|
||||||
((uint)PermissionMask.Copy |
|
|
||||||
(uint)PermissionMask.Transfer |
|
|
||||||
(uint)PermissionMask.Modify);
|
|
||||||
objectGroup.RootPart.NextOwnerMask |=
|
|
||||||
(uint)PermissionMask.Move;
|
|
||||||
|
|
||||||
item.BasePermissions = perms & objectGroup.RootPart.NextOwnerMask;
|
|
||||||
item.CurrentPermissions = item.BasePermissions;
|
item.CurrentPermissions = item.BasePermissions;
|
||||||
item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
|
item.NextPermissions = perms & objlist[0].RootPart.NextOwnerMask;
|
||||||
item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask & objectGroup.RootPart.NextOwnerMask;
|
item.EveryOnePermissions = objlist[0].RootPart.EveryoneMask & objlist[0].RootPart.NextOwnerMask;
|
||||||
item.GroupPermissions = objectGroup.RootPart.GroupMask & objectGroup.RootPart.NextOwnerMask;
|
item.GroupPermissions = objlist[0].RootPart.GroupMask & objlist[0].RootPart.NextOwnerMask;
|
||||||
|
|
||||||
item.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
|
// Magic number badness. Maybe this deserves an enum.
|
||||||
|
// bit 4 (16) is the "Slam" bit, it means treat as passed
|
||||||
|
// and apply next owner perms on rez
|
||||||
|
item.CurrentPermissions |= 16; // Slam!
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item.BasePermissions = objectGroup.GetEffectivePermissions();
|
item.BasePermissions = effectivePerms;
|
||||||
item.CurrentPermissions = objectGroup.GetEffectivePermissions();
|
item.CurrentPermissions = effectivePerms;
|
||||||
item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
|
item.NextPermissions = objlist[0].RootPart.NextOwnerMask & effectivePerms;
|
||||||
item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask;
|
item.EveryOnePermissions = objlist[0].RootPart.EveryoneMask & effectivePerms;
|
||||||
item.GroupPermissions = objectGroup.RootPart.GroupMask;
|
item.GroupPermissions = objlist[0].RootPart.GroupMask & effectivePerms;
|
||||||
|
|
||||||
item.CurrentPermissions &=
|
item.CurrentPermissions &=
|
||||||
((uint)PermissionMask.Copy |
|
((uint)PermissionMask.Copy |
|
||||||
|
@ -476,7 +543,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return assetID;
|
return assetID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
x = m_inventoryDeletes.Dequeue();
|
x = m_inventoryDeletes.Dequeue();
|
||||||
|
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[ASYNC DELETER]: Sending object to user's inventory, {0} item(s) remaining.", left);
|
"[ASYNC DELETER]: Sending object to user's inventory, action {1}, count {2}, {0} item(s) remaining.", left, x.action, x.objectGroups.Count);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -4865,8 +4865,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
float ominX, ominY, ominZ, omaxX, omaxY, omaxZ;
|
float ominX, ominY, ominZ, omaxX, omaxY, omaxZ;
|
||||||
|
|
||||||
|
Vector3 vec = g.AbsolutePosition;
|
||||||
|
|
||||||
g.GetAxisAlignedBoundingBoxRaw(out ominX, out omaxX, out ominY, out omaxY, out ominZ, out omaxZ);
|
g.GetAxisAlignedBoundingBoxRaw(out ominX, out omaxX, out ominY, out omaxY, out ominZ, out omaxZ);
|
||||||
|
|
||||||
|
ominX += vec.X;
|
||||||
|
omaxX += vec.X;
|
||||||
|
ominY += vec.Y;
|
||||||
|
omaxY += vec.Y;
|
||||||
|
ominZ += vec.Z;
|
||||||
|
omaxZ += vec.Z;
|
||||||
|
|
||||||
if (minX > ominX)
|
if (minX > ominX)
|
||||||
minX = ominX;
|
minX = ominX;
|
||||||
if (minY > ominY)
|
if (minY > ominY)
|
||||||
|
|
Loading…
Reference in New Issue