public void TestLoadIarV0_1AbsentCreator() { TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password"); m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "password", m_iarStream); InventoryItemBase foundItem1 = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); Assert.That( foundItem1.CreatorId, Is.EqualTo(m_uaMT.PrincipalID.ToString()), "Loaded item non-uuid creator doesn't match that of the loading user"); Assert.That( foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaMT.PrincipalID), "Loaded item uuid creator doesn't match that of the loading user"); AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); string xmlData = Utils.BytesToString(asset1.Data); SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaMT.PrincipalID)); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- private SceneObjectGroup GetRezReadySceneObject(UUID assetID, string name, string description, UUID ownerID, UUID groupID) { AssetBase rezAsset = m_scene.AssetService.Get(assetID.ToString()); if (rezAsset == null) { m_log.WarnFormat("[ObjectHandlers] Could not find asset {0}", assetID.ToString()); return(null); } string xmlData = Utils.BytesToString(rezAsset.Data); SceneObjectGroup group = (SceneObjectGroup)SceneObjectSerializer.FromOriginalXmlFormat(xmlData); if (group == null) { m_log.WarnFormat("[ObjectHandlers] Failed to decode asset {0}", assetID.ToString()); return(null); } group.ResetIDs(); group.SetGroup(groupID, null); // SceneObjectPart rootPart = group.GetPart(group.UUID); group.RootPart.Name = name; group.RootPart.Description = description; foreach (SceneObjectPart part in group.Parts) { part.LastOwnerID = ownerID; part.OwnerID = ownerID; part.Inventory.ChangeInventoryOwner(ownerID); } return(group); }
protected virtual void Display() { // m_log.InfoFormat("[WATER WARS]: Rezzing decorator {0} at {1}", m_itemName, m_positionToDisplay); TaskInventoryItem item = GetItem(m_itemStoreView, m_itemName); // we're only doing this beforehand so that we can get the rotation (since the existing RezObject() doesn't // retain it. FIXME FIXME FIXME AssetBase objectAsset = m_scene.AssetService.Get(item.AssetID.ToString()); string xml = Utils.BytesToString(objectAsset.Data); SceneObjectGroup originalSog = SceneObjectSerializer.FromOriginalXmlFormat(xml); // m_log.DebugFormat("[WATER WARS]: Using rotation {0} for decorator {1}", originalSog.GroupRotation, m_itemName); SceneObjectGroup so = m_scene.RezObject( m_itemStoreView.RootPart, item, m_positionToDisplay, originalSog.GroupRotation, Vector3.Zero, 0); base.Initialize(so); // We can only reposition after we've passed the scene object up to the parent class // so.AbsolutePosition = FindOnGroundPosition(so); // FIXME: We have to do this manually right now but really it's the responsibilty of OpenSim. // so.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 0); // Console.Write( // string.Format( // "[WATER WARS]: {0}, local ID {1}, textures {2}", // item.Name, so.RootPart.LocalId, so.RootPart.Shape.Textures)); }
/// <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> private void GetSceneObjectAssetUuids(UUID sceneObjectUuid, IDictionary <UUID, AssetType> assetUuids) { AssetBase objectAsset = GetAsset(sceneObjectUuid); if (null != objectAsset) { string xml = Utils.BytesToString(objectAsset.Data); CoalescedSceneObjects coa; if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa)) { foreach (SceneObjectGroup sog in coa.Objects) { GatherAssetUuids(sog, assetUuids); } } else { SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml); if (null != sog) { GatherAssetUuids(sog, assetUuids); } } } }
public void TestLoadIarCreatorAccountPresent() { TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood"); m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "meowfood", m_iarStream); InventoryItemBase foundItem1 = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_item1Name); Assert.That( foundItem1.CreatorId, Is.EqualTo(m_uaLL1.PrincipalID.ToString()), "Loaded item non-uuid creator doesn't match original"); Assert.That( foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL1.PrincipalID), "Loaded item uuid creator doesn't match original"); Assert.That(foundItem1.Owner, Is.EqualTo(m_uaLL1.PrincipalID), "Loaded item owner doesn't match inventory reciever"); AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); string xmlData = Utils.BytesToString(asset1.Data); SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID)); }
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); 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); }
protected virtual SceneObjectGroup CreateObjectFromInventory(InventoryItemBase item, IClientAPI remoteClient, UUID itemID, out System.Xml.XmlDocument doc) { if (item != null) { item.Owner = remoteClient.AgentId; AssetBase rezAsset = m_scene.AssetService.Get(item.AssetID.ToString()); 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) { itemId = item.ID; } } else { // Brave new fullperm world // itemId = item.ID; } string xmlData = Utils.BytesToString(rezAsset.Data); doc = new System.Xml.XmlDocument(); doc.LoadXml(xmlData); if (doc.FirstChild.OuterXml.StartsWith("<groups>")) { //We don't do multiple objects here return(null); } SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(itemId, doc.FirstChild.OuterXml, m_scene); if (group == null) { return(group); } group.IsDeleted = false; group.m_isLoaded = true; foreach (SceneObjectPart part in group.ChildrenList) { part.IsLoading = false; } return(group); } } doc = null; return(null); }
protected virtual SceneObjectGroup CreateObjectFromInventory(IClientAPI remoteClient, UUID itemID, UUID assetID, out XmlDocument doc) { AssetBase rezAsset = m_scene.AssetService.Get(assetID.ToString()); if (rezAsset != null) { string xmlData = Utils.BytesToString(rezAsset.Data); doc = new XmlDocument(); try { doc.LoadXml(xmlData); } catch { return(null); } if (doc.FirstChild.OuterXml.StartsWith("<groups>") || (doc.FirstChild.NextSibling != null && doc.FirstChild.NextSibling.OuterXml.StartsWith("<groups>"))) { //We don't do multiple objects here return(null); } string xml = ""; if (doc.FirstChild.NodeType == XmlNodeType.XmlDeclaration) { if (doc.FirstChild.NextSibling != null) { xml = doc.FirstChild.NextSibling.OuterXml; } } else { xml = doc.FirstChild.OuterXml; } SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(itemID, xml, m_scene); if (group == null) { return(null); } group.IsDeleted = false; group.m_isLoaded = true; foreach (SceneObjectPart part in group.ChildrenList) { part.IsLoading = false; } return(group); } doc = null; return(null); }
/// <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) { string xml = Utils.BytesToString(objectAsset.Data); SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml); GatherAssetUuids(sog, assetUuids); } }
public void TestDeserializeXml() { TestHelper.InMethod(); //log4net.Config.XmlConfigurator.Configure(); SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(xml); 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("PrimMyRide")); // 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, AssetType> assetUuids, IRegistryCore scene) { AssetBase objectAsset = GetAsset(sceneObjectUuid); if (null != objectAsset) { string xml = Utils.BytesToString(objectAsset.Data); SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xml, scene); if (group == null) { return; } GatherAssetUuids(group, assetUuids, scene); } }
public void TestDeserializeXmlObjectWithNoOtherParts() { TestHelpers.InMethod(); TestHelpers.EnableLogging(); SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(ObjectWithNoOtherPartsXml); 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("PrimMyRide")); OSDMap store = rootPart.DynAttrs.GetStore("MyNamespace", "MyStore"); Assert.AreEqual(42, store["the answer"].AsInteger()); // TODO: Check other properties }
private Dictionary <UUID, bool> SniffUUIDs(AssetBase asset) { Dictionary <UUID, bool> uuids = new Dictionary <UUID, bool>(); if ((asset != null) && ((AssetType)asset.Type == AssetType.Object)) { string ass_str = Utils.BytesToString(asset.Data); SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(ass_str); SniffTextureUUIDs(uuids, sog); // We need to sniff further... SniffTaskInventoryUUIDs(uuids, sog); } return(uuids); }
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); } } }
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 }
/// <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> /// Rez an object into the scene from the user's inventory /// </summary> /// 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. /// <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) { // Work out position details byte bRayEndIsIntersection = (byte)0; if (RayEndIsIntersection) { bRayEndIsIntersection = (byte)1; } else { bRayEndIsIntersection = (byte)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) { AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString()); 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) { itemId = item.ID; } } else { // Brave new fullperm world // itemId = item.ID; } string xmlData = Utils.BytesToString(rezAsset.Data); SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData); if (!m_Scene.Permissions.CanRezObject( group.Children.Count, 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); } group.ResetIDs(); if (attachment) { group.RootPart.ObjectFlags |= (uint)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); // 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. if (!attachment) { group.ScheduleGroupForFullUpdate(); float offsetHeight = 0; pos = m_Scene.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); } 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. rootPart.Name = item.Name; rootPart.Description = item.Description; List <SceneObjectPart> partList = new List <SceneObjectPart>(group.Children.Values); group.SetGroup(remoteClient.ActiveGroupId, remoteClient); 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) && (!attachment)) // Slam! { part.EveryoneMask = item.EveryOnePermissions; part.NextOwnerMask = item.NextPermissions; part.GroupMask = 0; // DO NOT propagate here } } rootPart.TrimPermissions(); if (!attachment) { if (group.RootPart.Shape.PCode == (byte)PCode.Prim) { group.ClearPartAttachmentData(); } // Fire on_rez group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 0); 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(rootPart.ParentGroup); } } return(null); }
/// <summary> /// Change the scene object in-world that represents this view. /// </summary> public virtual void ChangeSceneObject(AbstractView newObjectContainer, string newObjectName) { SceneObjectGroup group = RootPart.ParentGroup; // m_log.InfoFormat( // "[WATER WARS]: Entering AbstractView.ChangeSceneObject to change object {0} to {1}", // group.Name, newObjectName); // delete everything except the root prim // m_log.InfoFormat( // "[WATER WARS]: Deleting {0} old prims from {1}", // originalParts.Count, group.Name); foreach (SceneObjectPart part in group.Parts) { if (!part.IsRoot) { SceneObjectGroup groupToDelete = group.DelinkFromGroup(part, false); m_scene.DeleteSceneObject(groupToDelete, false); } } // Super-annoying pause to avoid ghost objects where a final update comes in after the kill command // FIXME: Really need a better way of ensuring that this problem doesn't happen //System.Threading.Thread.Sleep(1000); // get the new thing that we want to look like AssetBase objectAsset = m_scene.AssetService.Get(GetItem(newObjectContainer, newObjectName).AssetID.ToString()); string xml = Utils.BytesToString(objectAsset.Data); SceneObjectGroup sogToCopy = SceneObjectSerializer.FromOriginalXmlFormat(xml); // change the name of the morphed group to reflect its new identity group.Name = sogToCopy.Name; // change the shape of the root prim group.RootPart.Shape = sogToCopy.RootPart.Shape; // m_log.InfoFormat( // "[WATER WARS]: Adding {0} prims as part of change from {1} to {2}", // sogToCopy.Children.Count, group.Name, newObjectName); // create all the linked parts of the morph foreach (SceneObjectPart part in sogToCopy.Parts) { if (!part.IsRoot) { part.UUID = UUID.Random(); // This is necessary to stop inventory item IDs being identical and failing persistence. part.Inventory.ResetInventoryIDs(); part.LocalId = m_scene.AllocateLocalId(); part.ParentID = group.RootPart.LocalId; part.ParentUUID = group.RootPart.UUID; group.AddPart(part); } } // XXX: Nasty nasty nasty group.HasGroupChanged = true; group.ScheduleGroupForFullUpdate(); }
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> /// 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) { MainConsole.Instance.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 uuid = filename.Remove(filename.Length - extension.Length); if (ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension)) { AssetType assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; if (assetType == AssetType.Unknown) { MainConsole.Instance.WarnFormat("[INVENTORY ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, uuid); } else if (assetType == AssetType.Object) { string xmlData = Utils.BytesToString(data); List <SceneObjectGroup> sceneObjects = new List <SceneObjectGroup> { SceneObjectSerializer.FromOriginalXmlFormat(xmlData, m_registry) }; if (m_creatorIdForAssetId.ContainsKey(UUID.Parse(uuid))) { foreach (SceneObjectPart sop in from sog in sceneObjects from sop in sog.Parts where string.IsNullOrEmpty(sop.CreatorData) select sop) { sop.CreatorID = m_creatorIdForAssetId[UUID.Parse(uuid)]; } } foreach (SceneObjectGroup sog in sceneObjects) { foreach (SceneObjectPart sop in sog.Parts) { //Fix ownerIDs and perms sop.Inventory.ApplyGodPermissions((uint)PermissionMask.All); sog.ApplyPermissions((uint)PermissionMask.All); foreach (TaskInventoryItem item in sop.Inventory.GetInventoryItems()) { item.OwnerID = m_userInfo.PrincipalID; } sop.OwnerID = m_userInfo.PrincipalID; } } data = Utils.StringToBytes(SceneObjectSerializer.ToOriginalXmlFormat(sceneObjects[0])); } //MainConsole.Instance.DebugFormat("[INVENTORY ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType); AssetBase asset = new AssetBase(UUID.Parse(uuid), "RandomName", assetType, UUID.Zero) { Data = data, Flags = AssetFlags.Normal }; asset.ID = m_registry.RequestModuleInterface <IAssetService>().Store(asset); return(true); } else { MainConsole.Instance.ErrorFormat( "[INVENTORY ARCHIVER]: Tried to dearchive data with path {0} with an unknown type extension {1}", assetPath, extension); return(false); } }
/// <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); } }
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); }