Exemple #1
0
        /// <summary>
        /// Reads the map values
        /// </summary>
        public void Read()
        {
            // Read header
            Header.Read(ref InputStream);

            // determine if this is a pc map or not
            PC = Header.Version != VERSION.XBOX;

            // Move to the index table
            InputStream.Seek(Header.OffsetToIndex, SeekOrigin.Begin);

            // Read the index table and index elements
            IndexHeader.Read(ref InputStream, PC, ref magic, ref bspsMagic);
        }
Exemple #2
0
        /// <summary>
        /// Gets the index header.
        /// </summary>
        /// <param name="targetIndex">Index of the target.</param>
        /// <param name="indexTypeMapping">The index type mapping.</param>
        /// <param name="typeId">The type id.</param>
        /// <param name="primaryId">The primary id.</param>
        /// <param name="storeContext">The store context.</param>
        /// <returns>IndexHeader</returns>
        private static IndexHeader GetIndexHeader(CacheIndexInternal targetIndex,
                                                  IndexTypeMapping indexTypeMapping,
                                                  short typeId,
                                                  int primaryId,
                                                  IndexStoreContext storeContext)
        {
            IndexHeader indexHeader = new IndexHeader();

            #region Metadata

            if (indexTypeMapping.MetadataStoredSeperately)
            {
                #region Check if metadata is stored seperately

                //Send a get message to local index storage and fetch seperately stored metadata
                RelayMessage getMsg = new RelayMessage(typeId, primaryId, targetIndex.InDeserializationContext.IndexId, MessageType.Get);
                storeContext.IndexStorageComponent.HandleMessage(getMsg);
                if (getMsg.Payload != null)
                {
                    indexHeader.Metadata = getMsg.Payload.ByteArray;
                }

                #endregion
            }
            else
            {
                #region Check metadata on targetIndex

                if (indexTypeMapping.IndexCollection[targetIndex.InDeserializationContext.IndexName].MetadataPresent)
                {
                    indexHeader.Metadata = targetIndex.Metadata;
                }

                #endregion
            }

            #endregion

            #region VirtualCount

            indexHeader.VirtualCount = targetIndex.VirtualCount;

            #endregion

            return(indexHeader);
        }
Exemple #3
0
        public bool?VerifyMediaImage()
        {
            // This will traverse all blocks and check their CRC64 without uncompressing them
            DicConsole.DebugWriteLine("DiscImageChef format plugin", "Checking index integrity at {0}",
                                      header.indexOffset);
            imageStream.Position = (long)header.indexOffset;

            IndexHeader idxHeader = new IndexHeader();

            structureBytes = new byte[Marshal.SizeOf(idxHeader)];
            imageStream.Read(structureBytes, 0, structureBytes.Length);
            structurePointer = Marshal.AllocHGlobal(Marshal.SizeOf(idxHeader));
            Marshal.Copy(structureBytes, 0, structurePointer, Marshal.SizeOf(idxHeader));
            idxHeader = (IndexHeader)Marshal.PtrToStructure(structurePointer, typeof(IndexHeader));
            Marshal.FreeHGlobal(structurePointer);

            if (idxHeader.identifier != BlockType.Index)
            {
                DicConsole.DebugWriteLine("DiscImageChef format plugin", "Incorrect index identifier");
                return(false);
            }

            DicConsole.DebugWriteLine("DiscImageChef format plugin", "Index at {0} contains {1} entries",
                                      header.indexOffset, idxHeader.entries);

            structureBytes = new byte[Marshal.SizeOf(typeof(IndexEntry)) * idxHeader.entries];
            imageStream.Read(structureBytes, 0, structureBytes.Length);
            Crc64Context.Data(structureBytes, out byte[] verifyCrc);

            if (BitConverter.ToUInt64(verifyCrc, 0) != idxHeader.crc64)
            {
                DicConsole.DebugWriteLine("DiscImageChef format plugin", "Expected index CRC {0:X16} but got {1:X16}",
                                          idxHeader.crc64, BitConverter.ToUInt64(verifyCrc, 0));
                return(false);
            }

            imageStream.Position -= structureBytes.Length;

            List <IndexEntry> vrIndex = new List <IndexEntry>();

            for (ushort i = 0; i < idxHeader.entries; i++)
            {
                IndexEntry entry = new IndexEntry();
                structureBytes = new byte[Marshal.SizeOf(entry)];
                imageStream.Read(structureBytes, 0, structureBytes.Length);
                structurePointer = Marshal.AllocHGlobal(Marshal.SizeOf(entry));
                Marshal.Copy(structureBytes, 0, structurePointer, Marshal.SizeOf(entry));
                entry = (IndexEntry)Marshal.PtrToStructure(structurePointer, typeof(IndexEntry));
                Marshal.FreeHGlobal(structurePointer);
                DicConsole.DebugWriteLine("DiscImageChef format plugin",
                                          "Block type {0} with data type {1} is indexed to be at {2}", entry.blockType,
                                          entry.dataType, entry.offset);
                vrIndex.Add(entry);
            }

            // Read up to 1MiB at a time for verification
            const int VERIFY_SIZE = 1024 * 1024;

            foreach (IndexEntry entry in vrIndex)
            {
                imageStream.Position = (long)entry.offset;
                Crc64Context crcVerify;
                ulong        readBytes;
                byte[]       verifyBytes;

                switch (entry.blockType)
                {
                case BlockType.DataBlock:
                    BlockHeader blockHeader = new BlockHeader();
                    structureBytes = new byte[Marshal.SizeOf(blockHeader)];
                    imageStream.Read(structureBytes, 0, structureBytes.Length);
                    structurePointer = Marshal.AllocHGlobal(Marshal.SizeOf(blockHeader));
                    Marshal.Copy(structureBytes, 0, structurePointer, Marshal.SizeOf(blockHeader));
                    blockHeader = (BlockHeader)Marshal.PtrToStructure(structurePointer, typeof(BlockHeader));
                    Marshal.FreeHGlobal(structurePointer);

                    crcVerify = new Crc64Context();
                    readBytes = 0;

                    DicConsole.DebugWriteLine("DiscImageChef format plugin",
                                              "Verifying data block type {0} at position {1}", entry.dataType,
                                              entry.offset);

                    while (readBytes + VERIFY_SIZE < blockHeader.cmpLength)
                    {
                        verifyBytes = new byte[VERIFY_SIZE];
                        imageStream.Read(verifyBytes, 0, verifyBytes.Length);
                        crcVerify.Update(verifyBytes);
                        readBytes += (ulong)verifyBytes.LongLength;
                    }

                    verifyBytes = new byte[blockHeader.cmpLength - readBytes];
                    imageStream.Read(verifyBytes, 0, verifyBytes.Length);
                    crcVerify.Update(verifyBytes);

                    verifyCrc = crcVerify.Final();

                    if (BitConverter.ToUInt64(verifyCrc, 0) != blockHeader.cmpCrc64)
                    {
                        DicConsole.DebugWriteLine("DiscImageChef format plugin",
                                                  "Expected block CRC {0:X16} but got {1:X16}",
                                                  blockHeader.cmpCrc64, BitConverter.ToUInt64(verifyCrc, 0));
                        return(false);
                    }

                    break;

                case BlockType.DeDuplicationTable:
                    DdtHeader ddtHeader = new DdtHeader();
                    structureBytes = new byte[Marshal.SizeOf(ddtHeader)];
                    imageStream.Read(structureBytes, 0, structureBytes.Length);
                    structurePointer = Marshal.AllocHGlobal(Marshal.SizeOf(ddtHeader));
                    Marshal.Copy(structureBytes, 0, structurePointer, Marshal.SizeOf(ddtHeader));
                    ddtHeader = (DdtHeader)Marshal.PtrToStructure(structurePointer, typeof(DdtHeader));
                    Marshal.FreeHGlobal(structurePointer);

                    crcVerify = new Crc64Context();
                    readBytes = 0;

                    DicConsole.DebugWriteLine("DiscImageChef format plugin",
                                              "Verifying deduplication table type {0} at position {1}",
                                              entry.dataType, entry.offset);

                    while (readBytes + VERIFY_SIZE < ddtHeader.cmpLength)
                    {
                        verifyBytes = new byte[readBytes];
                        imageStream.Read(verifyBytes, 0, verifyBytes.Length);
                        crcVerify.Update(verifyBytes);
                        readBytes += (ulong)verifyBytes.LongLength;
                    }

                    verifyBytes = new byte[ddtHeader.cmpLength - readBytes];
                    imageStream.Read(verifyBytes, 0, verifyBytes.Length);
                    crcVerify.Update(verifyBytes);

                    verifyCrc = crcVerify.Final();

                    if (BitConverter.ToUInt64(verifyCrc, 0) != ddtHeader.cmpCrc64)
                    {
                        DicConsole.DebugWriteLine("DiscImageChef format plugin",
                                                  "Expected DDT CRC {0:X16} but got {1:X16}", ddtHeader.cmpCrc64,
                                                  BitConverter.ToUInt64(verifyCrc, 0));
                        return(false);
                    }

                    break;

                case BlockType.TracksBlock:
                    TracksHeader trkHeader = new TracksHeader();
                    structureBytes = new byte[Marshal.SizeOf(trkHeader)];
                    imageStream.Read(structureBytes, 0, structureBytes.Length);
                    structurePointer = Marshal.AllocHGlobal(Marshal.SizeOf(trkHeader));
                    Marshal.Copy(structureBytes, 0, structurePointer, Marshal.SizeOf(trkHeader));
                    trkHeader = (TracksHeader)Marshal.PtrToStructure(structurePointer, typeof(TracksHeader));
                    Marshal.FreeHGlobal(structurePointer);

                    DicConsole.DebugWriteLine("DiscImageChef format plugin",
                                              "Track block at {0} contains {1} entries", header.indexOffset,
                                              trkHeader.entries);

                    structureBytes = new byte[Marshal.SizeOf(typeof(TrackEntry)) * trkHeader.entries];
                    imageStream.Read(structureBytes, 0, structureBytes.Length);
                    Crc64Context.Data(structureBytes, out verifyCrc);

                    if (BitConverter.ToUInt64(verifyCrc, 0) != trkHeader.crc64)
                    {
                        DicConsole.DebugWriteLine("DiscImageChef format plugin",
                                                  "Expected index CRC {0:X16} but got {1:X16}", trkHeader.crc64,
                                                  BitConverter.ToUInt64(verifyCrc, 0));
                        return(false);
                    }

                    break;

                default:
                    DicConsole.DebugWriteLine("DiscImageChef format plugin", "Ignored field type {0}",
                                              entry.blockType);
                    break;
                }
            }

            return(true);
        }
Exemple #4
0
        public bool?VerifyMediaImage()
        {
            // This will traverse all blocks and check their CRC64 without uncompressing them
            AaruConsole.DebugWriteLine("Aaru Format plugin", "Checking index integrity at {0}", _header.indexOffset);
            _imageStream.Position = (long)_header.indexOffset;

            _structureBytes = new byte[Marshal.SizeOf <IndexHeader>()];
            _imageStream.Read(_structureBytes, 0, _structureBytes.Length);
            IndexHeader idxHeader = Marshal.SpanToStructureLittleEndian <IndexHeader>(_structureBytes);

            if (idxHeader.identifier != BlockType.Index)
            {
                AaruConsole.DebugWriteLine("Aaru Format plugin", "Incorrect index identifier");

                return(false);
            }

            AaruConsole.DebugWriteLine("Aaru Format plugin", "Index at {0} contains {1} entries", _header.indexOffset,
                                       idxHeader.entries);

            _structureBytes = new byte[Marshal.SizeOf <IndexEntry>() * idxHeader.entries];
            _imageStream.Read(_structureBytes, 0, _structureBytes.Length);
            Crc64Context.Data(_structureBytes, out byte[] verifyCrc);

            if (BitConverter.ToUInt64(verifyCrc, 0) != idxHeader.crc64)
            {
                AaruConsole.DebugWriteLine("Aaru Format plugin", "Expected index CRC {0:X16} but got {1:X16}",
                                           idxHeader.crc64, BitConverter.ToUInt64(verifyCrc, 0));

                return(false);
            }

            _imageStream.Position -= _structureBytes.Length;

            List <IndexEntry> vrIndex = new List <IndexEntry>();

            for (ushort i = 0; i < idxHeader.entries; i++)
            {
                _structureBytes = new byte[Marshal.SizeOf <IndexEntry>()];
                _imageStream.Read(_structureBytes, 0, _structureBytes.Length);
                IndexEntry entry = Marshal.SpanToStructureLittleEndian <IndexEntry>(_structureBytes);

                AaruConsole.DebugWriteLine("Aaru Format plugin",
                                           "Block type {0} with data type {1} is indexed to be at {2}", entry.blockType,
                                           entry.dataType, entry.offset);

                vrIndex.Add(entry);
            }

            // Read up to 1MiB at a time for verification
            const int verifySize = 1024 * 1024;

            foreach (IndexEntry entry in vrIndex)
            {
                _imageStream.Position = (long)entry.offset;
                Crc64Context crcVerify;
                ulong        readBytes;
                byte[]       verifyBytes;

                switch (entry.blockType)
                {
                case BlockType.DataBlock:
                    _structureBytes = new byte[Marshal.SizeOf <BlockHeader>()];
                    _imageStream.Read(_structureBytes, 0, _structureBytes.Length);
                    BlockHeader blockHeader = Marshal.SpanToStructureLittleEndian <BlockHeader>(_structureBytes);

                    crcVerify = new Crc64Context();
                    readBytes = 0;

                    AaruConsole.DebugWriteLine("Aaru Format plugin",
                                               "Verifying data block type {0} at position {1}", entry.dataType,
                                               entry.offset);

                    while (readBytes + verifySize < blockHeader.cmpLength)
                    {
                        verifyBytes = new byte[verifySize];
                        _imageStream.Read(verifyBytes, 0, verifyBytes.Length);
                        crcVerify.Update(verifyBytes);
                        readBytes += (ulong)verifyBytes.LongLength;
                    }

                    verifyBytes = new byte[blockHeader.cmpLength - readBytes];
                    _imageStream.Read(verifyBytes, 0, verifyBytes.Length);
                    crcVerify.Update(verifyBytes);

                    verifyCrc = crcVerify.Final();

                    if (BitConverter.ToUInt64(verifyCrc, 0) != blockHeader.cmpCrc64)
                    {
                        AaruConsole.DebugWriteLine("Aaru Format plugin",
                                                   "Expected block CRC {0:X16} but got {1:X16}",
                                                   blockHeader.cmpCrc64, BitConverter.ToUInt64(verifyCrc, 0));

                        return(false);
                    }

                    break;

                case BlockType.DeDuplicationTable:
                    _structureBytes = new byte[Marshal.SizeOf <DdtHeader>()];
                    _imageStream.Read(_structureBytes, 0, _structureBytes.Length);
                    DdtHeader ddtHeader = Marshal.SpanToStructureLittleEndian <DdtHeader>(_structureBytes);

                    crcVerify = new Crc64Context();
                    readBytes = 0;

                    AaruConsole.DebugWriteLine("Aaru Format plugin",
                                               "Verifying deduplication table type {0} at position {1}",
                                               entry.dataType, entry.offset);

                    while (readBytes + verifySize < ddtHeader.cmpLength)
                    {
                        verifyBytes = new byte[readBytes];
                        _imageStream.Read(verifyBytes, 0, verifyBytes.Length);
                        crcVerify.Update(verifyBytes);
                        readBytes += (ulong)verifyBytes.LongLength;
                    }

                    verifyBytes = new byte[ddtHeader.cmpLength - readBytes];
                    _imageStream.Read(verifyBytes, 0, verifyBytes.Length);
                    crcVerify.Update(verifyBytes);

                    verifyCrc = crcVerify.Final();

                    if (BitConverter.ToUInt64(verifyCrc, 0) != ddtHeader.cmpCrc64)
                    {
                        AaruConsole.DebugWriteLine("Aaru Format plugin", "Expected DDT CRC {0:X16} but got {1:X16}",
                                                   ddtHeader.cmpCrc64, BitConverter.ToUInt64(verifyCrc, 0));

                        return(false);
                    }

                    break;

                case BlockType.TracksBlock:
                    _structureBytes = new byte[Marshal.SizeOf <TracksHeader>()];
                    _imageStream.Read(_structureBytes, 0, _structureBytes.Length);
                    TracksHeader trkHeader = Marshal.SpanToStructureLittleEndian <TracksHeader>(_structureBytes);

                    AaruConsole.DebugWriteLine("Aaru Format plugin", "Track block at {0} contains {1} entries",
                                               _header.indexOffset, trkHeader.entries);

                    _structureBytes = new byte[Marshal.SizeOf <TrackEntry>() * trkHeader.entries];
                    _imageStream.Read(_structureBytes, 0, _structureBytes.Length);
                    Crc64Context.Data(_structureBytes, out verifyCrc);

                    if (BitConverter.ToUInt64(verifyCrc, 0) != trkHeader.crc64)
                    {
                        AaruConsole.DebugWriteLine("Aaru Format plugin",
                                                   "Expected index CRC {0:X16} but got {1:X16}", trkHeader.crc64,
                                                   BitConverter.ToUInt64(verifyCrc, 0));

                        return(false);
                    }

                    break;

                default:
                    AaruConsole.DebugWriteLine("Aaru Format plugin", "Ignored field type {0}", entry.blockType);

                    break;
                }
            }

            return(true);
        }
        public void Load(string file)
        {
            filename = file;
            string directory = Path.GetDirectoryName(file) + '\\';

            #region open maps
            shared = new SharedMaps(new FileStream(directory + MainMenu, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), new FileStream(directory + Shared, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), new FileStream(directory + SinglePlayerShared, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));

            map    = new FileStream(file, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
            reader = new BinaryReader(map);
            writer = new BinaryWriter(map);
            #endregion

            #region header and index
            header       = Reinterpret.Memory <MapHeader>(reader.ReadBytes(Marshal.SizeOf(typeof(MapHeader))));
            map.Position = header.IndexOffset;
            index        = Reinterpret.Memory <IndexHeader>(reader.ReadBytes(Marshal.SizeOf(typeof(IndexHeader))));
            magic        = (index.MagicConstant - header.IndexOffset - Marshal.SizeOf(typeof(IndexHeader))) + (header.AllExceptRawLength - header.IndexAndMetaLength - header.IndexLength);

            // each "TagType" is three dwords
            map.Position += 12 * index.TagTypeCount;

            tags = new List <IndexElement>(index.TagCount);
            for (int i = 0; i < index.TagCount; i++)
            {
                tags.Add(Reinterpret.Memory <IndexElement>(reader.ReadBytes(Marshal.SizeOf(typeof(IndexElement)))));
            }
            #endregion

            #region bsps
            int bspCount  = 0;
            int bspOffset = 0;

            if (header.HeadSignature == HeadSignature)
            {
                map.Position = 528 + unchecked (tags[LocateTagByID(index.ScenarioIdentifier)].Offset - magic);
                bspCount     = reader.ReadInt32();
                bspOffset    = unchecked (reader.ReadInt32() - magic);

                bsps = new Bsp[bspCount];
                for (int i = 0; i < bspCount; i++)
                {
                    bsps[i]      = new Bsp();
                    map.Position = bsps[i].LocationInScenario = bspOffset + 68 * i;

                    bsps[i].BspHeaderOffset = reader.ReadInt32();
                    int totalBspSize = reader.ReadInt32();
                    bsps[i].Magic = reader.ReadInt32();

                    map.Position      += 8;
                    bsps[i].BspID      = reader.ReadInt32();
                    map.Position      += 4;
                    bsps[i].LightmapID = reader.ReadInt32();

                    /*
                     * HEADER FORMAT
                     * total size
                     * pointer to bsp location
                     * pointer to lightmap location
                     * 'sbsp'
                     */

                    map.Position = bsps[i].BspHeaderOffset;
                    int inHeaderBspSize   = reader.ReadInt32();
                    int inHeaderBspOffset = reader.ReadInt32();
                    int lightmapOffset    = reader.ReadInt32();
                    bsps[i].BspOffset = (inHeaderBspOffset - bsps[i].Magic) + bsps[i].BspHeaderOffset;

                    if (bsps[i].LightmapID == -1)
                    {
                        bsps[i].BspSize = inHeaderBspSize;
                    }
                    else
                    {
                        bsps[i].LightmapOffset = unchecked (lightmapOffset - bsps[i].Magic) + bsps[i].BspHeaderOffset;
                        bsps[i].BspSize        = bsps[i].LightmapOffset - bsps[i].BspOffset;
                        bsps[i].LightmapSize   = totalBspSize - bsps[i].BspSize;
                    }
                }
            }
            #endregion

            #region strings
            strings      = new List <string>(header.StringIdCount);
            map.Position = header.StringIdTableOffset;
            for (int i = 0; i < header.StringIdCount; i++)
            {
                strings.Add(String.Empty);
                while (true)
                {
                    byte character = reader.ReadByte();
                    if (character == 0)
                    {
                        break;
                    }
                    else
                    {
                        strings[i] += Convert.ToChar(character);
                    }
                }
            }
            string[] stringArray = strings.ToArray();
            #endregion

            #region names
            map.Position      = header.NameTableOffset;
            names             = new List <string>(header.NameTableCount);
            dictionary        = new Dictionary <int, string>(header.NameTableCount);
            inverseDictionary = new Dictionary <string, int>(header.NameTableCount);

            for (int i = 0; i < header.NameTableCount; i++)
            {
                names.Add(String.Empty);
                while (true)
                {
                    byte character = reader.ReadByte();
                    if (character == 0)
                    {
                        break;
                    }
                    else
                    {
                        names[i] += Convert.ToChar(character);
                    }
                }

                string dictionaryName = names[i] + '.' + Singleton <ClassManager> .Instance.GetClassByID(tags[i].Type).Name;

                dictionary.Add(tags[i].Identifier, dictionaryName);
                inverseDictionary.Add(dictionaryName, tags[i].Identifier);
            }
            #endregion

            #region globals and coconuts
            if (header.HeadSignature == HeadSignature)
            {
                map.Position = unchecked (tags[LocateTagByID(index.GlobalsIdentifier)].Offset - magic);
                globals      = new Globals(reader);

                map.Position = unchecked (tags[index.TagCount - 1].Offset - magic);
                coconuts     = new Coconuts(reader, shared, magic, stringArray);
            }
            #endregion

            #region composition
            if (header.HeadSignature == HeadSignature)
            {
                for (int i = 0; i < index.TagCount; i++)
                {
                    int result;

                    switch (tags[i].Type)
                    {
                    case Animation:
                        map.Position = unchecked (tags[i].Offset - magic);
                        result       = Tag.GetFirstInternalResourceOffset(reader, Animation, magic);
                        if (result != -1)
                        {
                            if (result < animationStart || animationStart == -1)
                            {
                                animationStart = result;
                            }
                        }
                        break;

                    case Decorators:
                        map.Position = unchecked (tags[i].Offset - magic);
                        result       = Tag.GetFirstInternalResourceOffset(reader, Decorators, magic);
                        if (result != -1)
                        {
                            if (result < decoratorStart || decoratorStart == -1)
                            {
                                decoratorStart = result;
                            }
                        }
                        break;

                    case ParticleModel:
                        map.Position = unchecked (tags[i].Offset - magic);
                        result       = Tag.GetFirstInternalResourceOffset(reader, ParticleModel, magic);
                        if (result != -1)
                        {
                            if (result < particleModelStart || particleModelStart == -1)
                            {
                                particleModelStart = result;
                            }
                        }
                        break;

                    case WeatherSystem:
                        map.Position = unchecked (tags[i].Offset - magic);
                        result       = Tag.GetFirstInternalResourceOffset(reader, WeatherSystem, magic);
                        if (result != -1)
                        {
                            if (result < weatherStart || weatherStart == -1)
                            {
                                weatherStart = result;
                            }
                        }
                        break;

                    case RenderModel:
                        map.Position = unchecked (tags[i].Offset - magic);
                        result       = Tag.GetFirstInternalResourceOffset(reader, RenderModel, magic);
                        if (result != -1)
                        {
                            if (result < modelStart || modelStart == -1)
                            {
                                modelStart = result;
                            }
                        }
                        break;
                    }
                }

                // this is (should be anyways) constant
                soundStart = Marshal.SizeOf(typeof(MapHeader));

                // this is a calculated value
                bitmapStart = header.CrazyDataOffset + header.CrazyDataSize;

                for (int i = 0; i < bspCount; i++)
                {
                    Bsp bsp = bsps[i];
                    if (bsp.BspOffset < bspMetaStart || bspMetaStart == -1)
                    {
                        bspMetaStart = bsp.BspHeaderOffset;
                    }
                    else if (bsp.LightmapOffset < bspMetaStart || bspMetaStart == -1)
                    {
                        bspMetaStart = bsp.BspHeaderOffset;
                    }

                    int result;

                    if (bsp.BspID != -1)
                    {
                        reader.BaseStream.Position = bsp.BspOffset;
                        result = Tag.GetFirstInternalResourceOffset(reader, StructureBsp, bsp.Magic - bsp.BspHeaderOffset);
                        if (result != -1)
                        {
                            if (result < bspRawStart || bspRawStart == -1 && result != -1)
                            {
                                bspRawStart = result;
                            }
                        }
                    }

                    if (bsp.LightmapID != -1)
                    {
                        reader.BaseStream.Position = bsp.LightmapOffset;
                        result = Tag.GetFirstInternalResourceOffset(reader, StructureLightmap, bsp.Magic - bsp.BspHeaderOffset);
                        if (result != -1)
                        {
                            if (result < bspRawStart || bspRawStart == -1)
                            {
                                bspRawStart = result;
                            }
                        }
                    }
                }

                foreach (Coconuts.ExtraInfo extraInfo in coconuts.ExtraInfos)
                {
                    if (extraInfo.ResourceBlock.RawSize > 0)
                    {
                        uint encoded = Conversion.ToUInt(extraInfo.ResourceBlock.RawOffset);
                        if ((encoded & 0xc0000000) == 0)
                        {
                            if (extraInfo.ResourceBlock.RawOffset < coconutsModelStart || coconutsModelStart == -1)
                            {
                                coconutsModelStart = extraInfo.ResourceBlock.RawOffset;
                            }
                        }
                    }
                }

                if (bspMetaStart < 0)
                {
                    bspMetaStart = header.StringIdPaddedOffset;
                }
                if (animationStart < 0)
                {
                    animationStart = bspMetaStart;
                }
                if (coconutsModelStart < 0)
                {
                    coconutsModelStart = animationStart;
                }
                if (particleModelStart < 0)
                {
                    particleModelStart = coconutsModelStart;
                }
                if (decoratorStart < 0)
                {
                    decoratorStart = particleModelStart;
                }
                if (weatherStart < 0)
                {
                    weatherStart = decoratorStart;
                }
                if (bspRawStart < 0)
                {
                    bspRawStart = weatherStart;
                }
                if (modelStart < 0)
                {
                    modelStart = bspRawStart;
                }

                // these are all duplicates
                stringPaddedStart = header.StringIdPaddedOffset;
                stringIndexStart  = header.StringIdIndexOffset;
                stringTableStart  = header.StringIdTableOffset;
                nameTableStart    = header.NameTableOffset;
                nameIndexStart    = header.NameIndexOffset;
                crazyStart        = header.CrazyDataOffset;

                // this can be calculated a multitude of ways
                unicodeStart = header.NameIndexOffset + header.NameTableCount * sizeof(int);
            }
            #endregion

            valid = true;
        }
        /// <summary>
        /// Gets the index header.
        /// </summary>
        /// <param name="internalIndexDictionary">The internal index dictionary.</param>
        /// <param name="indexId">The index id.</param>
        /// <param name="query">The query.</param>
        /// <param name="indexTypeMapping">The index type mapping.</param>
        /// <param name="typeId">The type id.</param>
        /// <param name="primaryId">The primary id.</param>
        /// <param name="extendedId">The extended id.</param>
        /// <param name="storeContext">The store context.</param>
        /// <returns>IndexHeader</returns>
        private static IndexHeader GetIndexHeader(Dictionary <KeyValuePair <byte[], string>, CacheIndexInternal> internalIndexDictionary,
                                                  CacheIndexInternal targetIndexCacheIndexInternal,
                                                  byte[] indexId,
                                                  BaseMultiIndexIdQuery <TQueryResult> query,
                                                  IndexTypeMapping indexTypeMapping,
                                                  short typeId,
                                                  IndexStoreContext storeContext)
        {
            IndexHeader indexHeader = new IndexHeader();
            KeyValuePair <byte[] /*IndexId */, string /*IndexName*/> kvp;

            #region Metadata

            if (CheckMetaData(internalIndexDictionary, indexTypeMapping))
            {
                if (indexTypeMapping.MetadataStoredSeperately)
                {
                    #region Check if metadata is stored seperately

                    //Send a get message to local index storage and fetch seperately stored metadata
                    RelayMessage getMsg = new RelayMessage(typeId, IndexCacheUtils.GeneratePrimaryId(indexId), indexId, MessageType.Get);
                    storeContext.IndexStorageComponent.HandleMessage(getMsg);

                    if (getMsg.Payload != null)
                    {
                        indexHeader.Metadata = getMsg.Payload.ByteArray;
                    }

                    #endregion
                }
                else
                {
                    #region Check metadata on targetIndex

                    if (indexTypeMapping.IndexCollection[query.TargetIndexName].MetadataPresent)
                    {
                        indexHeader.Metadata = targetIndexCacheIndexInternal.Metadata;
                    }

                    #endregion

                    #region Check metadata on other extracted indexes

                    if (query.TagsFromIndexes != null)
                    {
                        foreach (string indexName in query.TagsFromIndexes)
                        {
                            if (indexTypeMapping.IndexCollection[indexName].MetadataPresent)
                            {
                                indexHeader.Metadata = internalIndexDictionary[new KeyValuePair <byte[], string>(indexId, indexName)].Metadata;
                            }
                        }
                    }

                    #endregion
                }
            }

            #endregion

            #region VirtualCount

            indexHeader.VirtualCount = targetIndexCacheIndexInternal.VirtualCount;

            #endregion

            return(indexHeader);
        }
Exemple #7
0
 internal void Dump()
 {
     Console.WriteLine(Helpers.Indent(2) + "BVcn 0x{0:X8}",
                       IndexBlockVcn);
     IndexHeader.Dump();
 }