/// <summary> /// Gather all the asset uuids associated with a given object. /// </summary> /// This includes both those directly associated with /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained /// within this object). /// <param name="sceneObject">The scene object for which to gather assets</param> /// <param name="assetUuids">The assets gathered</param> public void GatherAssetUuids(ISceneEntity sceneObject, IDictionary <UUID, AssetType> assetUuids) { //MainConsole.Instance.DebugFormat( // "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID); ISceneChildEntity [] parts = sceneObject.ChildrenEntities().ToArray(); foreach (ISceneChildEntity part in parts) { //MainConsole.Instance.DebugFormat( // "[Archiver]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID); try { Primitive.TextureEntry textureEntry = part.Shape.Textures; if (textureEntry != null) { // Get the prim's default texture. This will be used for faces which don't have their own texture if (textureEntry.DefaultTexture != null) { assetUuids [textureEntry.DefaultTexture.TextureID] = AssetType.Texture; } if (textureEntry.FaceTextures != null) { // Loop through the rest of the texture faces (a non-null face means the face is different from DefaultTexture) foreach ( Primitive.TextureEntryFace texture in textureEntry.FaceTextures.Where(texture => texture != null)) { assetUuids [texture.TextureID] = AssetType.Texture; } } } // If the prim is a sculpt then preserve this information too if (part.Shape.SculptTexture != UUID.Zero) { assetUuids [part.Shape.SculptTexture] = AssetType.Texture; } TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); // Now analyze this prim's inventory items to preserve all the uuids that they reference foreach ( TaskInventoryItem tii in taskDictionary.Values.Where(tii => !assetUuids.ContainsKey(tii.AssetID))) { if (!assetUuids.ContainsKey(tii.AssetID)) { GatherAssetUuids(tii.AssetID, (AssetType)tii.Type, assetUuids); } } GatherMaterialsUuids(part, assetUuids); } catch (Exception e) { MainConsole.Instance.ErrorFormat("[UUID Gatherer]: Failed to get part - {0}", e); MainConsole.Instance.DebugFormat( "[UUID Gatherer]: Texture entry length for prim was {0} (min is 46)", part.Shape.TextureEntry.Length); } } }
public void llBreakAllLinks() { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return; } ISceneEntity parentPrim = m_host.ParentEntity; if (parentPrim.RootChild.AttachmentPoint != 0) { return; // Fail silently if attached } List <ISceneChildEntity> parts = new List <ISceneChildEntity>(parentPrim.ChildrenEntities()); parts.Remove(parentPrim.RootChild); foreach (ISceneChildEntity part in parts) { parentPrim.DelinkFromGroup(part, true); parentPrim.TriggerScriptChangedEvent(Changed.LINK); part.ParentEntity.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate); } parentPrim.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate); }
/// <summary> /// Synchronously delete the given object from the scene. /// </summary> /// <param name="group">Object Id</param> /// <param name="DeleteScripts">Remove the scripts from the ScriptEngine as well</param> /// <param name="removeFromDatabase">Remove from the database?</param> protected bool DeleteSceneObject(ISceneEntity group, bool DeleteScripts, bool removeFromDatabase) { //MainConsole.Instance.DebugFormat("[Backup]: Deleting scene object {0} {1}", group.Name, group.UUID); lock (group.SitTargetAvatar) { if (group.SitTargetAvatar.Count != 0) { UUID[] ids = new UUID[group.SitTargetAvatar.Count]; group.SitTargetAvatar.CopyTo(ids); foreach (UUID avID in ids) { //Don't screw up avatar's that are sitting on us! IScenePresence SP = m_scene.GetScenePresence(avID); if (SP != null) { SP.StandUp(); } } } } // Serialise calls to RemoveScriptInstances to avoid // deadlocking on m_parts inside SceneObjectGroup if (DeleteScripts) { group.RemoveScriptInstances(true); } foreach (ISceneChildEntity part in group.ChildrenEntities()) { IScriptControllerModule m = m_scene.RequestModuleInterface <IScriptControllerModule>(); if (m != null) { m.RemoveAllScriptControllers(part); } } if (group.RootChild.PhysActor != null) { //Remove us from the physics sim m_scene.PhysicsScene.DeletePrim(group.RootChild.PhysActor); //We MUST leave this to the PhysicsScene or it will hate us forever! //group.RootChild.PhysActor = null; } if (!group.IsAttachment) { m_scene.SimulationDataService.Tainted(); } if (m_scene.SceneGraph.DeleteEntity(group)) { // We need to keep track of this state in case this group is still queued for backup. group.IsDeleted = true; m_scene.EventManager.TriggerObjectBeingRemovedFromScene(group); return(true); } //MainConsole.Instance.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); return(false); }
private void SelectObject(ISceneEntity obj, bool IsNowSelected) { if (obj.IsAttachment) { return; } if (((obj.RootChild.Flags & PrimFlags.TemporaryOnRez) != 0)) { return; } Vector3 pos = obj.AbsolutePosition; ILandObject landObject = m_Scene.RequestModuleInterface <IParcelManagementModule>().GetLandObject(pos.X, pos.Y); LandData landData = landObject.LandData; ParcelCounts parcelCounts; if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts)) { int partCount = obj.ChildrenEntities().Count; if (IsNowSelected) { parcelCounts.Selected += partCount; } else { parcelCounts.Selected -= partCount; } } }
private void DetachSingleAttachmentGroupToInventoryInternal(UUID itemID, IClientAPI remoteClient, bool fireEvent, ISceneEntity group) { if (fireEvent) { m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); group.DetachToInventoryPrep(); } IScenePresence presence = m_scene.GetScenePresence(remoteClient.AgentId); if (presence != null) { AvatarAttachments attModule = presence.RequestModuleInterface <AvatarAttachments>(); if (attModule != null) { attModule.RemoveAttachment(group); } if (attModule != null) { presence.SetAttachments(attModule.Get()); } } MainConsole.Instance.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); //Update the saved attach points if (group.RootChild.AttachedPos != group.RootChild.SavedAttachedPos || group.RootChild.SavedAttachmentPoint != group.RootChild.AttachmentPoint) { group.RootChild.SavedAttachedPos = group.RootChild.AttachedPos; group.RootChild.SavedAttachmentPoint = group.RootChild.AttachmentPoint; //Make sure we get updated group.HasGroupChanged = true; } // If an item contains scripts, it's always changed. // This ensures script state is saved on detach foreach (ISceneChildEntity p in group.ChildrenEntities()) { if (p.Inventory.ContainsScripts()) { group.HasGroupChanged = true; break; } } if (group.HasGroupChanged) { UpdateKnownItem(remoteClient, group, group.RootChild.FromUserInventoryItemID, group.OwnerID); } }
object AuroraEventManager_OnGenericEvent(string FunctionName, object parameters) { if (FunctionName == "DeleteToInventory") { //Resave all the state saves for this object ISceneEntity entity = (ISceneEntity)parameters; foreach (ISceneChildEntity child in entity.ChildrenEntities()) { m_module.SaveStateSaves(child.UUID); } } return(null); }
private void FireDeadAvatarEvent(string KillerName, IScenePresence DeadAv, ISceneEntity killer) { IScriptModule[] scriptEngines = DeadAv.Scene.RequestModuleInterfaces <IScriptModule>(); foreach (IScriptModule m in scriptEngines) { if (killer != null) { foreach (ISceneChildEntity part in killer.ChildrenEntities()) { m.PostObjectEvent(part.UUID, "dead_avatar", new object[] { DeadAv.Name, KillerName, DeadAv.UUID }); } foreach (UUID primID in m_combatModule.PrimCombatServers) { m.PostObjectEvent(primID, "dead_avatar", new object[] { DeadAv.Name, KillerName, DeadAv.UUID }); } } } }
protected void OnObjectBeingAddedToScene(ISceneEntity obj) { lock (m_objectsLock) { foreach (ISceneChildEntity child in obj.ChildrenEntities()) { bool physicalStatus = (child.Flags & PrimFlags.Physics) == PrimFlags.Physics; if (!m_lastAddedPhysicalStatus.ContainsKey(child.UUID)) { m_objects++; //Check physical status now if (physicalStatus) { m_activeObjects++; } //Add it to the list so that we have a record of it m_lastAddedPhysicalStatus.Add(child.UUID, physicalStatus); } else { //Its a dupe! Its a dupe! // Check that the physical status has changed if (physicalStatus != m_lastAddedPhysicalStatus[child.UUID]) { //It changed... fix the count if (physicalStatus) { m_activeObjects++; } else { m_activeObjects--; } //Update the cache m_lastAddedPhysicalStatus[child.UUID] = physicalStatus; } } } } }
protected void OnObjectBeingRemovedFromScene(ISceneEntity obj) { lock (m_objectsLock) { foreach (ISceneChildEntity child in obj.ChildrenEntities()) { bool physicalStatus = (child.Flags & PrimFlags.Physics) == PrimFlags.Physics; if (m_lastAddedPhysicalStatus.ContainsKey(child.UUID)) { m_objects--; //Check physical status now and remove if necessary if (physicalStatus) { m_activeObjects--; } //Remove our record of it m_lastAddedPhysicalStatus.Remove(child.UUID); } } } }
/// <summary> /// Gather all the asset uuids associated with a given object. /// </summary> /// /// This includes both those directly associated with /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained /// within this object). /// /// <param name="sceneObject">The scene object for which to gather assets</param> /// <param name="assetUuids">The assets gathered</param> public void GatherAssetUuids(ISceneEntity sceneObject, IDictionary<UUID, AssetType> assetUuids, IRegistryCore scene) { // m_log.DebugFormat( // "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID); ISceneChildEntity[] parts = sceneObject.ChildrenEntities().ToArray(); for (int i = 0; i < parts.Length; i++) { ISceneChildEntity part = parts[i]; // m_log.DebugFormat( // "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID); try { Primitive.TextureEntry textureEntry = part.Shape.Textures; if (textureEntry != null) { // Get the prim's default texture. This will be used for faces which don't have their own texture if (textureEntry.DefaultTexture != null) assetUuids[textureEntry.DefaultTexture.TextureID] = AssetType.Texture; if (textureEntry.FaceTextures != null) { // Loop through the rest of the texture faces (a non-null face means the face is different from DefaultTexture) foreach (Primitive.TextureEntryFace texture in textureEntry.FaceTextures) { if (texture != null) assetUuids[texture.TextureID] = AssetType.Texture; } } } // If the prim is a sculpt then preserve this information too if (part.Shape.SculptTexture != UUID.Zero) assetUuids[part.Shape.SculptTexture] = AssetType.Texture; TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); // Now analyze this prim's inventory items to preserve all the uuids that they reference foreach (TaskInventoryItem tii in taskDictionary.Values) { // m_log.DebugFormat( // "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}", // tii.Name, tii.Type, part.Name, part.UUID); if (!assetUuids.ContainsKey(tii.AssetID)) GatherAssetUuids(tii.AssetID, (AssetType)tii.Type, assetUuids, scene); } } catch (Exception e) { m_log.ErrorFormat("[UUID GATHERER]: Failed to get part - {0}", e); m_log.DebugFormat( "[UUID GATHERER]: Texture entry length for prim was {0} (min is 46)", part.Shape.TextureEntry.Length); } } }
/// <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="checkPermissions">Which permissions to check: "C" = Copy, "T" = Transfer</param> /// <returns>Whether the user is allowed to export the object to an OAR</returns> private bool CanUserArchiveObject(UUID user, ISceneEntity objGroup, string checkPermissions) { if (checkPermissions == null) { return(true); } IPermissionsModule module = m_scene.RequestModuleInterface <IPermissionsModule>(); if (module == 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 (ISceneChildEntity obj in objGroup.ChildrenEntities()) { uint perm; PermissionClass permissionClass = module.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 (checkPermissions.Contains("C") && !canCopy) { partPermitted = false; } if (checkPermissions.Contains("T") && !canTransfer) { partPermitted = false; } //string name = (objGroup.PrimCount == 1) ? objGroup.Name : string.Format("{0} ({1}/{2})", obj.Name, primNumber, objGroup.PrimCount); //MainConsole.Instance.DebugFormat("[ARCHIVER]: Object permissions: {0}: Base={1:X4}, Owner={2:X4}, Everyone={3:X4}, permissionClass={4}, checkPermissions={5}, canCopy={6}, canTransfer={7}, permitted={8}", // name, obj.BaseMask, obj.OwnerMask, obj.EveryoneMask, // permissionClass, checkPermissions, canCopy, canTransfer, permitted); if (!partPermitted) { permitted = false; break; } //++primNumber; } return(permitted); }
public void llBreakLink(int linknum) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return; } UUID invItemID = InventorySelf(); lock (m_host.TaskInventory) { if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 && !m_automaticLinkPermission) { Error("llBreakLink", "PERMISSION_CHANGE_LINKS permission not set"); return; } } if (linknum < ScriptBaseClass.LINK_THIS) { return; } ISceneEntity parentPrim = m_host.ParentEntity; if (parentPrim.RootChild.AttachmentPoint != 0) { return; // Fail silently if attached } ISceneChildEntity childPrim = null; if (linknum == ScriptBaseClass.LINK_ROOT) { } else if (linknum == ScriptBaseClass.LINK_SET || ScriptBaseClass.LINK_ALL_OTHERS || ScriptBaseClass.LINK_ALL_CHILDREN || ScriptBaseClass.LINK_THIS) { foreach (ISceneChildEntity part in parentPrim.ChildrenEntities()) { if (part.UUID != m_host.UUID) { childPrim = part; break; } } } else { IEntity target = m_host.ParentEntity.GetLinkNumPart(linknum); if (target is ISceneChildEntity) { childPrim = target as ISceneChildEntity; } else { return; } if (childPrim.UUID == m_host.UUID) { childPrim = null; } } if (linknum == ScriptBaseClass.LINK_ROOT) { // Restructuring Multiple Prims. List <ISceneChildEntity> parts = new List <ISceneChildEntity>(parentPrim.ChildrenEntities()); parts.Remove(parentPrim.RootChild); foreach (ISceneChildEntity part in parts) { parentPrim.DelinkFromGroup(part, true); } parentPrim.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate); parentPrim.TriggerScriptChangedEvent(Changed.LINK); if (parts.Count > 0) { ISceneChildEntity newRoot = parts[0]; parts.Remove(newRoot); foreach (ISceneChildEntity part in parts) { newRoot.ParentEntity.LinkToGroup(part.ParentEntity); } newRoot.ParentEntity.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate); } } else { if (childPrim == null) { return; } parentPrim.DelinkFromGroup(childPrim, true); childPrim.ParentEntity.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate); parentPrim.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate); parentPrim.TriggerScriptChangedEvent(Changed.LINK); } }
private void FireDeadAvatarEvent (string KillerName, IScenePresence DeadAv, ISceneEntity killer) { IScriptModule[] scriptEngines = DeadAv.Scene.RequestModuleInterfaces<IScriptModule>(); foreach (IScriptModule m in scriptEngines) { if (killer != null) { foreach (ISceneChildEntity part in killer.ChildrenEntities()) { m.PostObjectEvent(part.UUID, "dead_avatar", new object[] { DeadAv.Name, KillerName, DeadAv.UUID }); } foreach (UUID primID in m_combatModule.PrimCombatServers) { m.PostObjectEvent(primID, "dead_avatar", new object[] { DeadAv.Name, KillerName, DeadAv.UUID }); } } } }
/// <summary> /// Reset all of the UUID's, localID's, etc in this group (includes children) /// </summary> /// <param name="entity"></param> private void ResetEntityIDs(ISceneEntity entity) { List<ISceneChildEntity> children = entity.ChildrenEntities(); //Sort so that we rebuild in the same order and the root being first children.Sort(LinkSetSorter); entity.ClearChildren(); foreach (ISceneChildEntity child in children) { UUID oldID = child.UUID; child.ResetEntityIDs(); entity.AddChild(child, child.LinkNum); } //This clears the xml file, which will need rebuilt now that we have changed the UUIDs entity.HasGroupChanged = true; foreach (ISceneChildEntity child in children) { if (!child.IsRoot) { child.SetParentLocalId(entity.RootChild.LocalId); } } }
/// <summary> /// Move the given scene object into a new region /// </summary> /// <param name="destination"></param> /// <param name="grp">Scene Object Group that we're crossing</param> /// <param name="attemptedPos"></param> /// <returns> /// true if the crossing itself was successful, false on failure /// </returns> protected bool CrossPrimGroupIntoNewRegion(GridRegion destination, ISceneEntity grp, Vector3 attemptedPos) { bool successYN = false; if (destination != null) { if (grp.SitTargetAvatar.Count != 0) { foreach (UUID avID in grp.SitTargetAvatar) { IScenePresence SP = grp.Scene.GetScenePresence(avID); SP.Velocity = grp.RootChild.PhysActor.Velocity; InternalCross(SP, attemptedPos, false, destination); } foreach (ISceneChildEntity part in grp.ChildrenEntities()) { part.SitTargetAvatar = new List <UUID> (); } IBackupModule backup = grp.Scene.RequestModuleInterface <IBackupModule> (); if (backup != null) { return(backup.DeleteSceneObjects(new [] { grp }, false, false)); } return(true); //They do all the work adding the prim in the other region } ISceneEntity copiedGroup = grp.Copy(false); copiedGroup.SetAbsolutePosition(true, attemptedPos); if (grp.Scene != null) { successYN = grp.Scene.RequestModuleInterface <ISimulationService> () .CreateObject(destination, copiedGroup); } if (successYN) { // We remove the object here try { IBackupModule backup = grp.Scene.RequestModuleInterface <IBackupModule> (); if (backup != null) { return(backup.DeleteSceneObjects(new [] { grp }, false, true)); } } catch (Exception e) { MainConsole.Instance.ErrorFormat( "[Entity transfer]: Exception deleting the old object left behind on a border crossing for {0}, {1}", grp, e); } } else { if (!grp.IsDeleted) { if (grp.RootChild.PhysActor != null) { grp.RootChild.PhysActor.CrossingFailure(); } } MainConsole.Instance.ErrorFormat("[Entity transfer]r]: Prim crossing failed for {0}", grp); } } else { MainConsole.Instance.Error( "[Entity transfer]: destination was unexpectedly null in Scene.CrossPrimGroupIntoNewRegion()"); } return(successYN); }
public void StoreObject(ISceneEntity obj, UUID regionUUID) { uint flags = obj.RootChild.GetEffectiveObjectFlags(); // Eligibility check // if ((flags & (uint)PrimFlags.Temporary) != 0) { return; } if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0) { return; } foreach (ISceneChildEntity prim in obj.ChildrenEntities()) { GD.Replace(m_primsRealm, new string[] { "UUID", "CreationDate", "Name", "Text", "Description", "SitName", "TouchName", "ObjectFlags", "OwnerMask", "NextOwnerMask", "GroupMask", "EveryoneMask", "BaseMask", "PositionX", "PositionY", "PositionZ", "GroupPositionX", "GroupPositionY", "GroupPositionZ", "VelocityX", "VelocityY", "VelocityZ", "AngularVelocityX", "AngularVelocityY", "AngularVelocityZ", "AccelerationX", "AccelerationY", "AccelerationZ", "RotationX", "RotationY", "RotationZ", "RotationW", "SitTargetOffsetX", "SitTargetOffsetY", "SitTargetOffsetZ", "SitTargetOrientW", "SitTargetOrientX", "SitTargetOrientY", "SitTargetOrientZ", "RegionUUID", "CreatorID", "OwnerID", "GroupID", "LastOwnerID", "SceneGroupID", "PayPrice", "PayButton1", "PayButton2", "PayButton3", "PayButton4", "LoopedSound", "LoopedSoundGain", "TextureAnimation", "OmegaX", "OmegaY", "OmegaZ", "CameraEyeOffsetX", "CameraEyeOffsetY", "CameraEyeOffsetZ", "CameraAtOffsetX", "CameraAtOffsetY", "CameraAtOffsetZ", "ForceMouselook", "ScriptAccessPin", "AllowedDrop", "DieAtEdge", "SalePrice", "SaleType", "ColorR", "ColorG", "ColorB", "ColorA", "ParticleSystem", "ClickAction", "Material", "CollisionSound", "CollisionSoundVolume", "PassTouches", "LinkNumber", "MediaURL", "Generic" }, new object[] { prim.UUID.ToString(), prim.CreationDate, prim.Name, prim.Text, prim.Description, prim.SitName, prim.TouchName, (uint)prim.Flags, prim.OwnerMask, prim.NextOwnerMask, prim.GroupMask, prim.EveryoneMask, prim.BaseMask, (double)prim.AbsolutePosition.X, (double)prim.AbsolutePosition.Y, (double)prim.AbsolutePosition.Z, (double)prim.GroupPosition.X, (double)prim.GroupPosition.Y, (double)prim.GroupPosition.Z, (double)prim.Velocity.X, (double)prim.Velocity.Y, (double)prim.Velocity.Z, (double)prim.AngularVelocity.X, (double)prim.AngularVelocity.Y, (double)prim.AngularVelocity.Z, (double)prim.Acceleration.X, (double)prim.Acceleration.Y, (double)prim.Acceleration.Z, (double)prim.Rotation.X, (double)prim.Rotation.Y, (double)prim.Rotation.Z, (double)prim.Rotation.W, (double)prim.SitTargetPosition.X, (double)prim.SitTargetPosition.Y, (double)prim.SitTargetPosition.Z, (double)prim.SitTargetOrientation.W, (double)prim.SitTargetOrientation.X, (double)prim.SitTargetOrientation.Y, (double)prim.SitTargetOrientation.Z, regionUUID, prim.CreatorID, prim.OwnerID, prim.GroupID, prim.LastOwnerID, obj.UUID, prim.PayPrice[0], prim.PayPrice[1], prim.PayPrice[2], prim.PayPrice[3], prim.PayPrice[4], ((prim.SoundFlags & 1) == 1) ? prim.Sound : UUID.Zero, ((prim.SoundFlags & 1) == 1) ? prim.SoundGain : 0, prim.TextureAnimation, (double)prim.AngularVelocity.X, (double)prim.AngularVelocity.Y, (double)prim.AngularVelocity.Z, (double)prim.CameraEyeOffset.X, (double)prim.CameraEyeOffset.Y, (double)prim.CameraEyeOffset.Z, (double)prim.CameraEyeOffset.X, (double)prim.CameraEyeOffset.Y, (double)prim.CameraEyeOffset.Z, prim.ForceMouselook ? 1 : 0, prim.ScriptAccessPin, prim.AllowedDrop ? 1 : 0, prim.DIE_AT_EDGE ? 1 : 0, prim.SalePrice, unchecked ((sbyte)(prim.ObjectSaleType)), prim.Color.R, prim.Color.G, prim.Color.B, prim.Color.A, prim.ParticleSystem, unchecked ((sbyte)(prim.ClickAction)), unchecked ((sbyte)(prim.Material)), prim.CollisionSound, prim.CollisionSoundVolume, prim.PassTouch, prim.LinkNum, prim.MediaUrl, prim.GenericData }); GD.Replace(m_primShapesRealm, new string[] { "UUID", "Shape", "ScaleX", "ScaleY", "ScaleZ", "PCode", "PathBegin", "PathEnd", "PathScaleX", "PathScaleY", "PathShearX", "PathShearY", "PathSkew", "PathCurve", "PathRadiusOffset", "PathRevolutions", "PathTaperX", "PathTaperY", "PathTwist", "PathTwistBegin", "ProfileBegin", "ProfileEnd", "ProfileCurve", "ProfileHollow", "Texture", "ExtraParams", "State", "Media" }, new object[] { prim.UUID, 0, (double)prim.Shape.Scale.X, (double)prim.Shape.Scale.Y, (double)prim.Shape.Scale.Z, prim.Shape.PCode, prim.Shape.PathBegin, prim.Shape.PathEnd, prim.Shape.PathScaleX, prim.Shape.PathScaleY, prim.Shape.PathShearX, prim.Shape.PathShearY, prim.Shape.PathSkew, prim.Shape.PathCurve, prim.Shape.PathRadiusOffset, prim.Shape.PathRevolutions, prim.Shape.PathTaperX, prim.Shape.PathTaperY, prim.Shape.PathTwist, prim.Shape.PathTwistBegin, prim.Shape.ProfileBegin, prim.Shape.ProfileEnd, prim.Shape.ProfileCurve, prim.Shape.ProfileHollow, prim.Shape.TextureEntry, prim.Shape.ExtraParams, prim.Shape.State, null == prim.Shape.Media ? null : prim.Shape.Media.ToXml() }); } }
/// <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="checkPermissions">Which permissions to check: "C" = Copy, "T" = Transfer</param> /// <returns>Whether the user is allowed to export the object to an OAR</returns> private bool CanUserArchiveObject(UUID user, ISceneEntity objGroup, string checkPermissions) { if (checkPermissions == null) return true; IPermissionsModule module = m_scene.RequestModuleInterface<IPermissionsModule>(); if (module == 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 (ISceneChildEntity obj in objGroup.ChildrenEntities()) { uint perm; PermissionClass permissionClass = module.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 (checkPermissions.Contains("C") && !canCopy) partPermitted = false; if (checkPermissions.Contains("T") && !canTransfer) partPermitted = false; //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}, permitted={8}", // name, obj.BaseMask, obj.OwnerMask, obj.EveryoneMask, // permissionClass, checkPermissions, canCopy, canTransfer, permitted); if (!partPermitted) { permitted = false; break; } //++primNumber; } return permitted; }
/// <summary> /// Reset all of the UUID's, localID's, etc in this group (includes children) /// </summary> /// <param name="entity"></param> private void ResetEntityIDs (ISceneEntity entity) { List<ISceneChildEntity> children = entity.ChildrenEntities (); //Sort so that we rebuild in the same order and the root being first children.Sort(LinkSetSorter); entity.ClearChildren(); foreach (ISceneChildEntity child in children) { child.ResetEntityIDs(); entity.AddChild(child, child.LinkNum); } }
/// <summary> /// Attach the object to the avatar /// </summary> /// <param name="remoteClient">The client that is having the attachment done</param> /// <param name="localID">The localID (SceneObjectPart) that is being attached (for the attach script event)</param> /// <param name="group">The group (SceneObjectGroup) that is being attached</param> /// <param name="AttachmentPt">The point to where the attachment will go</param> /// <param name="assetID" /> /// <param name="forceUpdatePrim">Force updating of the prim the next time the user attempts to deattach it</param> /// <param name="isTempAttach">Is a temporary attachment</param> protected void FindAttachmentPoint(IClientAPI remoteClient, uint localID, ISceneEntity group, int AttachmentPt, UUID assetID, bool forceUpdatePrim, bool isTempAttach) { //Make sure that we arn't over the limit of attachments ISceneEntity[] attachments = GetAttachmentsForAvatar(remoteClient.AgentId); if (attachments.Length + 1 > m_maxNumberOfAttachments) { //Too many remoteClient.SendAgentAlertMessage( "You are wearing too many attachments. Take one off to attach this object", false); return; } Vector3 attachPos = group.GetAttachmentPos(); bool hasMultipleAttachmentsSet = (AttachmentPt & 0x7f) != 0 || AttachmentPt == 0; if (!m_allowMultipleAttachments) { hasMultipleAttachmentsSet = false; } AttachmentPt &= 0x7f; //Disable it! Its evil! //Did the attachment change position or attachment point? bool changedPositionPoint = false; // If the attachment point isn't the same as the one previously used // set it's offset position = 0 so that it appears on the attachment point // and not in a weird location somewhere unknown. //Simplier terms: the attachment point changed, set it to the default 0,0,0 location if (AttachmentPt != 0 && AttachmentPt != (group.GetAttachmentPoint() & 0x7f)) { attachPos = Vector3.Zero; changedPositionPoint = true; } else { // AttachmentPt 0 means the client chose to 'wear' the attachment. if (AttachmentPt == 0) { // Check object for stored attachment point AttachmentPt = group.GetSavedAttachmentPoint() & 0x7f; attachPos = group.GetAttachmentPos(); } //Check state afterwards... use the newer GetSavedAttachmentPoint and Pos above first if (AttachmentPt == 0) { // Check object for older stored attachment point AttachmentPt = group.RootChild.Shape.State & 0x7f; } // if we still didn't find a suitable attachment point, force it to the default //This happens on the first time an avatar 'wears' an object if (AttachmentPt == 0) { // Stick it on right hand with Zero Offset from the attachment point. AttachmentPt = (int)AttachmentPoint.RightHand; //Default location attachPos = Vector3.Zero; changedPositionPoint = true; } } MainConsole.Instance.DebugFormat( "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2} localID {3}", group.Name, remoteClient.Name, AttachmentPt, group.LocalId); //Update where we are put group.SetAttachmentPoint((byte)AttachmentPt); //Fix the position with the one we found group.AbsolutePosition = attachPos; // Remove any previous attachments IScenePresence presence = m_scene.GetScenePresence(remoteClient.AgentId); if (presence == null) { return; } UUID itemID = UUID.Zero; //Check for multiple attachment bits and whether we should remove the old if (!hasMultipleAttachmentsSet) { foreach (ISceneEntity grp in attachments) { if (grp.GetAttachmentPoint() == (byte)AttachmentPt) { itemID = grp.RootChild.FromUserInventoryItemID; break; } } if (itemID != UUID.Zero) { DetachSingleAttachmentToInventory(itemID, remoteClient); } } itemID = group.RootChild.FromUserInventoryItemID; group.RootChild.AttachedAvatar = presence.UUID; List <ISceneChildEntity> parts = group.ChildrenEntities(); foreach (ISceneChildEntity t in parts) { t.AttachedAvatar = presence.UUID; } if (group.RootChild.PhysActor != null) { m_scene.PhysicsScene.DeletePrim(group.RootChild.PhysActor); group.RootChild.PhysActor = null; } group.RootChild.AttachedPos = attachPos; group.RootChild.IsAttachment = true; group.AbsolutePosition = attachPos; group.RootChild.SetParentLocalId(presence.LocalId); group.SetAttachmentPoint(Convert.ToByte(AttachmentPt)); // Killing it here will cause the client to deselect it // It then reappears on the avatar, deselected // through the full update below if (group.IsSelected) { foreach (ISceneChildEntity part in group.ChildrenEntities()) { part.CreateSelected = true; } } //NOTE: This MUST be here, otherwise we limit full updates during attachments when they are selected and it will block the first update. // So until that is changed, this MUST stay. The client will instantly reselect it, so this value doesn't stay borked for long. group.IsSelected = false; if (!isTempAttach) { if (itemID == UUID.Zero) { //Delete the object inworld to inventory List <ISceneEntity> groups = new List <ISceneEntity>(1) { group }; IInventoryAccessModule inventoryAccess = m_scene.RequestModuleInterface <IInventoryAccessModule>(); if (inventoryAccess != null) { inventoryAccess.DeleteToInventory(DeRezAction.AcquireToUserInventory, UUID.Zero, groups, remoteClient.AgentId, out itemID); } } else { //it came from an item, we need to start the scripts // Fire after attach, so we don't get messy perms dialogs. group.CreateScriptInstances(0, true, StateSource.AttachedRez, UUID.Zero, false); } if (UUID.Zero == itemID) { MainConsole.Instance.Error( "[ATTACHMENTS MODULE]: Unable to save attachment. Error inventory item ID."); remoteClient.SendAgentAlertMessage( "Unable to save attachment. Error inventory item ID.", false); return; } // XXYY!! if (assetID == UUID.Zero) { assetID = m_scene.InventoryService.GetItemAssetID(remoteClient.AgentId, itemID); //Update the ItemID with the new item group.SetFromItemID(itemID, assetID); } } else { // Fire after attach, so we don't get messy perms dialogs. group.CreateScriptInstances(0, true, StateSource.AttachedRez, UUID.Zero, false); group.RootChild.FromUserInventoryItemID = UUID.Zero; } AvatarAttachments attPlugin = presence.RequestModuleInterface <AvatarAttachments>(); if (attPlugin != null) { attPlugin.AddAttachment(group); presence.SetAttachments(attPlugin.Get()); if (!isTempAttach) { IAvatarAppearanceModule appearance = presence.RequestModuleInterface <IAvatarAppearanceModule>(); appearance.Appearance.SetAttachments(attPlugin.Get()); AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); } } // In case it is later dropped again, don't let // it get cleaned up group.RootChild.RemFlag(PrimFlags.TemporaryOnRez); group.HasGroupChanged = changedPositionPoint || forceUpdatePrim; //Now recreate it so that it is selected group.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate); m_scene.EventManager.TriggerOnAttach(localID, group.RootChild.FromUserInventoryItemID, remoteClient.AgentId); }
private void SelectObject(ISceneEntity obj, bool IsNowSelected) { if (obj.IsAttachment) return; if (((obj.RootChild.Flags & PrimFlags.TemporaryOnRez) != 0)) return; Vector3 pos = obj.AbsolutePosition; ILandObject landObject = m_Scene.RequestModuleInterface<IParcelManagementModule>().GetLandObject(pos.X, pos.Y); LandData landData = landObject.LandData; ParcelCounts parcelCounts; if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts)) { int partCount = obj.ChildrenEntities().Count; if (IsNowSelected) parcelCounts.Selected += partCount; else parcelCounts.Selected -= partCount; } }
public ISceneEntity RezSingleAttachmentFromInventory( IClientAPI remoteClient, UUID itemID, UUID assetID, int AttachmentPt, bool updateUUIDs) { MainConsole.Instance.DebugFormat( "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}", (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name); IInventoryAccessModule invAccess = m_scene.RequestModuleInterface <IInventoryAccessModule>(); if (invAccess != null) { InventoryItemBase item = null; ISceneEntity objatt = assetID == UUID.Zero ? invAccess.CreateObjectFromInventory(remoteClient, itemID, out item) : invAccess.CreateObjectFromInventory(remoteClient, itemID, assetID, null); if (objatt != null) { #region Set up object for attachment status if (item != null) { assetID = item.AssetID; // 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. objatt.RootChild.Name = item.Name; objatt.RootChild.Description = item.Description; } objatt.RootChild.Flags |= PrimFlags.Phantom; objatt.RootChild.IsAttachment = true; objatt.SetFromItemID(itemID, assetID); List <ISceneChildEntity> partList = new List <ISceneChildEntity>(objatt.ChildrenEntities()); foreach (ISceneChildEntity part in partList) { part.AttachedAvatar = remoteClient.AgentId; } objatt.SetGroup(remoteClient.ActiveGroupId, remoteClient.AgentId, false); if (objatt.RootChild.OwnerID != remoteClient.AgentId) { //Need to kill the for sale here objatt.RootChild.ObjectSaleType = 0; objatt.RootChild.SalePrice = 10; if (m_scene.Permissions.PropagatePermissions()) { if (item == null) { item = m_scene.InventoryService.GetItem(remoteClient.AgentId, itemID); } if (item == null) { return(null); } if ((item.CurrentPermissions & 8) != 0) { foreach (ISceneChildEntity part in partList) { part.EveryoneMask = item.EveryOnePermissions; part.NextOwnerMask = item.NextPermissions; part.GroupMask = 0; // DO NOT propagate here } } objatt.ApplyNextOwnerPermissions(); } } foreach (ISceneChildEntity part in partList) { if (part.OwnerID != remoteClient.AgentId) { part.LastOwnerID = part.OwnerID; part.OwnerID = remoteClient.AgentId; part.Inventory.ChangeInventoryOwner(remoteClient.AgentId); } } objatt.RootChild.TrimPermissions(); objatt.RootChild.IsAttachment = true; objatt.IsDeleted = false; //Update the ItemID with the new item objatt.SetFromItemID(itemID, assetID); //We also have to reset the IDs so that it doesn't have the same IDs as one inworld (possibly)! ISceneEntity[] atts = GetAttachmentsForAvatar(remoteClient.AgentId); foreach (var obj in atts) { if (obj.UUID == objatt.UUID) { updateUUIDs = false; //If the user is already wearing it, don't readd } } bool forceUpdateOnNextDeattach = false; try { bool foundDuplicate = false; foreach (var obj in atts) { if (obj.RootChild.FromUserInventoryItemID == objatt.RootChild.FromUserInventoryItemID) { foundDuplicate = true; } } IEntity e; if (!m_scene.SceneGraph.TryGetEntity(objatt.UUID, out e)) //if (updateUUIDs) { foreach (var prim in objatt.ChildrenEntities()) { prim.LocalId = 0; } bool success = m_scene.SceneGraph.RestorePrimToScene(objatt, false); if (!success) { MainConsole.Instance.Error("[AttachmentModule]: Failed to add attachment " + objatt.Name + " for user " + remoteClient.Name + "!"); return(null); } } else { if (!foundDuplicate) { //If the user has information stored about this object, we need to force updating next time if (m_scene.SceneGraph.AddPrimToScene(objatt)) { forceUpdateOnNextDeattach = true; } } else { if (e as ISceneEntity != null) { (e as ISceneEntity).ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate); } return(e as ISceneEntity); //It was already added } } } catch { } //If we updated the attachment, we need to save the change IScenePresence presence = m_scene.GetScenePresence(remoteClient.AgentId); if (presence != null) { FindAttachmentPoint(remoteClient, objatt.LocalId, objatt, AttachmentPt, assetID, forceUpdateOnNextDeattach, false); } else { objatt = null; //Presence left, kill the attachment } #endregion } else { MainConsole.Instance.WarnFormat( "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", itemID, remoteClient.Name, AttachmentPt); } return(objatt); } return(null); }
private void CacheCreators(ISceneEntity sog) { //MainConsole.Instance.DebugFormat("[USER MANAGEMENT MODULE]: processing {0} {1}; {2}", sog.RootPart.Name, sog.RootPart.CreatorData, sog.RootPart.CreatorIdentification); AddUser (sog.RootChild.CreatorID, sog.RootChild.CreatorData); foreach (ISceneChildEntity sop in sog.ChildrenEntities()) { AddUser (sop.CreatorID, sop.CreatorData); foreach (TaskInventoryItem item in sop.TaskInventory.Values) AddUser (item.CreatorID, item.CreatorData); } }
public void StoreObject(ISceneEntity obj, UUID regionUUID) { uint flags = obj.RootChild.GetEffectiveObjectFlags (); // Eligibility check // if ((flags & (uint)PrimFlags.Temporary) != 0) return; if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0) return; foreach (ISceneChildEntity prim in obj.ChildrenEntities ()) { GD.Replace (m_primsRealm, new string[] { "UUID", "CreationDate", "Name", "Text", "Description", "SitName", "TouchName", "ObjectFlags", "OwnerMask", "NextOwnerMask", "GroupMask", "EveryoneMask", "BaseMask", "PositionX", "PositionY", "PositionZ", "GroupPositionX", "GroupPositionY", "GroupPositionZ", "VelocityX", "VelocityY", "VelocityZ", "AngularVelocityX", "AngularVelocityY", "AngularVelocityZ", "AccelerationX", "AccelerationY", "AccelerationZ", "RotationX", "RotationY", "RotationZ", "RotationW", "SitTargetOffsetX", "SitTargetOffsetY", "SitTargetOffsetZ", "SitTargetOrientW", "SitTargetOrientX", "SitTargetOrientY", "SitTargetOrientZ", "RegionUUID", "CreatorID", "OwnerID", "GroupID", "LastOwnerID", "SceneGroupID", "PayPrice", "PayButton1", "PayButton2", "PayButton3", "PayButton4", "LoopedSound", "LoopedSoundGain", "TextureAnimation", "OmegaX", "OmegaY", "OmegaZ", "CameraEyeOffsetX", "CameraEyeOffsetY", "CameraEyeOffsetZ", "CameraAtOffsetX", "CameraAtOffsetY", "CameraAtOffsetZ", "ForceMouselook", "ScriptAccessPin", "AllowedDrop", "DieAtEdge", "SalePrice", "SaleType", "ColorR", "ColorG", "ColorB", "ColorA", "ParticleSystem", "ClickAction", "Material", "CollisionSound", "CollisionSoundVolume", "PassTouches", "LinkNumber", "MediaURL", "Generic" }, new object[] { prim.UUID.ToString(), prim.CreationDate, prim.Name, prim.Text, prim.Description, prim.SitName, prim.TouchName, (uint)prim.Flags, prim.OwnerMask, prim.NextOwnerMask, prim.GroupMask, prim.EveryoneMask, prim.BaseMask, (double)prim.AbsolutePosition.X, (double)prim.AbsolutePosition.Y, (double)prim.AbsolutePosition.Z, (double)prim.GroupPosition.X, (double)prim.GroupPosition.Y, (double)prim.GroupPosition.Z, (double)prim.Velocity.X, (double)prim.Velocity.Y, (double)prim.Velocity.Z, (double)prim.AngularVelocity.X, (double)prim.AngularVelocity.Y, (double)prim.AngularVelocity.Z, (double)prim.Acceleration.X, (double)prim.Acceleration.Y, (double)prim.Acceleration.Z, (double)prim.Rotation.X, (double)prim.Rotation.Y, (double)prim.Rotation.Z, (double)prim.Rotation.W, (double)prim.SitTargetPosition.X, (double)prim.SitTargetPosition.Y, (double)prim.SitTargetPosition.Z, (double)prim.SitTargetOrientation.W, (double)prim.SitTargetOrientation.X, (double)prim.SitTargetOrientation.Y, (double)prim.SitTargetOrientation.Z, regionUUID, prim.CreatorID, prim.OwnerID, prim.GroupID, prim.LastOwnerID, obj.UUID, prim.PayPrice[0], prim.PayPrice[1], prim.PayPrice[2], prim.PayPrice[3], prim.PayPrice[4], ((prim.SoundFlags & 1) == 1) ? prim.Sound : UUID.Zero, ((prim.SoundFlags & 1) == 1) ? prim.SoundGain : 0, prim.TextureAnimation, (double)prim.AngularVelocity.X, (double)prim.AngularVelocity.Y, (double)prim.AngularVelocity.Z, (double)prim.CameraEyeOffset.X, (double)prim.CameraEyeOffset.Y, (double)prim.CameraEyeOffset.Z, (double)prim.CameraEyeOffset.X, (double)prim.CameraEyeOffset.Y, (double)prim.CameraEyeOffset.Z, prim.ForceMouselook ? 1 : 0, prim.ScriptAccessPin, prim.AllowedDrop ? 1 : 0, prim.DIE_AT_EDGE ? 1 : 0, prim.SalePrice, unchecked((sbyte)(prim.ObjectSaleType)), prim.Color.R, prim.Color.G, prim.Color.B, prim.Color.A, prim.ParticleSystem, unchecked((sbyte)(prim.ClickAction)), unchecked((sbyte)(prim.Material)), prim.CollisionSound, prim.CollisionSoundVolume, prim.PassTouch, prim.LinkNum, prim.MediaUrl, prim.GenericData }); GD.Replace (m_primShapesRealm, new string[] { "UUID", "Shape", "ScaleX", "ScaleY", "ScaleZ", "PCode", "PathBegin", "PathEnd", "PathScaleX", "PathScaleY", "PathShearX", "PathShearY", "PathSkew", "PathCurve", "PathRadiusOffset", "PathRevolutions", "PathTaperX", "PathTaperY", "PathTwist", "PathTwistBegin", "ProfileBegin", "ProfileEnd", "ProfileCurve", "ProfileHollow", "Texture", "ExtraParams", "State", "Media" }, new object[] { prim.UUID, 0, (double)prim.Shape.Scale.X, (double)prim.Shape.Scale.Y, (double)prim.Shape.Scale.Z, prim.Shape.PCode, prim.Shape.PathBegin, prim.Shape.PathEnd, prim.Shape.PathScaleX, prim.Shape.PathScaleY, prim.Shape.PathShearX, prim.Shape.PathShearY, prim.Shape.PathSkew, prim.Shape.PathCurve, prim.Shape.PathRadiusOffset, prim.Shape.PathRevolutions, prim.Shape.PathTaperX, prim.Shape.PathTaperY, prim.Shape.PathTwist, prim.Shape.PathTwistBegin, prim.Shape.ProfileBegin, prim.Shape.ProfileEnd, prim.Shape.ProfileCurve, prim.Shape.ProfileHollow, prim.Shape.TextureEntry, prim.Shape.ExtraParams, prim.Shape.State, null == prim.Shape.Media ? null : prim.Shape.Media.ToXml() }); } }
// NOTE: Call under Taint Lock private void RemoveObject(ISceneEntity obj) { if (obj.IsAttachment) { return; } if (((obj.RootChild.Flags & PrimFlags.TemporaryOnRez) != 0)) { return; } Vector3 pos = obj.AbsolutePosition; ILandObject landObject = m_Scene.RequestModuleInterface <IParcelManagementModule>().GetLandObject(pos.X, pos.Y); if (landObject == null) { landObject = m_Scene.RequestModuleInterface <IParcelManagementModule>().GetNearestAllowedParcel( UUID.Zero, pos.X, pos.Y); } if (landObject == null) { return; } LandData landData = landObject.LandData; ParcelCounts parcelCounts; if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts)) { UUID landOwner = landData.OwnerID; foreach (ISceneChildEntity child in obj.ChildrenEntities()) { if (!parcelCounts.Objects.ContainsKey(child.UUID)) { //Well... now what? } else { parcelCounts.Objects.Remove(child.UUID); if (m_SimwideCounts.ContainsKey(landOwner)) { m_SimwideCounts[landOwner] -= 1; } if (parcelCounts.Users.ContainsKey(obj.OwnerID)) { parcelCounts.Users[obj.OwnerID] -= 1; } if (landData.IsGroupOwned) { if (obj.OwnerID == landData.GroupID) { parcelCounts.Owner -= 1; } else if (obj.GroupID == landData.GroupID) { parcelCounts.Group -= 1; } else { parcelCounts.Others -= 1; } } else { if (obj.OwnerID == landData.OwnerID) { parcelCounts.Owner -= 1; } else if (obj.GroupID == landData.GroupID) { parcelCounts.Group -= 1; } else { parcelCounts.Others -= 1; } } } } } }
private void DetachSingleAttachmentGroupToInventoryInternal (UUID itemID, IClientAPI remoteClient, bool fireEvent, ISceneEntity group) { if (fireEvent) { m_scene.EventManager.TriggerOnAttach (group.LocalId, itemID, UUID.Zero); group.DetachToInventoryPrep (); } IScenePresence presence = m_scene.GetScenePresence (remoteClient.AgentId); if (presence != null) { AvatarAttachments attModule = presence.RequestModuleInterface<AvatarAttachments> (); if (attModule != null) attModule.RemoveAttachment (group); presence.RemoveAttachment (group); } m_log.Debug ("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint ()).ToString ()); //Update the saved attach points if (group.RootChild.AttachedPos != group.RootChild.SavedAttachedPos || group.RootChild.SavedAttachmentPoint != group.RootChild.AttachmentPoint) { group.RootChild.SavedAttachedPos = group.RootChild.AttachedPos; group.RootChild.SavedAttachmentPoint = group.RootChild.AttachmentPoint; //Make sure we get updated group.HasGroupChanged = true; } // If an item contains scripts, it's always changed. // This ensures script state is saved on detach foreach (ISceneChildEntity p in group.ChildrenEntities ()) { if (p.Inventory.ContainsScripts ()) { group.HasGroupChanged = true; break; } } UpdateKnownItem (remoteClient, group, group.RootChild.FromUserInventoryItemID, group.OwnerID); }
/// <summary> /// Synchronously delete the given object from the scene. /// </summary> /// <param name="group">Object Id</param> /// <param name="DeleteScripts">Remove the scripts from the ScriptEngine as well</param> /// <param name="removeFromDatabase">Remove from the database?</param> protected bool DeleteSceneObject(ISceneEntity group, bool DeleteScripts, bool removeFromDatabase) { //m_log.DebugFormat("[Backup]: Deleting scene object {0} {1}", group.Name, group.UUID); lock (group.SitTargetAvatar) { if (group.SitTargetAvatar.Count != 0) { UUID[] ids = new UUID[group.SitTargetAvatar.Count]; group.SitTargetAvatar.CopyTo(ids); foreach (UUID avID in ids) { //Don't screw up avatar's that are sitting on us! IScenePresence SP = m_scene.GetScenePresence(avID); if (SP != null) SP.StandUp(); } } } // Serialise calls to RemoveScriptInstances to avoid // deadlocking on m_parts inside SceneObjectGroup if (DeleteScripts) { group.RemoveScriptInstances(true); } foreach (ISceneChildEntity part in group.ChildrenEntities()) { IScriptControllerModule m = m_scene.RequestModuleInterface<IScriptControllerModule>(); if(m != null) m.RemoveAllScriptControllers(part); if (part.PhysActor != null) { //Remove us from the physics sim m_scene.PhysicsScene.RemovePrim(part.PhysActor); //We MUST leave this to the PhysicsScene or it will hate us forever! //part.PhysActor = null; } } m_scene.SimulationDataService.Tainted (); if (m_scene.SceneGraph.DeleteEntity(group)) { // We need to keep track of this state in case this group is still queued for backup. group.IsDeleted = true; //Clear the update schedule HERE so that IsDeleted will not have to fire as well foreach (ISceneChildEntity part in group.ChildrenEntities ()) { //Make sure it isn't going to be updated again part.ClearUpdateSchedule (); } m_scene.EventManager.TriggerObjectBeingRemovedFromScene(group); return true; } //m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); return false; }
/// <summary> /// Gather all the asset uuids associated with a given object. /// </summary> /// This includes both those directly associated with /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained /// within this object). /// <param name="sceneObject">The scene object for which to gather assets</param> /// <param name="assetUuids">The assets gathered</param> public void GatherAssetUuids (ISceneEntity sceneObject, IDictionary<UUID, AssetType> assetUuids) { //MainConsole.Instance.DebugFormat("[Asset Gatherer]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID); ISceneChildEntity [] parts = sceneObject.ChildrenEntities ().ToArray (); foreach (ISceneChildEntity part in parts) { //MainConsole.Instance.DebugFormat("[Archiver]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID); try { Primitive.TextureEntry textureEntry = part.Shape.Textures; if (textureEntry != null) { // Get the prim's default texture. This will be used for faces which don't have their own texture if (textureEntry.DefaultTexture != null) assetUuids [textureEntry.DefaultTexture.TextureID] = AssetType.Texture; if (textureEntry.FaceTextures != null) { // Loop through the rest of the texture faces (a non-null face means the face is different from DefaultTexture) foreach ( Primitive.TextureEntryFace texture in textureEntry.FaceTextures.Where (texture => texture != null)) { assetUuids [texture.TextureID] = AssetType.Texture; } } } // If the prim is a sculpt then preserve this information too if (part.Shape.SculptTexture != UUID.Zero) assetUuids [part.Shape.SculptTexture] = AssetType.Texture; TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone (); // Now analyze this prim's inventory items to preserve all the uuids that they reference foreach ( TaskInventoryItem tii in taskDictionary.Values.Where (tii => !assetUuids.ContainsKey (tii.AssetID))) { if (!assetUuids.ContainsKey (tii.AssetID)) GatherAssetUuids (tii.AssetID, (AssetType)tii.Type, assetUuids); } GatherMaterialsUuids (part, assetUuids); } catch (Exception e) { MainConsole.Instance.ErrorFormat ("[UUID Gatherer]: Failed to get part - {0}", e); MainConsole.Instance.DebugFormat ("[UUID Gatherer]: Texture entry length for prim was {0} (min is 46)", part.Shape.TextureEntry.Length); } } }
// NOTE: Call under Taint Lock private void RemoveObject(ISceneEntity obj) { if (obj.IsAttachment) return; if (((obj.RootChild.Flags & PrimFlags.TemporaryOnRez) != 0)) return; IParcelManagementModule parcelManagment = m_Scene.RequestModuleInterface<IParcelManagementModule>(); Vector3 pos = obj.AbsolutePosition; ILandObject landObject = parcelManagment.GetLandObject(pos.X, pos.Y) ?? parcelManagment.GetNearestAllowedParcel(UUID.Zero, pos.X, pos.Y); if (landObject == null) return; LandData landData = landObject.LandData; ParcelCounts parcelCounts; if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts)) { UUID landOwner = landData.OwnerID; foreach (ISceneChildEntity child in obj.ChildrenEntities()) { bool foundit = false; if (!parcelCounts.Objects.ContainsKey(child.UUID)) { //was not found, lets look through all the parcels foreach (ILandObject parcel in parcelManagment.AllParcels()) { landData = parcel.LandData; if (!m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts)) continue; landOwner = landData.OwnerID; if (!parcelCounts.Objects.ContainsKey(child.UUID)) continue; foundit = true; break; } } else foundit = true; if (!foundit) continue; parcelCounts.Objects.Remove(child.UUID); if (m_SimwideCounts.ContainsKey(landOwner)) m_SimwideCounts[landOwner] -= 1; if (parcelCounts.Users.ContainsKey(obj.OwnerID)) parcelCounts.Users[obj.OwnerID] -= 1; if (landData.IsGroupOwned) { if (obj.OwnerID == landData.GroupID) parcelCounts.Owner -= 1; else if (obj.GroupID == landData.GroupID) parcelCounts.Group -= 1; else parcelCounts.Others -= 1; } else { if (obj.OwnerID == landData.OwnerID) parcelCounts.Owner -= 1; else if (obj.GroupID == landData.GroupID) parcelCounts.Group -= 1; else parcelCounts.Others -= 1; } } } }
public bool LinkPartToSOG(ISceneEntity grp, ISceneChildEntity part, int linkNum) { part.SetParentLocalId(grp.RootChild.LocalId); part.SetParent(grp); // Insert in terms of link numbers, the new links // before the current ones (with the exception of // the root prim. Shuffle the old ones up foreach (ISceneChildEntity otherPart in grp.ChildrenEntities()) { if (otherPart.LinkNum >= linkNum) { // Don't update root prim link number otherPart.LinkNum += 1; } } part.LinkNum = linkNum; return LinkPartToEntity(grp, part); }
public RegionData LoadBackup(string file) { if (!File.Exists(file)) { return(null); } var stream = ArchiveHelpers.GetStream(file); if (stream == null) { return(null); } GZipStream m_loadStream = new GZipStream(stream, CompressionMode.Decompress); TarArchiveReader reader = new TarArchiveReader(m_loadStream); List <uint> foundLocalIDs = new List <uint>(); RegionData regiondata = new RegionData(); regiondata.Init(); byte[] data; string filePath; TarArchiveReader.TarEntryType entryType; System.Collections.Concurrent.ConcurrentQueue <byte[]> groups = new System.Collections.Concurrent.ConcurrentQueue <byte[]>(); //Load the archive data that we need while ((data = reader.ReadEntry(out filePath, out entryType)) != null) { if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType) { continue; } if (filePath.StartsWith("parcels/")) { //Only use if we are not merging LandData parcel = new LandData(); OSD parcelData = OSDParser.DeserializeLLSDBinary(data); parcel.FromOSD((OSDMap)parcelData); if (parcel.OwnerID != UUID.Parse("05948863-b678-433e-87a4-e44d17678d1d")) { //The default owner of the 'default' region regiondata.Parcels.Add(parcel); } } else if (filePath.StartsWith("newstyleterrain/")) { regiondata.Terrain = data; } else if (filePath.StartsWith("newstylerevertterrain/")) { regiondata.RevertTerrain = data; } else if (filePath.StartsWith("newstylewater/")) { regiondata.Water = data; } else if (filePath.StartsWith("newstylerevertwater/")) { regiondata.RevertWater = data; } else if (filePath.StartsWith("entities/")) { groups.Enqueue(data); } else if (filePath.StartsWith("regioninfo/")) { RegionInfo info = new RegionInfo(); info.FromOSD((OSDMap)OSDParser.DeserializeLLSDBinary(data)); regiondata.RegionInfo = info; } data = null; } m_loadStream.Close(); m_loadStream = null; int threadCount = groups.Count > 16 ? 16 : groups.Count; System.Threading.Thread[] threads = new System.Threading.Thread[threadCount]; for (int i = 0; i < threadCount; i++) { threads[i] = new System.Threading.Thread(() => { byte[] groupData; while (groups.TryDequeue(out groupData)) { MemoryStream ms = new MemoryStream(groupData); ISceneEntity sceneObject = SceneEntitySerializer.SceneObjectSerializer .FromXml2Format(ref ms, null); ms.Close(); ms = null; data = null; if (sceneObject != null) { foreach ( ISceneChildEntity part in sceneObject.ChildrenEntities()) { lock (foundLocalIDs) { if ( !foundLocalIDs.Contains( part.LocalId)) { foundLocalIDs.Add(part.LocalId); } else { part.LocalId = 0; } //Reset it! Only use it once! } } regiondata.Groups.Add( sceneObject as SceneObjectGroup); } } }); threads[i].Start(); } for (int i = 0; i < threadCount; i++) { threads[i].Join(); } foundLocalIDs.Clear(); return(regiondata); }
// NOTE: Call under Taint Lock private void RemoveObject(ISceneEntity obj) { if (obj.IsAttachment) return; if (((obj.RootChild.Flags & PrimFlags.TemporaryOnRez) != 0)) return; Vector3 pos = obj.AbsolutePosition; ILandObject landObject = m_Scene.RequestModuleInterface<IParcelManagementModule>().GetLandObject(pos.X, pos.Y); if (landObject == null) landObject = m_Scene.RequestModuleInterface<IParcelManagementModule>().GetNearestAllowedParcel(UUID.Zero, pos.X, pos.Y); if (landObject == null) return; LandData landData = landObject.LandData; ParcelCounts parcelCounts; if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts)) { UUID landOwner = landData.OwnerID; foreach (ISceneChildEntity child in obj.ChildrenEntities()) { if (!parcelCounts.Objects.ContainsKey(child.UUID)) { //Well... now what? } else { parcelCounts.Objects.Remove(child.UUID); if (m_SimwideCounts.ContainsKey(landOwner)) m_SimwideCounts[landOwner] -= 1; if (parcelCounts.Users.ContainsKey(obj.OwnerID)) parcelCounts.Users[obj.OwnerID] -= 1; if (landData.IsGroupOwned) { if (obj.OwnerID == landData.GroupID) parcelCounts.Owner -= 1; else if (obj.GroupID == landData.GroupID) parcelCounts.Group -= 1; else parcelCounts.Others -= 1; } else { if (obj.OwnerID == landData.OwnerID) parcelCounts.Owner -= 1; else if (obj.GroupID == landData.GroupID) parcelCounts.Group -= 1; else parcelCounts.Others -= 1; } } } } }
/// <summary> /// Add the Entity to the Scene and back it up, but do NOT reset its ID's /// </summary> /// <param name="entity"></param> /// <returns></returns> public bool RestorePrimToScene(ISceneEntity entity) { List<ISceneChildEntity> children = entity.ChildrenEntities (); //Sort so that we rebuild in the same order and the root being first children.Sort(LinkSetSorter); entity.ClearChildren(); foreach (ISceneChildEntity child in children) { if (((SceneObjectPart)child).PhysActor != null) ((SceneObjectPart)child).PhysActor.LocalID = child.LocalId; if (child.LocalId == 0) child.LocalId = AllocateLocalId(); entity.AddChild(child, child.LinkNum); } //Tell the entity that they are being added to a scene entity.AttachToScene(m_parentScene); //Now save the entity that we have return AddEntity(entity, false); }
public bool BuyObject(IClientAPI remoteClient, UUID categoryID, uint localID, byte saleType, int salePrice) { ISceneChildEntity part = m_scene.GetSceneObjectPart(localID); if (part == null) { return(false); } if (part.ParentEntity == null) { return(false); } ISceneEntity group = part.ParentEntity; ILLClientInventory inventoryModule = m_scene.RequestModuleInterface <ILLClientInventory>(); switch (saleType) { case 1: // Sell as original (in-place sale) uint effectivePerms = group.GetEffectivePermissions(); if ((effectivePerms & (uint)PermissionMask.Transfer) == 0) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale"); } return(false); } group.SetOwnerId(remoteClient.AgentId); group.SetRootPartOwner(part, remoteClient.AgentId, remoteClient.ActiveGroupId); if (m_scene.Permissions.PropagatePermissions()) { foreach (ISceneChildEntity child in group.ChildrenEntities()) { child.Inventory.ChangeInventoryOwner(remoteClient.AgentId); child.TriggerScriptChangedEvent(Changed.OWNER); child.ApplyNextOwnerPermissions(); } } part.ObjectSaleType = 0; part.SalePrice = 10; group.HasGroupChanged = true; part.GetProperties(remoteClient); part.TriggerScriptChangedEvent(Changed.OWNER); group.ResumeScripts(); part.ScheduleUpdate(PrimUpdateFlags.ForcedFullUpdate); break; case 2: // Sell a copy Vector3 inventoryStoredPosition = new Vector3 (((group.AbsolutePosition.X > m_scene.RegionInfo.RegionSizeX) ? m_scene.RegionInfo.RegionSizeX - 1 : group.AbsolutePosition.X) , (group.AbsolutePosition.X > m_scene.RegionInfo.RegionSizeY) ? m_scene.RegionInfo.RegionSizeY - 1 : group.AbsolutePosition.X, group.AbsolutePosition.Z); Vector3 originalPosition = group.AbsolutePosition; group.AbsolutePosition = inventoryStoredPosition; string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat((SceneObjectGroup)group); group.AbsolutePosition = originalPosition; uint perms = group.GetEffectivePermissions(); if ((perms & (uint)PermissionMask.Transfer) == 0) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale"); } return(false); } AssetBase asset = new AssetBase(UUID.Random(), part.Name, AssetType.Object, group.OwnerID) { Description = part.Description, Data = Utils.StringToBytes(sceneObjectXml) }; asset.ID = m_scene.AssetService.Store(asset); InventoryItemBase item = new InventoryItemBase { CreatorId = part.CreatorID.ToString(), CreatorData = part.CreatorData, ID = UUID.Random(), Owner = remoteClient.AgentId, AssetID = asset.ID, Description = asset.Description, Name = asset.Name, AssetType = asset.Type, InvType = (int)InventoryType.Object, Folder = categoryID }; uint nextPerms = (perms & 7) << 13; if ((nextPerms & (uint)PermissionMask.Copy) == 0) { perms &= ~(uint)PermissionMask.Copy; } if ((nextPerms & (uint)PermissionMask.Transfer) == 0) { perms &= ~(uint)PermissionMask.Transfer; } if ((nextPerms & (uint)PermissionMask.Modify) == 0) { perms &= ~(uint)PermissionMask.Modify; } item.BasePermissions = perms & part.NextOwnerMask; item.CurrentPermissions = perms & part.NextOwnerMask; item.NextPermissions = part.NextOwnerMask; item.EveryOnePermissions = part.EveryoneMask & part.NextOwnerMask; item.GroupPermissions = part.GroupMask & part.NextOwnerMask; item.CurrentPermissions |= 16; // Slam! item.CreationDate = Util.UnixTimeSinceEpoch(); if (inventoryModule != null) { if (inventoryModule.AddInventoryItem(item)) { remoteClient.SendInventoryItemCreateUpdate(item, 0); } else { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "Cannot buy now. Your inventory is unavailable"); } return(false); } } break; case 3: // Sell contents List <UUID> invList = part.Inventory.GetInventoryList(); #if (!ISWIN) bool okToSell = true; foreach (UUID invId in invList) { TaskInventoryItem item1 = part.Inventory.GetInventoryItem(invId); if ((item1.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) { okToSell = false; break; } } #else bool okToSell = invList.Select(invID => part.Inventory.GetInventoryItem(invID)).All(item1 => (item1.CurrentPermissions & (uint)PermissionMask.Transfer) != 0); #endif if (!okToSell) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser( remoteClient, "This item's inventory doesn't appear to be for sale"); } return(false); } if (invList.Count > 0) { if (inventoryModule != null) { inventoryModule.MoveTaskInventoryItemsToUserInventory(remoteClient.AgentId, part.Name, part, invList); } } break; } return(true); }
/// <summary> /// Attach the object to the avatar /// </summary> /// <param name="remoteClient">The client that is having the attachment done</param> /// <param name="localID">The localID (SceneObjectPart) that is being attached (for the attach script event)</param> /// <param name="group">The group (SceneObjectGroup) that is being attached</param> /// <param name="AttachmentPt">The point to where the attachment will go</param> /// <param name="item">If this is not null, it saves a query in this method to the InventoryService /// This is the Item that the object is in (if it is in one yet)</param> protected void FindAttachmentPoint (IClientAPI remoteClient, uint localID, ISceneEntity group, int AttachmentPt, InventoryItemBase item) { //Make sure that we arn't over the limit of attachments ISceneEntity[] attachments = GetAttachmentsForAvatar (remoteClient.AgentId); if (attachments.Length + 1 > m_maxNumberOfAttachments) { //Too many remoteClient.SendAgentAlertMessage( "You are wearing too many attachments. Take one off to attach this object", false); return; } Vector3 attachPos = group.GetAttachmentPos(); bool hasMultipleAttachmentsSet = (AttachmentPt & 0x7f) != 0 || AttachmentPt == 0; if(!m_allowMultipleAttachments) hasMultipleAttachmentsSet = false; AttachmentPt &= 0x7f; //Disable it! Its evil! //Did the attachment change position or attachment point? bool changedPositionPoint = false; // If the attachment point isn't the same as the one previously used // set it's offset position = 0 so that it appears on the attachment point // and not in a weird location somewhere unknown. //Simplier terms: the attachment point changed, set it to the default 0,0,0 location if (AttachmentPt != 0 && AttachmentPt != (int)(group.GetAttachmentPoint() & 0x7f)) { attachPos = Vector3.Zero; changedPositionPoint = true; } else { // AttachmentPt 0 means the client chose to 'wear' the attachment. if (AttachmentPt == 0) { // Check object for stored attachment point AttachmentPt = (int)group.GetSavedAttachmentPoint() & 0x7f; attachPos = group.GetAttachmentPos(); } //Check state afterwards... use the newer GetSavedAttachmentPoint and Pos above first if (AttachmentPt == 0) { // Check object for older stored attachment point AttachmentPt = group.RootChild.Shape.State & 0x7f; //attachPos = group.AbsolutePosition; } // if we still didn't find a suitable attachment point, force it to the default //This happens on the first time an avatar 'wears' an object if (AttachmentPt == 0) { // Stick it on right hand with Zero Offset from the attachment point. AttachmentPt = (int)AttachmentPoint.RightHand; //Default location attachPos = Vector3.Zero; changedPositionPoint = true; } } group.HasGroupChanged = changedPositionPoint; //Update where we are put group.SetAttachmentPoint((byte)AttachmentPt); //Fix the position with the one we found group.AbsolutePosition = attachPos; // Remove any previous attachments IScenePresence presence = m_scene.GetScenePresence (remoteClient.AgentId); if (presence == null) return; UUID itemID = UUID.Zero; //Check for multiple attachment bits and whether we should remove the old if(!hasMultipleAttachmentsSet) { foreach (ISceneEntity grp in attachments) { if (grp.GetAttachmentPoint() == (byte)AttachmentPt) { itemID = grp.RootChild.FromUserInventoryItemID; break; } } if (itemID != UUID.Zero) DetachSingleAttachmentToInventory(itemID, remoteClient); } itemID = group.RootChild.FromUserInventoryItemID; group.RootChild.AttachedAvatar = presence.UUID; List<ISceneChildEntity> parts = group.ChildrenEntities(); for (int i = 0; i < parts.Count; i++) parts[i].AttachedAvatar = presence.UUID; if (group.RootChild.PhysActor != null) { m_scene.PhysicsScene.RemovePrim (group.RootChild.PhysActor); group.RootChild.PhysActor = null; } group.RootChild.AttachedPos = attachPos; group.RootChild.IsAttachment = true; group.AbsolutePosition = attachPos; group.RootChild.SetParentLocalId (presence.LocalId); group.SetAttachmentPoint(Convert.ToByte(AttachmentPt)); AvatarAttachments attPlugin = presence.RequestModuleInterface<AvatarAttachments>(); if (attPlugin != null) { attPlugin.AddAttachment (group); presence.AddAttachment (group); } // Killing it here will cause the client to deselect it // It then reappears on the avatar, deselected // through the full update below // if (group.IsSelected) { foreach (ISceneChildEntity part in group.ChildrenEntities()) { part.CreateSelected = true; } } //Kill the previous entity so that it will be selected SendKillEntity(group.RootChild); //NOTE: This MUST be here, otherwise we limit full updates during attachments when they are selected and it will block the first update. // So until that is changed, this MUST stay. The client will instantly reselect it, so this value doesn't stay borked for long. group.IsSelected = false; if (itemID == UUID.Zero) { //Delete the object inworld to inventory List<ISceneEntity> groups = new List<ISceneEntity> (1) { group }; IInventoryAccessModule inventoryAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); if (inventoryAccess != null) inventoryAccess.DeleteToInventory(DeRezAction.AcquireToUserInventory, UUID.Zero, groups, remoteClient.AgentId, out itemID); } else { //it came from an item, we need to start the scripts // Fire after attach, so we don't get messy perms dialogs // 4 == AttachedRez group.CreateScriptInstances(0, true, StateSource.AttachedRez, UUID.Zero); group.ResumeScripts(); } if (UUID.Zero == itemID) { m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment. Error inventory item ID."); remoteClient.SendAgentAlertMessage( "Unable to save attachment. Error inventory item ID.", false); return; } // XXYY!! if (item == null) { item = new InventoryItemBase(itemID, remoteClient.AgentId); item = m_scene.InventoryService.GetItem(item); } //Update the ItemID with the new item group.SetFromItemID (itemID); //If we updated the attachment, we need to save the change IAvatarAppearanceModule appearance = presence.RequestModuleInterface<IAvatarAppearanceModule> (); if (appearance.Appearance.SetAttachment ((int)AttachmentPt, itemID, item.AssetID)) AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); // In case it is later dropped again, don't let // it get cleaned up group.RootChild.RemFlag(PrimFlags.TemporaryOnRez); group.HasGroupChanged = false; //Now recreate it so that it is selected group.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate); m_scene.EventManager.TriggerOnAttach(localID, group.RootChild.FromUserInventoryItemID, remoteClient.AgentId); }
/// <summary> /// Synchronously delete the given object from the scene. /// </summary> /// <param name="group">Object Id</param> /// <param name="DeleteScripts">Remove the scripts from the ScriptEngine as well</param> /// <param name="removeFromDatabase">Remove from the database?</param> protected bool DeleteSceneObject(ISceneEntity group, bool DeleteScripts, bool removeFromDatabase) { //MainConsole.Instance.DebugFormat("[Backup]: Deleting scene object {0} {1}", group.Name, group.UUID); if (group.SitTargetAvatar.Count != 0) { foreach (UUID avID in group.SitTargetAvatar) { //Don't screw up avatar's that are sitting on us! IScenePresence SP = m_scene.GetScenePresence(avID); if (SP != null) SP.StandUp(); } } // Serialise calls to RemoveScriptInstances to avoid // deadlocking on m_parts inside SceneObjectGroup if (DeleteScripts) { group.RemoveScriptInstances(true); } foreach (ISceneChildEntity part in group.ChildrenEntities()) { IScriptControllerModule m = m_scene.RequestModuleInterface<IScriptControllerModule>(); if (m != null) m.RemoveAllScriptControllers(part); } if (group.RootChild.PhysActor != null) { //Remove us from the physics sim m_scene.PhysicsScene.DeletePrim(group.RootChild.PhysActor); group.RootChild.PhysActor = null; } if (!group.IsAttachment) m_scene.SimulationDataService.Tainted(); if (m_scene.SceneGraph.DeleteEntity(group)) { // We need to keep track of this state in case this group is still queued for backup. group.IsDeleted = true; m_scene.EventManager.TriggerObjectBeingRemovedFromScene(group); return true; } //MainConsole.Instance.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); return false; }
/// <summary> /// Load an asset /// </summary> /// <param name="assetPath"> </param> /// <param name="data"></param> /// <returns>true if asset was successfully loaded, false otherwise</returns> private bool LoadAsset(string assetPath, byte[] data) { //IRegionSerialiser serialiser = scene.RequestModuleInterface<IRegionSerialiser>(); // Right now we're nastily obtaining the UUID from the filename string filename = assetPath.Remove(0, ArchiveConstants.ASSETS_PATH.Length); int i = filename.LastIndexOf(ArchiveConstants.ASSET_EXTENSION_SEPARATOR); if (i == -1) { MainConsole.Instance.ErrorFormat( "[INVENTORY ARCHIVER]: Could not find extension information in asset path {0} since it's missing the separator {1}. Skipping", assetPath, ArchiveConstants.ASSET_EXTENSION_SEPARATOR); return(false); } string extension = filename.Substring(i); string uuid = filename.Remove(filename.Length - extension.Length); if (ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension)) { AssetType assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; if (assetType == AssetType.Unknown) { MainConsole.Instance.WarnFormat( "[INVENTORY ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, uuid); } else if (assetType == AssetType.Object) { string xmlData = Utils.BytesToString(data); ISceneEntity sceneObject = SceneEntitySerializer.SceneObjectSerializer.FromOriginalXmlFormat( xmlData, m_registry); if (sceneObject != null) { if (m_creatorIdForAssetId.ContainsKey(UUID.Parse(uuid))) { foreach ( ISceneChildEntity sop in from sop in sceneObject.ChildrenEntities() where string.IsNullOrEmpty(sop.CreatorData) select sop) { sop.CreatorID = m_creatorIdForAssetId[UUID.Parse(uuid)]; } } foreach (ISceneChildEntity sop in sceneObject.ChildrenEntities()) { //Fix ownerIDs and perms sop.Inventory.ApplyGodPermissions((uint)PermissionMask.All); sceneObject.ApplyPermissions((uint)PermissionMask.All); foreach (TaskInventoryItem item in sop.Inventory.GetInventoryItems()) { item.OwnerID = m_userInfo.PrincipalID; } sop.OwnerID = m_userInfo.PrincipalID; } data = Utils.StringToBytes( SceneEntitySerializer.SceneObjectSerializer.ToOriginalXmlFormat(sceneObject)); } } //MainConsole.Instance.DebugFormat("[INVENTORY ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType); AssetBase asset = new AssetBase(UUID.Parse(uuid), "RandomName", assetType, m_overridecreator) { Data = data, Flags = AssetFlags .Normal }; IAssetService assetService = m_registry.RequestModuleInterface <IAssetService>(); IAssetDataPlugin assetData = Framework.Utilities.DataManager.RequestPlugin <IAssetDataPlugin>(); if (assetData != null && ReplaceAssets) { assetData.Delete(asset.ID, true); } assetService.Store(asset); return(true); } MainConsole.Instance.ErrorFormat( "[INVENTORY ARCHIVER]: Tried to dearchive data with path {0} with an unknown type extension {1}", assetPath, extension); return(false); }
/// <summary> /// Load an asset /// </summary> /// <param name="assetPath"> </param> /// <param name="data"></param> /// <returns>true if asset was successfully loaded, false otherwise</returns> bool LoadAsset(string assetPath, byte [] data) { //IRegionSerializer serializer = scene.RequestModuleInterface<IRegionSerializer>(); // Right now we're nastily obtaining the UUID from the filename string filename = assetPath.Remove(0, ArchiveConstants.ASSETS_PATH.Length); int i = filename.LastIndexOf(ArchiveConstants.ASSET_EXTENSION_SEPARATOR, StringComparison.Ordinal); if (i == -1) { MainConsole.Instance.ErrorFormat( "[Inventory Archiver]: Could not find extension information in asset path {0} since it's missing the separator {1}. Skipping", assetPath, ArchiveConstants.ASSET_EXTENSION_SEPARATOR); return(false); } string extension = filename.Substring(i); string uuid = filename.Remove(filename.Length - extension.Length); UUID assetID = UUID.Parse(uuid); if (ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension)) { AssetType assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE [extension]; if (assetType == AssetType.Unknown) { MainConsole.Instance.WarnFormat( "[Inventory Archiver]: Importing {0} byte asset {1} with unknown type", data.Length, uuid); } else if (assetType == AssetType.Object) { string xmlData = Utils.BytesToString(data); ISceneEntity sceneObject = SceneEntitySerializer.SceneObjectSerializer.FromOriginalXmlFormat( xmlData, m_registry); if (sceneObject != null) { if (m_creatorIdForAssetId.ContainsKey(assetID)) { foreach ( ISceneChildEntity sop in from sop in sceneObject.ChildrenEntities() where string.IsNullOrEmpty(sop.CreatorData) select sop) { sop.CreatorID = m_creatorIdForAssetId [assetID]; } } foreach (ISceneChildEntity sop in sceneObject.ChildrenEntities()) { //Fix ownerIDs and perms sop.Inventory.ApplyGodPermissions((uint)PermissionMask.All); sceneObject.ApplyPermissions((uint)PermissionMask.All); foreach (TaskInventoryItem item in sop.Inventory.GetInventoryItems()) { item.OwnerID = m_userInfo.PrincipalID; } sop.OwnerID = m_userInfo.PrincipalID; } data = Utils.StringToBytes( SceneEntitySerializer.SceneObjectSerializer.ToOriginalXmlFormat(sceneObject)); } } //MainConsole.Instance.DebugFormat("[Inventory Archiver]: Importing asset {0}, type {1}", uuid, assetType); AssetBase asset = new AssetBase(assetID, m_invName, assetType, m_overridecreator) { Data = data, Flags = AssetFlags.Normal }; if (m_assetData != null && ReplaceAssets) { m_assetData.Delete(asset.ID, true); } // check if this asset already exists in the database try { if (!m_assetService.GetExists(asset.ID.ToString())) { m_assetService.Store(asset); } } catch { MainConsole.Instance.Error( "[Inventory Archiver]: Error checking if asset exists. Possibly 'Path too long' for file based asset storage"); } asset.Dispose(); return(true); } MainConsole.Instance.ErrorFormat( "[Inventory Archiver]: Tried to dearchive data with path {0} with an unknown type extension {1}", assetPath, extension); return(false); }
/// <summary> /// Move the given scene object into a new region /// </summary> /// <param name="destination"></param> /// <param name="grp">Scene Object Group that we're crossing</param> /// <param name="attemptedPos"></param> /// <returns> /// true if the crossing itself was successful, false on failure /// </returns> protected bool CrossPrimGroupIntoNewRegion(GridRegion destination, ISceneEntity grp, Vector3 attemptedPos) { bool successYN = false; if (destination != null) { if (grp.SitTargetAvatar.Count != 0) { foreach (UUID avID in grp.SitTargetAvatar) { IScenePresence SP = grp.Scene.GetScenePresence(avID); SP.Velocity = grp.RootChild.PhysActor.Velocity; InternalCross(SP, attemptedPos, false, destination); } foreach (ISceneChildEntity part in grp.ChildrenEntities()) part.SitTargetAvatar = new List<UUID>(); IBackupModule backup = grp.Scene.RequestModuleInterface<IBackupModule>(); if (backup != null) return backup.DeleteSceneObjects(new[] {grp}, false, false); return true; //They do all the work adding the prim in the other region } ISceneEntity copiedGroup = grp.Copy(false); copiedGroup.SetAbsolutePosition(true, attemptedPos); if (grp.Scene != null) successYN = grp.Scene.RequestModuleInterface<ISimulationService>() .CreateObject(destination, copiedGroup); if (successYN) { // We remove the object here try { IBackupModule backup = grp.Scene.RequestModuleInterface<IBackupModule>(); if (backup != null) return backup.DeleteSceneObjects(new[] {grp}, false, true); } catch (Exception e) { MainConsole.Instance.ErrorFormat( "[ENTITY TRANSFER MODULE]: Exception deleting the old object left behind on a border crossing for {0}, {1}", grp, e); } } else { if (!grp.IsDeleted) { if (grp.RootChild.PhysActor != null) { grp.RootChild.PhysActor.CrossingFailure(); } } MainConsole.Instance.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); } } else { MainConsole.Instance.Error( "[ENTITY TRANSFER MODULE]: destination was unexpectedly null in Scene.CrossPrimGroupIntoNewRegion()"); } return successYN; }
// NOTE: Call under Taint Lock private void RemoveObject(ISceneEntity obj) { if (obj.IsAttachment) { return; } if (((obj.RootChild.Flags & PrimFlags.TemporaryOnRez) != 0)) { return; } IParcelManagementModule parcelManagment = m_Scene.RequestModuleInterface <IParcelManagementModule>(); Vector3 pos = obj.AbsolutePosition; ILandObject landObject = parcelManagment.GetLandObject(pos.X, pos.Y) ?? parcelManagment.GetNearestAllowedParcel(UUID.Zero, pos.X, pos.Y); if (landObject == null) { return; } LandData landData = landObject.LandData; ParcelCounts parcelCounts; if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts)) { UUID landOwner = landData.OwnerID; foreach (ISceneChildEntity child in obj.ChildrenEntities()) { bool foundit = false; if (!parcelCounts.Objects.ContainsKey(child.UUID)) { //was not found, lets look through all the parcels foreach (ILandObject parcel in parcelManagment.AllParcels()) { landData = parcel.LandData; if (!m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts)) { continue; } landOwner = landData.OwnerID; if (!parcelCounts.Objects.ContainsKey(child.UUID)) { continue; } foundit = true; break; } } else { foundit = true; } if (!foundit) { continue; } parcelCounts.Objects.Remove(child.UUID); if (m_SimwideCounts.ContainsKey(landOwner)) { m_SimwideCounts[landOwner] -= 1; } if (parcelCounts.Users.ContainsKey(obj.OwnerID)) { parcelCounts.Users[obj.OwnerID] -= 1; } if (landData.IsGroupOwned) { if (obj.OwnerID == landData.GroupID) { parcelCounts.Owner -= 1; } else if (obj.GroupID == landData.GroupID) { parcelCounts.Group -= 1; } else { parcelCounts.Others -= 1; } } else { if (obj.OwnerID == landData.OwnerID) { parcelCounts.Owner -= 1; } else if (obj.GroupID == landData.GroupID) { parcelCounts.Group -= 1; } else { parcelCounts.Others -= 1; } } } } }
public ISceneEntity GetRezReadySceneObject(TaskInventoryItem item) { byte[] rezAsset = m_part.ParentGroup.Scene.AssetService.GetData(item.AssetID.ToString()); if (null == rezAsset) { MainConsole.Instance.WarnFormat( "[PRIM INVENTORY]: Could not find asset {0} for inventory item {1} in {2}", item.AssetID, item.Name, m_part.Name); return(null); } string xmlData = Utils.BytesToString(rezAsset); ISceneEntity group = SceneEntitySerializer.SceneObjectSerializer.FromOriginalXmlFormat(xmlData, m_part.ParentGroup .Scene); if (group == null) { return(null); } group.IsDeleted = false; foreach (ISceneChildEntity part in group.ChildrenEntities()) { part.IsLoading = false; } //Reset IDs, etc m_part.ParentGroup.Scene.SceneGraph.PrepPrimForAdditionToScene(group); ISceneChildEntity rootPart = group.GetChildPart(group.UUID); // Since renaming the item in the inventory does not affect the name stored // in the serialization, transfer the correct name from the inventory to the // object itself before we rez. rootPart.Name = item.Name; rootPart.Description = item.Description; List <ISceneChildEntity> partList = group.ChildrenEntities(); group.SetGroup(m_part.GroupID, group.OwnerID, false); if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) { if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions()) { foreach (ISceneChildEntity part in partList) { part.EveryoneMask = item.EveryonePermissions; part.NextOwnerMask = item.NextPermissions; } group.ApplyNextOwnerPermissions(); } } foreach (ISceneChildEntity part in partList) { if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) { part.LastOwnerID = part.OwnerID; part.OwnerID = item.OwnerID; part.Inventory.ChangeInventoryOwner(item.OwnerID); } part.EveryoneMask = item.EveryonePermissions; part.NextOwnerMask = item.NextPermissions; } rootPart.TrimPermissions(); return(group); }
/// <summary> /// Reset all of the UUID's, localID's, etc in this group (includes children) /// </summary> /// <param name="entity"></param> private void ResetEntityIDs (ISceneEntity entity) { List<ISceneChildEntity> children = entity.ChildrenEntities (); //Sort so that we rebuild in the same order and the root being first children.Sort(LinkSetSorter); entity.ClearChildren(); IComponentManager manager = m_parentScene.RequestModuleInterface<IComponentManager> (); foreach (ISceneChildEntity child in children) { UUID oldID = child.UUID; child.ResetEntityIDs(); entity.AddChild (child, child.LinkNum); if (manager != null) manager.ResetComponentIDsToNewObject (oldID, child); } }
/// <summary> /// Add the Entity to the Scene and back it up, but do NOT reset its ID's /// </summary> /// <param name="entity"></param> /// <param name="force"></param> /// <returns></returns> public bool RestorePrimToScene(ISceneEntity entity, bool force) { List<ISceneChildEntity> children = entity.ChildrenEntities(); //Sort so that we rebuild in the same order and the root being first children.Sort(LinkSetSorter); entity.ClearChildren(); foreach (ISceneChildEntity child in children) { if (child.LocalId == 0) child.LocalId = AllocateLocalId(); if (((SceneObjectPart) child).PhysActor != null) { ((SceneObjectPart) child).PhysActor.LocalID = child.LocalId; ((SceneObjectPart) child).PhysActor.UUID = child.UUID; } child.Flags &= ~PrimFlags.Scripted; child.TrimPermissions(); entity.AddChild(child, child.LinkNum); } //Tell the entity that they are being added to a scene entity.AttachToScene(m_parentScene); //Now save the entity that we have bool success = AddEntity(entity, false); if (force && !success) { IBackupModule backup = m_parentScene.RequestModuleInterface<IBackupModule>(); backup.DeleteSceneObjects(new ISceneEntity[1] {entity}, false, true); return RestorePrimToScene(entity, false); } return success; }
protected void OnObjectBeingAddedToScene(ISceneEntity obj) { lock (m_objectsLock) { foreach (ISceneChildEntity child in obj.ChildrenEntities()) { bool physicalStatus = (child.Flags & PrimFlags.Physics) == PrimFlags.Physics; if (!m_lastAddedPhysicalStatus.ContainsKey(child.UUID)) { m_objects++; //Check physical status now if (physicalStatus) m_activeObjects++; //Add it to the list so that we have a record of it m_lastAddedPhysicalStatus.Add(child.UUID, physicalStatus); } else { //Its a dupe! Its a dupe! // Check that the physical status has changed if (physicalStatus != m_lastAddedPhysicalStatus[child.UUID]) { //It changed... fix the count if (physicalStatus) m_activeObjects++; else m_activeObjects--; //Update the cache m_lastAddedPhysicalStatus[child.UUID] = physicalStatus; } } } } }
/// <summary> /// Check all the localIDs in this group to make sure that they have not been used previously /// </summary> /// <param name="group"></param> public void CheckAllocationOfLocalIds(ISceneEntity group) { foreach (ISceneChildEntity part in group.ChildrenEntities()) { if (part.LocalId != 0) CheckAllocationOfLocalId(part.LocalId); } }
protected void OnObjectBeingRemovedFromScene(ISceneEntity obj) { lock (m_objectsLock) { foreach (ISceneChildEntity child in obj.ChildrenEntities()) { bool physicalStatus = (child.Flags & PrimFlags.Physics) == PrimFlags.Physics; if (m_lastAddedPhysicalStatus.ContainsKey(child.UUID)) { m_objects--; //Check physical status now and remove if necessary if (physicalStatus) m_activeObjects--; //Remove our record of it m_lastAddedPhysicalStatus.Remove(child.UUID); } } } }
private void DearchiveRegion0DotStar() { if (m_loadStream == null) { return; } int successfulAssetRestores = 0; int failedAssetRestores = 0; string filePath = "NONE"; DateTime start = DateTime.Now; TarArchiveReader archive = new TarArchiveReader(m_loadStream); if (!m_skipAssets) { m_threadpool = new AuroraThreadPool(new AuroraThreadPoolStartInfo() { Threads = 1, priority = System.Threading.ThreadPriority .BelowNormal }); } IBackupModule backup = m_scene.RequestModuleInterface <IBackupModule>(); if (!m_merge) { DateTime before = DateTime.Now; MainConsole.Instance.Info("[ARCHIVER]: Clearing all existing scene objects"); if (backup != null) { backup.DeleteAllSceneObjects(); } MainConsole.Instance.Info("[ARCHIVER]: Cleared all existing scene objects in " + (DateTime.Now - before).Minutes + ":" + (DateTime.Now - before).Seconds); } IScriptModule[] modules = m_scene.RequestModuleInterfaces <IScriptModule>(); //Disable the script engine so that it doesn't load in the background and kill OAR loading foreach (IScriptModule module in modules) { module.Disabled = true; } //Disable backup for now as well if (backup != null) { backup.LoadingPrims = true; } IRegionSerialiserModule serialiser = m_scene.RequestModuleInterface <IRegionSerialiserModule>(); int sceneObjectsLoadedCount = 0; //We save the groups so that we can back them up later List <ISceneEntity> groupsToBackup = new List <ISceneEntity>(); List <LandData> landData = new List <LandData>(); // must save off some stuff until after assets have been saved and recieved new uuids // keeping these collection local because I am sure they will get large and garbage collection is better that way List <byte[]> seneObjectGroups = new List <byte[]>(); Dictionary <UUID, UUID> assetBinaryChangeRecord = new Dictionary <UUID, UUID>(); Queue <UUID> assets2Save = new Queue <UUID>(); try { byte[] data; TarArchiveReader.TarEntryType entryType; while ((data = archive.ReadEntry(out filePath, out entryType)) != null) { if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType) { continue; } if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH)) { seneObjectGroups.Add(data); } else if (!m_skipAssets && filePath.StartsWith(ArchiveConstants.ASSETS_PATH)) { AssetBase asset; if (LoadAsset(filePath, data, out asset)) { successfulAssetRestores++; if (m_useAsync) { lock (AssetsToAdd) AssetsToAdd.Add(asset); } else { if (asset.IsBinaryAsset) { UUID aid = asset.ID; asset.ID = m_scene.AssetService.Store(asset); if (asset.ID != aid && asset.ID != UUID.Zero) { assetBinaryChangeRecord.Add(aid, asset.ID); } } else { if (!assetNonBinaryCollection.ContainsKey(asset.ID)) { assetNonBinaryCollection.Add(asset.ID, asset); // I need something I can safely loop through assets2Save.Enqueue(asset.ID); } } } } else { failedAssetRestores++; } if ((successfulAssetRestores + failedAssetRestores) % 250 == 0) { MainConsole.Instance.Info("[ARCHIVER]: Loaded " + successfulAssetRestores + " assets and failed to load " + failedAssetRestores + " assets..."); } } else if (filePath.StartsWith(ArchiveConstants.TERRAINS_PATH)) { LoadTerrain(filePath, data); } else if (!m_merge && filePath.StartsWith(ArchiveConstants.SETTINGS_PATH)) { LoadRegionSettings(filePath, data); } else if (filePath.StartsWith(ArchiveConstants.LANDDATA_PATH)) { LandData parcel = LandDataSerializer.Deserialize(m_utf8Encoding.GetString(data)); parcel.OwnerID = ResolveUserUuid(parcel.OwnerID, UUID.Zero, "", Vector3.Zero, null); landData.Add(parcel); } else if (filePath == ArchiveConstants.CONTROL_FILE_PATH) { LoadControlFile(data); } } // Save Assets int savingAssetsCount = 0; while (assets2Save.Count > 0) { try { UUID assetid = assets2Save.Dequeue(); SaveNonBinaryAssets(assetid, assetNonBinaryCollection[assetid], assetBinaryChangeRecord); savingAssetsCount++; if ((savingAssetsCount) % 250 == 0) { MainConsole.Instance.Info("[ARCHIVER]: Saving " + savingAssetsCount + " assets..."); } } catch (Exception ex) { MainConsole.Instance.Info("[ARCHIVER]: Exception in saving an asset: " + ex.ToString()); } } foreach (byte[] data2 in seneObjectGroups) { byte[] data3 = data2; string stringData = Utils.BytesToString(data3); MatchCollection mc = Regex.Matches(stringData, sPattern); bool didChange = false; if (mc.Count >= 1) { foreach (Match match in mc) { UUID thematch = new UUID(match.Value); UUID newvalue = thematch; if (assetNonBinaryCollection.ContainsKey(thematch)) { newvalue = assetNonBinaryCollection[thematch].ID; } else if (assetBinaryChangeRecord.ContainsKey(thematch)) { newvalue = assetBinaryChangeRecord[thematch]; } if (thematch == newvalue) { continue; } stringData = stringData.Replace(thematch.ToString().Trim(), newvalue.ToString().Trim()); didChange = true; } } if (didChange) { data3 = Utils.StringToBytes(stringData); } ISceneEntity sceneObject = serialiser.DeserializeGroupFromXml2(data3, m_scene); if (sceneObject == null) { //! big error! MainConsole.Instance.Error("Error reading SOP XML (Please mantis this!): " + m_asciiEncoding.GetString(data3)); continue; } foreach (ISceneChildEntity part in sceneObject.ChildrenEntities()) { if (string.IsNullOrEmpty(part.CreatorData)) { part.CreatorID = ResolveUserUuid(part.CreatorID, part.CreatorID, part.CreatorData, part.AbsolutePosition, landData); } part.OwnerID = ResolveUserUuid(part.OwnerID, part.CreatorID, part.CreatorData, part.AbsolutePosition, landData); part.LastOwnerID = ResolveUserUuid(part.LastOwnerID, part.CreatorID, part.CreatorData, part.AbsolutePosition, landData); // And zap any troublesome sit target information part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); part.SitTargetPosition = new Vector3(0, 0, 0); // Fix ownership/creator of inventory items // Not doing so results in inventory items // being no copy/no mod for everyone lock (part.TaskInventory) { TaskInventoryDictionary inv = part.TaskInventory; foreach (KeyValuePair <UUID, TaskInventoryItem> kvp in inv) { kvp.Value.OwnerID = ResolveUserUuid(kvp.Value.OwnerID, kvp.Value.CreatorID, kvp.Value.CreatorData, part.AbsolutePosition, landData); if (string.IsNullOrEmpty(kvp.Value.CreatorData)) { kvp.Value.CreatorID = ResolveUserUuid(kvp.Value.CreatorID, kvp.Value.CreatorID, kvp.Value.CreatorData, part.AbsolutePosition, landData); } } } } //Add the offsets of the region Vector3 newPos = new Vector3(sceneObject.AbsolutePosition.X + m_offsetX, sceneObject.AbsolutePosition.Y + m_offsetY, sceneObject.AbsolutePosition.Z + m_offsetZ); if (m_flipX) { newPos.X = m_scene.RegionInfo.RegionSizeX - newPos.X; } if (m_flipY) { newPos.Y = m_scene.RegionInfo.RegionSizeY - newPos.Y; } sceneObject.SetAbsolutePosition(false, newPos); if (m_scene.SceneGraph.AddPrimToScene(sceneObject)) { groupsToBackup.Add(sceneObject); sceneObject.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate); sceneObject.CreateScriptInstances(0, false, StateSource.RegionStart, UUID.Zero, true); } sceneObjectsLoadedCount++; if (sceneObjectsLoadedCount % 250 == 0) { MainConsole.Instance.Info("[ARCHIVER]: Loaded " + sceneObjectsLoadedCount + " objects..."); } } assetNonBinaryCollection.Clear(); assetBinaryChangeRecord.Clear(); seneObjectGroups.Clear(); } catch (Exception e) { MainConsole.Instance.ErrorFormat( "[ARCHIVER]: Aborting load with error in archive file {0}. {1}", filePath, e); m_errorMessage += e.ToString(); m_scene.EventManager.TriggerOarFileLoaded(UUID.Zero.Guid, m_errorMessage); return; } finally { archive.Close(); m_loadStream.Close(); m_loadStream.Dispose(); //Reeanble now that we are done foreach (IScriptModule module in modules) { module.Disabled = false; } //Reset backup too if (backup != null) { backup.LoadingPrims = false; } } //Now back up the prims foreach (ISceneEntity grp in groupsToBackup) { //Backup! grp.HasGroupChanged = true; } if (!m_skipAssets && m_useAsync && !AssetSaverIsRunning) { m_threadpool.QueueEvent(SaveAssets, 0); } if (!m_skipAssets) { MainConsole.Instance.InfoFormat("[ARCHIVER]: Restored {0} assets", successfulAssetRestores); if (failedAssetRestores > 0) { MainConsole.Instance.ErrorFormat("[ARCHIVER]: Failed to load {0} assets", failedAssetRestores); m_errorMessage += String.Format("Failed to load {0} assets", failedAssetRestores); } } // Try to retain the original creator/owner/lastowner if their uuid is present on this grid // otherwise, use the master avatar uuid instead // Reload serialized parcels MainConsole.Instance.InfoFormat("[ARCHIVER]: Loading {0} parcels. Please wait.", landData.Count); IParcelManagementModule parcelManagementModule = m_scene.RequestModuleInterface <IParcelManagementModule>(); if (parcelManagementModule != null) { parcelManagementModule.IncomingLandDataFromOAR(landData, m_merge, new Vector2(m_offsetX, m_offsetY)); } MainConsole.Instance.InfoFormat("[ARCHIVER]: Restored {0} parcels.", landData.Count); //Clean it out landData.Clear(); MainConsole.Instance.InfoFormat("[ARCHIVER]: Successfully loaded archive in " + (DateTime.Now - start).Minutes + ":" + (DateTime.Now - start).Seconds); m_validUserUuids.Clear(); m_scene.EventManager.TriggerOarFileLoaded(UUID.Zero.Guid, m_errorMessage); }
/// <summary> /// Reset all of the UUID's, localID's, etc in this group (includes children) /// </summary> /// <param name="entity"></param> private void ResetEntityIDs (ISceneEntity entity) { List<ISceneChildEntity> children = entity.ChildrenEntities (); //Sort so that we rebuild in the same order and the root being first children.Sort(LinkSetSorter); entity.ClearChildren(); IComponentManager manager = m_parentScene.RequestModuleInterface<IComponentManager> (); foreach (ISceneChildEntity child in children) { UUID oldID = child.UUID; child.ResetEntityIDs(); entity.AddChild (child, child.LinkNum); if (manager != null) manager.ResetComponentIDsToNewObject (oldID, child); } //This clears the xml file, which will need rebuilt now that we have changed the UUIDs entity.HasGroupChanged = true; foreach (ISceneChildEntity child in children) { if(!child.IsRoot) { child.SetParentLocalId (entity.RootChild.LocalId); } } }