public void TestRenderMaterialsSerialization() { var sop1 = SceneUtil.RandomSOP("Root", 1); var sop2 = SceneUtil.RandomSOP("Child1", 2); var sop3 = SceneUtil.RandomSOP("Child2", 3); var mat1 = new RenderMaterial(UUID.Random(), UUID.Random()); var mat2 = new RenderMaterial(UUID.Random(), UUID.Random()); sop1.Shape.RenderMaterials.AddMaterial(mat1); sop2.Shape.RenderMaterials.AddMaterial(mat2); SceneObjectGroup group = new SceneObjectGroup(sop1); group.AddPart(sop2); group.AddPart(sop3); SceneObjectGroup deserGroup = null; string grpBytes = null; Assert.DoesNotThrow(() => { grpBytes = SceneObjectSerializer.ToXml2Format(group, true); }); Assert.NotNull(grpBytes); Assert.DoesNotThrow(() => { deserGroup = SceneObjectSerializer.FromXml2Format(grpBytes); }); var newsop1 = deserGroup.GetChildPart(1); var newsop2 = deserGroup.GetChildPart(2); var newsop3 = deserGroup.GetChildPart(3); Assert.That(sop1.Shape.RenderMaterials, Is.EqualTo(newsop1.Shape.RenderMaterials)); Assert.That(sop2.Shape.RenderMaterials, Is.EqualTo(newsop2.Shape.RenderMaterials)); Assert.That(sop3.Shape.RenderMaterials, Is.EqualTo(newsop3.Shape.RenderMaterials)); }
public static PrimitiveBaseShape DeSerializeShape(string shapeString) { if (shapeString == null || shapeString == String.Empty || shapeString == "") { return(null); } StringReader sr = new StringReader(shapeString); XmlTextReader reader = new XmlTextReader(sr); PrimitiveBaseShape shapeValue; try { List <string> errors = new List <string>(); shapeValue = SceneObjectSerializer.ReadShape(reader, "Shape", out errors); } catch (Exception e) { Console.WriteLine("DeSerializeShape: Error " + e.Message); return(null); } return(shapeValue); }
public void TestDeserializeXmlObjectWithOtherParts() { TestHelpers.InMethod(); TestHelpers.EnableLogging(); SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(ObjectWithOtherPartsXml); SceneObjectPart[] parts = so.Parts; Assert.AreEqual(3, so.Parts.Length); { SceneObjectPart part = parts[0]; Assert.That(part.UUID, Is.EqualTo(new UUID("e6a5a05e-e8cc-4816-8701-04165e335790"))); Assert.That(part.CreatorID, Is.EqualTo(new UUID("a6dacf01-4636-4bb9-8a97-30609438af9d"))); Assert.That(part.Name, Is.EqualTo("PrimMyRide")); OSDMap store = part.DynAttrs.GetStore("MyNamespace", "MyStore"); Assert.AreEqual(42, store["the answer"].AsInteger()); } { SceneObjectPart part = parts[1]; Assert.That(part.UUID, Is.EqualTo(new UUID("9958feb1-02a6-49e4-a4ce-eba6f578ee13"))); Assert.That(part.CreatorID, Is.EqualTo(new UUID("a6dacf01-4636-4bb9-8a97-30609438af9d"))); Assert.That(part.Name, Is.EqualTo("Alien Head 1")); } { SceneObjectPart part = parts[2]; Assert.That(part.UUID, Is.EqualTo(new UUID("674b6b86-f5aa-439a-8e00-0d75bc08c80a"))); Assert.That(part.CreatorID, Is.EqualTo(new UUID("a6dacf01-4636-4bb9-8a97-30609438af9d"))); Assert.That(part.Name, Is.EqualTo("Alien Head 2")); } // TODO: Check other properties }
/// <summary> /// Get all the asset uuids associated with a given object. This includes both those directly associated with /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained /// within this object). /// </summary> /// <param name="sceneObject"></param> /// <param name="assetUuids"></param> protected void GetSceneObjectAssetUuids(UUID sceneObjectUuid, IDictionary <UUID, int> assetUuids) { AssetBase objectAsset = GetAsset(sceneObjectUuid); if (null != objectAsset) { SceneObjectGroup sog; if (m_inventorySerializer.IsValidCoalesced(objectAsset.Data)) { m_log.WarnFormat("[ARCHIVER]: UUID gatherer encountered a coalesced object, asset ID {0} - skipped.", objectAsset.FullID); return; } if (m_inventorySerializer.IsValidGroup(objectAsset.Data)) { sog = m_inventorySerializer.DeserializeGroupFromInventoryBytes(objectAsset.Data); } else { string xml = Utils.BytesToString(objectAsset.Data); sog = SceneObjectSerializer.FromOriginalXmlFormat(xml); if (sog == null) { // in some case it may have been saved as XML2 sog = SceneObjectSerializer.FromXml2Format(xml); if (sog != null) { m_log.InfoFormat("[ARCHIVER]: Was able to recover asset {0} as XML2 format.", objectAsset.FullID); } } } if (sog != null) { GatherAssetUuids(sog, assetUuids); } } }
/// <summary> /// Get all the asset uuids associated with a given object. This includes both those directly associated with /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained /// within this object). /// </summary> /// <param name="sceneObjectAsset"></param> private void RecordSceneObjectAssetUuids(AssetBase sceneObjectAsset) { string xml = Utils.BytesToString(sceneObjectAsset.Data); CoalescedSceneObjects coa; if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa)) { foreach (SceneObjectGroup sog in coa.Objects) { AddForInspection(sog); } } else { SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml); if (null != sog) { AddForInspection(sog); } } }
/** * Object-related communications */ public bool SendCreateObject(ulong regionHandle, SceneObjectGroup sog, bool isLocalCall) { // Try local first if (m_localBackend.SendCreateObject(regionHandle, sog, true)) { //m_log.Debug("[REST COMMS]: LocalBackEnd SendCreateObject succeeded"); return(true); } // else do the remote thing if (!m_localBackend.IsLocalRegion(regionHandle)) { RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle); if (regInfo != null) { return(m_regionClient.DoCreateObjectCall( regInfo, sog, SceneObjectSerializer.ToXml2Format(sog), m_aScene.m_allowScriptCrossings)); } //else // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); } return(false); }
/// <summary> /// Update the attachment asset for the new sog details if they have changed. /// </summary> /// /// This is essential for preserving attachment attributes such as permission. Unlike normal scene objects, /// these details are not stored on the region. /// /// <param name="remoteClient"></param> /// <param name="grp"></param> /// <param name="itemID"></param> /// <param name="agentID"></param> protected UUID UpdateKnownItem(IClientAPI remoteClient, ISceneEntity grp, UUID itemID, UUID agentID) { if (grp != null) { if (!grp.HasGroupChanged) { //MainConsole.Instance.WarnFormat("[ATTACHMENTS MODULE]: Save request for {0} which is unchanged", grp.UUID); return(UUID.Zero); } //let things like state saves and another async things be performed before we serialize the object grp.BackupPreparation(); MainConsole.Instance.InfoFormat( "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", grp.UUID, grp.GetAttachmentPoint()); string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat((SceneObjectGroup)grp); AssetBase asset = new AssetBase(UUID.Random(), grp.Name, AssetType.Object, remoteClient.AgentId) { Description = grp.RootChild.Description, Data = Utils.StringToBytes(sceneObjectXml) }; asset.ID = m_scene.AssetService.Store(asset); m_scene.InventoryService.UpdateAssetIDForItem(itemID, asset.ID); // this gets called when the agent logs off! //remoteClient.SendInventoryItemCreateUpdate(item, 0); return(asset.ID); } return(UUID.Zero); }
public void TestDeserializeBadFloatsXml() { TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(ObjectWithBadFloatsXml); SceneObjectPart rootPart = so.RootPart; Assert.That(rootPart.UUID, Is.EqualTo(new UUID("e6a5a05e-e8cc-4816-8701-04165e335790"))); Assert.That(rootPart.CreatorID, Is.EqualTo(new UUID("a6dacf01-4636-4bb9-8a97-30609438af9d"))); Assert.That(rootPart.Name, Is.EqualTo("NaughtyPrim")); // This terminates the deserialization earlier if couldn't be parsed. // TODO: Need to address this Assert.That(rootPart.GroupPosition.X, Is.EqualTo(147.23f)); Assert.That(rootPart.Shape.PathCurve, Is.EqualTo(16)); // Defaults for bad parses Assert.That(rootPart.Shape.FlexiTension, Is.EqualTo(0)); Assert.That(rootPart.Shape.FlexiDrag, Is.EqualTo(0)); // TODO: Check other properties }
private static string GetObjectXml(Scene scene) { string xmlstream = "<scene>"; EntityBase[] EntityList = scene.GetEntities(); List <string> EntityXml = new List <string>(); foreach (EntityBase ent in EntityList) { if (ent is SceneObjectGroup) { EntityXml.Add(SceneObjectSerializer.ToXml2Format((SceneObjectGroup)ent)); } } EntityXml.Sort(); foreach (string xml in EntityXml) { xmlstream += xml; } xmlstream += "</scene>"; return(xmlstream); }
public void TestLoadOarV0_2() { TestHelper.InMethod(); // log4net.Config.XmlConfigurator.Configure(); MemoryStream archiveWriteStream = new MemoryStream(); TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream); // Put in a random blank directory to check that this doesn't upset the load process tar.WriteDir("ignoreme"); // Also check that direct entries which will also have a file entry containing that directory doesn't // upset load tar.WriteDir(ArchiveConstants.TERRAINS_PATH); tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestExecution.Create0p2ControlFile()); SceneObjectPart part1 = CreateSceneObjectPart1(); SceneObjectGroup object1 = new SceneObjectGroup(part1); // Let's put some inventory items into our object string soundItemName = "sound-item1"; UUID soundItemUuid = UUID.Parse("00000000-0000-0000-0000-000000000002"); Type type = GetType(); Assembly assembly = type.Assembly; string soundDataResourceName = null; string[] names = assembly.GetManifestResourceNames(); foreach (string name in names) { if (name.EndsWith(".Resources.test-sound.wav")) { soundDataResourceName = name; } } Assert.That(soundDataResourceName, Is.Not.Null); byte[] soundData; Console.WriteLine("Loading " + soundDataResourceName); using (Stream resource = assembly.GetManifestResourceStream(soundDataResourceName)) { using (BinaryReader br = new BinaryReader(resource)) { // FIXME: Use the inspector insteadthere are so many forums and lists already, though admittedly none of them are suitable for cross virtual-enivornemnt discussion soundData = br.ReadBytes(99999999); UUID soundUuid = UUID.Parse("00000000-0000-0000-0000-000000000001"); string soundAssetFileName = ArchiveConstants.ASSETS_PATH + soundUuid + ArchiveConstants.ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.SoundWAV]; tar.WriteFile(soundAssetFileName, soundData); /* * AssetBase soundAsset = AssetHelpers.CreateAsset(soundUuid, soundData); * scene.AssetService.Store(soundAsset); * asset1FileName = ArchiveConstants.ASSETS_PATH + soundUuid + ".wav"; */ TaskInventoryItem item1 = new TaskInventoryItem { AssetID = soundUuid, ItemID = soundItemUuid, Name = soundItemName }; part1.Inventory.AddInventoryItem(item1, true); } } m_scene.AddNewSceneObject(object1, false); string object1FileName = string.Format( "{0}_{1:000}-{2:000}-{3:000}__{4}.xml", part1.Name, Math.Round(part1.GroupPosition.X), Math.Round(part1.GroupPosition.Y), Math.Round(part1.GroupPosition.Z), part1.UUID); tar.WriteFile(ArchiveConstants.OBJECTS_PATH + object1FileName, SceneObjectSerializer.ToXml2Format(object1)); tar.Close(); MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); lock (this) { m_scene.EventManager.OnOarFileLoaded += LoadCompleted; m_archiverModule.DearchiveRegion(archiveReadStream); } Assert.That(m_lastErrorMessage, Is.Null); SceneObjectPart object1PartLoaded = m_scene.GetSceneObjectPart(part1.Name); Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded"); Assert.That(object1PartLoaded.Name, Is.EqualTo(part1.Name), "object1 names not identical"); Assert.That(object1PartLoaded.GroupPosition, Is.EqualTo(part1.GroupPosition), "object1 group position not equal"); Assert.That( object1PartLoaded.RotationOffset, Is.EqualTo(part1.RotationOffset), "object1 rotation offset not equal"); Assert.That( object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal"); TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItems(soundItemName)[0]; Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null"); AssetBase loadedSoundAsset = m_scene.AssetService.Get(loadedSoundItem.AssetID.ToString()); Assert.That(loadedSoundAsset, Is.Not.Null, "loaded sound asset was null"); Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match"); // Temporary Console.WriteLine("Successfully completed {0}", MethodBase.GetCurrentMethod()); }
public SceneObjectGroup GetRezReadySceneObject(TaskInventoryItem item) { AssetBase rezAsset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); if (null == rezAsset) { m_log.WarnFormat( "[PRIM INVENTORY]: Could not find asset {0} for inventory item {1} in {2}", item.AssetID, item.Name, m_part.Name); return(null); } string xmlData = Utils.BytesToString(rezAsset.Data); SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); group.ResetIDs(); SceneObjectPart rootPart = group.GetChildPart(group.UUID); // Since renaming the item in the inventory does not affect the name stored // in the serialization, transfer the correct name from the inventory to the // object itself before we rez. rootPart.Name = item.Name; rootPart.Description = item.Description; SceneObjectPart[] partList = group.Parts; group.SetGroup(m_part.GroupID, null); // TODO: Remove magic number badness if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number { if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions()) { foreach (SceneObjectPart part in partList) { if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) { part.EveryoneMask = item.EveryonePermissions; } if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) { part.NextOwnerMask = item.NextPermissions; } if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) { part.GroupMask = item.GroupPermissions; } } group.ApplyNextOwnerPermissions(); } } foreach (SceneObjectPart part in partList) { // TODO: Remove magic number badness if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number { part.LastOwnerID = part.OwnerID; part.OwnerID = item.OwnerID; part.Inventory.ChangeInventoryOwner(item.OwnerID); } if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) { part.EveryoneMask = item.EveryonePermissions; } if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) { part.NextOwnerMask = item.NextPermissions; } if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) { part.GroupMask = item.GroupPermissions; } } rootPart.TrimPermissions(); return(group); }
/// <summary> /// Retrieves the latest revision of a region in xml form, /// converts it to scene object groups and scene presences, /// swaps the current scene's entity list with the revision's list. /// Note: Since deleted objects while /// </summary> public void RollbackRegion(Scene scene) { System.Collections.ArrayList xmllist = null; SceneObjectGroup temp = null; System.Collections.Hashtable deleteListUUIDs = new Hashtable(); // Dictionary<LLUUID, EntityBase> SearchList = new Dictionary<LLUUID,EntityBase>(); Dictionary <UUID, EntityBase> ReplacementList = new Dictionary <UUID, EntityBase>(); int revision = m_database.GetMostRecentRevision(scene.RegionInfo.RegionID); // EntityBase[] searchArray; xmllist = m_database.GetRegionObjectXMLList(scene.RegionInfo.RegionID, revision); if (xmllist == null) { m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") does not have given revision number (" + revision + ")."); return; } m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") revision number (" + revision + ")."); m_log.Info("[CMMODEL]: Scene Objects = " + xmllist.Count); m_log.Info("[CMMODEL]: Converting scene entities list to specified revision."); m_log.ErrorFormat("[CMMODEL]: 1"); foreach (string xml in xmllist) { try { temp = SceneObjectSerializer.FromXml2Format(xml); temp.SetScene(scene); SceneObjectPart[] parts = temp.Parts; for (int i = 0; i < parts.Length; i++) { parts[i].RegionHandle = scene.RegionInfo.RegionHandle; } ReplacementList.Add(temp.UUID, (EntityBase)temp); } catch (Exception e) { m_log.Info("[CMMODEL]: Error while creating replacement list for rollback: " + e); } } //If in scene but not in revision and not a client, remove them while (true) { try { foreach (EntityBase entity in scene.GetEntities()) { if (entity == null) { continue; } if (entity is ScenePresence) { ReplacementList.Add(entity.UUID, entity); continue; } else //if (!ReplacementList.ContainsKey(entity.UUID)) { deleteListUUIDs.Add(entity.UUID, 0); } } } catch (Exception e) { m_log.ErrorFormat("[CMMODEL]: " + e); deleteListUUIDs.Clear(); ReplacementList.Clear(); continue; } break; } foreach (UUID uuid in deleteListUUIDs.Keys) { try { // I thought that the DeleteGroup() function would handle all of this, but it doesn't. I'm not sure WHAT it handles. ((SceneObjectGroup)scene.Entities[uuid]).DetachFromBackup(); scene.PhysicsScene.RemovePrim(((SceneObjectGroup)scene.Entities[uuid]).RootPart.PhysActor); scene.SendKillObject(scene.Entities[uuid].LocalId); scene.SceneGraph.DeleteSceneObject(uuid, false); ((SceneObjectGroup)scene.Entities[uuid]).DeleteGroupFromScene(false); } catch (Exception e) { m_log.ErrorFormat("[CMMODEL]: Error while removing objects from scene: " + e); } } lock (scene) { scene.Entities.Clear(); foreach (KeyValuePair <UUID, EntityBase> kvp in ReplacementList) { scene.Entities.Add(kvp.Value); } } foreach (EntityBase ent in ReplacementList.Values) { try { if (!(ent is SceneObjectGroup)) { continue; } if ((((SceneObjectGroup)ent).RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) == 0) { ((SceneObjectGroup)ent).ApplyPhysics(true); } ((SceneObjectGroup)ent).AttachToBackup(); ((SceneObjectGroup)ent).HasGroupChanged = true; // If not true, then attaching to backup does nothing because no change is detected. ((SceneObjectGroup)ent).ScheduleGroupForFullUpdate(); } catch (Exception e) { m_log.ErrorFormat("[CMMODEL]: Error while attaching new scene entities to backup and scheduling for a full update: " + e); } } m_log.Info("[CMMODEL]: Scheduling a backup of new scene object groups to backup."); scene.Backup(true); }
public void TestSerializeXml() { TestHelper.InMethod(); //log4net.Config.XmlConfigurator.Configure(); string rpName = "My Little Donkey"; UUID rpUuid = UUID.Parse("00000000-0000-0000-0000-000000000964"); UUID rpCreatorId = UUID.Parse("00000000-0000-0000-0000-000000000915"); PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere(); // Vector3 groupPosition = new Vector3(10, 20, 30); // Quaternion rotationOffset = new Quaternion(20, 30, 40, 50); // Vector3 offsetPosition = new Vector3(5, 10, 15); SceneObjectPart rp = new SceneObjectPart(); rp.UUID = rpUuid; rp.Name = rpName; rp.CreatorID = rpCreatorId; rp.Shape = shape; SceneObjectGroup so = new SceneObjectGroup(rp); // Need to add the object to the scene so that the request to get script state succeeds m_scene.AddSceneObject(so); string xml = SceneObjectSerializer.ToOriginalXmlFormat(so); XmlTextReader xtr = new XmlTextReader(new StringReader(xml)); xtr.ReadStartElement("SceneObjectGroup"); xtr.ReadStartElement("RootPart"); xtr.ReadStartElement("SceneObjectPart"); UUID uuid = UUID.Zero; string name = null; UUID creatorId = UUID.Zero; while (xtr.Read() && xtr.Name != "SceneObjectPart") { if (xtr.NodeType != XmlNodeType.Element) { continue; } switch (xtr.Name) { case "UUID": xtr.ReadStartElement("UUID"); try { uuid = UUID.Parse(xtr.ReadElementString("UUID")); xtr.ReadEndElement(); } catch { } // ignore everything but <UUID><UUID>...</UUID></UUID> break; case "Name": name = xtr.ReadElementContentAsString(); break; case "CreatorID": xtr.ReadStartElement("CreatorID"); creatorId = UUID.Parse(xtr.ReadElementString("UUID")); xtr.ReadEndElement(); break; } } xtr.ReadEndElement(); xtr.ReadEndElement(); xtr.ReadStartElement("OtherParts"); xtr.ReadEndElement(); xtr.Close(); // TODO: More checks Assert.That(uuid, Is.EqualTo(rpUuid)); Assert.That(name, Is.EqualTo(rpName)); Assert.That(creatorId, Is.EqualTo(rpCreatorId)); }
public void TestLoadOarV0_2() { TestHelper.InMethod(); //log4net.Config.XmlConfigurator.Configure(); MemoryStream archiveWriteStream = new MemoryStream(); TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream); // Put in a random blank directory to check that this doesn't upset the load process tar.WriteDir("ignoreme"); // Also check that direct entries which will also have a file entry containing that directory doesn't // upset load tar.WriteDir(ArchiveConstants.TERRAINS_PATH); tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestExecution.Create0p2ControlFile()); string part1Name = "object1"; PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder(); Vector3 groupPosition = new Vector3(90, 80, 70); Quaternion rotationOffset = new Quaternion(60, 70, 80, 90); Vector3 offsetPosition = new Vector3(20, 25, 30); SerialiserModule serialiserModule = new SerialiserModule(); ArchiverModule archiverModule = new ArchiverModule(); Scene scene = SceneSetupHelpers.SetupScene(); SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); SceneObjectPart part1 = new SceneObjectPart( UUID.Zero, shape, groupPosition, rotationOffset, offsetPosition); part1.Name = part1Name; SceneObjectGroup object1 = new SceneObjectGroup(part1); scene.AddNewSceneObject(object1, false); string object1FileName = string.Format( "{0}_{1:000}-{2:000}-{3:000}__{4}.xml", part1Name, Math.Round(groupPosition.X), Math.Round(groupPosition.Y), Math.Round(groupPosition.Z), part1.UUID); tar.WriteFile(ArchiveConstants.OBJECTS_PATH + object1FileName, SceneObjectSerializer.ToXml2Format(object1)); tar.Close(); MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); lock (this) { scene.EventManager.OnOarFileLoaded += LoadCompleted; archiverModule.DearchiveRegion(archiveReadStream); } Assert.That(m_lastErrorMessage, Is.Null); SceneObjectPart object1PartLoaded = scene.GetSceneObjectPart(part1Name); Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded"); Assert.That(object1PartLoaded.Name, Is.EqualTo(part1Name), "object1 names not identical"); Assert.That(object1PartLoaded.GroupPosition, Is.EqualTo(groupPosition), "object1 group position not equal"); Assert.That( object1PartLoaded.RotationOffset, Is.EqualTo(rotationOffset), "object1 rotation offset not equal"); Assert.That( object1PartLoaded.OffsetPosition, Is.EqualTo(offsetPosition), "object1 offset position not equal"); // Temporary Console.WriteLine("Successfully completed {0}", MethodBase.GetCurrentMethod()); }
public bool BuyObject(IClientAPI remoteClient, UUID categoryID, uint localID, byte saleType, int salePrice) { SceneObjectPart part = m_scene.GetSceneObjectPart(localID); if (part == null) { return(false); } SceneObjectGroup group = part.ParentGroup; if (group == null || group.IsDeleted || group.inTransit) { return(false); } // make sure we are not buying a child part part = group.RootPart; switch (saleType) { case 1: // Sell as original (in-place sale) uint effectivePerms = group.EffectiveOwnerPerms; if ((effectivePerms & (uint)PermissionMask.Transfer) == 0) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale"); } return(false); } group.SetOwner(remoteClient.AgentId, remoteClient.ActiveGroupId); if (m_scene.Permissions.PropagatePermissions()) { foreach (SceneObjectPart child in group.Parts) { child.Inventory.ChangeInventoryOwner(remoteClient.AgentId); child.TriggerScriptChangedEvent(Changed.OWNER); child.ApplyNextOwnerPermissions(); } group.InvalidateDeepEffectivePerms(); } part.ObjectSaleType = 0; part.SalePrice = 10; part.ClickAction = Convert.ToByte(0); group.HasGroupChanged = true; part.SendPropertiesToClient(remoteClient); part.TriggerScriptChangedEvent(Changed.OWNER); group.ResumeScripts(); part.ScheduleFullUpdate(); break; case 2: // Sell a copy uint perms = group.EffectiveOwnerPerms; if ((perms & (uint)PermissionMask.Transfer) == 0) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale"); } return(false); } if ((perms & (uint)PermissionMask.Copy) == 0) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "This sale has been blocked by the permissions system"); } return(false); } string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(group); AssetBase asset = m_scene.CreateAsset( group.GetPartName(localID), group.GetPartDescription(localID), (sbyte)AssetType.Object, Utils.StringToBytes(sceneObjectXml), group.OwnerID); m_scene.AssetService.Store(asset); InventoryItemBase item = new InventoryItemBase(); item.CreatorId = part.CreatorID.ToString(); item.CreatorData = part.CreatorData; item.ID = UUID.Random(); item.Owner = remoteClient.AgentId; item.AssetID = asset.FullID; item.Description = asset.Description; item.Name = asset.Name; item.AssetType = asset.Type; item.InvType = (int)InventoryType.Object; item.Folder = categoryID; perms = group.CurrentAndFoldedNextPermissions(); // apply parts inventory next perms PermissionsUtil.ApplyNoModFoldedPermissions(perms, ref perms); // change to next owner perms perms &= part.NextOwnerMask; // update folded perms = PermissionsUtil.FixAndFoldPermissions(perms); item.BasePermissions = perms; item.CurrentPermissions = perms; item.NextPermissions = part.NextOwnerMask & perms; item.EveryOnePermissions = part.EveryoneMask & perms; item.GroupPermissions = part.GroupMask & perms; item.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; item.CreationDate = Util.UnixTimeSinceEpoch(); if (m_scene.AddInventoryItem(item)) { remoteClient.SendInventoryItemCreateUpdate(item, 0); } else { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "Cannot buy now. Your inventory is unavailable"); } return(false); } break; case 3: // Sell contents List <UUID> invList = part.Inventory.GetInventoryList(); bool okToSell = true; foreach (UUID invID in invList) { TaskInventoryItem item1 = part.Inventory.GetInventoryItem(invID); if ((item1.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) { okToSell = false; break; } } if (!okToSell) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser( remoteClient, "This item's inventory doesn't appear to be for sale"); } return(false); } if (invList.Count > 0) { m_scene.MoveTaskInventoryItems(remoteClient.AgentId, part.Name, part, invList); } break; } return(true); }
/// 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) { // 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( "[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 uuid = filename.Remove(filename.Length - extension.Length); if (m_assetService.GetMetadata(uuid) != null) { // m_log.DebugFormat("[ARCHIVER]: found existing asset {0}",uuid); return(true); } if (ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension)) { sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; if (assetType == (sbyte)AssetType.Unknown) { m_log.WarnFormat("[ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, uuid); } else if (assetType == (sbyte)AssetType.Object) { data = SceneObjectSerializer.ModifySerializedObject(UUID.Parse(uuid), data, sog => { ModifySceneObject(m_rootScene, sog); return(true); }); if (data == null) { return(false); } } //m_log.DebugFormat("[ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType); AssetBase asset = new AssetBase(new UUID(uuid), String.Empty, assetType, UUID.Zero.ToString()); asset.Data = data; // We're relying on the asset service to do the sensible thing and not store the asset if it already // exists. m_assetService.Store(asset); /** * Create layers on decode for image assets. This is likely to significantly increase the time to load archives so * it might be best done when dearchive takes place on a separate thread * if (asset.Type=AssetType.Texture) * { * IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface<IJ2KDecoder>(); * if (cacheLayerDecode != null) * cacheLayerDecode.syncdecode(asset.FullID, asset.Data); * } */ return(true); } else { m_log.ErrorFormat( "[ARCHIVER]: Tried to dearchive data with path {0} with an unknown type extension {1}", assetPath, extension); return(false); } }
public ContentManagementEntity(string objectXML, Scene scene, bool physics) : base(objectXML, scene, false) { m_UnchangedEntity = SceneObjectSerializer.FromXml2Format(objectXML); }
public bool BuyObject(IClientAPI remoteClient, UUID categoryID, uint localID, byte saleType, int salePrice) { ISceneChildEntity part = m_scene.GetSceneObjectPart(localID); if (part == null) { return(false); } if (part.ParentEntity == null) { return(false); } ISceneEntity group = part.ParentEntity; ILLClientInventory inventoryModule = m_scene.RequestModuleInterface <ILLClientInventory>(); switch (saleType) { case 1: // Sell as original (in-place sale) uint effectivePerms = group.GetEffectivePermissions(); if ((effectivePerms & (uint)PermissionMask.Transfer) == 0) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale"); } return(false); } group.SetOwnerId(remoteClient.AgentId); group.SetRootPartOwner(part, remoteClient.AgentId, remoteClient.ActiveGroupId); if (m_scene.Permissions.PropagatePermissions()) { foreach (ISceneChildEntity child in group.ChildrenEntities()) { child.Inventory.ChangeInventoryOwner(remoteClient.AgentId); child.TriggerScriptChangedEvent(Changed.OWNER); child.ApplyNextOwnerPermissions(); } } part.ObjectSaleType = 0; part.SalePrice = 10; group.HasGroupChanged = true; part.GetProperties(remoteClient); part.TriggerScriptChangedEvent(Changed.OWNER); group.ResumeScripts(); part.ScheduleUpdate(PrimUpdateFlags.ForcedFullUpdate); break; case 2: // Sell a copy Vector3 inventoryStoredPosition = new Vector3 (((group.AbsolutePosition.X > m_scene.RegionInfo.RegionSizeX) ? m_scene.RegionInfo.RegionSizeX - 1 : group.AbsolutePosition.X) , (group.AbsolutePosition.X > m_scene.RegionInfo.RegionSizeY) ? m_scene.RegionInfo.RegionSizeY - 1 : group.AbsolutePosition.X, group.AbsolutePosition.Z); Vector3 originalPosition = group.AbsolutePosition; group.AbsolutePosition = inventoryStoredPosition; string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat((SceneObjectGroup)group); group.AbsolutePosition = originalPosition; uint perms = group.GetEffectivePermissions(); if ((perms & (uint)PermissionMask.Transfer) == 0) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale"); } return(false); } AssetBase asset = new AssetBase(UUID.Random(), part.Name, AssetType.Object, group.OwnerID) { Description = part.Description, Data = Utils.StringToBytes(sceneObjectXml) }; asset.ID = m_scene.AssetService.Store(asset); InventoryItemBase item = new InventoryItemBase { CreatorId = part.CreatorID.ToString(), CreatorData = part.CreatorData, ID = UUID.Random(), Owner = remoteClient.AgentId, AssetID = asset.ID, Description = asset.Description, Name = asset.Name, AssetType = asset.Type, InvType = (int)InventoryType.Object, Folder = categoryID }; uint nextPerms = (perms & 7) << 13; if ((nextPerms & (uint)PermissionMask.Copy) == 0) { perms &= ~(uint)PermissionMask.Copy; } if ((nextPerms & (uint)PermissionMask.Transfer) == 0) { perms &= ~(uint)PermissionMask.Transfer; } if ((nextPerms & (uint)PermissionMask.Modify) == 0) { perms &= ~(uint)PermissionMask.Modify; } item.BasePermissions = perms & part.NextOwnerMask; item.CurrentPermissions = perms & part.NextOwnerMask; item.NextPermissions = part.NextOwnerMask; item.EveryOnePermissions = part.EveryoneMask & part.NextOwnerMask; item.GroupPermissions = part.GroupMask & part.NextOwnerMask; item.CurrentPermissions |= 16; // Slam! item.CreationDate = Util.UnixTimeSinceEpoch(); if (inventoryModule != null) { if (inventoryModule.AddInventoryItem(item)) { remoteClient.SendInventoryItemCreateUpdate(item, 0); } else { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "Cannot buy now. Your inventory is unavailable"); } return(false); } } break; case 3: // Sell contents List <UUID> invList = part.Inventory.GetInventoryList(); #if (!ISWIN) bool okToSell = true; foreach (UUID invId in invList) { TaskInventoryItem item1 = part.Inventory.GetInventoryItem(invId); if ((item1.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) { okToSell = false; break; } } #else bool okToSell = invList.Select(invID => part.Inventory.GetInventoryItem(invID)).All(item1 => (item1.CurrentPermissions & (uint)PermissionMask.Transfer) != 0); #endif if (!okToSell) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser( remoteClient, "This item's inventory doesn't appear to be for sale"); } return(false); } if (invList.Count > 0) { if (inventoryModule != null) { inventoryModule.MoveTaskInventoryItemsToUserInventory(remoteClient.AgentId, part.Name, part, invList); } } break; } return(true); }
public bool BuyObject(IClientAPI remoteClient, UUID categoryID, uint localID, byte saleType, int salePrice) { SceneObjectPart part = m_scene.GetSceneObjectPart(localID); if (part == null) { return(false); } SceneObjectGroup group = part.ParentGroup; switch (saleType) { case 1: // Sell as original (in-place sale) uint effectivePerms = group.GetEffectivePermissions(); if ((effectivePerms & (uint)PermissionMask.Transfer) == 0) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale"); } return(false); } group.SetOwnerId(remoteClient.AgentId); group.SetRootPartOwner(part, remoteClient.AgentId, remoteClient.ActiveGroupId); if (m_scene.Permissions.PropagatePermissions()) { foreach (SceneObjectPart child in group.Parts) { child.Inventory.ChangeInventoryOwner(remoteClient.AgentId); child.TriggerScriptChangedEvent(Changed.OWNER); child.ApplyNextOwnerPermissions(); } } part.ObjectSaleType = 0; part.SalePrice = 10; group.HasGroupChanged = true; part.SendPropertiesToClient(remoteClient); part.TriggerScriptChangedEvent(Changed.OWNER); group.ResumeScripts(); part.ScheduleFullUpdate(); break; case 2: // Sell a copy Vector3 inventoryStoredPosition = new Vector3( Math.Min(group.AbsolutePosition.X, m_scene.RegionInfo.RegionSizeX - 6), Math.Min(group.AbsolutePosition.Y, m_scene.RegionInfo.RegionSizeY - 6), group.AbsolutePosition.Z); Vector3 originalPosition = group.AbsolutePosition; group.AbsolutePosition = inventoryStoredPosition; string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(group); group.AbsolutePosition = originalPosition; uint perms = group.GetEffectivePermissions(); if ((perms & (uint)PermissionMask.Transfer) == 0) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale"); } return(false); } AssetBase asset = m_scene.CreateAsset( group.GetPartName(localID), group.GetPartDescription(localID), (sbyte)AssetType.Object, Utils.StringToBytes(sceneObjectXml), group.OwnerID); m_scene.AssetService.Store(asset); InventoryItemBase item = new InventoryItemBase(); item.CreatorId = part.CreatorID.ToString(); item.CreatorData = part.CreatorData; item.ID = UUID.Random(); item.Owner = remoteClient.AgentId; item.AssetID = asset.FullID; item.Description = asset.Description; item.Name = asset.Name; item.AssetType = asset.Type; item.InvType = (int)InventoryType.Object; item.Folder = categoryID; PermissionsUtil.ApplyFoldedPermissions(perms, ref perms); item.BasePermissions = perms & part.NextOwnerMask; item.CurrentPermissions = perms & part.NextOwnerMask; item.NextPermissions = part.NextOwnerMask; item.EveryOnePermissions = part.EveryoneMask & part.NextOwnerMask; item.GroupPermissions = part.GroupMask & part.NextOwnerMask; item.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; item.CreationDate = Util.UnixTimeSinceEpoch(); if (m_scene.AddInventoryItem(item)) { remoteClient.SendInventoryItemCreateUpdate(item, 0); } else { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "Cannot buy now. Your inventory is unavailable"); } return(false); } break; case 3: // Sell contents List <UUID> invList = part.Inventory.GetInventoryList(); bool okToSell = true; foreach (UUID invID in invList) { TaskInventoryItem item1 = part.Inventory.GetInventoryItem(invID); if ((item1.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) { okToSell = false; break; } } if (!okToSell) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser( remoteClient, "This item's inventory doesn't appear to be for sale"); } return(false); } if (invList.Count > 0) { m_scene.MoveTaskInventoryItems(remoteClient.AgentId, part.Name, part, invList); } break; } return(true); }
private List <SceneObjectGroup> RezMultipleObjectsFromInventory(XmlNodeList nodes, UUID itemId, IClientAPI remoteClient, Vector3 pos, bool RezSelected, InventoryItemBase item, UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, Vector3 RayEnd, Vector3 RayStart, byte bRayEndIsIntersection) { Vector3 OldMiddlePos = Vector3.Zero; List <SceneObjectGroup> NewGroup = new List <SceneObjectGroup>(); foreach (System.Xml.XmlNode aPrimNode in nodes) { if (aPrimNode.OuterXml.StartsWith("<middle>")) { string Position = aPrimNode.OuterXml.Remove(0, 13); Position = Position.Remove(Position.Length - 16, 16); string[] XYZ = Position.Split(' '); OldMiddlePos = new Vector3(float.Parse(XYZ[0]), float.Parse(XYZ[1]), float.Parse(XYZ[2])); continue; } SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(aPrimNode.OuterXml, m_scene); if (group == null) { return(null); } group.IsDeleted = false; group.m_isLoaded = true; foreach (SceneObjectPart part in group.ChildrenList) { part.IsLoading = false; } NewGroup.Add(group); string reason; if (!m_scene.Permissions.CanRezObject( group.ChildrenList.Count, remoteClient.AgentId, pos, out reason)) { // The client operates in no fail mode. It will // have already removed the item from the folder // if it's no copy. // Put it back if it's not an attachment // if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)) { remoteClient.SendBulkUpdateInventory(item); } return(null); } if (RezSelected) { group.RootPart.AddFlag(PrimFlags.CreateSelected); } // If we're rezzing an attachment then don't ask AddNewSceneObject() to update the client since // we'll be doing that later on. Scheduling more than one full update during the attachment // process causes some clients to fail to display the attachment properly. m_scene.SceneGraph.AddPrimToScene(group); // m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z); // if attachment we set it's asset id so object updates can reflect that // if not, we set it's position in world. float offsetHeight = 0; pos = m_scene.SceneGraph.GetNewRezLocation( RayStart, RayEnd, RayTargetID, Quaternion.Identity, BypassRayCast, bRayEndIsIntersection, true, group.GetAxisAlignedBoundingBox(out offsetHeight), false); pos.Z += offsetHeight; //group.AbsolutePosition = pos; // m_log.InfoFormat("rezx point for inventory rezz is {0} {1} {2} and offsetheight was {3}", pos.X, pos.Y, pos.Z, offsetHeight); SceneObjectPart rootPart = (SceneObjectPart)group.GetChildPart(group.UUID); // Since renaming the item in the inventory does not affect the name stored // in the serialization, transfer the correct name from the inventory to the // object itself before we rez. rootPart.Name = item.Name; rootPart.Description = item.Description; List <SceneObjectPart> partList = new List <SceneObjectPart>(group.ChildrenList); group.SetGroup(remoteClient.ActiveGroupId, remoteClient); item.Owner = remoteClient.AgentId; if (rootPart.OwnerID != item.Owner) { //Need to kill the for sale here rootPart.ObjectSaleType = 0; rootPart.SalePrice = 10; if (m_scene.Permissions.PropagatePermissions()) { if ((item.CurrentPermissions & 8) != 0) { foreach (SceneObjectPart part in partList) { part.EveryoneMask = item.EveryOnePermissions; part.NextOwnerMask = item.NextPermissions; part.GroupMask = 0; // DO NOT propagate here } } group.ApplyNextOwnerPermissions(); } } foreach (SceneObjectPart part in partList) { if (part.OwnerID != item.Owner) { part.LastOwnerID = part.OwnerID; part.OwnerID = item.Owner; part.Inventory.ChangeInventoryOwner(item.Owner); } else if ((item.CurrentPermissions & 8) != 0) // Slam! { part.EveryoneMask = item.EveryOnePermissions; part.NextOwnerMask = item.NextPermissions; part.GroupMask = 0; // DO NOT propagate here } } rootPart.TrimPermissions(); if (group.RootPart.Shape.PCode == (byte)PCode.Prim) { group.ClearPartAttachmentData(); } // Fire on_rez group.CreateScriptInstances(0, true, 0, UUID.Zero); rootPart.ParentGroup.ResumeScripts(); if (!m_scene.Permissions.BypassPermissions()) { if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) { // If this is done on attachments, no // copy ones will be lost, so avoid it // List <UUID> uuids = new List <UUID>(); uuids.Add(item.ID); m_scene.InventoryService.DeleteItems(item.Owner, uuids); } } } foreach (SceneObjectGroup group in NewGroup) { if (OldMiddlePos != Vector3.Zero) { Vector3 NewPosOffset = Vector3.Zero; NewPosOffset.X = group.AbsolutePosition.X - OldMiddlePos.X; NewPosOffset.Y = group.AbsolutePosition.Y - OldMiddlePos.Y; NewPosOffset.Z = group.AbsolutePosition.Z - OldMiddlePos.Z; group.AbsolutePosition = pos + NewPosOffset; } group.ScheduleGroupUpdate(PrimUpdateFlags.FullUpdate); } return(NewGroup); }
/// <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); }
public virtual SceneObjectGroup RezObject( IClientAPI remoteClient, InventoryItemBase item, UUID assetID, Vector3 RayEnd, Vector3 RayStart, UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) { AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString()); if (rezAsset == null) { if (item != null) { m_log.WarnFormat( "[InventoryAccessModule]: Could not find asset {0} for item {1} {2} for {3} in RezObject()", assetID, item.Name, item.ID, remoteClient.Name); } else { m_log.WarnFormat( "[INVENTORY ACCESS MODULE]: Could not find asset {0} for {1} in RezObject()", assetID, remoteClient.Name); } return(null); } SceneObjectGroup group = null; string xmlData = Utils.BytesToString(rezAsset.Data); List <SceneObjectGroup> objlist = new List <SceneObjectGroup>(); List <Vector3> veclist = new List <Vector3>(); byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); Vector3 pos; XmlDocument doc = new XmlDocument(); doc.LoadXml(xmlData); XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); if (e == null || attachment) // Single { SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); objlist.Add(g); veclist.Add(Vector3.Zero); float offsetHeight = 0; pos = m_Scene.GetNewRezLocation( RayStart, RayEnd, RayTargetID, Quaternion.Identity, BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false); pos.Z += offsetHeight; } else { XmlElement coll = (XmlElement)e; float bx = Convert.ToSingle(coll.GetAttribute("x")); float by = Convert.ToSingle(coll.GetAttribute("y")); float bz = Convert.ToSingle(coll.GetAttribute("z")); Vector3 bbox = new Vector3(bx, by, bz); pos = m_Scene.GetNewRezLocation(RayStart, RayEnd, RayTargetID, Quaternion.Identity, BypassRayCast, bRayEndIsIntersection, true, bbox, false); pos -= bbox / 2; XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); foreach (XmlNode n in groups) { SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); objlist.Add(g); XmlElement el = (XmlElement)n; string rawX = el.GetAttribute("offsetx"); string rawY = el.GetAttribute("offsety"); string rawZ = el.GetAttribute("offsetz"); // // m_log.DebugFormat( // "[INVENTORY ACCESS MODULE]: Converting coalesced object {0} offset <{1}, {2}, {3}>", // g.Name, rawX, rawY, rawZ); float x = Convert.ToSingle(rawX); float y = Convert.ToSingle(rawY); float z = Convert.ToSingle(rawZ); veclist.Add(new Vector3(x, y, z)); } } if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, veclist, attachment)) { return(null); } for (int i = 0; i < objlist.Count; i++) { group = objlist[i]; // m_log.DebugFormat( // "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", // group.Name, group.LocalId, group.UUID, // group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask, // remoteClient.Name); // Vector3 storedPosition = group.AbsolutePosition; if (group.UUID == UUID.Zero) { m_log.Debug("[INVENTORY ACCESS MODULE]: Object has UUID.Zero! Position 3"); } // if this was previously an attachment and is now being rezzed, // save the old attachment info. if (group.IsAttachment == false && group.RootPart.Shape.State != 0) { group.RootPart.AttachedPos = group.AbsolutePosition; group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint; } foreach (SceneObjectPart part in group.Parts) { // Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset. part.LastOwnerID = part.OwnerID; part.OwnerID = remoteClient.AgentId; } if (!attachment) { // If it's rezzed in world, select it. Much easier to // find small items. // foreach (SceneObjectPart part in group.Parts) { part.CreateSelected = true; } } group.ResetIDs(); if (attachment) { group.RootPart.Flags |= PrimFlags.Phantom; group.IsAttachment = true; } // If we're rezzing an attachment then don't ask // AddNewSceneObject() to update the client since // we'll be doing that later on. Scheduling more than // one full update during the attachment // process causes some clients to fail to display the // attachment properly. m_Scene.AddNewSceneObject(group, true, false); // if attachment we set it's asset id so object updates // can reflect that, if not, we set it's position in world. if (!attachment) { group.ScheduleGroupForFullUpdate(); group.AbsolutePosition = pos + veclist[i]; } group.SetGroup(remoteClient.ActiveGroupId, remoteClient); if (!attachment) { SceneObjectPart rootPart = group.RootPart; if (rootPart.Shape.PCode == (byte)PCode.Prim) { group.ClearPartAttachmentData(); } // Fire on_rez group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); rootPart.ParentGroup.ResumeScripts(); rootPart.ScheduleFullUpdate(); } // m_log.DebugFormat( // "[INVENTORY ACCESS MODULE]: Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", // group.Name, group.LocalId, group.UUID, // group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask, // remoteClient.Name); } if (item != null) { DoPostRezWhenFromItem(item, attachment); } return(group); }
/// <summary> /// Takes an XML description of a scene object group and converts it to a meta entity. /// </summary> public MetaEntity(string objectXML, Scene scene, bool physics) { m_Entity = SceneObjectSerializer.FromXml2Format(objectXML); m_Entity.SetScene(scene); Initialize(physics); }
/// <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); }
protected virtual void ReadBackup(IScene scene) { MainConsole.Instance.Debug("[FileBasedSimulationData]: Reading file for " + scene.RegionInfo.RegionName); List <uint> foundLocalIDs = new List <uint>(); var stream = ArchiveHelpers.GetStream((m_loadDirectory == "" || m_loadDirectory == "/") ? m_fileName : Path.Combine(m_loadDirectory, m_fileName)); if (stream == null) { lock (m_saveLock) { if (!m_shutdown) { SaveBackup(m_saveDirectory, false); } } return; } GZipStream m_loadStream = new GZipStream(stream, CompressionMode.Decompress); TarArchiveReader reader = new TarArchiveReader(m_loadStream); byte[] data; string filePath; TarArchiveReader.TarEntryType entryType; System.Collections.Concurrent.ConcurrentQueue <byte[]> groups = new System.Collections.Concurrent.ConcurrentQueue <byte[]>(); //Load the archive data that we need while ((data = reader.ReadEntry(out filePath, out entryType)) != null) { if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType) { continue; } if (filePath.StartsWith("parcels/")) { //Only use if we are not merging LandData parcel = new LandData(); OSD parcelData = OSDParser.DeserializeLLSDBinary(data); parcel.FromOSD((OSDMap)parcelData); m_parcels.Add(parcel); } else if (filePath.StartsWith("terrain/")) { m_oldstyleterrain = data; } else if (filePath.StartsWith("revertterrain/")) { m_oldstylerevertTerrain = data; } else if (filePath.StartsWith("newstyleterrain/")) { m_terrain = data; } else if (filePath.StartsWith("newstylerevertterrain/")) { m_revertTerrain = data; } else if (filePath.StartsWith("newstylewater/")) { m_water = data; } else if (filePath.StartsWith("newstylerevertwater/")) { m_revertWater = data; } else if (filePath.StartsWith("entities/")) { MemoryStream ms = new MemoryStream(data); SceneObjectGroup sceneObject = SceneObjectSerializer.FromXml2Format(ref ms, scene); ms.Close(); ms = null; data = null; foreach (ISceneChildEntity part in sceneObject.ChildrenEntities()) { if (!foundLocalIDs.Contains(part.LocalId)) { foundLocalIDs.Add(part.LocalId); } else { part.LocalId = 0; //Reset it! Only use it once! } } m_groups.Add(sceneObject); } data = null; } m_loadStream.Close(); m_loadStream = null; foundLocalIDs.Clear(); GC.Collect(); }
/// <summary> /// Rez an object into the scene from the user's inventory /// </summary> /// <remarks> /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing /// things to the scene. The caller should be doing that, I think. /// </remarks> /// <param name="remoteClient"></param> /// <param name="itemID"></param> /// <param name="RayEnd"></param> /// <param name="RayStart"></param> /// <param name="RayTargetID"></param> /// <param name="BypassRayCast"></param> /// <param name="RayEndIsIntersection"></param> /// <param name="RezSelected"></param> /// <param name="RemoveItem"></param> /// <param name="fromTaskID"></param> /// <param name="attachment"></param> /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful.</returns> public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) { // m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID); byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f); Vector3 pos = m_Scene.GetNewRezLocation( RayStart, RayEnd, RayTargetID, Quaternion.Identity, BypassRayCast, bRayEndIsIntersection, true, scale, false); // Rez object InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = m_Scene.InventoryService.GetItem(item); if (item != null) { item.Owner = remoteClient.AgentId; AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString()); SceneObjectGroup group = null; if (rezAsset != null) { UUID itemId = UUID.Zero; // If we have permission to copy then link the rezzed object back to the user inventory // item that it came from. This allows us to enable 'save object to inventory' if (!m_Scene.Permissions.BypassPermissions()) { if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) { itemId = item.ID; } } else { if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) { // Brave new fullperm world itemId = item.ID; } } string xmlData = Utils.BytesToString(rezAsset.Data); List <SceneObjectGroup> objlist = new List <SceneObjectGroup>(); List <Vector3> veclist = new List <Vector3>(); XmlDocument doc = new XmlDocument(); doc.LoadXml(xmlData); XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); if (e == null || attachment) // Single { SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat( itemId, xmlData); objlist.Add(g); veclist.Add(new Vector3(0, 0, 0)); float offsetHeight = 0; pos = m_Scene.GetNewRezLocation( RayStart, RayEnd, RayTargetID, Quaternion.Identity, BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false); pos.Z += offsetHeight; } else { XmlElement coll = (XmlElement)e; float bx = Convert.ToSingle(coll.GetAttribute("x")); float by = Convert.ToSingle(coll.GetAttribute("y")); float bz = Convert.ToSingle(coll.GetAttribute("z")); Vector3 bbox = new Vector3(bx, by, bz); pos = m_Scene.GetNewRezLocation(RayStart, RayEnd, RayTargetID, Quaternion.Identity, BypassRayCast, bRayEndIsIntersection, true, bbox, false); pos -= bbox / 2; XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); foreach (XmlNode n in groups) { SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat( itemId, n.OuterXml); objlist.Add(g); XmlElement el = (XmlElement)n; string rawX = el.GetAttribute("offsetx"); string rawY = el.GetAttribute("offsety"); string rawZ = el.GetAttribute("offsetz"); // // m_log.DebugFormat( // "[INVENTORY ACCESS MODULE]: Converting coalesced object {0} offset <{1}, {2}, {3}>", // g.Name, rawX, rawY, rawZ); float x = Convert.ToSingle(rawX); float y = Convert.ToSingle(rawY); float z = Convert.ToSingle(rawZ); veclist.Add(new Vector3(x, y, z)); } } int primcount = 0; foreach (SceneObjectGroup g in objlist) { primcount += g.PrimCount; } if (!m_Scene.Permissions.CanRezObject( primcount, remoteClient.AgentId, pos) && !attachment) { // The client operates in no fail mode. It will // have already removed the item from the folder // if it's no copy. // Put it back if it's not an attachment // if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment)) { remoteClient.SendBulkUpdateInventory(item); } return(null); } for (int i = 0; i < objlist.Count; i++) { group = objlist[i]; Vector3 storedPosition = group.AbsolutePosition; if (group.UUID == UUID.Zero) { m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 3"); } group.RootPart.FromFolderID = item.Folder; // If it's rezzed in world, select it. Much easier to // find small items. // if (!attachment) { group.RootPart.CreateSelected = true; foreach (SceneObjectPart child in group.Parts) { child.CreateSelected = true; } } group.ResetIDs(); if (attachment) { group.RootPart.Flags |= PrimFlags.Phantom; group.RootPart.IsAttachment = true; } // If we're rezzing an attachment then don't ask // AddNewSceneObject() to update the client since // we'll be doing that later on. Scheduling more than // one full update during the attachment // process causes some clients to fail to display the // attachment properly. m_Scene.AddNewSceneObject(group, true, false); // if attachment we set it's asset id so object updates // can reflect that, if not, we set it's position in world. if (!attachment) { group.ScheduleGroupForFullUpdate(); group.AbsolutePosition = pos + veclist[i]; } else { group.SetFromItemID(itemID); } SceneObjectPart rootPart = null; try { rootPart = group.GetChildPart(group.UUID); } catch (NullReferenceException) { string isAttachment = ""; if (attachment) { isAttachment = " Object was an attachment"; } m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment); } // Since renaming the item in the inventory does not // affect the name stored in the serialization, transfer // the correct name from the inventory to the // object itself before we rez. // // Only do these for the first object if we are rezzing a coalescence. if (i == 0) { rootPart.Name = item.Name; rootPart.Description = item.Description; rootPart.ObjectSaleType = item.SaleType; rootPart.SalePrice = item.SalePrice; } group.SetGroup(remoteClient.ActiveGroupId, remoteClient); if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) { //Need to kill the for sale here rootPart.ObjectSaleType = 0; rootPart.SalePrice = 10; if (m_Scene.Permissions.PropagatePermissions()) { foreach (SceneObjectPart part in group.Parts) { if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) { part.EveryoneMask = item.EveryOnePermissions; part.NextOwnerMask = item.NextPermissions; } part.GroupMask = 0; // DO NOT propagate here } group.ApplyNextOwnerPermissions(); } } foreach (SceneObjectPart part in group.Parts) { if ((part.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) { part.LastOwnerID = part.OwnerID; part.OwnerID = item.Owner; part.Inventory.ChangeInventoryOwner(item.Owner); part.GroupMask = 0; // DO NOT propagate here } part.EveryoneMask = item.EveryOnePermissions; part.NextOwnerMask = item.NextPermissions; } rootPart.TrimPermissions(); if (!attachment) { if (group.RootPart.Shape.PCode == (byte)PCode.Prim) { group.ClearPartAttachmentData(); } // Fire on_rez group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); rootPart.ParentGroup.ResumeScripts(); rootPart.ScheduleFullUpdate(); } } if (!m_Scene.Permissions.BypassPermissions()) { if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) { // If this is done on attachments, no // copy ones will be lost, so avoid it // if (!attachment) { List <UUID> uuids = new List <UUID>(); uuids.Add(item.ID); m_Scene.InventoryService.DeleteItems(item.Owner, uuids); } } } } return(group); } return(null); }
/// <summary> /// Add a scene object as a new attachment in the user inventory. /// </summary> /// <param name="remoteClient"></param> /// <param name="grp"></param> /// <returns>The user inventory item created that holds the attachment.</returns> private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IScenePresence sp, SceneObjectGroup grp) { // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", // grp.Name, grp.LocalId, remoteClient.Name); Vector3 inventoryStoredPosition = new Vector3 (((grp.AbsolutePosition.X > (int)Constants.RegionSize) ? Constants.RegionSize - 6 : grp.AbsolutePosition.X) , (grp.AbsolutePosition.Y > (int)Constants.RegionSize) ? Constants.RegionSize - 6 : grp.AbsolutePosition.Y, grp.AbsolutePosition.Z); Vector3 originalPosition = grp.AbsolutePosition; grp.AbsolutePosition = inventoryStoredPosition; // 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. string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false); grp.AbsolutePosition = originalPosition; AssetBase asset = m_scene.CreateAsset( grp.GetPartName(grp.LocalId), grp.GetPartDescription(grp.LocalId), (sbyte)AssetType.Object, Utils.StringToBytes(sceneObjectXml), sp.UUID); m_scene.AssetService.Store(asset); InventoryItemBase item = new InventoryItemBase(); item.CreatorId = grp.RootPart.CreatorID.ToString(); item.CreatorData = grp.RootPart.CreatorData; item.Owner = sp.UUID; item.ID = UUID.Random(); item.AssetID = asset.FullID; item.Description = asset.Description; item.Name = asset.Name; item.AssetType = asset.Type; item.InvType = (int)InventoryType.Object; InventoryFolderBase folder = m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); if (folder != null) { item.Folder = folder.ID; } else // oopsies { item.Folder = UUID.Zero; } if ((sp.UUID != grp.RootPart.OwnerID) && m_scene.Permissions.PropagatePermissions()) { item.BasePermissions = grp.RootPart.NextOwnerMask; item.CurrentPermissions = grp.RootPart.NextOwnerMask; item.NextPermissions = grp.RootPart.NextOwnerMask; item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask; item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask; } else { item.BasePermissions = grp.RootPart.BaseMask; item.CurrentPermissions = grp.RootPart.OwnerMask; item.NextPermissions = grp.RootPart.NextOwnerMask; item.EveryOnePermissions = grp.RootPart.EveryoneMask; item.GroupPermissions = grp.RootPart.GroupMask; } item.CreationDate = Util.UnixTimeSinceEpoch(); // sets itemID so client can show item as 'attached' in inventory grp.SetFromItemID(item.ID); if (m_scene.AddInventoryItem(item)) { sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0); } else { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(sp.ControllingClient, "Operation failed"); } } return(item); }
public ISceneEntity GetRezReadySceneObject(TaskInventoryItem item) { AssetBase rezAsset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); if (null == rezAsset) { m_log.WarnFormat( "[PRIM INVENTORY]: Could not find asset {0} for inventory item {1} in {2}", item.AssetID, item.Name, m_part.Name); return(null); } string xmlData = Utils.BytesToString(rezAsset.Data); SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData, m_part.ParentGroup.Scene); if (group == null) { return(null); } group.IsDeleted = false; group.m_isLoaded = true; foreach (SceneObjectPart part in group.ChildrenList) { part.IsLoading = false; } //Reset IDs, etc m_part.ParentGroup.Scene.SceneGraph.PrepPrimForAdditionToScene(group); SceneObjectPart rootPart = (SceneObjectPart)group.GetChildPart(group.UUID); // Since renaming the item in the inventory does not affect the name stored // in the serialization, transfer the correct name from the inventory to the // object itself before we rez. rootPart.Name = item.Name; rootPart.Description = item.Description; SceneObjectPart[] partList = group.Parts; group.SetGroup(m_part.GroupID, null); if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) { if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions()) { foreach (SceneObjectPart part in partList) { part.EveryoneMask = item.EveryonePermissions; part.NextOwnerMask = item.NextPermissions; } group.ApplyNextOwnerPermissions(); } } foreach (SceneObjectPart part in partList) { if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) { part.LastOwnerID = part.OwnerID; part.OwnerID = item.OwnerID; part.Inventory.ChangeInventoryOwner(item.OwnerID); } part.EveryoneMask = item.EveryonePermissions; part.NextOwnerMask = item.NextPermissions; } rootPart.TrimPermissions(); return(group); }
/// <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)) { m_log.ErrorFormat( "[INVENTORY ARCHIVER]: Tried to dearchive data with path {0} with an unknown type extension {1}", assetPath, extension); return(false); } 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); return(false); } if (assetType == (sbyte)AssetType.Object) { UUID owner = m_userInfo.PrincipalID; bool doCreatorID = m_creatorIdForAssetId.ContainsKey(assetId); data = SceneObjectSerializer.ModifySerializedObject(assetId, data, sog => { foreach (SceneObjectPart sop in sog.Parts) { sop.OwnerID = owner; if (doCreatorID && string.IsNullOrEmpty(sop.CreatorData)) { sop.CreatorID = m_creatorIdForAssetId[assetId]; } foreach (TaskInventoryItem it in sop.Inventory.GetInventoryItems()) { it.OwnerID = owner; if (string.IsNullOrEmpty(it.CreatorData) && m_creatorIdForAssetId.ContainsKey(it.AssetID)) { it.CreatorID = m_creatorIdForAssetId[it.AssetID]; } } } return(true); }); if (data == null) { return(false); } } //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); }
/// <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); } }