/// <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);
        }
Exemple #2
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.ToString(),
                                         OSDParser.SerializeLLSDBinary(parcelMap));
                        parcelMap = null;
                    }
                }

                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.ToString() + ".terrain", sdata);
                        sdata = null;

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

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

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

                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);
                IAuroraBackupArchiver archiver       = m_scene.RequestModuleInterface <IAuroraBackupArchiver>();
                bool saveAssets = false;

                if (archiver.AllowPrompting)
                {
                    saveAssets =
                        MainConsole.Instance.Prompt("Save assets? (Will not be able to load on other grids)", "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.ToString(), 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");
            }