예제 #1
0
파일: Backup.cs 프로젝트: x8ball/Aurora-Sim
            public void SaveModuleToArchive(TarArchiveWriter writer, IScene scene)
            {
                m_isArchiving = true;

                m_log.Info("[Archive]: Writing parcels to archive");

                writer.WriteDir("parcels");

                IParcelManagementModule module = scene.RequestModuleInterface <IParcelManagementModule>();

                if (module != null)
                {
                    List <ILandObject> landObject = module.AllParcels();
                    foreach (ILandObject parcel in landObject)
                    {
                        OSDMap parcelMap = parcel.LandData.ToOSD();
                        writer.WriteFile("parcels/" + parcel.LandData.GlobalID.ToString(), OSDParser.SerializeLLSDBinary(parcelMap));
                    }
                }

                m_log.Info("[Archive]: Finished writing parcels to archive");
                m_log.Info("[Archive]: Writing terrain to archive");

                writer.WriteDir("terrain");

                ITerrainModule tModule = scene.RequestModuleInterface <ITerrainModule>();

                if (tModule != null)
                {
                    MemoryStream s = new MemoryStream();
                    tModule.SaveToStream(scene.RegionInfo.RegionID.ToString() + ".r32", s);
                    writer.WriteFile("terrain/" + scene.RegionInfo.RegionID.ToString() + ".r32", s.ToArray());
                    s.Close();
                }

                m_log.Info("[Archive]: Finished writing terrain to archive");
                m_log.Info("[Archive]: Writing entities to archive");
                ISceneEntity[] entities = scene.Entities.GetEntities();
                //Get all entities, then start writing them to the database
                writer.WriteDir("entities");

                IDictionary <UUID, AssetType> assets = new Dictionary <UUID, AssetType>();
                UuidGatherer assetGatherer           = new UuidGatherer(m_scene.AssetService);

                foreach (ISceneEntity entity in entities)
                {
                    //Write all entities
                    writer.WriteFile("entities/" + entity.UUID.ToString(), ((ISceneObject)entity).ToXml2());
                    //Get all the assets too
                    assetGatherer.GatherAssetUuids(entity, assets, scene);
                }

                m_log.Info("[Archive]: Finished writing entities to archive");
                m_log.Info("[Archive]: Writing assets for entities to archive");

                bool foundAllAssets = true;

                foreach (UUID assetID in new List <UUID>(assets.Keys))
                {
                    AssetBase asset = m_scene.AssetService.GetCached(assetID.ToString());
                    if (asset != null)
                    {
                        WriteAsset(asset, writer); //Write it syncronously since we havn't
                    }
                    else
                    {
                        foundAllAssets = false; //Not all are cached
                        m_missingAssets.Add(assetID);
                        m_scene.AssetService.Get(assetID.ToString(), writer, RetrievedAsset);
                    }
                }
                if (foundAllAssets)
                {
                    m_isArchiving = false; //We're done if all the assets were found
                }
                m_log.Info("[Archive]: Finished writing assets for entities to archive");
            }
예제 #2
0
        public bool SaveBackup(string fileName, RegionData regiondata)
        {
            try
            {
                bool oldFileExists = File.Exists(fileName);
                //Do new style saving here!
                GZipStream m_saveStream = new GZipStream(new FileStream(fileName + ".tmp", FileMode.Create),
                                                         CompressionMode.Compress);
                TarArchiveWriter writer       = new TarArchiveWriter(m_saveStream);
                GZipStream       m_loadStream = new GZipStream(new FileStream(fileName, FileMode.Open),
                                                               CompressionMode.Decompress);
                TarArchiveReader reader = new TarArchiveReader(m_loadStream);

                writer.WriteDir("parcels");

                foreach (LandData parcel in regiondata.Parcels)
                {
                    OSDMap parcelMap = parcel.ToOSD();
                    var    binary    = OSDParser.SerializeLLSDBinary(parcelMap);
                    writer.WriteFile("parcels/" + parcel.GlobalID.ToString(),
                                     binary);
                    binary    = null;
                    parcelMap = null;
                }

                writer.WriteDir("newstyleterrain");
                writer.WriteDir("newstylerevertterrain");

                writer.WriteDir("newstylewater");
                writer.WriteDir("newstylerevertwater");

                writer.WriteDir("regioninfo");
                byte[] regionData = OSDParser.SerializeLLSDBinary(regiondata.RegionInfo.PackRegionInfoData());
                writer.WriteFile("regioninfo/regioninfo", regionData);

                try
                {
                    writer.WriteFile("newstyleterrain/" + regiondata.RegionInfo.RegionID.ToString() + ".terrain",
                                     regiondata.Terrain);

                    writer.WriteFile(
                        "newstylerevertterrain/" + regiondata.RegionInfo.RegionID.ToString() + ".terrain",
                        regiondata.RevertTerrain);

                    if (regiondata.Water != null)
                    {
                        writer.WriteFile("newstylewater/" + regiondata.RegionInfo.RegionID.ToString() + ".terrain",
                                         regiondata.Water);

                        writer.WriteFile(
                            "newstylerevertwater/" + regiondata.RegionInfo.RegionID.ToString() + ".terrain",
                            regiondata.RevertWater);
                    }
                }
                catch (Exception ex)
                {
                    MainConsole.Instance.WarnFormat("[Backup]: Exception caught: {0}", ex);
                }

                List <UUID> entitiesToSave = new List <UUID>();
                foreach (ISceneEntity entity in regiondata.Groups)
                {
                    try
                    {
                        if (entity.IsAttachment ||
                            ((entity.RootChild.Flags & PrimFlags.Temporary) == PrimFlags.Temporary) ||
                            ((entity.RootChild.Flags & PrimFlags.TemporaryOnRez) == PrimFlags.TemporaryOnRez))
                        {
                            continue;
                        }
                        if (entity.HasGroupChanged || !oldFileExists)
                        {
                            entity.HasGroupChanged = false;
                            //Write all entities
                            writer.WriteFile("entities/" + entity.UUID.ToString(), entity.ToBinaryXml2());
                        }
                        else
                        {
                            entitiesToSave.Add(entity.UUID);
                        }
                    }
                    catch (Exception ex)
                    {
                        MainConsole.Instance.WarnFormat("[Backup]: Exception caught: {0}", ex);
                        entitiesToSave.Add(entity.UUID);
                    }
                }

                if (oldFileExists)
                {
                    byte[] data;
                    string filePath;
                    TarArchiveReader.TarEntryType entryType;
                    //Load the archive data that we need
                    try
                    {
                        while ((data = reader.ReadEntry(out filePath, out entryType)) != null)
                        {
                            if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType)
                            {
                                continue;
                            }
                            if (filePath.StartsWith("entities/"))
                            {
                                UUID entityID = UUID.Parse(filePath.Remove(0, 9));
                                if (entitiesToSave.Contains(entityID))
                                {
                                    writer.WriteFile(filePath, data);
                                    entitiesToSave.Remove(entityID);
                                }
                            }
                            data = null;
                        }
                    }
                    catch (Exception ex)
                    {
                        MainConsole.Instance.WarnFormat("[Backup]: Exception caught: {0}", ex);
                    }

                    if (entitiesToSave.Count > 0)
                    {
                        MainConsole.Instance.Fatal(entitiesToSave.Count +
                                                   " PRIMS WERE NOT GOING TO BE SAVED! FORCE SAVING NOW! ");
                        foreach (ISceneEntity entity in regiondata.Groups)
                        {
                            if (entitiesToSave.Contains(entity.UUID))
                            {
                                if (entity.IsAttachment ||
                                    ((entity.RootChild.Flags & PrimFlags.Temporary) == PrimFlags.Temporary) ||
                                    ((entity.RootChild.Flags & PrimFlags.TemporaryOnRez) == PrimFlags.TemporaryOnRez))
                                {
                                    continue;
                                }
                                //Write all entities
                                byte[] xml = entity.ToBinaryXml2();
                                writer.WriteFile("entities/" + entity.UUID.ToString(), xml);
                                xml = null;
                            }
                        }
                    }
                }

                reader.Close();
                writer.Close();
                m_loadStream.Close();
                m_saveStream.Close();
                GC.Collect();
            }
            catch (Exception ex)
            {
                MainConsole.Instance.Warn("[ProtobufRegionLoader]: Failed to save backup: " + ex.ToString());
                return(false);
            }
            return(true);
        }
        protected internal void Save(ICollection <UUID> assetsFoundUuids, ICollection <UUID> assetsNotFoundUuids)
        {
            foreach (UUID uuid in assetsNotFoundUuids)
            {
                MainConsole.Instance.DebugFormat("[Archiver]: Could not find asset {0}", uuid);
            }

            //MainConsole.Instance.InfoFormat(
            //    "[Archiver]: Received {0} of {1} assets requested", assetsFoundUuids.Count, assetsFoundUuids.Count + assetsNotFoundUuids.Count);

            MainConsole.Instance.InfoFormat("[Archiver]: Creating archive file.  This may take some time.");

            // Write out control file
            m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, Create0p2ControlFile());
            MainConsole.Instance.InfoFormat("[Archiver]: Added control file to archive.");

            // Write out region settings
            string settingsPath
                = string.Format("{0}{1}.xml", ArchiveConstants.SETTINGS_PATH, m_scene.RegionInfo.RegionName);

            m_archiveWriter.WriteFile(settingsPath,
                                      RegionSettingsSerializer.Serialize(m_scene.RegionInfo.RegionSettings));

            MainConsole.Instance.InfoFormat("[Archiver]: Added region settings to archive.");

            // Write out land data (aka parcel) settings
            IParcelManagementModule parcelManagement = m_scene.RequestModuleInterface <IParcelManagementModule>();

            if (parcelManagement != null)
            {
                List <ILandObject> landObjects = parcelManagement.AllParcels();
                foreach (ILandObject lo in landObjects)
                {
                    LandData landData     = lo.LandData;
                    string   landDataPath = string.Format("{0}{1}.xml", ArchiveConstants.LANDDATA_PATH, landData.GlobalID);
                    m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData));
                }
            }

            MainConsole.Instance.InfoFormat("[Archiver]: Added parcel settings to archive.");

            // Write out terrain
            string terrainPath
                = string.Format("{0}{1}.r32", ArchiveConstants.TERRAINS_PATH, m_scene.RegionInfo.RegionName);

            MemoryStream ms = new MemoryStream();

            m_terrainModule.SaveToStream(m_terrainModule.TerrainMap, terrainPath, ms);
            m_archiveWriter.WriteFile(terrainPath, ms.ToArray());
            ms.Close();

            MainConsole.Instance.InfoFormat("[Archiver]: Added terrain information to archive.");

            // Write out scene object metadata
            foreach (ISceneEntity sceneObject in m_sceneObjects)
            {
                //MainConsole.Instance.DebugFormat("[Archiver]: Saving {0} {1}, {2}", entity.Name, entity.UUID, entity.GetType());

                string serializedObject = m_serializer.SerializeGroupToXml2(sceneObject);
                if (serializedObject != null)
                {
                    m_archiveWriter.WriteFile(ArchiveHelpers.CreateObjectPath(sceneObject), serializedObject);
                }
            }

            MainConsole.Instance.InfoFormat("[Archiver]: Added scene objects to archive.");
        }
예제 #4
0
        protected internal void ReceivedAllAssets(
            ICollection <UUID> assetsFoundUuids, ICollection <UUID> assetsNotFoundUuids)
        {
            foreach (UUID uuid in assetsNotFoundUuids)
            {
                m_log.DebugFormat("[ARCHIVER]: Could not find asset {0}", uuid);
            }

//            m_log.InfoFormat(
//                "[ARCHIVER]: Received {0} of {1} assets requested",
//                assetsFoundUuids.Count, assetsFoundUuids.Count + assetsNotFoundUuids.Count);

            m_log.InfoFormat("[ARCHIVER]: Creating archive file.  This may take some time.");

            // Write out control file
            m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, Create0p2ControlFile());
            m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");

            // Write out region settings
            string settingsPath
                = String.Format("{0}{1}.xml", ArchiveConstants.SETTINGS_PATH, m_scene.RegionInfo.RegionName);

            m_archiveWriter.WriteFile(settingsPath, RegionSettingsSerializer.Serialize(m_scene.RegionInfo.RegionSettings));

            m_log.InfoFormat("[ARCHIVER]: Added region settings to archive.");

            // Write out terrain
            string terrainPath
                = String.Format("{0}{1}.r32", ArchiveConstants.TERRAINS_PATH, m_scene.RegionInfo.RegionName);

            MemoryStream ms = new MemoryStream();

            m_terrainModule.SaveToStream(terrainPath, ms);
            m_archiveWriter.WriteFile(terrainPath, ms.ToArray());
            ms.Close();

            m_log.InfoFormat("[ARCHIVER]: Added terrain information to archive.");

            // Write out scene object metadata
            foreach (SceneObjectGroup sceneObject in m_sceneObjects)
            {
                //m_log.DebugFormat("[ARCHIVER]: Saving {0} {1}, {2}", entity.Name, entity.UUID, entity.GetType());

                Vector3 position = sceneObject.AbsolutePosition;

                string serializedObject = m_serialiser.SerializeGroupToXml2(sceneObject);
                string filename
                    = string.Format(
                          "{0}{1}_{2:000}-{3:000}-{4:000}__{5}.xml",
                          ArchiveConstants.OBJECTS_PATH, sceneObject.Name,
                          Math.Round(position.X), Math.Round(position.Y), Math.Round(position.Z),
                          sceneObject.UUID);

                m_archiveWriter.WriteFile(filename, serializedObject);
            }

            m_log.InfoFormat("[ARCHIVER]: Added scene objects to archive.");

            m_archiveWriter.Close();

            m_log.InfoFormat("[ARCHIVER]: Finished writing out OAR for {0}", m_scene.RegionInfo.RegionName);

            m_scene.EventManager.TriggerOarFileSaved(m_requestId, String.Empty);
        }
예제 #5
0
        /// <summary>
        /// Execute the inventory write request
        /// </summary>
        public void Execute(Dictionary <string, object> options, IUserAccountService userAccountService)
        {
            if (options.ContainsKey("noassets") && (bool)options["noassets"])
            {
                SaveAssets = false;
            }

            try
            {
                InventoryFolderBase inventoryFolder = null;
                InventoryItemBase   inventoryItem   = null;
                InventoryFolderBase rootFolder      = m_scene.InventoryService.GetRootFolder(m_userInfo.PrincipalID);

                bool saveFolderContentsOnly = false;

                // Eliminate double slashes and any leading / on the path.
                string[] components
                    = m_invPath.Split(
                          new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries);

                int maxComponentIndex = components.Length - 1;

                // If the path terminates with a STAR then later on we want to archive all nodes in the folder but not the
                // folder itself.  This may get more sophisicated later on
                if (maxComponentIndex >= 0 && components[maxComponentIndex] == STAR_WILDCARD)
                {
                    saveFolderContentsOnly = true;
                    maxComponentIndex--;
                }
                else if (maxComponentIndex == -1)
                {
                    // If the user has just specified "/", then don't save the root "My Inventory" folder.  This is
                    // more intuitive then requiring the user to specify "/*" for this.
                    saveFolderContentsOnly = true;
                }

                m_invPath = String.Empty;
                for (int i = 0; i <= maxComponentIndex; i++)
                {
                    m_invPath += components[i] + InventoryFolderImpl.PATH_DELIMITER;
                }

                // Annoyingly Split actually returns the original string if the input string consists only of delimiters
                // Therefore if we still start with a / after the split, then we need the root folder
                if (m_invPath.Length == 0)
                {
                    inventoryFolder = rootFolder;
                }
                else
                {
                    m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER));
                    List <InventoryFolderBase> candidateFolders
                        = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, rootFolder, m_invPath);
                    if (candidateFolders.Count > 0)
                    {
                        inventoryFolder = candidateFolders[0];
                    }
                }

                // The path may point to an item instead
                if (inventoryFolder == null)
                {
                    inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath);
                }

                if (null == inventoryFolder && null == inventoryItem)
                {
                    // We couldn't find the path indicated
                    string    errorMessage = string.Format("Aborted save.  Could not find inventory path {0}", m_invPath);
                    Exception e            = new InventoryArchiverException(errorMessage);
                    m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e);
                    throw e;
                }

                m_archiveWriter = new TarArchiveWriter(m_saveStream);

                m_log.InfoFormat("[INVENTORY ARCHIVER]: Adding control file to archive.");

                // Write out control file.  This has to be done first so that subsequent loaders will see this file first
                // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this
                // not sure how to fix this though, short of going with a completely different file format.
                m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options));

                if (inventoryFolder != null)
                {
                    m_log.DebugFormat(
                        "[INVENTORY ARCHIVER]: Found folder {0} {1} at {2}",
                        inventoryFolder.Name,
                        inventoryFolder.ID,
                        m_invPath == String.Empty ? InventoryFolderImpl.PATH_DELIMITER : m_invPath);

                    //recurse through all dirs getting dirs and files
                    SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !saveFolderContentsOnly, options, userAccountService);
                }
                else if (inventoryItem != null)
                {
                    m_log.DebugFormat(
                        "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}",
                        inventoryItem.Name, inventoryItem.ID, m_invPath);

                    SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH, options, userAccountService);
                }

                // Don't put all this profile information into the archive right now.
                //SaveUsers();

                if (SaveAssets)
                {
                    m_log.DebugFormat("[INVENTORY ARCHIVER]: Saving {0} assets for items", m_assetUuids.Count);

                    AssetsRequest ar
                        = new AssetsRequest(
                              new AssetsArchiver(m_archiveWriter),
                              m_assetUuids, m_scene.AssetService,
                              m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
                              options, ReceivedAllAssets);

                    Util.RunThreadNoTimeout(o => ar.Execute(), "AssetsRequest", null);
                }
                else
                {
                    m_log.DebugFormat("[INVENTORY ARCHIVER]: Not saving assets since --noassets was specified");

                    ReceivedAllAssets(new List <UUID>(), new List <UUID>(), false);
                }
            }
            catch (Exception)
            {
                m_saveStream.Close();
                throw;
            }
        }
예제 #6
0
            public void SaveModuleToArchive(TarArchiveWriter writer, IScene scene)
            {
                m_isArchiving = true;

                MainConsole.Instance.Info("[Archive]: Writing parcels to archive");

                writer.WriteDir("parcels");

                IParcelManagementModule module = scene.RequestModuleInterface <IParcelManagementModule> ();

                if (module != null)
                {
                    List <ILandObject> landObject = module.AllParcels();
                    foreach (ILandObject parcel in landObject)
                    {
                        OSDMap parcelMap = parcel.LandData.ToOSD();
                        writer.WriteFile("parcels/" + parcel.LandData.GlobalID,
                                         OSDParser.SerializeLLSDBinary(parcelMap));
                    }
                }

                MainConsole.Instance.Info("[Archive]: Finished writing parcels to archive");
                MainConsole.Instance.Info("[Archive]: Writing terrain to archive");

                writer.WriteDir("newstyleterrain");
                writer.WriteDir("newstylerevertterrain");

                writer.WriteDir("newstylewater");
                writer.WriteDir("newstylerevertwater");

                ITerrainModule tModule = scene.RequestModuleInterface <ITerrainModule> ();

                if (tModule != null)
                {
                    try {
                        byte [] sdata = WriteTerrainToStream(tModule.TerrainMap);
                        writer.WriteFile("newstyleterrain/" + scene.RegionInfo.RegionID + ".terrain", sdata);

                        sdata = WriteTerrainToStream(tModule.TerrainRevertMap);
                        writer.WriteFile("newstylerevertterrain/" + scene.RegionInfo.RegionID + ".terrain",
                                         sdata);
                        sdata = null;

                        if (tModule.TerrainWaterMap != null)
                        {
                            sdata = WriteTerrainToStream(tModule.TerrainWaterMap);
                            writer.WriteFile("newstylewater/" + scene.RegionInfo.RegionID + ".terrain", sdata);

                            sdata = WriteTerrainToStream(tModule.TerrainWaterRevertMap);
                            writer.WriteFile("newstylerevertwater/" + scene.RegionInfo.RegionID + ".terrain", sdata);
                            sdata = null;
                        }
                    } catch (Exception ex) {
                        MainConsole.Instance.WarnFormat("[Backup]: Exception caught: {0}", ex);
                    }
                }

                MainConsole.Instance.Info("[Archive]: Finished writing terrain to archive");
                MainConsole.Instance.Info("[Archive]: Writing entities to archive");
                ISceneEntity [] entities = scene.Entities.GetEntities();
                //Get all entities, then start writing them to the database
                writer.WriteDir("entities");

                IDictionary <UUID, AssetType> assets   = new Dictionary <UUID, AssetType> ();
                UuidGatherer             assetGatherer = new UuidGatherer(m_scene.AssetService);
                IWhiteCoreBackupArchiver archiver      = m_scene.RequestModuleInterface <IWhiteCoreBackupArchiver> ();
                bool saveAssets = false;

                if (archiver.AllowPrompting)
                {
                    saveAssets =
                        MainConsole.Instance.Prompt("Save assets? (Will not be able to load on other grids if not saved)", "false")
                        .Equals("true", StringComparison.CurrentCultureIgnoreCase);
                }

                int count = 0;

                foreach (ISceneEntity entity in entities)
                {
                    try {
                        if (entity.IsAttachment ||
                            ((entity.RootChild.Flags & PrimFlags.Temporary) == PrimFlags.Temporary) ||
                            ((entity.RootChild.Flags & PrimFlags.TemporaryOnRez) == PrimFlags.TemporaryOnRez))
                        {
                            continue;
                        }

                        //Write all entities
                        byte [] xml = entity.ToBinaryXml2();
                        writer.WriteFile("entities/" + entity.UUID, xml);
                        xml = null;
                        count++;
                        if (count % 3 == 0)
                        {
                            Thread.Sleep(5);
                        }

                        //Get all the assets too
                        if (saveAssets)
                        {
                            assetGatherer.GatherAssetUuids(entity, assets);
                        }
                    } catch (Exception ex) {
                        MainConsole.Instance.WarnFormat("[Backup]: Exception caught: {0}", ex);
                    }
                }
                entities = null;

                MainConsole.Instance.Info("[Archive]: Finished writing entities to archive");
                MainConsole.Instance.Info("[Archive]: Writing assets for entities to archive");

                bool foundAllAssets = true;

                foreach (UUID assetID in new List <UUID> (assets.Keys))
                {
                    try {
                        foundAllAssets = false; //Not all are cached
                        m_scene.AssetService.Get(assetID.ToString(), writer, RetrievedAsset);
                        m_missingAssets.Add(assetID);
                    } catch (Exception ex) {
                        MainConsole.Instance.WarnFormat("[Backup]: Exception caught: {0}", ex);
                    }
                }
                if (foundAllAssets)
                {
                    m_isArchiving = false; //We're done if all the assets were found
                }
                MainConsole.Instance.Info("[Archive]: Finished writing assets for entities to archive");
            }
        public static void Save(
            UGUI principal,
            InventoryServiceInterface inventoryService,
            AssetServiceInterface assetService,
            List <AvatarNameServiceInterface> nameServices,
            SaveOptions options,
            Stream outputFile,
            string frompath,
            TTY console_io = null)
        {
            UUID parentFolder;
            Dictionary <UUID, KeyValuePair <string, UUID> > folders = new Dictionary <UUID, KeyValuePair <string, UUID> >();

            parentFolder = inventoryService.Folder[principal.ID, AssetType.RootFolder].ID;

            if (!frompath.StartsWith("/"))
            {
                throw new InvalidInventoryPathException();
            }
            foreach (string pathcomp in frompath.Substring(1).Split('/'))
            {
                List <InventoryFolder> childfolders = inventoryService.Folder.GetFolders(principal.ID, parentFolder);
                int idx;
                for (idx = 0; idx < childfolders.Count; ++idx)
                {
                    if (pathcomp.ToLower() == childfolders[idx].Name.ToLower())
                    {
                        break;
                    }
                }

                if (idx == childfolders.Count)
                {
                    throw new InvalidInventoryPathException();
                }

                parentFolder          = childfolders[idx].ID;
                folders[parentFolder] = new KeyValuePair <string, UUID>(childfolders[idx].Name, UUID.Zero);
            }

            using (GZipStream gzip = new GZipStream(outputFile, CompressionMode.Compress))
            {
                TarArchiveWriter writer = new TarArchiveWriter(gzip);

                bool saveAssets = (options & SaveOptions.NoAssets) == 0;

                if (console_io != null)
                {
                    console_io.Write("Saving archive info...");
                }

                writer.WriteFile("archive.xml", WriteArchiveXml(saveAssets));

                List <UUID> nextFolders = new List <UUID>();
                List <UUID> assetIds    = new List <UUID>();
                nextFolders.Add(parentFolder);
                if (console_io != null)
                {
                    console_io.Write("Saving inventory data...");
                }

                while (nextFolders.Count != 0)
                {
                    InventoryFolderContent content;
                    UUID folderId = nextFolders[0];
                    nextFolders.RemoveAt(0);
                    content = inventoryService.Folder.Content[principal.ID, folderId];
                    foreach (InventoryFolder folder in content.Folders)
                    {
                        folders[folder.ID] = new KeyValuePair <string, UUID>(folder.Name, folderId);
                    }

                    foreach (InventoryItem item in content.Items)
                    {
                        if (item.AssetType != AssetType.Link && item.AssetType != AssetType.LinkFolder &&
                            !assetIds.Contains(item.AssetID) && saveAssets)
                        {
                            assetIds.Add(item.AssetID);
                        }

                        writer.WriteFile(GetFolderPath(folders, item), WriteInventoryItem(item));
                    }
                }

                if (saveAssets)
                {
                    if (console_io != null)
                    {
                        console_io.Write("Saving asset data...");
                    }
                    /* we only parse sim details when saving assets */
                    AssetData data;

                    int assetidx = 0;
                    while (assetidx < assetIds.Count)
                    {
                        UUID assetID = assetIds[assetidx++];
                        try
                        {
                            data = assetService[assetID];
                        }
                        catch
                        {
                            continue;
                        }
                        writer.WriteAsset(data);
                        try
                        {
                            foreach (UUID refid in data.References)
                            {
                                if (!assetIds.Contains(refid))
                                {
                                    assetIds.Add(refid);
                                }
                            }
                        }
                        catch
                        {
                            console_io.WriteFormatted("Failed to parse asset {0}", assetID);
                        }
                    }
                }
            }
        }
예제 #8
0
        /// <summary>
        /// Archive the region requested.
        /// </summary>
        /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception>
        public void ArchiveRegion(Dictionary <string, object> options)
        {
            if (options.ContainsKey("noassets") && (bool)options["noassets"])
            {
                SaveAssets = false;
            }

            try
            {
                Dictionary <UUID, AssetType> assetUuids = new Dictionary <UUID, AssetType>();

                EntityBase[]            entities     = m_scene.GetEntities();
                List <SceneObjectGroup> sceneObjects = new List <SceneObjectGroup>();

                string checkPermissions             = null;
                int    numObjectsSkippedPermissions = 0;
                Object temp;
                if (options.TryGetValue("checkPermissions", out temp))
                {
                    checkPermissions = (string)temp;
                }

                // Filter entities so that we only have scene objects.
                // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
                // end up having to do this
                foreach (EntityBase entity in entities)
                {
                    if (entity is SceneObjectGroup)
                    {
                        SceneObjectGroup sceneObject = (SceneObjectGroup)entity;

                        if (!sceneObject.IsDeleted && !sceneObject.IsAttachment)
                        {
                            if (!CanUserArchiveObject(m_scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, checkPermissions))
                            {
                                // The user isn't allowed to copy/transfer this object, so it will not be included in the OAR.
                                ++numObjectsSkippedPermissions;
                            }
                            else
                            {
                                sceneObjects.Add(sceneObject);
                            }
                        }
                    }
                }

                if (SaveAssets)
                {
                    UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService);

                    foreach (SceneObjectGroup sceneObject in sceneObjects)
                    {
                        assetGatherer.GatherAssetUuids(sceneObject, assetUuids);
                    }

                    m_log.DebugFormat(
                        "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
                        sceneObjects.Count, assetUuids.Count);
                }
                else
                {
                    m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified");
                }

                if (numObjectsSkippedPermissions > 0)
                {
                    m_log.DebugFormat(
                        "[ARCHIVER]: {0} scene objects skipped due to lack of permissions",
                        numObjectsSkippedPermissions);
                }

                // Make sure that we also request terrain texture assets
                RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings;

                if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1)
                {
                    assetUuids[regionSettings.TerrainTexture1] = AssetType.Texture;
                }

                if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2)
                {
                    assetUuids[regionSettings.TerrainTexture2] = AssetType.Texture;
                }

                if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3)
                {
                    assetUuids[regionSettings.TerrainTexture3] = AssetType.Texture;
                }

                if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4)
                {
                    assetUuids[regionSettings.TerrainTexture4] = AssetType.Texture;
                }

                TarArchiveWriter archiveWriter = new TarArchiveWriter(m_saveStream);

                // Asynchronously request all the assets required to perform this archive operation
                ArchiveWriteRequestExecution awre
                    = new ArchiveWriteRequestExecution(
                          sceneObjects,
                          m_scene.RequestModuleInterface <ITerrainModule>(),
                          m_scene.RequestModuleInterface <IRegionSerialiserModule>(),
                          m_scene,
                          archiveWriter,
                          m_requestId,
                          options);

                m_log.InfoFormat("[ARCHIVER]: Creating archive file.  This may take some time.");

                // Write out control file.  This has to be done first so that subsequent loaders will see this file first
                // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this
                archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options));
                m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");

                if (SaveAssets)
                {
                    new AssetsRequest(
                        new AssetsArchiver(archiveWriter), assetUuids,
                        m_scene.AssetService, m_scene.UserAccountService,
                        m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets).Execute();
                }
                else
                {
                    awre.ReceivedAllAssets(new List <UUID>(), new List <UUID>());
                }
            }
            catch (Exception)
            {
                m_saveStream.Close();
                throw;
            }
        }
예제 #9
0
        public void TestLoadIarV0p1ExistingUsers()
        {
            Assert.Ignore();
            TestHelper.InMethod();
            Console.WriteLine("Started {0}", MethodBase.GetCurrentMethod());

            //log4net.Config.XmlConfigurator.Configure();

            string userFirstName  = "Mr";
            string userLastName   = "Tiddles";
            UUID   userUuid       = UUID.Parse("00000000-0000-0000-0000-000000000555");
            string user2FirstName = "Lord";
            string user2LastName  = "Lucan";
            UUID   user2Uuid      = UUID.Parse("00000000-0000-0000-0000-000000000666");

            string itemName = "b.lsl";
            string archiveItemName
                = string.Format("{0}{1}{2}", itemName, "_", UUID.Random());

            MemoryStream     archiveWriteStream = new MemoryStream();
            TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);

            InventoryItemBase item1 = new InventoryItemBase();

            item1.Name      = itemName;
            item1.AssetID   = UUID.Random();
            item1.GroupID   = UUID.Random();
            item1.CreatorId = OspResolver.MakeOspa(user2FirstName, user2LastName);
            //item1.CreatorId = userUuid.ToString();
            //item1.CreatorId = "00000000-0000-0000-0000-000000000444";
            item1.Owner = UUID.Zero;

            string item1FileName
                = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName);

            tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1));
            tar.Close();

            MemoryStream            archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
            SerialiserModule        serialiserModule  = new SerialiserModule();
            InventoryArchiverModule archiverModule    = new InventoryArchiverModule();

            // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene
            Scene             scene            = SceneSetupHelpers.SetupScene();
            IUserAdminService userAdminService = scene.CommsManager.UserAdminService;

            SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
            userAdminService.AddUser(
                userFirstName, userLastName, "meowfood", String.Empty, 1000, 1000, userUuid);
            userAdminService.AddUser(
                user2FirstName, user2LastName, "hampshire", String.Empty, 1000, 1000, user2Uuid);

            archiverModule.DearchiveInventory(userFirstName, userLastName, "/", archiveReadStream);

            CachedUserInfo userInfo
                = scene.CommsManager.UserProfileCacheService.GetUserDetails(userFirstName, userLastName);
            InventoryItemBase foundItem = userInfo.RootFolder.FindItemByPath(itemName);

            Assert.That(foundItem.CreatorId, Is.EqualTo(item1.CreatorId));
            Assert.That(foundItem.CreatorIdAsUuid, Is.EqualTo(user2Uuid));
            Assert.That(foundItem.Owner, Is.EqualTo(userUuid));

            Console.WriteLine("Successfully completed {0}", MethodBase.GetCurrentMethod());
        }
예제 #10
0
        public void TestLoadIarV0_1ExistingUsers()
        {
            TestHelper.InMethod();
            //log4net.Config.XmlConfigurator.Configure();

            string userFirstName            = "Mr";
            string userLastName             = "Tiddles";
            UUID   userUuid                 = UUID.Parse("00000000-0000-0000-0000-000000000555");
            string userItemCreatorFirstName = "Lord";
            string userItemCreatorLastName  = "Lucan";
            UUID   userItemCreatorUuid      = UUID.Parse("00000000-0000-0000-0000-000000000666");

            string item1Name       = "b.lsl";
            string archiveItemName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1Name, UUID.Random());

            MemoryStream     archiveWriteStream = new MemoryStream();
            TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);

            InventoryItemBase item1 = new InventoryItemBase();

            item1.Name      = item1Name;
            item1.AssetID   = UUID.Random();
            item1.GroupID   = UUID.Random();
            item1.CreatorId = OspResolver.MakeOspa(userItemCreatorFirstName, userItemCreatorLastName);
            //item1.CreatorId = userUuid.ToString();
            //item1.CreatorId = "00000000-0000-0000-0000-000000000444";
            item1.Owner = UUID.Zero;

            string item1FileName
                = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName);

            tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1));
            tar.Close();

            MemoryStream            archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
            SerialiserModule        serialiserModule  = new SerialiserModule();
            InventoryArchiverModule archiverModule    = new InventoryArchiverModule(true);

            // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene
            Scene scene = SceneSetupHelpers.SetupScene("inventory");

            SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);

            UserProfileTestUtils.CreateUserWithInventory(
                scene, userFirstName, userLastName, userUuid, "meowfood");
            UserProfileTestUtils.CreateUserWithInventory(
                scene, userItemCreatorFirstName, userItemCreatorLastName, userItemCreatorUuid, "hampshire");

            archiverModule.DearchiveInventory(userFirstName, userLastName, "/", "meowfood", archiveReadStream);

            InventoryItemBase foundItem1
                = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userUuid, item1Name);

            Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1");

// We have to disable this check since loaded items that did find users via OSPA resolution are now only storing the
// UUID, not the OSPA itself.
//            Assert.That(
//                foundItem1.CreatorId, Is.EqualTo(item1.CreatorId),
//                "Loaded item non-uuid creator doesn't match original");
            Assert.That(
                foundItem1.CreatorId, Is.EqualTo(userItemCreatorUuid.ToString()),
                "Loaded item non-uuid creator doesn't match original");

            Assert.That(
                foundItem1.CreatorIdAsUuid, Is.EqualTo(userItemCreatorUuid),
                "Loaded item uuid creator doesn't match original");
            Assert.That(foundItem1.Owner, Is.EqualTo(userUuid),
                        "Loaded item owner doesn't match inventory reciever");

            // Now try loading to a root child folder
            UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, userUuid, "xA");
            archiveReadStream = new MemoryStream(archiveReadStream.ToArray());
            archiverModule.DearchiveInventory(userFirstName, userLastName, "xA", "meowfood", archiveReadStream);

            InventoryItemBase foundItem2
                = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userUuid, "xA/" + item1Name);

            Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2");

            // Now try loading to a more deeply nested folder
            UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, userUuid, "xB/xC");
            archiveReadStream = new MemoryStream(archiveReadStream.ToArray());
            archiverModule.DearchiveInventory(userFirstName, userLastName, "xB/xC", "meowfood", archiveReadStream);

            InventoryItemBase foundItem3
                = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userUuid, "xB/xC/" + item1Name);

            Assert.That(foundItem3, Is.Not.Null, "Didn't find loaded item 3");
        }
        /// <summary>
        /// Archive the region requested.
        /// </summary>
        /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception>
        public void ArchiveRegion()
        {
            Dictionary <UUID, int> assetUuids = new Dictionary <UUID, int>();

            List <EntityBase>       entities     = m_scene.GetEntities();
            List <SceneObjectGroup> sceneObjects = new List <SceneObjectGroup>();
            List <UUID>             userlist     = new List <UUID>();

            // Filter entities so that we only have scene objects.
            // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
            // end up having to do this
            foreach (EntityBase entity in entities)
            {
                if (entity is SceneObjectGroup)
                {
                    SceneObjectGroup sceneObject = (SceneObjectGroup)entity;

                    // If storing assets, assume cross-grid and include the user list file
                    if (m_storeAssets)
                    {
                        AddObjectUsersToList(userlist, sceneObject);
                    }
                    if (MustCheckCreatorIds)
                    {
                        bool failedCreatorCheck = false;
                        foreach (SceneObjectPart part in sceneObject.GetParts())
                        {
                            if (!ExportIsAllowed(part.CreatorID))
                            {
                                failedCreatorCheck = true;
                                break;
                            }
                        }

                        if (failedCreatorCheck)
                        {
                            continue;
                        }
                    }

                    if (!sceneObject.IsDeleted && !sceneObject.IsAttachment)
                    {
                        sceneObjects.Add(sceneObject);
                    }
                }
            }

            if (m_storeAssets)
            {
                UuidGatherer assetGatherer = new UuidGatherer(m_scene.CommsManager.AssetCache);

                foreach (SceneObjectGroup sceneObject in sceneObjects)
                {
                    assetGatherer.GatherAssetUuids(sceneObject, assetUuids);
                }
            }

            // Make sure that we also request terrain texture assets
            RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings;

            if (m_storeAssets)
            {
                if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1)
                {
                    assetUuids[regionSettings.TerrainTexture1] = 1;
                }

                if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2)
                {
                    assetUuids[regionSettings.TerrainTexture2] = 1;
                }

                if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3)
                {
                    assetUuids[regionSettings.TerrainTexture3] = 1;
                }

                if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4)
                {
                    assetUuids[regionSettings.TerrainTexture4] = 1;
                }
            }

            if (MustCheckCreatorIds)
            {
                int originalCount = assetUuids.Count;

                m_log.DebugFormat(
                    "[ARCHIVER]: Filtering {0} asset IDs for {1} allowed creators",
                    originalCount, m_allowedCreatorIds.Count);

                C5.HashSet <UUID> assetsCreatedByAllowedUsers = this.CollectCreatedAssetIdsFromUserInventories();

                IEnumerable <UUID> uuids = new List <UUID>(assetUuids.Keys);
                assetUuids.Clear();

                foreach (UUID assetId in uuids)
                {
                    if (assetsCreatedByAllowedUsers.Contains(assetId))
                    {
                        assetUuids.Add(assetId, 1);
                    }
                }

                m_log.DebugFormat(
                    "[ARCHIVER]: Allowing export of {0} of {1} assets",
                    assetUuids.Count, originalCount);
            }

            m_log.DebugFormat(
                "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
                sceneObjects.Count, assetUuids.Count);

            TarArchiveWriter archiveWriter = new TarArchiveWriter(m_saveStream);

            // Asynchronously request all the assets required to perform this archive operation
            ArchiveWriteRequestExecution awre
                = new ArchiveWriteRequestExecution(
                      sceneObjects,
                      m_scene.RequestModuleInterface <ITerrainModule>(),
                      m_scene.RequestModuleInterface <IRegionSerializerModule>(),
                      m_scene,
                      archiveWriter,
                      m_requestId);

            // Write out archive.xml control file first
            archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, awre.CreateControlFile(assetUuids.Count > 0));
            m_log.InfoFormat("[ARCHIVER]: Added {0} control file to archive.", ArchiveConstants.CONTROL_FILE_PATH);

            // Now include the user list file (only if assets are being saved and it produced a list).
            if (userlist.Count > 0)
            {
                StringBuilder sb = new StringBuilder();
                foreach (UUID id in userlist)
                {
                    String name = m_scene.CommsManager.UserService.Key2Name(id, false);
                    if (!String.IsNullOrWhiteSpace(name))
                    {
                        sb.AppendFormat("{0} {1}{2}", id, name, Environment.NewLine);
                    }
                }
                String userlistContents = sb.ToString();
                if (!String.IsNullOrWhiteSpace(userlistContents))
                {
                    archiveWriter.WriteFile(ArchiveConstants.USERLIST_FILE_PATH, userlistContents);
                    m_log.InfoFormat("[ARCHIVER]: Added {0} file to archive.", ArchiveConstants.USERLIST_FILE_PATH);
                }
            }

            new AssetsRequest(
                new AssetsArchiver(archiveWriter, m_scene), assetUuids.Keys,
                m_scene.CommsManager.AssetCache, awre.ReceivedAllAssets).Execute();
        }
예제 #12
0
        /// <summary>
        /// Write an assets metadata file to the given archive
        /// </summary>
        /// <param name="archive"></param>
//        protected void WriteMetadata(TarArchiveWriter archive)
//        {
//            StringWriter sw = new StringWriter();
//            XmlTextWriter xtw = new XmlTextWriter(sw);
//
//            xtw.Formatting = Formatting.Indented;
//            xtw.WriteStartDocument();
//
//            xtw.WriteStartElement("assets");
//
//            foreach (UUID uuid in m_assets.Keys)
//            {
//                AssetBase asset = m_assets[uuid];
//
//                if (asset != null)
//                {
//                    xtw.WriteStartElement("asset");
//
//                    string extension = String.Empty;
//
//                    if (ArchiveConstants.ASSET_TYPE_TO_EXTENSION.ContainsKey(asset.Type))
//                    {
//                        extension = ArchiveConstants.ASSET_TYPE_TO_EXTENSION[asset.Type];
//                    }
//
//                    xtw.WriteElementString("filename", uuid.ToString() + extension);
//
//                    xtw.WriteElementString("name", asset.Name);
//                    xtw.WriteElementString("description", asset.Description);
//                    xtw.WriteElementString("asset-type", asset.Type.ToString());
//
//                    xtw.WriteEndElement();
//                }
//            }
//
//            xtw.WriteEndElement();
//
//            xtw.WriteEndDocument();
//
//            archive.WriteFile("assets.xml", sw.ToString());
//        }

        /// <summary>
        /// Write asset data files to the given archive
        /// </summary>
        /// <param name="asset"></param>
        protected void WriteData(AssetBase asset)
        {
            // It appears that gtar, at least, doesn't need the intermediate directory entries in the tar
            //archive.AddDir("assets");

            string extension = String.Empty;

            if (ArchiveConstants.ASSET_TYPE_TO_EXTENSION.ContainsKey(asset.Type))
            {
                extension = ArchiveConstants.ASSET_TYPE_TO_EXTENSION[asset.Type];
            }
            else
            {
                m_log.ErrorFormat(
                    "[ARCHIVER]: Unrecognized asset type {0} with uuid {1}.  This asset will be saved but not reloaded",
                    asset.Type, asset.ID);
            }

            // Check for Thoosa Inventory object and decode to XML if necessary for Archive.
            string xmlData;

            if ((asset.Type == (sbyte)AssetType.Object) && (m_inventorySerializer != null) && (m_inventorySerializer.CanDeserialize(asset.Data)))
            {
                if (m_inventorySerializer.IsValidCoalesced(asset.Data))
                {
                    CoalescedObject            obj   = m_inventorySerializer.DeserializeCoalescedObjFromInventoryBytes(asset.Data);
                    List <ItemPermissionBlock> perms = new List <ItemPermissionBlock>();
                    foreach (var grp in obj.Groups)
                    {
                        perms.Add(obj.FindPermissions(grp.UUID));
                    }
                    xmlData = CoalescedSceneObjectSerializer.ToXmlFormat(obj.Groups, perms, StopScriptReason.None);
                }
                else
                if (m_inventorySerializer.IsValidGroup(asset.Data))
                {
                    SceneObjectGroup grp = m_inventorySerializer.DeserializeGroupFromInventoryBytes(asset.Data);
                    xmlData = m_serializer.SaveGroupToOriginalXml(grp);
                }
                else
                {
                    return;     // can't pass the CanDeserialize test above, but makes the compiler happy
                }
                // Now write out the XML format asset
                m_archiveWriter.WriteFile(
                    ArchiveConstants.ASSETS_PATH + asset.FullID.ToString() + extension,
                    xmlData);
            }
            else
            {
                // Now write out the same (raw) asset unchanged.
                m_archiveWriter.WriteFile(
                    ArchiveConstants.ASSETS_PATH + asset.FullID.ToString() + extension,
                    asset.Data);
            }
            m_assetsWritten++;

            if (m_assetsWritten % LOG_ASSET_LOAD_NOTIFICATION_INTERVAL == 0)
            {
                m_log.InfoFormat("[ARCHIVER]: Added {0} assets to archive", m_assetsWritten);
            }
        }
예제 #13
0
        public static void Save(
            SceneInterface scene,
            SaveOptions options,
            Stream outputFile,
            TTY console_io = null)
        {
            using (var gzip = new GZipStream(outputFile, CompressionMode.Compress))
            {
                var writer = new TarArchiveWriter(gzip);

                bool saveAssets = (options & SaveOptions.NoAssets) == 0;
                var  xmloptions = XmlSerializationOptions.None;
                if ((options & SaveOptions.Publish) == 0)
                {
                    xmloptions |= XmlSerializationOptions.WriteOwnerInfo;
                }

                if (console_io != null)
                {
                    console_io.Write("Saving archive info...");
                }

                writer.WriteFile("archive.xml", WriteArchiveXml08(scene, saveAssets));

                var objectAssets = new Dictionary <string, AssetData>();

                if (console_io != null)
                {
                    console_io.Write("Collecting object data...");
                }
                foreach (ObjectGroup sog in scene.Objects)
                {
                    if (sog.IsTemporary || sog.IsAttached)
                    {
                        /* skip temporary or attached */
                        continue;
                    }
                    AssetData data = sog.Asset(xmloptions | XmlSerializationOptions.WriteXml2 | XmlSerializationOptions.WriteKeyframeMotion | XmlSerializationOptions.WriteRezDate);
                    objectAssets.Add(EscapingMethods.EscapeName(sog.Name) + "_" + ((int)sog.GlobalPosition.X).ToString() + "-" + ((int)sog.GlobalPosition.Y).ToString() + "-" + ((int)sog.GlobalPosition.Z).ToString() + "__" + sog.ID.ToString() + ".xml", data);
                }

                #region Save Assets
                if (saveAssets)
                {
                    if (console_io != null)
                    {
                        console_io.Write("Saving asset data...");
                    }
                    /* we only parse sim details when saving assets */
                    var       assetIDs = new List <UUID>();
                    AssetData data;

                    foreach (AssetData objdata in objectAssets.Values)
                    {
                        foreach (UUID id in objdata.References)
                        {
                            if (id != UUID.Zero && !assetIDs.Contains(id))
                            {
                                assetIDs.Add(id);
                            }
                        }
                    }

                    foreach (ParcelInfo pinfo in scene.Parcels)
                    {
                        if (pinfo.MediaID != UUID.Zero)
                        {
                            assetIDs.Add(pinfo.MediaID);
                        }
                        if (pinfo.SnapshotID != UUID.Zero)
                        {
                            assetIDs.Add(pinfo.SnapshotID);
                        }
                    }

                    int assetidx = 0;
                    while (assetidx < assetIDs.Count)
                    {
                        UUID assetID = assetIDs[assetidx++];
                        try
                        {
                            data = scene.AssetService[assetID];
                        }
                        catch
                        {
                            continue;
                        }
                        writer.WriteAsset(data);
                        try
                        {
                            foreach (UUID refid in data.References)
                            {
                                if (!assetIDs.Contains(refid))
                                {
                                    assetIDs.Add(refid);
                                }
                            }
                        }
                        catch
                        {
                            console_io.WriteFormatted("Failed to parse asset {0}", assetID);
                        }
                    }
                }
                #endregion

                #region Region Settings
                if (console_io != null)
                {
                    console_io.Write("Saving region settings...");
                }
                using (var ms = new MemoryStream())
                {
                    using (XmlTextWriter xmlwriter = ms.UTF8XmlTextWriter())
                    {
                        RegionSettings settings = scene.RegionSettings;
                        xmlwriter.WriteStartElement("RegionSettings");
                        {
                            xmlwriter.WriteStartElement("General");
                            {
                                xmlwriter.WriteNamedValue("AllowDamage", settings.AllowDamage);
                                xmlwriter.WriteNamedValue("AllowLandResell", settings.AllowLandResell);
                                xmlwriter.WriteNamedValue("AllowLandJoinDivide", settings.AllowLandJoinDivide);
                                xmlwriter.WriteNamedValue("BlockFly", settings.BlockFly);
                                xmlwriter.WriteNamedValue("BlockFlyOver", settings.BlockFlyOver);
                                xmlwriter.WriteNamedValue("BlockLandShowInSearch", settings.BlockShowInSearch);
                                xmlwriter.WriteNamedValue("BlockTerraform", settings.BlockTerraform);
                                xmlwriter.WriteNamedValue("DisableCollisions", settings.DisableCollisions);
                                xmlwriter.WriteNamedValue("DisablePhysics", settings.DisablePhysics);
                                xmlwriter.WriteNamedValue("DisableScripts", settings.DisableScripts);
                                switch (scene.Access)
                                {
                                case RegionAccess.PG:
                                    xmlwriter.WriteNamedValue("MaturityRating", 0);
                                    break;

                                case RegionAccess.Mature:
                                    xmlwriter.WriteNamedValue("MaturityRating", 1);
                                    break;

                                case RegionAccess.Adult:
                                default:
                                    xmlwriter.WriteNamedValue("MaturityRating", 2);
                                    break;
                                }
                                xmlwriter.WriteNamedValue("RestrictPushing", settings.RestrictPushing);
                                xmlwriter.WriteNamedValue("AgentLimit", settings.AgentLimit);
                                xmlwriter.WriteNamedValue("ObjectBonus", settings.ObjectBonus);
                                xmlwriter.WriteNamedValue("ResetHomeOnTeleport", settings.ResetHomeOnTeleport);
                                xmlwriter.WriteNamedValue("AllowLandmark", settings.AllowLandmark);
                                xmlwriter.WriteNamedValue("AllowDirectTeleport", settings.AllowDirectTeleport);
                                xmlwriter.WriteNamedValue("MaxBasePrims", settings.MaxBasePrims);
                            }
                            xmlwriter.WriteEndElement();
                            xmlwriter.WriteStartElement("GroundTextures");
                            {
                                xmlwriter.WriteNamedValue("Texture1", settings.TerrainTexture1);
                                xmlwriter.WriteNamedValue("Texture2", settings.TerrainTexture2);
                                xmlwriter.WriteNamedValue("Texture3", settings.TerrainTexture3);
                                xmlwriter.WriteNamedValue("Texture4", settings.TerrainTexture4);
                                xmlwriter.WriteNamedValue("ElevationLowSW", settings.Elevation1SW);
                                xmlwriter.WriteNamedValue("ElevationLowNW", settings.Elevation1NW);
                                xmlwriter.WriteNamedValue("ElevationLowSE", settings.Elevation1SE);
                                xmlwriter.WriteNamedValue("ElevationLowNE", settings.Elevation1NE);
                                xmlwriter.WriteNamedValue("ElevationHighSW", settings.Elevation2SW);
                                xmlwriter.WriteNamedValue("ElevationHighNW", settings.Elevation2NW);
                                xmlwriter.WriteNamedValue("ElevationHighSE", settings.Elevation2SE);
                                xmlwriter.WriteNamedValue("ElevationHighNE", settings.Elevation2NE);
                            }
                            xmlwriter.WriteEndElement();
                            xmlwriter.WriteStartElement("Terrain");
                            {
                                xmlwriter.WriteNamedValue("WaterHeight", settings.WaterHeight);
                                xmlwriter.WriteNamedValue("TerrainRaiseLimit", settings.TerrainRaiseLimit);
                                xmlwriter.WriteNamedValue("TerrainLowerLimit", settings.TerrainLowerLimit);
                                xmlwriter.WriteNamedValue("UseEstateSun", settings.UseEstateSun);
                                xmlwriter.WriteNamedValue("FixedSun", settings.IsSunFixed);
                                xmlwriter.WriteNamedValue("SunPosition", settings.SunPosition + 6);
                            }
                            xmlwriter.WriteEndElement();
                            xmlwriter.WriteNamedValue("WalkableCoefficients", Convert.ToBase64String(settings.WalkableCoefficientsSerialization));
                            if (settings.TelehubObject != UUID.Zero)
                            {
                                xmlwriter.WriteStartElement("Telehub");
                                {
                                    xmlwriter.WriteNamedValue("TelehubObject", settings.TelehubObject);
                                    // yes, OpenSim likes to convert around data
                                    double yaw;
                                    double pitch;
                                    double distance;
                                    foreach (Vector3 sp in scene.SpawnPoints)
                                    {
                                        distance = sp.Length;

                                        Vector3 dir = sp.Normalize();

                                        // Get the bearing of the spawn point
                                        yaw = (float)Math.Atan2(dir.Y, dir.X);

                                        // Get the elevation of the spawn point
                                        pitch = (float)-Math.Atan2(dir.Z, Math.Sqrt(dir.X * dir.X + dir.Y * dir.Y));

                                        xmlwriter.WriteNamedValue("SpawnPoint", string.Format(CultureInfo.InvariantCulture, "{0},{1},{2}", yaw, pitch, distance));
                                    }
                                }
                                xmlwriter.WriteEndElement();
                            }
                        }
                        xmlwriter.WriteEndElement();
                    }
                    writer.WriteFile("settings/" + scene.Name + ".xml", ms.ToArray());
                }
                #endregion

                #region Saving parcels
                if (console_io != null)
                {
                    console_io.Write("Saving parcel data...");
                }

                foreach (ParcelInfo pinfo in scene.Parcels)
                {
                    using (var ms = new MemoryStream())
                    {
                        using (XmlTextWriter xmlwriter = ms.UTF8XmlTextWriter())
                        {
                            xmlwriter.WriteStartElement("LandData");
                            {
                                xmlwriter.WriteNamedValue("Area", pinfo.Area);
                                xmlwriter.WriteNamedValue("AuctionID", pinfo.AuctionID);
                                xmlwriter.WriteNamedValue("AuthBuyerID", pinfo.AuthBuyer.ID);
                                xmlwriter.WriteNamedValue("Category", (byte)pinfo.Category);
                                xmlwriter.WriteNamedValue("ClaimDate", pinfo.ClaimDate.DateTimeToUnixTime().ToString());
                                xmlwriter.WriteNamedValue("ClaimPrice", pinfo.ClaimPrice);
                                xmlwriter.WriteNamedValue("GlobalID", pinfo.ID);
                                if ((options & SaveOptions.Publish) != 0)
                                {
                                    xmlwriter.WriteNamedValue("GroupID", UUID.Zero);
                                    xmlwriter.WriteNamedValue("IsGroupOwned", false);
                                }
                                else
                                {
                                    xmlwriter.WriteNamedValue("GroupID", pinfo.Group.ID);
                                    xmlwriter.WriteNamedValue("IsGroupOwned", pinfo.GroupOwned);
                                }
                                xmlwriter.WriteNamedValue("Bitmap", Convert.ToBase64String(pinfo.LandBitmap.Data));
                                xmlwriter.WriteNamedValue("Description", pinfo.Description);
                                xmlwriter.WriteNamedValue("Flags", (uint)pinfo.Flags);
                                xmlwriter.WriteNamedValue("LandingType", (uint)pinfo.LandingType);
                                xmlwriter.WriteNamedValue("Name", pinfo.Name);
                                xmlwriter.WriteNamedValue("Status", (uint)pinfo.Status);
                                xmlwriter.WriteNamedValue("LocalID", pinfo.LocalID);
                                xmlwriter.WriteNamedValue("MediaAutoScale", pinfo.MediaAutoScale);
                                xmlwriter.WriteNamedValue("MediaID", pinfo.MediaID);
                                if (pinfo.MediaURI != null)
                                {
                                    xmlwriter.WriteNamedValue("MediaURL", pinfo.MediaURI.ToString());
                                }
                                else
                                {
                                    xmlwriter.WriteStartElement("MediaURL");
                                    xmlwriter.WriteEndElement();
                                }
                                if (pinfo.MusicURI != null)
                                {
                                    xmlwriter.WriteNamedValue("MusicURL", pinfo.MusicURI.ToString());
                                }
                                else
                                {
                                    xmlwriter.WriteStartElement("MusicURL");
                                    xmlwriter.WriteEndElement();
                                }
                                xmlwriter.WriteNamedValue("OwnerID", pinfo.Owner.ID);
                                xmlwriter.WriteStartElement("ParcelAccessList");
                                if ((options & SaveOptions.Publish) == 0)
                                {
                                    /* only serialize ParcelAccessEntry when not writing Publish OAR */
                                    foreach (ParcelAccessEntry pae in scene.Parcels.WhiteList[scene.ID, pinfo.ID])
                                    {
                                        xmlwriter.WriteStartElement("ParcelAccessEntry");
                                        xmlwriter.WriteNamedValue("AgentID", pae.Accessor.ID.ToString());
                                        xmlwriter.WriteNamedValue("AgentData", pae.Accessor.CreatorData);
                                        xmlwriter.WriteNamedValue("Time", pae.ExpiresAt.AsULong);
                                        xmlwriter.WriteNamedValue("AccessList", (int)OarAccessFlags.Access);
                                        xmlwriter.WriteEndElement();
                                    }
                                    foreach (ParcelAccessEntry pae in scene.Parcels.BlackList[scene.ID, pinfo.ID])
                                    {
                                        xmlwriter.WriteStartElement("ParcelAccessEntry");
                                        xmlwriter.WriteNamedValue("AgentID", pae.Accessor.ID.ToString());
                                        xmlwriter.WriteNamedValue("AgentData", pae.Accessor.CreatorData);
                                        xmlwriter.WriteNamedValue("Time", pae.ExpiresAt.AsULong);
                                        xmlwriter.WriteNamedValue("AccessList", (int)OarAccessFlags.Ban);
                                        xmlwriter.WriteEndElement();
                                    }
                                }
                                xmlwriter.WriteEndElement();
                                xmlwriter.WriteNamedValue("PassHours", pinfo.PassHours);
                                xmlwriter.WriteNamedValue("PassPrice", pinfo.PassPrice);
                                xmlwriter.WriteNamedValue("SalePrice", pinfo.SalePrice);
                                xmlwriter.WriteNamedValue("SnapshotID", pinfo.SnapshotID);
                                xmlwriter.WriteNamedValue("UserLocation", pinfo.LandingPosition.ToString());
                                xmlwriter.WriteNamedValue("UserLookAt", pinfo.LandingLookAt.ToString());
                                xmlwriter.WriteNamedValue("Dwell", pinfo.Dwell);
                                xmlwriter.WriteNamedValue("OtherCleanTime", pinfo.OtherCleanTime);
                            }
                            xmlwriter.WriteEndElement();
                            xmlwriter.Flush();

                            writer.WriteFile("landdata/" + pinfo.ID.ToString() + ".xml", ms.ToArray());
                        }
                    }
                }
                #endregion

                #region Storing object data
                if (console_io != null)
                {
                    console_io.Write("Storing object data...");
                }
                foreach (KeyValuePair <string, AssetData> kvp in objectAssets)
                {
                    writer.WriteFile("objects/" + kvp.Key, kvp.Value.Data);
                }
                #endregion

                #region Storing terrain
                if (console_io != null)
                {
                    console_io.Write("Saving terrain data...");
                }
                writer.WriteFile("terrains/" + scene.Name + ".r32", GenTerrainFile(scene.Terrain.AllPatches));
                #endregion
                writer.WriteEndOfTar();
            }
        }
예제 #14
0
        /// <summary>
        /// Archive the region requested.
        /// </summary>
        /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception>
        public void ArchiveRegion(Dictionary <string, object> options)
        {
            Dictionary <UUID, AssetType> assetUuids = new Dictionary <UUID, AssetType>();

            EntityBase[]            entities     = m_scene.GetEntities();
            List <SceneObjectGroup> sceneObjects = new List <SceneObjectGroup>();

            /*
             *  foreach (ILandObject lo in m_scene.LandChannel.AllParcels())
             *  {
             *      if (name == lo.LandData.Name)
             *      {
             *          // This is the parcel we want
             *      }
             *  }
             */

            // Filter entities so that we only have scene objects.
            // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
            // end up having to do this
            foreach (EntityBase entity in entities)
            {
                if (entity is SceneObjectGroup)
                {
                    SceneObjectGroup sceneObject = (SceneObjectGroup)entity;

                    if (!sceneObject.IsDeleted && !sceneObject.IsAttachment)
                    {
                        sceneObjects.Add((SceneObjectGroup)entity);
                    }
                }
            }

            UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService);

            foreach (SceneObjectGroup sceneObject in sceneObjects)
            {
                assetGatherer.GatherAssetUuids(sceneObject, assetUuids);
            }

            m_log.DebugFormat(
                "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
                sceneObjects.Count, assetUuids.Count);

            // Make sure that we also request terrain texture assets
            RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings;

            if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1)
            {
                assetUuids[regionSettings.TerrainTexture1] = AssetType.Texture;
            }

            if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2)
            {
                assetUuids[regionSettings.TerrainTexture2] = AssetType.Texture;
            }

            if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3)
            {
                assetUuids[regionSettings.TerrainTexture3] = AssetType.Texture;
            }

            if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4)
            {
                assetUuids[regionSettings.TerrainTexture4] = AssetType.Texture;
            }

            TarArchiveWriter archiveWriter = new TarArchiveWriter(m_saveStream);

            // Asynchronously request all the assets required to perform this archive operation
            ArchiveWriteRequestExecution awre
                = new ArchiveWriteRequestExecution(
                      sceneObjects,
                      m_scene.RequestModuleInterface <IVoxelModule>(),
                      m_scene.RequestModuleInterface <IRegionSerialiserModule>(),
                      m_scene,
                      archiveWriter,
                      m_requestId,
                      options);

            m_log.InfoFormat("[ARCHIVER]: Creating archive file.  This may take some time.");

            // Write out control file.  This has to be done first so that subsequent loaders will see this file first
            // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this
            archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, Create0p2ControlFile(options));
            m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");

            new AssetsRequest(
                new AssetsArchiver(archiveWriter), assetUuids,
                m_scene.AssetService, awre.ReceivedAllAssets).Execute();
        }
예제 #15
0
파일: Backup.cs 프로젝트: x8ball/Aurora-Sim
 private void WriteAsset(AssetBase asset, TarArchiveWriter writer)
 {
     writer.WriteFile("assets", asset.Data);
 }
예제 #16
0
        public void TestLoadIarV0p1TempProfiles()
        {
            Assert.Ignore();
            TestHelper.InMethod();
            Console.WriteLine("### Started {0} ###", MethodBase.GetCurrentMethod());

            log4net.Config.XmlConfigurator.Configure();

            string userFirstName  = "Dennis";
            string userLastName   = "Menace";
            UUID   userUuid       = UUID.Parse("00000000-0000-0000-0000-000000000aaa");
            string user2FirstName = "Walter";
            string user2LastName  = "Mitty";

            string itemName = "b.lsl";
            string archiveItemName
                = string.Format("{0}{1}{2}", itemName, "_", UUID.Random());

            MemoryStream     archiveWriteStream = new MemoryStream();
            TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);

            InventoryItemBase item1 = new InventoryItemBase();

            item1.Name      = itemName;
            item1.AssetID   = UUID.Random();
            item1.GroupID   = UUID.Random();
            item1.CreatorId = OspResolver.MakeOspa(user2FirstName, user2LastName);
            item1.Owner     = UUID.Zero;

            string item1FileName
                = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName);

            tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1));
            tar.Close();

            MemoryStream            archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
            SerialiserModule        serialiserModule  = new SerialiserModule();
            InventoryArchiverModule archiverModule    = new InventoryArchiverModule();

            // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene
            Scene             scene            = SceneSetupHelpers.SetupScene();
            IUserAdminService userAdminService = scene.CommsManager.UserAdminService;

            SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
            userAdminService.AddUser(
                userFirstName, userLastName, "meowfood", String.Empty, 1000, 1000, userUuid);

            archiverModule.DearchiveInventory(userFirstName, userLastName, "/", archiveReadStream);

            // Check that a suitable temporary user profile has been created.
            UserProfileData user2Profile
                = scene.CommsManager.UserService.GetUserProfile(
                      OspResolver.HashName(user2FirstName + " " + user2LastName));

            Assert.That(user2Profile, Is.Not.Null);
            Assert.That(user2Profile.FirstName == user2FirstName);
            Assert.That(user2Profile.SurName == user2LastName);

            CachedUserInfo userInfo
                = scene.CommsManager.UserProfileCacheService.GetUserDetails(userFirstName, userLastName);
            InventoryItemBase foundItem = userInfo.RootFolder.FindItemByPath(itemName);

            Assert.That(foundItem.CreatorId, Is.EqualTo(item1.CreatorId));
            Assert.That(
                foundItem.CreatorIdAsUuid, Is.EqualTo(OspResolver.HashName(user2FirstName + " " + user2LastName)));
            Assert.That(foundItem.Owner, Is.EqualTo(userUuid));

            Console.WriteLine("### Successfully completed {0} ###", MethodBase.GetCurrentMethod());
        }
예제 #17
0
        /// <summary>
        /// Archive the region requested.
        /// </summary>
        /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception>
        public void ArchiveRegion(Dictionary <string, object> options)
        {
            m_options = options;

            if (options.ContainsKey("all") && (bool)options["all"])
            {
                MultiRegionFormat = true;
            }

            if (options.ContainsKey("noassets") && (bool)options["noassets"])
            {
                SaveAssets = false;
            }

            if (options.TryGetValue("checkPermissions", out Object temp))
            {
                FilterContent = (string)temp;
            }


            // Find the regions to archive
            ArchiveScenesGroup scenesGroup = new ArchiveScenesGroup();

            if (MultiRegionFormat)
            {
                m_log.InfoFormat("[ARCHIVER]: Saving {0} regions", SceneManager.Instance.Scenes.Count);
                SceneManager.Instance.ForEachScene(delegate(Scene scene)
                {
                    scenesGroup.AddScene(scene);
                });
            }
            else
            {
                scenesGroup.AddScene(m_rootScene);
            }
            scenesGroup.CalcSceneLocations();

            m_archiveWriter = new TarArchiveWriter(m_saveStream);

            try
            {
                // Write out control file. It should be first so that it will be found ASAP when loading the file.
                m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(scenesGroup));
                m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");

                // Archive the regions

                Dictionary <UUID, sbyte> assetUuids           = new Dictionary <UUID, sbyte>();
                HashSet <UUID>           failedIDs            = new HashSet <UUID>();
                HashSet <UUID>           uncertainAssetsUUIDs = new HashSet <UUID>();

                scenesGroup.ForEachScene(delegate(Scene scene)
                {
                    string regionDir = MultiRegionFormat ? scenesGroup.GetRegionDir(scene.RegionInfo.RegionID) : "";
                    ArchiveOneRegion(scene, regionDir, assetUuids, failedIDs, uncertainAssetsUUIDs);
                });

                // Archive the assets

                if (SaveAssets)
                {
                    m_log.DebugFormat("[ARCHIVER]: Saving {0} assets", assetUuids.Count);

                    AssetsRequest ar = new AssetsRequest(
                        new AssetsArchiver(m_archiveWriter), assetUuids,
                        failedIDs.Count,
                        m_rootScene.AssetService, m_rootScene.UserAccountService,
                        m_rootScene.RegionInfo.ScopeID, options, null);
                    ar.Execute();
                    assetUuids = null;
                }
                else
                {
                    m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified");
//                    CloseArchive(string.Empty);
                }
                CloseArchive(string.Empty);
            }
            catch (Exception e)
            {
                CloseArchive(e.Message);
                throw;
            }

            GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.Default;
        }
        protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary <string, object> options, IUserAccountService userAccountService)
        {
            if (options.ContainsKey("exclude"))
            {
                if (((List <String>)options["exclude"]).Contains(inventoryItem.Name) ||
                    ((List <String>)options["exclude"]).Contains(inventoryItem.ID.ToString()))
                {
                    if (options.ContainsKey("verbose"))
                    {
                        m_log.InfoFormat(
                            "[INVENTORY ARCHIVER]: Skipping inventory item {0} {1} at {2}",
                            inventoryItem.Name, inventoryItem.ID, path);
                    }
                    return;
                }
            }

            if (options.ContainsKey("verbose"))
            {
                m_log.InfoFormat(
                    "[INVENTORY ARCHIVER]: Saving item {0} {1} (asset UUID {2})",
                    inventoryItem.ID, inventoryItem.Name, inventoryItem.AssetID);
            }

            string filename = path + CreateArchiveItemName(inventoryItem);

            // Record the creator of this item for user record purposes (which might go away soon)
            m_userUuids[inventoryItem.CreatorIdAsUuid] = 1;

            string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService);

            m_archiveWriter.WriteFile(filename, serialization);

            AssetType itemAssetType = (AssetType)inventoryItem.AssetType;

            // Don't chase down link asset items as they actually point to their target item IDs rather than an asset
            if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder)
            {
                int curErrorCntr = m_assetGatherer.ErrorCount;
                int possible     = m_assetGatherer.possibleNotAssetCount;
                m_assetGatherer.AddForInspection(inventoryItem.AssetID);
                m_assetGatherer.GatherAll();
                curErrorCntr = m_assetGatherer.ErrorCount - curErrorCntr;
                possible     = m_assetGatherer.possibleNotAssetCount - possible;

                if (curErrorCntr > 0 || possible > 0)
                {
                    string spath;
                    int    indx = path.IndexOf("__");
                    if (indx > 0)
                    {
                        spath = path.Substring(0, indx);
                    }
                    else
                    {
                        spath = path;
                    }

                    if (curErrorCntr > 0)
                    {
                        m_log.ErrorFormat("[INVENTORY ARCHIVER Warning]: item {0} '{1}', type {2}, in '{3}', contains {4} references to  missing or damaged assets",
                                          inventoryItem.ID, inventoryItem.Name, itemAssetType.ToString(), spath, curErrorCntr);
                        if (possible > 0)
                        {
                            m_log.WarnFormat("[INVENTORY ARCHIVER Warning]: item also contains {0} references that may be to missing or damaged assets or not a problem", possible);
                        }
                    }
                    else if (possible > 0)
                    {
                        m_log.WarnFormat("[INVENTORY ARCHIVER Warning]: item {0} '{1}', type {2}, in '{3}', contains {4} references that may be to missing or damaged assets or not a problem", inventoryItem.ID, inventoryItem.Name, itemAssetType.ToString(), spath, possible);
                    }
                }
            }
        }
예제 #19
0
        /// <summary>
        /// Archive the region requested.
        /// </summary>
        /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception>
        public void ArchiveRegion(Dictionary <string, object> options)
        {
            m_options = options;

            if (options.ContainsKey("all") && (bool)options["all"])
            {
                MultiRegionFormat = true;
            }

            if (options.ContainsKey("noassets") && (bool)options["noassets"])
            {
                SaveAssets = false;
            }

            Object temp;

            if (options.TryGetValue("checkPermissions", out temp))
            {
                CheckPermissions = (string)temp;
            }


            // Find the regions to archive
            ArchiveScenesGroup scenesGroup = new ArchiveScenesGroup();

            if (MultiRegionFormat)
            {
                m_log.InfoFormat("[ARCHIVER]: Saving {0} regions", SceneManager.Instance.Scenes.Count);
                SceneManager.Instance.ForEachScene(delegate(Scene scene)
                {
                    scenesGroup.AddScene(scene);
                });
            }
            else
            {
                scenesGroup.AddScene(m_rootScene);
            }
            scenesGroup.CalcSceneLocations();

            m_archiveWriter = new TarArchiveWriter(m_saveStream);

            try
            {
                // Write out control file. It should be first so that it will be found ASAP when loading the file.
                m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(scenesGroup));
                m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");

                // Archive the regions

                Dictionary <UUID, sbyte> assetUuids = new Dictionary <UUID, sbyte>();

                scenesGroup.ForEachScene(delegate(Scene scene)
                {
                    string regionDir = MultiRegionFormat ? scenesGroup.GetRegionDir(scene.RegionInfo.RegionID) : "";
                    ArchiveOneRegion(scene, regionDir, assetUuids);
                });

                // Archive the assets

                if (SaveAssets)
                {
                    m_log.DebugFormat("[ARCHIVER]: Saving {0} assets", assetUuids.Count);

                    // Asynchronously request all the assets required to perform this archive operation
                    AssetsRequest ar
                        = new AssetsRequest(
                              new AssetsArchiver(m_archiveWriter), assetUuids,
                              m_rootScene.AssetService, m_rootScene.UserAccountService,
                              m_rootScene.RegionInfo.ScopeID, options, ReceivedAllAssets);

                    Util.RunThreadNoTimeout(o => ar.Execute(), "AssetsRequest", null);

                    // CloseArchive() will be called from ReceivedAllAssets()
                }
                else
                {
                    m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified");
                    CloseArchive(string.Empty);
                }
            }
            catch (Exception e)
            {
                CloseArchive(e.Message);
                throw;
            }
        }
예제 #20
0
        /// <summary>
        ///   Save a backup of the sim
        /// </summary>
        /// <param name = "appendedFilePath">The file path where the backup will be saved</param>
        protected virtual void SaveBackup(string appendedFilePath, bool saveAssets)
        {
            if (appendedFilePath == "/")
            {
                appendedFilePath = "";
            }
            if (m_scene.RegionInfo.HasBeenDeleted)
            {
                return;
            }
            IBackupModule backupModule = m_scene.RequestModuleInterface <IBackupModule>();

            if (backupModule != null && backupModule.LoadingPrims) //Something is changing lots of prims
            {
                MainConsole.Instance.Info("[Backup]: Not saving backup because the backup module is loading prims");
                return;
            }

            //Save any script state saves that might be around
            IScriptModule[] engines = m_scene.RequestModuleInterfaces <IScriptModule>();
            try
            {
                if (engines != null)
                {
#if (!ISWIN)
                    foreach (IScriptModule engine in engines)
                    {
                        if (engine != null)
                        {
                            engine.SaveStateSaves();
                        }
                    }
#else
                    foreach (IScriptModule engine in engines.Where(engine => engine != null))
                    {
                        engine.SaveStateSaves();
                    }
#endif
                }
            }
            catch (Exception ex)
            {
                MainConsole.Instance.WarnFormat("[Backup]: Exception caught: {0}", ex);
            }

            MainConsole.Instance.Info("[FileBasedSimulationData]: Saving backup for region " + m_scene.RegionInfo.RegionName);
            string fileName = appendedFilePath + m_scene.RegionInfo.RegionName + m_saveAppendedFileName + ".abackup";
            if (File.Exists(fileName))
            {
                //Do new style saving here!
                GZipStream m_saveStream = new GZipStream(new FileStream(fileName + ".tmp", FileMode.Create),
                                                         CompressionMode.Compress);
                TarArchiveWriter writer       = new TarArchiveWriter(m_saveStream);
                GZipStream       m_loadStream = new GZipStream(new FileStream(fileName, FileMode.Open),
                                                               CompressionMode.Decompress);
                TarArchiveReader reader = new TarArchiveReader(m_loadStream);

                writer.WriteDir("parcels");

                IParcelManagementModule module = m_scene.RequestModuleInterface <IParcelManagementModule>();
                if (module != null)
                {
                    List <ILandObject> landObject = module.AllParcels();
                    foreach (ILandObject parcel in landObject)
                    {
                        OSDMap parcelMap = parcel.LandData.ToOSD();
                        var    binary    = OSDParser.SerializeLLSDBinary(parcelMap);
                        writer.WriteFile("parcels/" + parcel.LandData.GlobalID.ToString(),
                                         binary);
                        binary    = null;
                        parcelMap = null;
                    }
                }

                writer.WriteDir("newstyleterrain");
                writer.WriteDir("newstylerevertterrain");

                writer.WriteDir("newstylewater");
                writer.WriteDir("newstylerevertwater");

                ITerrainModule tModule = m_scene.RequestModuleInterface <ITerrainModule>();
                if (tModule != null)
                {
                    try
                    {
                        byte[] sdata = WriteTerrainToStream(tModule.TerrainMap);
                        writer.WriteFile("newstyleterrain/" + m_scene.RegionInfo.RegionID.ToString() + ".terrain", sdata);
                        sdata = null;

                        sdata = WriteTerrainToStream(tModule.TerrainRevertMap);
                        writer.WriteFile(
                            "newstylerevertterrain/" + m_scene.RegionInfo.RegionID.ToString() + ".terrain", sdata);
                        sdata = null;

                        if (tModule.TerrainWaterMap != null)
                        {
                            sdata = WriteTerrainToStream(tModule.TerrainWaterMap);
                            writer.WriteFile("newstylewater/" + m_scene.RegionInfo.RegionID.ToString() + ".terrain",
                                             sdata);
                            sdata = null;

                            sdata = WriteTerrainToStream(tModule.TerrainWaterRevertMap);
                            writer.WriteFile(
                                "newstylerevertwater/" + m_scene.RegionInfo.RegionID.ToString() + ".terrain", sdata);
                            sdata = null;
                        }
                    }
                    catch (Exception ex)
                    {
                        MainConsole.Instance.WarnFormat("[Backup]: Exception caught: {0}", ex);
                    }
                }

                IDictionary <UUID, AssetType> assets = new Dictionary <UUID, AssetType>();
                UuidGatherer assetGatherer           = new UuidGatherer(m_scene.AssetService);

                ISceneEntity[] saveentities   = m_scene.Entities.GetEntities();
                List <UUID>    entitiesToSave = new List <UUID>();
                foreach (ISceneEntity entity in saveentities)
                {
                    try
                    {
                        if (entity.IsAttachment ||
                            ((entity.RootChild.Flags & PrimFlags.Temporary) == PrimFlags.Temporary) ||
                            ((entity.RootChild.Flags & PrimFlags.TemporaryOnRez) == PrimFlags.TemporaryOnRez))
                        {
                            continue;
                        }
                        if (entity.HasGroupChanged)
                        {
                            entity.HasGroupChanged = false;
                            //Write all entities
                            byte[] xml = ((ISceneObject)entity).ToBinaryXml2();
                            writer.WriteFile("entities/" + entity.UUID.ToString(), xml);
                            xml = null;
                        }
                        else
                        {
                            entitiesToSave.Add(entity.UUID);
                        }
                        if (saveAssets)
                        {
                            assetGatherer.GatherAssetUuids(entity, assets, m_scene);
                        }
                    }
                    catch (Exception ex)
                    {
                        MainConsole.Instance.WarnFormat("[Backup]: Exception caught: {0}", ex);
                        entitiesToSave.Add(entity.UUID);
                    }
                }


                byte[] data;
                string filePath;
                TarArchiveReader.TarEntryType entryType;
                //Load the archive data that we need
                try
                {
                    while ((data = reader.ReadEntry(out filePath, out entryType)) != null)
                    {
                        if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType)
                        {
                            continue;
                        }
                        if (filePath.StartsWith("entities/"))
                        {
                            UUID entityID = UUID.Parse(filePath.Remove(0, 9));
                            if (entitiesToSave.Contains(entityID))
                            {
                                writer.WriteFile(filePath, data);
                                entitiesToSave.Remove(entityID);
                            }
                        }
                        data = null;
                    }
                }
                catch (Exception ex)
                {
                    MainConsole.Instance.WarnFormat("[Backup]: Exception caught: {0}", ex);
                }

                if (entitiesToSave.Count > 0)
                {
                    MainConsole.Instance.Fatal(entitiesToSave.Count + " PRIMS WERE NOT GOING TO BE SAVED! FORCE SAVING NOW! ");
                    foreach (ISceneEntity entity in saveentities)
                    {
                        if (entitiesToSave.Contains(entity.UUID))
                        {
                            if (entity.IsAttachment ||
                                ((entity.RootChild.Flags & PrimFlags.Temporary) == PrimFlags.Temporary) ||
                                ((entity.RootChild.Flags & PrimFlags.TemporaryOnRez) == PrimFlags.TemporaryOnRez))
                            {
                                continue;
                            }
                            //Write all entities
                            byte[] xml = ((ISceneObject)entity).ToBinaryXml2();
                            writer.WriteFile("entities/" + entity.UUID.ToString(), xml);
                            xml = null;
                        }
                    }
                }

                if (saveAssets)
                {
                    foreach (UUID assetID in new List <UUID>(assets.Keys))
                    {
                        try
                        {
                            WriteAsset(assetID.ToString(), m_scene.AssetService.Get(assetID.ToString()), writer);
                        }
                        catch (Exception ex)
                        {
                            MainConsole.Instance.WarnFormat("[Backup]: Exception caught: {0}", ex);
                        }
                    }
                }

                reader.Close();
                writer.Close();
                m_loadStream.Close();
                m_saveStream.Close();
                GC.Collect();

                if (m_keepOldSave && !m_oldSaveHasBeenSaved)
                {
                    //Havn't moved it yet, so make sure the directory exists, then move it
                    m_oldSaveHasBeenSaved = true;
                    if (!Directory.Exists(m_oldSaveDirectory))
                    {
                        Directory.CreateDirectory(m_oldSaveDirectory);
                    }
                    File.Copy(fileName + ".tmp",
                              Path.Combine(m_oldSaveDirectory,
                                           m_scene.RegionInfo.RegionName + SerializeDateTime() + m_saveAppendedFileName +
                                           ".abackup"));
                }
                //Just remove the file
                File.Delete(fileName);
            }
            else
            {
                //Add the .temp since we might need to make a backup and so that if something goes wrong, we don't corrupt the main backup
                GZipStream m_saveStream = new GZipStream(new FileStream(fileName + ".tmp", FileMode.Create),
                                                         CompressionMode.Compress);
                TarArchiveWriter      writer   = new TarArchiveWriter(m_saveStream);
                IAuroraBackupArchiver archiver = m_scene.RequestModuleInterface <IAuroraBackupArchiver>();

                //Turn off prompting so that we don't ask the user questions every time we need to save the backup
                archiver.AllowPrompting = false;
                archiver.SaveRegionBackup(writer, m_scene);
                archiver.AllowPrompting = true;

                m_saveStream.Close();
                writer.Close();
                GC.Collect();
            }
            File.Move(fileName + ".tmp", fileName);
            ISceneEntity[] entities = m_scene.Entities.GetEntities();
            try
            {
#if (!ISWIN)
                foreach (ISceneEntity entity in entities)
                {
                    if (entity.HasGroupChanged)
                    {
                        entity.HasGroupChanged = false;
                    }
                }
#else
                foreach (ISceneEntity entity in entities.Where(entity => entity.HasGroupChanged))
                {
                    entity.HasGroupChanged = false;
                }
#endif
            }
            catch (Exception ex)
            {
                MainConsole.Instance.WarnFormat("[Backup]: Exception caught: {0}", ex);
            }
            //Now make it the full file again
            MapTileNeedsGenerated = true;
            MainConsole.Instance.Info("[FileBasedSimulationData]: Saved Backup for region " + m_scene.RegionInfo.RegionName);
        }