/// <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));
 }
        /// <summary>
        /// Serialize coalesced objects to Xml
        /// </summary>
        /// <param name="coa"></param>
        /// <param name="doScriptStates">
        /// If true then serialize script states.  This will halt any running scripts
        /// </param>
        /// <returns></returns>
        public static string ToXml(CoalescedSceneObjects coa, bool doScriptStates)
        {
            using (StringWriter sw = new StringWriter())
            {
                using (XmlTextWriter writer = new XmlTextWriter(sw))
                {
                    Vector3 size;

                    List <SceneObjectGroup> coaObjects = coa.Objects;

                    //                    m_log.DebugFormat(
                    //                        "[COALESCED SCENE OBJECTS SERIALIZER]: Writing {0} objects for coalesced object",
                    //                        coaObjects.Count);

                    // This is weak - we're relying on the set of coalesced objects still being identical
                    Vector3[] offsets = coa.GetSizeAndOffsets(out size);

                    writer.WriteStartElement("CoalescedObject");

                    writer.WriteAttributeString("x", size.X.ToString(Culture.FormatProvider));
                    writer.WriteAttributeString("y", size.Y.ToString(Culture.FormatProvider));
                    writer.WriteAttributeString("z", size.Z.ToString(Culture.FormatProvider));

                    // Embed the offsets into the group XML
                    for (int i = 0; i < coaObjects.Count; i++)
                    {
                        SceneObjectGroup obj = coaObjects[i];

                        //                        m_log.DebugFormat(
                        //                            "[COALESCED SCENE OBJECTS SERIALIZER]: Writing offset for object {0}, {1}",
                        //                            i, obj.Name);

                        writer.WriteStartElement("SceneObjectGroup");
                        writer.WriteAttributeString("offsetx", offsets[i].X.ToString(Culture.FormatProvider));
                        writer.WriteAttributeString("offsety", offsets[i].Y.ToString(Culture.FormatProvider));
                        writer.WriteAttributeString("offsetz", offsets[i].Z.ToString(Culture.FormatProvider));

                        SceneObjectSerializer.ToOriginalXmlFormat(obj, writer, doScriptStates);

                        writer.WriteEndElement(); // SceneObjectGroup
                    }

                    writer.WriteEndElement(); // CoalescedObject
                }

                string output = sw.ToString();

                //                Console.WriteLine(output);

                return(output);
            }
        }
        /// <summary>
        /// Serialize coalesced objects to Xml
        /// </summary>
        /// <param name="coa"></param>
        /// <param name="doScriptStates">
        /// If true then serialize script states.  This will halt any running scripts
        /// </param>
        /// <returns></returns>
        public static string ToXml(CoalescedSceneObjects coa, bool doScriptStates)
        {            
            using (StringWriter sw = new StringWriter())
            {
                using (XmlTextWriter writer = new XmlTextWriter(sw))
                {                                        
                    Vector3 size;
                    
                    List<SceneObjectGroup> coaObjects = coa.Objects;
                    
//                    m_log.DebugFormat(
//                        "[COALESCED SCENE OBJECTS SERIALIZER]: Writing {0} objects for coalesced object", 
//                        coaObjects.Count);
                    
                    // This is weak - we're relying on the set of coalesced objects still being identical
                    Vector3[] offsets = coa.GetSizeAndOffsets(out size);

                    writer.WriteStartElement("CoalescedObject");
                    
                    writer.WriteAttributeString("x", size.X.ToString());
                    writer.WriteAttributeString("y", size.Y.ToString());
                    writer.WriteAttributeString("z", size.Z.ToString());                    
                    
                    // Embed the offsets into the group XML
                    for (int i = 0; i < coaObjects.Count; i++)
                    {
                        SceneObjectGroup obj = coaObjects[i];
                        
//                        m_log.DebugFormat(
//                            "[COALESCED SCENE OBJECTS SERIALIZER]: Writing offset for object {0}, {1}", 
//                            i, obj.Name);                        
                        
                        writer.WriteStartElement("SceneObjectGroup");
                        writer.WriteAttributeString("offsetx", offsets[i].X.ToString());
                        writer.WriteAttributeString("offsety", offsets[i].Y.ToString());
                        writer.WriteAttributeString("offsetz", offsets[i].Z.ToString());
                        
                        SceneObjectSerializer.ToOriginalXmlFormat(obj, writer, doScriptStates);
                        
                        writer.WriteEndElement(); // SceneObjectGroup
                    }  
                    
                    writer.WriteEndElement(); // CoalescedObject
                }

                string output = sw.ToString();
                
//                Console.WriteLine(output);
                
                return output;
            }
        }
示例#4
0
        public static bool TryFromXml(string xml, out CoalescedSceneObjects coa)
        {
//            m_log.DebugFormat("[COALESCED SCENE OBJECTS SERIALIZER]: TryFromXml() deserializing {0}", xml);

            coa = null;

            using (StringReader sr = new StringReader(xml))
            {
                using (XmlTextReader reader = new XmlTextReader(sr))
                {
                    try
                    {
                        reader.Read();
                        if (reader.Name != "CoalescedObject")
                        {
                            //                        m_log.DebugFormat(
                            //                            "[COALESCED SCENE OBJECTS SERIALIZER]: TryFromXml() root element was {0} so returning false",
                            //                            reader.Name);

                            return(false);
                        }

                        coa = new CoalescedSceneObjects(UUID.Zero);
                        reader.Read();

                        while (reader.NodeType != XmlNodeType.EndElement && reader.Name != "CoalescedObject")
                        {
                            if (reader.Name == "SceneObjectGroup")
                            {
                                string soXml = reader.ReadOuterXml();
                                coa.Add(SceneObjectSerializer.FromOriginalXmlFormat(soXml));
                            }
                        }

                        reader.ReadEndElement(); // CoalescedObject
                    }
                    catch (Exception e)
                    {
                        m_log.ErrorFormat(
                            "[COALESCED SCENE OBJECTS SERIALIZER]: Deserialization of xml failed with {0} {1}",
                            e.Message, e.StackTrace);

                        return(false);
                    }
                }
            }

            return(true);
        }
 /// <summary>
 /// Serialize coalesced objects to Xml
 /// </summary>
 /// <param name="coa"></param>
 /// <param name="doScriptStates">
 /// If true then serialize script states.  This will halt any running scripts
 /// </param>
 /// <returns></returns>
 public static string ToXml(CoalescedSceneObjects coa)
 {
     return(ToXml(coa, true));
 }
        public static bool TryFromXmlData(byte[] data, out CoalescedSceneObjects coa)
        {
            // m_log.DebugFormat("[COALESCED SCENE OBJECTS SERIALIZER]: TryFromXml() deserializing {0}", xml);

            coa = null;
            try
            {
                int len = data.Length;
                if (len < 32)
                {
                    return(false);
                }
                if (data[len - 1] == 0)
                {
                    --len;
                }
                // Quickly check if this is a coalesced object, without fully parsing the XML
                MemoryStream ms = new MemoryStream(data, 0, len, false);
                StreamReader sr = new StreamReader(ms, Encoding.UTF8);
                using (XmlTextReader reader = new XmlTextReader(sr))
                {
                    reader.MoveToContent(); // skip possible xml declaration

                    if (reader.Name != "CoalescedObject")
                    {
                        return(false);
                    }
                }

                XmlDocument doc = new XmlDocument();
                using (ms = new MemoryStream(data, 0, len, false))
                    doc.Load(ms);

                XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject");
                if (e == null)
                {
                    return(false);
                }

                coa = new CoalescedSceneObjects(UUID.Zero);

                XmlNodeList groups = e.SelectNodes("SceneObjectGroup");
                int         i      = 0;

                foreach (XmlNode n in groups)
                {
                    SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml);
                    if (so != null)
                    {
                        coa.Add(so);
                    }
                    else
                    {
                        // XXX: Possibly we should fail outright here rather than continuing if a particular component of the
                        // coalesced object fails to load.
                        m_log.WarnFormat(
                            "[COALESCED SCENE OBJECTS SERIALIZER]: Deserialization of xml for component {0} failed.  Continuing.",
                            i);
                    }

                    i++;
                }
            }
            catch (Exception e)
            {
                m_log.Error("[COALESCED SCENE OBJECTS SERIALIZER]: Deserialization of binary xml failed ", e);
                return(false);
            }

            return(true);
        }
        public static bool TryFromXml(string xml, out CoalescedSceneObjects coa)
        {
            //            m_log.DebugFormat("[COALESCED SCENE OBJECTS SERIALIZER]: TryFromXml() deserializing {0}", xml);

            coa = null;

            try
            {
                // Quickly check if this is a coalesced object, without fully parsing the XML
                using (XmlTextReader reader = new XmlTextReader(new StringReader(xml)))
                {
                    reader.MoveToContent(); // skip possible xml declaration

                    if (reader.Name != "CoalescedObject")
                    {
                        // m_log.DebugFormat(
                        //     "[COALESCED SCENE OBJECTS SERIALIZER]: TryFromXml() root element was {0} so returning false",
                        //     reader.Name);

                        return(false);
                    }
                }

                XmlDocument doc = new XmlDocument();
                doc.LoadXml(xml);
                XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject");
                if (e == null)
                {
                    return(false);
                }

                coa = new CoalescedSceneObjects(UUID.Zero);

                XmlNodeList groups = e.SelectNodes("SceneObjectGroup");
                int         i      = 0;

                foreach (XmlNode n in groups)
                {
                    SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml);
                    if (so != null)
                    {
                        coa.Add(so);
                    }
                    else
                    {
                        // XXX: Possibly we should fail outright here rather than continuing if a particular component of the
                        // coalesced object fails to load.
                        m_log.WarnFormat(
                            "[COALESCED SCENE OBJECTS SERIALIZER]: Deserialization of xml for component {0} failed.  Continuing.",
                            i);
                    }

                    i++;
                }
            }
            catch (Exception e)
            {
                m_log.Error("[COALESCED SCENE OBJECTS SERIALIZER]: Deserialization of xml failed ", e);
                Util.LogFailedXML("[COALESCED SCENE OBJECTS SERIALIZER]:", xml);
                return(false);
            }

            return(true);
        }
        public void TestRezCoalescedObject()
        {
            TestHelpers.InMethod();
            //            log4net.Config.XmlConfigurator.Configure();

            // Create asset
            SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, m_userId, "Object1", 0x20);

            object1.AbsolutePosition = new Vector3(15, 30, 45);

            SceneObjectGroup object2 = SceneHelpers.CreateSceneObject(1, m_userId, "Object2", 0x40);

            object2.AbsolutePosition = new Vector3(25, 50, 75);

            CoalescedSceneObjects coa = new CoalescedSceneObjects(m_userId, object1, object2);

            UUID      asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
            AssetBase asset1   = AssetHelpers.CreateAsset(asset1Id, coa);

            m_scene.AssetService.Store(asset1);

            // Create item
            UUID              item1Id   = UUID.Parse("00000000-0000-0000-0000-000000000080");
            string            item1Name = "My Little Dog";
            InventoryItemBase item1     = new InventoryItemBase();

            item1.Name    = item1Name;
            item1.AssetID = asset1.FullID;
            item1.ID      = item1Id;
            InventoryFolderBase objsFolder
                = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0];

            item1.Folder = objsFolder.ID;
            m_scene.AddInventoryItem(item1);

            SceneObjectGroup so
                = m_iam.RezObject(
                      m_tc, item1Id, new Vector3(100, 100, 100), Vector3.Zero, UUID.Zero, 1, false, false, false, UUID.Zero, false);

            Assert.That(so, Is.Not.Null);

            Assert.That(m_scene.SceneGraph.GetTotalObjectsCount(), Is.EqualTo(2));

            SceneObjectPart retrievedObj1Part = m_scene.GetSceneObjectPart(object1.Name);

            Assert.That(retrievedObj1Part, Is.Null);

            retrievedObj1Part = m_scene.GetSceneObjectPart(item1.Name);
            Assert.That(retrievedObj1Part, Is.Not.Null);
            Assert.That(retrievedObj1Part.Name, Is.EqualTo(item1.Name));

            // Bottom of coalescence is placed on ground, hence we end up with 100.5 rather than 85 since the bottom
            // object is unit square.
            Assert.That(retrievedObj1Part.AbsolutePosition, Is.EqualTo(new Vector3(95, 90, 100.5f)));

            SceneObjectPart retrievedObj2Part = m_scene.GetSceneObjectPart(object2.Name);

            Assert.That(retrievedObj2Part, Is.Not.Null);
            Assert.That(retrievedObj2Part.Name, Is.EqualTo(object2.Name));
            Assert.That(retrievedObj2Part.AbsolutePosition, Is.EqualTo(new Vector3(105, 110, 130.5f)));
        }
示例#9
0
        protected void ConstructDefaultIarBytesForTestLoad()
        {
            //            log4net.Config.XmlConfigurator.Configure();

            InventoryArchiverModule archiverModule = new InventoryArchiverModule();
            Scene scene = new SceneHelpers().SetupScene();

            SceneHelpers.SetupSceneModules(scene, archiverModule);

            UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire");

            MemoryStream archiveWriteStream = new MemoryStream();

            // Create scene object asset
            UUID             ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
            SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "Ray Gun Object", 0x50);

            UUID      asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
            AssetBase asset1   = AssetHelpers.CreateAsset(asset1Id, object1);

            scene.AssetService.Store(asset1);

            // Create scene object item
            InventoryItemBase item1 = new InventoryItemBase();

            item1.Name      = m_item1Name;
            item1.ID        = UUID.Parse("00000000-0000-0000-0000-000000000020");
            item1.AssetID   = asset1.FullID;
            item1.GroupID   = UUID.Random();
            item1.CreatorId = m_uaLL1.PrincipalID.ToString();
            item1.Owner     = m_uaLL1.PrincipalID;
            item1.Folder    = scene.InventoryService.GetRootFolder(m_uaLL1.PrincipalID).ID;
            scene.AddInventoryItem(item1);

            // Create coalesced objects asset
            SceneObjectGroup cobj1 = SceneHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object1", 0x120);

            cobj1.AbsolutePosition = new Vector3(15, 30, 45);

            SceneObjectGroup cobj2 = SceneHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object2", 0x140);

            cobj2.AbsolutePosition = new Vector3(25, 50, 75);

            CoalescedSceneObjects coa = new CoalescedSceneObjects(m_uaLL1.PrincipalID, cobj1, cobj2);

            AssetBase coaAsset = AssetHelpers.CreateAsset(0x160, coa);

            scene.AssetService.Store(coaAsset);

            // Create coalesced objects inventory item
            InventoryItemBase coaItem = new InventoryItemBase();

            coaItem.Name      = m_coaItemName;
            coaItem.ID        = UUID.Parse("00000000-0000-0000-0000-000000000180");
            coaItem.AssetID   = coaAsset.FullID;
            coaItem.GroupID   = UUID.Random();
            coaItem.CreatorId = m_uaLL1.PrincipalID.ToString();
            coaItem.Owner     = m_uaLL1.PrincipalID;
            coaItem.Folder    = scene.InventoryService.GetRootFolder(m_uaLL1.PrincipalID).ID;
            scene.AddInventoryItem(coaItem);

            archiverModule.ArchiveInventory(
                UUID.Random(), m_uaLL1.FirstName, m_uaLL1.LastName, "/*", "hampshire", archiveWriteStream);

            m_iarStreamBytes = archiveWriteStream.ToArray();
        }
 /// <summary>
 /// Serialize coalesced objects to Xml
 /// </summary>
 /// <param name="coa"></param>
 /// <param name="doScriptStates">
 /// If true then serialize script states.  This will halt any running scripts
 /// </param>
 /// <returns></returns>
 public static string ToXml(CoalescedSceneObjects coa)
 {
     return ToXml(coa, true);
 }
        public static bool TryFromXml(string xml, out CoalescedSceneObjects coa)
        {
//            m_log.DebugFormat("[COALESCED SCENE OBJECTS SERIALIZER]: TryFromXml() deserializing {0}", xml);
            
            coa = null;
            
            try
            {
                // Quickly check if this is a coalesced object, without fully parsing the XML
                using (StringReader sr = new StringReader(xml))
                {                
                    using (XmlTextReader reader = new XmlTextReader(sr))
                    {
                        reader.MoveToContent(); // skip possible xml declaration

                        if (reader.Name != "CoalescedObject")
                        {
    //                        m_log.DebugFormat(
    //                            "[COALESCED SCENE OBJECTS SERIALIZER]: TryFromXml() root element was {0} so returning false", 
    //                            reader.Name);
                            
                            return false;
                        }
                    }
                }

                XmlDocument doc = new XmlDocument();
                doc.LoadXml(xml);
                XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject");
                if (e == null)
                    return false;
                        
                coa = new CoalescedSceneObjects(UUID.Zero);

                XmlNodeList groups = e.SelectNodes("SceneObjectGroup");
                int i = 0;
                
                foreach (XmlNode n in groups)
                {
                    SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml);
                    if (so != null)
                    {
                        coa.Add(so);
                    }
                    else
                    {
                        // XXX: Possibly we should fail outright here rather than continuing if a particular component of the 
                        // coalesced object fails to load.
                        m_log.WarnFormat(
                            "[COALESCED SCENE OBJECTS SERIALIZER]: Deserialization of xml for component {0} failed.  Continuing.", 
                            i);
                    }

                    i++;
                }
            }
            catch (Exception e)
            {
                m_log.Error(string.Format(
                    "[COALESCED SCENE OBJECTS SERIALIZER]: Deserialization of xml failed with {0} ", 
                    e.Message), e);
                        
                return false;
            }                        
            
            return true;
        }
示例#12
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);
            }
        }
示例#13
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);
        }
        public static bool TryFromXml(string xml, out CoalescedSceneObjects coa)
        {
//            m_log.DebugFormat("[COALESCED SCENE OBJECTS SERIALIZER]: TryFromXml() deserializing {0}", xml);

            coa = null;
            int i = 0;

            using (StringReader sr = new StringReader(xml))
            {
                using (XmlTextReader reader = new XmlTextReader(sr))
                {
                    try
                    {
                        reader.Read();
                        if (reader.Name != "CoalescedObject")
                        {
                            //                        m_log.DebugFormat(
                            //                            "[COALESCED SCENE OBJECTS SERIALIZER]: TryFromXml() root element was {0} so returning false",
                            //                            reader.Name);

                            return(false);
                        }

                        coa = new CoalescedSceneObjects(UUID.Zero);
                        reader.Read();

                        while (reader.NodeType != XmlNodeType.EndElement && reader.Name != "CoalescedObject")
                        {
                            if (reader.Name == "SceneObjectGroup")
                            {
                                string soXml = reader.ReadOuterXml();

                                SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(soXml);

                                if (so != null)
                                {
                                    coa.Add(so);
                                }
                                else
                                {
                                    // XXX: Possibly we should fail outright here rather than continuing if a particular component of the
                                    // coalesced object fails to load.
                                    m_log.WarnFormat(
                                        "[COALESCED SCENE OBJECTS SERIALIZER]: Deserialization of xml for component {0} failed.  Continuing.",
                                        i);
                                }

                                i++;
                            }
                        }

                        reader.ReadEndElement(); // CoalescedObject
                    }
                    catch (Exception e)
                    {
                        m_log.ErrorFormat(
                            "[COALESCED SCENE OBJECTS SERIALIZER]: Deserialization of xml failed with {0} {1}",
                            e.Message, e.StackTrace);

                        return(false);
                    }
                }
            }

            return(true);
        }
 /// <summary>
 /// Create an asset from the given scene object.
 /// </summary>
 /// <param name="assetUuidTail">
 /// The hexadecimal last part of the UUID for the asset created.  A UUID of the form "00000000-0000-0000-0000-{0:XD12}"
 /// will be used.
 /// </param>
 /// <param name="coa"></param>
 /// <returns></returns>
 public static AssetBase CreateAsset(int assetUuidTail, CoalescedSceneObjects coa)
 {
     return(CreateAsset(new UUID(string.Format("00000000-0000-0000-0000-{0:X12}", assetUuidTail)), coa));
 }
示例#16
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>
        /// <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);
        }