public InventoryArchiveReadRequest(
     CachedUserInfo userInfo, string invPath, Stream loadStream, CommunicationsManager commsManager)
 {
     m_userInfo = userInfo;
     m_invPath = invPath;
     m_loadStream = loadStream;
     m_commsManager = commsManager;
 }
 private void SaveCompleted(
     bool succeeded, CachedUserInfo userInfo, string invPath, Stream saveStream, Exception reportedException)
 {
     lock (this)
     {
         Monitor.PulseAll(this);
     }
 }        
 /// <summary>
 /// Constructor
 /// </summary>
 public InventoryArchiveWriteRequest(
     InventoryArchiverModule module, CachedUserInfo userInfo, string invPath, string savePath)
     : this(
         module,
         userInfo,
         invPath,
         new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress))
 {
 }
 public InventoryArchiveReadRequest(
     CachedUserInfo userInfo, string invPath, string loadPath, CommunicationsManager commsManager)
     : this(
         userInfo,
         invPath,
         new GZipStream(new FileStream(loadPath, FileMode.Open), CompressionMode.Decompress),
         commsManager)
 {
 }
        public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, UUID groupID, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
                                    UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
                                    bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment, uint attachPoint,
                                    int? startParam, CachedUserInfo userInfo, InventoryItemBase item, bool allowUpdates)
        {
            // Work out position details
            byte bRayEndIsIntersection = (byte)0;

            if (RayEndIsIntersection)
            {
                bRayEndIsIntersection = (byte)1;
            }
            else
            {
                bRayEndIsIntersection = (byte)0;
            }

            Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f);


            Vector3 pos = GetNewRezLocation(
                      RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                      BypassRayCast, bRayEndIsIntersection, true, scale, false, remoteClient.AgentId);

            AssetBase rezAsset = CommsManager.AssetCache.GetAsset(item.AssetID, AssetRequestInfo.InternalRequest());

            if (rezAsset != null)
            {
                UUID itemId = UUID.Zero;

                // If we have permission to copy then link the rezzed object back to the user inventory
                // item that it came from.  This allows us to enable 'save object to inventory'
                if (!Permissions.BypassPermissions())
                {
                    if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy)
                    {
                        itemId = item.ID;
                    }
                }
                else
                {
                    // Brave new fullperm world
                    //
                    itemId = item.ID;
                }

                string xmlData = Utils.BytesToString(rezAsset.Data);
                bool success = false;
                SceneObjectGroup retGroup = null;

                if (item.ContainsMultipleItems)
                {
                    if (!attachment)
                    {
                        CoalescedObject obj = this.DoDeserializeCoalesced(itemId, rezAsset.Data);

                        //rez coalesced object
                        success = this.RezCoalescedObject(remoteClient, itemID, obj, RayEnd,
                                    RayStart, RayTargetID, BypassRayCast, bRayEndIsIntersection,
                                    RezSelected, false, pos, item, startParam, groupID,
                                    null);
                    }
                    else
                    {
                        return null; //rezzing a coalesced as an attachment doesnt make sense
                    }
                }
                else
                {
                    //rez single group
                    SceneObjectGroup group = this.DoDeserializeGroup(itemId, rezAsset.Data);

                    group.DisableUpdates = !allowUpdates;

                    bool shouldTaint = false;

                    // if attachment we set it's asset id so object updates can reflect that
                    // if not, we set it's position in world.
                    if (!attachment)
                    {
                        // Save the previous attachment params if they've never been saved or default.
                        if (group.RootPart.SavedAttachmentPos == Vector3.Zero)
                            group.RootPart.SavedAttachmentPos = group.RootPart.RawGroupPosition;
                        if (group.RootPart.SavedAttachmentRot == Quaternion.Identity)
                            group.RootPart.SavedAttachmentRot = group.RootPart.RotationOffset;

                        //after this, the group is no longer an attachment as it is being rezzed as a normal group.
                        //this prevents an issue where the BB calculation tries to get the worldpos for the
                        //attachment that is not yet attached and creates a null reference exception
                        //when trying to access the scene to look up the wearer
                        group.SetAttachmentPoint(0);

                        Box bbox = group.BoundingBox();
                        scale = bbox.Size; ; // update the 0.5 cube with the actual size
                        pos = GetNewRezLocation(
                            RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                            BypassRayCast, bRayEndIsIntersection, true, scale, false, remoteClient.AgentId);
                        float zCorrection = group.RootPart.GroupPosition.Z - bbox.Center.Z;
                        pos.Z += zCorrection;
                    }
                    else
                    {
                        //this is an attachment, prep the object for rez. particularly important so that it is not 
                        //first rezzed in world with physics in tact
                        if (!group.PrepareForRezAsAttachment(attachPoint, out shouldTaint, false))
                        {
                            return null;
                        }

                        //extract the saved position for sending to the rez method
                        pos = group.RawGroupPosition;
                    }

                    retGroup =
                        this.RezSingleObjectToWorld(remoteClient, itemID,
                                group, RayEnd, RayStart,
                                RayTargetID, BypassRayCast, bRayEndIsIntersection,
                                RezSelected, attachment, pos, item.Name,
                                item.Description, item, ItemPermissionBlock.FromOther(item),
                                startParam, groupID, null);

                    if (retGroup != null)
                    {
                        success = true;

                        if (shouldTaint)
                        {
                            retGroup.HasGroupChanged = true;
                            retGroup.TaintedAttachment = true;
                        }
                    }
                }

                if (success && !Permissions.BypassPermissions())
                {
                    //we check the inventory item permissions here instead of the prim permissions
                    //if the group or item is no copy, it should be removed
                    if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
                    {
                        // If this is done on attachments, no
                        // copy ones will be lost, so avoid it
                        //
                        if (!attachment)
                        {
                            if (userInfo != null)
                                userInfo.DeleteItem(item);
                        }
                    }
                }

                return retGroup;
            }
            return null;
        }
 /// <summary>
 /// Constructor
 /// </summary>
 public InventoryArchiveWriteRequest(
     InventoryArchiverModule module, CachedUserInfo userInfo, string invPath, Stream saveStream)
 {
     m_module = module;
     m_userInfo = userInfo;
     m_invPath = invPath;
     m_saveStream = saveStream;
     m_assetGatherer = new UuidGatherer(m_module.CommsManager.AssetCache);
 }
 /// <summary>
 /// Populate caches with the given cached user profile
 /// </summary>
 /// <param name="userInfo"></param>
 protected void AddToUserInfoCache(CachedUserInfo userInfo)
 {
     lock (m_userInfoLock)
     {
         UUID uuid = userInfo.UserProfile.ID;
         // Add or update the regular profiles data.
         if (m_userInfoByUUID.Contains(uuid))
             m_userInfoByUUID.Remove(uuid);
         m_userInfoByUUID.Add(uuid, new TimestampedItem<CachedUserInfo>(userInfo));
         m_userInfoByName[userInfo.UserProfile.Name] = userInfo;
     }
 }
        private void SetAppearanceAssets(CachedUserInfo profile, ref List<AvatarWearable> wearables, IClientAPI clientView)
        {
            foreach (AvatarWearable wearable in wearables)
            {
                // Skip it if its empty
                if (wearable.ItemID == UUID.Zero)
                    continue;

                // Ignore ruth's assets
                if (((wearable.WearableType == AvatarWearable.BODY) && (wearable.ItemID == AvatarWearable.DEFAULT_BODY_ITEM)) ||
                    ((wearable.WearableType == AvatarWearable.SKIN) && (wearable.ItemID == AvatarWearable.DEFAULT_SKIN_ITEM)) ||
                    ((wearable.WearableType == AvatarWearable.HAIR) && (wearable.ItemID == AvatarWearable.DEFAULT_HAIR_ITEM)) ||
                    ((wearable.WearableType == AvatarWearable.EYES) && (wearable.ItemID == AvatarWearable.DEFAULT_EYES_ITEM)) ||
                    ((wearable.WearableType == AvatarWearable.SHIRT) && (wearable.ItemID == AvatarWearable.DEFAULT_SHIRT_ITEM)) ||
                    ((wearable.WearableType == AvatarWearable.PANTS) && (wearable.ItemID == AvatarWearable.DEFAULT_PANTS_ITEM)))
                {
                    continue;
                }

                // Otherwise look up the asset and store the translated value
                // XXX dont look up stuff we already know about.. save a trip to the asset server

                InventoryItemBase baseItem = profile.FindItem(wearable.ItemID);
                baseItem = profile.ResolveLink(baseItem);
                

                if (baseItem != null)
                {
                    wearable.AssetID = baseItem.AssetID;
                }
                else
                {
                    m_log.ErrorFormat("[APPEARANCE]: Can't find inventory item {0}", wearable.ItemID);
                }
            }
        }
        public void SetAppearanceAssets(CachedUserInfo profile, ref AvatarAppearance appearance)
        {
            if (profile.RootFolder != null)
            {
                for (int i = 0; i < 13; i++)
                {
                    if (appearance.Wearables[i].ItemID == UUID.Zero)
                    {
                        appearance.Wearables[i].AssetID = UUID.Zero;
                    }
                    else
                    {
                        InventoryItemBase baseItem = profile.RootFolder.FindItem(appearance.Wearables[i].ItemID);

                        if (baseItem != null)
                        {
                            appearance.Wearables[i].AssetID = baseItem.AssetID;
                        }
                        else
                        {
                            m_log.ErrorFormat("[APPEARANCE]: Can't find inventory item {0}, setting to default", appearance.Wearables[i].ItemID);
                            appearance.Wearables[i].AssetID = def.Wearables[i].AssetID;
                        }
                    }
                }
            }
            else
            {
                m_log.Error("[APPEARANCE]: you have no inventory, appearance stuff isn't going to work");
            }
        }
        // Used to add group notice attachments or deliver them to members.  Perms checks already done by caller.  May need to apply next owner perms.
        // Note: When adding to a group notice, senderId is a user and senderUserInfo is non-null. Item is NOT added here but item to add returned.
        //       When delivering from a group notice, senderID is the group ID and senderUserInfo is null. Item is delivered to user.
        public virtual InventoryItemBase CheckDeliverGroupItem(InventoryItemBase item, UUID recipientId, UUID senderId, CachedUserInfo senderUserInfo)
        {
            CachedUserInfo recipientUserInfo = null;
            bool isDelivery = (senderUserInfo == null);
            bool applyNextPerms = false;    // don't bother applying them when attaching, and always apply on delivery

            if (isDelivery)
            {
                // delivery from group notice to user - always apply next owner perms
                applyNextPerms = true;
                recipientUserInfo = CommsManager.UserService.GetUserDetails(recipientId);
                if (recipientUserInfo == null)
                {
                    m_log.ErrorFormat("[GROUPS]: Group notice attachment could not be delivered - unknown user {0}", recipientId);
                    return null;
                }
                if (!recipientUserInfo.HasReceivedInventory)
                    recipientUserInfo.FetchInventory();
            }

            // Insert a copy of the item into the recipient
            InventoryItemBase itemCopy = new InventoryItemBase();

            // It's a new inventory item
            itemCopy.ID = UUID.Random();
            itemCopy.GroupOwned = false;
            itemCopy.GroupID = UUID.Zero;
            itemCopy.Folder = UUID.Zero;
            itemCopy.SaleType = (byte)SaleType.Not;
            itemCopy.SalePrice = 0;

            // Now copy the other fields
            itemCopy.InvType = item.InvType;
            itemCopy.AssetType = item.AssetType;
            itemCopy.AssetID = item.AssetID;
            itemCopy.CreatorId = item.CreatorId;
            itemCopy.Name = item.Name;
            itemCopy.Description = item.Description;
            itemCopy.Flags = item.Flags;

            // on final delivery, the owner of the new copy is the recipient
            itemCopy.Owner = isDelivery ? recipientId : item.Owner;

            CalcItemPermsFromInvItem(itemCopy, item, applyNextPerms);

            if (senderUserInfo == null)
            {
                // delivery from group notice to user
                recipientUserInfo.AddItem(itemCopy);
            }
            else
            {
                // attaching from a user inventory to a group notice
                // just return the item to the caller who will add it.
            }

            return itemCopy;
        }
Exemple #11
0
        public InventoryItemBase Get(InventoryItemBase item, UUID rootFolder, CachedUserInfo userInfo)
        {
            InventoryClient invCli = null;
            string inventoryURL = UserInventoryURL(item.Owner);
            if (!m_inventoryServers.TryGetValue(inventoryURL, out invCli))
            {
                m_log.Debug("[HGScene]: Starting new InventorytClient for " + inventoryURL);
                invCli = new InventoryClient(inventoryURL);
                m_inventoryServers.Add(inventoryURL, invCli);
            }

            item = invCli.GetInventoryItem(item);
            if (item != null)
            {
                // Change the folder, stick it in root folder, all items flattened out here in this region cache
                item.Folder = rootFolder;
                //userInfo.AddItem(item); don't use this, it calls back to the inventory server
                lock (userInfo.RootFolder.Items)
                {
                    userInfo.RootFolder.Items[item.ID] = item;
                }

            }
            return item;
        }
Exemple #12
0
 /// <summary>
 /// Populate caches with the given cached user profile
 /// </summary>
 /// <param name="userProfile"></param>
 protected void AddToProfileCache(CachedUserInfo userInfo)
 {
     DumpStatus("AddToProfileCache(entry)");
     lock (_userProfilesLock)
     {
         UUID uuid = userInfo.UserProfile.ID;
         if (_cachedLocalProfiles.ContainsKey(uuid))
         {
             // Already cached as a local profile, force an update
             _cachedLocalProfiles[uuid] = userInfo;
             m_userProfilesByName[userInfo.UserProfile.Name] = userInfo;
         }
         else
         {
             // Add or update the regular profiles data.
             if (_cachedProfileData.Contains(uuid))
                 _cachedProfileData.Remove(uuid);
             _cachedProfileData.Add(uuid, new TimestampedItem<CachedUserInfo>(userInfo));
             m_userProfilesByName[userInfo.UserProfile.Name] = userInfo;
         }
     }
     DumpStatus("AddToProfileCache(exit)");
 }
 /// <summary>
 /// Trigger the inventory archive saved event.
 /// </summary>
 protected internal void TriggerInventoryArchiveSaved(
     bool succeeded, CachedUserInfo userInfo, string invPath, Stream saveStream, Exception reportedException)
 {
     InventoryArchiveSaved handlerInventoryArchiveSaved = OnInventoryArchiveSaved;
     if (handlerInventoryArchiveSaved != null)
         handlerInventoryArchiveSaved(succeeded, userInfo, invPath, saveStream, reportedException);
 }
 /// <summary>
 /// Notify the client of loaded nodes if they are logged in
 /// </summary>
 /// <param name="loadedNodes">Can be empty.  In which case, nothing happens</param>
 private void UpdateClientWithLoadedNodes(CachedUserInfo userInfo, List<InventoryNodeBase> loadedNodes)
 {               
     if (loadedNodes.Count == 0)
         return;
            
     foreach (Scene scene in m_scenes.Values)
     {
         ScenePresence user = scene.GetScenePresence(userInfo.UserProfile.ID);
         
         if (user != null && !user.IsChildAgent)
         {        
             foreach (InventoryNodeBase node in loadedNodes)
             {
                 m_log.DebugFormat(
                     "[INVENTORY ARCHIVER]: Notifying {0} of loaded inventory node {1}", 
                     user.Name, node.Name);
                 
                 user.ControllingClient.SendBulkUpdateInventory(node);
             }
             
             break;
         }        
     }            
 }
 private void SaveInvConsoleCommandCompleted(
     bool succeeded, CachedUserInfo userInfo, string invPath, Stream saveStream, Exception reportedException)
 {
     if (succeeded)
     {
         m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive for {0}", userInfo.UserProfile.Name);
     }
     else
     {
         m_log.ErrorFormat(
             "[INVENTORY ARCHIVER]: Archive save for {0} failed - {1}", 
             userInfo.UserProfile.Name, reportedException.Message);
     }
 }
        // unpackedGroup is null for an actual user Inventory item. non-null for group from a coalesced inventory item.
        public virtual bool RestoreObject(IClientAPI remoteClient, CachedUserInfo userInfo, UUID itemID, InventoryItemBase item, SceneObjectGroup unpackedGroup, UUID groupID)
        {
            Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f);

            AssetBase rezAsset = CommsManager.AssetCache.GetAsset(item.AssetID, AssetRequestInfo.InternalRequest());
            if (rezAsset == null)
                return false;

            UUID itemId = UUID.Zero;
            bool success = false;

            // If we have permission to copy then link the rezzed object back to the user inventory
            // item that it came from.  This allows us to enable 'save object to inventory'
            if (!Permissions.BypassPermissions())
            {
                if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy)
                {
                    itemId = item.ID;
                }
            }
            else
            {
                // Brave new fullperm world
                //
                itemId = item.ID;
            }

            if ((unpackedGroup==null) && item.ContainsMultipleItems)
            {
                CoalescedObject obj = this.DoDeserializeCoalesced(itemId, rezAsset.Data);
                //restore (rez) coalesced object
                success = this.RestoreCoalescedObject(remoteClient, userInfo, obj, itemID, item, groupID);
            }
            else
            {
                //rez single group
                SceneObjectGroup group = (unpackedGroup == null) ? this.DoDeserializeGroup(itemId, rezAsset.Data) : unpackedGroup;
                Vector3 pos = group.RootPart.GroupPositionNoUpdate;
                bool attachment = group.IsAttachment;
                uint attachPoint = group.AttachmentPoint;
                group.DisableUpdates = false;

                bool shouldTaint = false;

                if (attachment)
                {
                    remoteClient.SendAlertMessage("Inventory item is an attachment, use Wear or Add instead.");
                    return false;
                }

                // Save the previous attachment params if they've never been saved or default.
                if (group.RootPart.SavedAttachmentPos == Vector3.Zero)
                    group.RootPart.SavedAttachmentPos = group.RootPart.RawGroupPosition;
                if (group.RootPart.SavedAttachmentRot == Quaternion.Identity)
                    group.RootPart.SavedAttachmentRot = group.RootPart.RotationOffset;

                //after this, the group is no longer an attachment as it is being rezzed as a normal group.
                //this prevents an issue where the BB calculation tries to get the worldpos for the
                //attachment that is not yet attached and creates a null reference exception
                //when trying to access the scene to look up the wearer
                group.SetAttachmentPoint(0);

                Box bbox = group.BoundingBox();
                scale = bbox.Size; ; // update the 0.5 cube with the actual size
                pos = group.AbsolutePosition;
                float zCorrection = group.RootPart.GroupPosition.Z - bbox.Center.Z;
                pos.Z += zCorrection;

                SceneObjectGroup rezGroup =
                    this.RezSingleObjectToWorld(remoteClient, itemID,
                            group, pos, Vector3.Zero, UUID.Zero, 1, 1, false,
                            attachment, pos, group.Name, group.RootPart.Description,
                            item, ItemPermissionBlock.FromOther(item), 0, groupID, null);

                if (rezGroup != null)
                {
                    success = true;

                    if (shouldTaint)
                    {
                        rezGroup.HasGroupChanged = true;
                        rezGroup.TaintedAttachment = true;
                    }
                }
            }

            if (success && !Permissions.BypassPermissions())
            {
                //we check the inventory item permissions here instead of the prim permissions
                //if the group or item is no copy, it should be removed
                if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
                {
                    // Not an attachment, so remove inventory copy, if no-copy.
                    if (userInfo != null)
                        userInfo.DeleteItem(item);
                }
            }

            return success;
        }
        private bool RestoreCoalescedObject(IClientAPI remoteClient, CachedUserInfo userInfo, CoalescedObject obj, UUID itemID, InventoryItemBase item, UUID groupId)
        {
            //determine the bounding box of the entire set
            Box coBoundingBox = obj.GetBoundingBox();
            Vector3 rezAtRootOffset = Vector3.Zero;

            Vector3 newPos = coBoundingBox.Center;

            //rez each group
            bool success = true;
            foreach (SceneObjectGroup group in obj.Groups)
            {
                group.ResetInstance(true, false, UUID.Zero);
                success &= RestoreObject(remoteClient, userInfo, itemID, item, group, groupId);
            }

            return success;
        }
        private bool CheckFolderHeirarchyIsAppropriateForPurge(InventoryFolderBase folder, CachedUserInfo userProfile)
        {
            if (folder.Type == (short)AssetType.TrashFolder ||
                folder.Type == (short)AssetType.LostAndFoundFolder)
            {
                return true;
            }

            if (folder.ParentID == UUID.Zero ||
                folder.Type == (short)AssetType.RootFolder)
            {
                //got to the top, didnt find squat
                return false;
            }

            InventoryFolderBase parent = userProfile.GetFolderAttributes(folder.ParentID);
            return CheckFolderHeirarchyIsAppropriateForPurge(parent, userProfile);
        }
        // Used to deliver group notice attachments.  Perms checks already done at send time.  May need to apply next owner perms.
        // Also called by GiveInventoryItem since it factors most of the guts of that operation.
        // Note: when sender is a group, senderID is groupID and senderUserInfo is null, otherwise senderUserInfo must be non-null.
        public virtual InventoryItemBase DeliverItem(InventoryItemBase item, UUID recipientId, UUID recipientFolderId, UUID senderId, CachedUserInfo senderUserInfo)
        {
            CachedUserInfo recipientUserInfo
                = CommsManager.UserService.GetUserDetails(recipientId);

            if (recipientUserInfo != null)
            {
                if (!recipientUserInfo.HasReceivedInventory)
                    recipientUserInfo.FetchInventory();

                // Insert a copy of the item into the recipient
                InventoryItemBase itemCopy = new InventoryItemBase();
                itemCopy.Owner = recipientId;
                itemCopy.CreatorId = item.CreatorId;
                itemCopy.ID = UUID.Random();
                itemCopy.AssetID = item.AssetID;
                itemCopy.Description = item.Description;
                itemCopy.Name = item.Name;
                itemCopy.AssetType = item.AssetType;
                itemCopy.InvType = item.InvType;
                itemCopy.Folder = recipientFolderId;

                CalcItemPermsFromInvItem(itemCopy, item, (recipientId != senderId));
                        
                // copy is never group owned
                itemCopy.GroupOwned = false;

                itemCopy.Flags = item.Flags;
                itemCopy.SalePrice = item.SalePrice;
                itemCopy.SaleType = item.SaleType;

                recipientUserInfo.AddItem(itemCopy);

                if (!Permissions.BypassPermissions())
                {
                    if (senderUserInfo != null) //  if not a group item (notice attachment)
                    {
                        if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
                        {
                            senderUserInfo.DeleteItem(item);
                        }
                    }
                }

                return itemCopy;
            }
            else
            {
                m_log.ErrorFormat(
                    "[AGENT INVENTORY]: Could not find userinfo for recipient user {0} of item {1}, {2} from {3}",
                    recipientId, item.Name,
                    item.ID, senderId);
            }
            return null;
        }
            private static InventoryFolderBase GetCurrentOutfitFolder(CachedUserInfo userInfo)
            {
                // Duplicate method exists at Scene.Inventory.cs::Scene::GetCurrentOutfitFolder

                InventoryFolderBase currentOutfitFolder = null;

                try
                {
                    currentOutfitFolder = userInfo.FindFolderForType((int)FolderType.CurrentOutfit);
                }
                catch (InventoryStorageException)
                {
                    // could not find it by type. load root and try to find it by name.
                    InventorySubFolderBase foundFolder = null;
                    InventoryFolderBase rootFolder = userInfo.FindFolderForType((int)FolderType.Root);
                    foreach (var subfolder in rootFolder.SubFolders)
                    {
                        if (subfolder.Name == COF_NAME)
                        {
                            foundFolder = subfolder;
                            break;
                        }
                    }
                    if (foundFolder != null)
                    {
                        currentOutfitFolder = userInfo.GetFolder(foundFolder.ID);
                        if (currentOutfitFolder != null)
                        {
                            currentOutfitFolder.Level = InventoryFolderBase.FolderLevel.TopLevel;
                            userInfo.UpdateFolder(currentOutfitFolder);
                        }
                    }
                }
                if(currentOutfitFolder != null)
                    currentOutfitFolder = userInfo.GetFolder(currentOutfitFolder.ID);
                return currentOutfitFolder;
            }
            private static InventoryFolderBase GetCurrentOutfitFolder(CachedUserInfo userInfo)
            {
                InventoryFolderBase CurrentOutfitFolder = null;

                try
                {
                    CurrentOutfitFolder = userInfo.FindFolderForType((int)AssetType.CurrentOutfitFolder);
                }
                catch (InventoryStorageException)
                {
                    // could not find it by type. load root and try to find it by name.
                    InventorySubFolderBase foundFolder = null;
                    InventoryFolderBase rootFolder = userInfo.FindFolderForType((int)AssetType.RootFolder);
                    foreach (var subfolder in rootFolder.SubFolders)
                    {
                        if (subfolder.Name == COF_NAME)
                        {
                            foundFolder = subfolder;
                            break;
                        }
                    }
                    if (foundFolder != null)
                    {
                        CurrentOutfitFolder = userInfo.GetFolder(foundFolder.ID);
                        if (CurrentOutfitFolder != null)
                        {
                            CurrentOutfitFolder.Level = InventoryFolderBase.FolderLevel.TopLevel;
                            userInfo.UpdateFolder(CurrentOutfitFolder);
                        }
                    }
                }
                if(CurrentOutfitFolder != null)
                    CurrentOutfitFolder = userInfo.GetFolder(CurrentOutfitFolder.ID);
                return CurrentOutfitFolder;
            }
Exemple #22
0
        private bool WaitForInventory(CachedUserInfo info)
        {
            // 200 Seconds wait. This is called in the context of the
            // background delete thread, so we can afford to waste time
            // here.
            //
            int count = 200;

            while (count > 0)
            {
                System.Threading.Thread.Sleep(100);
                count--;
                if (info.HasReceivedInventory)
                    return true;
            }
            m_log.DebugFormat("Timed out waiting for inventory of user {0}",
                    info.UserProfile.ID.ToString());
            return false;
        }
        private void ReplaceUserInfo(CachedUserInfo userInfo)
        {
            UUID uuid = userInfo.UserProfile.ID;

            lock (m_userInfoLock)
            {
                // Let's handle the UUID caches first, then name cache is common between them.
                if (m_userInfoByUUID.Contains(uuid))
                    m_userInfoByUUID.Remove(uuid);
                m_userInfoByUUID.Add(uuid, new TimestampedItem<CachedUserInfo>(userInfo));

                // Now do the name cache.
                if (m_userInfoByName.ContainsKey(userInfo.UserProfile.Name))
                    m_userInfoByName.Remove(userInfo.UserProfile.Name);
                m_userInfoByName.Add(userInfo.UserProfile.Name, userInfo);
            }
        }
        /// <summary>
        /// Hot patches inventory items that may have the wrong flags set and thus will not wear in the viewer
        /// </summary>
        /// <param name="baseItem"></param>
        /// <param name="uinfo"></param>
        /// <param name="clientView"></param>
        /// <returns></returns>
        private bool FixupItemFlagsOnWearableTypeMismatch(InventoryItemBase baseItem, CachedUserInfo uinfo, IClientAPI clientView)
        {
            if (baseItem.InvType != (int)InventoryType.Wearable) return false;

            //download the asset and extract the type. make sure the type matches the lower byte
            //of the inventory item flags

            AssetBase asset;
            try
            {
                asset = CommsManager.AssetCache.GetAsset(baseItem.AssetID, AssetRequestInfo.InternalRequest());
                if (asset == null) return false;    // not found
            }
            catch
            {
                //we couldnt get the asset, cant apply fixups
                return false;
            }

            //do we have the correct asset type to parse?
            if (asset.Type != (sbyte)AssetType.Clothing && asset.Type != (sbyte)AssetType.Bodypart) return false;

            try
            {
                uint wearableTypeInAsset = this.ParseWearableAndGetType(asset);

                //do they match?
                if (wearableTypeInAsset != (baseItem.Flags & 0xFF))
                {
                    //no. we need a fixup
                    m_log.ErrorFormat("[APPEARANCE]: Hotpatching item {0} due to flags mismatch: Got {1}, should be {2}",
                        baseItem.ID, baseItem.Flags & 0xFF, wearableTypeInAsset);

                    //remove the first byte
                    baseItem.Flags = baseItem.Flags & 0xFFFFFF00;
                    //combine our type
                    baseItem.Flags = baseItem.Flags | (wearableTypeInAsset & 0xFF);

                    //save back the inventory item with updated flags
                    uinfo.UpdateItem(baseItem);

                    //inform viewer
                    clientView.SendBulkUpdateInventory(baseItem);

                    return true;
                }

                return false;
            }
            catch (Exception e)
            {
                m_log.ErrorFormat("[APPEARANCE]: Error when attempting to parse wearable and update item for Flags hotpatch {0}", e);

                //couldnt parse wearable
                return false;
            }
        }
        private void CopyItemsToFolder(CachedUserInfo inventoryOwner, UUID folderId, IList<SceneObjectGroup> items,
            IClientAPI remoteClient, bool stopScripts)
        {
            SerializationFlags serFlags = stopScripts ? SerializationFlags.StopScripts : SerializationFlags.None;

            if (items.Count == 0)
            {
                throw new ArgumentOutOfRangeException("CopyItemsToFolder() Given 0 items to copy");
            }

            //if there is only one item, this will be the basis for it
            //if this a coalesced object, this will be the basis for the name etc
            InventoryItemBase newInvItem = new InventoryItemBase();
            newInvItem.CreatorId = items[0].RootPart.CreatorID.ToString();
            newInvItem.ID = UUID.Random();
            newInvItem.InvType = (int)InventoryType.Object;
            newInvItem.Folder = folderId;
            newInvItem.Owner = inventoryOwner.UserProfile.ID;

            if (items.Count == 1)
            {
                ItemPermissionBlock newPerms = items[0].GetNewItemPermissions(inventoryOwner.UserProfile.ID);
                newPerms.ApplyToOther(newInvItem);

                byte[] objAsset = this.DoSerializeSingleGroup(items[0], serFlags);
                
                //single item, store as single item asset
                AssetBase itemAsset = CreateAsset(
                    items[0].GetPartName(items[0].RootPart.LocalId),
                    items[0].GetPartDescription(items[0].RootPart.LocalId),
                    (sbyte)AssetType.Object,
                    objAsset);

                //exception storing asset will get thrown up and prevent the object from
                //vanishing from the scene
                try
                {
                    CommsManager.AssetCache.AddAsset(itemAsset, AssetRequestInfo.InternalRequest());
                }
                catch (AssetServerException)
                {
                    if (remoteClient != null) remoteClient.SendAgentAlertMessage("Unable to create asset. Please try again later.", false);
                    throw;
                }
                
                //store inventory object
                newInvItem.CreationDate = Util.UnixTimeSinceEpoch();
                newInvItem.Description = itemAsset.Description;
                newInvItem.Name = itemAsset.Name;
                newInvItem.AssetType = itemAsset.Type;
                newInvItem.AssetID = itemAsset.FullID;

                inventoryOwner.AddItem(newInvItem);

                this.InformClientOfInvChange(remoteClient, newInvItem);
            }
            else if (items.Count > 1)
            {
                //we have a coalesced object, this must be serialized differently and flags set

                //retrieve a set of the next permissions for each item
                List<ItemPermissionBlock> itemPermissions = new List<ItemPermissionBlock>();
                foreach (SceneObjectGroup item in items)
                {
                    ItemPermissionBlock permsBlock = item.GetNewItemPermissions(inventoryOwner.UserProfile.ID);
                    itemPermissions.Add(permsBlock);
                }

                //serialize coalesced
                byte[] objAsset = this.DoSerializeCoalesced(items, itemPermissions, serFlags);

                //grab the first item to set the name etc
                SceneObjectGroup modelItem = items[0];

                //multiple items, store as multi item asset
                AssetBase itemAsset = CreateAsset(
                    modelItem.GetPartName(modelItem.RootPart.LocalId),
                    modelItem.GetPartDescription(modelItem.RootPart.LocalId),
                    (sbyte)AssetType.Object,
                    objAsset);

                //exception storing asset will get thrown up and prevent the object from
                //vanishing from the scene
                try
                {
                    CommsManager.AssetCache.AddAsset(itemAsset, AssetRequestInfo.InternalRequest());
                }
                catch (AssetServerException)
                {
                    if (remoteClient != null) remoteClient.SendAgentAlertMessage("Unable to create asset. Please try again later.", false);
                    throw;
                }

                //calculate minimum permissions for the coalesced object
                ItemPermissionBlock.CalculateCoalescedPermissions(itemPermissions).ApplyToOther(newInvItem);

                //misc
                newInvItem.CreationDate = Util.UnixTimeSinceEpoch();
                newInvItem.Description = itemAsset.Description;
                newInvItem.Name = itemAsset.Name;
                newInvItem.AssetType = itemAsset.Type;
                newInvItem.AssetID = itemAsset.FullID;

                //mark as coalesced
                newInvItem.Flags |= (uint)InventoryItemBase.Flag.OBJECT_HAS_MULTIPLE_ITEMS;

                //store inventory object
                inventoryOwner.AddItem(newInvItem);

                this.InformClientOfInvChange(remoteClient, newInvItem);
            }
        }
        InventoryFolderBase GetFolderIfValidAndNotInTrash(UUID folderId, CachedUserInfo uInfo)
        {
            try
            {
                //first make sure the folder exists at all
                InventoryFolderBase desiredFolder = uInfo.GetFolderAttributesChecked(folderId); //this will throw if the user doesnt own the folder or if it doesnt exist
                if (desiredFolder == null) return null;

                InventoryFolderBase topLevelFolder = uInfo.FindTopLevelFolderFor(desiredFolder.ID);

                if ((topLevelFolder != null) && (topLevelFolder.Type != (int)AssetType.TrashFolder))
                {
                    return desiredFolder;
                }
            }
            catch (Exception e)
            {
                m_log.InfoFormat("[AGENT INVENTORY] Unable to check heirarchy for {0}. {1}", folderId, e);
            }

            return null;
        }
 /// <summary>
 /// Constructor
 /// </summary>
 public InventoryArchiveWriteRequest(
     Guid id, InventoryArchiverModule module, Scene scene, 
     CachedUserInfo userInfo, string invPath, Stream saveStream)
 {
     m_id = id;
     m_module = module;
     m_scene = scene;
     m_userInfo = userInfo;
     m_invPath = invPath;
     m_saveStream = saveStream;
     m_assetGatherer = new UuidGatherer(m_scene.AssetService);
 }
Exemple #28
0
        private void InitialAttachmentRez(CachedUserInfo userInfo)
        {
            //retrieve all attachments
            List<AvatarAttachment> attachments = m_appearance.GetAttachments();
            m_appearance.ClearAttachments();
            bool updated = false;

            m_log.DebugFormat("[SCENE PRESENCE]: InitialAttachmentRez for {0} attachments", attachments.Count);

            foreach (AvatarAttachment attachment in attachments)
            {
                if (attachment.ItemID == UUID.Zero)
                    continue;

                // intial rez always appends
                SceneObjectGroup sog =
                    m_scene.RezSingleAttachmentSync(ControllingClient, attachment.ItemID, (uint)attachment.AttachPoint, true);
                if (sog != null)
                    updated = true;
            }

            if (updated)
            {
                IAvatarFactory ava = m_scene.RequestModuleInterface<IAvatarFactory>();
                if ((ava != null) && ((ControllingClient != null) && ControllingClient.IsActive))
                    ava.UpdateDatabase(ControllingClient.AgentId, Appearance, null, null);
            }
        }