private void ReadUOPFiles(string pattern) { m_UOPReader = new BinaryReader(m_Map); m_UOPReader.BaseStream.Seek(0, SeekOrigin.Begin); if (m_UOPReader.ReadInt32() != 0x50594D) { throw new ArgumentException("Bad UOP file."); } m_UOPReader.ReadInt64(); // version + signature long nextBlock = m_UOPReader.ReadInt64(); m_UOPReader.ReadInt32(); // block capacity int count = m_UOPReader.ReadInt32(); UOPFiles = new UOPFile[count]; Dictionary <ulong, int> hashes = new Dictionary <ulong, int>(); for (int i = 0; i < count; i++) { string file = string.Format("build/{0}/{1:D8}.dat", pattern, i); ulong hash = FileIndex.HashFileName(file); if (!hashes.ContainsKey(hash)) { hashes.Add(hash, i); } } m_UOPReader.BaseStream.Seek(nextBlock, SeekOrigin.Begin); do { int filesCount = m_UOPReader.ReadInt32(); nextBlock = m_UOPReader.ReadInt64(); for (int i = 0; i < filesCount; i++) { long offset = m_UOPReader.ReadInt64(); int headerLength = m_UOPReader.ReadInt32(); int compressedLength = m_UOPReader.ReadInt32(); int decompressedLength = m_UOPReader.ReadInt32(); ulong hash = m_UOPReader.ReadUInt64(); m_UOPReader.ReadUInt32(); // Adler32 short flag = m_UOPReader.ReadInt16(); int length = flag == 1 ? compressedLength : decompressedLength; if (offset == 0) { continue; } int idx; if (hashes.TryGetValue(hash, out idx)) { if (idx < 0 || idx > UOPFiles.Length) { throw new IndexOutOfRangeException( "hashes dictionary and files collection have different count of entries!"); } UOPFiles[idx] = new UOPFile(offset + headerLength, length); } else { throw new ArgumentException(string.Format( "File with hash 0x{0:X8} was not found in hashes dictionary! EA Mythic changed UOP format!", hash)); } } } while (m_UOPReader.BaseStream.Seek(nextBlock, SeekOrigin.Begin) != 0); }