/// <summary> /// Saves the game to disk in the background. /// </summary> /// <param name="data">The uncompressed save data.</param> private void DoSave(BackgroundSaveData data) { byte[] buffer; try { var stream = data.Stream; long len = stream.Length; // Uh oh if (len >= int.MaxValue) { PUtil.LogError("Save file is too big, game will not save correctly!"); } else { PUtil.LogDebug("Background save to: " + data.FileName); } if (data.Compress) { buffer = SaveLoader.CompressContents(stream.GetBuffer(), (int)len); } else { buffer = stream.ToArray(); } CleanAutosaves(data.FileName); // Write the file header using (var writer = new BinaryWriter(File.Open(data.FileName, FileMode.Create))) { var saveHeader = SaveGame.Instance.GetSaveHeader(true, data.Compress, out SaveGame.Header header); writer.Write(header.buildVersion); writer.Write(header.headerSize); writer.Write(header.headerVersion); writer.Write(header.compression); writer.Write(saveHeader); KSerialization.Manager.SerializeDirectory(writer); writer.Write(buffer); writer.Flush(); } buffer = null; status = SaveStatus.Done; PUtil.LogDebug("Background save complete"); } catch (IOException e) { // Autosave error! PUtil.LogExcWarn(e); status = SaveStatus.IOError; } catch (Exception e) { // Allowing it to continue here will crash with a simdll error PUtil.LogException(e); status = SaveStatus.Failed; } finally { try { // Cannot throw during a finally, or it will discard the original exception data.Dispose(); } catch (Exception e) { PUtil.LogException(e); } } }