Beispiel #1
0
        /// <exception cref="U2FException"/>
        /// <exception cref="System.IO.IOException"/>
        public static IU2FRequest ParseRequest(Stream inputStream)
        {
            using (var dataInputStream = new EndianReader(inputStream, Endianness.BigEndian))
            {
                var version = dataInputStream.ReadByte();
                if (version != Version)
                {
                    throw new U2FException($"Unsupported message version: {version}");
                }
                var command = dataInputStream.ReadByte();
                switch (command)
                {
                    case CommandRegister:
                    {
                        return RawMessageCodec.DecodeKeyRegisterRequest(ParseMessage(dataInputStream
                            ));
                    }

                    case CommandAuthenticate:
                    {
                        return RawMessageCodec.DecodeKeySignRequest(ParseMessage
                            (dataInputStream));
                    }

                    default:
                    {
                        throw new U2FException($"Unsupported command: {command}");
                    }
                }
            }
        }
        public static InitializationPacket ReadFrom(ArraySegment<byte> segment)
        {
            if (segment.Count < NoDataSize)
            {
                throw new InvalidPacketSizeException(segment,
                    $"Data is too small, expected {NoDataSize} bytes but provided only {segment.Count}");
            }

            var result = new InitializationPacket();

            using (var stream = new MemoryStream(segment.Array, segment.Offset, segment.Count))
            {
                var reader = new EndianReader(stream, Endianness.BigEndian);
                result.ChannelIdentifier = reader.ReadUInt32();
                result.CommandIdentifier = reader.ReadByte();

                CheckCommand(segment, result.CommandIdentifier);

                var payloadLengthHi = reader.ReadByte();
                var payloadLengthLo = reader.ReadByte();
                result.PayloadLength = (ushort)(payloadLengthHi << 8 | payloadLengthLo);
            }

            var remainingBytes = Math.Min(segment.Count - NoDataSize, result.PayloadLength);
            result.Data = new ArraySegment<byte>(segment.Array, segment.Offset + NoDataSize,
                remainingBytes);

            return result;
        }
Beispiel #3
0
        private static void DumpSharedResources(string mapPath, EngineDatabase db)
        {
            ICacheFile cacheFile;
            ResourceTable resources;
            using (var reader = new EndianReader(File.OpenRead(mapPath), Endian.BigEndian))
            {
                cacheFile = CacheFileLoader.LoadCacheFile(reader, db);
                resources = cacheFile.Resources.LoadResourceTable(reader);
            }

            using (var output = new StreamWriter(Path.ChangeExtension(mapPath, ".txt")))
            {
                output.WriteLine("Shared resources referenced by {0}:", Path.GetFileName(mapPath));
                output.WriteLine();
                output.WriteLine("Rsrc Datum  Map File      Class  Tag");
                output.WriteLine("----------  --------      -----  ---");

                foreach (Resource resource in resources.Resources.Where(r => r.Location != null && r.ParentTag != null))
                {
                    // If either page has a null file path, then it's shared
                    ResourcePointer loc = resource.Location;
                    string primaryFile = (loc.PrimaryPage != null) ? loc.PrimaryPage.FilePath : null;
                    string secondaryFile = (loc.SecondaryPage != null) ? loc.SecondaryPage.FilePath : null;
                    if (primaryFile != null || secondaryFile != null)
                    {
                        string className = CharConstant.ToString(resource.ParentTag.Class.Magic);
                        string name = cacheFile.FileNames.GetTagName(resource.ParentTag) ?? resource.ParentTag.Index.ToString();
                        string fileName = primaryFile ?? secondaryFile;
                        fileName = fileName.Substring(fileName.IndexOf('\\') + 1);
                        output.WriteLine("{0}  {1, -12}  {2}   {3}", resource.Index, fileName, className, name);
                    }
                }
            }
        }
Beispiel #4
0
		public List<LocalizedString> LoadStrings(IReader reader)
		{
			var result = new List<LocalizedString>();
			if (StringCount == 0)
				return result;

			byte[] stringData = ReadLocaleData(reader);
			using (var stringReader = new EndianReader(new MemoryStream(stringData), Endian.BigEndian))
			{
				reader.SeekTo(LocaleIndexTableLocation.AsOffset());

				// Read each locale
				for (int i = 0; i < StringCount; i++)
				{
					// Read the offset and stringID
					StringID id;
					int offset;
					ReadLocalePointer(reader, out id, out offset);

					if (offset >= stringReader.Length)
						break; // Bad table - bail out so we don't end up in a huge memory-hogging loop

					stringReader.SeekTo(offset);
					string locale = stringReader.ReadUTF8();
					result.Add(new LocalizedString(id, locale));
				}
			}
			return result;
		}
Beispiel #5
0
        /// <summary>
        /// Decrypts a segment of an EndianReader stream.
        /// </summary>
        /// <param name="Reader">The EndianReader to read from.</param>
        /// <param name="StartPosition">The stream position to decrypt from.</param>
        /// <param name="Length">The number of bytes to decrypt.</param>
        /// <param name="Key">The decryption key as a string.</param>
        /// <returns>A new EndianReader stream containing only the decrypted segment.</returns>
        public static EndianReader DecryptSegment(EndianReader Reader, int StartPosition, int Length, string Key)
        {
            Reader.SeekTo(StartPosition);
            if (Length % 16 != 0) Length += 16 - Length % 16;
            byte[] data = Reader.ReadBytes(Length);
            byte[] bKey = System.Text.Encoding.ASCII.GetBytes(Key);
            byte[] XOR = new byte[bKey.Length];
            byte[] IV = new byte[bKey.Length];

            for (int i = 0; i < bKey.Length; i++)
            {
                XOR[i] = (byte)(bKey[i] ^ 0xFFA5);
                IV[i] = (byte)(XOR[i] ^ 0x3C);
            }

            var aes = new AesManaged()
            {
                Mode = CipherMode.CBC,
                Key = XOR,
                IV = IV,
                Padding = PaddingMode.Zeros
            };

            Stream stream = (Stream)new MemoryStream(aes.CreateDecryptor(aes.Key, aes.IV).TransformFinalBlock(data, 0, data.Length));
            return new EndianReader(stream, EndianFormat.Big);
        }
Beispiel #6
0
        private void makePatch_Click(object sender, EventArgs e)
        {
            Patch patch = new Patch();
            patch.Name = patchName.Text;
            patch.Description = patchDescription.Text;
            patch.Author = patchAuthor.Text;

            IReader originalReader = new EndianReader(File.OpenRead(unmoddedPath.Text), Endian.BigEndian);
            IReader newReader = new EndianReader(File.OpenRead(moddedPath.Text), Endian.BigEndian);

            ThirdGenVersionInfo version = new ThirdGenVersionInfo(originalReader);
            BuildInfoLoader loader = new BuildInfoLoader(XDocument.Load(@"Formats\SupportedBuilds.xml"), @"Formats\");
            BuildInformation buildInfo = loader.LoadBuild(version.BuildString);
            ThirdGenCacheFile originalFile = new ThirdGenCacheFile(originalReader, buildInfo, version.BuildString);
            ThirdGenCacheFile newFile = new ThirdGenCacheFile(newReader, buildInfo, version.BuildString);

            MetaComparer.CompareMeta(originalFile, originalReader, newFile, newReader, patch);
            LocaleComparer.CompareLocales(originalFile, originalReader, newFile, newReader, patch);

            originalReader.Close();
            newReader.Close();

            IWriter output = new EndianWriter(File.OpenWrite(outPath.Text), Endian.BigEndian);
            AssemblyPatchWriter.WritePatch(patch, output);
            output.Close();

            MessageBox.Show("Done!");
        }
        /// <summary>
        /// Extracts a Wwise OGG and converts it to a "regular" OGG file.
        /// </summary>
        /// <param name="reader">The stream to read from.</param>
        /// <param name="offset">The offset of the data to extract.</param>
        /// <param name="size">The size of the data to extract.</param>
        /// <param name="outPath">The path of the file to save to.</param>
        public static void ExtractWwiseToOGG(EndianReader reader, int offset, int size, string outPath)
        {
            // Just extract the RIFX to a temporary file
            string tempFile = Path.GetTempFileName();

            try
            {
                using (EndianWriter output = new EndianWriter(File.OpenWrite(tempFile), EndianFormat.BigEndian))
                {
                    reader.SeekTo(offset);
                    StreamUtil.Copy(reader, output, size);
                }

                // Run ww2ogg to convert the resulting RIFX to an OGG
                RunProgramSilently("Helpers/ww2ogg.exe",
                    string.Format("\"{0}\" -o \"{1}\" --pcb Helpers/packed_codebooks_aoTuV_603.bin", tempFile, outPath),
                    Directory.GetCurrentDirectory());

                // Run revorb to fix up the OGG
                RunProgramSilently("Helpers/revorb.exe", "\"" + outPath + "\"", Directory.GetCurrentDirectory());
            }
            finally
            {
                // Delete the old RIFX file
                if (File.Exists(tempFile))
                    File.Delete(tempFile);
            }
        }
		/// <summary>
		///     Processes the provided <paramref name="marker" /> in the stream held by
		///     <paramref name="reader" /> to determine the Endian setting of the stream.
		///     Advances the position in the stream by four bytes and returns a new
		///     binary reader to read the stream with the correct Endian setting.
		/// </summary>
		/// <returns>
		///     New BinaryReader for the stream.
		/// </returns>
		public static BinaryReader ProcessEndianMarker(this BinaryReader reader, uint marker)
		{
			var streamMarker = reader.ReadUInt32();

			if (streamMarker == marker)
			{
				return reader;
			}

			var swappedStreamMarker = (streamMarker << 24)
									  | ((streamMarker & 0x0000FF00) << 8)
									  | ((streamMarker & 0x00FF0000) >> 8)
									  | (streamMarker >> 24);

			if (swappedStreamMarker != marker)
			{
				throw new IOException($"Endian stream marker mismatch: received 0x{streamMarker.ToString("x8")}, expected 0x{marker.ToString("x8")}.");
			}

			var result = new EndianReader(reader);
			var source = reader as EndianReader;

			result.Endian = source != null ? source.Endian.Switch : Endian.NonNative;

			return result;
		}
 /// <summary>
 /// Extracts the raw contents of a sound to a file.
 /// </summary>
 /// <param name="reader">The stream to read from.</param>
 /// <param name="offset">The offset of the data to extract.</param>
 /// <param name="size">The size of the data to extract.</param>
 /// <param name="outPath">The path of the file to save to.</param>
 public static void ExtractRaw(EndianReader reader, int offset, int size, string outPath)
 {
     using (EndianWriter output = new EndianWriter(File.OpenWrite(outPath), EndianFormat.BigEndian))
     {
         // Just copy the data over to the output stream
         reader.SeekTo(offset);
         StreamUtil.Copy(reader, output, size);
     }
 }
Beispiel #10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EndianStream"/> class.
        /// </summary>
        /// <param name="stream">The stream to read from and write to.</param>
        /// <param name="endianness">The initial endianness to use when operating on the stream.</param>
        /// <exception cref="System.ArgumentException">Thrown if <paramref name="stream"/> is not both readable and writable.</exception>
        public EndianStream(Stream stream, Endian endianness)
        {
            if (!stream.CanRead || !stream.CanWrite)
                throw new ArgumentException("The input stream must be both readable and writable.");

            _stream = stream;
            _reader = new EndianReader(stream, endianness);
            _writer = new EndianWriter(stream, endianness);
        }
Beispiel #11
0
        public static void Copy(EndianReader input, EndianWriter output)
        {
            const int BufferSize = 0x1000;

            var buffer = new byte[BufferSize];
            int read;

            while ((read = input.ReadBlock(buffer, 0, BufferSize)) > 0)
                output.WriteBlock(buffer, 0, read);
        }
Beispiel #12
0
        /// <summary>
        /// Constructs a new EndianStream based off of a Stream object.
        /// </summary>
        /// <param name="stream">The Stream to use. It must at least be available for reading or writing.</param>
        /// <param name="endianness">The endianness to use when performing I/O operations.</param>
        public EndianStream(Stream stream, Endian endianness)
        {
            _stream = stream;
            if (stream.CanRead)
                _reader = new EndianReader(stream, endianness);
            if (stream.CanWrite)
                _writer = new EndianWriter(stream, endianness);

            if (_reader == null && _writer == null)
                throw new ArgumentException("The input stream cannot be read from or written to.");
        }
Beispiel #13
0
        public void Load(string filePath)
        {
            // Open Film
            FilmPath = filePath;
            var stream = new EndianReader(new FileStream(FilmPath, FileMode.Open), Endian.BigEndian);

            ValidateFilm(stream);

            LoadPlayerTable(stream);

            stream.Close();
        }
        public H2VistaMapPointerReader(ProcessMemoryStream stream)
        {
            // Get the base address of the process's main module
            // All addresses have to be based off of this because the game
            // randomizes its address space
            _baseAddress = (long) stream.BaseProcess.MainModule.BaseAddress;

            var reader = new EndianReader(stream, BitConverter.IsLittleEndian ? Endian.LittleEndian : Endian.BigEndian);
            FindMapHeader(reader);
            ReadMapPointers(reader);
            ReadMapHeader(reader);
            ProcessMapHeader();
        }
Beispiel #15
0
        public static CacheFile GetCache(string Filename)
        {
            CacheFile retCache = null;
            using (var fs = new FileStream(Filename, FileMode.Open, FileAccess.Read))
            {
                var Reader = new EndianReader((Stream)fs, EndianFormat.Big);

                var head = Reader.ReadInt32();
                if (head == 1684104552) Reader.Format = EndianFormat.Little;
                var v = Reader.ReadInt32();

                switch (v)
                {
                    case 5:   //H1X
                    case 7:   //HPC
                    case 609: //HCE
                        Reader.SeekTo(64);
                        break;
                    case 8:   //H2?
                        Reader.SeekTo(36);
                        switch (Reader.ReadInt32())
                        {
                            case 0: //H2X
                                Reader.SeekTo(288);
                                break;
                            case -1: //H2V
                                Reader.SeekTo(300);
                                break;
                        }
                        break;
                    default:  //360
                        Reader.SeekTo(284);
                        break;
                }

                var build = Reader.ReadString(32);
                var node = CacheFile.GetBuildNode(build);
                switch (node.Attributes["definitions"].Value)
                {
                    case "Halo3": retCache = new Halo3.CacheFile(Filename, build); break;
                    case "HaloODST":   retCache = new HaloODST.CacheFile(Filename, build); break;
                }
            }

            if (retCache != null)
            {
                retCache.LoadPlayZone();
                return retCache;
            }
            else throw new NotSupportedException("Cache version is unknown, unsupported or invalid.");
        }
 /// <summary>
 /// Extracts an xWMA sound and converts it to another format.
 /// </summary>
 /// <param name="reader">The stream to read from.</param>
 /// <param name="offset">The offset of the data to extract.</param>
 /// <param name="rifx">The RIFX data for the sound.</param>
 /// <param name="outPath">The path of the file to save to. The file extension will determine the output format.</param>
 public static void ExtractAndConvertXWMA(EndianReader reader, int offset, RIFX rifx, string outPath)
 {
     // Extract a WAV to a temporary file and then convert it
     string tempPath = Path.GetTempFileName();
     try
     {
         ExtractXWMAToWAV(reader, offset, rifx, tempPath);
         ConvertFile(tempPath, outPath);
     }
     finally
     {
         // Delete the temporary file
         if (File.Exists(tempPath))
             File.Delete(tempPath);
     }
 }
        public void BinaryWriterCompatible_NativeEndian()
        {
            var stream = new MemoryStream();
            var writer = new BinaryWriter(stream);
            var reader = new EndianReader(stream);

            foreach (TestValue value in _testValuesWithBits)
            {
                value.Write(writer);
            }

            writer.Flush();
            stream.Position = 0;

            foreach (TestValue value in _testValuesWithBits)
            {
                value.Read(reader);
            }
        }
Beispiel #18
0
 public EndianIO(string fileName, EndianType endiantype, bool Open, bool IsNewFile)
 {
     EndianType = endiantype;
     FileName = fileName;
     var mode = IsNewFile ? FileMode.Create : FileMode.Open;
     try
     {
         Stream = new FileStream(FileName, mode);
         Reader = new EndianReader(Stream, EndianType);
         Writer = new EndianWriter(Stream, EndianType);
         if (!Open)
         {
             Close();
         }
     }
     catch
     {
     }
 }
            public BitmapData(EndianReader Reader, int Address)
            {
                Reader.SeekTo(Address);

                Class = Reader.ReadString(4);
                Width = Reader.ReadUInt16();
                Height = Reader.ReadUInt16();
                Depth = Reader.ReadUInt16();
                //Flags = new Bitmask(Reader.ReadByte());
                Type = (BitmapType)Reader.ReadUInt16();
                Format = (BitmapFormat)Reader.ReadUInt16();
                Flags = new Bitmask(Reader.ReadUInt16());
                RegX = Reader.ReadUInt16();
                RegY = Reader.ReadUInt16();
                MipmapCount = Reader.ReadInt32();
                PixelsOffset = Reader.ReadInt32();
                PixelsSize = Reader.ReadInt32();

                Reader.SeekTo(Address + 48);
            }
Beispiel #20
0
        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                FileStream stream = new FileStream(ofd.FileName, FileMode.Open);
                EndianReader reader = new EndianReader(stream, EndianType.BigEndian);
                EndianWriter writer = new EndianWriter(stream, EndianType.BigEndian);

                int CSum = 0;
                reader.BaseStream.Position = 0xD000;
                for (int i = 0; i < 0x768; i += 4)
                    CSum += reader.ReadInt32();

                writer.Write(CSum);
                writer.Flush();
                writer.Close();
                reader.Close();
                MessageBox.Show("New Checksum: " + CSum.ToString("X2"), "Done!");
            }
        }
        public bitmap(CacheBase Cache, int Address)
        {
            int magic = Cache.Magic;
            EndianReader Reader;

            if (Address < 0) //external bitmap
            {
                var fs = new FileStream(Cache.FilePath + "\\bitmaps.map", FileMode.Open, FileAccess.Read);
                Reader = new EndianReader(fs, EndianFormat.LittleEndian);

                Reader.SeekTo(8);
                var indexOffset = Reader.ReadInt32();
                var index = Address + Cache.Magic;

                Reader.SeekTo(indexOffset + 12 * index + 8);
                Address = Reader.ReadInt32();
                magic = -Address;
            }
            else Reader = Cache.Reader;

            #region BitmapData Chunk
            Reader.SeekTo(Address + 96);
            int iCount = Reader.ReadInt32();
            int iOffset = Reader.ReadInt32() - magic;
            for (int i = 0; i < iCount; i++)
                Bitmaps.Add(new BitmapData(Reader, iOffset + 48 * i));
            #endregion

            if (Reader != Cache.Reader)
            {
                Reader.Close();
                Reader.Dispose();

                //add flag so the GetRawFromID function
                //can tell that it's an external bitmap
                foreach (var bData in Bitmaps)
                    bData.PixelsOffset |= int.MinValue; //0x80000000
            }
        }
        public static ContinuationPacket ReadFrom(ArraySegment<byte> segment, int maxDataSize)
        {
            if (segment.Count < NoDataSize)
            {
                throw new InvalidPacketSizeException(segment,
                    $"Data is too small, expected {NoDataSize} bytes but provided only {segment.Count}");
            }

            var result = new ContinuationPacket();

            using (var stream = new MemoryStream(segment.Array, segment.Offset, segment.Count))
            {
                var reader = new EndianReader(stream, Endianness.BigEndian);
                result.ChannelIdentifier = reader.ReadUInt32();
                result.PaketSequence = reader.ReadByte();

                CheckSequence(segment, result.PaketSequence);
            }

            var remainingBytes = Math.Min(maxDataSize, segment.Count - NoDataSize);
            result.Data = new ArraySegment<byte>(segment.Array, segment.Offset + NoDataSize, remainingBytes);

            return result;
        }
Beispiel #23
0
 public SoundPathRandomRange(EndianReader reader)
 {
     HorizontalRange = reader.ReadSingle();
     VerticalRange   = reader.ReadSingle();
 }
Beispiel #24
0
            public LocaleTable(CacheBase Cache, Language Lang)
            {
                cache = Cache;
                EndianReader Reader = cache.Reader;
                CacheHeader  CH     = cache.Header;

                #region Get Info
                int matgOffset = -1;
                foreach (IndexItem item in cache.IndexItems)
                {
                    if (item.ClassCode == "matg")
                    {
                        matgOffset = item.Offset;
                        break;
                    }
                }

                if (matgOffset == -1)
                {
                    return;
                }

                int localeStart = int.Parse(cache.buildNode.Attributes["localesStart"].Value);
                Reader.SeekTo(matgOffset + localeStart + (int)Lang * int.Parse(cache.buildNode.Attributes["languageSize"].Value));

                int localeCount = Reader.ReadInt32();
                int tableSize   = Reader.ReadInt32();
                int indexOffset = Reader.ReadInt32() + CH.localeModifier;
                int tableOffset = Reader.ReadInt32() + CH.localeModifier;
                #endregion

                #region Read Indices
                Reader.SeekTo(indexOffset);
                int[] indices = new int[localeCount];
                for (int i = 0; i < localeCount; i++)
                {
                    this.Add("");
                    Reader.ReadInt32();
                    indices[i] = Reader.ReadInt32();
                }
                #endregion

                #region Read Names
                Reader.SeekTo(tableOffset);
                EndianReader newReader = (cache.localesKey == "" || cache.localesKey == null)
                    ? new EndianReader(new MemoryStream(Reader.ReadBytes(tableSize)), EndianFormat.BigEndian)
                    : AES.DecryptSegment(Reader, tableOffset, tableSize, cache.localesKey);

                for (int i = 0; i < indices.Length; i++)
                {
                    if (indices[i] == -1)
                    {
                        this[i] = "<null>";
                        continue;
                    }

                    newReader.SeekTo(indices[i]);

                    int length;
                    if (i == indices.Length - 1)
                    {
                        length = tableSize - indices[i];
                    }
                    else
                    {
                        length = (indices[i + 1] != -1)
                            ? indices[i + 1] - indices[i]
                            : indices[i + 2] - indices[i];
                    }

                    if (length == 1)
                    {
                        this[i] = "<blank>";
                        continue;
                    }

                    this[i] = newReader.ReadString(length);
                }
                newReader.Close();
                newReader.Dispose();
                #endregion
            }
Beispiel #25
0
        private ScenarioStructureBsp ConvertScenarioStructureBsp(ScenarioStructureBsp sbsp, CachedTagInstance instance, Dictionary <ResourceLocation, Stream> resourceStreams)
        {
            sbsp.CollisionBspResource = ConvertStructureBspTagResources(sbsp, resourceStreams);
            sbsp.PathfindingResource  = ConvertStructureBspCacheFileTagResources(sbsp, resourceStreams);

            sbsp.Unknown86 = 1;

            //
            // Set compatibility flag for H3 mopps
            //

            if (BlamCache.Version == CacheVersion.Halo3Retail)
            {
                sbsp.CompatibilityFlags = ScenarioStructureBsp.StructureBspCompatibilityValue.UseMoppIndexPatch;
            }
            else
            {
                sbsp.CompatibilityFlags = ScenarioStructureBsp.StructureBspCompatibilityValue.None;
            }

            //
            // Fix cluster tag ref and decorator grids
            //

            var resource = sbsp.Geometry.Resource;

            if (resource != null && resource.Page.Index >= 0 && resource.GetLocation(out var location))
            {
                var resourceContext = new ResourceSerializationContext(CacheContext, sbsp.Geometry.Resource);
                var definition      = CacheContext.Deserializer.Deserialize <RenderGeometryApiResourceDefinition>(resourceContext);

                using (var edResourceStream = new MemoryStream())
                    using (var edResourceReader = new EndianReader(edResourceStream, EndianFormat.LittleEndian))
                    {
                        var pageable = sbsp.Geometry.Resource;

                        if (pageable == null)
                        {
                            throw new ArgumentNullException("sbsp.Geometry.Resource");
                        }

                        if (!edResourceStream.CanWrite)
                        {
                            throw new ArgumentException("The output stream is not open for writing", "outStream");
                        }

                        pageable.GetLocation(out var resourceLocation);

                        var cache = CacheContext.GetResourceCache(resourceLocation);

                        if (!resourceStreams.ContainsKey(resourceLocation))
                        {
                            resourceStreams[resourceLocation] = FlagIsSet(PortingFlags.Memory) ?
                                                                new MemoryStream() :
                                                                (Stream)CacheContext.OpenResourceCacheReadWrite(resourceLocation);

                            if (FlagIsSet(PortingFlags.Memory))
                            {
                                using (var resourceStream = CacheContext.OpenResourceCacheRead(resourceLocation))
                                    resourceStream.CopyTo(resourceStreams[resourceLocation]);
                            }
                        }

                        cache.Decompress(resourceStreams[resourceLocation], pageable.Page.Index, pageable.Page.CompressedBlockSize, edResourceStream);

                        var inVertexStream = VertexStreamFactory.Create(CacheVersion.HaloOnline106708, edResourceStream);

                        foreach (var cluster in sbsp.Clusters)
                        {
                            List <ScenarioStructureBsp.Cluster.DecoratorGrid> newDecoratorGrids = new List <ScenarioStructureBsp.Cluster.DecoratorGrid>();

                            foreach (var grid in cluster.DecoratorGrids)
                            {
                                grid.DecoratorGeometryIndex_HO = grid.DecoratorGeometryIndex_H3;
                                grid.DecoratorIndex_HO         = grid.DecoratorIndex_H3;

                                if (grid.Amount == 0)
                                {
                                    newDecoratorGrids.Add(grid);
                                }
                                else
                                {
                                    List <TinyPositionVertex> vertices = new List <TinyPositionVertex>();

                                    // Get the buffer the right grid
                                    var vertexBuffer = definition.VertexBuffers[grid.DecoratorGeometryIndex_HO].Definition;
                                    // Get the offset from the grid
                                    edResourceStream.Position = vertexBuffer.Data.Address.Offset + grid.DecoratorGeometryOffset;
                                    // Read all vertices and add to the list
                                    for (int i = 0; i < grid.Amount; i++)
                                    {
                                        vertices.Add(inVertexStream.ReadTinyPositionVertex());
                                    }

                                    // Get the new grids
                                    List <ScenarioStructureBsp.Cluster.DecoratorGrid> newGrids = ConvertDecoratorGrid(vertices, grid);

                                    // Add all to list
                                    foreach (var newGrid in newGrids)
                                    {
                                        newDecoratorGrids.Add(newGrid);
                                    }
                                }
                            }

                            cluster.DecoratorGrids = newDecoratorGrids;
                        }
                    }
            }

            //
            // Temporary Fixes:
            //

            // Without this 005_intro crash on cortana sbsp
            sbsp.Geometry2.UnknownSections = new List <RenderGeometry.UnknownSection>();

            return(sbsp);
        }
Beispiel #26
0
 public void ReadHash(EndianReader reader)
 {
     Index = reader.ReadUInt64();
     reader.Read(Hash, 0, 0x14);
     HashZero = reader.ReadUInt32();
 }
Beispiel #27
0
 /// <summary>
 /// Reads a DatumIndex from a EndianReader and returns it.
 /// </summary>
 /// <param name="reader">The EndianReader to read from.</param>
 /// <returns>The DatumIndex that was read.</returns>
 public static DatumIndex ReadFrom(EndianReader reader)
 {
     return(new DatumIndex(reader.ReadUInt32()));
 }
        public scenario_structure_bsp(CacheBase Cache, int Address)
        {
            cache = Cache;
            EndianReader Reader = Cache.Reader;
            Reader.SeekTo(Address);

            #region sldt ID
            //sldt's sections address will be used instead of the one in sbsp
            int sectionAddress = 0;
            foreach (var item in Cache.IndexItems)
            {
                if (item.ClassCode == "scnr")
                {
                    Reader.SeekTo(item.Offset + 12);
                    int cnt = Reader.ReadInt32();
                    int ptr = Reader.ReadInt32() - Cache.Magic;

                    int bspIndex = 0;

                    for (int i = 0; i < cnt; i++)
                    {
                        Reader.SeekTo(ptr + 104 * i + 12);
                        if (Cache.IndexItems.GetItemByID(Reader.ReadInt32()).Offset == Address)
                        {
                            bspIndex = i;
                            break;
                        }
                    }

                    Reader.SeekTo(item.Offset + 1720 + 12);
                    int sldtID = Reader.ReadInt32();
                    int sldtAddress = Cache.IndexItems.GetItemByID(sldtID).Offset;

                    Reader.SeekTo(sldtAddress + 4);
                    cnt = Reader.ReadInt32();
                    ptr = Reader.ReadInt32() - Cache.Magic;

                    for (int i = 0; i < cnt; i++)
                    {
                        Reader.SeekTo(ptr + 436 * i + 2);

                        if (Reader.ReadInt16() != bspIndex) continue;

                        Reader.SeekTo(ptr + 436 * i + 312);
                        sectionAddress = Reader.ReadInt32() - Cache.Magic;

                        Reader.SeekTo(ptr + 436 * i + 428);
                        geomRawID = Reader.ReadInt32();
                    }

                    break;
                }
            }
            #endregion

            Reader.SeekTo(Address + 60);
            XBounds = new RealBounds(Reader.ReadSingle(), Reader.ReadSingle());
            YBounds = new RealBounds(Reader.ReadSingle(), Reader.ReadSingle());
            ZBounds = new RealBounds(Reader.ReadSingle(), Reader.ReadSingle());

            #region Clusters Block
            Reader.SeekTo(Address + 180);
            int iCount = Reader.ReadInt32();
            int iOffset = Reader.ReadInt32() - Cache.Magic;
            for (int i = 0; i < iCount; i++)
                Clusters.Add(new Cluster(Cache, iOffset + 236 * i));
            #endregion

            #region Shaders Block
            Reader.SeekTo(Address + 192);
            iCount = Reader.ReadInt32();
            iOffset = Reader.ReadInt32() - Cache.Magic;
            for (int i = 0; i < iCount; i++)
                Shaders.Add(new Halo3Beta.render_model.Shader(Cache, iOffset + 36 * i));
            #endregion

            #region GeometryInstances Block
            Reader.SeekTo(Address + 432);
            iCount = Reader.ReadInt32();
            iOffset = Reader.ReadInt32() - Cache.Magic;
            for (int i = 0; i < iCount; i++)
                GeomInstances.Add(new InstancedGeometry(Cache, iOffset + 120 * i));
            #endregion

            Reader.SeekTo(Address + 580);
            RawID1 = Reader.ReadInt32();

            #region ModelSections Block
            Reader.SeekTo(Address + 740);
            iCount = Reader.ReadInt32();
            iOffset = Reader.ReadInt32() - Cache.Magic;
            for (int i = 0; i < iCount; i++)
                ModelSections.Add(new Halo3Beta.render_model.ModelSection(Cache, sectionAddress + 76 * i));
            #endregion

            #region BoundingBox Block
            Reader.SeekTo(Address + 752);
            iCount = Reader.ReadInt32();
            iOffset = Reader.ReadInt32() - Cache.Magic;
            for (int i = 0; i < iCount; i++)
                BoundingBoxes.Add(new Halo3Beta.render_model.BoundingBox(Cache, iOffset + 44 * i));
            #endregion

            Reader.SeekTo(Address + 860);
            RawID2 = Reader.ReadInt32();

            Reader.SeekTo(Address + 892);
            RawID3 = Reader.ReadInt32();
        }
Beispiel #29
0
            public IndexTable(CacheBase Cache)
            {
                cache = Cache;

                var IH     = cache.IndexHeader;
                var CH     = cache.Header;
                var Reader = cache.Reader;

                ClassList = new List <TagClass>();

                #region Read Class List

                Reader.SeekTo(IH.tagClassIndexOffset);
                for (int i = 0; i < IH.tagClassCount; i++)
                {
                    TagClass tc = new TagClass();
                    tc.ClassCode = Reader.ReadString(4);
                    tc.Parent    = Reader.ReadString(4);
                    tc.Parent2   = Reader.ReadString(4);
                    tc.StringID  = Reader.ReadInt32();
                    ClassList.Add(tc);
                }
                #endregion

                #region Read Tags' Info
                Reader.SeekTo(IH.tagInfoOffset);
                for (int i = 0; i < IH.tagCount; i++)
                {
                    IndexItem item = new IndexItem()
                    {
                        Cache = cache
                    };
                    item.ClassIndex = Reader.ReadInt16();
                    item.ID         = (Reader.ReadInt16() << 16) | i;
                    item.Offset     = Reader.ReadInt32() - cache.Magic;
                    item.metaIndex  = i;
                    this.Add(item);
                }
                #endregion

                #region Read Indices
                Reader.SeekTo(CH.fileTableIndexOffset);
                int[] indices = new int[IH.tagCount];
                for (int i = 0; i < IH.tagCount; i++)
                {
                    indices[i] = Reader.ReadInt32();
                }
                #endregion

                #region Read Names
                Reader.SeekTo(CH.fileTableOffset);
                EndianReader newReader = (cache.tagsKey == "" || cache.tagsKey == null)
                    ? new EndianReader(new MemoryStream(Reader.ReadBytes(CH.fileTableSize)), EndianFormat.BigEndian)
                    : AES.DecryptSegment(Reader, CH.fileTableOffset, CH.fileTableSize, cache.tagsKey);

                for (int i = 0; i < indices.Length; i++)
                {
                    if (indices[i] == -1)
                    {
                        this[i].Filename = "<null>";
                        continue;
                    }

                    newReader.SeekTo(indices[i]);

                    int length;
                    if (i == indices.Length - 1)
                    {
                        length = CH.fileTableSize - indices[i];
                    }
                    else
                    {
                        if (indices[i + 1] == -1)
                        {
                            int index = -1;

                            for (int j = i + 1; j < indices.Length; j++)
                            {
                                if (indices[j] != -1)
                                {
                                    index = j;
                                    break;
                                }
                            }

                            length = (index == -1) ? CH.fileTableSize - indices[i] : indices[index] - indices[i];
                        }
                        else
                        {
                            length = indices[i + 1] - indices[i];
                        }
                    }

                    if (length == 1)
                    {
                        this[i].Filename = "<blank>";
                        continue;
                    }

                    if (length < 0)
                    {
                        int i0 = indices[i];
                        int i1 = indices[i + 1];
                        int i2 = indices[i + 2];
                        int i3 = indices[i + 3];
                    }

                    this[i].Filename = newReader.ReadString(length);
                }

                newReader.Close();
                newReader.Dispose();
                #endregion
            }
Beispiel #30
0
        public void GetRmt2Info(Stream cacheStream)
        {
            if (Rmt2TagsInfo.Count != 0)
            {
                return;
            }

            if (!cacheStream.CanRead)
            {
                Console.Write("Waiting for cache stream to become available...");
                while (!cacheStream.CanRead)
                {
                    ;
                }
                Console.Write("done.");
            }

            using (var reader = new EndianReader(cacheStream, true))
            {
                foreach (var instance in CacheContext.TagCache.TagTable)
                {
                    if (instance == null || !instance.IsInGroup("rmt2") || instance.Name == null || instance.Name.StartsWith("s3d"))
                    {
                        continue;
                    }

                    if (!UseMS30 && instance.Name.StartsWith("ms30"))
                    {
                        continue;
                    }

                    var bitmaps   = new List <string>();
                    var arguments = new List <string>();

                    var hoInstance = (CachedTagHaloOnline)instance;

                    reader.SeekTo(hoInstance.HeaderOffset + hoInstance.DefinitionOffset + 0x48);
                    var vectorArgsCount   = reader.ReadInt32();
                    var vectorArgsAddress = reader.ReadUInt32();

                    if (vectorArgsCount != 0 && vectorArgsAddress != 0)
                    {
                        for (var i = 0; i < vectorArgsCount; i++)
                        {
                            reader.SeekTo(hoInstance.HeaderOffset + (vectorArgsAddress - 0x40000000) + (i * 0x4));
                            arguments.Add(CacheContext.StringTable.GetString(reader.ReadStringId()));
                        }
                    }

                    reader.SeekTo(hoInstance.HeaderOffset + hoInstance.DefinitionOffset + 0x6C);
                    var samplerArgsCount   = reader.ReadInt32();
                    var samplerArgsAddress = reader.ReadUInt32();

                    if (samplerArgsCount != 0 && samplerArgsAddress != 0)
                    {
                        for (var i = 0; i < samplerArgsCount; i++)
                        {
                            reader.SeekTo(hoInstance.HeaderOffset + (samplerArgsAddress - 0x40000000) + (i * 0x4));
                            bitmaps.Add(CacheContext.StringTable.GetString(reader.ReadStringId()));
                        }
                    }

                    Rmt2TagsInfo.Add(instance.Index, new List <List <string> > {
                        bitmaps, arguments
                    });
                }
            }
        }
        public override byte[] GetSoundRaw(int ID, int size)
        {
            var Entry = zone.RawEntries[ID & ushort.MaxValue];

            if (Entry.SegmentIndex == -1) throw new InvalidDataException("Raw data not found.");

            var segment = play.Segments[Entry.SegmentIndex];
            var sRaw = play.SoundRawChunks[segment.SoundRawIndex];
            var reqPage = play.Pages[segment.RequiredPageIndex];
            var optPage = play.Pages[segment.OptionalPageIndex];

            if (size == 0) size = (reqPage.CompressedSize != 0) ? reqPage.CompressedSize : optPage.CompressedSize;

            var reqSize = size - sRaw.RawSize;
            var optSize = size - reqSize;

            //if (reqPage.CompressedSize != reqPage.DecompressedSize || optPage.CompressedSize != optPage.DecompressedSize)
            //    throw new Exception("COMPRESSED DATA");

            //if (sRaw.Sizes.Count > 1)
            //    throw new Exception("MULTIPLE SEGMENTS");

            byte[] buffer;
            byte[] data = new byte[size];
            int offset;
            EndianReader er;
            string fName = "";

            #region REQUIRED
            if (reqSize > 0)
            {
                if (reqPage.CacheIndex != -1)
                {
                    fName = play.SharedCaches[reqPage.CacheIndex].FileName;
                    fName = fName.Substring(fName.LastIndexOf('\\'));
                    fName = FilePath + fName;

                    if (fName == Filename)
                        er = Reader;
                    else
                        er = new EndianReader(new FileStream(fName, FileMode.Open, FileAccess.Read), EndianFormat.BigEndian);
                }
                else
                    er = Reader;

                er.SeekTo(1136);
                offset = reqPage.RawOffset + er.ReadInt32();

                er.SeekTo(offset);
                buffer = er.ReadBytes(reqPage.CompressedSize);

                Array.Copy(buffer, segment.RequiredPageOffset, data, 0, reqSize);

                if (er != Reader)
                {
                    er.Close();
                    er.Dispose();
                }
            }
            #endregion

            #region OPTIONAL
            if (segment.OptionalPageIndex != -1 && optSize > 0)
            {
                if (optPage.CacheIndex != -1)
                {
                    fName = play.SharedCaches[optPage.CacheIndex].FileName;
                    fName = fName.Substring(fName.LastIndexOf('\\'));
                    fName = FilePath + fName;

                    if (fName == Filename)
                        er = Reader;
                    else
                        er = new EndianReader(new FileStream(fName, FileMode.Open, FileAccess.Read), EndianFormat.BigEndian);
                }
                else
                    er = Reader;

                er.SeekTo(1136);
                offset = optPage.RawOffset + er.ReadInt32();

                er.SeekTo(offset);
                buffer = er.ReadBytes(optPage.CompressedSize);

                if (buffer.Length > data.Length)
                    data = buffer;
                else
                    Array.Copy(buffer, segment.OptionalPageOffset, data, reqSize, optSize);

                if (er != Reader)
                {
                    er.Close();
                    er.Dispose();
                }
            }
            #endregion

            return data;
        }
Beispiel #32
0
        static void Main(string[] args)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Title = "Open Cache File";
            ofd.Filter = "Blam Cache Files|*.map";
            if (ofd.ShowDialog() != DialogResult.OK)
                return;

            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Title = "Save String Dump";
            sfd.Filter = "Text Files|*.txt";
            if (sfd.ShowDialog() != DialogResult.OK)
                return;

            string mapPath = ofd.FileName;
            string dumpPath = sfd.FileName;

            BuildInfoLoader loader = new BuildInfoLoader(@"Formats\SupportedBuilds.xml", "Formats");
            ICacheFile cacheFile;
            LocaleTable locales;
            using (IReader reader = new EndianReader(File.OpenRead(mapPath), Endian.BigEndian))
            {
                Console.WriteLine("Loading cache file...");
                cacheFile = CacheFileLoader.LoadCacheFile(reader, loader);

                Console.WriteLine("Loading locales...");
                locales = cacheFile.Languages[LocaleLanguage.English].LoadStrings(reader);
            }

            StreamWriter output = new StreamWriter(dumpPath);
            output.WriteLine("Input file: {0}.map", cacheFile.InternalName);
            output.WriteLine();

            // Sort locales by stringID
            List<Locale> localesById = new List<Locale>();
            foreach (Locale str in locales.Strings)
            {
                if (str != null)
                    localesById.Add(str);
            }
            localesById.Sort((x, y) => x.ID.Value.CompareTo(y.ID.Value));

            // Dump locales
            Console.WriteLine("Dumping locales...");
            output.WriteLine("---------------");
            output.WriteLine("English Locales");
            output.WriteLine("---------------");
            foreach (Locale str in localesById)
            {
                if (str != null)
                    output.WriteLine("{0} = \"{1}\"", str.ID, str.Value);
            }
            output.WriteLine();

            // Dump stringIDs
            Console.WriteLine("Dumping stringIDs...");
            output.WriteLine("---------");
            output.WriteLine("StringIDs");
            output.WriteLine("---------");
            int index = 0;
            foreach (string str in cacheFile.StringIDs)
            {
                if (str != null)
                    output.WriteLine("0x{0:X} = \"{1}\"", index, str);
                else
                    output.WriteLine("0x{0:X} = (null)", index);

                index++;
            }
            output.Close();

            Console.WriteLine("Done!");
        }
Beispiel #33
0
        private List <ShaderTemplateItem> CollectRmt2Info(Stream cacheStream, CachedTag bmRmt2Instance, List <string> bmMaps, List <string> bmArgs)
        {
            var edRmt2BestStats = new List <ShaderTemplateItem>();

            RenderMethodTemplate bmRmt2;
            PixelShader          bmPixl;

            using (var blamStream = BlamCache.OpenCacheRead())
            {
                bmRmt2 = BlamCache.Deserialize <RenderMethodTemplate>(blamStream, bmRmt2Instance);
                bmPixl = BlamCache.Deserialize <PixelShader>(blamStream, bmRmt2.PixelShader);
            }


            // loop trough all rmt2 and find the closest
            foreach (var edRmt2_ in Rmt2TagsInfo)
            {
                var rmt2Type = bmRmt2Instance.Name.Split("\\".ToArray())[1];

                var edRmt2Tag = (CachedTagHaloOnline)CacheContext.TagCache.GetTag(edRmt2_.Key);

                // Ignore all rmt2 that are not of the same type.
                if (edRmt2Tag == null || !(edRmt2Tag.Name?.Contains(rmt2Type) ?? false))
                {
                    continue;
                }

                using (var reader = new EndianReader(cacheStream, true))
                {
                    reader.SeekTo(edRmt2Tag.HeaderOffset + edRmt2Tag.DefinitionOffset + 28);
                    var edPixl = (CachedTagHaloOnline)CacheContext.TagCache.GetTag(reader.ReadInt32());

                    if (edPixl == null)
                    {
                        continue;
                    }

                    reader.SeekTo(edPixl.HeaderOffset + edPixl.DefinitionOffset + 0x4);
                    var drawModeCount = reader.ReadInt32();

                    reader.SeekTo(edPixl.HeaderOffset + edPixl.DefinitionOffset + 0x14);
                    var shaderCount = reader.ReadInt32();

                    if (bmPixl.DrawModes.Count > drawModeCount || bmPixl.Shaders.Count > shaderCount)
                    {
                        continue;
                    }
                }

                int mapsCommon   = 0;
                int argsCommon   = 0;
                int mapsUncommon = 0;
                int argsUncommon = 0;
                int mapsMissing  = 0;
                int argsMissing  = 0;

                var edMaps_ = new List <string>();
                var edArgs_ = new List <string>();

                foreach (var a in edRmt2_.Value[0])
                {
                    edMaps_.Add(a);
                }

                foreach (var a in edRmt2_.Value[1])
                {
                    edArgs_.Add(a);
                }

                foreach (var a in bmMaps)
                {
                    if (edMaps_.Contains(a))
                    {
                        mapsCommon++;
                    }
                }

                foreach (var a in bmMaps)
                {
                    if (!edMaps_.Contains(a))
                    {
                        mapsMissing++;
                    }
                }

                foreach (var a in edMaps_)
                {
                    if (!bmMaps.Contains(a))
                    {
                        mapsUncommon++;
                    }
                }

                foreach (var a in bmArgs)
                {
                    if (edArgs_.Contains(a))
                    {
                        argsCommon++;
                    }
                }

                foreach (var a in bmArgs)
                {
                    if (!edArgs_.Contains(a))
                    {
                        argsMissing++;
                    }
                }

                foreach (var a in edArgs_)
                {
                    if (!bmArgs.Contains(a))
                    {
                        argsUncommon++;
                    }
                }

                edRmt2BestStats.Add(new ShaderTemplateItem
                {
                    rmt2TagIndex            = edRmt2_.Key,
                    rmdfValuesMatchingCount = 0,
                    mapsCountEd             = edRmt2_.Value[0].Count,
                    argsCountEd             = edRmt2_.Value[1].Count,
                    mapsCountBm             = bmMaps.Count,
                    argsCountBm             = bmArgs.Count,
                    mapsCommon   = mapsCommon,
                    argsCommon   = argsCommon,
                    mapsUncommon = mapsUncommon,
                    argsUncommon = argsUncommon,
                    mapsMissing  = mapsMissing,
                    argsMissing  = argsMissing
                });
            }

            return(edRmt2BestStats);
        }
Beispiel #34
0
        public void TestFunctionParsing()
        {
            // This method is essentially test of the BytecodeEditor parser with the actual ui logic all removed
            GlobalTest.Init();

            // Loads compressed packages, save them uncompressed. Load package, save re-compressed, compare results
            var packagesPath = GlobalTest.GetTestPackagesDirectory();
            //var packages = Directory.GetFiles(packagesPath, "*.*", SearchOption.AllDirectories);
            var packages = Directory.GetFiles(packagesPath, "*.*", SearchOption.AllDirectories);

            foreach (var p in packages)
            {
                if (p.RepresentsPackageFilePath())
                {
                    (var game, var platform) = GlobalTest.GetExpectedTypes(p);

                    // Use to skip
                    //if (platform != MEPackage.GamePlatform.Xenon) continue;
                    //if (game != MEGame.ME1) continue;

                    Console.WriteLine($"Opening package {p}");

                    // Do not use package caching in tests
                    var originalLoadedPackage = MEPackageHandler.OpenMEPackage(p, forceLoadFromDisk: true);
                    foreach (var export in originalLoadedPackage.Exports.Where(x => x.ClassName == "Function" || x.ClassName == "State"))
                    {
                        //Console.WriteLine($" >> Decompiling {export.InstancedFullPath}");
                        var data    = export.Data;
                        var funcBin = ObjectBinary.From <UFunction>(export); //parse it out
                        if (export.FileRef.Game == MEGame.ME3 || export.FileRef.Platform == MEPackage.GamePlatform.PS3)
                        {
                            var func = new Function(data, export);
                            func.ParseFunction();
                            func.GetSignature();
                            if (export.ClassName == "Function")
                            {
                                var    nativeBackOffset = export.FileRef.Game < MEGame.ME3 ? 7 : 6;
                                var    pos         = data.Length - nativeBackOffset;
                                string flagStr     = func.GetFlags();
                                var    nativeIndex = EndianReader.ToInt16(data, pos, export.FileRef.Endian);
                                pos += 2;
                                var flags = EndianReader.ToInt16(data, pos, export.FileRef.Endian);
                            }
                            else
                            {
                                //State
                                //parse remaining
                                var footerstartpos = 0x20 + funcBin.ScriptStorageSize;
                                var footerdata     = data.Slice(footerstartpos, (int)data.Length - (footerstartpos));
                                var fpos           = 0;
                                //ScriptFooterBlocks.Add(new ScriptHeaderItem("Probemask?", "??", fpos + footerstartpos) { length = 8 });
                                fpos += 0x8;

                                //ScriptFooterBlocks.Add(new ScriptHeaderItem("Unknown 8 FF's", "??", fpos + footerstartpos) { length = 8 });
                                fpos += 0x8;

                                //ScriptFooterBlocks.Add(new ScriptHeaderItem("Label Table Offset", "??", fpos + footerstartpos) { length = 2 });
                                fpos += 0x2;

                                var stateFlagsBytes = footerdata.Slice(fpos, 0x4);
                                var stateFlags      = (StateFlags)EndianReader.ToInt32(stateFlagsBytes, 0, export.FileRef.Endian);
                                var names           = stateFlags.ToString().Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
                                fpos += 0x4;

                                var numMappedFunctions = EndianReader.ToInt32(footerdata, fpos, export.FileRef.Endian);
                                fpos += 4;
                                for (int i = 0; i < numMappedFunctions; i++)
                                {
                                    var name        = EndianReader.ToInt32(footerdata, fpos, export.FileRef.Endian);
                                    var uindex      = EndianReader.ToInt32(footerdata, fpos + 8, export.FileRef.Endian);
                                    var funcMapText = $"{export.FileRef.GetNameEntry(name)} => {export.FileRef.GetEntry(uindex)?.FullPath}()";
                                    fpos += 12;
                                }
                            }
                        }
                        else if (export.FileRef.Game == MEGame.ME1 || export.FileRef.Game == MEGame.ME2)
                        {
                            //Header
                            int pos = 16;

                            var nextItemCompilingChain = EndianReader.ToInt32(data, pos, export.FileRef.Endian);
                            //ScriptHeaderBlocks.Add(new ScriptHeaderItem("Next item in loading chain", nextItemCompilingChain, pos, nextItemCompilingChain > 0 ? export : null));

                            pos += 8;
                            nextItemCompilingChain = EndianReader.ToInt32(data, pos, export.FileRef.Endian);
                            //ScriptHeaderBlocks.Add(new ScriptHeaderItem("Children Probe Start", nextItemCompilingChain, pos, nextItemCompilingChain > 0 ? export : null));

                            pos += 8;
                            var line = EndianReader.ToInt32(data, pos, export.FileRef.Endian);
                            //ScriptHeaderBlocks.Add(new ScriptHeaderItem("Line", EndianReader.ToInt32(data, pos, export.FileRef.Endian), pos));

                            pos += 4;
                            //EndianReader.ToInt32(data, pos, export.FileRef.Endian)
                            //ScriptHeaderBlocks.Add(new ScriptHeaderItem("TextPos", EndianReader.ToInt32(data, pos, export.FileRef.Endian), pos));

                            pos += 4;
                            int scriptSize = EndianReader.ToInt32(data, pos, export.FileRef.Endian);
                            //ScriptHeaderBlocks.Add(new ScriptHeaderItem("Script Size", scriptSize, pos));
                            pos += 4;
                            var BytecodeStart = pos;
                            var func          = export.ClassName == "State" ? UE3FunctionReader.ReadState(export, data) : UE3FunctionReader.ReadFunction(export, data);
                            func.Decompile(new TextBuilder(), false); //parse bytecode

                            bool defined = func.HasFlag("Defined");
                            //if (defined)
                            //{
                            //    DecompiledScriptBlocks.Add(func.FunctionSignature + " {");
                            //}
                            //else
                            //{
                            //    //DecompiledScriptBlocks.Add(func.FunctionSignature);
                            //}
                            for (int i = 0; i < func.Statements.statements.Count; i++)
                            {
                                Statement s = func.Statements.statements[i];
                                s.SetPaddingForScriptSize(scriptSize);
                                if (s.Reader != null && i == 0)
                                {
                                    //Add tokens read from statement. All of them point to the same reader, so just do only the first one.
                                    s.Reader.ReadTokens.Select(x => x.ToBytecodeSingularToken(pos)).OrderBy(x => x.StartPos);
                                }
                            }

                            //if (defined)
                            //{
                            //    DecompiledScriptBlocks.Add("}");
                            //}

                            //Footer
                            pos = data.Length - (func.HasFlag("Net") ? 17 : 15);
                            string flagStr = func.GetFlags();
                            //ScriptFooterBlocks.Add(new ScriptHeaderItem("Native Index", EndianReader.ToInt16(data, pos, export.FileRef.Endian), pos));
                            pos += 2;

                            //ScriptFooterBlocks.Add(new ScriptHeaderItem("Operator Precedence", data[pos], pos));
                            pos++;

                            int functionFlags = EndianReader.ToInt32(data, pos, export.FileRef.Endian);
                            //ScriptFooterBlocks.Add(new ScriptHeaderItem("Flags", $"0x{functionFlags:X8} {flagStr}", pos));
                            pos += 4;

                            //if ((functionFlags & func._flagSet.GetMask("Net")) != 0)
                            //{
                            //ScriptFooterBlocks.Add(new ScriptHeaderItem("Unknown 1 (RepOffset?)", EndianReader.ToInt16(data, pos, export.FileRef.Endian), pos));
                            //pos += 2;
                            //}

                            int friendlyNameIndex = EndianReader.ToInt32(data, pos, export.FileRef.Endian);
                            var friendlyName      = export.FileRef.GetNameEntry(friendlyNameIndex);
                            //ScriptFooterBlocks.Add(new ScriptHeaderItem("Friendly Name", Pcc.GetNameEntry(friendlyNameIndex), pos) { length = 8 });
                            pos += 8;

                            //ME1Explorer.Unreal.Classes.Function func = new ME1Explorer.Unreal.Classes.Function(data, export.FileRef as ME1Package);
                            //try
                            //{
                            //    Function_TextBox.Text = func.ToRawText();
                            //}
                            //catch (Exception e)
                            //{
                            //    Function_TextBox.Text = "Error parsing function: " + e.Message;
                            //}
                        }
                        else
                        {
                            //Function_TextBox.Text = "Parsing UnrealScript Functions for this game is not supported.";
                        }
                    }
                    //}
                }
            }
        }
Beispiel #35
0
 public SoundPath(EndianReader reader)
 {
     FirstPointIndex = reader.ReadInt32();
     PointCount      = reader.ReadInt32();
 }
Beispiel #36
0
 public override void Read(EndianReader br)
 {
     R = br.ReadSingle();
     G = br.ReadSingle();
     B = br.ReadSingle();
 }
Beispiel #37
0
 public override void Read(EndianReader br, int Magic)
 {
     Read(br);
 }
Beispiel #38
0
		// Meta Sorting

		private void LoadPatch(bool isAlteration)
		{
			try
			{
				using (var reader = new EndianReader(File.OpenRead(txtApplyPatchFile.Text), Endian.LittleEndian))
				{
					string magic = reader.ReadAscii(4);
					reader.SeekTo(0);

					if (magic == "asmp")
					{
						// Load into UI
						reader.Endianness = Endian.BigEndian;
						currentPatch = AssemblyPatchLoader.LoadPatch(reader);
						txtApplyPatchAuthor.Text = currentPatch.Author;
						txtApplyPatchDesc.Text = currentPatch.Description;
						txtApplyPatchName.Text = currentPatch.Name;
						txtApplyPatchInternalName.Text = currentPatch.MapInternalName;
						//txtApplyPatchMapID.Text = currentPatch.MapID.ToString(CultureInfo.InvariantCulture);

						// Set Visibility
						PatchApplicationPatchExtra.Visibility =
							currentPatch.CustomBlfContent != null
								? Visibility.Visible
								: Visibility.Collapsed;
						ApplyPatchControls.Visibility = Visibility.Visible;
						btnExtractInfo.IsEnabled = true;
					}
					else
					{
						currentPatch = OldPatchLoader.LoadPatch(reader, isAlteration);
						txtApplyPatchAuthor.Text = currentPatch.Author;
						txtApplyPatchDesc.Text = currentPatch.Description;
						txtApplyPatchName.Text = "Ascension/Alteration Patch";
						txtApplyPatchInternalName.Text = "Ascension/Alteration Patch";

						ApplyPatchControls.Visibility = Visibility.Visible;
						PatchApplicationPatchExtra.Visibility = Visibility.Collapsed;
						btnExtractInfo.IsEnabled = false;
					}
				}

				// Set Screenshot
				if (currentPatch.Screenshot == null)
				{
					// Set default
					var source = new Uri(@"/Assembly;component/Metro/Images/super_patcher.png", UriKind.Relative);
					imgApplyPreview.Source = new BitmapImage(source);
				}
				else
				{
					var image = new BitmapImage();
					image.BeginInit();
					image.StreamSource = new MemoryStream(currentPatch.Screenshot);
					image.EndInit();
					imgApplyPreview.Source = image;
				}
			}
			catch (Exception ex)
			{
				MetroException.Show(ex);
			}
		}
        protected void LoadFixups()
        {
            var Entry = cache.zone.RawEntries[geomRawID & ushort.MaxValue];
            var reader = new EndianReader(new MemoryStream(cache.zone.FixupData), EndianFormat.BigEndian);

            reader.SeekTo(Entry.FixupOffset + (Entry.FixupSize - 24));
            int vCount = reader.ReadInt32();
            reader.Skip(8);
            int iCount = reader.ReadInt32();

            reader.SeekTo(Entry.FixupOffset);

            for (int i = 0; i < vCount; i++)
            {
                VertInfoList.Add(new mode.VertexBufferInfo()
                {
                    Offset = Entry.Fixups[i].Offset,
                    VertexCount = reader.ReadInt32(),
                    Unknown1 = reader.ReadInt32(),
                    DataLength = reader.ReadInt32(),
                    Unknown2 = reader.ReadInt32(), //blank from here so far
                    Unknown3 = reader.ReadInt32(),
                    Unknown4 = reader.ReadInt32(),
                    Unknown5 = reader.ReadInt32(),
                });
            }

            for (int i = 0; i < vCount; i++)
            {
                //assumed to be vertex related
                Unknown1List.Add(new mode.UnknownInfo1()
                {
                    Unknown1 = reader.ReadInt32(), //always 0 so far
                    Unknown2 = reader.ReadInt32(), //always 0 so far
                    Unknown3 = reader.ReadInt32(), //1350707457
                });
            }

            for (int i = 0; i < iCount; i++)
            {
                var data = new mode.IndexBufferInfo();
                data.Offset = Entry.Fixups[vCount * 2 + i].Offset;
                data.FaceFormat = reader.ReadInt32();

                //value exists only in reach beta and newer
                if (cache.Version >= DefinitionSet.HaloReachBeta) data.UnknownX = reader.ReadInt32();
                else data.UnknownX = -1;

                data.DataLength = reader.ReadInt32();
                data.Unknown0 = reader.ReadInt32(); //blank from here so far
                data.Unknown1 = reader.ReadInt32();
                data.Unknown2 = reader.ReadInt32();
                data.Unknown3 = reader.ReadInt32();

                IndexInfoList.Add(data);
            }

            for (int i = 0; i < iCount; i++)
            {
                //assumed to be index related
                Unknown2List.Add(new mode.UnknownInfo2()
                {
                    Unknown1 = reader.ReadInt32(), //always 0 so far
                    Unknown2 = reader.ReadInt32(), //always 0 so far
                    Unknown3 = reader.ReadInt32(), //1753688321
                });
            }

            for (int i = 0; i < 4; i++)
            {
                Unknown3List.Add(new mode.UnknownInfo3()
                {
                    Unknown1 = reader.ReadInt32(), //vCount in 3rd, iCount in 4th
                    Unknown2 = reader.ReadInt32(), //always 0 so far
                    Unknown3 = reader.ReadInt32(),
                });
            }

            reader.Close();
            reader.Dispose();
        }
Beispiel #40
0
        public override Bitmap DecodeImage(Stream stream, uint width, uint height)
        {
            Bitmap image = new Bitmap((int)width, (int)height);

            EndianReader reader = new EndianReader(stream, Endianness.BigEndian);

            for (int y = 0; y < height; y += 8)
            {
                for (int x = 0; x < width; x += 8)
                {
                    for (int y2 = 0; y2 < 8; y2 += 4)
                    {
                        for (int x2 = 0; x2 < 8; x2 += 4)
                        {
                            u16 c0   = reader.ReadUInt16();
                            u16 c1   = reader.ReadUInt16();
                            u32 bits = reader.ReadUInt32();
                            u8  b0   = (u8)((c0 & 0x1f) << 3);
                            u8  g0   = (u8)(((c0 >> 5) & 0x3f) << 2);
                            u8  r0   = (u8)(((c0 >> 11) & 0x1f) << 3);
                            u8  b1   = (u8)((c1 & 0x1f) << 3);
                            u8  g1   = (u8)(((c1 >> 5) & 0x3f) << 2);
                            u8  r1   = (u8)(((c1 >> 11) & 0x1f) << 3);
                            for (int y3 = 3; y3 >= 0; y3--)
                            {
                                for (int x3 = 3; x3 >= 0; x3--)
                                {
                                    int newx = x + x2 + x3;
                                    int newy = y + y2 + y3;
                                    if (newx >= width || newy >= height)
                                    {
                                        continue;
                                    }

                                    uint control = bits & 3;
                                    bits >>= 2;
                                    Color colour;
                                    switch (control)
                                    {
                                    case 0:
                                        colour = Color.FromArgb(255, r0, g0, b0);
                                        break;

                                    case 1:
                                        colour = Color.FromArgb(255, r1, g1, b1);
                                        break;

                                    case 2:
                                        if (c0 > c1)
                                        {
                                            colour = Color.FromArgb(255, (2 * r0 + r1) / 3, (2 * g0 + g1) / 3, (2 * b0 + b1) / 3);
                                        }
                                        else
                                        {
                                            colour = Color.FromArgb(255, (r0 + r1) / 2, (g0 + g1) / 2, (b0 + b1) / 2);
                                        }
                                        break;

                                    case 3:
                                        if (c0 > c1)
                                        {
                                            colour = Color.FromArgb(255, (r0 + 2 * r1) / 3, (g0 + 2 * g1) / 3, (b0 + 2 * b1) / 3);
                                        }
                                        else
                                        {
                                            colour = Color.FromArgb(255, 0, 0, 0);
                                        }
                                        break;

                                    default:
                                        continue;
                                    }

                                    image.SetPixel(newx, newy, colour);
                                }
                            }
                        }
                    }
                }
            }

            return(image);
        }
        public override void LoadRaw()
        {
            if (RawLoaded) return;

            var data = cache.GetRawFromID(geomRawID);

            var ms = new MemoryStream(data);
            var reader = new EndianReader(ms, EndianFormat.BigEndian);

            var validParts = new Dictionary<int, mode.ModelSection>();

            LoadFixups();

            #region Read Vertices
            for (int i = 0; i < ModelSections.Count; i++)
            {
                var section = ModelSections[i];
                if (section.Submeshes.Count == 0) continue;

                if (section.VertsIndex >= 0 && section.VertsIndex < VertInfoList.Count) reader.SeekTo(VertInfoList[section.VertsIndex].Offset);

                if (cache.vertexNode == null) throw new NotSupportedException("No vertex definitions found for " + cache.Version.ToString());

                #region Get Vertex Definition
                XmlNode formatNode = null;
                foreach (XmlNode node in cache.vertexNode.ChildNodes)
                {
                    if (Convert.ToInt32(node.Attributes["type"].Value, 16) == section.VertexFormat)
                    {
                        formatNode = node;
                        break;
                    }
                }

                if (formatNode == null) throw new NotSupportedException("Format " + section.VertexFormat.ToString() + " not found in definition for " + cache.Version.ToString());
                #endregion

                mode.ModelSection validPart;
                if (validParts.TryGetValue(section.VertsIndex, out validPart))
                {
                    section.Vertices = validPart.Vertices;
                    continue;
                }
                else
                    validParts.Add(section.VertsIndex, section);

                section.Vertices = new Vertex[VertInfoList[section.VertsIndex].VertexCount];

                #region Get Vertices
                for (int j = 0; j < VertInfoList[section.VertsIndex].VertexCount; j++)
                {
                    mode.BoundingBox bb;
                    section.Vertices[j] = new Vertex(reader, formatNode);
                    if (i >= BoundingBoxes.Count)
                    {
                        bb = new mode.BoundingBox();
                        bb.XBounds = bb.YBounds = bb.ZBounds =
                        bb.UBounds = bb.VBounds = new RealBounds(0, 0);
                    }
                    else
                        bb = BoundingBoxes[i];

                    ModelFunctions.DecompressVertex(ref section.Vertices[j], bb);
                }
                #endregion
            }
            #endregion

            validParts.Clear();

            #region Read Indices
            for (int i = 0; i < ModelSections.Count; i++)
            {
                var section = ModelSections[i];
                if (section.Submeshes.Count == 0) continue;

                if (section.FacesIndex >= 0 && section.FacesIndex < IndexInfoList.Count) reader.SeekTo(IndexInfoList[section.FacesIndex].Offset);

                mode.ModelSection validPart;
                if (validParts.TryGetValue(section.FacesIndex, out validPart))
                {
                    section.Indices = validPart.Indices;
                    continue;
                }
                else
                    validParts.Add(section.FacesIndex, section);

                section.Indices = new int[section.TotalFaceCount];
                for (int j = 0; j < section.TotalFaceCount; j++)
                    section.Indices[j] = (VertInfoList[section.VertsIndex].VertexCount > 0xFFFF) ? reader.ReadInt32() : reader.ReadUInt16();
            }
            #endregion

            RawLoaded = true;
        }
Beispiel #42
0
        public void Versions02(ByteOrder order)
        {
            var rng = new Random();

            using (var stream = new MemoryStream())
                using (var reader = new EndianReader(stream, order))
                    using (var writer = new EndianWriter(stream, order))
                    {
                        var rand = new object[5];

                        rand[0] = rng.Next(int.MinValue, int.MaxValue);
                        writer.Write((int)rand[0]);

                        writer.Write(0);

                        rand[1] = (float)rng.NextDouble();
                        writer.Write((float)rand[1]);

                        rand[2] = (float)rng.NextDouble();
                        writer.Write((float)rand[2]);

                        rand[3] = (float)rng.NextDouble();
                        writer.Write((float)rand[3]);

                        rand[4] = rng.NextDouble();
                        writer.Write((double)rand[4]);

                        stream.Position = 0;
                        var obj = (DataClass10)reader.ReadObject(typeof(DataClass10), 1);

                        Assert.AreEqual(rand[0], obj.Property1);
                        Assert.AreEqual(0, obj.Version);
                        Assert.AreEqual(rand[1], obj.Property2);
                        Assert.IsNull(obj.Property3);
                        Assert.IsNull(obj.Property4);

                        stream.Position = 0;
                        obj             = (DataClass10)reader.ReadObject(typeof(DataClass10), 2);

                        Assert.AreEqual(rand[0], obj.Property1);
                        Assert.AreEqual(0, obj.Version);
                        Assert.AreEqual(rand[2], obj.Property2);
                        Assert.AreEqual(rand[3], obj.Property3);
                        Assert.IsNull(obj.Property4);

                        stream.Position = 0;
                        obj             = (DataClass10)reader.ReadObject(typeof(DataClass10), 3);

                        Assert.AreEqual(rand[0], obj.Property1);
                        Assert.AreEqual(0, obj.Version);
                        Assert.AreEqual(rand[2], obj.Property2);
                        Assert.AreEqual(rand[3], obj.Property3);
                        Assert.IsNull(obj.Property4);

                        stream.Position = 0;
                        obj             = (DataClass10)reader.ReadObject(typeof(DataClass10), 4);

                        Assert.AreEqual(rand[0], obj.Property1);
                        Assert.AreEqual(0, obj.Version);
                        Assert.AreEqual(rand[2], obj.Property2);
                        Assert.IsNull(obj.Property3);
                        Assert.AreEqual(rand[4], obj.Property4);
                    }
        }
Beispiel #43
0
        public static void AssertBinary(ArraySegment <byte> actualBytes, Endianness endianess, params object[] expectedContent)
        {
            var str = SegmentToString(actualBytes);

            using (var stream = actualBytes.AsStream())
            {
                var reader = new EndianReader(stream, endianess);

                foreach (var expectedObject in expectedContent)
                {
                    var index = stream.Position;
                    var type  = expectedObject.GetType();
                    if (type == typeof(uint))
                    {
                        var expected = (uint)expectedObject;
                        var actual   = reader.ReadUInt32();
                        Check.That(actual).IsEqualTo(expected);
                    }
                    else if (type == typeof(ushort))
                    {
                        var expected = (ushort)expectedObject;
                        var actual   = reader.ReadUInt16();
                        Check.That(actual).IsEqualTo(expected);
                    }
                    else if (type == typeof(byte))
                    {
                        var expected = (byte)expectedObject;
                        var actual   = reader.ReadByte();
                        if (actual != expected)
                        {
                            throw new AssertionException(
                                      $"Byte at index {index} is 0x{actual:X2} but 0x{expected:X2} was expected.\r\n\r\n{str}");
                        }
                    }
                    else if (type == typeof(BytesHolder))
                    {
                        var holder = (BytesHolder)expectedObject;
                        reader.Read(holder.Bytes, 0, holder.ByteCount);
                    }
                    else if (type == typeof(ArraySegment <byte>))
                    {
                        var expected = (ArraySegment <byte>)expectedObject;
                        var actual   = new byte[expected.Count];
                        reader.Read(actual, 0, actual.Length);
                        Check.That(expected.ContentEquals(actual.Segment())).IsTrue();
                    }
                    else if (type == typeof(byte[]))
                    {
                        var expected = (byte[])expectedObject;
                        var actual   = new byte[expected.Length];
                        reader.Read(actual, 0, actual.Length);
                        if (!expected.Segment().ContentEquals(actual.Segment()))
                        {
                            var actualStr   = SegmentToString(actual.Segment());
                            var expectedStr = SegmentToString(expected.Segment());
                            throw new AssertionException($"The 2 binary data differ, expected: \r\n{expectedStr}\r\nRead:\r\n{actualStr}\r\nFull actual data:\r\n{str}");
                        }
                    }
                }
            }
        }
Beispiel #44
0
        public render_model(CacheBase Cache, int Address)
        {
            cache = Cache;
            EndianReader Reader = Cache.Reader;

            Reader.SeekTo(Address);

            Name  = Cache.Strings.GetItemByID(Reader.ReadInt32());
            Flags = new Bitmask(Reader.ReadInt32());

            #region Regions Block
            Reader.SeekTo(Address + 12);
            int iCount  = Reader.ReadInt32();
            int iOffset = Reader.ReadInt32() - Cache.Magic;
            for (int i = 0; i < iCount; i++)
            {
                Regions.Add(new Region(Cache, iOffset + 16 * i));
            }
            #endregion

            Reader.SeekTo(Address + 28);
            InstancedGeometryIndex = Reader.ReadInt32();

            #region Instanced Geometry Block
            Reader.SeekTo(Address + 32);
            iCount  = Reader.ReadInt32();
            iOffset = Reader.ReadInt32() - Cache.Magic;
            for (int i = 0; i < iCount; i++)
            {
                GeomInstances.Add(new InstancedGeometry(Cache, iOffset + 60 * i));
            }
            #endregion

            #region Nodes Block
            Reader.SeekTo(Address + 48);
            iCount  = Reader.ReadInt32();
            iOffset = Reader.ReadInt32() - Cache.Magic;
            for (int i = 0; i < iCount; i++)
            {
                Nodes.Add(new Node(Cache, iOffset + 112 * i));
            }
            #endregion

            #region MarkerGroups Block
            Reader.SeekTo(Address + 60);
            iCount  = Reader.ReadInt32();
            iOffset = Reader.ReadInt32() - Cache.Magic;
            for (int i = 0; i < iCount; i++)
            {
                MarkerGroups.Add(new MarkerGroup(Cache, iOffset + 16 * i));
            }
            #endregion

            #region Shaders Block
            Reader.SeekTo(Address + 72);
            iCount  = Reader.ReadInt32();
            iOffset = Reader.ReadInt32() - Cache.Magic;
            for (int i = 0; i < iCount; i++)
            {
                Shaders.Add(new Shader(Cache, iOffset + 44 * i));
            }
            #endregion

            #region ModelParts Block
            Reader.SeekTo(Address + 104);
            iCount  = Reader.ReadInt32();
            iOffset = Reader.ReadInt32() - Cache.Magic;
            for (int i = 0; i < iCount; i++)
            {
                ModelSections.Add(new ModelSection(Cache, iOffset + 112 * i));
            }
            #endregion

            #region BoundingBox Block
            Reader.SeekTo(Address + 128);
            iCount  = Reader.ReadInt32();
            iOffset = Reader.ReadInt32() - Cache.Magic;
            for (int i = 0; i < iCount; i++)
            {
                BoundingBoxes.Add(new BoundingBox(Cache, iOffset + 52 * i));
            }
            #endregion

            #region NodeMapGroup Block
            Reader.SeekTo(Address + 188);
            iCount  = Reader.ReadInt32();
            iOffset = Reader.ReadInt32() - Cache.Magic;
            for (int i = 0; i < iCount; i++)
            {
                NodeIndexGroups.Add(new NodeIndexGroup(Cache, iOffset + 12 * i));
            }
            #endregion

            Reader.SeekTo(Address + 248);
            RawID = Reader.ReadInt32();
        }
Beispiel #45
0
 internal override void DeserializeData(EndianReader reader)
 {
     Flags = reader.ReadUInt32LE();
 }
Beispiel #46
0
        public override object Execute(List <string> args)
        {
            // Deserialize the definition data
            var resourceContext = new ResourceSerializationContext(CacheContext, BSP.CollisionBspResource);
            var definition      = CacheContext.Deserializer.Deserialize <StructureBspTagResources>(resourceContext);

            // Extract the resource data
            var resourceDataStream = new MemoryStream();

            CacheContext.ExtractResource(BSP.CollisionBspResource, resourceDataStream);

            using (var reader = new EndianReader(resourceDataStream))
            {
                #region collision bsps

                foreach (var cbsp in definition.CollisionBsps)
                {
                    reader.BaseStream.Position = cbsp.Bsp3dNodes.Address.Offset;
                    for (var i = 0; i < cbsp.Bsp3dNodes.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Bsp3dNode));
                        cbsp.Bsp3dNodes.Add((CollisionGeometry.Bsp3dNode)element);
                    }

                    reader.BaseStream.Position = cbsp.Planes.Address.Offset;
                    for (var i = 0; i < cbsp.Planes.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Plane));
                        cbsp.Planes.Add((CollisionGeometry.Plane)element);
                    }

                    reader.BaseStream.Position = cbsp.Leaves.Address.Offset;
                    for (var i = 0; i < cbsp.Leaves.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Leaf));
                        cbsp.Leaves.Add((CollisionGeometry.Leaf)element);
                    }

                    reader.BaseStream.Position = cbsp.Bsp2dReferences.Address.Offset;
                    for (var i = 0; i < cbsp.Bsp2dReferences.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Bsp2dReference));
                        cbsp.Bsp2dReferences.Add((CollisionGeometry.Bsp2dReference)element);
                    }

                    reader.BaseStream.Position = cbsp.Bsp2dNodes.Address.Offset;
                    for (var i = 0; i < cbsp.Bsp2dNodes.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Bsp2dNode));
                        cbsp.Bsp2dNodes.Add((CollisionGeometry.Bsp2dNode)element);
                    }

                    reader.BaseStream.Position = cbsp.Surfaces.Address.Offset;
                    for (var i = 0; i < cbsp.Surfaces.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Surface));
                        cbsp.Surfaces.Add((CollisionGeometry.Surface)element);
                    }

                    reader.BaseStream.Position = cbsp.Edges.Address.Offset;
                    for (var i = 0; i < cbsp.Edges.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Edge));
                        cbsp.Edges.Add((CollisionGeometry.Edge)element);
                    }

                    reader.BaseStream.Position = cbsp.Vertices.Address.Offset;
                    for (var i = 0; i < cbsp.Vertices.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Vertex));
                        cbsp.Vertices.Add((CollisionGeometry.Vertex)element);
                    }
                }

                #endregion

                #region large collision bsps

                foreach (var cbsp in definition.LargeCollisionBsps)
                {
                    reader.BaseStream.Position = cbsp.Bsp3dNodes.Address.Offset;
                    for (var i = 0; i < cbsp.Bsp3dNodes.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(StructureBspTagResources.LargeCollisionBspBlock.Bsp3dNode));
                        cbsp.Bsp3dNodes.Add((StructureBspTagResources.LargeCollisionBspBlock.Bsp3dNode)element);
                    }

                    reader.BaseStream.Position = cbsp.Planes.Address.Offset;
                    for (var i = 0; i < cbsp.Planes.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Plane));
                        cbsp.Planes.Add((CollisionGeometry.Plane)element);
                    }

                    reader.BaseStream.Position = cbsp.Leaves.Address.Offset;
                    for (var i = 0; i < cbsp.Leaves.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Leaf));
                        cbsp.Leaves.Add((CollisionGeometry.Leaf)element);
                    }

                    reader.BaseStream.Position = cbsp.Bsp2dReferences.Address.Offset;
                    for (var i = 0; i < cbsp.Bsp2dReferences.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(StructureBspTagResources.LargeCollisionBspBlock.Bsp2dReference));
                        cbsp.Bsp2dReferences.Add((StructureBspTagResources.LargeCollisionBspBlock.Bsp2dReference)element);
                    }

                    reader.BaseStream.Position = cbsp.Bsp2dNodes.Address.Offset;
                    for (var i = 0; i < cbsp.Bsp2dNodes.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(StructureBspTagResources.LargeCollisionBspBlock.Bsp2dNode));
                        cbsp.Bsp2dNodes.Add((StructureBspTagResources.LargeCollisionBspBlock.Bsp2dNode)element);
                    }

                    reader.BaseStream.Position = cbsp.Surfaces.Address.Offset;
                    for (var i = 0; i < cbsp.Surfaces.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(StructureBspTagResources.LargeCollisionBspBlock.Surface));
                        cbsp.Surfaces.Add((StructureBspTagResources.LargeCollisionBspBlock.Surface)element);
                    }

                    reader.BaseStream.Position = cbsp.Edges.Address.Offset;
                    for (var i = 0; i < cbsp.Edges.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(StructureBspTagResources.LargeCollisionBspBlock.Edge));
                        cbsp.Edges.Add((StructureBspTagResources.LargeCollisionBspBlock.Edge)element);
                    }

                    reader.BaseStream.Position = cbsp.Vertices.Address.Offset;
                    for (var i = 0; i < cbsp.Vertices.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(StructureBspTagResources.LargeCollisionBspBlock.Vertex));
                        cbsp.Vertices.Add((StructureBspTagResources.LargeCollisionBspBlock.Vertex)element);
                    }
                }

                #endregion

                #region compressions

                foreach (var instance in definition.InstancedGeometry)
                {
                    #region compression's resource data

                    reader.BaseStream.Position = instance.CollisionInfo.Bsp3dNodes.Address.Offset;
                    for (var i = 0; i < instance.CollisionInfo.Bsp3dNodes.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Bsp3dNode));
                        instance.CollisionInfo.Bsp3dNodes.Add((CollisionGeometry.Bsp3dNode)element);
                    }

                    reader.BaseStream.Position = instance.CollisionInfo.Planes.Address.Offset;
                    for (var i = 0; i < instance.CollisionInfo.Planes.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Plane));
                        instance.CollisionInfo.Planes.Add((CollisionGeometry.Plane)element);
                    }

                    reader.BaseStream.Position = instance.CollisionInfo.Leaves.Address.Offset;
                    for (var i = 0; i < instance.CollisionInfo.Leaves.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Leaf));
                        instance.CollisionInfo.Leaves.Add((CollisionGeometry.Leaf)element);
                    }

                    reader.BaseStream.Position = instance.CollisionInfo.Bsp2dReferences.Address.Offset;
                    for (var i = 0; i < instance.CollisionInfo.Bsp2dReferences.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Bsp2dReference));
                        instance.CollisionInfo.Bsp2dReferences.Add((CollisionGeometry.Bsp2dReference)element);
                    }

                    reader.BaseStream.Position = instance.CollisionInfo.Bsp2dNodes.Address.Offset;
                    for (var i = 0; i < instance.CollisionInfo.Bsp2dNodes.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Bsp2dNode));
                        instance.CollisionInfo.Bsp2dNodes.Add((CollisionGeometry.Bsp2dNode)element);
                    }

                    reader.BaseStream.Position = instance.CollisionInfo.Surfaces.Address.Offset;
                    for (var i = 0; i < instance.CollisionInfo.Surfaces.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Surface));
                        instance.CollisionInfo.Surfaces.Add((CollisionGeometry.Surface)element);
                    }

                    reader.BaseStream.Position = instance.CollisionInfo.Edges.Address.Offset;
                    for (var i = 0; i < instance.CollisionInfo.Edges.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Edge));
                        instance.CollisionInfo.Edges.Add((CollisionGeometry.Edge)element);
                    }

                    reader.BaseStream.Position = instance.CollisionInfo.Vertices.Address.Offset;
                    for (var i = 0; i < instance.CollisionInfo.Vertices.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Vertex));
                        instance.CollisionInfo.Vertices.Add((CollisionGeometry.Vertex)element);
                    }

                    #endregion

                    #region compression's other resource data

                    foreach (var cbsp in instance.CollisionGeometries)
                    {
                        reader.BaseStream.Position = cbsp.Bsp3dNodes.Address.Offset;
                        for (var i = 0; i < cbsp.Bsp3dNodes.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Bsp3dNode));
                            cbsp.Bsp3dNodes.Add((CollisionGeometry.Bsp3dNode)element);
                        }

                        reader.BaseStream.Position = cbsp.Planes.Address.Offset;
                        for (var i = 0; i < cbsp.Planes.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Plane));
                            cbsp.Planes.Add((CollisionGeometry.Plane)element);
                        }

                        reader.BaseStream.Position = cbsp.Leaves.Address.Offset;
                        for (var i = 0; i < cbsp.Leaves.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Leaf));
                            cbsp.Leaves.Add((CollisionGeometry.Leaf)element);
                        }

                        reader.BaseStream.Position = cbsp.Bsp2dReferences.Address.Offset;
                        for (var i = 0; i < cbsp.Bsp2dReferences.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Bsp2dReference));
                            cbsp.Bsp2dReferences.Add((CollisionGeometry.Bsp2dReference)element);
                        }

                        reader.BaseStream.Position = cbsp.Bsp2dNodes.Address.Offset;
                        for (var i = 0; i < cbsp.Bsp2dNodes.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Bsp2dNode));
                            cbsp.Bsp2dNodes.Add((CollisionGeometry.Bsp2dNode)element);
                        }

                        reader.BaseStream.Position = cbsp.Surfaces.Address.Offset;
                        for (var i = 0; i < cbsp.Surfaces.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Surface));
                            cbsp.Surfaces.Add((CollisionGeometry.Surface)element);
                        }

                        reader.BaseStream.Position = cbsp.Edges.Address.Offset;
                        for (var i = 0; i < cbsp.Edges.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Edge));
                            cbsp.Edges.Add((CollisionGeometry.Edge)element);
                        }

                        reader.BaseStream.Position = cbsp.Vertices.Address.Offset;
                        for (var i = 0; i < cbsp.Vertices.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(CollisionGeometry.Vertex));
                            cbsp.Vertices.Add((CollisionGeometry.Vertex)element);
                        }
                    }

                    #endregion

                    #region Unknown Data

                    for (var i = 0; i < instance.Unknown1.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(StructureBspTagResources.InstancedGeometryBlock.Unknown1Block));
                        instance.Unknown1.Add((StructureBspTagResources.InstancedGeometryBlock.Unknown1Block)element);
                    }

                    for (var i = 0; i < instance.Unknown2.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(StructureBspTagResources.InstancedGeometryBlock.Unknown2Block));
                        instance.Unknown2.Add((StructureBspTagResources.InstancedGeometryBlock.Unknown2Block)element);
                    }

                    for (var i = 0; i < instance.Unknown3.Count; i++)
                    {
                        var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(StructureBspTagResources.InstancedGeometryBlock.Unknown3Block));
                        instance.Unknown3.Add((StructureBspTagResources.InstancedGeometryBlock.Unknown3Block)element);
                    }

                    #endregion

                    #region compression's havok collision data

                    foreach (var collision in instance.BspPhysics)
                    {
                        for (var i = 0; i < collision.Data.Count; i++)
                        {
                            var element = CacheContext.Deserializer.DeserializeValue(reader, null, null, typeof(byte));
                            collision.Data.Add(new StructureBspTagResources.CollisionBspPhysicsBlock.Datum {
                                Value = (byte)element
                            });
                        }
                    }

                    #endregion
                }

                #endregion
            }

            return(true);
        }
Beispiel #47
0
 public override void Read(EndianReader br)
 {
     Tag = (Index = Id = br.ReadInt32()) != -1 ? ((Dictionary <string, int>)EngineManager.Engines[Global.Application.Instance.Project.Engine]["TagIds"]).Keys.ElementAt(Index) : "Null Reference";
 }
Beispiel #48
0
            public CacheHeader(CacheBase Cache)
            {
                cache = Cache;
                EndianReader Reader = cache.Reader;

                #region Read Values
                XmlNode      headerNode = cache.versionNode.ChildNodes[0];
                XmlAttribute attr       = headerNode.Attributes["fileSize"];
                int          offset     = int.Parse(attr.Value);
                Reader.SeekTo(offset);
                fileSize = Reader.ReadInt32();

                attr   = headerNode.Attributes["indexOffset"];
                offset = int.Parse(attr.Value);
                Reader.SeekTo(offset);
                indexOffset = Reader.ReadInt32();

                attr   = headerNode.Attributes["tagDataAddress"];
                offset = int.Parse(attr.Value);
                Reader.SeekTo(offset);
                tagDataAddress = Reader.ReadInt32();

                attr   = headerNode.Attributes["stringCount"];
                offset = int.Parse(attr.Value);
                Reader.SeekTo(offset);
                stringCount = Reader.ReadInt32();

                attr   = headerNode.Attributes["stringTableSize"];
                offset = int.Parse(attr.Value);
                Reader.SeekTo(offset);
                stringTableSize = Reader.ReadInt32();

                attr   = headerNode.Attributes["stringTableIndexOffset"];
                offset = int.Parse(attr.Value);
                Reader.SeekTo(offset);
                stringTableIndexOffset = Reader.ReadInt32();

                attr   = headerNode.Attributes["stringTableOffset"];
                offset = int.Parse(attr.Value);
                Reader.SeekTo(offset);
                stringTableOffset = Reader.ReadInt32();

                attr   = headerNode.Attributes["scenarioName"];
                offset = int.Parse(attr.Value);
                Reader.SeekTo(offset);
                scenarioName = Reader.ReadString(256);

                attr   = headerNode.Attributes["fileCount"];
                offset = int.Parse(attr.Value);
                Reader.SeekTo(offset);
                fileCount = Reader.ReadInt32();

                attr   = headerNode.Attributes["fileTableOffset"];
                offset = int.Parse(attr.Value);
                Reader.SeekTo(offset);
                fileTableOffset = Reader.ReadInt32();

                attr   = headerNode.Attributes["fileTableSize"];
                offset = int.Parse(attr.Value);
                Reader.SeekTo(offset);
                fileTableSize = Reader.ReadInt32();

                attr   = headerNode.Attributes["fileTableIndexOffset"];
                offset = int.Parse(attr.Value);
                Reader.SeekTo(offset);
                fileTableIndexOffset = Reader.ReadInt32();

                #endregion
            }
        public List <ModelAnimationGraph.ResourceGroup> ConvertModelAnimationGraphResourceGroups(Stream cacheStream, Dictionary <ResourceLocation, Stream> resourceStreams, List <ModelAnimationGraph.ResourceGroup> resourceGroups)
        {
            if (BlamCache.ResourceGestalt == null)
            {
                BlamCache.LoadResourceTags();
            }

            var resourceDefinition = new List <ModelAnimationTagResource>();

            foreach (var group in resourceGroups)
            {
                var resourceEntry = BlamCache.ResourceGestalt.TagResources[group.ZoneAssetDatumIndex & ushort.MaxValue];

                group.Resource = new PageableResource
                {
                    Page = new RawPage
                    {
                        Index = -1,
                    },
                    Resource = new TagResourceGen3
                    {
                        ResourceType             = TagResourceTypeGen3.Animation,
                        DefinitionData           = BlamCache.ResourceGestalt.FixupInformation.Skip(resourceEntry.FixupInformationOffset).Take(resourceEntry.FixupInformationLength).ToArray(),
                        DefinitionAddress        = resourceEntry.DefinitionAddress,
                        ResourceFixups           = new List <TagResourceGen3.ResourceFixup>(),
                        ResourceDefinitionFixups = new List <TagResourceGen3.ResourceDefinitionFixup>(),
                        Unknown2 = 1
                    }
                };

                // Convert blam fixups

                // get the list of members in this resourcegroup. this list contains address, various offsets, and other info about the member.
                if (group.Resource.Resource.DefinitionData.Length != 0)
                {
                    using (var definitionStream = new MemoryStream(group.Resource.Resource.DefinitionData, true))
                        using (var definitionReader = new EndianReader(definitionStream, EndianFormat.BigEndian))
                            using (var definitionWriter = new EndianWriter(definitionStream, EndianFormat.BigEndian))
                            {
                                foreach (var fixup in resourceEntry.ResourceFixups)
                                {
                                    var newFixup = new TagResourceGen3.ResourceFixup
                                    {
                                        BlockOffset = (uint)fixup.BlockOffset,
                                        Address     = new CacheAddress(CacheAddressType.Resource, fixup.Offset)
                                    };

                                    definitionStream.Position = newFixup.BlockOffset;
                                    definitionWriter.Write(newFixup.Address.Value);

                                    group.Resource.Resource.ResourceFixups.Add(newFixup);
                                }

                                var dataContext = new DataSerializationContext(definitionReader, definitionWriter, CacheAddressType.Definition);

                                definitionStream.Position = group.Resource.Resource.DefinitionAddress.Offset + 0x4;
                                definitionWriter.Write(0x20000000);
                                // ODST's resource type is 4 when it's supposed to be 2 because the resource definition is in the tag and not as a raw resource

                                definitionStream.Position = group.Resource.Resource.DefinitionAddress.Offset;

                                resourceDefinition.Add(BlamCache.Deserializer.Deserialize <ModelAnimationTagResource>(dataContext));
                            }
                }
            }

            var diffLines   = new List <string>();
            var resDefIndex = -1;

            foreach (var group in resourceGroups)
            {
                resDefIndex++;

                if (resourceDefinition.Count < resDefIndex + 1)
                {
                    continue; // rare cases, might break the game
                }
                // Get the resource group real size, which is probably not in the resource definition
                var groupSize = 0;
                foreach (var groupMember in resourceDefinition[resDefIndex].GroupMembers)
                {
                    groupSize += groupMember.AnimationData.Size;
                    while (groupSize % 0x10 != 0) // align to 0x10.
                    {
                        groupSize += 4;
                    }
                }

                var resourceData = BlamCache.GetRawFromID(group.ZoneAssetDatumIndex, groupSize);

                if (resourceData == null)
                {
                    return(null);
                }

                using (var blamResourceStream = new MemoryStream(resourceData))
                    using (var resourceReader = new EndianReader(blamResourceStream, EndianFormat.BigEndian))
                        using (var dataStream = new MemoryStream(new byte[groupSize]))
                            using (var resourceWriter = new EndianWriter(dataStream, EndianFormat.LittleEndian))
                            {
                                var dataContext = new DataSerializationContext(resourceReader, resourceWriter);

                                var memberIndex  = -1;
                                var memberOffset = 0;
                                foreach (var member in resourceDefinition[resDefIndex].GroupMembers)
                                {
                                    memberIndex++;

                                    ModelAnimationTagResource.GroupMember.Codec     codec;
                                    ModelAnimationTagResource.GroupMember.FrameInfo frameInfo;

                                    if ((byte)member.BaseHeader != 0)
                                    {
                                        blamResourceStream.Position = member.AnimationData.Address.Offset;
                                        dataStream.Position         = member.AnimationData.Address.Offset;

                                        codec = BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.Codec>(dataContext);

                                        CacheContext.Serializer.Serialize(dataContext, codec);

                                        var Format1 = BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.Format1>(dataContext);

                                        CacheContext.Serializer.Serialize(dataContext, Format1);

                                        // blamResourceStream.Position = (long)member.AnimationData.Address.Offset + headerSize;
                                        // edResourceStream.Position = blamResourceStream.Position;
                                        for (int i = 0; i < codec.RotationNodeCount; i++)
                                        {
                                            CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.RotationFrame>(dataContext));
                                        }

                                        blamResourceStream.Position = member.AnimationData.Address.Offset + Format1.DataStart;
                                        dataStream.Position         = blamResourceStream.Position;
                                        for (int i = 0; i < codec.PositionNodeCount; i++)
                                        {
                                            CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.PositionFrame>(dataContext));
                                        }

                                        blamResourceStream.Position = member.AnimationData.Address.Offset + Format1.ScaleFramesOffset;
                                        dataStream.Position         = blamResourceStream.Position;
                                        for (int i = 0; i < codec.ScaleNodeCount; i++)
                                        {
                                            CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.ScaleFrame>(dataContext));
                                        }
                                    }

                                    // If the overlay header is alone, member.OverlayOffset = 0
                                    blamResourceStream.Position = (long)member.AnimationData.Address.Offset + member.OverlayOffset;
                                    dataStream.Position         = (long)member.AnimationData.Address.Offset + member.OverlayOffset;

                                    codec = BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.Codec>(dataContext);
                                    CacheContext.Serializer.Serialize(dataContext, codec);

                                    // deserialize second header. or as first header if the type1/format1 header isn't used.
                                    switch (codec.AnimationCodec)
                                    {
                                    case ModelAnimationTagResource.AnimationCompressionFormats.Type3: // should merge with type1
                                        var header = BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.Format1>(dataContext);

                                        CacheContext.Serializer.Serialize(dataContext, header);

                                        for (int nodeIndex = 0; nodeIndex < codec.RotationNodeCount; nodeIndex++)
                                        {
                                            for (int frameIndex = 0; frameIndex < member.FrameCount; frameIndex++)
                                            {
                                                CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.RotationFrame>(dataContext));
                                            }
                                        }

                                        blamResourceStream.Position = (long)member.AnimationData.Address.Offset + member.OverlayOffset + header.DataStart;
                                        dataStream.Position         = blamResourceStream.Position;
                                        for (int nodeIndex = 0; nodeIndex < codec.PositionNodeCount; nodeIndex++)
                                        {
                                            for (int frameIndex = 0; frameIndex < member.FrameCount; frameIndex++)
                                            {
                                                CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.PositionFrame>(dataContext));
                                            }
                                        }

                                        blamResourceStream.Position = (long)member.AnimationData.Address.Offset + member.OverlayOffset + header.ScaleFramesOffset;
                                        dataStream.Position         = blamResourceStream.Position;
                                        for (int nodeIndex = 0; nodeIndex < codec.ScaleNodeCount; nodeIndex++)
                                        {
                                            for (int frameIndex = 0; frameIndex < member.FrameCount; frameIndex++)
                                            {
                                                CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.ScaleFrame>(dataContext));
                                            }
                                        }

                                        break;

                                    case ModelAnimationTagResource.AnimationCompressionFormats.Type4:
                                    case ModelAnimationTagResource.AnimationCompressionFormats.Type5:
                                    case ModelAnimationTagResource.AnimationCompressionFormats.Type6:
                                    case ModelAnimationTagResource.AnimationCompressionFormats.Type7:
                                        var overlay = BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.Overlay>(dataContext);

                                        CacheContext.Serializer.Serialize(dataContext, overlay);

                                        #region Description
                                        // Description by DemonicSandwich from http://remnantmods.com/forums/viewtopic.php?f=13&t=1574 (matches my previous observations)

                                        // Format 6 uses Keyframes the way there are supposed to be used. As KEY frames, with the majority of the frames being Tweens.
                                        //
                                        // This format adds two extra blocks of data to it's structure.
                                        // One block that determines how many Keyframes each Node will have, and an offset to to where it's Markers start from.
                                        //
                                        // Advantages:
                                        // This format requires far fewer Keyframes to make a complex animation.
                                        // You do not need a keyframe for each render frame.
                                        // Disadvantages:
                                        // It's a bit more complex to work with.
                                        // Since it's Keyrame Markers are only 1 byte in size, you're animation cannot be longer than 256 frames, or ~8.5 seconds for non - machine objects. > 12 bits for gen3, max 0xFFF frames
                                        // Machines are still limited to 256 frames but the frames can be stretched out.
                                        #endregion

                                        var RotationFrameCount = new List <uint>();
                                        var PositionFrameCount = new List <uint>();
                                        var ScaleFrameCount    = new List <uint>();

                                        for (int i = 0; i < codec.RotationNodeCount; i++)
                                        {
                                            frameInfo = BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.FrameInfo>(dataContext);

                                            CacheContext.Serializer.Serialize(dataContext, frameInfo);

                                            var keyframesOffset = frameInfo.FrameCount & 0x00FFF000; // unused in this conversion
                                            var keyframes       = frameInfo.FrameCount & 0x00000FFF;
                                            RotationFrameCount.Add(keyframes);
                                        }

                                        for (int i = 0; i < codec.PositionNodeCount; i++)
                                        {
                                            frameInfo = BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.FrameInfo>(dataContext);

                                            CacheContext.Serializer.Serialize(dataContext, frameInfo);

                                            var keyframesOffset = frameInfo.FrameCount & 0x00FFF000;
                                            var keyframes       = frameInfo.FrameCount & 0x00000FFF;
                                            PositionFrameCount.Add(keyframes);
                                        }

                                        for (int i = 0; i < codec.ScaleNodeCount; i++)
                                        {
                                            frameInfo = BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.FrameInfo>(dataContext);

                                            CacheContext.Serializer.Serialize(dataContext, frameInfo);

                                            var keyframesOffset = frameInfo.FrameCount & 0x00FFF000;
                                            var keyframes       = frameInfo.FrameCount & 0x00000FFF;
                                            ScaleFrameCount.Add(keyframes);
                                        }

                                        blamResourceStream.Position = (long)member.AnimationData.Address.Offset + member.OverlayOffset + overlay.RotationKeyframesOffset;
                                        dataStream.Position         = blamResourceStream.Position;
                                        foreach (var framecount in RotationFrameCount)
                                        {
                                            for (int i = 0; i < framecount; i++)
                                            {
                                                if (codec.AnimationCodec == ModelAnimationTagResource.AnimationCompressionFormats.Type4)
                                                {
                                                    CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.Keyframe>(dataContext));
                                                }
                                                else if (codec.AnimationCodec == ModelAnimationTagResource.AnimationCompressionFormats.Type5)
                                                {
                                                    CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.KeyframeType5>(dataContext));
                                                }
                                                else if (codec.AnimationCodec == ModelAnimationTagResource.AnimationCompressionFormats.Type6)
                                                {
                                                    CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.Keyframe>(dataContext));
                                                }
                                                else if (codec.AnimationCodec == ModelAnimationTagResource.AnimationCompressionFormats.Type7)
                                                {
                                                    CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.KeyframeType5>(dataContext));
                                                }
                                            }
                                        }

                                        blamResourceStream.Position = (long)member.AnimationData.Address.Offset + member.OverlayOffset + overlay.PositionKeyframesOffset;
                                        dataStream.Position         = blamResourceStream.Position;
                                        foreach (var framecount in PositionFrameCount)
                                        {
                                            for (int i = 0; i < framecount; i++)
                                            {
                                                if (codec.AnimationCodec == ModelAnimationTagResource.AnimationCompressionFormats.Type4)
                                                {
                                                    CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.Keyframe>(dataContext));
                                                }
                                                else if (codec.AnimationCodec == ModelAnimationTagResource.AnimationCompressionFormats.Type5)
                                                {
                                                    CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.KeyframeType5>(dataContext));
                                                }
                                                else if (codec.AnimationCodec == ModelAnimationTagResource.AnimationCompressionFormats.Type6)
                                                {
                                                    CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.Keyframe>(dataContext));
                                                }
                                                else if (codec.AnimationCodec == ModelAnimationTagResource.AnimationCompressionFormats.Type7)
                                                {
                                                    CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.KeyframeType5>(dataContext));
                                                }
                                            }
                                        }

                                        blamResourceStream.Position = (long)member.AnimationData.Address.Offset + member.OverlayOffset + overlay.ScaleKeyframesOffset;
                                        dataStream.Position         = blamResourceStream.Position;
                                        foreach (var framecount in ScaleFrameCount)
                                        {
                                            for (int i = 0; i < framecount; i++)
                                            {
                                                if (codec.AnimationCodec == ModelAnimationTagResource.AnimationCompressionFormats.Type4)
                                                {
                                                    CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.Keyframe>(dataContext));
                                                }
                                                else if (codec.AnimationCodec == ModelAnimationTagResource.AnimationCompressionFormats.Type5)
                                                {
                                                    CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.KeyframeType5>(dataContext));
                                                }
                                                else if (codec.AnimationCodec == ModelAnimationTagResource.AnimationCompressionFormats.Type6)
                                                {
                                                    CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.Keyframe>(dataContext));
                                                }
                                                else if (codec.AnimationCodec == ModelAnimationTagResource.AnimationCompressionFormats.Type7)
                                                {
                                                    CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.KeyframeType5>(dataContext));
                                                }
                                            }
                                        }

                                        blamResourceStream.Position = (long)member.AnimationData.Address.Offset + member.OverlayOffset + overlay.RotationFramesOffset;
                                        dataStream.Position         = blamResourceStream.Position;
                                        foreach (var framecount in RotationFrameCount)
                                        {
                                            for (int i = 0; i < framecount; i++)
                                            {
                                                CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.RotationFrame>(dataContext));
                                            }
                                        }

                                        blamResourceStream.Position = (long)member.AnimationData.Address.Offset + member.OverlayOffset + overlay.PositionFramesOffset;
                                        dataStream.Position         = blamResourceStream.Position;
                                        foreach (var framecount in PositionFrameCount)
                                        {
                                            for (int i = 0; i < framecount; i++)
                                            {
                                                CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.PositionFrame>(dataContext));
                                            }
                                        }

                                        blamResourceStream.Position = (long)member.AnimationData.Address.Offset + member.OverlayOffset + overlay.ScaleFramesOffset;
                                        dataStream.Position         = blamResourceStream.Position;
                                        foreach (var framecount in ScaleFrameCount)
                                        {
                                            for (int i = 0; i < framecount; i++)
                                            {
                                                CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.ScaleFrame>(dataContext));
                                            }
                                        }
                                        break;

                                    case ModelAnimationTagResource.AnimationCompressionFormats.Type8:
                                        // Type 8 is basically a type 3 but with rotation frames using 4 floats, or a realQuaternion
                                        var Format8 = BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.Format8>(dataContext);

                                        CacheContext.Serializer.Serialize(dataContext, Format8);

                                        for (int nodeIndex = 0; nodeIndex < codec.RotationNodeCount; nodeIndex++)
                                        {
                                            for (int frameIndex = 0; frameIndex < member.FrameCount; frameIndex++)
                                            {
                                                CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.RotationFrameFloat>(dataContext));
                                            }
                                        }

                                        blamResourceStream.Position = (long)member.AnimationData.Address.Offset + member.OverlayOffset + Format8.PositionFramesOffset;
                                        dataStream.Position         = blamResourceStream.Position;
                                        for (int nodeIndex = 0; nodeIndex < codec.PositionNodeCount; nodeIndex++)
                                        {
                                            for (int frameIndex = 0; frameIndex < member.FrameCount; frameIndex++)
                                            {
                                                CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.PositionFrame>(dataContext));
                                            }
                                        }

                                        blamResourceStream.Position = (long)member.AnimationData.Address.Offset + member.OverlayOffset + Format8.ScaleFramesOffset;
                                        dataStream.Position         = blamResourceStream.Position;
                                        for (int nodeIndex = 0; nodeIndex < codec.ScaleNodeCount; nodeIndex++)
                                        {
                                            for (int frameIndex = 0; frameIndex < member.FrameCount; frameIndex++)
                                            {
                                                CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.ScaleFrame>(dataContext));
                                            }
                                        }

                                        break;

                                    default:
                                        throw new DataMisalignedException();
                                    }

                                    #region How Footer/Flags works
                                    // Better description by DemonicSandwich from http://remnantmods.com/forums/viewtopic.php?f=13&t=1574 : Node List Block: (matches my previous observations)
                                    // Just a block of flags. Tick a flag and the respective node will be affected by animation.
                                    // The size of this block should always be a multiple of 12. It's size is determined my the meta value Node List Size [byte, offset: 61]
                                    // When set to 12, the list can handle objects with a node count up to 32 (0-31).
                                    // When set to 24, the object can have 64 nodes and so on.
                                    // The block is split into 3 groups of flags.
                                    // The first group determines what nodes are affected by rotation, the second group for position, and the third group for scale.
                                    //
                                    // If looking at it in hex, the Node ticks for each group will be in order as follows:
                                    // [7][6][5][4][3][2][1][0] - [15][14][13][12][11][10][9][8] - etc.
                                    // Each flag corresponding to a Node index.
                                    #endregion

                                    #region Footer/Flag block
                                    // There's one bitfield32 for every 32 nodes that are animated which i'll call a node flags.
                                    // There's at least 3 flags if the animation only has an overlay header, which i'll call a flag set.
                                    // There's at least 6 flags if the animation has both a base header and an overlay header, so 2 sets.
                                    // If the animated nodes count is over 32, then a new flags set is added.
                                    // 1 set per header is added, such as 32 nodes = 1 set, 64 = 2 sets, 96 = 3 sets etc , 128-256 maybe max

                                    blamResourceStream.Position = (long)member.AnimationData.Address.Offset + member.OverlayOffset + member.FlagsOffset;
                                    dataStream.Position         = blamResourceStream.Position;

                                    var footerSizeBase = (byte)member.BaseHeader / 4;
                                    for (int flagsCount = 0; flagsCount < footerSizeBase; flagsCount++)
                                    {
                                        CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.ScaleFrame>(dataContext));
                                    }

                                    var footerSizeOverlay = (byte)member.OverlayHeader / 4;
                                    for (int flagsCount = 0; flagsCount < footerSizeOverlay; flagsCount++)
                                    {
                                        CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.ScaleFrame>(dataContext));
                                    }
                                    #endregion

                                    switch (member.MovementDataType)
                                    {
                                    case ModelAnimationTagResource.GroupMemberMovementDataType.None:
                                        if (member.Unknown1 > 0)
                                        {
                                            for (int i = 0; i < member.FrameCount; i++)
                                            {
                                                CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.FrameInfoDyaw>(dataContext));
                                            }
                                        }
                                        if (member.Unknown2 > 0)
                                        {
                                            for (int i = 0; i < member.FrameCount; i++)
                                            {
                                                CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.FrameInfoDxDyDyaw>(dataContext));
                                            }
                                        }
                                        break;

                                    case ModelAnimationTagResource.GroupMemberMovementDataType.dx_dy:
                                        if (member.Unknown1 > 0)
                                        {
                                            for (int i = 0; i < member.FrameCount; i++)
                                            {
                                                CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.FrameInfoDxDy>(dataContext));
                                            }
                                        }
                                        if (member.Unknown2 > 0)
                                        {
                                            for (int i = 0; i < member.FrameCount; i++)
                                            {
                                                CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.FrameInfoDxDyDyaw>(dataContext));
                                            }
                                        }
                                        break;

                                    case ModelAnimationTagResource.GroupMemberMovementDataType.dx_dy_dyaw:
                                        if (member.Unknown1 > 0)
                                        {
                                            for (int i = 0; i < member.FrameCount; i++)
                                            {
                                                CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.FrameInfoDxDyDyaw>(dataContext));
                                            }
                                        }
                                        if (member.Unknown2 > 0)
                                        {
                                            for (int i = 0; i < member.FrameCount; i++)
                                            {
                                                CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.FrameInfoDxDyDyaw>(dataContext));
                                            }
                                        }
                                        break;

                                    case ModelAnimationTagResource.GroupMemberMovementDataType.dx_dy_dz_dyaw:
                                        if (member.Unknown1 > 0)
                                        {
                                            for (int i = 0; i < member.FrameCount; i++)
                                            {
                                                CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.FrameInfoDxDyDzDyaw>(dataContext));
                                            }
                                        }
                                        if (member.Unknown2 > 0)
                                        {
                                            for (int i = 0; i < member.FrameCount; i++)
                                            {
                                                CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.FrameInfoDxDyDzDyaw>(dataContext));
                                            }
                                        }
                                        break;

                                    default:
                                        break;
                                    }

                                    dataStream.Position = memberOffset + member.AnimationData.Size;

                                    // Before the next animation member, there's some padding that is garbage data in H3/ODST, but zeroed in HO.
                                    // In order to compare converted to original raw easily, copy the original data.
                                    while (blamResourceStream.Position % 0x10 != 0) // align to 0x10, useless padding of garbage data, it's zeroed in 1:1 HO raw, just read as 4 lame bytes
                                    {
                                        if (blamResourceStream.Position == blamResourceStream.Length)
                                        {
                                            break;
                                        }

                                        CacheContext.Serializer.Serialize(dataContext, BlamCache.Deserializer.Deserialize <ModelAnimationTagResource.GroupMember.ScaleFrame>(dataContext));
                                    }

                                    // Align the next animation member to 0x10.
                                    memberOffset += member.AnimationData.Size;
                                    while (memberOffset % 0x10 != 0)
                                    {
                                        memberOffset += 4;
                                    }
                                }

                                dataStream.Position = 0;

                                CacheContext.Serializer.Serialize(new ResourceSerializationContext(CacheContext, group.Resource), resourceDefinition[resDefIndex]);

                                group.Resource.ChangeLocation(ResourceLocation.ResourcesB);
                                var resource = group.Resource;

                                if (resource == null)
                                {
                                    throw new ArgumentNullException("resource");
                                }

                                if (!dataStream.CanRead)
                                {
                                    throw new ArgumentException("The input stream is not open for reading", "dataStream");
                                }

                                var cache = CacheContext.GetResourceCache(ResourceLocation.ResourcesB);

                                if (!resourceStreams.ContainsKey(ResourceLocation.ResourcesB))
                                {
                                    resourceStreams[ResourceLocation.ResourcesB] = FlagIsSet(PortingFlags.Memory) ?
                                                                                   new MemoryStream() :
                                                                                   (Stream)CacheContext.OpenResourceCacheReadWrite(ResourceLocation.ResourcesB);

                                    if (FlagIsSet(PortingFlags.Memory))
                                    {
                                        using (var resourceStream = CacheContext.OpenResourceCacheRead(ResourceLocation.ResourcesB))
                                            resourceStream.CopyTo(resourceStreams[ResourceLocation.ResourcesB]);
                                    }
                                }

                                var dataSize = (int)(dataStream.Length - dataStream.Position);
                                var data     = new byte[dataSize];
                                dataStream.Read(data, 0, dataSize);

                                resource.Page.Index = cache.Add(resourceStreams[ResourceLocation.ResourcesB], data, out uint compressedSize);
                                resource.Page.CompressedBlockSize   = compressedSize;
                                resource.Page.UncompressedBlockSize = (uint)dataSize;
                                resource.DisableChecksum();
                            }
            }

            return(resourceGroups);
        }
Beispiel #50
0
        public CachedTag FixRmt2Reference(Stream cacheStream, string blamTagName, CachedTag blamRmt2Tag, RenderMethodTemplate blamRmt2Definition, List <string> bmMaps, List <string> bmArgs)
        {
            switch (blamTagName)
            {
            case @"levels\multi\snowbound\shaders\cov_grey_icy":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"ms30\shaders\shader_templates\_0_2_0_1_7_2_0_0_0_0_0_0"));
                }
                catch { }
                break;

            case @"objects\vehicles\ghost\shaders\ghost_damage":
            case @"objects\vehicles\wraith\shaders\wraith_blown_open":
            case @"objects\vehicles\banshee\shaders\banshee_damage":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_2_0_1_2_2_2_0_1_1_0"));
                }
                catch { }
                break;

            case @"objects\vehicles\ghost\shaders\ghost_torn":
            case @"objects\vehicles\banshee\shaders\banshee_torn":
            case @"objects\vehicles\wraith\shaders\wraith_torn":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_2_1_1_2_2_0_0_0_0_0"));
                }
                catch { }
                break;

            case @"objects\vehicles\wraith\shaders\wraith_torn_metal":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_2_1_1_1_2_0_0_0_0_0"));
                }
                catch { }
                break;

            case @"objects\vehicles\ghost\shaders\ghost_dash_zcam":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\halogram_templates\_0_11_0_1_0_2_0"));
                }
                catch { }
                break;

            case @"fx\particles\energy\electric_arcs_blue":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\particle_templates\_2_8_0_0_0_0_1_0_0_0"));
                }
                catch { }
                break;

            case @"objects\weapons\melee\energy_blade\fx\particles\plasma_wispy":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\particle_templates\_5_8_0_0_0_1_0_0_0_0"));
                }
                catch { }
                break;

            case @"objects\weapons\melee\energy_blade\fx\particles\energy_pulse":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\particle_templates\_3_7_0_0_1_0_0_0_0_0"));
                }
                catch { }
                break;

            case @"levels\dlc\fortress\shaders\panel_platform_center":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_1_0_1_2_2_5_0_1_0_0"));
                }
                catch
                { }
                break;

            case @"levels\dlc\sidewinder\shaders\side_tree_branch_snow":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_1_1_0_0_2_5_0_0_0_0"));
                }
                catch
                { }
                break;

            case @"levels\dlc\sidewinder\shaders\justin\sw_ground_ice1":
            case @"levels\dlc\sidewinder\shaders\justin\sw_ground_rock1":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\terrain_templates\_0_0_1_1_1_2"));
                }
                catch
                { }
                break;

            case @"levels\multi\snowbound\sky\shaders\skydome":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_0_0_0_0_0_0_0_0_0_0"));
                }
                catch
                { }
                break;

            case @"levels\solo\020_base\lights\light_volume_hatlight":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\halogram_templates\_0_5_1_0_0_1_1"));
                }
                catch { }
                break;

            case @"levels\dlc\armory\shaders\metal_doodad_a":
            case @"levels\dlc\armory\shaders\metal_doodad_a_illum_blue":
            case @"levels\dlc\armory\shaders\metal_doodad_a_illum_cool":
            case @"levels\dlc\armory\shaders\metal_doodad_a_illum_red":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_7_2_0_1_1_0_1_0_0_0_0"));
                }
                catch { }
                break;

            case @"levels\dlc\armory\shaders\razor_wire":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_1_1_2_5_2_0_1_0_0_0"));
                }
                catch { }
                break;

            case @"levels\multi\deadlock\shaders\deadlock_concrete_wall_a_rubble":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_2_0_0_0_0_0_0_0_0_0"));
                }
                catch { }
                break;

            case @"levels\multi\snowbound\shaders\rock_cliffs":
            case @"levels\multi\snowbound\shaders\rock_rocky":
            case @"levels\multi\snowbound\shaders\rock_rocky_icy":
            case @"levels\solo\020_base\shaders\hb_metal_arch_unwrap_a":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_7_2_0_1_2_1_0_0_1_0_0"));
                }
                catch { }
                break;

            case @"levels\dlc\armory\shaders\concrete_wall_01":
            case @"levels\dlc\armory\shaders\concrete_wall_01_blue":
            case @"levels\dlc\armory\shaders\concrete_wall_01_red":
            case @"levels\dlc\armory\shaders\concrete_wall_02_blue":
            case @"levels\dlc\armory\shaders\concrete_wall_02_red":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_7_2_0_1_7_0_0_0_0_0_0"));
                }
                catch { }
                break;

            case @"objects\levels\solo\010_jungle\shaders\dam_fence":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_1_1_1_1_2_0_0_0_1_0"));
                }
                catch { }
                break;

            case @"levels\dlc\chillout\shaders\chillout_capsule_liquid":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\halogram_templates\_2_5_1_0_1_2_1"));
                }
                catch { }
                break;

            case @"levels\dlc\chillout\shaders\chillout_flood_godrays":
            case @"levels\dlc\chillout\shaders\chillout_invis_godrays":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\halogram_templates\_0_5_1_0_0_1_1"));
                }
                catch { }
                break;

            case @"objects\levels\dlc\chillout\shaders\chill_energy_blocker_small":
            case @"objects\levels\dlc\chillout\shaders\chill_viewing_area_blocker":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\halogram_templates\_0_8_1_0_0_4_1"));
                }
                catch { }
                break;

            case @"levels\dlc\chillout\shaders\chillout_floodroom01":
            case @"levels\dlc\chillout\shaders\chillout_floodroom02":
            case @"levels\dlc\chillout\shaders\chillout_floodroom03":
            case @"levels\dlc\chillout\shaders\chillout_transporter":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_2_0_1_1_2_5_0_0_1_0"));
                }
                catch { }
                break;

            case @"levels\dlc\chillout\shaders\chillout_flood_suckers":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_1_1_2_1_1_0_0_0_0_0"));
                }
                catch { }
                break;

            case @"levels\shared\shaders\flood\flood_sackyb":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_1_0_0_1_0_0_3_1_1_0"));
                }
                catch { }
                break;

            case @"objects\characters\flood_infection\shaders\flood_fronds":
            case @"objects\characters\flood_tank\shaders\flood_fronds":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_1_1_0_0_2_5_0_0_0_0"));
                }
                catch { }
                break;

            case @"objects\characters\flood_infection\shaders\flood_infection":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"ms30\shaders\shader_templates\_0_2_0_1_1_0_1_0_0_0_0_0"));
                }
                catch { }
                break;

            case @"objects\weapons\melee\energy_blade\shaders\energy_blade":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_2_0_1_1_0_3_3_1_1_0"));
                }
                catch
                { }
                break;

            case @"objects\weapons\rifle\plasma_rifle_red\shaders\plasma_rifle_red":
            case @"objects\weapons\rifle\plasma_rifle\shaders\plasma_rifle":
            case @"objects\weapons\rifle\covenant_carbine\shaders\carbine":
            case @"objects\weapons\rifle\covenant_carbine\shaders\carbine_dull":
            case @"objects\weapons\pistol\plasma_pistol\shaders\plasma_pistol_metal":
            case @"objects\weapons\pistol\needler\shaders\needler_blue":
            case @"objects\weapons\pistol\needler\shaders\needler_pink":
            case @"objects\weapons\support_high\flak_cannon\shaders\flak_cannon":
            case @"objects\weapons\rifle\beam_rifle\shaders\beam_rifle":
            case @"objects\weapons\rifle\beam_rifle\shaders\beam_rifle2":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_2_0_1_2_1_1_0_0_0_0"));
                }
                catch
                { }
                break;

            case @"objects\weapons\pistol\needler\shaders\needler_glass":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_0_0_0_0_0_1_0_3_0_0_0"));
                }
                catch
                { }
                break;

            case @"objects\weapons\rifle\sniper_rifle\shaders\scope_alpha":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\halogram_templates\_0_11_0_1_0_2_0"));
                }
                catch { }
                break;

            //Vehicles
            case @"objects\vehicles\scorpion\turrets\cannon\shaders\turret_cannon":
                try
                {
                    return(CacheContext.GetTag <RenderMethodTemplate>(@"shaders\shader_templates\_3_2_0_1_1_0_0_0_0_0_0"));
                }
                catch { }
                break;
            }

            // Find existing rmt2 tags
            // If tagnames are not fixed, ms30 tags have an additional _0 or _0_0. This shouldn't happen if the tags have proper names, so it's mostly to preserve compatibility with older tagnames
            using (var reader = new EndianReader(cacheStream, true))
            {
                foreach (var instance in CacheContext.TagCache.TagTable)
                {
                    if (instance == null || !instance.IsInGroup("rmt2") || instance.Name == null)
                    {
                        continue;
                    }

                    var rmt2Name = instance.Name;

                    // ignore s3d rmt2s
                    if (rmt2Name.StartsWith("s3d"))
                    {
                        continue;
                    }

                    // check if rmt2 is from ms30
                    if (rmt2Name.StartsWith("ms30"))
                    {
                        rmt2Name = rmt2Name.Replace("ms30\\", "");
                        // skip over ms30 rmt2s
                        if (!UseMS30)
                        {
                            continue;
                        }
                    }

                    //match found
                    if (rmt2Name.StartsWith(blamRmt2Tag.Name))
                    {
                        return(instance);
                    }
                }
            }

            // if no tagname matches, find rmt2 tags based on the most common values in the name
            return(FindEquivalentRmt2(cacheStream, blamRmt2Tag, blamRmt2Definition, bmMaps, bmArgs));
        }
Beispiel #51
0
        private void btnImport_Click(object sender, RoutedEventArgs e)
        {
            var ofd = new OpenFileDialog
            {
                Title = "Open Tag Container",
                Filter = "Tag Container Files|*.tagc"
            };
            bool? result = ofd.ShowDialog();
            if (!result.Value)
                return;

            TagContainer container;
            using (var reader = new EndianReader(File.OpenRead(ofd.FileName), Endian.BigEndian))
                container = TagContainerReader.ReadTagContainer(reader);

            var injector = new TagContainerInjector(_cacheFile, container);
            using (IStream stream = _mapManager.OpenReadWrite())
            {
                foreach (ExtractedTag tag in container.Tags)
                    injector.InjectTag(tag, stream);

                injector.SaveChanges(stream);
            }

            // Fix the SID trie
            foreach (StringID sid in injector.InjectedStringIDs)
                _stringIdTrie.Add(_cacheFile.StringIDs.GetString(sid));

            LoadTags();
            MetroMessageBox.Show("Import Successful",
                "Imported " + injector.InjectedTags.Count + " tag(s), " + injector.InjectedBlocks.Count + " data block(s), " +
                injector.InjectedPages.Count + " resource page pointer(s), " + injector.InjectedResources.Count +
                " resource pointer(s), and " + injector.InjectedStringIDs.Count +
                " stringID(s).\r\n\r\nPlease remember that you cannot poke to injected or modified tags without causing problems. Load the modified map in the game first.\r\n\r\nAdditionally, if applicable, make sure that your game executable is patched so that any map header hash checks are bypassed. Using an executable which only has RSA checks patched out will refuse to load the map.");
        }
Beispiel #52
0
 internal override void DeserializeStreamer(EndianReader reader)
 {
     InitialFrameID = reader.ReadUInt32LE();
     ((ISerializable)RequestedFormat).Deserialize(reader);
 }
Beispiel #53
0
        static void Main(string[] args)
        {
            if (args.Length != 3)
            {
                Console.WriteLine("Usage: BlockAlignmentScanner <map dir> <in plugin dir> <out plugin dir>");
                return;
            }

            var mapDir = args[0];
            var inDir = args[1];
            var outDir = args[2];

            Console.WriteLine("Loading plugins...");
            var pluginsByClass = new Dictionary<string, XDocument>();
            foreach (var pluginPath in Directory.EnumerateFiles(inDir, "*.xml"))
            {
                Console.WriteLine("- {0}", pluginPath);
                var document = XDocument.Load(pluginPath);
                var className = Path.GetFileNameWithoutExtension(pluginPath);
                pluginsByClass[className] = document;
            }

            Console.WriteLine("Loading engine database...");
            var exeDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            var dbPath = Path.Combine(exeDir, "Formats", "Engines.xml");
            var db = XMLEngineDatabaseLoader.LoadDatabase(dbPath);

            Console.WriteLine("Processing maps...");
            var alignsByElem = new Dictionary<XElement, int>();
            foreach (var mapPath in Directory.EnumerateFiles(mapDir, "*.map"))
            {
                Console.WriteLine("- {0}", Path.GetFileName(mapPath));
                using (var reader = new EndianReader(File.OpenRead(mapPath), Endian.BigEndian))
                {
                    var map = CacheFileLoader.LoadCacheFile(reader, db);
                    var visitedTagBlocks = new HashSet<uint>();
                    foreach (var tag in map.Tags)
                    {
                        if (tag == null || tag.Class == null || tag.MetaLocation == null)
                            continue;

                        // Get the plugin for the tag
                        var className = CharConstant.ToString(tag.Class.Magic);
                        XDocument plugin;
                        if (!pluginsByClass.TryGetValue(className, out plugin))
                            continue;

                        // Process it
                        var baseOffset = tag.MetaLocation.AsOffset();
                        var baseElement = plugin.Element("plugin");
                        DetectAlignment(map, reader, baseOffset, baseElement, alignsByElem, visitedTagBlocks);
                    }
                }
            }

            Console.WriteLine("Adjusting plugins...");
            foreach (var align in alignsByElem)
            {
                if (align.Value != 4)
                {
                    Console.WriteLine("- \"{0}\" -> align 0x{1:X}", align.Key.Attribute("name").Value, align.Value);
                    align.Key.SetAttributeValue(XName.Get("align"), "0x" + align.Value.ToString("X"));
                }
            }

            if (!Directory.Exists(outDir))
                Directory.CreateDirectory(outDir);

            Console.WriteLine("Saving plugins...");
            foreach (var plugin in pluginsByClass)
            {
                var outPath = Path.Combine(outDir, plugin.Key + ".xml");
                Console.WriteLine("- {0}", outPath);

                var settings = new XmlWriterSettings();
                settings.Indent = true;
                settings.IndentChars = "\t";
                using (var writer = XmlWriter.Create(outPath, settings))
                    plugin.Value.Save(writer);
            }
        }
Beispiel #54
0
 public void Read(EndianReader stream)
 {
     DecompressedSize = stream.ReadUInt32();
     CompressedSize   = stream.ReadUInt32();
     Flags            = (BundleFlag)stream.ReadUInt16();
 }
        public override byte[] GetRawFromID(int ID, int DataLength)
        {
            EndianReader er;
            string fName = "";

            var Entry = zone.RawEntries[ID & ushort.MaxValue];

            if (Entry.SegmentIndex == -1) throw new InvalidDataException("Raw data not found.");

            var Loc = play.Segments[Entry.SegmentIndex];

            //if (Loc.SoundRawIndex != -1)
            //    return GetSoundRaw(ID);

            int index = (Loc.OptionalPageIndex2 != -1) ? Loc.OptionalPageIndex2 : (Loc.OptionalPageIndex != -1) ? Loc.OptionalPageIndex : Loc.RequiredPageIndex;
            int locOffset = (Loc.OptionalPageOffset2 != -1) ? Loc.OptionalPageOffset2 : (Loc.OptionalPageOffset != -1) ? Loc.OptionalPageOffset : Loc.RequiredPageOffset;

            if (index == -1 || locOffset == -1) throw new InvalidDataException("Raw data not found.");

            if (play.Pages[index].RawOffset == -1)
            {
                index = Loc.RequiredPageIndex;
                locOffset = Loc.RequiredPageOffset;
            }

            var Pool = play.Pages[index];

            if (Pool.CacheIndex != -1)
            {
                fName = play.SharedCaches[Pool.CacheIndex].FileName;
                fName = fName.Substring(fName.LastIndexOf('\\'));
                fName = FilePath + fName;

                if (fName == Filename)
                    er = Reader;
                else
                {
                    FileStream fs = new FileStream(fName, FileMode.Open, FileAccess.Read);
                    er = new EndianReader(fs, EndianFormat.BigEndian);
                }
            }
            else
                er = Reader;

            er.SeekTo(int.Parse(versionNode.ChildNodes[0].Attributes["rawTableOffset"].Value));
            int offset = Pool.RawOffset + er.ReadInt32();
            er.SeekTo(offset);
            byte[] compressed = er.ReadBytes(Pool.CompressedSize);
            byte[] decompressed = new byte[Pool.DecompressedSize];

            if (Version >= DefinitionSet.Halo4Retail)
            {
                int decompressionContext = 0;
                XCompress.XMemCreateDecompressionContext(XCompress.XMemCodecType.LZX, 0, 0, ref decompressionContext);
                XCompress.XMemResetDecompressionContext(decompressionContext);
                XCompress.XMemDecompressStream(decompressionContext, decompressed, ref Pool.DecompressedSize, compressed, ref Pool.CompressedSize);
                XCompress.XMemDestroyDecompressionContext(decompressionContext);
            }
            else
            {
                BinaryReader BR = new BinaryReader(new DeflateStream(new MemoryStream(compressed), CompressionMode.Decompress));
                decompressed = BR.ReadBytes(Pool.DecompressedSize);
                BR.Close();
                BR.Dispose();
            }

            byte[] data = new byte[(DataLength != -1) ? DataLength : (Pool.DecompressedSize - locOffset)];
            int length = data.Length;
            if (length > decompressed.Length) length = decompressed.Length;
            Array.Copy(decompressed, locOffset, data, 0, length);

            if (er != Reader)
            {
                er.Close();
                er.Dispose();
            }

            return data;
        }
Beispiel #56
0
        public InMemoryBlockCollection(IMetadataStream stream, EndianReader reader, XmlNode node, InMemoryBlockCollection parent, int parentBlockIndex)
        {
            this.stream   = stream;
            defaultValues = new Dictionary <int, byte[]>();

            XmlNode          = node;
            ParentBlock      = parent;
            ParentEntryIndex = parentBlockIndex;
            ChildBlocks      = new List <InMemoryBlockCollection>();
            ParentBlock?.ChildBlocks.Add(this);

            if (parent == null) //tag root
            {
                Name       = stream.SourceTag.FileName();
                blockRef   = null;
                EntryCount = 1;
                EntrySize  = node.GetIntAttribute("baseSize") ?? 0;
                data       = reader.ReadBytes(VirtualSize);
            }
            else
            {
                offsetInParent = node.GetIntAttribute("offset") ?? 0;
                Name           = node.GetStringAttribute("name");
                blockRef       = reader.ReadObject <TagBlock>();
                EntryCount     = BlockRef.IsInvalid ? 0 : BlockRef.Count;
                EntrySize      = node.GetIntAttribute("elementSize", "entrySize", "size") ?? 0;

                if (EntryCount > 0)
                {
                    reader.Seek(BlockRef.Pointer.Address, SeekOrigin.Begin);
                    data = reader.ReadBytes(VirtualSize);
                }
                else
                {
                    data = Array.Empty <byte>();
                }
            }

            foreach (var element in node.SelectNodes("*[@offset][@defaultValue]").OfType <XmlNode>())
            {
                var offset       = element.GetIntAttribute("offset").Value;
                var defaultValue = element.GetStringAttribute("defaultValue");

                Func <string, int> getFlagValue = (val) => val.Split('|').Select(s => 1 << int.Parse(s)).Sum();

                byte[] bytes;
                switch (element.Name.ToLower())
                {
                case "int8":
                case "enum8":
                case "blockindex8":
                    bytes = new[] { defaultValue == "-1" ? byte.MaxValue : byte.Parse(defaultValue) };
                    break;

                case "int16":
                case "blockindex16":
                    bytes = BitConverter.GetBytes(short.Parse(defaultValue));
                    break;

                case "uint16":
                case "enum16":
                    bytes = BitConverter.GetBytes(ushort.Parse(defaultValue));
                    break;

                case "int32":
                case "blockindex32":
                    bytes = BitConverter.GetBytes(int.Parse(defaultValue));
                    break;

                case "uint32":
                case "enum32":
                    bytes = BitConverter.GetBytes(uint.Parse(defaultValue));
                    break;

                case "float32":
                    bytes = BitConverter.GetBytes(float.Parse(defaultValue));
                    break;

                case "flags8":
                    bytes = BitConverter.GetBytes((byte)getFlagValue(defaultValue));
                    break;

                case "flags16":
                    bytes = BitConverter.GetBytes((ushort)getFlagValue(defaultValue));
                    break;

                case "flags32":
                    bytes = BitConverter.GetBytes((uint)getFlagValue(defaultValue));
                    break;

                default:
                    continue;
                }

                if (stream.ByteOrder == ByteOrder.BigEndian)
                {
                    Array.Reverse(bytes);
                }

                defaultValues.Add(offset, bytes);
            }
        }
Beispiel #57
0
		// Patch Creation
		private void btnCreatePatch_Click(object sender, RoutedEventArgs e)
		{
			try
			{
				// Check the user isn't completly retarded
				if (!CheckAllCreateMandatoryFields())
					return;

				// Check the user isn't a skid
				if (!CheckAllCreateMetaFilesExists())
					return;

				// Paths
				string cleanMapPath = txtCreatePatchUnModifiedMap.Text;
				string moddedMapPath = txtCreatePatchModifiedMap.Text;
				string outputPath = txtCreatePatchOutputPatch.Text;
				string previewImage = txtCreatePatchPreviewImage.Text;

				// Details
				string author = txtCreatePatchContentAuthor.Text;
				string desc = txtCreatePatchContentDescription.Text;
				string name = txtCreatePatchContentName.Text;
				string outputName = txtCreatePatchOutputName.Text;

				// Make dat patch
				var patch = new Patch
				{
					Author = author,
					Description = desc,
					Name = name,
					OutputName = outputName,
					Screenshot = String.IsNullOrEmpty(previewImage)
						? null
						: File.ReadAllBytes(previewImage)
				};

				EndianReader originalReader = null;
				EndianReader newReader = null;
				try
				{
					originalReader = new EndianReader(File.OpenRead(cleanMapPath), Endian.BigEndian);
					newReader = new EndianReader(File.OpenRead(moddedMapPath), Endian.BigEndian);

					ICacheFile originalFile = CacheFileLoader.LoadCacheFile(originalReader,
						App.AssemblyStorage.AssemblySettings.DefaultDatabase);
					ICacheFile newFile = CacheFileLoader.LoadCacheFile(newReader, App.AssemblyStorage.AssemblySettings.DefaultDatabase);

					if (cbCreatePatchHasCustomMeta.IsChecked != null && (bool) cbCreatePatchHasCustomMeta.IsChecked &&
					    cboxCreatePatchTargetGame.SelectedIndex < 4)
					{
						var targetGame = (TargetGame) cboxCreatePatchTargetGame.SelectedIndex;
						byte[] mapInfo = File.ReadAllBytes(txtCreatePatchMapInfo.Text);
						var mapInfoFileInfo = new FileInfo(txtCreatePatchMapInfo.Text);
						FileInfo blfFileInfo;

						patch.CustomBlfContent = new BlfContent(mapInfoFileInfo.FullName, mapInfo, targetGame);

						#region Blf Data

						if (PatchCreationBlfOption0.Visibility == Visibility.Visible)
						{
							blfFileInfo = new FileInfo(txtCreatePatchblf0.Text);
							patch.CustomBlfContent.BlfContainerEntries.Add(new BlfContainerEntry(blfFileInfo.Name,
								File.ReadAllBytes(blfFileInfo.FullName)));
						}
						if (PatchCreationBlfOption1.Visibility == Visibility.Visible)
						{
							blfFileInfo = new FileInfo(txtCreatePatchblf1.Text);
							patch.CustomBlfContent.BlfContainerEntries.Add(new BlfContainerEntry(blfFileInfo.Name,
								File.ReadAllBytes(blfFileInfo.FullName)));
						}
						if (PatchCreationBlfOption2.Visibility == Visibility.Visible)
						{
							blfFileInfo = new FileInfo(txtCreatePatchblf2.Text);
							patch.CustomBlfContent.BlfContainerEntries.Add(new BlfContainerEntry(blfFileInfo.Name,
								File.ReadAllBytes(blfFileInfo.FullName)));
						}
						if (PatchCreationBlfOption3.Visibility == Visibility.Visible)
						{
							blfFileInfo = new FileInfo(txtCreatePatchblf3.Text);
							patch.CustomBlfContent.BlfContainerEntries.Add(new BlfContainerEntry(blfFileInfo.Name,
								File.ReadAllBytes(blfFileInfo.FullName)));
						}

						#endregion
					}

					PatchBuilder.BuildPatch(originalFile, originalReader, newFile, newReader, patch);
				}
				finally
				{
					if (originalReader != null)
						originalReader.Close();
					if (newReader != null)
						newReader.Close();
				}

				IWriter output = new EndianWriter(File.Open(outputPath, FileMode.Create, FileAccess.Write), Endian.BigEndian);
				AssemblyPatchWriter.WritePatch(patch, output);
				output.Close();

				MetroMessageBox.Show("Patch Created!",
					"Your patch has been created in the designated location. Happy sailing, modder!");
			}
			catch (Exception ex)
			{
				MetroException.Show(ex);
			}
		}
Beispiel #58
0
 public abstract bool Read(EndianReader reader);
Beispiel #59
0
		private void LoadPatchToPoke()
		{
			try
			{
				using (var reader = new EndianReader(File.OpenRead(txtPokePatchFile.Text), Endian.LittleEndian))
				{
					string magic = reader.ReadAscii(4);
					reader.SeekTo(0);

					if (magic == "asmp")
					{
						// Load into UI
						reader.Endianness = Endian.BigEndian;
						currentPatchToPoke = AssemblyPatchLoader.LoadPatch(reader);
						txtPokePatchAuthor.Text = currentPatchToPoke.Author;
						txtPokePatchDesc.Text = currentPatchToPoke.Description;
						txtPokePatchName.Text = currentPatchToPoke.Name;
						txtPokePatchInternalName.Text = currentPatchToPoke.MapInternalName;
						//txtPokePatchMapID.Text = currentPatchToPoke.MapID.ToString(CultureInfo.InvariantCulture);

						// Set Visibility
						PokePatchControls.Visibility = Visibility.Visible;
					}
					else
					{
						MetroMessageBox.Show("You can't poke a patch from Alteration/Ascension. Convert it to a Assembly Patch first");
						return;
					}
				}

				// Set Screenshot
				if (currentPatchToPoke.Screenshot == null)
				{
					// Set default
					var source = new Uri(@"/Assembly;component/Metro/Images/super_patcher.png", UriKind.Relative);
					imgPokePreview.Source = new BitmapImage(source);
				}
				else
				{
					var image = new BitmapImage();
					image.BeginInit();
					image.StreamSource = new MemoryStream(currentPatchToPoke.Screenshot);
					image.EndInit();
					imgPokePreview.Source = image;
				}
			}
			catch (Exception ex)
			{
				MetroException.Show(ex);
			}
		}
Beispiel #60
0
        public void Versions01(ByteOrder order, bool dynamicRead)
        {
            var rng = new Random();

            using (var stream = new MemoryStream())
                using (var reader = new EndianReader(stream, order))
                    using (var writer = new EndianWriter(stream, order))
                    {
                        reader.DynamicReadEnabled = dynamicRead;

                        var rand = new object[6];

                        rand[0] = rng.Next(int.MinValue, int.MaxValue);
                        writer.Write((int)rand[0]);

                        writer.Write(1);

                        rand[1] = (float)rng.NextDouble();
                        writer.Write((float)rand[1]);

                        rand[2] = (float)rng.NextDouble();
                        writer.Write((float)rand[2]);

                        rand[3] = (float)rng.NextDouble();
                        writer.Write((float)rand[3]);

                        rand[4] = rng.NextDouble();
                        writer.Write((double)rand[4]);

                        rand[5] = rng.NextDouble();
                        writer.Write((double)rand[5]);

                        stream.Position = 0;
                        var obj = (DataClass09)reader.ReadObject(typeof(DataClass09));

                        Assert.AreEqual(rand[0], obj.Property1);
                        Assert.AreEqual(1, obj.Version);
                        Assert.AreEqual(rand[1], obj.Property2);
                        Assert.IsNull(obj.Property3);
                        Assert.IsNull(obj.Property4);

                        stream.Position = 4;
                        writer.Write(2);
                        stream.Position = 0;

                        obj = (DataClass09)reader.ReadObject(typeof(DataClass09));

                        Assert.AreEqual(rand[0], obj.Property1);
                        Assert.AreEqual(2, obj.Version);
                        Assert.AreEqual(rand[2], obj.Property2);
                        Assert.AreEqual(rand[3], obj.Property3);
                        Assert.IsNull(obj.Property4);

                        stream.Position = 4;
                        writer.Write(3);
                        stream.Position = 0;

                        obj = (DataClass09)reader.ReadObject(typeof(DataClass09));

                        Assert.AreEqual(rand[0], obj.Property1);
                        Assert.AreEqual(3, obj.Version);
                        Assert.AreEqual(rand[2], obj.Property2);
                        Assert.AreEqual(rand[3], obj.Property3);
                        Assert.IsNull(obj.Property4);

                        stream.Position = 4;
                        writer.Write(4);
                        stream.Position = 0;

                        obj = (DataClass09)reader.ReadObject(typeof(DataClass09));

                        Assert.AreEqual(rand[0], obj.Property1);
                        Assert.AreEqual(4, obj.Version);
                        Assert.AreEqual(rand[2], obj.Property2);
                        Assert.IsNull(obj.Property3);
                        Assert.AreEqual(rand[4], obj.Property4);
                        Assert.AreEqual(rand[5], obj.Property5);
                    }
        }