Exemple #1
0
        public static void Save(bool message = true, bool permitBackgroundWrite = false)
        {
            if (Saving)
            {
                return;
            }

            GameServer.Instance.Clients.Each(c => c.Flush());

            WaitForWriteCompletion();             // Blocks Save until current disk flush is done.

            Saving = true;

            m_DiskWriteHandle.Reset();

            if (message)
            {
                Broadcast(0x35, true, "The world is saving, please wait.");
            }

            log.Info("Save started");

            var strategy = SaveStrategy.Acquire();

            log.Info("Using {0} save strategy", strategy.Name.ToLowerInvariant());

            var watch = Stopwatch.StartNew();

            try
            {
                EventSink.InvokeWorldBeforeSave();
            }
            catch (Exception e)
            {
                throw new Exception("World Before Save event threw an exception. Save failed!", e);
            }

            if (!Directory.Exists(MobileBasePath))
            {
                Directory.CreateDirectory(MobileBasePath);
            }
            if (!Directory.Exists(ItemBasePath))
            {
                Directory.CreateDirectory(ItemBasePath);
            }
            if (!Directory.Exists(GuildBasePath))
            {
                Directory.CreateDirectory(GuildBasePath);
            }

            strategy.Save(permitBackgroundWrite);

            log.Info("Entities saved in {0:F2} seconds.", watch.Elapsed.TotalSeconds);

            try
            {
                EventSink.InvokeWorldSave(new WorldSaveEventArgs(message));
            }
            catch (Exception e)
            {
                throw new Exception("World Save event threw an exception. Save failed!", e);
            }

            if (ManualGC)
            {
                GC.Collect();
            }

            watch.Stop();

            Saving = false;

            if (!permitBackgroundWrite)
            {
                NotifyDiskWriteComplete();                 // Sets the DiskWriteHandle. If we allow background writes, we leave this upto the individual save strategies.
            }
            ProcessSafetyQueues();

            strategy.OnFinished();

            log.Info("Save done in {0:F2} seconds.", watch.Elapsed.TotalSeconds);

            if (message)
            {
                Broadcast(0x35, true, "World save complete. The entire process took {0:F2} seconds.", watch.Elapsed.TotalSeconds);
            }
        }