Inheritance: Universe.Framework.Modules.IDataTransferable
        public AvatarArchive LoadAvatarArchive (string fileName, UUID principalID)
        {
            AvatarArchive archive = new AvatarArchive ();
            UserAccount account = userAccountService.GetUserAccount (null, principalID);
            if (account == null) {
                MainConsole.Instance.Error ("[Avatar Archiver]: User not found!");
                return null;
            }

            // need to be smart here...
            fileName = PathHelpers.VerifyReadFile (fileName, ".aa", m_storeDirectory);
            if (!File.Exists (fileName)) {
                MainConsole.Instance.Error ("[Avatar Archiver]: Unable to load from file: file does not exist!");
                return null;
            }
            MainConsole.Instance.Info ("[Avatar Archiver]: Loading archive from " + fileName);

            archive.FromOSD ((OSDMap)OSDParser.DeserializeLLSDXml (File.ReadAllText (fileName)));

            AvatarAppearance appearance = ConvertXMLToAvatarAppearance (archive.BodyMap);

            appearance.Owner = principalID;

            InventoryFolderBase AppearanceFolder = inventoryService.GetFolderForType (account.PrincipalID,
                                                                                     InventoryType.Wearable,
                                                                                     FolderType.Clothing);

            if (AppearanceFolder == null) {
                AppearanceFolder = new InventoryFolderBase (); // does not exist so...
                AppearanceFolder.Owner = account.PrincipalID;
                AppearanceFolder.ID = UUID.Random ();
                AppearanceFolder.Type = (short)FolderType.Clothing;
            }

            List<InventoryItemBase> items;

            InventoryFolderBase folderForAppearance
                = new InventoryFolderBase (
                    UUID.Random (), archive.FolderName, account.PrincipalID,
                (short)FolderType.None, AppearanceFolder.ID, 1);

            inventoryService.AddFolder (folderForAppearance);

            folderForAppearance = inventoryService.GetFolder (folderForAppearance);

            try {
                LoadAssets (archive.AssetsMap);
                appearance = CopyWearablesAndAttachments (account.PrincipalID, UUID.Zero, appearance, folderForAppearance,
                                                         account.PrincipalID, archive.ItemsMap, out items);
            } catch (Exception ex) {
                MainConsole.Instance.Warn ("[AvatarArchiver]: Error loading assets and items, " + ex);
            }

            /*  implement fully if we need to
            // inform the client if needed

            ScenePresence SP;
            MainConsole.Instance.ConsoleScenes[0].TryGetScenePresence(account.PrincipalID, out SP);
            if (SP == null)
                return; // nobody home!

            SP.ControllingClient.SendAlertMessage("Appearance loading in progress...");
            SP.ControllingClient.SendBulkUpdateInventory(folderForAppearance);
            */

            MainConsole.Instance.Info ("[Avatar Archiver]: Loaded archive from " + fileName);
            archive.Appearance = appearance;
            return archive;
        }
        void SaveAsset (UUID AssetID, ref AvatarArchive archive, bool isPortable)
        {
            IDictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType> ();

            AssetBase assetBase = assetService.Get (AssetID.ToString ());
            if (assetBase == null)
                return;

            if (isPortable)
                assetGatherer.GatherAssetUuids (assetBase.ID, assetBase.TypeAsset, assetUuids);
            else
                // we need this one at least
                assetUuids [assetBase.ID] = assetBase.TypeAsset;
            assetBase.Dispose ();
						// was //assetBase = null;

            // save the required assets
            foreach (KeyValuePair<UUID, AssetType> kvp in assetUuids) {
                var asset = assetService.Get (kvp.Key.ToString ());
                if (asset != null) {
                    MainConsole.Instance.Debug ("[Avatar Archiver]: Saving asset " + asset.ID);
                    archive.AssetsMap [asset.ID.ToString ()] = asset.ToOSD ();
                } else {
                    MainConsole.Instance.Debug ("[Avatar Archiver]: Could not find asset to save: " + kvp.Key);
                    return;
                }
                asset.Dispose ();
                //was//asset = null;
            }
        }
 void SaveItem (UUID ItemID, ref AvatarArchive archive)
 {
     InventoryItemBase saveItem = inventoryService.GetItem (UUID.Zero, ItemID);
     if (saveItem == null) {
         MainConsole.Instance.Warn ("[Avatar Archiver]: Could not find item to save: " + ItemID);
         return;
     }
     MainConsole.Instance.Info ("[Avatar Archiver]: Saving item " + ItemID);
     archive.ItemsMap [ItemID.ToString ()] = saveItem.ToOSD ();
 }
        /// <summary>
        /// Gets all public avatar archives
        /// </summary>
        /// <returns></returns>
        public List<AvatarArchive> GetAvatarArchives ()
        {
            var archives = new List<AvatarArchive> ();

            if (Directory.Exists (m_storeDirectory)) {
                foreach (string file in Directory.GetFiles (m_storeDirectory, "*.aa")) {
                    try {
                        AvatarArchive archive = new AvatarArchive ();
                        archive.FromOSD ((OSDMap)OSDParser.DeserializeLLSDXml (File.ReadAllText (file)));
                        if (archive.IsPublic) {
                            //check for a local snapshot
                            var localPic = Path.ChangeExtension (file, "jpg");
                            if (File.Exists (localPic))
                                archive.LocalSnapshot = localPic;
                            else
                                archive.LocalSnapshot = string.Empty;

                            archives.Add (archive);
                        }
                    } catch {
                        MainConsole.Instance.ErrorFormat ("[Avatar Archiver]: error deserializing {0} archive", file);
                    }
                }
            }

            return archives;
        }
        /// <summary>
        /// Saves the avatar archive.
        /// </summary>
        /// <returns><c>true</c>, if avatar archive was saved, <c>false</c> otherwise.</returns>
        /// <param name="fileName">File name.</param>
        /// <param name="principalID">Principal I.</param>
        /// <param name="folderName">Folder name.</param>
        /// <param name="snapshotUUID">Snapshot UUI.</param>
        /// <param name="isPublic">If set to <c>true</c> is public.</param>
        /// <param name="isPortable">If set to <c>true</c> create a portable archive.</param>
        public bool SaveAvatarArchive (string fileName, UUID principalID, string folderName,
            UUID snapshotUUID, bool isPublic, bool isPortable)
        {
            UserAccount account = userAccountService.GetUserAccount (null, principalID);
            if (account == null) {
                MainConsole.Instance.Error ("[Avatar Archiver]: User not found!");
                return false;
            }

            AvatarAppearance appearance = avatarService.GetAppearance (account.PrincipalID);
            if (appearance == null) {
                MainConsole.Instance.Error ("[Avatar Archiver] Appearance not found!");
                return false;
            }

            string archiveName = Path.GetFileNameWithoutExtension (fileName);
            string filePath = Path.GetDirectoryName (fileName);

            AvatarArchive archive = new AvatarArchive ();
            archive.AssetsMap = new OSDMap ();
            archive.ItemsMap = new OSDMap ();

            int wearCount = 0;
            foreach (AvatarWearable wear in appearance.Wearables) {
                for (int i = 0; i < wear.Count; i++) {
                    WearableItem w = wear [i];

                    if (w.AssetID != UUID.Zero) {
                        SaveItem (w.ItemID, ref archive);
                        SaveAsset (w.AssetID, ref archive, isPortable);
                        wearCount++;
                    }
                }
            }
            MainConsole.Instance.InfoFormat ("[Avatar Archiver] Adding {0} wearables to {1}", wearCount, archiveName);

            int attachCount = 0;
            List<AvatarAttachment> attachments = appearance.GetAttachments ();
            foreach (AvatarAttachment a in attachments.Where (a => a.AssetID != UUID.Zero)) {
                SaveItem (a.ItemID, ref archive);
                SaveAsset (a.AssetID, ref archive, isPortable);
                attachCount++;
            }
            MainConsole.Instance.InfoFormat ("[Avatar Archiver] Adding {0} attachments to {1}", attachCount, archiveName);

            // set details
            archive.Appearance = appearance;
            archive.BodyMap = appearance.Pack ();
            archive.FolderName = folderName;
            archive.Snapshot = snapshotUUID;
            archive.IsPublic = isPublic;
            archive.IsPortable = isPortable;

            File.WriteAllText (fileName, OSDParser.SerializeLLSDXmlString (archive.ToOSD ()));

            if (snapshotUUID != UUID.Zero) {

                ExportArchiveImage (snapshotUUID, archiveName, filePath);
                MainConsole.Instance.Info ("[Avatar Archiver] Saved archive snapshot");
            }

            MainConsole.Instance.Info ("[Avatar Archiver] Saved archive to " + fileName);

            return true;
        }
 void SaveAsset(UUID AssetID, ref AvatarArchive archive)
 {
     try
     {
         AssetBase asset = assetService.Get(AssetID.ToString());
         if (asset != null)
         {
             MainConsole.Instance.Info("[AvatarArchive]: Saving asset " + asset.ID);
             archive.AssetsMap[asset.ID.ToString()] = asset.ToOSD();
         }
         else
         {
             MainConsole.Instance.Warn("[AvatarArchive]: Could not find asset to save: " + AssetID.ToString());
             return;
         }
     }
     catch (Exception ex)
     {
         MainConsole.Instance.Warn("[AvatarArchive]: Could not save asset: " + AssetID.ToString() + ", " + ex);
     }
 }
        public AvatarArchive LoadAvatarArchive(string fileName, UUID principalID)
        {
            AvatarArchive archive = new AvatarArchive();
            UserAccount account = userAccountService.GetUserAccount(null, principalID);
            if (account == null)
            {
                MainConsole.Instance.Error("[AvatarArchive]: User not found!");
                return null;
            }

            // need to be smart here...
            fileName = PathHelpers.VerifyReadFile (fileName, ".aa", m_storeDirectory);
            if (!File.Exists(fileName))
            {
                MainConsole.Instance.Error("[AvatarArchive]: Unable to load from file: file does not exist!");
                return null;
            }
            MainConsole.Instance.Info("[AvatarArchive]: Loading archive from " + fileName);

            archive.FromOSD((OSDMap)OSDParser.DeserializeLLSDXml(File.ReadAllText(fileName)));

            AvatarAppearance appearance = ConvertXMLToAvatarAppearance(archive.BodyMap);

            appearance.Owner = principalID;

            InventoryFolderBase AppearanceFolder = inventoryService.GetFolderForType(account.PrincipalID,
                                                                                     InventoryType.Wearable,
                                                                                     AssetType.Clothing);

            if (AppearanceFolder == null)
            {
                AppearanceFolder = new InventoryFolderBase (); // does not exist so...
                AppearanceFolder.Owner = account.PrincipalID;
                AppearanceFolder.ID = UUID.Random ();
                AppearanceFolder.Type = (short) InventoryType.Wearable;
            }

            List<InventoryItemBase> items;

            InventoryFolderBase folderForAppearance
                = new InventoryFolderBase(
                    UUID.Random(), archive.FolderName, account.PrincipalID,
                    -1, AppearanceFolder.ID, 1);

            inventoryService.AddFolder(folderForAppearance);

            folderForAppearance = inventoryService.GetFolder(folderForAppearance);

            try
            {
                LoadAssets(archive.AssetsMap);
                appearance = CopyWearablesAndAttachments(account.PrincipalID, UUID.Zero, appearance, folderForAppearance,
                                                         account.PrincipalID, archive.ItemsMap, out items);
            }
            catch (Exception ex)
            {
                MainConsole.Instance.Warn("[AvatarArchiver]: Error loading assets and items, " + ex);
            }

            MainConsole.Instance.Info("[AvatarArchive]: Loaded archive from " + fileName);
            archive.Appearance = appearance;
            return archive;
        }
        /// <summary>
        /// Gets all public avatar archives
        /// </summary>
        /// <returns></returns>
        public List<AvatarArchive> GetAvatarArchives()
        {
            var archives = new List<AvatarArchive>();

            if (Directory.Exists(m_storeDirectory))
            {
                foreach (string file in Directory.GetFiles(m_storeDirectory, "*.aa"))
                {
                    try
                    {
                        AvatarArchive archive = new AvatarArchive();
                        archive.FromOSD((OSDMap)OSDParser.DeserializeLLSDXml(File.ReadAllText(file)));
                        if (archive.IsPublic)
                            archives.Add(archive);
                    }
                    catch
                    {
                    }
                }
            }

            return archives;
        }