Пример #1
0
        private void btnFix_Click(object sender, EventArgs e)
        {
            if (_stream != null && _stream.CanWrite && streamReader != null && textBox1.Text != "")
            {
                streamWriter = new SaveWriter(new FileStream(textBox1.Text, FileMode.OpenOrCreate));

                // Load the whole stream into memory
                MemoryStream memoryStream = new MemoryStream((int)streamReader.Length);
                memoryStream.SetLength(streamReader.Length);
                streamReader.Seek(0x00, SeekOrigin.Begin);
                streamReader.ReadBlock(memoryStream.GetBuffer(), 0, (int)memoryStream.Length);

                // Hash the contents
                memoryStream.Position = 0x2D25C;
                memoryStream.Write(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0, 20);
                byte[] hash = SaveSHA1.ComputeHash(memoryStream.GetBuffer());

                // Write the new digest
                streamWriter.Seek(0x2D25C, SeekOrigin.Begin);
                foreach (byte hashPart in hash)
                {
                    streamWriter.WriteByte(hashPart);
                }

                streamWriter.Close();

                MessageBox.Show("Save resigned.");
            }
        }
Пример #2
0
        private void loadSave(string filePath)
        {
            listView1.Items.Clear();

            // Load into Stream
            Stream stream = File.OpenRead(filePath);

            // Load into Aaron's nice Liberty IO
            streamReader = new SaveReader(stream);

            uncompressedDataStart = streamReader.Length - 0x40A000;
            streamReader.Seek(uncompressedDataStart, SeekOrigin.Begin);
            streamReader.ReadBlock(uncompressedSaveDate, 0, 0x040A000);

            stream       = new MemoryStream(uncompressedSaveDate);
            streamReader = new SaveReader(stream);

            // Verify Valid Container
            byte[] header = new byte[4];
            if (streamReader.ReadAscii() != "non compressed save")
            {
                throw new ArgumentException("The file format is invalid: bad header\r\nShould be \"non compressed save\"");
            }

            if (stream.Length != 0x40A000)
            {
                throw new ArgumentException("The file format is invalid: incorrect file size\r\nExpected 0x40A000 but got 0x" + stream.Length.ToString("X"));
            }

            streamReader.Seek(0x53090, SeekOrigin.Begin);
            UInt32 baseAddress  = streamReader.ReadUInt32();
            UInt32 startAddress = 0x53094;

            objEntrys.Clear();
            for (ushort i = 0; i < 2048; i++)
            {
                streamReader.Seek(0x53094 + (12 * i), SeekOrigin.Begin);
                long pos = streamReader.Position;

                HCEXObjectEntry objEntry = new HCEXObjectEntry();
                objEntry.offset        = pos;
                objEntry.DatumIndex    = (uint)(streamReader.ReadUInt16() << 16 | i);
                objEntry.Flags         = streamReader.ReadByte();
                objEntry.TagGroup      = (TagGroup)streamReader.ReadByte();
                objEntry.Unknown       = streamReader.ReadUInt16();
                objEntry.DataSize      = streamReader.ReadUInt16();
                objEntry.ObjectAddress = streamReader.ReadUInt32();
                objEntry.ObjectAddress = (objEntry.ObjectAddress - baseAddress) + startAddress;

                objEntrys.Add(objEntry);
            }

            poolChunks.Clear();
            foreach (HCEXObjectEntry objEntry in objEntrys)
            {
                if ((objEntry.DatumIndex >> 16) != 0)
                {
                    streamReader.Seek(objEntry.ObjectAddress, SeekOrigin.Begin);
                    HCEXPoolChunk poolChunk = new HCEXPoolChunk();
                    {
                        poolChunk.MapIdent    = streamReader.ReadUInt32();
                        poolChunk.ObjectEntry = objEntry;

                        streamReader.Seek(objEntry.ObjectAddress + 0xD8, SeekOrigin.Begin);
                        poolChunk.HealthModifier = streamReader.ReadFloat();
                        poolChunk.ShieldModifier = streamReader.ReadFloat();

                        streamReader.Seek(objEntry.ObjectAddress + 0x114, SeekOrigin.Begin);
                        poolChunk.NextCarried  = streamReader.ReadUInt32();
                        poolChunk.FirstCarried = streamReader.ReadUInt32();
                        poolChunk.Carrier      = streamReader.ReadUInt32();

                        streamReader.Seek(objEntry.ObjectAddress + 0x2B6, SeekOrigin.Begin);
                        poolChunk.WeaponAmmo     = streamReader.ReadInt16();
                        poolChunk.WeaponClipAmmo = streamReader.ReadInt16();

                        streamReader.Seek(objEntry.ObjectAddress + 0x2F8, SeekOrigin.Begin);
                        poolChunk.PrimaryWeapon    = streamReader.ReadUInt32();
                        poolChunk.SecondaryWeapon  = streamReader.ReadUInt32();
                        poolChunk.TertiaryWeapon   = streamReader.ReadUInt32();
                        poolChunk.QuaternaryWeapon = streamReader.ReadUInt32();

                        streamReader.Seek(objEntry.ObjectAddress + 0x5C, SeekOrigin.Begin);
                        poolChunk.PositionCordX = streamReader.ReadFloat();
                        poolChunk.PositionCordY = streamReader.ReadFloat();
                        poolChunk.PositionCordZ = streamReader.ReadFloat();

                        streamReader.Seek(objEntry.ObjectAddress + 0x31E, SeekOrigin.Begin);
                        poolChunk.FragNades   = streamReader.ReadByte();
                        poolChunk.PlasmaNades = streamReader.ReadByte();
                    }
                    poolChunks.Add(poolChunk);
                }
                else
                {
                    poolChunks.Add(null);
                }
            }

            poolChunkLvi.Clear();
            foreach (HCEXPoolChunk poolChunk in poolChunks)
            {
                if (poolChunk == null)
                {
                    continue;
                }

                ListViewItem lvi = new ListViewItem();
                lvi.Text = poolChunk.ObjectEntry.DatumIndex.ToString("X");
                lvi.SubItems.Add(poolChunk.MapIdent.ToString("X"));
                lvi.SubItems.Add(poolChunk.ObjectEntry.TagGroup.ToString());
                lvi.SubItems.Add("Tagnames coming soon...");
                lvi.SubItems.Add(poolChunk.ObjectEntry.DataSize.ToString("X"));
                lvi.Tag = poolChunk;
                poolChunkLvi[poolChunk] = lvi;

                listView1.Items.Add(lvi);
            }

            // Read player data
            // TODO: Parse players table properly instead of just assuming the datum index is at this offset
            streamReader.Seek(0x2AD9AA, SeekOrigin.Begin);
            int playerIndex = streamReader.ReadUInt16();

            playerBiped = poolChunks[playerIndex];

            textBox1.Text = filePath;
            toolStripStatusLabel2.Text = "Loaded gamestate file... hehe :3";
            splitContainer1.Enabled    = true;
        }
Пример #3
0
        /// <summary>
        /// Read the header from the save
        /// </summary>
        /// <param name="reader">The SaveReader stream of the Save</param>
        /// <seealso cref="SaveIO.SaveReader"/>
        public void ReadFrom(SaveReader reader)
        {
            // Verify Valid Container
            byte[] header = new byte[4];
            reader.Seek(0, System.IO.SeekOrigin.Begin);
            reader.ReadBlock(header, 0, 4);
            if (header[0] != 0xAA || header[1] != 0x46 || header[2] != 0xAF || header[3] != 0x2F)
            {
                throw new ArgumentException("The file format is invalid: bad header\r\nShould be 4E B2 C1 86");
            }

            if (reader.Length != 0xAD0000)
            {
                throw new ArgumentException("The file format is invalid: incorrect file size\r\nExpected 0xAD0000 but got 0x" + reader.Length.ToString("X"));
            }

            // Read Map Scenario
            reader.Seek(8, SeekOrigin.Begin);
            _mapScenario = reader.ReadAscii();

            // Read Engine Build
            reader.Seek(0x108, SeekOrigin.Begin);
            _engineBuild = reader.ReadAscii();

            // Read Engine Map Location
            reader.Seek(0x1C964, SeekOrigin.Begin);
            _engineMapLocation = reader.ReadAscii();

            // Read Difficulty
            reader.Seek(0x1CB03, SeekOrigin.Begin);
            _difficulty = (Difficulty)reader.ReadByte();
            switch (_difficulty)
            {
            case Halo4.Difficulty.Easy:
                _difficultyName = "Easy";
                break;

            case Halo4.Difficulty.Normal:
                _difficultyName = "Normal";
                break;

            case Halo4.Difficulty.Heroic:
                _difficultyName = "Heroic";
                break;

            case Halo4.Difficulty.Legendary:
                _difficultyName = "Legendary";
                break;

            default:
                _difficultyName = "Normal";
                break;
            }

            // Read Gamertag
            reader.Seek(0x2B438, SeekOrigin.Begin);
            _gamertag = reader.ReadUTF16();

            // Read ServiceTag
            reader.Seek(0x2B47C, SeekOrigin.Begin);
            _serviceTag = reader.ReadUTF16();
        }
Пример #4
0
        void loadSave()
        {
            // Load into Stream
            MemoryStream stream = new MemoryStream(File.ReadAllBytes(textBox1.Text));

            // Load into Aaron's nice Liberty IO
            streamReader = new SaveReader(stream);

            // Verify Valid Container
            byte[] header = new byte[4];
            streamReader.Seek(0, SeekOrigin.Begin);
            streamReader.ReadBlock(header, 0, 4);
            if (header[0] != 0x4E || header[1] != 0xB2 || header[2] != 0xC1 || header[3] != 0x86)
            {
                throw new ArgumentException("The file format is invalid: bad header\r\nShould be 4E B2 C1 86");
            }

            if (stream.Length != 0x7E0000)
            {
                throw new ArgumentException("The file format is invalid: incorrect file size\r\nExpected 0x7E0000 but got 0x" + stream.Length.ToString("X"));
            }

            // Load Header
            streamReader.Seek(0x08, SeekOrigin.Begin);
            gamestateHeader.mapScenarioName = streamReader.ReadAscii();
            streamReader.Seek(0x0108, SeekOrigin.Begin);
            gamestateHeader.relativeEngineBuild = streamReader.ReadAscii();
            streamReader.Seek(0x0154, SeekOrigin.Begin);
            gamestateHeader.mapDiskDirectory1 = streamReader.ReadAscii();
            streamReader.Seek(0xE6D9, SeekOrigin.Begin);
            gamestateHeader.player1GT1 = streamReader.ReadUTF16();
            streamReader.Seek(0xE70F, SeekOrigin.Begin);
            gamestateHeader.player1ST1 = streamReader.ReadUTF16();
            streamReader.Seek(0xE7A1, SeekOrigin.Begin);
            gamestateHeader.player1GT2 = streamReader.ReadUTF16();
            streamReader.Seek(0x3E0290, SeekOrigin.Begin);
            gamestateHeader.mapDiskDirectory2 = streamReader.ReadUTF16();

            string[] tmp = gamestateHeader.mapScenarioName.Split('\\');
            gamestateHeader.trueMapName = tmp[2];
            tmp = null;

            // Get Relative taglist
            trueTaglist = new Liberty.classInfo.iniFile(iniFolderPath + "map-" + gamestateHeader.trueMapName + ".tagCDB");

            // Load LinkObjects
            streamReader.Seek(0x46A0F4, SeekOrigin.Begin);
            linkObjects.Clear();
            for (int i = 0; i < 2048; i++)
            {
                streamReader.Seek(0x46A0F4 + (16 * i), SeekOrigin.Begin);

                LinkObjectTable linkObj = new LinkObjectTable();
                linkObj.MahOffsat = stream.Position;

                linkObj.DatumSaltIndex = (uint)(streamReader.ReadUInt16() << 16 | i);
                //linkObj.Unk1 =
                streamReader.ReadByte();
                linkObj.TagGroup   = (byte)streamReader.ReadByte();
                linkObj.Unk3       = streamReader.ReadUInt16();
                linkObj.Unk4       = streamReader.ReadUInt16();
                linkObj.PoolOffset = streamReader.ReadUInt32();
                linkObj.Unk6       = streamReader.ReadUInt32();

                streamReader.Seek(0x4721F4 + linkObj.PoolOffset, SeekOrigin.Begin);
                UInt32 gid = streamReader.ReadUInt32();
                if (gid != 0x0)
                {
                    linkObjects.Add(linkObj);
                }
            }

            IdentParents[0]  = 0;
            IdentParents[1]  = 1;
            IdentParents[2]  = 2;
            IdentParents[3]  = 3;
            IdentParents[4]  = 4;
            IdentParents[5]  = 5;
            IdentParents[6]  = 6;
            IdentParents[7]  = 7;
            IdentParents[8]  = 8;
            IdentParents[9]  = 9;
            IdentParents[10] = 10;
            IdentParents[11] = 11;
            IdentParents[13] = 13;

            foreach (LinkObjectTable linkedObjects in linkObjects)
            {
                //if (!((IList<int>)IdentParents).Contains((int)linkedObjects.TagGroup))
                {
                    if (!linkedObjects.PoolOffset.Equals(0))
                    {
                        H3GameObject h3g = new H3GameObject();
                        streamReader.Seek(0x4721F4 + linkedObjects.PoolOffset - 16, SeekOrigin.Begin);
                        h3g.objectSizeWithLink = streamReader.ReadUInt32();
                        h3g.objectDatumIndex   = streamReader.ReadUInt32();

                        streamReader.Seek(0x4721F4 + linkedObjects.PoolOffset, SeekOrigin.Begin);
                        h3g.linkedData = linkedObjects;
                        h3g.GameIdent  = streamReader.ReadUInt32();

                        streamReader.Seek(0x4721F4 + linkedObjects.PoolOffset + 0x20, SeekOrigin.Begin);
                        h3g.BoundingBoxX1 = streamReader.ReadFloat();
                        h3g.BoundingBoxY1 = streamReader.ReadFloat();
                        h3g.BoundingBoxZ1 = streamReader.ReadFloat();

                        streamReader.Seek(0x4721F4 + linkedObjects.PoolOffset + 0x30, SeekOrigin.Begin);
                        h3g.BoundingBoxX2 = streamReader.ReadFloat();
                        h3g.BoundingBoxY2 = streamReader.ReadFloat();
                        h3g.BoundingBoxZ2 = streamReader.ReadFloat();

                        streamReader.Seek(0x4721F4 + linkedObjects.PoolOffset + 0x40, SeekOrigin.Begin);
                        h3g.PositionX = streamReader.ReadFloat();
                        h3g.PositionY = streamReader.ReadFloat();
                        h3g.PositionZ = streamReader.ReadFloat();

                        switch (h3g.linkedData.TagGroup)
                        {
                        case (byte)TagGroup.Weap:
                            H3WeaponObject h3w = new H3WeaponObject();
                            streamReader.Seek(0x4721F4 + linkedObjects.PoolOffset + 0x23A, SeekOrigin.Begin);
                            h3w.ExternalAmmo = streamReader.ReadInt16();
                            streamReader.Seek(0x4721F4 + linkedObjects.PoolOffset + 0x23E, SeekOrigin.Begin);
                            h3w.ClipAmmo = streamReader.ReadInt16();

                            h3g.weaponData = h3w;
                            h3g.bipedData  = null;
                            break;

                        case (byte)TagGroup.Bipd:
                            H3BipedObject h3b = new H3BipedObject();
                            streamReader.Seek(0x4721F4 + linkedObjects.PoolOffset + 0x17C, SeekOrigin.Begin);
                            h3b.PlayerIndex = streamReader.ReadUInt16();

                            streamReader.Seek(0x4721F4 + linkedObjects.PoolOffset + 0x28C, SeekOrigin.Begin);
                            h3b.FragNade   = (sbyte)streamReader.ReadSByte();
                            h3b.PlasmaNade = (sbyte)streamReader.ReadSByte();
                            h3b.SpikeNade  = (sbyte)streamReader.ReadSByte();
                            h3b.FireNade   = (sbyte)streamReader.ReadSByte();

                            h3g.bipedData  = h3b;
                            h3g.weaponData = null;
                            break;
                        }
                        gameObjects.Add(h3g);
                    }
                }
            }

            foreach (H3GameObject gameObj in gameObjects)
            {
                ListViewItem lvi = new ListViewItem();
                lvi.Text = trueTaglist.IniReadValue(gamestateHeader.trueMapName, gameObj.GameIdent.ToString("X"));
                lvi.SubItems.Add(gameObj.GameIdent.ToString("X"));
                lvi.SubItems.Add(gameObj.linkedData.TagGroup.ToString());
                lvi.SubItems.Add(gameObj.linkedData.DatumSaltIndex.ToString("X"));
                lvi.Tag = gameObj;

                listView1.Items.Add(lvi);
            }

            toolStripStatusLabel2.Text = "Loaded gamestate file... hehe :3";
        }
Пример #5
0
        void loadSave()
        {
            // Load into Stream
            _stream = new MemoryStream(File.ReadAllBytes(textBox1.Text));

            // Load into Aaron's nice Liberty IO
            streamReader = new SaveReader(_stream);

            // Verify Valid Container
            byte[] header = new byte[4];
            streamReader.Seek(0, SeekOrigin.Begin);
            streamReader.ReadBlock(header, 0, 4);
            if (header.Equals(new byte[] { 0xAA, 0x46, 0xAF, 0x2F }))
            {
                throw new ArgumentException("The file format is invalid: bad header\r\nShould be 4E B2 C1 86");
            }

            if (streamReader.Length != 0xAD0000)
            {
                throw new ArgumentException("The file format is invalid: incorrect file size\r\nExpected 0xAD0000 but got 0x" + streamReader.Length.ToString("X"));
            }

            // Load Header
            streamReader.Seek(0x08, SeekOrigin.Begin);
            gamestateHeader.mapScenarioName = streamReader.ReadAscii();
            streamReader.Seek(0x108, SeekOrigin.Begin);
            gamestateHeader.relativeEngineBuild = streamReader.ReadAscii();
            streamReader.Seek(0x1C964, SeekOrigin.Begin);
            gamestateHeader.mapDiskDirectory1 = streamReader.ReadAscii();
            streamReader.Seek(0x2B438, SeekOrigin.Begin);
            gamestateHeader.player1GT1 = streamReader.ReadUTF16();
            streamReader.Seek(0x2B47C, SeekOrigin.Begin);
            gamestateHeader.player1ST1 = streamReader.ReadUTF16();

            string[] tmp = gamestateHeader.mapScenarioName.Split('\\');
            gamestateHeader.trueMapName = tmp[2];
            tmp = null;

            // Get Relative taglist
            trueTaglist = new Liberty.classInfo.iniFile(iniFolderPath + gamestateHeader.trueMapName + ".taglist");

            // Load LinkObjects
            streamReader.Seek(0x7074FC, SeekOrigin.Begin);
            linkObjects.Clear();
            for (int i = 0; i < 2048; i++)
            {
                streamReader.Seek(0x7074FC + (16 * i), SeekOrigin.Begin);

                LinkObjectTable linkObj = new LinkObjectTable();
                linkObj.GlobalOffset   = (int)streamReader.Position;
                linkObj.RelativeOffset = linkObj.GlobalOffset - 0x7074FC;

                linkObj.DatumSaltIndex = (UInt16)(streamReader.ReadUInt16() << 16 | i);
                linkObj.Flags          = streamReader.ReadInt16();
                linkObj.TagGroup       = (byte)streamReader.ReadByte();
                streamReader.Seek(linkObj.GlobalOffset + 0x08, SeekOrigin.Begin);
                linkObj.PoolOffset    = streamReader.ReadUInt32();
                linkObj.MemoryAddress = streamReader.ReadUInt32();

                streamReader.Seek(0x70F5FC + linkObj.PoolOffset, SeekOrigin.Begin);
                UInt32 gid = streamReader.ReadUInt32();
                if (gid != 0x0)
                {
                    linkObjects.Add(linkObj);
                }
            }

            IdentParents[0]  = 0;
            IdentParents[1]  = 1;
            IdentParents[2]  = 2;
            IdentParents[3]  = 3;
            IdentParents[4]  = 4;
            IdentParents[5]  = 5;
            IdentParents[6]  = 6;
            IdentParents[7]  = 7;
            IdentParents[8]  = 8;
            IdentParents[9]  = 9;
            IdentParents[10] = 10;
            IdentParents[11] = 11;
            IdentParents[13] = 13;

            foreach (LinkObjectTable linkedObjects in linkObjects)
            {
                //if (!((IList<int>)IdentParents).Contains((int)linkedObjects.TagGroup))
                {
                    if (!linkedObjects.PoolOffset.Equals(0))
                    {
                        H4GameObject h4g = new H4GameObject();
                        streamReader.Seek(0x70F5FC + linkedObjects.PoolOffset - 16, SeekOrigin.Begin);
                        h4g.objectSizeWithLink = streamReader.ReadUInt32();
                        h4g.objectDatumIndex   = streamReader.ReadUInt32();

                        streamReader.Seek(0x70F5FC + linkedObjects.PoolOffset, SeekOrigin.Begin);
                        h4g.linkedData = linkedObjects;
                        h4g.GameIdent  = streamReader.ReadUInt32();

                        streamReader.Seek(0x70F5FC + linkedObjects.PoolOffset + 0x40, SeekOrigin.Begin);
                        h4g.BoundingBoxX1 = streamReader.ReadFloat();
                        h4g.BoundingBoxY1 = streamReader.ReadFloat();
                        h4g.BoundingBoxZ1 = streamReader.ReadFloat();

                        streamReader.Seek(0x70F5FC + linkedObjects.PoolOffset + 0x50, SeekOrigin.Begin);
                        h4g.BoundingBoxX2 = streamReader.ReadFloat();
                        h4g.BoundingBoxY2 = streamReader.ReadFloat();
                        h4g.BoundingBoxZ2 = streamReader.ReadFloat();

                        streamReader.Seek(0x70F5FC + linkedObjects.PoolOffset + 0x64, SeekOrigin.Begin);
                        h4g.PositionX = streamReader.ReadFloat();
                        h4g.PositionY = streamReader.ReadFloat();
                        h4g.PositionZ = streamReader.ReadFloat();

                        switch (h4g.linkedData.TagGroup)
                        {
                        //case (byte)TagGroup.Weap:
                        //    H4WeaponObject h4w = new H4WeaponObject();
                        //    streamReader.Seek(0x70F5FC + linkedObjects.PoolOffset + 0x23A, SeekOrigin.Begin);
                        //    h4w.ExternalAmmo = streamReader.ReadInt16();
                        //    streamReader.Seek(0x70F5FC + linkedObjects.PoolOffset + 0x23E, SeekOrigin.Begin);
                        //    h4w.ClipAmmo = streamReader.ReadInt16();

                        //    h4g.weaponData = h4w;
                        //    h4g.bipedData = null;
                        //    break;
                        case (byte)TagGroup.Bipd:
                            H4BipedObject h4b = new H4BipedObject();
                            //streamReader.Seek(0x70F5FC + linkedObjects.PoolOffset + 0x17C, SeekOrigin.Begin);
                            //h4b.PlayerIndex = streamReader.ReadUInt16();

                            streamReader.Seek(0x70F5FC + linkedObjects.PoolOffset + 0x666, SeekOrigin.Begin);
                            h4b.FragNade   = (sbyte)streamReader.ReadSByte();
                            h4b.PlasmaNade = (sbyte)streamReader.ReadSByte();
                            h4b.SpikeNade  = (sbyte)streamReader.ReadSByte();
                            h4b.FireNade   = (sbyte)streamReader.ReadSByte();

                            h4g.bipedData  = h4b;
                            h4g.weaponData = null;
                            break;
                        }
                        gameObjects.Add(h4g);
                    }
                }
            }

            foreach (H4GameObject gameObj in gameObjects)
            {
                ListViewItem lvi   = new ListViewItem();
                string       ident = "0x" + gameObj.GameIdent.ToString("X");
                lvi.Text = trueTaglist.IniReadValue("yo", ident);
                lvi.SubItems.Add(gameObj.GameIdent.ToString("X"));
                lvi.SubItems.Add(gameObj.linkedData.TagGroup.ToString());
                lvi.SubItems.Add(gameObj.linkedData.DatumSaltIndex.ToString("X"));
                lvi.Tag = gameObj;

                listView1.Items.Add(lvi);
            }

            toolStripStatusLabel2.Text = "Loaded gamestate file... hehe :3";
        }