コード例 #1
0
        /// <summary>Saves the mission to <see cref="MissionFile.MissionPath"/></summary>
        /// <exception cref="UnauthorizedAccessException">Write permissions for <see cref="MissionFile.MissionPath"/> are denied</exception>
        public void Save()
        {
            //[JB] Rewrote the backup logic since it was broken.  It should now retain the same protection concept with more robust handling.
            //First check whether the file exists and is read-only.  Copying to a backup will inherit the read-only property and prevent any attempt to delete, silently breaking the backup feature unless the user directly intervenes to manually delete it.
            if (File.Exists(MissionPath) && (File.GetAttributes(MissionPath) & FileAttributes.ReadOnly) != 0)
            {
                throw new UnauthorizedAccessException("Cannot save, existing file is read-only.");
            }

            FileStream fs = null;
            //The backup filename must be normalized, as filenames are case-insensitive, unlike strings.  If the replace does not work, the resulting backup name will match the source, and attempting to copy will throw an exception.
            string backup = MissionPath.ToLower().Replace(".tie", "_tie.bak");
            bool   backupCreated = false, writerCreated = false;

            if (File.Exists(MissionPath) && MissionPath.ToLower() != backup)
            {
                try
                {
                    if (File.Exists(backup))
                    {
                        File.Delete(backup);
                    }
                    File.Copy(MissionPath, backup);
                    backupCreated = true;
                }
                catch { }
            }
            try
            {
                if (File.Exists(MissionPath))
                {
                    File.Delete(MissionPath);
                }
                fs = File.OpenWrite(MissionPath);
                BinaryWriter bw = new BinaryWriter(fs, System.Text.Encoding.GetEncoding(437));                  //[JB] Changed encoding to IBM437 (OEM United States) to properly handle the DOS ASCII character set.
                writerCreated = true;
                bw.Write((short)-1);
                bw.Write((short)FlightGroups.Count);
                bw.Write((short)Messages.Count);
                bw.Write((short)3);
                fs.Position = 0xA;
                fs.WriteByte((byte)OfficersPresent);
                fs.Position = 0xD;
                bw.Write(CapturedOnEjection);
                fs.Position = 0x18;
                for (int i = 0; i < 6; i++)
                {
                    long p = fs.Position;
                    if (EndOfMissionMessageColor[i] != 0)
                    {
                        bw.Write(Convert.ToByte(EndOfMissionMessageColor[i] + 48));
                    }
                    bw.Write(_endOfMissionMessages[i].ToCharArray()); bw.Write('\0');
                    fs.Position = p + 0x40;
                }
                fs.Position += 2;
                for (int i = 2; i < 6; i++)
                {
                    long p = fs.Position;
                    if (_iffHostile[i])
                    {
                        bw.Write('1');
                    }
                    bw.Write(_iff[i].ToCharArray()); bw.Write('\0');
                    fs.Position = p + 0xC;
                }
                #region Flightgroups
                for (int i = 0; i < FlightGroups.Count; i++)
                {
                    long p = fs.Position;
                    int  j;
                    #region Craft
                    bw.Write(FlightGroups[i].Name.ToCharArray());
                    fs.Position = p + 0xC;
                    bw.Write(FlightGroups[i].Pilot.ToCharArray());
                    fs.Position = p + 0x18;
                    bw.Write(FlightGroups[i].Cargo.ToCharArray());
                    fs.Position = p + 0x24;
                    bw.Write(FlightGroups[i].SpecialCargo.ToCharArray());
                    fs.Position = p + 0x30;
                    if (FlightGroups[i].SpecialCargoCraft == 0)
                    {
                        fs.WriteByte(FlightGroups[i].NumberOfCraft);
                    }
                    else
                    {
                        fs.WriteByte((byte)(FlightGroups[i].SpecialCargoCraft - 1));
                    }
                    bw.Write(FlightGroups[i].RandSpecCargo);
                    fs.WriteByte(FlightGroups[i].CraftType);
                    fs.WriteByte(FlightGroups[i].NumberOfCraft);
                    fs.WriteByte(FlightGroups[i].Status1);
                    fs.WriteByte(FlightGroups[i].Missile);
                    fs.WriteByte(FlightGroups[i].Beam);
                    fs.WriteByte(FlightGroups[i].IFF);
                    fs.WriteByte(FlightGroups[i].AI);
                    fs.WriteByte(FlightGroups[i].Markings);
                    bw.Write(FlightGroups[i].FollowsOrders);
                    fs.WriteByte(FlightGroups[i].Unknowns.Unknown1);
                    fs.WriteByte(FlightGroups[i].Formation);
                    fs.WriteByte(FlightGroups[i].FormDistance);
                    fs.WriteByte(FlightGroups[i].GlobalGroup);
                    fs.WriteByte(FlightGroups[i].FormLeaderDist);
                    fs.WriteByte((byte)(FlightGroups[i].NumberOfWaves - 1));
                    fs.WriteByte(FlightGroups[i].Unknowns.Unknown5);
                    fs.WriteByte(FlightGroups[i].PlayerCraft);
                    fs.WriteByte((byte)(FlightGroups[i].Yaw * 0x100 / 360));
                    fs.WriteByte((byte)((FlightGroups[i].Pitch >= 90 ? FlightGroups[i].Pitch - 270 : FlightGroups[i].Pitch + 90) * 0x100 / 360));
                    fs.WriteByte((byte)(FlightGroups[i].Roll * 0x100 / 360));
                    bw.Write(FlightGroups[i].PermaDeathEnabled);
                    fs.WriteByte(FlightGroups[i].PermaDeathID);
                    fs.WriteByte(FlightGroups[i].Unknowns.Unknown11);
                    #endregion
                    #region Arr/Dep
                    fs.WriteByte(FlightGroups[i].Difficulty);
                    for (j = 0; j < 4; j++)
                    {
                        fs.WriteByte(FlightGroups[i].ArrDepTriggers[0][j]);
                    }
                    for (j = 0; j < 4; j++)
                    {
                        fs.WriteByte(FlightGroups[i].ArrDepTriggers[1][j]);
                    }
                    bw.Write(FlightGroups[i].AT1AndOrAT2);
                    fs.WriteByte(FlightGroups[i].Unknowns.Unknown12);
                    fs.WriteByte(FlightGroups[i].ArrivalDelayMinutes);
                    fs.WriteByte(FlightGroups[i].ArrivalDelaySeconds);
                    for (j = 0; j < 4; j++)
                    {
                        fs.WriteByte(FlightGroups[i].ArrDepTriggers[2][j]);
                    }
                    fs.WriteByte(FlightGroups[i].DepartureTimerMinutes);
                    fs.WriteByte(FlightGroups[i].DepartureTimerSeconds);
                    fs.WriteByte(FlightGroups[i].AbortTrigger);
                    fs.WriteByte(FlightGroups[i].Unknowns.Unknown15);
                    fs.WriteByte(FlightGroups[i].Unknowns.Unknown16);
                    fs.WriteByte(FlightGroups[i].Unknowns.Unknown17);
                    fs.WriteByte(FlightGroups[i].ArrivalCraft1);
                    bw.Write(FlightGroups[i].ArrivalMethod1);
                    fs.WriteByte(FlightGroups[i].DepartureCraft1);
                    bw.Write(FlightGroups[i].DepartureMethod1);
                    fs.WriteByte(FlightGroups[i].ArrivalCraft2);
                    bw.Write(FlightGroups[i].ArrivalMethod2);
                    fs.WriteByte(FlightGroups[i].DepartureCraft2);
                    bw.Write(FlightGroups[i].DepartureMethod2);
                    #endregion
                    for (j = 0; j < 3; j++)
                    {
                        for (int k = 0; k < 18; k++)
                        {
                            fs.WriteByte(FlightGroups[i].Orders[j][k]);
                        }
                    }
                    for (j = 0; j < 9; j++)
                    {
                        fs.WriteByte(FlightGroups[i].Goals[j]);
                    }
                    fs.Position++;
                    for (j = 0; j < 4; j++)
                    {
                        for (int k = 0; k < 15; k++)
                        {
                            bw.Write((short)(FlightGroups[i].Waypoints[k][j] * (j == 1 ? -1 : 1)));
                        }
                    }
                    bw.Write(FlightGroups[i].Unknowns.Unknown19);
                    fs.Position++;
                    fs.WriteByte(FlightGroups[i].Unknowns.Unknown20);
                    bw.Write(FlightGroups[i].Unknowns.Unknown21);
                    fs.Position = p + 0x124;
                }
                #endregion
                #region Messages
                for (int i = 0; i < Messages.Count; i++)
                {
                    long p = fs.Position;
                    if (Messages[i].Color != 0)
                    {
                        bw.Write((byte)(Messages[i].Color + 0x30));
                    }
                    bw.Write(Messages[i].MessageString.ToCharArray()); bw.Write('\0');
                    fs.Position = p + 0x3F;
                    fs.WriteByte(0);
                    for (int j = 0; j < 4; j++)
                    {
                        fs.WriteByte(Messages[i].Triggers[0][j]);
                    }
                    for (int j = 0; j < 4; j++)
                    {
                        fs.WriteByte(Messages[i].Triggers[1][j]);
                    }
                    bw.Write(Messages[i].Short.ToCharArray()); bw.Write('\0');
                    fs.Position = p + 0x57;
                    fs.WriteByte(0);
                    fs.WriteByte(Messages[i].Delay);
                    bw.Write(Messages[i].Trig1AndOrTrig2);
                }
                #endregion
                #region Globals
                for (int i = 0; i < 3; i++)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        fs.WriteByte(GlobalGoals.Goals[i].Triggers[0][j]);
                    }
                    for (int j = 0; j < 4; j++)
                    {
                        fs.WriteByte(GlobalGoals.Goals[i].Triggers[1][j]);
                    }
                    fs.Position += 0x11;
                    bw.Write(GlobalGoals.Goals[i].T1AndOrT2);
                    fs.Position += 2;
                }
                #endregion
                #region Briefing
                bw.Write(Briefing.Length);
                bw.Write(Briefing.Unknown1);
                bw.Write(Briefing.StartLength);
                bw.Write(Briefing.EventsLength);
                fs.Position += 2;
                byte[] briefBuffer = new byte[Briefing.Events.Length * 2];
                Buffer.BlockCopy(Briefing.Events, 0, briefBuffer, 0, briefBuffer.Length);
                bw.Write(briefBuffer);
                for (int i = 0; i < 32; i++)
                {
                    string str_t = Briefing.BriefingTag[i].Replace("\r", "");
                    int    j     = Briefing.BriefingTag[i].Length;
                    bw.Write((short)j);
                    bw.Write(str_t.ToCharArray());
                }
                for (int i = 0; i < 32; i++)
                {
                    string str_t = Briefing.BriefingString[i].Replace("\r", "");
                    int    j     = Briefing.BriefingString[i].Length;
                    bw.Write((short)j);
                    bw.Write(str_t.ToCharArray());
                }
                #endregion
                #region Questions
                for (int i = 0; i < 10; i++)
                {
                    int    j;
                    string str_q = BriefingQuestions.PreMissQuestions[i];
                    string str_a = BriefingQuestions.PreMissAnswers[i];
                    str_a = str_a.Replace("\r", "");
                    str_a = str_a.Replace(']', Convert.ToChar(1));
                    str_a = str_a.Replace('[', Convert.ToChar(2));
                    j     = str_q.Length + str_a.Length;
                    if (j == 0)
                    {
                        bw.Write((short)0);
                        continue;               //if it doesn't exist, don't even bother with the rest of this
                    }
                    j++;                        //takes into account the q/a spacer
                    bw.Write((short)j);
                    bw.Write(str_q.ToCharArray());
                    fs.WriteByte(0xA);
                    bw.Write(str_a.ToCharArray());
                }
                for (int i = 0; i < 10; i++)
                {
                    int    j;
                    string str_q = BriefingQuestions.PostMissQuestions[i];
                    string str_a = BriefingQuestions.PostMissAnswers[i];
                    str_a = str_a.Replace("\r", "");
                    str_a = str_a.Replace(']', Convert.ToChar(1));                      //[JB] Debrief questions use the same highlight scheme.  Added character conversions.
                    str_a = str_a.Replace('[', Convert.ToChar(2));
                    j     = str_q.Length + str_a.Length;
                    if (j == 0)
                    {
                        bw.Write((short)0);
                        continue;
                    }
                    j += 3;
                    long p = fs.Position;
                    bw.Write((short)j);
                    fs.WriteByte(BriefingQuestions.PostTrigger[i]);
                    fs.WriteByte(BriefingQuestions.PostTrigType[i]);
                    bw.Write(str_q.ToCharArray());
                    fs.WriteByte(0xA);
                    bw.Write(str_a.ToCharArray());
                }
                #endregion
                bw.Write((short)0x2106); fs.WriteByte(0xFF);
                fs.SetLength(fs.Position);
                fs.Close();
            }
            catch
            {
                if (fs != null)
                {
                    fs.Close();                             //Prevent object instance exception if it failed to open.
                }
                //If the stream was opened successfully but failed at any point during writing, the contents are corrupt, so restore from backup.  Otherwise it's probably a different kind of access error, such as file already open.
                if (writerCreated && backupCreated)
                {
                    File.Delete(MissionPath);
                    File.Copy(backup, MissionPath);
                    File.Delete(backup);
                }
                throw;
            }
            //Save completed successfully.
            if (backupCreated)
            {
                File.Delete(backup);
            }
        }
コード例 #2
0
ファイル: Mission.cs プロジェクト: RandomStarfighter/Platform
        /// <summary>Saves the mission to <see cref="MissionFile.MissionPath"/></summary>
        /// <exception cref="UnauthorizedAccessException">Write permissions for <see cref="MissionFile.MissionPath"/> are denied</exception>
        public void Save()
        {
            //[JB] Added backup logic.  See the TIE Save() function for comments.
            if (File.Exists(MissionPath) && (File.GetAttributes(MissionPath) & FileAttributes.ReadOnly) != 0)
            {
                throw new UnauthorizedAccessException("Cannot save, existing file is read-only.");
            }

            FileStream fs = null;
            string     backup = MissionPath.ToLower().Replace(".xwi", "_xwi.bak");
            bool       backupCreated = false, writerCreated = false;

            if (File.Exists(MissionPath) && MissionPath.ToLower() != backup)
            {
                try
                {
                    if (File.Exists(backup))
                    {
                        File.Delete(backup);
                    }
                    File.Copy(MissionPath, backup);
                    backupCreated = true;
                }
                catch { }
            }
            try
            {
                if (File.Exists(MissionPath))
                {
                    File.Delete(MissionPath);
                }
                fs = File.OpenWrite(MissionPath);
                BinaryWriter bw = new BinaryWriter(fs, System.Text.Encoding.GetEncoding(437)); //[JB] Changed encoding to IBM437 (OEM United States) to properly handle the DOS ASCII character set.
                writerCreated = true;
                bw.Write((short)0x2);                                                          //Platform
                bw.Write(TimeLimitMinutes);
                bw.Write(EndEvent);
                bw.Write(RndSeed);
                bw.Write(Location);
                for (int i = 0; i < 3; i++)
                {
                    long p = fs.Position;
                    bw.Write(_endOfMissionMessages[i].ToCharArray()); bw.Write('\0');
                    fs.Position = p + 0x40;
                }
                int numFG = 0;
                int numOG = 0;
                for (int i = 0; i < FlightGroups.Count; i++)
                {
                    if (FlightGroups[i].CraftType > 0)
                    {
                        numFG++;
                    }
                    if (FlightGroups[i].ObjectType > 0)
                    {
                        numOG++;
                    }
                }
                bw.Write((short)numFG);
                bw.Write((short)numOG);


                #region Flightgroups
                for (int i = 0; i < FlightGroups.Count; i++)
                {
                    if (FlightGroups[i].CraftType == 0)
                    {
                        continue;
                    }

                    long p = fs.Position;

                    #region Craft
                    bw.Write(FlightGroups[i].Name.ToCharArray());
                    fs.Position = p + 0x10;
                    bw.Write(FlightGroups[i].Cargo.ToCharArray());
                    fs.Position = p + 0x20;
                    bw.Write(FlightGroups[i].SpecialCargo.ToCharArray());
                    fs.Position = p + 0x30;
                    bw.Write((short)FlightGroups[i].SpecialCargoCraft);
                    bw.Write((short)FlightGroups[i].CraftType);
                    bw.Write((short)FlightGroups[i].IFF);
                    bw.Write((short)FlightGroups[i].Status1);
                    bw.Write((short)FlightGroups[i].NumberOfCraft);
                    bw.Write((short)FlightGroups[i].NumberOfWaves);
                    #endregion
                    #region Arr/Dep
                    bw.Write((short)FlightGroups[i].ArrivalEvent);
                    bw.Write((short)FlightGroups[i].ArrivalDelay);
                    bw.Write((short)FlightGroups[i].ArrivalFG);
                    bw.Write((short)FlightGroups[i].Mothership);
                    bw.Write((short)FlightGroups[i].ArrivalHyperspace);
                    bw.Write((short)FlightGroups[i].DepartureHyperspace);
                    #endregion

                    //Waypoints (7 real waypoints, rest are virtualized BRF coordinate sets)
                    for (int j = 0; j < 4; j++)
                    {
                        for (int k = 0; k < 7; k++)
                        {
                            bw.Write(FlightGroups[i].Waypoints[k][j] /* * (j == 1 ? -1 : 1))*/);
                        }
                    }

                    //More craft info
                    bw.Write((short)FlightGroups[i].Formation);
                    bw.Write((short)FlightGroups[i].PlayerCraft);
                    bw.Write((short)FlightGroups[i].AI);
                    bw.Write(FlightGroups[i].Order);
                    bw.Write(FlightGroups[i].DockTimeThrottle);
                    bw.Write((short)FlightGroups[i].Markings);
                    bw.Write((short)FlightGroups[i].Markings);                      //Was Unknown1. Another color value. Official missions always have the same color.
                    bw.Write(FlightGroups[i].Objective);
                    bw.Write(FlightGroups[i].TargetPrimary);
                    bw.Write(FlightGroups[i].TargetSecondary);
                }
                // OBJECT GROUPS
                for (int i = 0; i < FlightGroups.Count; i++)
                {
                    if (FlightGroups[i].ObjectType == 0)
                    {
                        continue;
                    }

                    long p = fs.Position;

                    bw.Write(FlightGroups[i].Name.ToCharArray());
                    fs.Position = p + 0x10;
                    bw.Write(FlightGroups[i].Cargo.ToCharArray());
                    fs.Position = p + 0x20;
                    bw.Write(FlightGroups[i].SpecialCargo.ToCharArray());
                    fs.Position = p + 0x30;
                    bw.Write(FlightGroups[i].SpecialCargoCraft);

                    bw.Write(FlightGroups[i].ObjectType);
                    bw.Write((short)FlightGroups[i].IFF);
                    //The format begins to deviate here
                    bw.Write((short)FlightGroups[i].Formation);
                    bw.Write((short)FlightGroups[i].NumberOfCraft);
                    bw.Write(FlightGroups[i].Waypoints[0][0]);
                    bw.Write(FlightGroups[i].Waypoints[0][1]);
                    bw.Write(FlightGroups[i].Waypoints[0][2]);
                    bw.Write(FlightGroups[i].Yaw);                     //Conversion to/from degrees handled in the editor. This helps preserve the exact values used by pilot proving ground platforms.
                    bw.Write(FlightGroups[i].Pitch);
                    bw.Write(FlightGroups[i].Roll);
                }
                #endregion
                fs.SetLength(fs.Position);
                fs.Close();
            }
            catch
            {
                if (fs != null)
                {
                    fs.Close();
                }
                if (writerCreated && backupCreated)
                {
                    File.Delete(MissionPath);
                    File.Copy(backup, MissionPath);
                    File.Delete(backup);
                }
                throw;
            }
            if (backupCreated)
            {
                File.Delete(backup);
            }

            //Finished saving XWI file.  Now save the BRF file.
            string BriefingPath = MissionPath;
            bool   upper;                                           //This stuff is merely to try and make the BRF extension match the case of the XWI, so the file names look nice and tidy.
            int    extPos = BriefingPath.LastIndexOf('.');
            if (extPos >= 0 && extPos < BriefingPath.Length - 1)
            {
                upper        = char.IsUpper(BriefingPath[extPos + 1]);           //Detect case from the first character of the extension.
                BriefingPath = BriefingPath.Remove(extPos + 1);                  //Strip extension so a new one can be added.
            }
            else
            {
                upper         = char.IsUpper(BriefingPath[BriefingPath.Length - 1]);           //If for some reason the file has no extension, detect from the last character of the name.
                BriefingPath += ".";
            }
            BriefingPath += upper ? "BRF" : "brf";

            if (File.Exists(BriefingPath) && (File.GetAttributes(BriefingPath) & FileAttributes.ReadOnly) != 0)
            {
                throw new UnauthorizedAccessException("Cannot save briefing, existing file is read-only.");
            }

            fs            = null;
            backup        = BriefingPath.ToLower().Replace(".brf", "_brf.bak");
            backupCreated = false; writerCreated = false;

            if (File.Exists(BriefingPath) && BriefingPath.ToLower() != backup)
            {
                try
                {
                    if (File.Exists(backup))
                    {
                        File.Delete(backup);
                    }
                    File.Copy(BriefingPath, backup);
                    backupCreated = true;
                }
                catch { }
            }
            try
            {
                if (File.Exists(BriefingPath))
                {
                    File.Delete(BriefingPath);
                }
                fs = File.OpenWrite(BriefingPath);
                BinaryWriter bw = new BinaryWriter(fs, System.Text.Encoding.GetEncoding(437)); //[JB] Changed encoding to IBM437 (OEM United States) to properly handle the DOS ASCII character set.
                writerCreated = true;
                bw.Write((short)2);                                                            //Version
                bw.Write((short)FlightGroupsBriefing.Count);
                bw.Write(Briefing.MaxCoordSet);                                                //Coordinate count;
                long p  = 0;
                int  wp = 0;
                for (int i = 0; i < Briefing.MaxCoordSet; i++)                  //Coordinate count
                {
                    //Just in case there too many coord sets than what the editor allows, read them but only load them if the indexes are valid.
                    if (i == 0)
                    {
                        wp = 0;                              //SP1
                    }
                    else
                    {
                        wp = 7 + i - 1;                          //CS1 starts at [7], but at this point i==1 so subtract to compensate
                    }
                    if (wp >= 10)
                    {
                        wp = -1;
                    }

                    for (int j = 0; j < FlightGroupsBriefing.Count; j++)
                    {
                        for (int k = 0; k < 3; k++)
                        {
                            short dat = 0;
                            if (wp >= 0)
                            {
                                dat = FlightGroupsBriefing[j].Waypoints[wp][k];
                            }

                            bw.Write(dat);
                        }
                    }
                }
                for (int i = 0; i < FlightGroupsBriefing.Count; i++)
                {
                    if (FlightGroupsBriefing[i].IsFlightGroup())
                    {
                        bw.Write((short)FlightGroupsBriefing[i].CraftType);
                    }
                    else
                    {
                        bw.Write(FlightGroupsBriefing[i].ObjectType);
                    }

                    bw.Write((short)FlightGroupsBriefing[i].IFF);
                    bw.Write((short)FlightGroupsBriefing[i].NumberOfCraft);
                    bw.Write((short)FlightGroupsBriefing[i].NumberOfWaves);

                    p = fs.Position;
                    bw.Write(FlightGroupsBriefing[i].Name.ToCharArray());
                    fs.Position = p + 0x10;
                    bw.Write(FlightGroupsBriefing[i].Cargo.ToCharArray());
                    fs.Position = p + 0x20;
                    bw.Write(FlightGroupsBriefing[i].SpecialCargo.ToCharArray());
                    fs.Position = p + 0x30;

                    bw.Write(FlightGroupsBriefing[i].SpecialCargoCraft);
                    bw.Write(FlightGroupsBriefing[i].Yaw);
                    bw.Write(FlightGroupsBriefing[i].Pitch);
                    bw.Write(FlightGroupsBriefing[i].Roll);
                }

                #region WindowUISettings
                short count = (short)Briefing.WindowSettings.Count;
                bw.Write(count);
                for (int i = 0; i < count; i++)
                {
                    for (int j = 0; j < 5; j++)
                    {
                        BriefingUIItem item = Briefing.WindowSettings[i].Items[j];
                        bw.Write(item.Top);
                        bw.Write(item.Left);
                        bw.Write(item.Bottom);
                        bw.Write(item.Right);
                        bw.Write(Convert.ToInt16(item.IsVisible));
                    }
                }
                #endregion WindowUISettings

                #region Pages
                bw.Write((short)Briefing.Pages.Count);
                for (int i = 0; i < Briefing.Pages.Count; i++)
                {
                    BriefingPage pg = Briefing.GetBriefingPage(i);
                    bw.Write(pg.Length);
                    bw.Write(pg.EventsLength);
                    bw.Write(pg.CoordSet);
                    bw.Write(pg.PageType);

                    byte[] briefBuffer = new byte[pg.EventsLength * 2];
                    Buffer.BlockCopy(pg.Events, 0, briefBuffer, 0, briefBuffer.Length);
                    bw.Write(briefBuffer);
                }
                #endregion Pages

                bw.Write(TimeLimitMinutes);
                bw.Write(EndEvent);
                bw.Write(RndSeed);
                bw.Write(Briefing.MissionLocation);

                p = fs.Position;
                for (int i = 0; i < 3; i++)
                {
                    bw.Write(EndOfMissionMessages[i].ToCharArray());
                    fs.Position = p + ((i + 1) * 64);
                }

                p = fs.Position;
                for (int i = 0; i < FlightGroupsBriefing.Count; i++)
                {
                    fs.Position += 68;
                    bw.Write((short)FlightGroupsBriefing[i].PlayerCraft);
                    fs.Position = p + ((i + 1) * 90);
                }

                #region Text/Tags
                bw.Write((short)32);                 //Count
                for (int i = 0; i < 32; i++)
                {
                    bw.Write((short)Briefing.BriefingTag[i].Length);
                    bw.Write(Briefing.BriefingTag[i].ToCharArray());
                }
                bw.Write((short)32);
                for (int i = 0; i < 32; i++)
                {
                    string t   = Briefing.RemoveBrackets(Briefing.BriefingString[i]);
                    int    len = t.Length;
                    bw.Write((short)len);
                    bw.Write(t.ToCharArray());
                    byte[] highlight = Briefing.TranslateStringToHighlight(Briefing.BriefingString[i]);
                    bw.Write(highlight);
                }
                #endregion Text/Tags
                fs.SetLength(fs.Position);
                fs.Close();
            }
            catch
            {
                if (fs != null)
                {
                    fs.Close();
                }
                if (writerCreated && backupCreated)
                {
                    File.Delete(BriefingPath);
                    File.Copy(backup, BriefingPath);
                    File.Delete(backup);
                }
                throw;
            }
            if (backupCreated)
            {
                File.Delete(backup);
            }
        }