Пример #1
0
        //Takes the file, splits it based upon which pointer accesses it.
        //Also modifies all pointers to be 0-based!
        public PointeredFile(string inFilename, byte[] rawData, byte[] subHeader, int[] ptrs, int baseAddr, bool useAsBigEndian)
        {
            isBigEndian = useAsBigEndian;

            header     = subHeader;
            filename   = inFilename;
            fileLength = BitConverter.ToInt32(rawData, 4);
            if (ptrs == null)
            {
                ptrs = new int[0];
            }
            var memStream  = new MemoryStream(rawData);
            var fileReader = BigEndianBinaryReader.GetEndianSpecificBinaryReader(memStream, useAsBigEndian);

            List <int> pointerDestinations = new List <int>(ptrs.Length + 1);

            memStream.Seek(8, SeekOrigin.Begin);

            int rootPtr = fileReader.ReadInt32();

            if (rootPtr < 0 || rootPtr >= rawData.Length)
            {
                markFileBroken(rawData, ptrs, baseAddr);
                return;
            }

            addToMaps(8, rootPtr);

            for (int i = 0; i < ptrs.Length; i++)
            {
                int effectivePtr = ptrs[i] - baseAddr;
                if (effectivePtr < 0 || effectivePtr >= rawData.Length)
                {
                    markFileBroken(rawData, ptrs, baseAddr);
                    return;
                }

                memStream.Seek(effectivePtr, SeekOrigin.Begin);
                int tempPtr = fileReader.ReadInt32();
                if (tempPtr - baseAddr < 0 || tempPtr - baseAddr > rawData.Length)
                {
                    markFileBroken(rawData, ptrs, baseAddr);
                    return;
                }
                addToMaps(effectivePtr, tempPtr - baseAddr);
            }

            int startAddr = 0;

            splitData = new List <FileChunk>(destinationToPointers.Count + 1);
            foreach (int dest in destinationToPointers.Keys.Union(new int[] { rawData.Length }).OrderBy(key => key))
            {
                memStream.Seek(startAddr, SeekOrigin.Begin);
                byte[] bytes = fileReader.ReadBytes(dest - startAddr);
                splitData.Add(new FileChunk {
                    chunkLocation = startAddr, contents = bytes
                });
                startAddr = dest;
            }
        }
Пример #2
0
        public SetFile(string inFilename, byte[] rawData, byte[] inHeader, int[] ptrs, int baseAddr, bool bigEndian = false)
        {
            header   = inHeader;
            filename = inFilename;  //Assuming they'll always base 0.
            MemoryStream transFile  = new MemoryStream(rawData);
            BinaryReader fileReader = BigEndianBinaryReader.GetEndianSpecificBinaryReader(transFile, bigEndian);

            transFile.Seek(8, SeekOrigin.Begin);
            int headerLoc = fileReader.ReadInt32();

            transFile.Seek(headerLoc, SeekOrigin.Begin);
            areaID = fileReader.ReadInt16();
            short mapCount        = fileReader.ReadInt16();
            int   mainListPointer = fileReader.ReadInt32() - baseAddr;

            mapData = new MapListing[mapCount];
            for (int i = 0; i < mapCount; i++)
            {
                transFile.Seek(mainListPointer + i * 12, SeekOrigin.Begin);
                mapData[i]           = new MapListing();
                mapData[i].mapNumber = fileReader.ReadInt16();
                short listCount = fileReader.ReadInt16();
                mapData[i].headers = new ListHeader[listCount];
                int listPtr = fileReader.ReadInt32() - baseAddr;
                for (int j = 0; j < listCount; j++)
                {
                    transFile.Seek(listPtr + j * 0x28, SeekOrigin.Begin);
                    mapData[i].headers[j]             = new ListHeader();
                    mapData[i].headers[j].headerBytes = fileReader.ReadBytes(34);
                    short listEntryCount = fileReader.ReadInt16();
                    mapData[i].headers[j].objects = new ObjectEntry[listEntryCount];
                    int objectListLoc = fileReader.ReadInt32() - baseAddr;
                    for (int k = 0; k < listEntryCount; k++)
                    {
                        transFile.Seek(objectListLoc + k * 0x34, SeekOrigin.Begin);
                        ObjectEntry temp = new ObjectEntry();
                        temp.startBytes     = fileReader.ReadBytes(14);
                        temp.objID          = fileReader.ReadInt16();
                        temp.unkInt1        = fileReader.ReadInt32();
                        temp.objX           = fileReader.ReadSingle();
                        temp.objY           = fileReader.ReadSingle();
                        temp.objZ           = fileReader.ReadSingle();
                        temp.objRotX        = fileReader.ReadSingle();
                        temp.objRotY        = fileReader.ReadSingle();
                        temp.objRotZ        = fileReader.ReadSingle();
                        temp.metadataLength = fileReader.ReadInt32();
                        int metadataLoc = fileReader.ReadInt32() - baseAddr;
                        transFile.Seek(metadataLoc, SeekOrigin.Begin);
                        temp.metadata = fileReader.ReadBytes(temp.metadataLength);
                        mapData[i].headers[j].objects[k] = temp;
                    }
                }
            }
        }
Пример #3
0
 private BinaryReader getBinaryReader(Stream s)
 {
     return(BigEndianBinaryReader.GetEndianSpecificBinaryReader(s, isBigEndian));
 }