public bool SaveBackup(string file, RegionData regiondata)
 {
     FileStream stream = null;
     try
     {
         stream = File.OpenWrite(file);
         ProtoBuf.Serializer.Serialize<RegionData>(stream, regiondata);
     }
     catch (Exception ex)
     {
         MainConsole.Instance.Warn("[ProtobufRegionLoader]: Failed to save backup: " + ex.ToString());
         return false;
     }
     finally
     {
         if (stream != null && stream.CanWrite)
             stream.Close();
     }
     return true;
 }
        protected virtual void ReadBackup(string fileName)
        {
            m_fileName = fileName;
            string simName = Path.GetFileName(fileName);
            MainConsole.Instance.Info("[FileBasedSimulationData]: Restoring sim backup for region " + simName + "...");

            _regionData = _regionLoader.LoadBackup(BuildSaveFileName());
            if (_regionData == null)
                _regionData = _oldRegionLoader.LoadBackup(Path.ChangeExtension(BuildSaveFileName(),
                    _oldRegionLoader.FileType));
            if (_regionData == null)
            {
                _regionData = new RegionData();
                _regionData.Init();
            }
            else
            {
                //Make sure the region port is set
                if (_regionData.RegionInfo.RegionPort == 0)
                {
                    _regionData.RegionInfo.RegionPort = int.Parse(MainConsole.Instance.Prompt("Region Port: ",
                        (9000).ToString()));
                }
            }
            GC.Collect();
        }
        /// <summary>
        ///     Save a backup of the sim
        /// </summary>
        /// <param name="isOldSave"></param>
        protected virtual void SaveBackup(bool isOldSave)
        {
            if (m_scene == null || 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)
                {
                    foreach (IScriptModule engine in engines.Where(engine => engine != null))
                    {
                        engine.SaveStateSaves();
                    }
                }
            }
            catch (Exception ex)
            {
                MainConsole.Instance.WarnFormat("[Backup]: Exception caught: {0}", ex);
            }

            MainConsole.Instance.Info("[FileBasedSimulationData]: Saving backup for region " +
                                      m_scene.RegionInfo.RegionName);

            RegionData regiondata = new RegionData();
            regiondata.Init();

            regiondata.RegionInfo = m_scene.RegionInfo;
            IParcelManagementModule module = m_scene.RequestModuleInterface<IParcelManagementModule>();
            if (module != null)
            {
                List<ILandObject> landObject = module.AllParcels();
                foreach (ILandObject parcel in landObject)
                    regiondata.Parcels.Add(parcel.LandData);
            }

            ITerrainModule tModule = m_scene.RequestModuleInterface<ITerrainModule>();
            if (tModule != null)
            {
                try
                {
                    regiondata.Terrain = WriteTerrainToStream(tModule.TerrainMap);
                    regiondata.RevertTerrain = WriteTerrainToStream(tModule.TerrainRevertMap);

                    if (tModule.TerrainWaterMap != null)
                    {
                        regiondata.Water = WriteTerrainToStream(tModule.TerrainWaterMap);
                        regiondata.RevertWater = WriteTerrainToStream(tModule.TerrainWaterRevertMap);
                    }
                }
                catch (Exception ex)
                {
                    MainConsole.Instance.WarnFormat("[Backup]: Exception caught: {0}", ex);
                }
            }

            ISceneEntity[] entities = m_scene.Entities.GetEntities();
            regiondata.Groups = new List<SceneObjectGroup>(
                entities.Cast<SceneObjectGroup>().Where(
                    (entity) => {return !( entity.IsAttachment ||
                        ((entity.RootChild.Flags & PrimFlags.Temporary) == PrimFlags.Temporary) ||
                        ((entity.RootChild.Flags & PrimFlags.TemporaryOnRez) == PrimFlags.TemporaryOnRez));
                }));
            try
            {
                foreach (ISceneEntity entity in regiondata.Groups.Where(ent => ent.HasGroupChanged))
                    entity.HasGroupChanged = false;
            }
            catch (Exception ex)
            {
                MainConsole.Instance.WarnFormat("[Backup]: Exception caught: {0}", ex);
            }
            string filename = isOldSave ? BuildOldSaveFileName() : BuildSaveFileName();

            if (File.Exists(filename + (isOldSave ? "" : ".tmp")))
                File.Delete(filename + (isOldSave ? "" : ".tmp")); //Remove old tmp files
            if (!_regionLoader.SaveBackup(filename + (isOldSave ? "" : ".tmp"), regiondata))
            {
                if (File.Exists(filename + (isOldSave ? "" : ".tmp")))
                    File.Delete(filename + (isOldSave ? "" : ".tmp")); //Remove old tmp files
                MainConsole.Instance.Error("[FileBasedSimulationData]: Failed to save backup for region " +
                                           m_scene.RegionInfo.RegionName + "!");
                return;
            }

            //RegionData data = _regionLoader.LoadBackup(filename + ".tmp");
            if (!isOldSave)
            {
                if (File.Exists(filename))
                    File.Delete(filename);
                File.Move(filename + ".tmp", filename);

                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, BuildOldSaveFileName());
                }
            }
            regiondata.Dispose();
            //Now make it the full file again
            MapTileNeedsGenerated = true;
            MainConsole.Instance.Info("[FileBasedSimulationData]: Saved Backup for region " +
                                      m_scene.RegionInfo.RegionName);
        }
        /// <summary>
        /// Initializes a new region using the passed regioninfo
        /// </summary>
        /// <returns></returns>
        /// <param name="simBase">Sim base.</param>
        /// <param name="regionInfo">Region info.</param>
        /// <param name="currentInfo">Current region info.</param>
        public virtual RegionInfo CreateNewRegion(ISimulationBase simBase, RegionInfo regionInfo, Dictionary<string, int> currentInfo)
        {
            ReadConfig(simBase);
            _regionData = new RegionData();
            _regionData.Init();

            // something wrong here, prompt for details
            if (regionInfo == null)
                return CreateNewRegion(simBase, currentInfo );

            m_fileName = regionInfo.RegionName;

            if (m_scene != null)
            {
                IGridRegisterModule gridRegister = m_scene.RequestModuleInterface<IGridRegisterModule>();
                //Re-register so that if the position has changed, we get the new neighbors
                gridRegister.RegisterRegionWithGrid(m_scene, true, false, null);

                ForceBackup();

                MainConsole.Instance.Info("[FileBasedSimulationData]: Save completed.");
            }

            return regionInfo;
        }
        public virtual RegionInfo LoadRegionNameInfo(string regionName, ISimulationBase simBase)
        {
            ReadConfig(simBase);
            _regionData = new RegionData();
            _regionData.Init();

            string regionFile = m_storeDirectory + regionName + ".sim";
            if (File.Exists(regionFile))
            {
                regionFile = Path.GetFileNameWithoutExtension (regionFile);
                ReadBackup (regionFile);
                m_fileName = regionFile;
            }

            return _regionData.RegionInfo;
        }
        public virtual RegionInfo CreateNewRegion(ISimulationBase simBase, string regionName, Dictionary<string, int> currentInfo)
        {
            ReadConfig(simBase);
            _regionData = new RegionData();
            _regionData.Init();
            RegionInfo info = new RegionInfo();
            info.RegionName = regionName;
            info.NewRegion = true;

            info = CreateRegionFromConsole(info, true, currentInfo);
            if (info == null)
                return CreateNewRegion(simBase, info, currentInfo);

            m_fileName = info.RegionName;
            return info;
        }
 public virtual void CacheDispose()
 {
     _regionData.Dispose();
     _regionData = null;
 }
 public virtual RegionInfo CreateNewRegion(ISimulationBase simBase)
 {
     ReadConfig(simBase);
     _regionData = new RegionData();
     _regionData.Init();
     RegionInfo info = CreateRegionFromConsole(null);
     if (info == null)
         return CreateNewRegion(simBase);
     m_fileName = info.RegionName;
     return info;
 }
        public RegionData LoadBackup(string file)
        {
            if (!File.Exists(file))
                return null;

            var stream = ArchiveHelpers.GetStream(file);
            if (stream == null)
                return null;

            MainConsole.Instance.Warn("[TarRegionDataLoader]: loading region data: " + file);

            GZipStream m_loadStream = new GZipStream(stream, CompressionMode.Decompress);
            TarArchiveReader reader = new TarArchiveReader(m_loadStream);
            List<uint> foundLocalIDs = new List<uint>();
            RegionData regiondata = new RegionData();
            regiondata.Init();

            byte[] data;
            string filePath;
            TarArchiveReader.TarEntryType entryType;
            System.Collections.Concurrent.ConcurrentQueue<byte[]> groups =
                new System.Collections.Concurrent.ConcurrentQueue<byte[]>();
            //Load the archive data that we need
            while ((data = reader.ReadEntry(out filePath, out entryType)) != null)
            {
                MainConsole.Instance.Warn(".");
               	if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType)
                    continue;

                if (filePath.StartsWith("parcels/"))
                {
                    //Only use if we are not merging
                    LandData parcel = new LandData();
                    OSD parcelData = OSDParser.DeserializeLLSDBinary(data);
                    parcel.FromOSD((OSDMap) parcelData);
                    if (parcel.OwnerID != UUID.Parse("05948863-b678-433e-87a4-e44d17678d1d"))
                        //The default owner of the 'default' region
                        regiondata.Parcels.Add(parcel);
                }
                else if (filePath.StartsWith("newstyleterrain/"))
                {
                    regiondata.Terrain = data;
                }
                else if (filePath.StartsWith("newstylerevertterrain/"))
                {
                    regiondata.RevertTerrain = data;
                }
                else if (filePath.StartsWith("newstylewater/"))
                {
                    regiondata.Water = data;
                }
                else if (filePath.StartsWith("newstylerevertwater/"))
                {
                    regiondata.RevertWater = data;
                }
                else if (filePath.StartsWith("entities/"))
                {
                    groups.Enqueue(data);
                }
                else if (filePath.StartsWith("regioninfo/"))
                {
                    RegionInfo info = new RegionInfo();
                    info.FromOSD((OSDMap) OSDParser.DeserializeLLSDBinary(data));
                    regiondata.RegionInfo = info;
                }
                data = null;
            }
            m_loadStream.Close();
            m_loadStream = null;

            int threadCount = groups.Count > 16 ? 16 : groups.Count;
            System.Threading.Thread[] threads = new System.Threading.Thread[threadCount];
            for (int i = 0; i < threadCount; i++)
            {
                threads[i] = new System.Threading.Thread(() =>
                                                             {
                                                                 byte[] groupData;
                                                                 while (groups.TryDequeue(out groupData))
                                                                 {
                                                                     MemoryStream ms = new MemoryStream(groupData);
                                                                     ISceneEntity sceneObject =
                                                                         SceneEntitySerializer.SceneObjectSerializer
                                                                                              .FromXml2Format(ref ms,
                                                                                                              null);
                                                                     ms.Close();
                                                                     ms = null;
                                                                     data = null;
                                                                     if (sceneObject != null)
                                                                     {
                                                                         foreach (
                                                                             ISceneChildEntity part in
                                                                                 sceneObject.ChildrenEntities())
                                                                         {
                                                                             lock (foundLocalIDs)
                                                                             {
                                                                                 if (
                                                                                     !foundLocalIDs.Contains(
                                                                                         part.LocalId))
                                                                                     foundLocalIDs.Add(part.LocalId);
                                                                                 else
                                                                                     part.LocalId = 0;
                                                                                         //Reset it! Only use it once!
                                                                             }
                                                                         }
                                                                         regiondata.Groups.Add(
                                                                             sceneObject as SceneObjectGroup);
                                                                     }
                                                                 }
                                                             });
                threads[i].Start();
            }
            for (int i = 0; i < threadCount; i++)
                threads[i].Join();

            foundLocalIDs.Clear();

            MainConsole.Instance.Warn("[TarRegionDataLoader]: completed: ");

            return regiondata;
        }
        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("[TarRegionDataLoader]: Failed to save backup: " + ex.ToString());
                return false;
            }
            return true;
        }