/// <summary> /// Deserialize a scene object from the original xml format /// </summary> /// <param name="xmlData"></param> /// <returns>The scene object deserialized. Null on failure.</returns> public static SceneObjectGroup FromOriginalXmlFormat(XmlReader reader) { //m_log.DebugFormat("[SOG]: Starting deserialization of SOG"); //int time = System.Environment.TickCount; SceneObjectGroup sceneObject = null; try { int linkNum; reader.ReadToFollowing("RootPart"); reader.ReadToFollowing("SceneObjectPart"); sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(reader)); reader.ReadToFollowing("OtherParts"); if(reader.IsEmptyElement) { /* do not try to read parts on empty elements */ } else if (reader.ReadToDescendant("Part")) { do { if (reader.ReadToDescendant("SceneObjectPart")) { SceneObjectPart part = SceneObjectPart.FromXml(reader); linkNum = part.LinkNum; sceneObject.AddPart(part); part.LinkNum = linkNum; part.TrimPermissions(); } } while (reader.ReadToNextSibling("Part")); } // Script state may, or may not, exist. Not having any, is NOT // ever a problem. sceneObject.LoadScriptState(reader); } catch (Exception e) { m_log.ErrorFormat("[SERIALIZER]: Deserialization of xml failed. Exception {0}", e); return null; } return sceneObject; }
/// <summary> /// Serialize a scene object to the original xml format /// </summary> /// <param name="sceneObject"></param> /// <returns></returns> public static string ToOriginalXmlFormat(SceneObjectGroup sceneObject) { return ToOriginalXmlFormat(sceneObject, true); }
private GroupDisplayData GroupDisplayDataFromSOG(UUID userId, GroupLoader.LoaderParams parms, SceneObjectGroup sog, IInventoryStorage inv, string userName, InventoryItemBase item) { if (((parms.Checks & LoaderChecks.PrimLimit) != 0) && sog.GetParts().Count > parms.PrimLimit) { throw new Exceptions.PrimExporterPermissionException("Object contains too many prims"); } HashSet <UUID> fullPermTextures = CollectFullPermTexturesIfNecessary(ref userId, parms, inv); PrimDisplayData rootPrim = null; List <PrimDisplayData> groupData = new List <PrimDisplayData>(); foreach (SceneObjectPart part in sog.GetParts()) { if (((parms.Checks & LoaderChecks.UserMustBeCreator) != 0) && part.CreatorID != userId) { throw new Exceptions.PrimExporterPermissionException("You are not the creator of all parts"); } PrimDisplayData pdd = this.ExtractPrimMesh(part, parms, fullPermTextures); if (pdd == null) { throw new NullReferenceException("Prim mesh could not be loaded"); } groupData.Add(pdd); if (pdd.IsRootPrim) { rootPrim = pdd; } } //assign parent to all prims foreach (var part in groupData) { if (!part.IsRootPrim) { part.Parent = rootPrim; } } //sort prims by link number var sortedPrims = groupData.OrderBy(g => g.LinkNum); return(new GroupDisplayData { Prims = sortedPrims, RootPrim = rootPrim, CreatorName = userName, ObjectName = sog.Name }); }
/// <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); }
public void Init() { m_scene = new SceneHelpers().SetupScene(); m_so1 = SceneHelpers.CreateSceneObject(1, m_ownerId, "so1", 0x10); m_so2 = SceneHelpers.CreateSceneObject(1, m_ownerId, "so2", 0x20); }
////////// Write ///////// public void SOGToXml2(XmlTextWriter writer, SceneObjectGroup sog, Dictionary<string, object> options) { writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty); SOPToXml2(writer, sog.RootPart, options); writer.WriteStartElement(String.Empty, "OtherParts", String.Empty); sog.ForEachPart(delegate(SceneObjectPart sop) { if (sop.UUID != sog.RootPart.UUID) SOPToXml2(writer, sop, options); }); writer.WriteEndElement(); writer.WriteEndElement(); }
/// <summary> /// Serialize a scene object to the 'xml2' format. /// </summary> /// <param name = "sceneObject"></param> /// <returns></returns> public static byte[] ToBinaryXml2Format(SceneObjectGroup sceneObject) { using (MemoryStream sw = new MemoryStream()) { using (StreamWriter wr = new StreamWriter(sw, Encoding.UTF8)) { using (XmlTextWriter writer = new XmlTextWriter(wr)) { SOGToXml2(writer, sceneObject, new Dictionary<string, object>()); } return sw.ToArray(); } } }
public void TestLoadIarPathWithEscapedChars() { TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); string itemName = "You & you are a mean/man/"; string humanEscapedItemName = @"You & you are a mean\/man\/"; string userPassword = "******"; InventoryArchiverModule archiverModule = new InventoryArchiverModule(); Scene scene = new SceneHelpers().SetupScene(); SceneHelpers.SetupSceneModules(scene, archiverModule); // Create user string userFirstName = "Jock"; string userLastName = "Stirrup"; UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); UserAccountHelpers.CreateUserWithInventory(scene, userFirstName, userLastName, userId, "meowfood"); // Create asset SceneObjectGroup object1; SceneObjectPart part1; { string partName = "part name"; UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); 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); part1 = new SceneObjectPart( ownerId, shape, groupPosition, rotationOffset, offsetPosition); part1.Name = partName; object1 = new SceneObjectGroup(part1); scene.AddNewSceneObject(object1, false); } UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); scene.AssetService.Store(asset1); // Create item UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080"); InventoryItemBase item1 = new InventoryItemBase(); item1.Name = itemName; item1.AssetID = asset1.FullID; item1.ID = item1Id; InventoryFolderBase objsFolder = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, userId, "Objects")[0]; item1.Folder = objsFolder.ID; scene.AddInventoryItem(item1); MemoryStream archiveWriteStream = new MemoryStream(); archiverModule.OnInventoryArchiveSaved += SaveCompleted; mre.Reset(); archiverModule.ArchiveInventory( Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream); mre.WaitOne(60000, false); // LOAD ITEM MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); archiverModule.DearchiveInventory(userFirstName, userLastName, "Scripts", userPassword, archiveReadStream); InventoryItemBase foundItem1 = InventoryArchiveUtils.FindItemByPath( scene.InventoryService, userId, "Scripts/Objects/" + humanEscapedItemName); Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); // Assert.That( // foundItem1.CreatorId, Is.EqualTo(userUuid), // "Loaded item non-uuid creator doesn't match that of the loading user"); Assert.That( foundItem1.Name, Is.EqualTo(itemName), "Loaded item name doesn't match saved name"); }
public void InitialAttachmentRez(ScenePresence sp, List <AvatarAttachment> attachments, UUID originalOwner, bool isSavedOutfit) { ScenePresence ownerSP = null; //retrieve all attachments sp.Appearance.ClearAttachments(); foreach (AvatarAttachment attachment in attachments) { UUID origItemID = attachment.ItemID ^ sp.UUID; if (origItemID == UUID.Zero) { continue; } // Are we already attached? if (sp.Appearance.GetAttachmentForItem(origItemID) == null) { IInventoryProviderSelector inventorySelect = ProviderRegistry.Instance.Get <IInventoryProviderSelector>(); var provider = inventorySelect.GetProvider(originalOwner); InventoryItemBase item = provider.GetItem(origItemID, UUID.Zero); if ((item.CurrentPermissions & (uint)PermissionMask.Copy) != (uint)PermissionMask.Copy) { if (ownerSP == null) { ownerSP = m_scene.GetScenePresence(originalOwner); } if (ownerSP != null) { ownerSP.ControllingClient.SendAgentAlertMessage("Bot cannot wear no-copy attachment: '" + item.Name + "'.", true); } continue;//No copy objects cannot be attached } // sp.ControllingClient can go null on botRemoveBot from another script IClientAPI remoteClient = sp.ControllingClient; // take a reference and use if (remoteClient == null) { return; } SceneObjectGroup grp = m_scene.RezObject(remoteClient, remoteClient.ActiveGroupId, origItemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, false, false, sp.UUID, true, (uint)attachment.AttachPoint, 0, null, item, false); if (grp != null) { grp.OwnerID = sp.UUID; //Force UUID to botID, this should probably update the parts too, but right now they are separate grp.SetOwnerId(grp.OwnerID); // let's do this for safety and consistency. In case childpart.OwnerID is referenced, or rootpart.OwnerID bool tainted = false; if (attachment.AttachPoint != 0 && attachment.AttachPoint != grp.GetBestAttachmentPoint()) { tainted = true; } m_scene.SceneGraph.AttachObject(remoteClient, grp.LocalId, (uint)attachment.AttachPoint, true, false, AttachFlags.None); if (tainted) { grp.HasGroupChanged = true; } // Fire after attach, so we don't get messy perms dialogs // grp.CreateScriptInstances(0, ScriptStartFlags.PostOnRez, m_scene.DefaultScriptEngine, (int)ScriptStateSource.PrimData, null); attachment.AttachPoint = grp.RootPart.AttachmentPoint; UUID assetId = grp.UUID; sp.Appearance.SetAttachment((int)attachment.AttachPoint, true, attachment.ItemID, assetId); grp.DisableUpdates = false; grp.ScheduleGroupForFullUpdate(PrimUpdateFlags.ForcedFullUpdate); } } } }
///<summary> ///</summary> ///<param name = "assetID"></param> ///<param name = "inventoryItem"></param> ///<param name = "data"></param> public UUID UploadCompleteHandler(string assetName, string assetDescription, UUID assetID, UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType, string assetType, uint everyone_mask, uint group_mask, uint next_owner_mask) { sbyte assType = 0; sbyte inType = 0; if (inventoryType == "sound") { inType = 1; assType = 1; } else if (inventoryType == "animation") { inType = 19; assType = 20; } else if (inventoryType == "snapshot") { inType = 15; assType = 0; } else if (inventoryType == "wearable") { inType = 18; switch (assetType) { case "bodypart": assType = 13; break; case "clothing": assType = 5; break; } } else if (inventoryType == "object") { inType = (sbyte)InventoryType.Object; assType = (sbyte)AssetType.Object; List <Vector3> positions = new List <Vector3>(); List <Quaternion> rotations = new List <Quaternion>(); OSDMap request = (OSDMap)OSDParser.DeserializeLLSDXml(data); OSDArray instance_list = (OSDArray)request["instance_list"]; OSDArray mesh_list = (OSDArray)request["mesh_list"]; OSDArray texture_list = (OSDArray)request["texture_list"]; SceneObjectGroup grp = null; List <UUID> textures = new List <UUID>(); #if (!ISWIN) for (int i = 0; i < texture_list.Count; i++) { AssetBase textureAsset = new AssetBase(UUID.Random(), assetName, AssetType.Texture, m_service.AgentID); textureAsset.Data = texture_list[i].AsBinary(); textureAsset.ID = m_assetService.Store(textureAsset); textures.Add(textureAsset.ID); } #else foreach (AssetBase textureAsset in texture_list.Select(t => new AssetBase(UUID.Random(), assetName, AssetType.Texture, m_service.AgentID) { Data = t.AsBinary() })) { textureAsset.ID = m_assetService.Store(textureAsset); textures.Add(textureAsset.ID); } #endif InventoryFolderBase meshFolder = m_inventoryService.GetFolderForType(m_service.AgentID, InventoryType.Mesh, AssetType.Mesh); for (int i = 0; i < mesh_list.Count; i++) { PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox(); Primitive.TextureEntry textureEntry = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE); OSDMap inner_instance_list = (OSDMap)instance_list[i]; OSDArray face_list = (OSDArray)inner_instance_list["face_list"]; for (uint face = 0; face < face_list.Count; face++) { OSDMap faceMap = (OSDMap)face_list[(int)face]; Primitive.TextureEntryFace f = pbs.Textures.CreateFace(face); if (faceMap.ContainsKey("fullbright")) { f.Fullbright = faceMap["fullbright"].AsBoolean(); } if (faceMap.ContainsKey("diffuse_color")) { f.RGBA = faceMap["diffuse_color"].AsColor4(); } int textureNum = faceMap["image"].AsInteger(); float imagerot = faceMap["imagerot"].AsInteger(); float offsets = (float)faceMap["offsets"].AsReal(); float offsett = (float)faceMap["offsett"].AsReal(); float scales = (float)faceMap["scales"].AsReal(); float scalet = (float)faceMap["scalet"].AsReal(); if (imagerot != 0) { f.Rotation = imagerot; } if (offsets != 0) { f.OffsetU = offsets; } if (offsett != 0) { f.OffsetV = offsett; } if (scales != 0) { f.RepeatU = scales; } if (scalet != 0) { f.RepeatV = scalet; } f.TextureID = textures.Count > textureNum ? textures[textureNum] : Primitive.TextureEntry.WHITE_TEXTURE; textureEntry.FaceTextures[face] = f; } pbs.TextureEntry = textureEntry.GetBytes(); AssetBase meshAsset = new AssetBase(UUID.Random(), assetName, AssetType.Mesh, m_service.AgentID) { Data = mesh_list[i].AsBinary() }; meshAsset.ID = m_assetService.Store(meshAsset); if (meshFolder == null) { m_inventoryService.CreateUserInventory(m_service.AgentID, false); meshFolder = m_inventoryService.GetFolderForType(m_service.AgentID, InventoryType.Mesh, AssetType.Mesh); } InventoryItemBase itemBase = new InventoryItemBase(UUID.Random(), m_service.AgentID) { AssetType = (sbyte)AssetType.Mesh, AssetID = meshAsset.ID, CreatorId = m_service.AgentID.ToString(), Folder = meshFolder.ID, InvType = (int)InventoryType.Texture, Name = "(Mesh) - " + assetName, CurrentPermissions = (uint)PermissionMask.All, BasePermissions = (uint)PermissionMask.All, EveryOnePermissions = everyone_mask, GroupPermissions = group_mask, NextPermissions = next_owner_mask }; //Bad... but whatever m_inventoryService.AddItem(itemBase); pbs.SculptEntry = true; pbs.SculptTexture = meshAsset.ID; pbs.SculptType = (byte)SculptType.Mesh; pbs.SculptData = meshAsset.Data; Vector3 position = inner_instance_list["position"].AsVector3(); Vector3 scale = inner_instance_list["scale"].AsVector3(); Quaternion rotation = inner_instance_list["rotation"].AsQuaternion(); int physicsShapeType = inner_instance_list["physics_shape_type"].AsInteger(); int material = inner_instance_list["material"].AsInteger(); int mesh = inner_instance_list["mesh"].AsInteger(); UUID owner_id = m_service.AgentID; IScene fakeScene = new Scene(); fakeScene.AddModuleInterfaces(m_service.Registry.GetInterfaces()); SceneObjectPart prim = new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero, assetName, fakeScene) { Scale = scale, AbsolutePosition = position }; rotations.Add(rotation); positions.Add(position); prim.UUID = UUID.Random(); prim.CreatorID = owner_id; prim.OwnerID = owner_id; prim.GroupID = UUID.Zero; prim.LastOwnerID = prim.OwnerID; prim.CreationDate = Util.UnixTimeSinceEpoch(); prim.Name = assetName; prim.Description = ""; prim.PhysicsType = (byte)physicsShapeType; prim.BaseMask = (uint)PermissionMask.All; prim.EveryoneMask = everyone_mask; prim.NextOwnerMask = next_owner_mask; prim.GroupMask = group_mask; prim.OwnerMask = (uint)PermissionMask.All; if (grp == null) { grp = new SceneObjectGroup(prim, fakeScene); } else { grp.AddChild(prim, i + 1); } grp.RootPart.IsAttachment = false; } if (grp.ChildrenList.Count > 1) //Fix first link # { grp.RootPart.LinkNum++; } Vector3 rootPos = positions[0]; grp.SetAbsolutePosition(false, rootPos); for (int i = 0; i < positions.Count; i++) { Vector3 offset = positions[i] - rootPos; grp.ChildrenList[i].SetOffsetPosition(offset); Vector3 abs = grp.ChildrenList[i].AbsolutePosition; Vector3 currentPos = positions[i]; } //grp.Rotation = rotations[0]; for (int i = 0; i < rotations.Count; i++) { if (i != 0) { grp.ChildrenList[i].SetRotationOffset(false, rotations[i], false); } } grp.UpdateGroupRotationR(rotations[0]); data = Encoding.ASCII.GetBytes(grp.ToXml2()); } AssetBase asset = new AssetBase(assetID, assetName, (AssetType)assType, m_service.AgentID) { Data = data }; asset.ID = m_assetService.Store(asset); assetID = asset.ID; InventoryItemBase item = new InventoryItemBase { Owner = m_service.AgentID, CreatorId = m_service.AgentID.ToString(), ID = inventoryItem, AssetID = asset.ID, Description = assetDescription, Name = assetName, AssetType = assType, InvType = inType, Folder = parentFolder, CurrentPermissions = (uint)PermissionMask.All, BasePermissions = (uint)PermissionMask.All, EveryOnePermissions = everyone_mask, NextPermissions = next_owner_mask, GroupPermissions = group_mask, CreationDate = Util.UnixTimeSinceEpoch() }; m_inventoryService.AddItem(item); return(assetID); }
public void TestLinkDelink2SceneObjects() { TestHelper.InMethod(); bool debugtest = false; Scene scene = SceneSetupHelpers.SetupScene(); SceneObjectPart part1 = SceneSetupHelpers.AddSceneObject(scene); SceneObjectGroup grp1 = part1.ParentGroup; SceneObjectPart part2 = SceneSetupHelpers.AddSceneObject(scene); SceneObjectGroup grp2 = part2.ParentGroup; grp1.AbsolutePosition = new Vector3(10, 10, 10); grp2.AbsolutePosition = Vector3.Zero; // <90,0,0> grp1.Rotation = (Quaternion.CreateFromEulers(90 * Utils.DEG_TO_RAD, 0, 0)); // <180,0,0> grp2.UpdateGroupRotation(Quaternion.CreateFromEulers(180 * Utils.DEG_TO_RAD, 0, 0)); // Required for linking grp1.RootPart.UpdateFlag = 0; grp2.RootPart.UpdateFlag = 0; // Link grp2 to grp1. part2 becomes child prim to grp1. grp2 is eliminated. grp1.LinkToGroup(grp2); // FIXME: Can't do this test yet since group 2 still has its root part! We can't yet null this since // it might cause SOG.ProcessBackup() to fail due to the race condition. This really needs to be fixed. Assert.That(grp2.IsDeleted, "SOG 2 was not registered as deleted after link."); Assert.That(grp2.Children.Count, Is.EqualTo(0), "Group 2 still contained children after delink."); Assert.That(grp1.Children.Count == 2); if (debugtest) { m_log.Debug("parts: " + grp1.Children.Count); m_log.Debug("Group1: Pos:" + grp1.AbsolutePosition + ", Rot:" + grp1.Rotation); m_log.Debug("Group1: Prim1: OffsetPosition:" + part1.OffsetPosition + ", OffsetRotation:" + part1.RotationOffset); m_log.Debug("Group1: Prim2: OffsetPosition:" + part2.OffsetPosition + ", OffsetRotation:" + part2.RotationOffset); } // root part should have no offset position or rotation Assert.That(part1.OffsetPosition == Vector3.Zero && part1.RotationOffset == Quaternion.Identity); // offset position should be root part position - part2.absolute position. Assert.That(part2.OffsetPosition == new Vector3(-10, -10, -10)); float roll = 0; float pitch = 0; float yaw = 0; // There's a euler anomoly at 180, 0, 0 so expect 180 to turn into -180. part1.RotationOffset.GetEulerAngles(out roll, out pitch, out yaw); Vector3 rotEuler1 = new Vector3(roll * Utils.RAD_TO_DEG, pitch * Utils.RAD_TO_DEG, yaw * Utils.RAD_TO_DEG); if (debugtest) { m_log.Debug(rotEuler1); } part2.RotationOffset.GetEulerAngles(out roll, out pitch, out yaw); Vector3 rotEuler2 = new Vector3(roll * Utils.RAD_TO_DEG, pitch * Utils.RAD_TO_DEG, yaw * Utils.RAD_TO_DEG); if (debugtest) { m_log.Debug(rotEuler2); } Assert.That(rotEuler2.ApproxEquals(new Vector3(-180, 0, 0), 0.001f) || rotEuler2.ApproxEquals(new Vector3(180, 0, 0), 0.001f)); // Delink part 2 grp1.DelinkFromGroup(part2.LocalId); if (debugtest) { m_log.Debug("Group2: Prim2: OffsetPosition:" + part2.AbsolutePosition + ", OffsetRotation:" + part2.RotationOffset); } Assert.That(grp1.Children.Count, Is.EqualTo(1), "Group 1 still contained part2 after delink."); Assert.That(part2.AbsolutePosition == Vector3.Zero); }
public void TestRezAttachmentFromInventory() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); Scene scene = CreateTestScene(); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); { scene.AttachmentsModule.RezSingleAttachmentFromInventory( sp, attItem.ID, (uint)AttachmentPoint.Chest); // Check scene presence status Assert.That(sp.HasAttachments(), Is.True); List <SceneObjectGroup> attachments = sp.GetAttachments(); Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); Assert.That(attSo.IsAttachment); Assert.That(attSo.UsesPhysics, Is.False); Assert.That(attSo.IsTemporary, Is.False); Assert.IsFalse(attSo.Backup); // Check appearance status Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); // Check events Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); } // Test attaching an already attached attachment { scene.AttachmentsModule.RezSingleAttachmentFromInventory( sp, attItem.ID, (uint)AttachmentPoint.Chest); // Check scene presence status Assert.That(sp.HasAttachments(), Is.True); List <SceneObjectGroup> attachments = sp.GetAttachments(); Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); Assert.That(attSo.IsAttachment); Assert.That(attSo.UsesPhysics, Is.False); Assert.That(attSo.IsTemporary, Is.False); // Check appearance status Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); // Check events Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); } }
protected virtual string DoObject2Post(Stream request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse) { if (!Util.CheckHttpAuthorization(_gridSendKey, httpRequest.Headers)) { m_log.WarnFormat("[REST COMMS]: /object2/ communication from untrusted peer {0}", httpRequest.RemoteIPEndPoint.Address.ToString()); httpResponse.StatusCode = 401; return("Untrusted"); } //m_log.Debug(" >> " + request["http-method"] + " " + request["content-type"] + " uri=" + request["uri"]); UUID objectID; string action; ulong regionHandle; if (!GetParams(path, out objectID, out regionHandle, out action)) { m_log.InfoFormat("[REST COMMS]: Invalid parameters for object message {0}", path); httpResponse.StatusCode = 400; return("Invalid Parameters"); } ObjectPostMessage message = ProtoBuf.Serializer.Deserialize <ObjectPostMessage>(request); if (message == null) { httpResponse.StatusCode = 400; return("Invalid Request"); } // System.Threading.Thread.Sleep(16000); //used for interpolation ulong createTime = Util.GetLongTickCount(); SceneObjectGroup sog = null; long nonceID = GetNonceID(httpRequest.Headers); try { var engine = ProviderRegistry.Instance.Get <ISerializationEngine>(); sog = engine.SceneObjectSerializer.DeserializeGroupFromBytes(message.Sog); sog.TimeReceived = createTime; sog.NonceID = nonceID; } catch (Exception ex) { m_log.InfoFormat("[REST COMMS]: exception on deserializing scene object {0}", ex); httpResponse.StatusCode = 500; return(ex.Message); } if (CheckNonceID(nonceID)) { // possibly would have succeeded but client side cancelled // m_log.WarnFormat("[REST COMMS]: Skipping object create for nonce ID nonce ID {0}", nonceID); httpResponse.StatusCode = 204; return("No Content"); } // else m_log.WarnFormat("[REST COMMS]: Nonce ID {0} not found, allowing rez.", nonceID); if (message.Pos.HasValue) { sog.OriginalEnteringScenePosition = sog.AbsolutePosition; sog.AbsolutePosition = Util.GetValidRegionXYZ(message.Pos.Value); } List <UUID> avatarIDs = new List <UUID>(); if (message.Avatars == null) { sog.AvatarsToExpect = message.NumAvatars; } else { sog.AvatarsToExpect = message.Avatars.Length; foreach (Guid id in message.Avatars) { avatarIDs.Add(new UUID(id)); } } // This is the meaning of POST object bool result = m_localBackend.SendCreateObject(regionHandle, sog, avatarIDs, false, message.Pos.HasValue ? message.Pos.Value : Vector3.Zero, message.Pos.HasValue); if (result) { httpResponse.StatusCode = 200; } else { httpResponse.StatusCode = 500; } return(result.ToString()); }
protected virtual void DoObjectPost(Hashtable request, Hashtable responsedata, ulong regionhandle) { OSDMap args = RegionClient.GetOSDMap((string)request["body"]); if (args == null) { responsedata["int_response_code"] = 400; responsedata["str_response_string"] = "false"; return; } Vector3 pos = Vector3.Zero; string sogXmlStr = String.Empty, extraStr = String.Empty, stateXmlStr = String.Empty; if (args.ContainsKey("sog")) { sogXmlStr = args["sog"].AsString(); } if (args.ContainsKey("extra")) { extraStr = args["extra"].AsString(); } if (args.ContainsKey("pos")) { pos = args["pos"].AsVector3(); } UUID regionID = m_localBackend.GetRegionID(regionhandle); SceneObjectGroup sog = null; try { sog = SceneObjectSerializer.FromXml2Format(sogXmlStr); sog.ExtraFromXmlString(extraStr); } catch (Exception ex) { m_log.InfoFormat("[REST COMMS]: exception on deserializing scene object {0}", ex.Message); responsedata["int_response_code"] = 400; responsedata["str_response_string"] = "false"; return; } if (args.ContainsKey("pos")) { sog.AbsolutePosition = pos; } if (args.ContainsKey("avatars")) { sog.AvatarsToExpect = args["avatars"].AsInteger(); } if ((args.ContainsKey("state")) && m_aScene.m_allowScriptCrossings) { stateXmlStr = args["state"].AsString(); if (!String.IsNullOrEmpty(stateXmlStr)) { try { sog.SetState(stateXmlStr, regionID); } catch (Exception ex) { m_log.InfoFormat("[REST COMMS]: exception on setting state for scene object {0}", ex.Message); } } } // This is the meaning of POST object bool result = m_localBackend.SendCreateObject(regionhandle, sog, null, false, pos, args["pos"] == null); responsedata["int_response_code"] = 200; responsedata["str_response_string"] = result.ToString(); }
/// <summary> /// Serialize a scene object to the original xml format /// </summary> /// <param name="sceneObject"></param> /// <returns></returns> public static void ToOriginalXmlFormat(SceneObjectGroup sceneObject, XmlTextWriter writer, bool doScriptStates) { ToOriginalXmlFormat(sceneObject, writer, doScriptStates, false); }
public void TestJsonReadNotecard() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); string notecardName = "nc1"; SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1)); m_scene.AddSceneObject(so); UUID creatingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }"); // Write notecard InvokeOpOnHost("JsonWriteNotecard", so.UUID, creatingStoreId, "", notecardName); { // Read notecard UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}"); UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "", notecardName); Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); Assert.That(value, Is.EqualTo("World")); } { // Read notecard to new single component path UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}"); UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make", notecardName); Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); Assert.That(value, Is.EqualTo("")); value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.Hello"); Assert.That(value, Is.EqualTo("World")); } { // Read notecard to new multi-component path. This should not work. UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}"); UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName); Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); Assert.That(value, Is.EqualTo("")); value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello"); Assert.That(value, Is.EqualTo("")); } { // Read notecard to existing multi-component path. This should work UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'make' : { 'it' : 'so' } }"); UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName); Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); Assert.That(value, Is.EqualTo("")); value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello"); Assert.That(value, Is.EqualTo("World")); } { // Read notecard to invalid path. This should not work. UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'make' : { 'it' : 'so' } }"); UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "/", notecardName); Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); Assert.That(value, Is.EqualTo("")); } { // Try read notecard to fake store. UUID fakeStoreId = TestHelpers.ParseTail(0x500); UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, fakeStoreId, "", notecardName); Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); string value = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello"); Assert.That(value, Is.EqualTo("")); } }
/// <summary> /// Serialize a scene object to the original xml format /// </summary> /// <param name="sceneObject"></param> /// <param name="writer"></param> /// <param name="noRootElement">If false, don't write the enclosing SceneObjectGroup element</param> /// <returns></returns> public static void ToOriginalXmlFormat( SceneObjectGroup sceneObject, XmlTextWriter writer, bool doScriptStates, bool noRootElement) { // m_log.DebugFormat("[SERIALIZER]: Starting serialization of {0}", sceneObject.Name); // int time = System.Environment.TickCount; if (!noRootElement) writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty); writer.WriteStartElement(String.Empty, "RootPart", String.Empty); ToXmlFormat(sceneObject.RootPart, writer); writer.WriteEndElement(); writer.WriteStartElement(String.Empty, "OtherParts", String.Empty); SceneObjectPart[] parts = sceneObject.Parts; for (int i = 0; i < parts.Length; i++) { SceneObjectPart part = parts[i]; if (part.UUID != sceneObject.RootPart.UUID) { writer.WriteStartElement(String.Empty, "Part", String.Empty); ToXmlFormat(part, writer); writer.WriteEndElement(); } } writer.WriteEndElement(); // OtherParts if (doScriptStates) sceneObject.SaveScriptedState(writer); if (!noRootElement) writer.WriteEndElement(); // SceneObjectGroup // m_log.DebugFormat("[SERIALIZER]: Finished serialization of SOG {0}, {1}ms", sceneObject.Name, System.Environment.TickCount - time); }
public void StoreObject(SceneObjectGroup obj, UUID regionUUID) { throw new NotImplementedException(); }
/// <summary> /// Serialize a scene object to the original xml format /// </summary> /// <param name = "sceneObject"></param> /// <returns></returns> public static string ToOriginalXmlFormat(SceneObjectGroup sceneObject) { using (StringWriter sw = new StringWriter()) { using (XmlTextWriter writer = new XmlTextWriter(sw)) { ToOriginalXmlFormat(sceneObject, writer); } return sw.ToString(); } }
public void TestSerializeXml2() { TestHelpers.InMethod(); //log4net.Config.XmlConfigurator.Configure(); string rpName = "My Little Pony"; UUID rpUuid = UUID.Parse("00000000-0000-0000-0000-000000000064"); UUID rpCreatorId = UUID.Parse("00000000-0000-0000-0000-000000000015"); 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; string daNamespace = "MyNamespace"; string daStoreName = "MyStore"; string daKey = "foo"; string daValue = "bar"; OSDMap myStore = new OSDMap(); myStore.Add(daKey, daValue); rp.DynAttrs = new DAMap(); rp.DynAttrs.SetStore(daNamespace, daStoreName, myStore); 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); Dictionary <string, object> options = new Dictionary <string, object>(); options["old-guids"] = true; string xml2 = m_serialiserModule.SerializeGroupToXml2(so, options); XmlTextReader xtr = new XmlTextReader(new StringReader(xml2)); xtr.ReadStartElement("SceneObjectGroup"); xtr.ReadStartElement("SceneObjectPart"); UUID uuid = UUID.Zero; string name = null; UUID creatorId = UUID.Zero; DAMap daMap = null; while (xtr.Read() && xtr.Name != "SceneObjectPart") { if (xtr.NodeType != XmlNodeType.Element) { continue; } switch (xtr.Name) { case "UUID": xtr.ReadStartElement("UUID"); uuid = UUID.Parse(xtr.ReadElementString("Guid")); xtr.ReadEndElement(); break; case "Name": name = xtr.ReadElementContentAsString(); break; case "CreatorID": xtr.ReadStartElement("CreatorID"); creatorId = UUID.Parse(xtr.ReadElementString("Guid")); xtr.ReadEndElement(); break; case "DynAttrs": daMap = new DAMap(); daMap.ReadXml(xtr); break; } } 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)); Assert.NotNull(daMap); Assert.AreEqual(daValue, daMap.GetStore(daNamespace, daStoreName)[daKey].AsString()); }
/// <summary> /// Serialize a scene object to the original xml format /// </summary> /// <param name="sceneObject"></param> /// <param name="writer"></param> /// <returns></returns> protected void ToOriginalXmlFormat(SceneObjectGroup sceneObject, XmlTextWriter writer) { //MainConsole.Instance.DebugFormat("[SERIALIZER]: Starting serialization of {0}", Name); //int time = Util.EnvironmentTickCount(); writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty); writer.WriteStartElement(String.Empty, "RootPart", String.Empty); ToXmlFormat(sceneObject.RootPart, writer); writer.WriteEndElement(); writer.WriteStartElement(String.Empty, "OtherParts", String.Empty); SceneObjectPart[] parts = sceneObject.Parts; foreach (SceneObjectPart part in parts.Where(part => part.UUID != sceneObject.RootPart.UUID)) { writer.WriteStartElement(String.Empty, "Part", String.Empty); ToXmlFormat(part, writer); writer.WriteEndElement(); } writer.WriteEndElement(); // OtherParts writer.WriteEndElement(); // SceneObjectGroup //MainConsole.Instance.DebugFormat("[SERIALIZER]: Finished serialization of SOG {0}, {1}ms", Name, Util.EnvironmentTickCount() - time); }
public void TestCrossOnSameSimulatorWithSittingAvatar() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); UUID userId = TestHelpers.ParseTail(0x1); int sceneObjectIdTail = 0x2; Vector3 so1StartPos = new Vector3(128, 10, 20); EntityTransferModule etmA = new EntityTransferModule(); EntityTransferModule etmB = new EntityTransferModule(); LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); IConfigSource config = new IniConfigSource(); IConfig modulesConfig = config.AddConfig("Modules"); modulesConfig.Set("EntityTransferModule", etmA.Name); modulesConfig.Set("SimulationServices", lscm.Name); IConfig entityTransferConfig = config.AddConfig("EntityTransfer"); // In order to run a single threaded regression test we do not want the entity transfer module waiting // for a callback from the destination scene before removing its avatar data. entityTransferConfig.Set("wait_for_callback", false); SceneHelpers sh = new SceneHelpers(); TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1000, 999); SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA); SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB); SceneObjectGroup so1 = SceneHelpers.AddSceneObject(sceneA, 1, userId, "", sceneObjectIdTail); UUID so1Id = so1.UUID; so1.AbsolutePosition = so1StartPos; AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); TestClient tc = new TestClient(acd, sceneA); List <TestClient> destinationTestClients = new List <TestClient>(); EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients); ScenePresence sp1SceneA = SceneHelpers.AddScenePresence(sceneA, tc, acd); sp1SceneA.AbsolutePosition = so1StartPos; sp1SceneA.HandleAgentRequestSit(sp1SceneA.ControllingClient, sp1SceneA.UUID, so1.UUID, Vector3.Zero); sceneA.Update(4); sceneB.Update(4); // Cross sceneA.SceneGraph.UpdatePrimGroupPosition( so1.LocalId, new Vector3(so1StartPos.X, so1StartPos.Y - 20, so1StartPos.Z), sp1SceneA.ControllingClient); // crossing is async sceneA.Update(4); sceneB.Update(4); Thread.Sleep(500); SceneObjectGroup so1PostCross; ScenePresence sp1SceneAPostCross = sceneA.GetScenePresence(userId); Assert.IsTrue(sp1SceneAPostCross.IsChildAgent, "sp1SceneAPostCross.IsChildAgent unexpectedly false"); ScenePresence sp1SceneBPostCross = sceneB.GetScenePresence(userId); TestClient sceneBTc = ((TestClient)sp1SceneBPostCross.ControllingClient); sceneBTc.CompleteMovement(); sceneA.Update(4); sceneB.Update(4); Assert.IsFalse(sp1SceneBPostCross.IsChildAgent, "sp1SceneAPostCross.IsChildAgent unexpectedly true"); Assert.IsTrue(sp1SceneBPostCross.IsSatOnObject); Assert.IsNull(sceneA.GetSceneObjectGroup(so1Id), "uck"); so1PostCross = sceneB.GetSceneObjectGroup(so1Id); Assert.NotNull(so1PostCross); Assert.AreEqual(1, so1PostCross.GetSittingAvatarsCount()); Vector3 so1PostCrossPos = so1PostCross.AbsolutePosition; // Console.WriteLine("CRISSCROSS"); // Recross sceneB.SceneGraph.UpdatePrimGroupPosition( so1PostCross.LocalId, new Vector3(so1PostCrossPos.X, so1PostCrossPos.Y + 20, so1PostCrossPos.Z), sp1SceneBPostCross.ControllingClient); sceneA.Update(4); sceneB.Update(4); // crossing is async Thread.Sleep(500); { ScenePresence sp1SceneBPostReCross = sceneB.GetScenePresence(userId); Assert.IsTrue(sp1SceneBPostReCross.IsChildAgent, "sp1SceneBPostReCross.IsChildAgent unexpectedly false"); ScenePresence sp1SceneAPostReCross = sceneA.GetScenePresence(userId); TestClient sceneATc = ((TestClient)sp1SceneAPostReCross.ControllingClient); sceneATc.CompleteMovement(); Assert.IsFalse(sp1SceneAPostReCross.IsChildAgent, "sp1SceneAPostCross.IsChildAgent unexpectedly true"); Assert.IsTrue(sp1SceneAPostReCross.IsSatOnObject); Assert.IsNull(sceneB.GetSceneObjectGroup(so1Id), "uck2"); SceneObjectGroup so1PostReCross = sceneA.GetSceneObjectGroup(so1Id); Assert.NotNull(so1PostReCross); Assert.AreEqual(1, so1PostReCross.GetSittingAvatarsCount()); } }
//////// Read ///////// public bool Xml2ToSOG(XmlTextReader reader, SceneObjectGroup sog) { reader.Read(); reader.ReadStartElement("SceneObjectGroup"); SceneObjectPart root = Xml2ToSOP(reader); if (root != null) sog.SetRootPart(root); else { return false; } if (sog.UUID == UUID.Zero) sog.UUID = sog.RootPart.UUID; reader.Read(); // OtherParts while (!reader.EOF) { switch (reader.NodeType) { case XmlNodeType.Element: if (reader.Name == "SceneObjectPart") { SceneObjectPart child = Xml2ToSOP(reader); if (child != null) sog.AddChild(child, child.LinkNum); } else { //Logger.Log("Found unexpected prim XML element " + reader.Name, Helpers.LogLevel.Debug); reader.Read(); } break; case XmlNodeType.EndElement: default: reader.Read(); break; } } return true; }
public void TestCrossOnSameSimulatorPrimLimitsOkay() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); UUID userId = TestHelpers.ParseTail(0x1); int sceneObjectIdTail = 0x2; EntityTransferModule etmA = new EntityTransferModule(); EntityTransferModule etmB = new EntityTransferModule(); LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); LandManagementModule lmmA = new LandManagementModule(); LandManagementModule lmmB = new LandManagementModule(); IConfigSource config = new IniConfigSource(); IConfig modulesConfig = config.AddConfig("Modules"); modulesConfig.Set("EntityTransferModule", etmA.Name); modulesConfig.Set("SimulationServices", lscm.Name); IConfig permissionsConfig = config.AddConfig("Permissions"); permissionsConfig.Set("permissionmodules", "PrimLimitsModule"); SceneHelpers sh = new SceneHelpers(); TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1000, 999); SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); SceneHelpers.SetupSceneModules( sceneA, config, etmA, lmmA, new PrimLimitsModule(), new PrimCountModule()); SceneHelpers.SetupSceneModules( sceneB, config, etmB, lmmB, new PrimLimitsModule(), new PrimCountModule()); // We must set up the parcel for this to work. Normally this is taken care of by OpenSimulator startup // code which is not yet easily invoked by tests. lmmA.EventManagerOnNoLandDataFromStorage(); lmmB.EventManagerOnNoLandDataFromStorage(); AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); TestClient tc = new TestClient(acd, sceneA); List <TestClient> destinationTestClients = new List <TestClient>(); EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients); ScenePresence sp1SceneA = SceneHelpers.AddScenePresence(sceneA, tc, acd); SceneObjectGroup so1 = SceneHelpers.AddSceneObject(sceneA, 1, userId, "", sceneObjectIdTail); UUID so1Id = so1.UUID; so1.AbsolutePosition = new Vector3(128, 10, 20); // Cross with a negative value. We must make this call rather than setting AbsolutePosition directly // because only this will execute permission checks in the source region. sceneA.SceneGraph.UpdatePrimGroupPosition(so1.LocalId, new Vector3(128, -10, 20), sp1SceneA.ControllingClient); // crossing is async Thread.Sleep(500); Assert.IsNull(sceneA.GetSceneObjectGroup(so1Id)); Assert.NotNull(sceneB.GetSceneObjectGroup(so1Id)); }
/// <summary> /// Create an item using details for the given scene object. /// </summary> /// <param name="action"></param> /// <param name="remoteClient"></param> /// <param name="so"></param> /// <param name="folderID"></param> /// <returns></returns> protected InventoryItemBase CreateItemForObject( DeRezAction action, IClientAPI remoteClient, SceneObjectGroup so, UUID folderID) { // Get the user info of the item destination // UUID userID = UUID.Zero; if (action == DeRezAction.Take || action == DeRezAction.TakeCopy || action == DeRezAction.SaveToExistingUserInventoryItem) { // Take or take copy require a taker // Saving changes requires a local user // if (remoteClient == null) { return(null); } userID = remoteClient.AgentId; } else { // All returns / deletes go to the object owner // userID = so.RootPart.OwnerID; } if (userID == UUID.Zero) // Can't proceed { return(null); } // If we're returning someone's item, it goes back to the // owner's Lost And Found folder. // Delete is treated like return in this case // Deleting your own items makes them go to trash // InventoryFolderBase folder = null; InventoryItemBase item = null; if (DeRezAction.SaveToExistingUserInventoryItem == action) { item = new InventoryItemBase(so.RootPart.FromUserInventoryItemID, userID); item = m_Scene.InventoryService.GetItem(item); //item = userInfo.RootFolder.FindItem( // objectGroup.RootPart.FromUserInventoryItemID); if (null == item) { m_log.DebugFormat( "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.", so.Name, so.UUID); return(null); } } else { // Folder magic // if (action == DeRezAction.Delete) { // Deleting someone else's item // if (remoteClient == null || so.OwnerID != remoteClient.AgentId) { folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); } else { folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); } } else if (action == DeRezAction.Return) { // Dump to lost + found unconditionally // folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); } if (folderID == UUID.Zero && folder == null) { if (action == DeRezAction.Delete) { // Deletes go to trash by default // folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); } else { if (remoteClient == null || so.OwnerID != remoteClient.AgentId) { // Taking copy of another person's item. Take to // Objects folder. folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object); } else { // Catch all. Use lost & found // folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); } } } // Override and put into where it came from, if it came // from anywhere in inventory // if (action == DeRezAction.Take || action == DeRezAction.TakeCopy) { if (so.RootPart.FromFolderID != UUID.Zero) { InventoryFolderBase f = new InventoryFolderBase(so.RootPart.FromFolderID, userID); folder = m_Scene.InventoryService.GetFolder(f); } } if (folder == null) // None of the above { folder = new InventoryFolderBase(folderID); if (folder == null) // Nowhere to put it { return(null); } } item = new InventoryItemBase(); item.ID = UUID.Random(); item.InvType = (int)InventoryType.Object; item.Folder = folder.ID; item.Owner = userID; } return(item); }
public void TestllGetLinkPrimitiveParams() { TestHelpers.InMethod(); TestHelpers.EnableLogging(); UUID ownerId = TestHelpers.ParseTail(0x1); SceneObjectGroup grp1 = SceneHelpers.CreateSceneObject(2, ownerId, "grp1-", 0x10); grp1.AbsolutePosition = new Vector3(10, 11, 12); m_scene.AddSceneObject(grp1); LSL_Api apiGrp1 = new LSL_Api(); apiGrp1.Initialize(m_engine, grp1.RootPart, null, null); // Check simple 1 prim case { LSL_List resList = apiGrp1.llGetLinkPrimitiveParams(1, new LSL_List(new LSL_Integer(ScriptBaseClass.PRIM_ROTATION))); Assert.That(resList.Length, Is.EqualTo(1)); } // Check 2 prim case { LSL_List resList = apiGrp1.llGetLinkPrimitiveParams( 1, new LSL_List( new LSL_Integer(ScriptBaseClass.PRIM_ROTATION), new LSL_Integer(ScriptBaseClass.PRIM_LINK_TARGET), new LSL_Integer(2), new LSL_Integer(ScriptBaseClass.PRIM_ROTATION))); Assert.That(resList.Length, Is.EqualTo(2)); } // Check invalid parameters are ignored { LSL_List resList = apiGrp1.llGetLinkPrimitiveParams(3, new LSL_List(new LSL_Integer(ScriptBaseClass.PRIM_ROTATION))); Assert.That(resList.Length, Is.EqualTo(0)); } // Check all parameters are ignored if an initial bad link is given { LSL_List resList = apiGrp1.llGetLinkPrimitiveParams( 3, new LSL_List( new LSL_Integer(ScriptBaseClass.PRIM_ROTATION), new LSL_Integer(ScriptBaseClass.PRIM_LINK_TARGET), new LSL_Integer(1), new LSL_Integer(ScriptBaseClass.PRIM_ROTATION))); Assert.That(resList.Length, Is.EqualTo(0)); } // Check only subsequent parameters are ignored when we hit the first bad link number { LSL_List resList = apiGrp1.llGetLinkPrimitiveParams( 1, new LSL_List( new LSL_Integer(ScriptBaseClass.PRIM_ROTATION), new LSL_Integer(ScriptBaseClass.PRIM_LINK_TARGET), new LSL_Integer(3), new LSL_Integer(ScriptBaseClass.PRIM_ROTATION))); Assert.That(resList.Length, Is.EqualTo(1)); } }
public GroupDisplayData LoadFromXML(string xmlData, GroupLoader.LoaderParams parms) { SceneObjectGroup sog = SceneXmlLoader.DeserializeGroupFromXml2(xmlData); return(GroupDisplayDataFromSOG(UUID.Zero, parms, sog, null, string.Empty, null)); }
/// <summary> /// Initialize the controller /// </summary> /// <param name="attachToVe">If true then the game is attached to the virtual environment</param> public void Initialise(bool attachToVe) { AttachedToVe = attachToVe; ModelFactory = new ModelFactory(this); Game = ModelFactory.CreateGame(UUID.Random(), "Game1"); Commands = new WaterWarsCommands(this); Resolver = new OpenSimResolver(this); ViewerWebServices = new ViewerWebServices(this); HudManager = new HudViewManager(this); Events = new WaterWars.Events.Events(this); Feeds = new WaterWars.Feeds.Feeds(this); GameDateManager = new GameDateManager(this); RoundManager = new RoundManager(this); StageTimer = new StageTimer(this); RainfallGenerator.Initialize(EventManager); WaterDistributor.Initialize(EventManager); if (null != Persister) { Persister.Initialize(this); } if (null != m_recorder) { m_recorder.Initialize(this); } // This has to be called before we establish a game state so that the persisted game object // can first be created EventManager.TriggerSystemInitialized(); new RegistrationState(this).Activate(); if (AttachedToVe) { Groups = new OpenSimGroupsMediator(this); CheckVeRequirements(); foreach (Scene scene in Scenes) { // Stop players deleting or editing objects they 'own' scene.Permissions.OnRezObject += delegate(int objectCount, UUID owner, Vector3 objectPosition, Scene myScene) { return(Groups.IsPlayerAnAdmin(owner)); }; scene.Permissions.OnDeleteObject += delegate(UUID objectID, UUID userID, Scene myScene) { return(Groups.IsPlayerAnAdmin(userID)); }; scene.Permissions.OnTakeObject += delegate(UUID objectID, UUID userID, Scene myScene) { return(Groups.IsPlayerAnAdmin(userID)); }; scene.Permissions.OnTakeCopyObject += delegate(UUID objectID, UUID userID, Scene myScene) { return(Groups.IsPlayerAnAdmin(userID)); }; scene.Permissions.OnEditObject += delegate(UUID objectID, UUID userID, Scene myScene) { return(Groups.IsPlayerAnAdmin(userID)); }; scene.Permissions.OnMoveObject += delegate(UUID objectID, UUID userID, Scene myScene) { return(Groups.IsPlayerAnAdmin(userID)); }; EntityBase[] entities = scene.Entities.GetAllByType <SceneObjectGroup>(); // Pass 1 - pick up the game manager view (first level of the hierarchy) foreach (EntityBase e in entities) { SceneObjectGroup so = (SceneObjectGroup)e; // m_log.InfoFormat( // "[WATER WARS]: Pass 1 - processing {0} {1} at {2} in existing scene", // so.Name, so.LocalId, so.AbsolutePosition); // This is messy, but there's actually only one game manager from which objects can come. if (so.Name == GameManagerView.IN_WORLD_NAME) { GameManagerView = new GameManagerView(this, scene); GameManagerView.Initialize(so); Dispatcher.RegisterGameManagerView(GameManagerView); } else if ( so.Name == StepBuiltDecorator.IN_WORLD_NAME || so.Name == WaterAllocationDecorator.IN_WORLD_NAME) { // FIXME: Temporarily, just delete our one decorator by name. // Eventually, the decorators will need to be re-registered with their game asset view. so.Scene.DeleteSceneObject(so, false); } } } if (GameManagerView == null) { throw new Exception( string.Format( "Could not find GameManagerView named {0} in any of the scenes. ABORTING.", GameManagerView.IN_WORLD_NAME)); } foreach (Scene scene in Scenes) { m_log.InfoFormat("[WATER WARS]: Processing buypoints on scene {0}", scene.RegionInfo.RegionName); // We'll keep track of these so that we can use them in pass 3 Dictionary <UUID, BuyPointView> buyPointViews = new Dictionary <UUID, BuyPointView>(); EntityBase[] entities = scene.Entities.GetAllByType <SceneObjectGroup>(); // Pass 2 - pick up the buy points (second level of the hierarchy) foreach (EntityBase e in entities) { SceneObjectGroup so = (SceneObjectGroup)e; try { // m_log.InfoFormat( // "[WATER WARS]: Pass 2 - processing {0} {1} at {2} in existing scene", // so.Name, so.LocalId, so.AbsolutePosition); IConfig config = GetPrimConfig(so); if (config != null) { AbstractGameAssetType modelType = GetModelTypeFromPrimConfig(config); if (modelType == AbstractGameAssetType.Parcel) { // We're using in-world buy point positioning to register them - not taking these from an // internal database and pushing them back up to the ve // // FIXME: The below might be old advice since I have now changed things such that // we can specify the uuid upfront // // We can't incorporate the first update buy point call within bpv.Initialize() because it // won't yet have registered with the dispatcher (which forms an intermediate layer between the // game logic and the view code). // We can't register with the dispatcher before initializing the view because no UUID will yet // exist for the dispatcher to record. // It might be possible to simplify this if we adapt OpenSim to allow us to specify the UUID // up-front. But other VE systems may not allow this. BuyPoint bp = Resolver.RegisterBuyPoint(so); BuyPointView bpv = GameManagerView.CreateBuyPointView(so, bp); buyPointViews.Add(bpv.Uuid, bpv); State.UpdateBuyPointStatus(bp); } } } catch (Exception ex) { m_log.Error( string.Format( "[WATER WARS]: Could not register {0} at {1} in {2}, ", so.Name, so.AbsolutePosition, so.Scene.RegionInfo.RegionName), ex); } } // Pass 3 - pick up the fields and game assets (third level of the hierarchy) foreach (EntityBase e in entities) { SceneObjectGroup so = (SceneObjectGroup)e; try { IConfig config = GetPrimConfig(so); if (config != null) { AbstractGameAssetType modelType = GetModelTypeFromPrimConfig(config); if (modelType == AbstractGameAssetType.Field) { Field f = Resolver.RegisterField(so); BuyPointView bpv = null; if (buyPointViews.TryGetValue(f.BuyPoint.Uuid, out bpv)) { bpv.CreateFieldView(so); } else { throw new Exception( string.Format( "Could not find BuyPointView for field {0}, parcel {1} at {2}", f.Name, f.BuyPoint.Name, f.BuyPoint.Location.LocalPosition)); } } else if ( modelType == AbstractGameAssetType.Crops || modelType == AbstractGameAssetType.Houses || modelType == AbstractGameAssetType.Factory) { // For now, just delete any existing game assets immediately. so.Scene.DeleteSceneObject(so, false); } } } catch (Exception ex) { m_log.Error( string.Format( "[WATER WARS]: Could not register {0} at {1} in {2}, ", so.Name, so.AbsolutePosition, so.Scene.RegionInfo.RegionName), ex); } } } HudManager.Initialise(); // Register in-game objects as they are created //m_scene.EventManager.OnObjectBeingAddedToScene += OnObjectAddedToScene; // At the moment, reset the game immediately on restarting so that we have a blank slate State.ResetGame(); // string statePath = Path.Combine(WaterWarsConstants.STATE_PATH, WaterWarsConstants.STATE_FILE_NAME); // if (File.Exists(statePath)) // RestoreGame(statePath); } }
public void TestLinkDelink2groups4SceneObjects() { TestHelper.InMethod(); bool debugtest = false; Scene scene = SceneSetupHelpers.SetupScene(); SceneObjectPart part1 = SceneSetupHelpers.AddSceneObject(scene); SceneObjectGroup grp1 = part1.ParentGroup; SceneObjectPart part2 = SceneSetupHelpers.AddSceneObject(scene); SceneObjectGroup grp2 = part2.ParentGroup; SceneObjectPart part3 = SceneSetupHelpers.AddSceneObject(scene); SceneObjectGroup grp3 = part3.ParentGroup; SceneObjectPart part4 = SceneSetupHelpers.AddSceneObject(scene); SceneObjectGroup grp4 = part4.ParentGroup; grp1.AbsolutePosition = new Vector3(10, 10, 10); grp2.AbsolutePosition = Vector3.Zero; grp3.AbsolutePosition = new Vector3(20, 20, 20); grp4.AbsolutePosition = new Vector3(40, 40, 40); // <90,0,0> grp1.Rotation = (Quaternion.CreateFromEulers(90 * Utils.DEG_TO_RAD, 0, 0)); // <180,0,0> grp2.UpdateGroupRotationR(Quaternion.CreateFromEulers(180 * Utils.DEG_TO_RAD, 0, 0)); // <270,0,0> grp3.Rotation = (Quaternion.CreateFromEulers(270 * Utils.DEG_TO_RAD, 0, 0)); // <0,90,0> grp4.UpdateGroupRotationR(Quaternion.CreateFromEulers(0, 90 * Utils.DEG_TO_RAD, 0)); // Required for linking grp1.RootPart.UpdateFlag = 0; grp2.RootPart.UpdateFlag = 0; grp3.RootPart.UpdateFlag = 0; grp4.RootPart.UpdateFlag = 0; // Link grp2 to grp1. part2 becomes child prim to grp1. grp2 is eliminated. grp1.LinkToGroup(grp2); // Link grp4 to grp3. grp3.LinkToGroup(grp4); // At this point we should have 4 parts total in two groups. Assert.That(grp1.Parts.Length == 2, "Group1 children count should be 2"); Assert.That(grp2.IsDeleted, "Group 2 was not registered as deleted after link."); Assert.That(grp2.Parts.Length, Is.EqualTo(0), "Group 2 still contained parts after delink."); Assert.That(grp3.Parts.Length == 2, "Group3 children count should be 2"); Assert.That(grp4.IsDeleted, "Group 4 was not registered as deleted after link."); Assert.That(grp4.Parts.Length, Is.EqualTo(0), "Group 4 still contained parts after delink."); if (debugtest) { m_log.Debug("--------After Link-------"); m_log.Debug("Group1: parts:" + grp1.Parts.Length); m_log.Debug("Group1: Pos:" + grp1.AbsolutePosition + ", Rot:" + grp1.Rotation); m_log.Debug("Group1: Prim1: OffsetPosition:" + part1.OffsetPosition + ", OffsetRotation:" + part1.RotationOffset); m_log.Debug("Group1: Prim2: OffsetPosition:" + part2.OffsetPosition + ", OffsetRotation:" + part2.RotationOffset); m_log.Debug("Group3: parts:" + grp3.Parts.Length); m_log.Debug("Group3: Pos:" + grp3.AbsolutePosition + ", Rot:" + grp3.Rotation); m_log.Debug("Group3: Prim1: OffsetPosition:" + part3.OffsetPosition + ", OffsetRotation:" + part3.RotationOffset); m_log.Debug("Group3: Prim2: OffsetPosition:" + part4.OffsetPosition + ", OffsetRotation:" + part4.RotationOffset); } // Required for linking grp1.RootPart.UpdateFlag = 0; grp3.RootPart.UpdateFlag = 0; // root part should have no offset position or rotation Assert.That(part1.OffsetPosition == Vector3.Zero && part1.RotationOffset == Quaternion.Identity, "root part should have no offset position or rotation (again)"); // offset position should be root part position - part2.absolute position. Assert.That(part2.OffsetPosition == new Vector3(-10, -10, -10), "offset position should be root part position - part2.absolute position (again)"); float roll = 0; float pitch = 0; float yaw = 0; // There's a euler anomoly at 180, 0, 0 so expect 180 to turn into -180. part1.RotationOffset.GetEulerAngles(out roll, out pitch, out yaw); Vector3 rotEuler1 = new Vector3(roll * Utils.RAD_TO_DEG, pitch * Utils.RAD_TO_DEG, yaw * Utils.RAD_TO_DEG); if (debugtest) { m_log.Debug(rotEuler1); } part2.RotationOffset.GetEulerAngles(out roll, out pitch, out yaw); Vector3 rotEuler2 = new Vector3(roll * Utils.RAD_TO_DEG, pitch * Utils.RAD_TO_DEG, yaw * Utils.RAD_TO_DEG); if (debugtest) { m_log.Debug(rotEuler2); } Assert.That(rotEuler2.ApproxEquals(new Vector3(-180, 0, 0), 0.001f) || rotEuler2.ApproxEquals(new Vector3(180, 0, 0), 0.001f), "Not sure what this assertion is all about..."); // Now we're linking the first group to the third group. This will make the first group child parts of the third one. grp3.LinkToGroup(grp1); // Delink parts 2 and 3 grp3.DelinkFromGroup(part2.LocalId); grp3.DelinkFromGroup(part3.LocalId); if (debugtest) { m_log.Debug("--------After De-Link-------"); m_log.Debug("Group1: parts:" + grp1.Parts.Length); m_log.Debug("Group1: Pos:" + grp1.AbsolutePosition + ", Rot:" + grp1.Rotation); m_log.Debug("Group1: Prim1: OffsetPosition:" + part1.OffsetPosition + ", OffsetRotation:" + part1.RotationOffset); m_log.Debug("Group1: Prim2: OffsetPosition:" + part2.OffsetPosition + ", OffsetRotation:" + part2.RotationOffset); m_log.Debug("Group3: parts:" + grp3.Parts.Length); m_log.Debug("Group3: Pos:" + grp3.AbsolutePosition + ", Rot:" + grp3.Rotation); m_log.Debug("Group3: Prim1: OffsetPosition:" + part3.OffsetPosition + ", OffsetRotation:" + part3.RotationOffset); m_log.Debug("Group3: Prim2: OffsetPosition:" + part4.OffsetPosition + ", OffsetRotation:" + part4.RotationOffset); } Assert.That(part2.AbsolutePosition == Vector3.Zero, "Badness 1"); Assert.That(part4.OffsetPosition == new Vector3(20, 20, 20), "Badness 2"); Quaternion compareQuaternion = new Quaternion(0, 0.7071068f, 0, 0.7071068f); Assert.That((part4.RotationOffset.X - compareQuaternion.X < 0.00003) && (part4.RotationOffset.Y - compareQuaternion.Y < 0.00003) && (part4.RotationOffset.Z - compareQuaternion.Z < 0.00003) && (part4.RotationOffset.W - compareQuaternion.W < 0.00003), "Badness 3"); }
private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary <UUID, sbyte> assetUuids, HashSet <UUID> failedIDs, HashSet <UUID> uncertainAssetsUUIDs) { m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.Name); EntityBase[] entities = scene.GetEntities(); List <SceneObjectGroup> sceneObjects = new List <SceneObjectGroup>(); int numObjectsSkippedPermissions = 0; // Filter entities so that we only have scene objects. // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods // end up having to do this IPermissionsModule permissionsModule = scene.RequestModuleInterface <IPermissionsModule>(); foreach (EntityBase entity in entities) { if (entity is SceneObjectGroup) { SceneObjectGroup sceneObject = (SceneObjectGroup)entity; if (!sceneObject.IsDeleted && !sceneObject.IsAttachment && !sceneObject.IsTemporary && !sceneObject.inTransit) { if (!CanUserArchiveObject(scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, FilterContent, permissionsModule)) { // The user isn't allowed to copy/transfer this object, so it will not be included in the OAR. ++numObjectsSkippedPermissions; } else { sceneObjects.Add(sceneObject); } } } } if (SaveAssets) { UuidGatherer assetGatherer = new UuidGatherer(scene.AssetService, assetUuids, failedIDs, uncertainAssetsUUIDs); int prevAssets = assetUuids.Count; foreach (SceneObjectGroup sceneObject in sceneObjects) { int curErrorCntr = assetGatherer.ErrorCount; int possible = assetGatherer.possibleNotAssetCount; assetGatherer.AddForInspection(sceneObject); assetGatherer.GatherAll(); curErrorCntr = assetGatherer.ErrorCount - curErrorCntr; possible = assetGatherer.possibleNotAssetCount - possible; if (curErrorCntr > 0) { m_log.ErrorFormat("[ARCHIVER]: object {0} '{1}', at {2}, contains {3} references to missing or damaged assets", sceneObject.UUID, sceneObject.Name, sceneObject.AbsolutePosition.ToString(), curErrorCntr); if (possible > 0) { m_log.WarnFormat("[ARCHIVER Warning]: object also contains {0} references that may not be assets or are missing", possible); } } else if (possible > 0) { m_log.WarnFormat("[ARCHIVER Warning]: object {0} '{1}', at {2}, contains {3} references that may not be assets or are missing", sceneObject.UUID, sceneObject.Name, sceneObject.AbsolutePosition.ToString(), possible); } } assetGatherer.GatherAll(); GC.Collect(); int errors = assetGatherer.FailedUUIDs.Count; m_log.DebugFormat( "[ARCHIVER]: {0} region scene objects to save reference {1} possible assets", sceneObjects.Count, assetUuids.Count - prevAssets + errors); if (errors > 0) { m_log.DebugFormat("[ARCHIVER]: {0} of these have problems or are not assets and will be ignored", errors); } } if (numObjectsSkippedPermissions > 0) { m_log.DebugFormat( "[ARCHIVER]: {0} scene objects skipped due to lack of permissions", numObjectsSkippedPermissions); } // Make sure that we also request terrain texture assets RegionSettings regionSettings = scene.RegionInfo.RegionSettings; if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1) { assetUuids[regionSettings.TerrainTexture1] = (sbyte)AssetType.Texture; } if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2) { assetUuids[regionSettings.TerrainTexture2] = (sbyte)AssetType.Texture; } if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3) { assetUuids[regionSettings.TerrainTexture3] = (sbyte)AssetType.Texture; } if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4) { assetUuids[regionSettings.TerrainTexture4] = (sbyte)AssetType.Texture; } if (scene.RegionEnvironment != null) { scene.RegionEnvironment.GatherAssets(assetUuids); } List <ILandObject> landObjects = scene.LandChannel.AllParcels(); foreach (ILandObject lo in landObjects) { if (lo.LandData != null && lo.LandData.Environment != null) { lo.LandData.Environment.GatherAssets(assetUuids); } } Save(scene, sceneObjects, regionDir); GC.Collect(); }
////////// Write ///////// public static void SOGToXml2(XmlTextWriter writer, SceneObjectGroup sog, Dictionary<string, object>options) { writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty); SOPToXml2(writer, sog.RootPart, options); writer.WriteStartElement(String.Empty, "OtherParts", String.Empty); sog.ForEachPart(delegate(SceneObjectPart sop) { if (sop.UUID != sog.RootPart.UUID) SOPToXml2(writer, sop, options); }); writer.WriteEndElement(); if (sog.RootPart.KeyframeMotion != null) { Byte[] data = sog.RootPart.KeyframeMotion.Serialize(); writer.WriteStartElement(String.Empty, "KeyframeMotion", String.Empty); writer.WriteBase64(data, 0, data.Length); writer.WriteEndElement(); } writer.WriteEndElement(); }
/// <summary> /// Checks whether the user has permission to export an object group to an OAR. /// </summary> /// <param name="user">The user</param> /// <param name="objGroup">The object group</param> /// <param name="filterContent">Which permissions to check: "C" = Copy, "T" = Transfer</param> /// <param name="permissionsModule">The scene's permissions module</param> /// <returns>Whether the user is allowed to export the object to an OAR</returns> private bool CanUserArchiveObject(UUID user, SceneObjectGroup objGroup, string filterContent, IPermissionsModule permissionsModule) { if (filterContent == null) { return(true); } if (permissionsModule == null) { return(true); // this shouldn't happen } // Check whether the user is permitted to export all of the parts in the SOG. If any // part can't be exported then the entire SOG can't be exported. bool permitted = true; //int primNumber = 1; foreach (SceneObjectPart obj in objGroup.Parts) { uint perm; PermissionClass permissionClass = permissionsModule.GetPermissionClass(user, obj); switch (permissionClass) { case PermissionClass.Owner: perm = obj.BaseMask; break; case PermissionClass.Group: perm = obj.GroupMask | obj.EveryoneMask; break; case PermissionClass.Everyone: default: perm = obj.EveryoneMask; break; } bool canCopy = (perm & (uint)PermissionMask.Copy) != 0; bool canTransfer = (perm & (uint)PermissionMask.Transfer) != 0; // Special case: if Everyone can copy the object then this implies it can also be // Transferred. // However, if the user is the Owner then we don't check EveryoneMask, because it seems that the mask // always (incorrectly) includes the Copy bit set in this case. But that's a mistake: the viewer // does NOT show that the object has Everyone-Copy permissions, and doesn't allow it to be copied. if (permissionClass != PermissionClass.Owner) { canTransfer |= (obj.EveryoneMask & (uint)PermissionMask.Copy) != 0; } bool partPermitted = true; if (filterContent.Contains("C") && !canCopy) { partPermitted = false; } if (filterContent.Contains("T") && !canTransfer) { partPermitted = false; } // If the user is the Creator of the object then it can always be included in the OAR bool creator = (obj.CreatorID.Guid == user.Guid); if (creator) { partPermitted = true; } //string name = (objGroup.PrimCount == 1) ? objGroup.Name : string.Format("{0} ({1}/{2})", obj.Name, primNumber, objGroup.PrimCount); //m_log.DebugFormat("[ARCHIVER]: Object permissions: {0}: Base={1:X4}, Owner={2:X4}, Everyone={3:X4}, permissionClass={4}, checkPermissions={5}, canCopy={6}, canTransfer={7}, creator={8}, permitted={9}", // name, obj.BaseMask, obj.OwnerMask, obj.EveryoneMask, // permissionClass, checkPermissions, canCopy, canTransfer, creator, partPermitted); if (!partPermitted) { permitted = false; break; } //++primNumber; } return(permitted); }
public static string ToOriginalXmlFormat(SceneObjectGroup sceneObject, string scriptedState) { using (StringWriter sw = new StringWriter()) { using (XmlTextWriter writer = new XmlTextWriter(sw)) { writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty); ToOriginalXmlFormat(sceneObject, writer, false, true); writer.WriteRaw(scriptedState); writer.WriteEndElement(); } return sw.ToString(); } }
public string SerializeGroupToXml2(SceneObjectGroup grp, Dictionary <string, object> options) { return(SceneXmlLoader.SaveGroupToXml2(grp, options)); }
public static SceneObjectGroup FromXml2Format(string xmlData) { //m_log.DebugFormat("[SOG]: Starting deserialization of SOG"); //int time = System.Environment.TickCount; try { XmlDocument doc = new XmlDocument(); /* this one is for OpenSim brain-deadness */ doc.LoadXml(xmlData.Replace("<SceneObjectPart xmlns:xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">", "<SceneObjectPart xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">")); XmlNodeList parts = doc.GetElementsByTagName("SceneObjectPart"); if (parts.Count == 0) { m_log.ErrorFormat("[SERIALIZER]: Deserialization of xml failed: No SceneObjectPart nodes. xml was " + xmlData); return null; } StringReader sr = new StringReader(parts[0].OuterXml); XmlTextReader reader = new XmlTextReader(sr); SceneObjectGroup sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(reader)); reader.Close(); sr.Close(); // Then deal with the rest for (int i = 1; i < parts.Count; i++) { sr = new StringReader(parts[i].OuterXml); reader = new XmlTextReader(sr); SceneObjectPart part = SceneObjectPart.FromXml(reader); int originalLinkNum = part.LinkNum; sceneObject.AddPart(part); // SceneObjectGroup.AddPart() tries to be smart and automatically set the LinkNum. // We override that here if (originalLinkNum != 0) part.LinkNum = originalLinkNum; reader.Close(); sr.Close(); } XmlNodeList keymotion = doc.GetElementsByTagName("KeyframeMotion"); if (keymotion.Count > 0) sceneObject.RootPart.KeyframeMotion = KeyframeMotion.FromData(sceneObject, Convert.FromBase64String(keymotion[0].InnerText)); else sceneObject.RootPart.KeyframeMotion = null; // Script state may, or may not, exist. Not having any, is NOT // ever a problem. sceneObject.LoadScriptState(doc); return sceneObject; } catch (Exception e) { m_log.ErrorFormat("[SERIALIZER]: Deserialization of xml failed with {0}. xml was {1}", e, xmlData); return null; } }
public void TestWearAttachmentFromGround() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); Scene scene = CreateTestScene(); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); SceneObjectGroup so2 = SceneHelpers.AddSceneObject(scene, "att2", sp.UUID); { SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, "att1", sp.UUID); m_numberOfAttachEventsFired = 0; scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, true, false); // Check status on scene presence Assert.That(sp.HasAttachments(), Is.True); List <SceneObjectGroup> attachments = sp.GetAttachments(); Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(so.Name)); Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); Assert.That(attSo.IsAttachment); Assert.That(attSo.UsesPhysics, Is.False); Assert.That(attSo.IsTemporary, Is.False); // Check item status Assert.That( sp.Appearance.GetAttachpoint(attSo.FromItemID), Is.EqualTo((int)AttachmentPoint.LeftHand)); InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID)); Assert.That(attachmentItem, Is.Not.Null); Assert.That(attachmentItem.Name, Is.EqualTo(so.Name)); InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(2)); // Check events Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); } // Test wearing a different attachment from the ground. { scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, true, false); // Check status on scene presence Assert.That(sp.HasAttachments(), Is.True); List <SceneObjectGroup> attachments = sp.GetAttachments(); Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(so2.Name)); Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); Assert.That(attSo.IsAttachment); Assert.That(attSo.UsesPhysics, Is.False); Assert.That(attSo.IsTemporary, Is.False); // Check item status Assert.That( sp.Appearance.GetAttachpoint(attSo.FromItemID), Is.EqualTo((int)AttachmentPoint.LeftHand)); InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID)); Assert.That(attachmentItem, Is.Not.Null); Assert.That(attachmentItem.Name, Is.EqualTo(so2.Name)); InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); // Check events Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3)); } // Test rewearing an already worn attachment from ground. Nothing should happen. { scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, true, false); // Check status on scene presence Assert.That(sp.HasAttachments(), Is.True); List <SceneObjectGroup> attachments = sp.GetAttachments(); Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(so2.Name)); Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); Assert.That(attSo.IsAttachment); Assert.That(attSo.UsesPhysics, Is.False); Assert.That(attSo.IsTemporary, Is.False); // Check item status Assert.That( sp.Appearance.GetAttachpoint(attSo.FromItemID), Is.EqualTo((int)AttachmentPoint.LeftHand)); InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID)); Assert.That(attachmentItem, Is.Not.Null); Assert.That(attachmentItem.Name, Is.EqualTo(so2.Name)); InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); // Check events Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3)); } }
public static string SaveGroupToXml2(SceneObjectGroup grp) { return SceneObjectSerializer.ToXml2Format(grp); }
public void TestWearAttachmentFromInventory() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); Scene scene = CreateTestScene(); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); InventoryItemBase attItem1 = CreateAttachmentItem(scene, ua1.PrincipalID, "att1", 0x10, 0x20); InventoryItemBase attItem2 = CreateAttachmentItem(scene, ua1.PrincipalID, "att2", 0x11, 0x21); { m_numberOfAttachEventsFired = 0; scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem1.ID, (uint)AttachmentPoint.Default); // default attachment point is currently the left hand. Assert.That(sp.HasAttachments(), Is.True); List <SceneObjectGroup> attachments = sp.GetAttachments(); Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(attItem1.Name)); Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); Assert.That(attSo.IsAttachment); // Check appearance status Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); Assert.That(sp.Appearance.GetAttachpoint(attItem1.ID), Is.EqualTo((int)AttachmentPoint.LeftHand)); Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); // Check events Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); } // Test wearing a second attachment at the same position // Until multiple attachments at one point is implemented, this will remove the first attachment // This test relies on both attachments having the same default attachment point (in this case LeftHand // since none other has been set). { scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem2.ID, (uint)AttachmentPoint.Default); // default attachment point is currently the left hand. Assert.That(sp.HasAttachments(), Is.True); List <SceneObjectGroup> attachments = sp.GetAttachments(); Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(attItem2.Name)); Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); Assert.That(attSo.IsAttachment); // Check appearance status Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); Assert.That(sp.Appearance.GetAttachpoint(attItem2.ID), Is.EqualTo((int)AttachmentPoint.LeftHand)); Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); // Check events Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3)); } // Test wearing an already attached attachment { scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem2.ID, (uint)AttachmentPoint.Default); // default attachment point is currently the left hand. Assert.That(sp.HasAttachments(), Is.True); List <SceneObjectGroup> attachments = sp.GetAttachments(); Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; Assert.That(attSo.Name, Is.EqualTo(attItem2.Name)); Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); Assert.That(attSo.IsAttachment); // Check appearance status Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); Assert.That(sp.Appearance.GetAttachpoint(attItem2.ID), Is.EqualTo((int)AttachmentPoint.LeftHand)); Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); // Check events Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3)); } }
/// <summary> /// Serialize a scene object to the 'xml2' format. /// </summary> /// <param name = "sceneObject"></param> /// <returns></returns> public static string ToXml2Format(SceneObjectGroup sceneObject) { using (StringWriter sw = new StringWriter()) { using (XmlTextWriter writer = new XmlTextWriter(sw)) { SOGToXml2(writer, sceneObject, new Dictionary<string, object>()); writer.Close(); } string str = sw.ToString(); sw.Flush(); sw.Close(); return str; } }
public void TestSameSimulatorNeighbouringRegionsTeleportV1() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); BaseHttpServer httpServer = new BaseHttpServer(99999); MainServer.AddHttpServer(httpServer); MainServer.Instance = httpServer; AttachmentsModule attModA = new AttachmentsModule(); AttachmentsModule attModB = new AttachmentsModule(); EntityTransferModule etmA = new EntityTransferModule(); EntityTransferModule etmB = new EntityTransferModule(); LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); IConfigSource config = new IniConfigSource(); IConfig modulesConfig = config.AddConfig("Modules"); modulesConfig.Set("EntityTransferModule", etmA.Name); modulesConfig.Set("SimulationServices", lscm.Name); IConfig entityTransferConfig = config.AddConfig("EntityTransfer"); // In order to run a single threaded regression test we do not want the entity transfer module waiting // for a callback from the destination scene before removing its avatar data. entityTransferConfig.Set("wait_for_callback", false); modulesConfig.Set("InventoryAccessModule", "BasicInventoryAccessModule"); SceneHelpers sh = new SceneHelpers(); TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000); SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); SceneHelpers.SetupSceneModules( sceneA, config, new CapabilitiesModule(), etmA, attModA, new BasicInventoryAccessModule()); SceneHelpers.SetupSceneModules( sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule()); // FIXME: Hack - this is here temporarily to revert back to older entity transfer behaviour lscm.ServiceVersion = "SIMULATION/0.1"; UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1); AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); TestClient tc = new TestClient(acd, sceneA); List <TestClient> destinationTestClients = new List <TestClient>(); EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients); ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, tc, acd); beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32); InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20); sceneA.AttachmentsModule.RezSingleAttachmentFromInventory( beforeTeleportSp, attItem.ID, (uint)AttachmentPoint.Chest); Vector3 teleportPosition = new Vector3(10, 11, 12); Vector3 teleportLookAt = new Vector3(20, 21, 22); m_numberOfAttachEventsFired = 0; sceneA.RequestTeleportLocation( beforeTeleportSp.ControllingClient, sceneB.RegionInfo.RegionHandle, teleportPosition, teleportLookAt, (uint)TeleportFlags.ViaLocation); destinationTestClients[0].CompleteMovement(); // Check attachments have made it into sceneB ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(ua1.PrincipalID); // This is appearance data, as opposed to actually rezzed attachments List <AvatarAttachment> sceneBAttachments = afterTeleportSceneBSp.Appearance.GetAttachments(); Assert.That(sceneBAttachments.Count, Is.EqualTo(1)); Assert.That(sceneBAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest)); Assert.That(sceneBAttachments[0].ItemID, Is.EqualTo(attItem.ID)); Assert.That(sceneBAttachments[0].AssetID, Is.EqualTo(attItem.AssetID)); Assert.That(afterTeleportSceneBSp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); // This is the actual attachment List <SceneObjectGroup> actualSceneBAttachments = afterTeleportSceneBSp.GetAttachments(); Assert.That(actualSceneBAttachments.Count, Is.EqualTo(1)); SceneObjectGroup actualSceneBAtt = actualSceneBAttachments[0]; Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name)); Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest)); Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1)); // Check attachments have been removed from sceneA ScenePresence afterTeleportSceneASp = sceneA.GetScenePresence(ua1.PrincipalID); // Since this is appearance data, it is still present on the child avatar! List <AvatarAttachment> sceneAAttachments = afterTeleportSceneASp.Appearance.GetAttachments(); Assert.That(sceneAAttachments.Count, Is.EqualTo(1)); Assert.That(afterTeleportSceneASp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); // This is the actual attachment, which should no longer exist List <SceneObjectGroup> actualSceneAAttachments = afterTeleportSceneASp.GetAttachments(); Assert.That(actualSceneAAttachments.Count, Is.EqualTo(0)); Assert.That(sceneA.GetSceneObjectGroups().Count, Is.EqualTo(0)); // Check events Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0)); }
/// /// DeleteToInventory /// public override UUID DeleteToInventory(DeRezAction action, UUID folderID, SceneObjectGroup objectGroup, IClientAPI remoteClient) { UUID assetID = base.DeleteToInventory(action, folderID, objectGroup, remoteClient); if (!assetID.Equals(UUID.Zero)) { UploadInventoryItem(remoteClient.AgentId, assetID, "", 0); } else m_log.Debug("[HGScene]: Scene.Inventory did not create asset"); return assetID; }
public void TestSameSimulatorNeighbouringRegionsTeleportV2() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); BaseHttpServer httpServer = new BaseHttpServer(99999); MainServer.AddHttpServer(httpServer); MainServer.Instance = httpServer; AttachmentsModule attModA = new AttachmentsModule(); AttachmentsModule attModB = new AttachmentsModule(); EntityTransferModule etmA = new EntityTransferModule(); EntityTransferModule etmB = new EntityTransferModule(); LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); IConfigSource config = new IniConfigSource(); IConfig modulesConfig = config.AddConfig("Modules"); modulesConfig.Set("EntityTransferModule", etmA.Name); modulesConfig.Set("SimulationServices", lscm.Name); modulesConfig.Set("InventoryAccessModule", "BasicInventoryAccessModule"); SceneHelpers sh = new SceneHelpers(); TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000); SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); SceneHelpers.SetupSceneModules( sceneA, config, new CapabilitiesModule(), etmA, attModA, new BasicInventoryAccessModule()); SceneHelpers.SetupSceneModules( sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule()); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1); AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); TestClient tc = new TestClient(acd, sceneA); List <TestClient> destinationTestClients = new List <TestClient>(); EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients); ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, tc, acd); beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32); Assert.That(destinationTestClients.Count, Is.EqualTo(1)); Assert.That(destinationTestClients[0], Is.Not.Null); InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20); sceneA.AttachmentsModule.RezSingleAttachmentFromInventory( beforeTeleportSp, attItem.ID, (uint)AttachmentPoint.Chest); Vector3 teleportPosition = new Vector3(10, 11, 12); Vector3 teleportLookAt = new Vector3(20, 21, 22); // Here, we need to make clientA's receipt of SendRegionTeleport trigger clientB's CompleteMovement(). This // is to operate the teleport V2 mechanism where the EntityTransferModule will first request the client to // CompleteMovement to the region and then call UpdateAgent to the destination region to confirm the receipt // Both these operations will occur on different threads and will wait for each other. // We have to do this via ThreadPool directly since FireAndForget has been switched to sync for the V1 // test protocol, where we are trying to avoid unpredictable async operations in regression tests. tc.OnTestClientSendRegionTeleport += (regionHandle, simAccess, regionExternalEndPoint, locationID, flags, capsURL) => ThreadPool.UnsafeQueueUserWorkItem(o => destinationTestClients[0].CompleteMovement(), null); m_numberOfAttachEventsFired = 0; sceneA.RequestTeleportLocation( beforeTeleportSp.ControllingClient, sceneB.RegionInfo.RegionHandle, teleportPosition, teleportLookAt, (uint)TeleportFlags.ViaLocation); // Check attachments have made it into sceneB ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(ua1.PrincipalID); // This is appearance data, as opposed to actually rezzed attachments List <AvatarAttachment> sceneBAttachments = afterTeleportSceneBSp.Appearance.GetAttachments(); Assert.That(sceneBAttachments.Count, Is.EqualTo(1)); Assert.That(sceneBAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest)); Assert.That(sceneBAttachments[0].ItemID, Is.EqualTo(attItem.ID)); Assert.That(sceneBAttachments[0].AssetID, Is.EqualTo(attItem.AssetID)); Assert.That(afterTeleportSceneBSp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); // This is the actual attachment List <SceneObjectGroup> actualSceneBAttachments = afterTeleportSceneBSp.GetAttachments(); Assert.That(actualSceneBAttachments.Count, Is.EqualTo(1)); SceneObjectGroup actualSceneBAtt = actualSceneBAttachments[0]; Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name)); Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest)); Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1)); // Check attachments have been removed from sceneA ScenePresence afterTeleportSceneASp = sceneA.GetScenePresence(ua1.PrincipalID); // Since this is appearance data, it is still present on the child avatar! List <AvatarAttachment> sceneAAttachments = afterTeleportSceneASp.Appearance.GetAttachments(); Assert.That(sceneAAttachments.Count, Is.EqualTo(1)); Assert.That(afterTeleportSceneASp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); // This is the actual attachment, which should no longer exist List <SceneObjectGroup> actualSceneAAttachments = afterTeleportSceneASp.GetAttachments(); Assert.That(actualSceneAAttachments.Count, Is.EqualTo(0)); Assert.That(sceneA.GetSceneObjectGroups().Count, Is.EqualTo(0)); // Check events Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0)); }
private SceneObjectGroup InternalFromXml2Format(XmlDocument doc, IScene scene) { //MainConsole.Instance.DebugFormat("[SOG]: Starting deserialization of SOG"); //int time = Util.EnvironmentTickCount(); try { XmlNodeList parts = doc.GetElementsByTagName("SceneObjectPart"); if (parts.Count == 0) { MainConsole.Instance.ErrorFormat( "[SERIALIZER]: Deserialization of xml failed: No SceneObjectPart nodes. xml was " + doc.Value); return null; } StringReader sr = new StringReader(parts[0].OuterXml); XmlTextReader reader = new XmlTextReader(sr); SceneObjectGroup sceneObject = new SceneObjectGroup(FromXml(reader), scene); reader.Close(); // Then deal with the rest for (int i = 1; i < parts.Count; i++) { sr = new StringReader(parts[i].OuterXml); reader = new XmlTextReader(sr); SceneObjectPart part = FromXml(reader); sceneObject.AddChild(part, part.LinkNum); part.StoreUndoState(); reader.Close(); } parts = null; doc = null; return sceneObject; } catch (Exception e) { MainConsole.Instance.ErrorFormat("[SERIALIZER]: Deserialization of xml failed with {0}. xml was {1}", e, doc.Value); return null; } }
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; 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 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); } 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); } 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); }
/// <summary> /// Deserialize a scene object from the original xml format /// </summary> /// <param name="fromUserInventoryItemID"></param> /// <param name="xmlData"></param> /// <param name="scene"></param> /// <returns></returns> public ISceneEntity FromOriginalXmlFormat(UUID fromUserInventoryItemID, string xmlData, IRegistryCore scene) { //MainConsole.Instance.DebugFormat("[SOG]: Starting deserialization of SOG"); //int time = Util.EnvironmentTickCount(); try { StringReader sr; XmlTextReader reader; XmlNodeList parts; XmlDocument doc; doc = new XmlDocument(); doc.LoadXml(xmlData); parts = doc.GetElementsByTagName("RootPart"); IScene m_sceneForGroup = scene is IScene ? (IScene) scene : null; ISceneEntity sceneObject; if (parts.Count == 0) { sceneObject = FromXml2Format(xmlData, m_sceneForGroup); if (sceneObject == null) return null; else return sceneObject; } sr = new StringReader(parts[0].InnerXml); reader = new XmlTextReader(sr); sceneObject = new SceneObjectGroup(FromXml(reader), m_sceneForGroup, false); sceneObject.RootChild.FromUserInventoryItemID = fromUserInventoryItemID; reader.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 = FromXml(reader); sceneObject.AddChild(part, part.LinkNum); part.TrimPermissions(); part.StoreUndoState(); reader.Close(); } return sceneObject; } catch (Exception e) { MainConsole.Instance.ErrorFormat( "[SERIALIZER]: Deserialization of xml failed with {0}. xml was {1}", e, xmlData); return null; } }
public void TestSerializeXml2() { TestHelper.InMethod(); //log4net.Config.XmlConfigurator.Configure(); string rpName = "My Little Pony"; UUID rpUuid = UUID.Parse("00000000-0000-0000-0000-000000000064"); UUID rpCreatorId = UUID.Parse("00000000-0000-0000-0000-000000000015"); 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 xml2 = m_serialiserModule.SerializeGroupToXml2(so); XmlTextReader xtr = new XmlTextReader(new StringReader(xml2)); xtr.ReadStartElement("SceneObjectGroup"); 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"); uuid = UUID.Parse(xtr.ReadElementString("Guid")); xtr.ReadEndElement(); break; case "Name": name = xtr.ReadElementContentAsString(); break; case "CreatorID": xtr.ReadStartElement("CreatorID"); creatorId = UUID.Parse(xtr.ReadElementString("Guid")); xtr.ReadEndElement(); break; } } 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)); }
/// <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 & 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.FromItemID = item.ID; } } return(true); }