Exemplo n.º 1
0
        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);
        }