private void CreatePointEntity(Scene scene, UUID uuid, Vector3 groupPos) { SceneObjectPart y = new SceneObjectPart(); //Initialize part y.Name = "Very Small Point"; y.RegionHandle = scene.RegionInfo.RegionHandle; y.CreationDate = (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; y.OwnerID = UUID.Zero; y.CreatorID = UUID.Zero; y.LastOwnerID = UUID.Zero; y.UUID = uuid; y.Shape = PrimitiveBaseShape.CreateBox(); y.Scale = new Vector3(0.01f, 0.01f, 0.01f); y.LastOwnerID = UUID.Zero; y.GroupPosition = groupPos; y.OffsetPosition = Vector3.Zero; y.RotationOffset = Quaternion.Identity; y.Velocity = Vector3.Zero; y.AngularVelocity = Vector3.Zero; y.Acceleration = Vector3.Zero; y.Flags = 0; y.TrimPermissions(); //Initialize group and add part as root part SceneObjectGroup x = new SceneObjectGroup(y); x.SetScene(scene); x.RegionHandle = scene.RegionInfo.RegionHandle; x.SetScene(scene); m_Entity = x; }
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); }
/// <summary> /// Loads the World's objects /// </summary> public void LoadPrimsFromStorage() { if (m_haveLoadedPrims || !m_shouldLoadPrims) { return; } m_haveLoadedPrims = true; LoadingPrims = true; m_log.Info("[BackupModule]: Loading objects from datastore"); List <SceneObjectGroup> PrimsFromDB = m_scene.SimulationDataService.LoadObjects(m_scene.RegionInfo.RegionID, m_scene); foreach (SceneObjectGroup group in PrimsFromDB) { try { m_scene.SceneGraph.CheckAllocationOfLocalIds(group); if (group.IsAttachment || (group.RootPart.Shape != null && (group.RootPart.Shape.State != 0 && (group.RootPart.Shape.PCode == (byte)PCode.None || group.RootPart.Shape.PCode == (byte)PCode.Prim || group.RootPart.Shape.PCode == (byte)PCode.Avatar)))) { m_log.Warn("[BackupModule]: Broken state for object " + group.Name + " while loading objects, removing it from the database."); //WTF went wrong here? Remove it and then pass it by on loading m_scene.SimulationDataService.RemoveObject(group.UUID, m_scene.RegionInfo.RegionID); continue; } else if (group.RootPart.Shape == null) { m_log.Warn("[BackupModule]: Broken object (" + group.Name + ") found while loading objects, removing it from the database."); //WTF went wrong here? Remove it and then pass it by on loading m_scene.SimulationDataService.RemoveObject(group.UUID, m_scene.RegionInfo.RegionID); continue; } group.Scene = m_scene; if (group.RootPart == null) { m_log.ErrorFormat("[BackupModule] Found a SceneObjectGroup with m_rootPart == null and {0} children", group.ChildrenList.Count); continue; } m_scene.SceneGraph.RestorePrimToScene(group); SceneObjectPart rootPart = (SceneObjectPart)group.GetChildPart(group.UUID); rootPart.Flags &= ~PrimFlags.Scripted; rootPart.TrimPermissions(); group.CheckSculptAndLoad(); } catch (Exception ex) { m_log.WarnFormat("[BackupModule]: Exception attempting to load object from the database, {0}, removing...", ex.ToString()); m_scene.SimulationDataService.RemoveObject(group.UUID, m_scene.RegionInfo.RegionID); } } LoadingPrims = false; m_log.Info("[BackupModule]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)"); }
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> /// 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) { // 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.SceneGraph.GetNewRezLocation( RayStart, RayEnd, RayTargetID, Quaternion.Identity, BypassRayCast, bRayEndIsIntersection, true, scale, false); System.Xml.XmlDocument doc; InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = m_scene.InventoryService.GetItem(item); SceneObjectGroup group = CreateObjectFromInventory(item, remoteClient, itemID, out doc); if (doc == null) { //No asset, check task inventory IEntity e; m_scene.SceneGraph.TryGetEntity(fromTaskID, out e); if (e != null && e is SceneObjectGroup) { SceneObjectGroup grp = (SceneObjectGroup)e; TaskInventoryItem taskItem = grp.RootPart.Inventory.GetInventoryItem(itemID); item = new InventoryItemBase(); item.ID = UUID.Random(); item.CreatorId = taskItem.CreatorID.ToString(); item.Owner = remoteClient.AgentId; item.AssetID = taskItem.AssetID; item.Description = taskItem.Description; item.Name = taskItem.Name; item.AssetType = taskItem.Type; item.InvType = taskItem.InvType; item.Flags = taskItem.Flags; item.SalePrice = taskItem.SalePrice; item.SaleType = taskItem.SaleType; if (m_scene.Permissions.PropagatePermissions()) { item.BasePermissions = taskItem.BasePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move); if (taskItem.InvType == (int)InventoryType.Object) { item.CurrentPermissions = item.BasePermissions & (((taskItem.CurrentPermissions & 7) << 13) | (taskItem.CurrentPermissions & (uint)PermissionMask.Move)); } else { item.CurrentPermissions = item.BasePermissions & taskItem.CurrentPermissions; } item.CurrentPermissions |= 16; // Slam item.NextPermissions = taskItem.NextPermissions; item.EveryOnePermissions = taskItem.EveryonePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move); item.GroupPermissions = taskItem.GroupPermissions & taskItem.NextPermissions; } else { item.BasePermissions = taskItem.BasePermissions; item.CurrentPermissions = taskItem.CurrentPermissions; item.NextPermissions = taskItem.NextPermissions; item.EveryOnePermissions = taskItem.EveryonePermissions; item.GroupPermissions = taskItem.GroupPermissions; } group = CreateObjectFromInventory(item, remoteClient, itemID, out doc); } else { return(null); } } if (group == null && doc.FirstChild.OuterXml.StartsWith("<groups>")) { List <SceneObjectGroup> Groups = RezMultipleObjectsFromInventory(doc.FirstChild.ChildNodes, itemID, remoteClient, pos, RezSelected, item, RayTargetID, BypassRayCast, RayEndIsIntersection, RayEnd, RayStart, bRayEndIsIntersection); if (Groups.Count != 0) { return(Groups[0]); } else { return(null); } } 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); } remoteClient.SendAlertMessage("You do not have permission to rez objects here."); 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); // 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); if (rootPart == null) { m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart."); return(null); } // 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(); group.ScheduleGroupUpdate(PrimUpdateFlags.FullUpdate); if (!m_scene.Permissions.BypassPermissions()) { if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) { List <UUID> uuids = new List <UUID> (); uuids.Add(item.ID); m_scene.InventoryService.DeleteItems(item.Owner, uuids); } } return(group); }
/// <summary> /// Deserialize a scene object from the original xml format /// </summary> /// <param name="serialization"></param> /// <returns></returns> public static SceneObjectGroup FromOriginalXmlFormat(UUID fromUserInventoryItemID, string xmlData) { //m_log.DebugFormat("[SOG]: Starting deserialization of SOG"); //int time = System.Environment.TickCount; SceneObjectGroup sceneObject = new SceneObjectGroup(); // libomv.types changes UUID to Guid xmlData = xmlData.Replace("<UUID>", "<Guid>"); xmlData = xmlData.Replace("</UUID>", "</Guid>"); // Handle Nested <UUID><UUID> property xmlData = xmlData.Replace("<Guid><Guid>", "<UUID><Guid>"); xmlData = xmlData.Replace("</Guid></Guid>", "</Guid></UUID>"); try { StringReader sr; XmlTextReader reader; XmlNodeList parts; XmlDocument doc; int linkNum; doc = new XmlDocument(); doc.LoadXml(xmlData); parts = doc.GetElementsByTagName("RootPart"); if (parts.Count == 0) { throw new Exception("Invalid Xml format - no root part"); } else { sr = new StringReader(parts[0].InnerXml); reader = new XmlTextReader(sr); sceneObject.SetRootPart(SceneObjectPart.FromXml(fromUserInventoryItemID, reader)); reader.Close(); sr.Close(); } parts = doc.GetElementsByTagName("Part"); for (int i = 0; i < parts.Count; i++) { sr = new StringReader(parts[i].InnerXml); reader = new XmlTextReader(sr); SceneObjectPart part = SceneObjectPart.FromXml(reader); linkNum = part.LinkNum; sceneObject.AddPart(part); part.LinkNum = linkNum; part.TrimPermissions(); part.StoreUndoState(); reader.Close(); sr.Close(); } // Script state may, or may not, exist. Not having any, is NOT // ever a problem. sceneObject.LoadScriptState(doc); //m_log.DebugFormat("[SERIALIZER]: Finished deserialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time); return(sceneObject); } catch (Exception e) { m_log.ErrorFormat( "[SERIALIZER]: Deserialization of xml failed with {0}. xml was {1}", e, xmlData); } return(null); }
/// <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> /// Do pre-rez processing when the object comes from an item. /// </summary> /// <param name="remoteClient"></param> /// <param name="item"></param> /// <param name="objlist"></param> /// <param name="pos"></param> /// <param name="veclist"> /// List of vector position adjustments for a coalesced objects. For ordinary objects /// this list will contain just Vector3.Zero. The order of adjustments must match the order of objlist /// </param> /// <param name="isAttachment"></param> /// <returns>true if we can processed with rezzing, false if we need to abort</returns> private bool DoPreRezWhenFromItem( IClientAPI remoteClient, InventoryItemBase item, List <SceneObjectGroup> objlist, Vector3 pos, List <Vector3> veclist, bool isAttachment) { UUID fromUserInventoryItemId = 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) { fromUserInventoryItemId = item.ID; } } else { if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) { // Brave new fullperm world fromUserInventoryItemId = item.ID; } } for (int i = 0; i < objlist.Count; i++) { SceneObjectGroup g = objlist[i]; if (!m_Scene.Permissions.CanRezObject( g.PrimCount, remoteClient.AgentId, pos + veclist[i]) && !isAttachment) { // 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) && (!isAttachment)) { remoteClient.SendBulkUpdateInventory(item); } ILandObject land = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y); remoteClient.SendAlertMessage(string.Format( "Can't rez object '{0}' at <{1:F3}, {2:F3}, {3:F3}> on parcel '{4}' in region {5}.", item.Name, pos.X, pos.Y, pos.Z, land != null ? land.LandData.Name : "Unknown", m_Scene.Name)); return(false); } } for (int i = 0; i < objlist.Count; i++) { SceneObjectGroup so = objlist[i]; SceneObjectPart rootPart = so.RootPart; // 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; } so.FromFolderID = item.Folder; // m_log.DebugFormat( // "[INVENTORY ACCESS MODULE]: rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}", // rootPart.OwnerID, item.Owner, item.CurrentPermissions); if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & SceneObjectGroup.SLAM) != 0) { //Need to kill the for sale here rootPart.ObjectSaleType = 0; rootPart.SalePrice = 10; } foreach (SceneObjectPart part in so.Parts) { part.FromUserInventoryItemID = fromUserInventoryItemId; part.ApplyPermissionsOnRez(item, true, m_Scene); } rootPart.TrimPermissions(); if (isAttachment) { so.FromItemID = item.ID; } } return(true); }
/// <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> /// Do pre-rez processing when the object comes from an item. /// </summary> /// <param name="remoteClient"></param> /// <param name="item"></param> /// <param name="objlist"></param> /// <param name="pos"></param> /// <param name="isAttachment"></param> /// <returns>true if we can processed with rezzing, false if we need to abort</returns> private bool DoPreRezWhenFromItem( IClientAPI remoteClient, InventoryItemBase item, List <SceneObjectGroup> objlist, Vector3 pos, bool isAttachment) { UUID fromUserInventoryItemId = 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) { fromUserInventoryItemId = item.ID; } } else { if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) { // Brave new fullperm world fromUserInventoryItemId = item.ID; } } int primcount = 0; foreach (SceneObjectGroup g in objlist) { primcount += g.PrimCount; } if (!m_Scene.Permissions.CanRezObject( primcount, remoteClient.AgentId, pos) && !isAttachment) { // 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) && (!isAttachment)) { remoteClient.SendBulkUpdateInventory(item); } return(false); } for (int i = 0; i < objlist.Count; i++) { SceneObjectGroup so = objlist[i]; SceneObjectPart rootPart = so.RootPart; // 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; } rootPart.FromFolderID = item.Folder; // Console.WriteLine("rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}", // rootPart.OwnerID, item.Owner, item.CurrentPermissions); 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 so.Parts) { if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) { part.EveryoneMask = item.EveryOnePermissions; part.NextOwnerMask = item.NextPermissions; } part.GroupMask = 0; // DO NOT propagate here } so.ApplyNextOwnerPermissions(); } } foreach (SceneObjectPart part in so.Parts) { part.FromUserInventoryItemID = fromUserInventoryItemId; if ((part.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) { part.Inventory.ChangeInventoryOwner(item.Owner); part.GroupMask = 0; // DO NOT propagate here } part.EveryoneMask = item.EveryOnePermissions; part.NextOwnerMask = item.NextPermissions; } rootPart.TrimPermissions(); if (isAttachment) { so.SetFromItemID(item.ID); } } return(true); }