Esempio n. 1
0
        /// <summary>
        ///   Generate a Player Profile and assign it as the LastProfile.
        /// </summary>
        /// <param name="pathParam"    >Inherit and pass the -path parameter.</param>
        /// <param name="lastprof"     >Inherit the LastProfile instance.</param>
        /// <param name="profile"      >Inherit the Profile instance.</param>
        /// <param name="makeScaffold" >Inherit and pass the bool indicating if the scaffold must be created.</param>
        /// <remarks>
        ///   Note: The selected profile's blam.sav will be overwritten with its data preserved. <br/>
        ///   This doesn't harm good profiles, but it will fix bad profiles.
        /// </remarks>
        public static void Create(string pathParam,
                                  LastProfile lastprof = null,
                                  Profile profile      = null,
                                  bool makeScaffold    = true,
                                  bool profileIsGood   = true)
        {
            if (string.IsNullOrWhiteSpace(pathParam))
            {
                throw new System.ArgumentException($"'{nameof(pathParam)}' cannot be null or whitespace.", nameof(pathParam));
            }

            Core("Beginning to generate a new Player Profile");

            /** Handle Defaulted Parameters and set Exists booleans. */
            if (lastprof is null)
            {
                lastprof = (LastProfile)Custom.LastProfile(pathParam);
            }

            if (profile is null)
            {
                var lastUsedExists = System.IO.File.Exists(Custom.Profile(pathParam, lastprof.Profile));

                if (lastUsedExists)
                {
                    profile = (Profile)Custom.Profile(pathParam, lastprof.Profile);
                }
                else if (Profile.List().Count != 0)
                {
                    profile = Profile.List(Custom.Profiles(pathParam))[0];
                }
                else
                {
                    profile = (Profile)Custom.Profile(pathParam, "New001");
                }
            }

            bool lastprofExists = lastprof.Exists();
            bool profileExists  = profile.Exists();
            bool savegameExists = System.IO.File.Exists(Custom.Progress(pathParam, profile.Details.Name));

            /** Double-check for existing files to determine if the
             * savegames scaffold still needs to be created.
             * We only do this when makeScaffold is true in case
             * the scaffold structure exists, but needs to be recreated.*/
            if (makeScaffold)
            {
                makeScaffold = !lastprofExists ||
                               !profileExists ||
                               !savegameExists ||
                               !profileIsGood;
            }

            /** Load settings from existing profile */
            if (profileExists)
            {
                profile.Load();
            }

            lastprof.Profile = profile.Details.Name;

            if (makeScaffold)
            {
                Scaffold(pathParam, lastprof, profile);
            }
            else
            {
                profile.Save();
                lastprof.Save();
            }
        }
Esempio n. 2
0
        /// <summary>
        ///   Create file and folder structure for Profile.Generate().
        /// </summary>
        /// <param name="pathParam"> -path parameter to pass to Halo and write to profiles.</param>
        /// <param name="lastprof" > Object reperesentation of LastProf.txt.</param>
        /// <param name="profile"  > Object representation of blam.sav.</param>
        private static void Scaffold(string pathParam, LastProfile lastprof, Profile profile)
        {
            if (string.IsNullOrWhiteSpace(pathParam))
            {
                throw new System.ArgumentException($"'{nameof(pathParam)}' cannot be null or empty.", nameof(pathParam));
            }

            if (lastprof is null)
            {
                throw new System.ArgumentNullException(nameof(lastprof));
            }

            if (profile is null)
            {
                throw new System.ArgumentNullException(nameof(profile));
            }

            Core("Creating Scaffold...");

            /** Set Path to the -path executable parameter */
            var file = (File)pathParam;

            RootDir();
            SavegamesDir();
            ProfileDir();
            BlamSav();
            SavegameBin();
            ProfileWaypoint();
            LastProfileTxt();

            Info("Scaffold Completed.");

            /// <summary>
            ///   Create the Scaffold root directory
            /// </summary>
            /// <example>
            ///   ".\temp\"
            /// </example>
            void RootDir()
            {
                Directory.CreateDirectory(file.Path);
                VerifyPath(file.Path);
            }

            /// <summary>
            ///   Create the Savegames directory if it doesn't exist.
            /// </summary>
            /// <example>
            ///   ".\temp\savegames\"
            /// </example>
            void SavegamesDir()
            {
                file.Path = Custom.Profiles(pathParam);
                Directory.CreateDirectory(file.Path);
                VerifyPath(file.Path);
            }

            /// <summary>
            ///  Create Profile's folder.
            /// </summary>
            void ProfileDir()
            {
                file.Path = Custom.ProfileDirectory(pathParam, profile.Details.Name);  /// e.g. ".\temp\savegames\New001\"
                Directory.CreateDirectory(file.Path);
                VerifyPath(file.Path);
            }

            /// <summary>
            ///   Create Profile's blam.sav
            /// </summary>
            /// <example>
            ///   ".\temp\savegames\New001\blam.sav"
            /// </example>
            /// <remarks>
            ///   The file is overwritten, so you must Load() existing data <br/>
            ///   if you want to keep that data.
            /// </remarks>
            void BlamSav()
            {
                CreateBlam();
                profile.Save();
                VerifyPath(profile.Path);

                /// <summary>
                ///   Produces a file identical to default_profile\00.sav <br/>
                ///   Write Input Blanks
                /// </summary>
                /// <see cref="Profile.Offset"/>
                void CreateBlam()
                {
                    using (var fs = new FileStream(profile.Path, FileMode.Create, FileAccess.ReadWrite))
                        using (var ms = new MemoryStream(8192))
                            using (var bw = new BinaryWriter(ms))
                            {
                                fs.Position = 0;
                                fs.CopyTo(ms);

                                /** Write Bindings filler (7fff) */
                                ms.Position = 0x13c;
                                while (ms.Position < 0x93a)
                                {
                                    bw.Write((ushort)0x7fff);
                                }

                                /** Write Gamepad Menu Bindings filler (ffff) */
                                ms.Position = 0x32A;
                                while (ms.Position != 0x33a)
                                {
                                    bw.Write((ushort)0xffff);
                                }

                                /** Unknown */
                                {
                                    ms.Position = 0x0;
                                    bw.Write((byte)0x9);

                                    ms.Position = 0x11a;
                                    bw.Write((ushort)0xffff);
                                    bw.Write((ushort)0x1);

                                    ms.Position = 0x12E;
                                    bw.Write((byte)0x3);

                                    ms.Position = 0x134;
                                    bw.Write((ushort)0x9);
                                    bw.Write((ushort)0xC);
                                    bw.Write((ushort)0x1B);
                                    bw.Write((ushort)0x1C);

                                    ms.Position = 0x14E;
                                    bw.Write((ushort)0x12);

                                    ms.Position = 0x170;
                                    bw.Write((ushort)0x3);
                                    bw.Write((ushort)0x5);
                                    bw.Write((ushort)0x13);
                                    bw.Write((ushort)0x2);
                                    bw.Write((ushort)0xD);
                                    bw.Write((ushort)0xF);
                                    bw.Write((ushort)0x10);

                                    ms.Position = 0x18E;
                                    bw.Write((ushort)0x15);
                                    bw.Write((ushort)0x14);
                                    bw.Write((ushort)0x16);
                                    bw.Write((ushort)0x4);
                                    bw.Write((ushort)0x1);
                                    bw.Write((ushort)0x11);

                                    ms.Position = 0x1A4;
                                    bw.Write((ushort)0x8);
                                    ms.Position += 2;
                                    bw.Write((ushort)0xB);
                                    bw.Write((ushort)0xE);

                                    ms.Position = 0x1BE;
                                    bw.Write((ushort)0xA);

                                    ms.Position = 0x1C4;
                                    bw.Write((ushort)0x0);

                                    ms.Position = 0x20E;
                                    bw.Write((ushort)0x7);
                                    bw.Write((ushort)0xB);
                                    bw.Write((ushort)0x6);

                                    ms.Position = 0x21E;
                                    bw.Write((ushort)0x1A);
                                    bw.Write((ushort)0x19);
                                    bw.Write((ushort)0x17);
                                    bw.Write((ushort)0x18);

                                    ms.Position = 0x93A;
                                    bw.Write((ushort)0x0000);
                                    bw.Write((ushort)0x0000);
                                    bw.Write((byte)0x80);
                                    bw.Write((byte)0x3F);
                                    bw.Write((ushort)0x0000);
                                    bw.Write((byte)0x80);
                                    bw.Write((byte)0x3F);
                                    bw.Write((byte)0xFC);
                                    bw.Write((byte)0x04);
                                    bw.Write((byte)0x41);
                                    bw.Write((byte)0x3E);
                                    bw.Write((byte)0xFC);
                                    bw.Write((byte)0x04);
                                    bw.Write((byte)0x41);
                                    bw.Write((byte)0x3E);
                                    bw.Write((ushort)0x0000);
                                    bw.Write((byte)0x00);
                                    bw.Write((byte)0x43);
                                    bw.Write((ushort)0x0000);
                                    bw.Write((byte)0x00);
                                    bw.Write((byte)0x43);
                                    bw.Write((ushort)0x0303);
                                    bw.Write((ushort)0x0303);
                                    bw.Write((ushort)0x0303);
                                    bw.Write((ushort)0x0303);
                                    bw.Write((ushort)0x0303);
                                    bw.Write((ushort)0x0000);
                                    bw.Write((ushort)0x0000);
                                    bw.Write((byte)0x40);
                                    bw.Write((byte)0x3f);
                                    bw.Write((ushort)0x0000);
                                    bw.Write((byte)0x40);
                                    bw.Write((byte)0x3f);

                                    ms.Position = 0x962;
                                    bw.Write((byte)0x40);
                                    bw.Write((byte)0x3F);
                                    bw.Write((byte)0x0);
                                    bw.Write((byte)0x0);
                                    bw.Write((byte)0x40);
                                    bw.Write((byte)0x3F);

                                    ms.Position = 0xA68;
                                    bw.Write((byte)0x20);
                                    bw.Write((byte)0x3);
                                    bw.Write((byte)0x58);
                                    bw.Write((byte)0x2);
                                    bw.Write((byte)0x3C);
                                    bw.Write((byte)0x0);
                                    bw.Write((byte)0x2);
                                    bw.Write((byte)0x2);
                                    bw.Write((byte)0x1);
                                    bw.Write((byte)0x1);
                                    bw.Write((byte)0x1);
                                    bw.Write((byte)0x2);
                                    bw.Write((byte)0x2);
                                    bw.Write((byte)0x2);
                                    bw.Write((byte)0x1);

                                    ms.Position = 0xb78;
                                    bw.Write((byte)0xA);
                                    bw.Write((byte)0xA);
                                    bw.Write((byte)0x6);
                                    bw.Write((byte)0x0);
                                    bw.Write((byte)0x0);
                                    bw.Write((byte)0x1);
                                    bw.Write((byte)0x0);
                                    bw.Write((byte)0x2);

                                    ms.Position = 0xC80;
                                    bw.Write((byte)0x3);
                                    bw.Write((byte)0x1);
                                    bw.Write((byte)0x1);
                                    bw.Write((byte)0x00);
                                    bw.Write((ushort)0x0000);
                                    bw.Write((byte)0x1);
                                    bw.Write((byte)0x1);

                                    ms.Position = 0xD8C;
                                    bw.Write(System.Text.Encoding.Unicode.GetBytes("Halo"));

                                    ms.Position = 0xEBF;
                                    bw.Write((byte)0x3);

                                    ms.Position = 0xFC0;
                                    bw.Write((byte)0x1);

                                    ms.Position = 0x1002;
                                    bw.Write(0xFE);
                                    ms.Position = 0x1003;
                                    bw.Write(0x08);
                                    ms.Position = 0x1004;
                                    bw.Write(0xFF);
                                    ms.Position = 0x1005;
                                    bw.Write(0x08);

                                    ms.Position = 0x1FFC;
                                    bw.Write((byte)0x50);
                                    bw.Write((byte)0x3B);
                                    bw.Write((byte)0xA1);
                                    bw.Write((byte)0x3C);
                                }

                                ms.Position = 0;
                                ms.CopyTo(fs);
                            }
                }
            }

            /// <summary>
            ///   Create Profile's savegame.bin.
            /// </summary>
            /// <example>
            ///   ".\temp\savegames\New001\savegame.bin"
            /// </example>
            void SavegameBin()
            {
                file.Path = Custom.Progress(pathParam, profile.Details.Name);

                /** Only create a new savegame.bin if one does not already exist. */
                if (!file.Exists() || file.Size() != 0x480000)
                {
                    file.WriteAllBytes(new byte[0x480000]); /// 0x480000 == int 4718592
                }

                VerifyPath(file.Path);
            }

            /// <summary>
            ///   Create Profile's Waypoint file.
            /// </summary>
            /// <example>
            ///   ".\temp\savegames\New001\New001"
            /// </example>
            void ProfileWaypoint()
            {
                file.Path = Custom.Waypoint(pathParam, profile.Details.Name);
                file.WriteAllText(Custom.Waypoint(pathParam, profile.Details.Name));
                VerifyPath(file.Path);
            }

            /// <summary>
            ///   Save Profile to lastprof.txt
            /// </summary>
            /// <example>
            ///   ".\temp\lastprof.txt"
            /// </example>
            void LastProfileTxt()
            {
                file.Path     = Custom.LastProfile(pathParam);
                lastprof.Path = file.Path;
                lastprof.Name = profile.Details.Name;
                lastprof.Save();
                VerifyPath(file.Path);
            }

            /// <summary>
            ///   Output the File.Path variable's current value. Verify its full path exists in the file system.
            /// </summary>
            void VerifyPath(string path)
            {
                bool isDir = System.IO.File.GetAttributes(path).HasFlag(FileAttributes.Directory);

                Debug(NewLine
                      + NewLine + $"Path is currently \"{path}\""
                      + NewLine + $"The Full Path is \"{Path.GetFullPath(path)}\""
                      + NewLine + $"Path points to a folder? {isDir}"
                      + NewLine + $"\"{path}\" exists?" + (isDir ? Directory.Exists(path) : System.IO.File.Exists(path))
                      );
            }
        }