Beispiel #1
0
        //internal override void SaveData(BinaryWriter writer)
        //{
        //    foreach (Rec r in this.Records)
        //    {
        //        r.SaveData(writer);
        //    }
        //}

        internal override void SaveData(SnipStreamWrapper snipStreamWrapper)
        {
            foreach (Rec r in this.Records)
            {
                r.SaveData(snipStreamWrapper);
            }
        }
Beispiel #2
0
        //internal override void SaveData(BinaryWriter writer)
        //{
        //    long startpos = writer.BaseStream.Position;
        //    var svSize = (uint)this.Size;
        //    var svSize2 = (uint)this.Size2;
        //    WriteString(writer, "GRUP");
        //    writer.Write(svSize); // Write uncompressed size for now
        //    writer.Write(this.data);
        //    writer.Write(this.groupType);
        //    writer.Write(this.dateStamp);
        //    writer.Write(this.flags); // should this check for oblivion?
        //    foreach (Rec r in this.Records)
        //    {
        //        r.SaveData(writer);
        //    }

        //    writer.Flush();
        //    long curpos = writer.BaseStream.Position;
        //    var wrSize = (uint)(curpos - startpos);
        //    if (wrSize != svSize2)
        //    {
        //        // fix size due to compression
        //        writer.BaseStream.Position = startpos + 4;
        //        writer.Write(wrSize); // Write the actuall compressed group size
        //        writer.BaseStream.Position = curpos;
        //    }
        //}

        internal override void SaveData(SnipStreamWrapper snipStreamWrapper)
        {
            long startpos = snipStreamWrapper.SnipStream.Position; //writer.BaseStream.Position;
            var  svSize   = (uint)this.Size;
            var  svSize2  = (uint)this.Size2;

            //if (this.Name == "????")
            //    snipStreamWrapper.WriteString("????"); //WriteString(writer, "GRUP");
            //else
            snipStreamWrapper.WriteStringInFileStream("GRUP");        //WriteString(writer, "GRUP");
            snipStreamWrapper.WriteUInt32(svSize);                    //writer.Write(svSize); // Write uncompressed size for now
            snipStreamWrapper.WriteBytesArrayInFileStream(this.data); //writer.Write(this.data);
            snipStreamWrapper.WriteUInt32(this.groupType);            //writer.Write(this.groupType);
            snipStreamWrapper.WriteUInt32(this.dateStamp);            //writer.Write(this.dateStamp);
            snipStreamWrapper.WriteUInt32(this.flags);                //writer.Write(this.flags); // should this check for oblivion?

            foreach (Rec r in this.Records)
            {
                r.SaveData(snipStreamWrapper);  //r.SaveData(writer);
            }

            //if (this.Name == "????")
            //    this.Name = "????";

            //writer.Flush();
            long curpos = snipStreamWrapper.SnipStream.Position;  //long curpos = writer.BaseStream.Position;
            var  wrSize = (uint)(curpos - startpos);

            if (wrSize != svSize2)
            {
                // fix size due to compression
                snipStreamWrapper.SnipStream.Seek(startpos + 4, SeekOrigin.Begin);
                //snipStreamWrapper.SnipStream.Position = startpos + 4; //writer.BaseStream.Position = startpos + 4;
                snipStreamWrapper.WriteUInt32(wrSize); //writer.Write(wrSize); // Write the actuall compressed group size
                //snipStreamWrapper.SnipStream.Position = curpos; //writer.BaseStream.Position = curpos;
                snipStreamWrapper.SnipStream.Seek(curpos, SeekOrigin.Begin);
            }
        }
Beispiel #3
0
        //internal override void SaveData(BinaryWriter writer)
        //{
        //    throw new NotImplementedException();
        //}

        internal override void SaveData(SnipStreamWrapper snipStreamWrapper)
        {
            throw new NotImplementedException();
        }
Beispiel #4
0
 //internal abstract void SaveData(BinaryWriter writer);
 internal abstract void SaveData(SnipStreamWrapper snipStreamWrapper);
Beispiel #5
0
        //internal GroupRecord(uint Size, BinaryReader br, bool Oblivion, string[] recFilter, bool filterAll)
        internal GroupRecord(uint Size, SnipStreamWrapper snipStreamWrapper, bool Oblivion, string[] recFilter, bool filterAll)
        {
            Name = "GRUP";
            //if (snipStreamWrapper.SnipStream.Position == 52776119 ) //>= 52776111)
            //    Name = "????";
            this.data      = snipStreamWrapper.ReadBytes(4); //br.ReadBytes(4);
            this.groupType = snipStreamWrapper.ReadUInt32(); //br.ReadUInt32();
            this.dateStamp = snipStreamWrapper.ReadUInt32(); //br.ReadUInt32();
            string contentType = this.groupType == 0 ? Encoding.Instance.GetString(this.data) : string.Empty;

            if (!Oblivion)
            {
                this.flags = snipStreamWrapper.ReadUInt32(); //br.ReadUInt32();
            }

            uint amountRead = 0;

            while (amountRead < Size - (Oblivion ? 20 : 24))
            {
                string s       = ReadRecName(snipStreamWrapper.ReadBytes(4)); //s = ReadRecName(br);
                uint   recsize = snipStreamWrapper.ReadUInt32();              //br.ReadUInt32();
                if (s == "GRUP")
                {
                    try
                    {
                        bool skip = filterAll || (recFilter != null && Array.IndexOf(recFilter, contentType) >= 0);
                        //var gr = new GroupRecord(recsize, br, Oblivion, recFilter, skip);
                        var gr = new GroupRecord(recsize, snipStreamWrapper, Oblivion, recFilter, skip);
                        if (!filterAll)
                        {
                            this.AddRecord(gr);
                        }
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show(e.Message);
                    }
                    finally
                    {
                        amountRead += recsize;
                    }
                }
                else
                {
                    bool skip = filterAll || (recFilter != null && Array.IndexOf(recFilter, s) >= 0);
                    if (skip)
                    {
                        long size = recsize + (Oblivion ? 12 : 16);

                        // if ((br.ReadUInt32() & 0x00040000) > 0) size += 4;
                        snipStreamWrapper.SnipStream.Seek(size, SeekOrigin.Current); //br.BaseStream.Position += size; // just read past the data
                        amountRead += (uint)(recsize + (Oblivion ? 20 : 24));
                    }
                    else
                    {
                        try
                        {
                            var r = new Record(s, recsize, snipStreamWrapper, Oblivion); //var r = new Record(s, recsize, br, Oblivion);
                            this.AddRecord(r);
                        }
                        catch (Exception e)
                        {
                            MessageBox.Show(e.Message);
                        }
                        finally
                        {
                            amountRead += (uint)(recsize + (Oblivion ? 20 : 24));
                        }
                    }
                }
            }

            this.UpdateShortDescription();
            if (amountRead != (Size - (Oblivion ? 20 : 24)))
            {
                throw new TESParserException(
                          string.Format("Record block did not match the size specified in the group header! Header Size={0:D} Group Size={1:D}", Size - (Oblivion ? 20 : 24), amountRead));
            }
        }
Beispiel #6
0
        //internal override void SaveData(BinaryWriter writer)
        internal override void SaveData(SnipStreamWrapper snipStreamWrapper)
        {
            bool hasRecordUnknown = false;
            //var position = writer.BaseStream.Position;
            var position = snipStreamWrapper.SnipStream.Position;

            //WriteString(writer, Name);
            snipStreamWrapper.WriteStringInFileStream(Name);

            var compressed = false;

            byte[] data;
            //using (var stream = new MemoryStream())
            //{

            //var dataWriter = new BinaryWriter(stream);
            snipStreamWrapper.ResetBufferSizeAndPosition();

            if (this.FormID == 496431)
            {
                compressed = false;
            }

            foreach (var subRecord in this.SubRecords)
            {
                //subRecord.SaveData(dataWriter);
                if (subRecord.Name == "????")
                {
                    hasRecordUnknown = true;
                }
                subRecord.SaveData(snipStreamWrapper); //write data into buffer
            }

            uint realSize = snipStreamWrapper.OutputBufferLength;

            if (hasRecordUnknown)
            {
                realSize = 0;
            }

            //data = stream.ToArray();  //data = stream.ToArray();

            if (Properties.Settings.Default.UseDefaultRecordCompression)
            {
                compressed = ((this.Flags1 & 0x00040000) != 0) ||
                             (Properties.Settings.Default.EnableAutoCompress && Compressor.CompressRecord(Name))
                             ||
                             (Properties.Settings.Default.EnableCompressionLimit &&
                              (realSize >= Properties.Settings.Default.CompressionLimit));

                //if (compressed)
                //    data = ZLib.Compress(stream, CompressLevel.Best); //data = ZLib.Compress(data);
            }

            // ajouter dans zlib un option pour dire oui compresser ou dans le record une variable pour dire que c'est compressé
            if (Properties.Settings.Default.UsePluginRecordCompression)
            {
                compressed = (this.Flags1 & 0x00040000) != 0;
            }

            if (compressed & compressLevel != CompressLevel.None)
            {
                ZLib.Compress(snipStreamWrapper, compressLevel);
                data = new byte[ZLibWrapper.OutputBufferLength];
                ZLibWrapper.CopyOutputBufferIntoByteArray(data);
            }
            else
            {
                data = new byte[snipStreamWrapper.OutputBufferLength];
                if (snipStreamWrapper.OutputBufferLength > 0)
                {
                    snipStreamWrapper.CopyOutputBufferToData(ref data);
                }
                //data = stream.ToArray();  //data = stream.ToArray();
            }

            //} // using (var stream = new MemoryStream())

            var dataSize = (uint)data.Length;
            var flags    = this.Flags1 & ~0x00040000U;

            if (compressed)
            {
                dataSize += 4;
                flags    |= 0x00040000;

                Debug.WriteLineIf(
                    this.dataSize != dataSize,
                    string.Format("COMPRESSED RECORD [NAME={0} AT POSITION={1}] SIZE DIFFERS FROM ORIGINAL: ORIGINAL={2} ACTUAL={3}, RAW RECORD SIZE={4}",
                                  Name, position, this.dataSize, dataSize, realSize));
            }

            snipStreamWrapper.WriteUInt32(dataSize); //writer.Write(dataSize); // Size of compressed section + length
            snipStreamWrapper.WriteUInt32(flags);    //writer.Write(flags);
            snipStreamWrapper.WriteUInt32(FormID);   //writer.Write(this.FormID);
            snipStreamWrapper.WriteUInt32(Flags2);   //writer.Write(this.Flags2);
            snipStreamWrapper.WriteUInt32(Flags3);   //writer.Write(this.Flags3);
            if (compressed)
            {
                snipStreamWrapper.WriteUInt32(realSize);  //writer.Write(realSize);
            }
            if (dataSize > 0)
            {
                snipStreamWrapper.WriteBytesArrayInFileStream(data); //writer.Write(data, 0, data.Length);
            }
        }
Beispiel #7
0
        internal Record(string name, uint dataSizeParam, SnipStreamWrapper snipStreamWrapper, bool oblivion)  //internal Record(string name, uint dataSize, BinaryReader recordReader, bool oblivion)
        {
            bool compressed = false;
            uint amountRead = 0;
            uint realSize   = 0;

            //MemoryStream stream = null;
            //BinaryReader dataReader = null;
            SubRecord record = null;

            //long ws;

            try
            {
                this.dataSize = dataSizeParam;

                this.SubRecords = new AdvancedList <SubRecord>(1)
                {
                    AllowSorting = false
                };

                //if (snipStreamWrapper.SnipStream.Position >= 1330432)
                //    Name = name;

                Name = name;
                RecordsTace.AddRecordToRecordsList(Name);
                this.Flags1 = snipStreamWrapper.ReadUInt32(); //recordReader.ReadUInt32();
                this.FormID = snipStreamWrapper.ReadUInt32(); //recordReader.ReadUInt32();
                this.Flags2 = snipStreamWrapper.ReadUInt32(); //recordReader.ReadUInt32();
                if (!oblivion)
                {
                    this.Flags3 = snipStreamWrapper.ReadUInt32(); //recordReader.ReadUInt32();
                }

                //if (this.FormID == 496431)
                //    Name = name;

                compressed = (this.Flags1 & 0x00040000) != 0;
                amountRead = 0;
                realSize   = dataSizeParam;

                if (!compressed)
                {
                    realSize = dataSizeParam;
                }

                if (compressed)
                {
                    realSize = snipStreamWrapper.ReadUInt32(); // recordReader.ReadUInt32();
                    // snipStreamWrapper.JumpTo(-4,SeekOrigin.Current);
                    //if (realSize > 0)
                    dataSizeParam -= 4;
                    RecordsTace.AddRecordToCompressedRecordsList(Name);
                }

#if DEBUGCOMPRESSREALSIZE
                if (compressed & realSize == 0)
                {
                    Clipboard.SetText(name + " - " + this.FormID.ToString(CultureInfo.InvariantCulture));
                }
#endif

                //using (var stream = new MemoryStream(recordReader.ReadBytes((int) dataSize)))
                //{
                //using (var dataReader = compressed ? ZLib.Decompress(stream, (int) realSize) : new BinaryReader(stream))
                //{.
                try
                {
                    //if (dataSize == 0)
                    //    throw new TESParserException("Record.Record: ZLib inflate error. Output buffer is empty.");

                    if (dataSizeParam > 0) //dawnguard.esm at position 6.812.369 at a dataSize == 0 - Record=NAVM
                    {
                        ZLibWrapper.CopyStreamToInputBuffer(snipStreamWrapper.SnipStream, dataSizeParam);
                        //stream = new MemoryStream(recordReader.ReadBytes((int) dataSize));
                        //dataReader = compressed ? ZLib.Decompress(stream, out compressLevel, (int)realSize) : new BinaryReader(stream);
                        if (compressed & realSize > 0)
                        {
                            //Clipboard.SetText(Name + realSize.ToString(CultureInfo.InvariantCulture));
                            ZLib.Decompress(compressLevel: out compressLevel, expectedSize: (int)realSize);
                            //Array.Copy();
                        }
                        else
                        {
                            ZLibWrapper.CopyInputBufferToOutputBuffer(dataSizeParam);
                        }
                    }
                    else
                    {
                        ZLibWrapper.ResetBufferSizeAndPosition();
                    }
                }
                catch (Exception ex)
                {
                    throw new TESParserException("Record.Record: ZLib error" + Environment.NewLine +
                                                 "Message: " + ex.Message +
                                                 Environment.NewLine +
                                                 "StackTrace: " + ex.StackTrace);
                }

                if (compressed & dataSizeParam > 0)          //dawnguard.esm at position 6.812.369 at a dataSize == 0 - Record=NAVM
                {
                    if (ZLibWrapper.OutputBufferLength <= 0) //if (dataReader == null)
                    {
                        throw new TESParserException("Record.Record: ZLib inflate error. Output buffer is empty.");
                    }
                }

                while (ZLibWrapper.OutputBufferPosition < ZLibWrapper.OutputBufferLength)
                //while (dataReader.BaseStream.Position < dataReader.BaseStream.Length)
                {
                    var  type = "XXXX";
                    uint size = 0;
                    if (realSize == 0)     //compressed &
                    {
                        type = "????";     //ReadRecName(ZLibWrapper.Read4Bytes());
                        size = dataSizeParam;
                        //realSize = dataSizeParam;
                        //this.dataSize = dataSizeParam;
                    }
                    else
                    {
                        type = ReadRecName(ZLibWrapper.Read4Bytes());     //var type = ReadRecName(dataReader);

                        if (type == "XXXX")
                        {
                            ZLibWrapper.ReadUInt16();                     //dataReader.ReadUInt16();
                            size = ZLibWrapper.ReadUInt32();              //dataReader.ReadUInt32();
                            type = ReadRecName(ZLibWrapper.Read4Bytes()); //ReadRecName(dataReader);
                            ZLibWrapper.ReadUInt16();                     //dataReader.ReadUInt16();
                        }
                        else
                        {
                            size = ZLibWrapper.ReadUInt16();     //dataReader.ReadUInt16();
                        }
                    }
                    record = new SubRecord(this, type, snipStreamWrapper, size);
                    //record = new SubRecord(this, type, dataReader, size); //var record = new SubRecord(this, type, dataReader, size);
                    this.SubRecords.Add(record);
                    amountRead += (uint)record.Size2;
                }

                //} //using (var dataReader = compressed ? ZLib.Decompress(stream, (int) realSize) : new BinaryReader(stream))
                //if (dataReader != null)
                //{
                //    dataReader.Close();
                //    dataReader.Dispose();
                //    dataReader = null;
                //}

                if ((compressed & realSize != 0) | (!compressed))
                {
                    if (amountRead > realSize)
                    {
                        Debug.Print(
                            " * ERROR: SUB-RECORD {0} DATA DOESN'T MATCH THE SIZE SPECIFIED IN THE HEADER: DATA-SIZE={1} REAL-SIZE={2} AMOUNT-READ={3}",
                            name, dataSizeParam, realSize, amountRead);
                        throw new TESParserException(
                                  string.Format(
                                      "Subrecord block did not match the size specified in the record header: ExpectedSize={0} ReadSize={1} DataSize={2}",
                                      realSize, amountRead, dataSizeParam));
                    }
                }


                this.descNameOverride = this.DefaultDescriptiveName;
                this.UpdateShortDescription();

                // br.BaseStream.Position+=Size;

                //} //using (var stream = new MemoryStream(recordReader.ReadBytes((int) dataSize)))
            }
            catch (Exception ex)
            {
                string errMsg =
                    "Message: " + ex.Message +
                    Environment.NewLine +
                    Environment.NewLine +
                    "StackTrace: " + ex.StackTrace +
                    Environment.NewLine +
                    Environment.NewLine +
                    "Source: " + ex.Source +
                    Environment.NewLine +
                    Environment.NewLine +
                    "GetType: " + ex.GetType().ToString();

                System.Windows.Forms.Clipboard.SetDataObject(errMsg, true);

                // Create an EventLog instance and assign its source.
                EventLog myLog = new EventLog();
                myLog.Source = "ThreadException";
                myLog.WriteEntry(errMsg);

                MessageBox.Show(errMsg, "Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
            finally
            {
                //if (stream != null)
                //{
                //    stream.Close();
                //    stream.Dispose();
                //}
            }
        }
Beispiel #8
0
        private void LoadPluginData(FileStream fs, bool headerOnly, string[] recFilter) //LoadPluginData(BinaryReader br, bool headerOnly, string[] recFilter)
        {
            bool oldHoldUpdates = HoldUpdates;
            SnipStreamWrapper snipStreamWrapper = null;

            try
            {
                ZLibWrapper.AllocateBuffers();
                RecordsTace.InitListOfRecords();
                snipStreamWrapper = new SnipStreamWrapper(fs);
                //BinaryReader br = new BinaryReader(fs);

                string s;
                uint   recsize;
                bool   IsOblivion = false;

                this.Filtered = recFilter != null && recFilter.Length > 0;

                HoldUpdates = true;

                s = ReadRecName(snipStreamWrapper.ReadBytes(4)); //s = ReadRecName(br);
                if (s != "TES4")
                {
                    throw new Exception("File is not a valid TES4 plugin (Missing TES4 record)");
                }

                // Check for file version by checking the position of the HEDR field in the file. (ie. how big are the record header.)
                snipStreamWrapper.JumpTo(20, SeekOrigin.Begin);  //br.BaseStream.Position = 20;
                s = ReadRecName(snipStreamWrapper.ReadBytes(4)); //s = ReadRecName(br);
                if (s == "HEDR")
                {
                    // Record Header is 20 bytes
                    IsOblivion = true;
                }
                else
                {
                    s = ReadRecName(snipStreamWrapper.ReadBytes(4)); //s = ReadRecName(br);
                    if (s != "HEDR")
                    {
                        throw new Exception("File is not a valid TES4 plugin (Missing HEDR subrecord in the TES4 record)");
                    }

                    // Record Header is 24 bytes. Or the file is illegal
                }

                snipStreamWrapper.JumpTo(4, SeekOrigin.Begin); //br.BaseStream.Position = 4;
                recsize = snipStreamWrapper.ReadUInt32();      //recsize = br.ReadUInt32();
                try
                {
                    this.AddRecord(new Record("TES4", recsize, snipStreamWrapper, IsOblivion));
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message);
                }

                if (!headerOnly)
                {
                    while (!snipStreamWrapper.Eof())                           //while (br.PeekChar() != -1)
                    {
                        s       = ReadRecName(snipStreamWrapper.ReadBytes(4)); //s = ReadRecName(br);
                        recsize = snipStreamWrapper.ReadUInt32();              //recsize = br.ReadUInt32();
                        if (s == "GRUP")
                        {
                            try
                            {
                                this.AddRecord(new GroupRecord(recsize, snipStreamWrapper, IsOblivion, recFilter, false)); //this.AddRecord(new GroupRecord(recsize, br, IsOblivion, recFilter, false));
                            }
                            catch (Exception e)
                            {
                                MessageBox.Show(e.Message);
                            }
                        }
                        else
                        {
                            bool skip = recFilter != null && Array.IndexOf(recFilter, s) >= 0;
                            if (skip)
                            {
                                long size = recsize + (IsOblivion ? 8 : 12);
                                if ((snipStreamWrapper.ReadUInt32() & 0x00040000) > 0) //if ((br.ReadUInt32() & 0x00040000) > 0)
                                {
                                    size += 4;                                         // Add 4 bytes for compressed record since the decompressed size is not included in the record size.
                                }

                                snipStreamWrapper.JumpTo((int)size, SeekOrigin.Current);  //br.BaseStream.Position += size; // just position past the data
                            }
                            else
                            {
                                try
                                {
                                    this.AddRecord(new Record(s, recsize, snipStreamWrapper, IsOblivion)); //this.AddRecord(new Record(s, recsize, br, IsOblivion));
                                }
                                catch (Exception e)
                                {
                                    MessageBox.Show(e.Message);
                                }
                            }
                        }
                    }
                }
            }
            finally
            {
                snipStreamWrapper.CloseAndDisposeFileStream();
                snipStreamWrapper = null;
                Clipboard.SetText("CompressedRecords:" + Environment.NewLine +
                                  string.Join <string>(string.Empty, RecordsTace.CompressedRecords) +
                                  "AllRecords:" + Environment.NewLine +
                                  string.Join <string>(string.Empty, RecordsTace.AllRecords) +
                                  "Max Size:" +
                                  ZLibWrapper.MaxOutputBufferPosition.ToString(CultureInfo.InvariantCulture));
                ZLibWrapper.ReleaseBuffers();
                ZLib.ReleaseInflater();
                HoldUpdates = oldHoldUpdates;
                FireRecordListUpdate(this, this);
            }
        }
Beispiel #9
0
        internal void Save(string filePath)
        {
            UpdateRecordCount();
            string extension = string.Empty;
            //BinaryWriter bw;
            SnipStreamWrapper snipStreamWrapper = null;

            string tmpFile = filePath + ".new";

            //if (File.Exists(filePath))
            //{
            //    //bw = new BinaryWriter(File.OpenWrite(filePath + ".new"));
            //    //extension = ".new";
            //}
            //else
            //{
            //    //bw = new BinaryWriter(File.OpenWrite(filePath));
            //    fs = new FileStream(filePath, FileMode.Open, FileAccess.Write);
            //}

            //fs = new FileStream(filePath + extension, FileMode.Open, FileAccess.Write);
            //bw = new BinaryWriter(File.OpenWrite(filePath + extension));

            //bw = new BinaryWriter(File.OpenWrite(tmpFile));
            FileStream fs = new FileStream(tmpFile, FileMode.Create, FileAccess.Write, FileShare.None);

            try
            {
                ZLibWrapper.AllocateBuffers();
                snipStreamWrapper = new SnipStreamWrapper(fs);
                snipStreamWrapper.AllocateBuffers();

                this.SaveData(snipStreamWrapper);
                Name       = Path.GetFileName(filePath);
                PluginPath = Path.GetDirectoryName(filePath);
            }
            finally
            {
                //bw.Close();
                snipStreamWrapper.CloseAndDisposeFileStream();
                snipStreamWrapper.ReleaseBuffers();
                snipStreamWrapper = null;
                fs = null;
            }

            try
            {
                // ** Create Backup
                bool   backupExists  = true;
                int    backupVersion = 0;
                string backupFolder  = CreateBackupFolder(filePath);
                while (backupExists && backupVersion < 999)
                {
                    backupExists =
                        File.Exists(Path.Combine(backupFolder, Name) + string.Format(".{0,3:D3}.bak", backupVersion));
                    if (backupExists)
                    {
                        backupVersion++;
                    }
                }
                string backupFile = Path.Combine(backupFolder, Name) + string.Format(".{0,3:D3}.bak", backupVersion);
                File.Copy(tmpFile, backupFile, true);

                //if (existed)
                //{
                ////string newFile = filePath;
                //string backupFile = Path.Combine(backupFolder, Name) + string.Format(".{0,3:D3}.bak", backupVersion);
                //File.Copy(tmpFile, backupFile, true);
                if (File.Exists(filePath))
                {
                    File.Delete(filePath);
                }
                File.Move(tmpFile, filePath);
                //}
            }
            catch (Exception ex)
            {
                string msg = string.Format(ex.Message);
                MessageBox.Show(
                    msg,
                    TranslateUI.TranslateUiGlobalization.ResManager.GetString("Application_Title"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                Clipboard.SetText(msg);
            }

            var tes4 = this.Records.OfType <Record>().FirstOrDefault(x => x.Name == "TES4");

            if (tes4 != null && (tes4.Flags1 & 0x80) != 0)
            {
                if (Properties.Settings.Default.SaveStringsFiles)
                {
                    string prefix = Path.Combine(Path.Combine(Path.GetDirectoryName(filePath), "Strings"), Path.GetFileNameWithoutExtension(filePath));
                    prefix += "_" + Properties.Settings.Default.LocalizationName;
                    this.SaveStrings(prefix);
                }
            }

            StringsDirty = false;
        }