/// <summary>
 /// Create an asset from the given scene object.
 /// </summary>
 /// <param name="assetUuid"></param>
 /// <param name="coa"></param>
 /// <returns></returns>
 public static AssetBase CreateAsset(UUID assetUuid, CoalescedSceneObjects coa)
 {
     return(CreateAsset(
                assetUuid,
                AssetType.Object,
                Encoding.ASCII.GetBytes(CoalescedSceneObjectsSerializer.ToXml(coa)),
                coa.CreatorId));
 }
Esempio n. 2
0
        /// <summary>
        /// Load an asset
        /// </summary>
        /// <param name="assetFilename"></param>
        /// <param name="data"></param>
        /// <returns>true if asset was successfully loaded, false otherwise</returns>
        private bool LoadAsset(string assetPath, byte[] data)
        {
            //IRegionSerialiser serialiser = scene.RequestModuleInterface<IRegionSerialiser>();
            // Right now we're nastily obtaining the UUID from the filename
            string filename = assetPath.Remove(0, ArchiveConstants.ASSETS_PATH.Length);
            int    i        = filename.LastIndexOf(ArchiveConstants.ASSET_EXTENSION_SEPARATOR);

            if (i == -1)
            {
                m_log.ErrorFormat(
                    "[INVENTORY ARCHIVER]: Could not find extension information in asset path {0} since it's missing the separator {1}.  Skipping",
                    assetPath, ArchiveConstants.ASSET_EXTENSION_SEPARATOR);

                return(false);
            }

            string extension = filename.Substring(i);
            string rawUuid   = filename.Remove(filename.Length - extension.Length);
            UUID   assetId   = new UUID(rawUuid);

            if (ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension))
            {
                sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension];

                if (assetType == (sbyte)AssetType.Unknown)
                {
                    m_log.WarnFormat("[INVENTORY ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, assetId);
                }
                else if (assetType == (sbyte)AssetType.Object)
                {
                    if (m_creatorIdForAssetId.ContainsKey(assetId))
                    {
                        string xmlData = Utils.BytesToString(data);
                        List <SceneObjectGroup> sceneObjects = new List <SceneObjectGroup>();

                        CoalescedSceneObjects coa = null;
                        if (CoalescedSceneObjectsSerializer.TryFromXml(xmlData, out coa))
                        {
//                            m_log.DebugFormat(
//                                "[INVENTORY ARCHIVER]: Loaded coalescence {0} has {1} objects", assetId, coa.Count);

                            if (coa.Objects.Count == 0)
                            {
                                m_log.WarnFormat(
                                    "[INVENTORY ARCHIVE READ REQUEST]: Aborting load of coalesced object from asset {0} as it has zero loaded components",
                                    assetId);
                                return(false);
                            }

                            sceneObjects.AddRange(coa.Objects);
                        }
                        else
                        {
                            SceneObjectGroup deserializedObject = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);

                            if (deserializedObject != null)
                            {
                                sceneObjects.Add(deserializedObject);
                            }
                            else
                            {
                                m_log.WarnFormat(
                                    "[INVENTORY ARCHIVE READ REQUEST]: Aborting load of object from asset {0} as deserialization failed",
                                    assetId);

                                return(false);
                            }
                        }

                        foreach (SceneObjectGroup sog in sceneObjects)
                        {
                            foreach (SceneObjectPart sop in sog.Parts)
                            {
                                if (string.IsNullOrEmpty(sop.CreatorData))
                                {
                                    sop.CreatorID = m_creatorIdForAssetId[assetId];
                                }
                            }
                        }

                        if (coa != null)
                        {
                            data = Utils.StringToBytes(CoalescedSceneObjectsSerializer.ToXml(coa));
                        }
                        else
                        {
                            data = Utils.StringToBytes(SceneObjectSerializer.ToOriginalXmlFormat(sceneObjects[0]));
                        }
                    }
                }

                //m_log.DebugFormat("[INVENTORY ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType);

                AssetBase asset = new AssetBase(assetId, "From IAR", assetType, UUID.Zero.ToString());
                asset.Data = data;

                m_AssetService.Store(asset);

                return(true);
            }
            else
            {
                m_log.ErrorFormat(
                    "[INVENTORY ARCHIVER]: Tried to dearchive data with path {0} with an unknown type extension {1}",
                    assetPath, extension);

                return(false);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Copy a bundle of objects to inventory.  If there is only one object, then this will create an object
        /// item.  If there are multiple objects then these will be saved as a single coalesced item.
        /// </summary>
        /// <param name="action"></param>
        /// <param name="folderID"></param>
        /// <param name="objlist"></param>
        /// <param name="remoteClient"></param>
        /// <returns></returns>
        protected UUID CopyBundleToInventory(
            DeRezAction action, UUID folderID, List <SceneObjectGroup> objlist, IClientAPI remoteClient)
        {
            UUID assetID = UUID.Zero;

            CoalescedSceneObjects      coa = new CoalescedSceneObjects(UUID.Zero);
            Dictionary <UUID, Vector3> originalPositions = new Dictionary <UUID, Vector3>();

            foreach (SceneObjectGroup objectGroup in objlist)
            {
                Vector3 inventoryStoredPosition = new Vector3
                                                      (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
                                  ? 250
                                  : objectGroup.AbsolutePosition.X)
                                                      ,
                                                      (objectGroup.AbsolutePosition.Y > (int)Constants.RegionSize)
                                 ? 250
                                 : objectGroup.AbsolutePosition.Y,
                                                      objectGroup.AbsolutePosition.Z);

                originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition;

                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;

                coa.Add(objectGroup);
            }

            string itemXml;

            if (objlist.Count > 1)
            {
                itemXml = CoalescedSceneObjectsSerializer.ToXml(coa);
            }
            else
            {
                itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0]);
            }

            // Restore the position of each group now that it has been stored to inventory.
            foreach (SceneObjectGroup objectGroup in objlist)
            {
                objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID];
            }

            InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID);

            if (item == null)
            {
                return(UUID.Zero);
            }

            // Can't know creator is the same, so null it in inventory
            if (objlist.Count > 1)
            {
                item.CreatorId = UUID.Zero.ToString();
                item.Flags     = (uint)InventoryItemFlags.ObjectHasMultipleItems;
            }
            else
            {
                item.CreatorId = objlist[0].RootPart.CreatorID.ToString();
                item.SaleType  = objlist[0].RootPart.ObjectSaleType;
                item.SalePrice = objlist[0].RootPart.SalePrice;
            }

            AssetBase asset = CreateAsset(
                objlist[0].GetPartName(objlist[0].RootPart.LocalId),
                objlist[0].GetPartDescription(objlist[0].RootPart.LocalId),
                (sbyte)AssetType.Object,
                Utils.StringToBytes(itemXml),
                objlist[0].OwnerID.ToString());

            m_Scene.AssetService.Store(asset);

            item.AssetID = asset.FullID;
            assetID      = asset.FullID;

            if (DeRezAction.SaveToExistingUserInventoryItem == action)
            {
                m_Scene.InventoryService.UpdateItem(item);
            }
            else
            {
                AddPermissions(item, objlist[0], objlist, remoteClient);

                item.CreationDate = Util.UnixTimeSinceEpoch();
                item.Description  = asset.Description;
                item.Name         = asset.Name;
                item.AssetType    = asset.Type;

                m_Scene.AddInventoryItem(item);

                if (remoteClient != null && item.Owner == remoteClient.AgentId)
                {
                    remoteClient.SendInventoryItemCreateUpdate(item, 0);
                }
                else
                {
                    ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner);
                    if (notifyUser != null)
                    {
                        notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
                    }
                }
            }

            // This is a hook to do some per-asset post-processing for subclasses that need that
            ExportAsset(remoteClient.AgentId, assetID);

            return(assetID);
        }
        /// <summary>
        /// Copy a bundle of objects to inventory.  If there is only one object, then this will create an object
        /// item.  If there are multiple objects then these will be saved as a single coalesced item.
        /// </summary>
        /// <param name="action"></param>
        /// <param name="folderID"></param>
        /// <param name="objlist"></param>
        /// <param name="remoteClient"></param>
        /// <param name="asAttachment">Should be true if the bundle is being copied as an attachment.  This prevents
        /// attempted serialization of any script state which would abort any operating scripts.</param>
        /// <returns>The inventory item created by the copy</returns>
        protected InventoryItemBase CopyBundleToInventory(
            DeRezAction action, UUID folderID, List <SceneObjectGroup> objlist, IClientAPI remoteClient,
            bool asAttachment)
        {
            CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero);
//            Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>();

            Dictionary <SceneObjectGroup, KeyframeMotion> group2Keyframe = new Dictionary <SceneObjectGroup, KeyframeMotion>();

            foreach (SceneObjectGroup objectGroup in objlist)
            {
                if (objectGroup.RootPart.KeyframeMotion != null)
                {
                    objectGroup.RootPart.KeyframeMotion.Pause();
                    group2Keyframe.Add(objectGroup, objectGroup.RootPart.KeyframeMotion);
                    objectGroup.RootPart.KeyframeMotion = null;
                }

//                Vector3 inventoryStoredPosition = new Vector3
//                            (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
//                                  ? 250
//                                  : objectGroup.AbsolutePosition.X)
//                             ,
//                             (objectGroup.AbsolutePosition.Y > (int)Constants.RegionSize)
//                                 ? 250
//                                 : objectGroup.AbsolutePosition.Y,
//                             objectGroup.AbsolutePosition.Z);
//
//                originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition;
//
//                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 |
                     (uint)PermissionMask.Export);
                objectGroup.RootPart.NextOwnerMask |=
                    (uint)PermissionMask.Move;

                coa.Add(objectGroup);
            }

            string itemXml;

            // If we're being called from a script, then trying to serialize that same script's state will not complete
            // in any reasonable time period.  Therefore, we'll avoid it.  The worst that can happen is that if
            // the client/server crashes rather than logging out normally, the attachment's scripts will resume
            // without state on relog.  Arguably, this is what we want anyway.
            if (objlist.Count > 1)
            {
                itemXml = CoalescedSceneObjectsSerializer.ToXml(coa, !asAttachment);
            }
            else
            {
                itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0], !asAttachment);
            }

//            // Restore the position of each group now that it has been stored to inventory.
//            foreach (SceneObjectGroup objectGroup in objlist)
//                objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID];

            InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID);

//            m_log.DebugFormat(
//                "[INVENTORY ACCESS MODULE]: Created item is {0}",
//                item != null ? item.ID.ToString() : "NULL");

            if (item == null)
            {
                return(null);
            }

            item.CreatorId   = objlist[0].RootPart.CreatorID.ToString();
            item.CreatorData = objlist[0].RootPart.CreatorData;

            if (objlist.Count > 1)
            {
                item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems;

                // If the objects have different creators then don't specify a creator at all
                foreach (SceneObjectGroup objectGroup in objlist)
                {
                    if ((objectGroup.RootPart.CreatorID.ToString() != item.CreatorId) ||
                        (objectGroup.RootPart.CreatorData.ToString() != item.CreatorData))
                    {
                        item.CreatorId   = UUID.Zero.ToString();
                        item.CreatorData = string.Empty;
                        break;
                    }
                }
            }
            else
            {
                item.SaleType  = objlist[0].RootPart.ObjectSaleType;
                item.SalePrice = objlist[0].RootPart.SalePrice;
            }

            AssetBase asset = CreateAsset(
                objlist[0].GetPartName(objlist[0].RootPart.LocalId),
                objlist[0].GetPartDescription(objlist[0].RootPart.LocalId),
                (sbyte)AssetType.Object,
                Utils.StringToBytes(itemXml),
                objlist[0].OwnerID.ToString());

            m_Scene.AssetService.Store(asset);

            item.AssetID = asset.FullID;

            if (DeRezAction.SaveToExistingUserInventoryItem == action)
            {
                m_Scene.InventoryService.UpdateItem(item);
            }
            else
            {
                item.CreationDate = Util.UnixTimeSinceEpoch();
                item.Description  = asset.Description;
                item.Name         = asset.Name;
                item.AssetType    = asset.Type;

                AddPermissions(item, objlist[0], objlist, remoteClient);

                m_Scene.AddInventoryItem(item);

                if (remoteClient != null && item.Owner == remoteClient.AgentId)
                {
                    remoteClient.SendInventoryItemCreateUpdate(item, 0);
                }
                else
                {
                    ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner);
                    if (notifyUser != null)
                    {
                        notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
                    }
                }
            }

            // Restore KeyframeMotion
            foreach (SceneObjectGroup objectGroup in group2Keyframe.Keys)
            {
                objectGroup.RootPart.KeyframeMotion = group2Keyframe[objectGroup];
                objectGroup.RootPart.KeyframeMotion.Start();
            }

            // This is a hook to do some per-asset post-processing for subclasses that need that
            if (remoteClient != null)
            {
                ExportAsset(remoteClient.AgentId, asset.FullID);
            }

            return(item);
        }