Beispiel #1
0
        public void GetSignature()
        {
            // Arrage
            var mver = new MVER();

            // Act
            string result = mver.GetSignature();

            // Assert
            Assert.AreEqual(result, "MVER");
        }
Beispiel #2
0
        public void LoadBinaryData()
        {
            // Arrage
            MVER mver = new MVER();

            // Act
            byte[] dataWithoutSignature = adt.Skip(0x4).ToArray();
            mver.LoadBinaryData(dataWithoutSignature);

            // Assert
            Assert.AreEqual(mver.Version, (uint)4);
        }
Beispiel #3
0
        public void Serialize()
        {
            // Arrage
            var mver = new MVER()
            {
                Version = 4
            };

            // Act
            byte[] result = mver.Serialize();

            // Assert
            CollectionAssert.AreEqual(result, new byte[] { 0x4, 0x0, 0x0, 0x0 });
        }
Beispiel #4
0
        public void GetSize()
        {
            // Arrage
            var mver = new MVER()
            {
                Version = 4
            };

            // Act
            uint result = mver.GetSize();

            // Assert
            Assert.AreEqual(result, (uint)4);
        }
        public TEX0(Files.WOTLK.ADT wotlk)
        {
            ADTfileInfo = new FileInfo(wotlk.ADTfileInfo.Name.Split('.')[0] + "_tex0.adt");
            Logger.log(ADTfileInfo.Name, Logger.Type.CONVERT, "<- " + wotlk.ADTfileInfo.Name);

            MVER = new MVER(wotlk.MVER);
            MAMP = new MAMP();
            MTEX = new MTEX(wotlk.MTEX);

            foreach (Files.WOTLK.Chunks.MCNK x in wotlk.MCNKs)
            {
                MCNKs.Add(new MCNK_TEX0(x));
                //MCNKLength += MCNKs[MCNKs.Count - 1].GetBytes().Length;
            }
            Logger.log("MCNK[]", Logger.Type.LEVEL1);
        }
        public OBJ1(Files.WOTLK.ADT wotlk)
        {
            ADTfileInfo = new FileInfo(wotlk.ADTfileInfo.Name.Split('.')[0] + "_obj1.adt");
            Logger.log(ADTfileInfo.Name, Logger.Type.CONVERT, "<- " + wotlk.ADTfileInfo.Name);

            MVER = new MVER(wotlk.MVER);
            MLFD = new MLFD(wotlk.MDDF, wotlk.MODF); //I'm not sure the chunk is really needed.
            MMDX = new MMDX(wotlk.MMDX);
            MMID = new MMID(wotlk.MMID);
            MWMO = new MWMO(wotlk.MWMO);
            MWID = new MWID(wotlk.MWID);
            MLDD = new MLDD(wotlk.MDDF);
            MLDX = new MLDX(wotlk.MDDF);
            MLMD = new MLMD(wotlk.MODF);
            MLMX = new MLMX(wotlk.MODF);
        }
Beispiel #7
0
        bool PrepareLoadedData()
        {
            FileChunk chunk = GetChunk("MVER");

            if (chunk == null)
            {
                return(false);
            }

            // Check version
            MVER version = chunk.As <MVER>();

            if (version.Version != 18)
            {
                return(false);
            }

            return(true);
        }
        public OBJ0(Files.WOTLK.ADT wotlk)
        {
            ADTfileInfo = new FileInfo(wotlk.ADTfileInfo.Name.Split('.')[0] + "_obj0.adt");
            Logger.log(ADTfileInfo.Name, Logger.Type.CONVERT, "<- " + wotlk.ADTfileInfo.Name);

            MVER = new MVER(wotlk.MVER);
            MMDX = new MMDX(wotlk.MMDX);
            MMID = new MMID(wotlk.MMID);
            MWMO = new MWMO(wotlk.MWMO);
            MWID = new MWID(wotlk.MWID);
            MDDF = new MDDF(wotlk.MDDF);
            MODF = new MODF(wotlk.MODF);

            foreach (Files.WOTLK.Chunks.MCNK x in wotlk.MCNKs)
            {
                MCNKs.Add(new MCNK_OBJ0(x));
                MCNKLength += MCNKs[MCNKs.Count - 1].GetBytes().Length;
            }
            Logger.log("MCNK[]", Logger.Type.LEVEL1);
        }
Beispiel #9
0
        public ADT(Files.WOTLK.ADT wotlk)
        {
            ADTfileInfo = new FileInfo(wotlk.ADTfileInfo.Name.Split('.')[0] + ".adt");
            Logger.log(ADTfileInfo.Name, Logger.Type.CONVERT, "<- " + wotlk.ADTfileInfo.Name);


            MVER = new MVER(wotlk.MVER);
            MHDR = new MHDR(wotlk.MHDR);

            if (wotlk.MH2O != null)
            {
                MH2O = new MH2O(wotlk.MH2O);
            }

            foreach (Files.WOTLK.Chunks.MCNK x in wotlk.MCNKs)
            {
                MCNKs.Add(new MCNK_ADT(x));
                MCNKLength += MCNKs[MCNKs.Count - 1].GetBytes().Length;
            }
            Logger.log("MCNK[]", Logger.Type.LEVEL1);

            if (wotlk.MFBO != null)
            {
                MFBO = new MFBO(wotlk.MFBO);
            }
            else if (YetAnotherAdtConverter.Program.config.CreateMFBO)
            {
                UInt32 address = 0;
                MFBO = new MFBO();

                address += (UInt32)MHDR.Header.Byte_size;

                if (MH2O != null)
                {
                    address += (UInt32)MH2O.GetBytes().Length;
                }

                address += (UInt32)MCNKLength;
                MHDR.UpdateMFBO(address);
            }
        }
Beispiel #10
0
        public ADT(string filePath)
        {
            ADTfileInfo = new FileInfo(filePath);

            Logger.log(ADTfileInfo.Name, Logger.Type.READ, ADTfileInfo.DirectoryName);

            //Start reading the .ADT File
            using (BinaryReader reader = new BinaryReader(ADTfileInfo.Open(FileMode.Open)))
            {
                Length = (int)reader.BaseStream.Length;
                reader.BaseStream.Seek(0, SeekOrigin.Begin);
                int MCNK_counter = 0;
                int MCNK_size    = 0;

                while (reader.BaseStream.Position < reader.BaseStream.Length)
                {
                    byte[] ChunkMagic   = reader.ReadBytes(4);
                    byte[] ChunkSize    = reader.ReadBytes(4);
                    byte[] ChunkContent = reader.ReadBytes(BitConverter.ToInt32(ChunkSize, 0));

                    string ChunkMagicString = MagicBytesToString(ChunkMagic);
                    //read the chunks
                    switch (ChunkMagicString)
                    {
                    case "MVER":
                        MVER = new MVER(MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent);
                        break;

                    case "MHDR":
                        MHDR = new MHDR(MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent);
                        break;

                    case "MCIN":
                        MCIN = new MCIN(MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent);
                        break;

                    case "MTEX":
                        MTEX = new MTEX(MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent);
                        break;

                    case "MMDX":
                        MMDX = new MMDX(MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent);
                        break;

                    case "MMID":
                        MMID = new MMID(MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent);
                        break;

                    case "MWMO":
                        MWMO = new MWMO(MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent);
                        break;

                    case "MWID":
                        MWID = new MWID(MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent);
                        break;

                    case "MDDF":
                        MDDF = new MDDF(MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent);
                        break;

                    case "MODF":
                        MODF = new MODF(MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent);
                        break;

                    case "MH2O":
                        MH2O = new MH2O(MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent);
                        break;

                    case "MCNK":
                        MCNKs.Add(new MCNK(MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent));
                        break;

                    case "MFBO":
                        MFBO = new MFBO(MagicBytesToChars(ChunkMagic), ChunkSize, ChunkContent);
                        break;
                    }

                    if (ChunkMagicString == "MCNK")
                    {
                        MCNK_counter++; MCNK_size += BitConverter.ToInt32(ChunkSize, 0);
                    }
                    else if (ChunkMagicString == "\0\0\0\0") /*Logger.log("0 Byte Chunk", Logger.Direction.WARNING);*/ } {
            }

            if (MCNK_counter > 0)
            {
                Logger.log("MCNK[]", Logger.Type.LEVEL1, MCNK_size + " byte");
            }
        }
    }
Beispiel #11
0
        private void parseFile()
        {
            FileStream ms = adtStream;

            if (ms == null)
            {
                throw new Exception("Stream null!");
            }
            BinaryReader bin = new BinaryReader(ms);

            BlizChunkHeader tempHeader;
            long            pos = 0;

            // Read bytes from the stream until we run out
            while (pos < ms.Length)
            {
                // Advance to the next Chunk
                ms.Position = pos;

                // Read in Chunk Header Name
                tempHeader = new BlizChunkHeader(bin.ReadChars(4), bin.ReadUInt32());
                tempHeader.Flip();

                // Set pos to the location of the next Chunk
                pos = ms.Position + tempHeader.Size;

                if (tempHeader.Is("MVER"))   // ADT File Version
                {
                    mver         = new MVER();
                    mver.version = bin.ReadUInt32();

                    continue;
                }

                if (tempHeader.Is("MHDR"))  // ADT File Header
                {
                    mhdr                   = new MHDR();
                    mhdr.pad               = bin.ReadUInt32();
                    mhdr.offsInfo          = bin.ReadUInt32();
                    mhdr.offsTex           = bin.ReadUInt32();
                    mhdr.offsModels        = bin.ReadUInt32();
                    mhdr.offsModelsIds     = bin.ReadUInt32();
                    mhdr.offsMapObejcts    = bin.ReadUInt32();
                    mhdr.offsMapObejctsIds = bin.ReadUInt32();
                    mhdr.offsDoodsDef      = bin.ReadUInt32();
                    mhdr.offsObjectsDef    = bin.ReadUInt32();
                    mhdr.pad1              = bin.ReadUInt32();
                    mhdr.pad2              = bin.ReadUInt32();
                    mhdr.pad3              = bin.ReadUInt32();
                    mhdr.pad4              = bin.ReadUInt32();
                    mhdr.pad5              = bin.ReadUInt32();
                    mhdr.pad6              = bin.ReadUInt32();
                    mhdr.pad7              = bin.ReadUInt32();

                    continue;
                }

                if (tempHeader.Is("MCIN"))  // Index for MCNK chunks.
                {
                    if (tempHeader.Size != 256 * 16)
                    {
                        throw new Exception("MCIN Chunk is short??");
                    }

                    mcin_array = new MCIN[256];

                    // Read in the 256 records
                    for (int i = 0; i < 256; i++)
                    {
                        mcin_array[i].MCNK_offset = bin.ReadUInt32();
                        mcin_array[i].MCNK_size   = bin.ReadUInt32();
                        mcin_array[i].flags       = bin.ReadUInt32();
                        mcin_array[i].asyncID     = bin.ReadUInt32();
                    }

                    continue;
                }

                if (tempHeader.Is("MTEX"))  // List of texture filenames used by the terrain in this map tile.
                {
                    // Not needed.
                    continue;
                }

                if (tempHeader.Is("MMDX")) // List of filenames for M2 models that appear in this map tile.
                {
                    // Not needed.
                    continue;
                }

                if (tempHeader.Is("MMID"))  // Lists the relative offsets of string beginnings in the above MMDX chunk.
                {
                    // Not needed.
                    continue;
                }

                if (tempHeader.Is("MWMO"))  // List of filenames for WMOs (world map objects) that appear in this map tile.
                {
                    byte[] wmoFilesChunk = bin.ReadBytes((int)tempHeader.Size);

                    wmoFiles = new List <String>();

                    StringBuilder str = new StringBuilder();

                    // Convert szString's to a List<String>.
                    for (int i = 0; i < wmoFilesChunk.Length; i++)
                    {
                        if (wmoFilesChunk[i] == '\0')
                        {
                            if (str.Length > 1)
                            {
                                wmoFiles.Add(str.ToString());
                            }
                            str = new StringBuilder();
                        }
                        else
                        {
                            str.Append((char)wmoFilesChunk[i]);
                        }
                    }

                    continue;
                }

                if (tempHeader.Is("MWID"))  // Lists the relative offsets of string beginnings in the above MWWO chunk.
                {
                    // Not needed.
                    continue;
                }

                if (tempHeader.Is("MDDF"))  // Placement information for doodads (M2 models).
                {
                    uint num = tempHeader.Size / 32;

                    doodadLocations = new MDDF[num];

                    for (int i = 0; i < num; i++)
                    {
                        doodadLocations[i].nameId   = bin.ReadUInt32();
                        doodadLocations[i].uniqueId = bin.ReadUInt32();
                        doodadLocations[i].coord    = new Coordinate(bin.ReadSingle(), bin.ReadSingle(), bin.ReadSingle());
                    }

                    continue;
                }

                if (tempHeader.Is("MODF"))  // Placement information for WMOs.
                {
                    uint num = tempHeader.Size / 64;

                    wmoLocations = new MODF[num];

                    for (int i = 0; i < num; i++)
                    {
                        wmoLocations[i].nameId      = bin.ReadUInt32();
                        wmoLocations[i].uniqueId    = bin.ReadUInt32();
                        wmoLocations[i].coord       = new Coordinate(bin.ReadSingle(), bin.ReadSingle(), bin.ReadSingle());
                        wmoLocations[i].orientation = new Vect3D(bin.ReadSingle(), bin.ReadSingle(), bin.ReadSingle());
                        wmoLocations[i].coord2      = new Coordinate(bin.ReadSingle(), bin.ReadSingle(), bin.ReadSingle());
                        wmoLocations[i].coord3      = new Coordinate(bin.ReadSingle(), bin.ReadSingle(), bin.ReadSingle());
                        wmoLocations[i].flags       = bin.ReadUInt32();
                        wmoLocations[i].doodadSet   = bin.ReadUInt16();
                        wmoLocations[i].nameSet     = bin.ReadUInt16();
                    }

                    continue;
                }

                if (tempHeader.Is("MCNK")) // || tempHeader.Is("MCVT") || tempHeader.Is("MCNR") || tempHeader.Is("MCLY") || tempHeader.Is("MCRF") || tempHeader.Is("MCSH") || tempHeader.Is("MCAL") || tempHeader.Is("MCLQ") || tempHeader.Is("MCSE"))
                {
                    // Skip these. They are read in afterwards.
                    continue;
                }

                // If we're still down here, we got a problem
                throw new Exception(String.Format("ADTFile: Woah. Got a header of {0}. Don't know how to deal with this, bailing out.", tempHeader.ToString()));
            }

            // Read in Map Chunks
            mapChunkTable = new MCNK[16][];

            for (int i = 0; i < 16; i++)
            {
                mapChunkTable[i] = new MCNK[16];

                for (int j = 0; j < 16; j++)
                {
                    int index = i * 16 + j;
                    Log.WriteLine(LogType.Terrain, "Parsing MCNK Chunk #{0} [{1}, {2}]", index, i, j);
                    mapChunkTable[i][j] = parseMapChunk(ms, mcin_array[index].MCNK_offset, mcin_array[index].MCNK_size);
                }
            }
        }
Beispiel #12
0
        private void parseFile()
        {
            FileStream ms = adtStream;
            if (ms == null)
            {
                throw new Exception("Stream null!");
            }
            BinaryReader bin = new BinaryReader(ms);

            BlizChunkHeader tempHeader;
            long pos = 0;

            // Read bytes from the stream until we run out
            while (pos < ms.Length)
            {
                // Advance to the next Chunk
                ms.Position = pos;

                // Read in Chunk Header Name
                tempHeader = new BlizChunkHeader(bin.ReadChars(4), bin.ReadUInt32());
                tempHeader.Flip();

                // Set pos to the location of the next Chunk
                pos = ms.Position + tempHeader.Size;

                if (tempHeader.Is("MVER"))   // ADT File Version
                {
                    mver = new MVER();
                    mver.version = bin.ReadUInt32();

                    continue;
                }

                if (tempHeader.Is("MHDR"))  // ADT File Header
                {
                    mhdr = new MHDR();
                    mhdr.pad = bin.ReadUInt32();
                    mhdr.offsInfo = bin.ReadUInt32();
                    mhdr.offsTex = bin.ReadUInt32();
                    mhdr.offsModels = bin.ReadUInt32();
                    mhdr.offsModelsIds = bin.ReadUInt32();
                    mhdr.offsMapObejcts = bin.ReadUInt32();
                    mhdr.offsMapObejctsIds = bin.ReadUInt32();
                    mhdr.offsDoodsDef = bin.ReadUInt32();
                    mhdr.offsObjectsDef = bin.ReadUInt32();
                    mhdr.pad1 = bin.ReadUInt32();
                    mhdr.pad2 = bin.ReadUInt32();
                    mhdr.pad3 = bin.ReadUInt32();
                    mhdr.pad4 = bin.ReadUInt32();
                    mhdr.pad5 = bin.ReadUInt32();
                    mhdr.pad6 = bin.ReadUInt32();
                    mhdr.pad7 = bin.ReadUInt32();

                    continue;
                }

                if (tempHeader.Is("MCIN"))  // Index for MCNK chunks.
                {
                    if (tempHeader.Size != 256 * 16)
                        throw new Exception("MCIN Chunk is short??");

                    mcin_array = new MCIN[256];

                    // Read in the 256 records
                    for (int i = 0; i < 256; i++)
                    {
                        mcin_array[i].MCNK_offset = bin.ReadUInt32();
                        mcin_array[i].MCNK_size = bin.ReadUInt32();
                        mcin_array[i].flags = bin.ReadUInt32();
                        mcin_array[i].asyncID = bin.ReadUInt32();
                    }

                    continue;
                }

                if (tempHeader.Is("MTEX"))  // List of texture filenames used by the terrain in this map tile.
                {
                    // Not needed.
                    continue;
                }

                if (tempHeader.Is("MMDX")) // List of filenames for M2 models that appear in this map tile.
                {
                    // Not needed.
                    continue;
                }

                if (tempHeader.Is("MMID"))  // Lists the relative offsets of string beginnings in the above MMDX chunk.
                {
                    // Not needed.
                    continue;
                }

                if (tempHeader.Is("MWMO"))  // List of filenames for WMOs (world map objects) that appear in this map tile.
                {
                    byte[] wmoFilesChunk = bin.ReadBytes((int)tempHeader.Size);

                    wmoFiles = new List<String>();

                    StringBuilder str = new StringBuilder();

                    // Convert szString's to a List<String>.
                    for (int i = 0; i < wmoFilesChunk.Length; i++)
                    {
                        if (wmoFilesChunk[i] == '\0')
                        {
                            if (str.Length > 1)
                                wmoFiles.Add(str.ToString());
                            str = new StringBuilder();
                        }
                        else
                            str.Append((char)wmoFilesChunk[i]);
                    }

                    continue;
                }

                if (tempHeader.Is("MWID"))  // Lists the relative offsets of string beginnings in the above MWWO chunk.
                {
                    // Not needed.
                    continue;
                }

                if (tempHeader.Is("MDDF"))  // Placement information for doodads (M2 models).
                {
                    uint num = tempHeader.Size / 32;

                    doodadLocations = new MDDF[num];

                    for (int i = 0; i < num; i++)
                    {
                        doodadLocations[i].nameId = bin.ReadUInt32();
                        doodadLocations[i].uniqueId = bin.ReadUInt32();
                        doodadLocations[i].coord = new Coordinate(bin.ReadSingle(), bin.ReadSingle(), bin.ReadSingle());
                    }

                    continue;
                }

                if (tempHeader.Is("MODF"))  // Placement information for WMOs.
                {
                    uint num = tempHeader.Size / 64;

                    wmoLocations = new MODF[num];

                    for (int i = 0; i < num; i++)
                    {
                        wmoLocations[i].nameId = bin.ReadUInt32();
                        wmoLocations[i].uniqueId = bin.ReadUInt32();
                        wmoLocations[i].coord = new Coordinate(bin.ReadSingle(), bin.ReadSingle(), bin.ReadSingle());
                        wmoLocations[i].orientation = new Vect3D(bin.ReadSingle(), bin.ReadSingle(), bin.ReadSingle());
                        wmoLocations[i].coord2 = new Coordinate(bin.ReadSingle(), bin.ReadSingle(), bin.ReadSingle());
                        wmoLocations[i].coord3 = new Coordinate(bin.ReadSingle(), bin.ReadSingle(), bin.ReadSingle());
                        wmoLocations[i].flags = bin.ReadUInt32();
                        wmoLocations[i].doodadSet = bin.ReadUInt16();
                        wmoLocations[i].nameSet = bin.ReadUInt16();
                    }

                    continue;
                }

                if (tempHeader.Is("MCNK")) // || tempHeader.Is("MCVT") || tempHeader.Is("MCNR") || tempHeader.Is("MCLY") || tempHeader.Is("MCRF") || tempHeader.Is("MCSH") || tempHeader.Is("MCAL") || tempHeader.Is("MCLQ") || tempHeader.Is("MCSE"))
                {
                    // Skip these. They are read in afterwards.
                    continue;
                }

                // If we're still down here, we got a problem
                throw new Exception(String.Format("ADTFile: Woah. Got a header of {0}. Don't know how to deal with this, bailing out.", tempHeader.ToString()));
            }

            // Read in Map Chunks
            mapChunkTable = new MCNK[16][];

            for (int i = 0; i < 16; i++)
            {
                mapChunkTable[i] = new MCNK[16];

                for (int j = 0; j < 16; j++)
                {
                    int index = i * 16 + j;
                    Log.WriteLine(LogType.Terrain,  "Parsing MCNK Chunk #{0} [{1}, {2}]", index, i, j);
                    mapChunkTable[i][j] = parseMapChunk(ms, mcin_array[index].MCNK_offset, mcin_array[index].MCNK_size);
                }
            }
        }
Beispiel #13
0
        public void Write()
        {
            using (var writer = new BinaryWriter(File.OpenWrite("test.adt")))
            {
                // MVER
                writer.Write(MVER.GetChunkHeaderBytes());
                writer.Write(MVER.GetChunkBytes());

                // Write MHDR later when we got all offsets
                var positionBeforeMHDR = writer.BaseStream.Position;
                writer.BaseStream.Position += _HeaderSize + MHDR.ChunkSize;

                // MTEX
                MHDR.OffsetMTEX = (uint)writer.BaseStream.Position;
                writer.Write(MTEX.GetChunkHeaderBytes());
                writer.Write(MTEX.GetChunkBytes());

                // MMDX
                MHDR.OffsetMMDX = (uint)writer.BaseStream.Position;
                writer.Write(MMDX.GetChunkHeaderBytes());
                writer.Write(MMDX.GetChunkBytes());

                // MMID
                MHDR.OffsetMMID = (uint)writer.BaseStream.Position;
                writer.Write(MMID.GetChunkHeaderBytes());
                writer.Write(MMID.GetChunkBytes());

                // MWMO
                MHDR.OffsetMWMO = (uint)writer.BaseStream.Position;
                writer.Write(MWMO.GetChunkHeaderBytes());
                writer.Write(MWMO.GetChunkBytes());

                // MWID
                MHDR.OffsetMWID = (uint)writer.BaseStream.Position;
                writer.Write(MWID.GetChunkHeaderBytes());
                writer.Write(MWID.GetChunkBytes());

                // MDDF
                MHDR.OffsetMDDF = (uint)writer.BaseStream.Position;
                writer.Write(MDDF.GetChunkHeaderBytes());
                writer.Write(MDDF.GetChunkBytes());

                // MODF
                MHDR.OffsetMODF = (uint)writer.BaseStream.Position;
                writer.Write(MODF.GetChunkHeaderBytes());
                writer.Write(MODF.GetChunkBytes());

                // MH2O
                MHDR.OffsetMH2O = (uint)writer.BaseStream.Position;
                writer.Write(MH2O.GetChunkHeaderBytes());
                writer.Write(MH2O.GetChunkBytes());

                // MCNK
                for (int i = 0; i < MCIN.Entries.Length; i++)
                {
                    MCIN.Entries[i].OffsetMCNK = (uint)writer.BaseStream.Position;
                    MCIN.Entries[i].ChunkSize  = MCNK[i].ChunkSize;
                    writer.Write(MCNK[i].GetChunkHeaderBytes());
                    writer.Write(MCNK[i].GetChunkBytes());
                }

                // MCIN
                MHDR.OffsetMCIN = (uint)writer.BaseStream.Position;
                writer.Write(MCIN.GetChunkHeaderBytes());
                writer.Write(MCIN.GetChunkBytes());

                // MFBO
                if (MHDR.Flags.HasFlag(MHDRFlags.MFBO))
                {
                    MHDR.OffsetMFBO = (uint)writer.BaseStream.Position;
                    writer.Write(MFBO.GetChunkHeaderBytes());
                    writer.Write(MFBO.GetChunkBytes());
                }
                else
                {
                    MHDR.OffsetMFBO = 0;
                }

                // MTXF
                MHDR.OffsetMTXF = (uint)writer.BaseStream.Position;
                writer.Write(MTXF.GetChunkHeaderBytes());
                writer.Write(MTXF.GetChunkBytes());

                // MHDR
                writer.BaseStream.Position = positionBeforeMHDR;
                writer.Write(MHDR.GetChunkHeaderBytes());
                writer.Write(MHDR.GetChunkBytes());
            }
        }
Beispiel #14
0
        public void Read(byte[] data)
        {
            // Clear chunks to prevent double data.
            Chunks.Clear();

            using (var stream = new MemoryStream(data))
                using (var reader = new BinaryReader(stream))
                {
                    while (reader.BaseStream.Position < reader.BaseStream.Length)
                    {
                        var chunkId   = (WMOChunkId)reader.ReadUInt32();
                        var chunkSize = reader.ReadUInt32();

                        var chunkData = new byte[chunkSize];
                        Buffer.BlockCopy(stream.ToArray(), (int)reader.BaseStream.Position, chunkData, 0, (int)chunkSize);

                        IChunk chunk = null;
                        switch (chunkId)
                        {
                        case WMOChunkId.MVER: chunk = new MVER(); break;

                        case WMOChunkId.MOHD: chunk = new MOHD(); break;

                        case WMOChunkId.MOTX: chunk = new MOTX(); break;

                        case WMOChunkId.MOMT: chunk = new MOMT(); break;

                        case WMOChunkId.MOGN: chunk = new MOGN(); break;

                        case WMOChunkId.MOGI: chunk = new MOGI(); break;

                        case WMOChunkId.MOPV: chunk = new MOPV(); break;

                        case WMOChunkId.MOPT: chunk = new MOPT(); break;

                        case WMOChunkId.MOPR: chunk = new MOPR(); break;

                        case WMOChunkId.MOLT: chunk = new MOLT(); break;

                        case WMOChunkId.MODS: chunk = new MODS(); break;

                        case WMOChunkId.MODI: chunk = new MODI(); break;

                        case WMOChunkId.MODD: chunk = new MODD(); break;

                        case WMOChunkId.MFOG: chunk = new MFOG(); break;

                        default: Console.WriteLine($"Skipping {chunkId} (0x{(uint)chunkId:X})"); break;
                        }

                        if (chunk != null)
                        {
                            chunk.Read(chunkData);
                            Chunks.Add(chunk);
                        }

                        reader.BaseStream.Position += chunkSize;
                    }

                    // Add mandatory chunks.
                    Chunks.Add(new MOSB());
                    Chunks.Add(new MOVV());
                    Chunks.Add(new MOVB());

                    // Close the streams so they can be written.
                    reader.Close();
                    stream.Close();
                }
        }