Exemple #1
1
        private void ReadTEX(string filename, Stream tex)
        {
            var bin = new BinaryReader(tex);
            BlizzHeader chunk;
            long position = 0;
            while (position < tex.Length)
            {
                tex.Position = position;

                chunk = new BlizzHeader(bin.ReadChars(4), bin.ReadUInt32());
                chunk.Flip();

                position = tex.Position + chunk.Size;

                switch (chunk.ToString())
                {
                    case "TXVR": ReadTXVRChunk(bin);
                        continue;
                    case "TXFN": ReadTXFNChunk(bin, chunk);
                        continue;
                    case "TXBT":
                    case "TXMD": continue;
                    default:
                        throw new Exception(String.Format("{2} Found unknown header at offset {1} \"{0}\" while we should've already read them all!", chunk.ToString(), position.ToString(), filename));
                }
            }
        }
Exemple #2
0
        private void ReadWDL(string filename, Stream wdl)
        {
            var bin = new BinaryReader(wdl);
            BlizzHeader chunk;
            long position = 0;
            while (position < wdl.Length)
            {
                wdl.Position = position;

                chunk = new BlizzHeader(bin.ReadChars(4), bin.ReadUInt32());
                chunk.Flip();

                position = wdl.Position + chunk.Size;

                switch (chunk.ToString())
                {
                    case "MVER": ReadMVERChunk(bin);
                        continue;
                    case "MWMO": ReadMWMOChunk(bin, chunk);
                        continue;
                    case "MWID":
                    case "MODF":
                    case "MAOF": //contains MARE and MAHO subchunks
                    case "MARE":
                    case "MAOC": //New in WoD
                    case "MAHO": continue;
                    default:
                        throw new Exception(String.Format("{2} Found unknown header at offset {1} \"{0}\" while we should've already read them all!", chunk.ToString(), position.ToString(), filename));
                }
            }
        }
Exemple #3
0
        private void ReadObjFile(string filename, Stream adtObjStream, ref BlizzHeader chunk)
        {
            var bin = new BinaryReader(adtObjStream);
            long position = 0;

            adtfile.objects = new Obj();

            while (position < adtObjStream.Length)
            {
                adtObjStream.Position = position;
                chunk = new BlizzHeader(bin.ReadChars(4), bin.ReadUInt32());
                chunk.Flip();
                position = adtObjStream.Position + chunk.Size;

                if (chunk.Is("MVER")) { if (bin.ReadUInt32() != 18) { throw new Exception("Unsupported ADT version!"); } continue; }
                if (chunk.Is("MMDX")) { adtfile.objects.m2Names = ReadMMDXChunk(chunk, bin); continue; }
                if (chunk.Is("MMID")) { adtfile.objects.m2NameOffsets = ReadMMIDChunk(chunk, bin); continue; }
                if (chunk.Is("MWMO")) { adtfile.objects.wmoNames = ReadMWMOChunk(chunk, bin); continue; }
                if (chunk.Is("MWID")) { adtfile.objects.wmoNameOffsets = readMWIDChunk(chunk, bin);  continue; }
                if (chunk.Is("MDDF")) { adtfile.objects.models = ReadMWIDChunk(chunk, bin); continue; }
                if (chunk.Is("MODF")) { adtfile.objects.worldModels = ReadMODFChunk(chunk, bin); continue; }
                if (chunk.Is("MCNK")) { continue; } // Only has MCRD and other useless things nobody cares about!

                throw new Exception(String.Format("{2} Found unknown header at offset {1} \"{0}\" while we should've already read them all!", chunk.ToString(), position.ToString(), filename));
            }
        }
Exemple #4
0
        private void ReadTexFile(string filename, Stream adtTexStream, ref BlizzHeader chunk)
        {
            var bin = new BinaryReader(adtTexStream);
            long position = 0;
            int MCNKi = 0;
            adtfile.texChunks = new TexMCNK[16 * 16];

            while (position < adtTexStream.Length)
            {
                adtTexStream.Position = position;
                chunk = new BlizzHeader(bin.ReadChars(4), bin.ReadUInt32());
                chunk.Flip();
                position = adtTexStream.Position + chunk.Size;
                if (chunk.Is("MVER")) { if (bin.ReadUInt32() != 18) { throw new Exception("Unsupported ADT version!"); } continue; }
                if (chunk.Is("MAMP")) { continue; }
                if (chunk.Is("MTEX")) { adtfile.textures = ReadMTEXChunk(chunk, bin); continue; }
                if (chunk.Is("MCNK")) { adtfile.texChunks[MCNKi] = ReadTexMCNKChunk(chunk, bin); MCNKi++;  continue; }
                if (chunk.Is("MTXP")) { continue; }

                throw new Exception(String.Format("{2} Found unknown header at offset {1} \"{0}\" while we should've already read them all!", chunk.ToString(), position.ToString(), filename));
            }
        }
Exemple #5
0
        public TexMCNK ReadTexMCNKChunk(BlizzHeader chunk, BinaryReader bin)
        {
            //256 of these chunks per file
            TexMCNK mapchunk = new TexMCNK();

            MemoryStream stream = new MemoryStream(bin.ReadBytes((int)chunk.Size));

            var subbin = new BinaryReader(stream);

            BlizzHeader subchunk;

            long subpos = 0;

            while (subpos < stream.Length)
            {
                subbin.BaseStream.Position = subpos;
                subchunk = new BlizzHeader(subbin.ReadChars(4), subbin.ReadUInt32());
                subchunk.Flip();
                subpos = stream.Position + subchunk.Size;

                switch (subchunk.ToString())
                {
                    case "MCLY":
                        mapchunk.layers = ReadMCLYSubChunk(subchunk, subbin);
                        break;
                    case "MCAL":
                        mapchunk.alphaLayer = ReadMCALSubChunk(subchunk, subbin, mapchunk);
                        break;
                    case "MCSH":
                    case "MCMT":
                        continue;
                    default:
                        throw new Exception(String.Format("Found unknown header at offset {1} \"{0}\" while we should've already read them all!", subchunk.ToString(), subpos.ToString()));
                }
            }
            return mapchunk;
        }
Exemple #6
0
        public void LoadADT(string filename, bool loadSecondaryADTs = true, bool filenamesOnly = false, bool localFile = false)
        {
            m2Files = new List<string>();
            wmoFiles = new List<string>();
            blpFiles = new List<string>();

            filename = Path.ChangeExtension(filename, ".adt");

            if (!localFile)
            {
                if (!CASC.FileExists(filename)) { new WoWFormatLib.Utils.MissingFile(filename); return; }
                if (!CASC.FileExists(filename.Replace(".adt", "_obj0.adt"))) { new WoWFormatLib.Utils.MissingFile(filename.Replace(".adt", "_obj0.adt")); return; }
                if (!CASC.FileExists(filename.Replace(".adt", "_obj1.adt"))) { new WoWFormatLib.Utils.MissingFile(filename.Replace(".adt", "_obj1.adt")); return; }
                if (!CASC.FileExists(filename.Replace(".adt", "_tex0.adt"))) { new WoWFormatLib.Utils.MissingFile(filename.Replace(".adt", "_tex0.adt")); return; }
                if (!CASC.FileExists(filename.Replace(".adt", "_tex1.adt"))) { new WoWFormatLib.Utils.MissingFile(filename.Replace(".adt", "_tex1.adt")); return; }
            }
            else
            {
                if (!File.Exists(filename)) { throw new Exception("Missing file!"); }
            }

            Stream adt;

            if (!localFile)
            {
                var mapname = filename.Replace("world\\maps\\", "").Substring(0, filename.Replace("world\\maps\\", "").IndexOf("\\"));

                if (CASC.FileExists("world\\maps\\" + mapname + "\\" + mapname + ".wdt"))
                {
                    var wdtr = new WDTReader();
                    wdtr.LoadWDT("world\\maps\\" + mapname + "\\" + mapname + ".wdt");
                    wdt = wdtr.wdtfile;
                }
                else
                {
                    throw new Exception("WDT does not exist, need this for MCAL flags!");
                }


                adt = CASC.OpenFile(filename);
            }
            else
            {
                adt = File.OpenRead(filename);
            }


            BlizzHeader chunk = null;
            if (filenamesOnly == false)
            {
                var bin = new BinaryReader(adt);
                long position = 0;
                int MCNKi = 0;
                adtfile.chunks = new MCNK[16 * 16];

                while (position < adt.Length)
                {
                    adt.Position = position;
                    chunk = new BlizzHeader(bin.ReadChars(4), bin.ReadUInt32());
                    chunk.Flip();
                    position = adt.Position + chunk.Size;

                    switch (chunk.ToString())
                    {
                        case "MVER":
                            uint version = bin.ReadUInt32();
                            if (version != 18)
                            {
                                throw new Exception("Unsupported ADT version!");
                            }
                            else
                            {
                                adtfile.version = version;
                            }
                            continue;
                        case "MCNK":
                            adtfile.chunks[MCNKi] = ReadMCNKChunk(chunk, bin);
                            MCNKi++;
                            continue;
                        case "MHDR":
                            adtfile.header = ReadMHDRChunk(chunk, bin);
                            continue;
                        case "MH2O":
                        case "MFBO":
                        //model.blob stuff
                        case "MBMH":
                        case "MBBB":
                        case "MBMI":
                        case "MBNV": continue;
                        default:
                            throw new Exception(String.Format("{2} Found unknown header at offset {1} \"{0}\" while we should've already read them all!", chunk.ToString(), position.ToString(), filename));
                    }
                }

                adt.Close();
            }

            if (loadSecondaryADTs)
            {
                using (var adtobj0 = CASC.OpenFile(filename.Replace(".adt", "_obj0.adt")))
                {
                    ReadObjFile(filename, adtobj0, ref chunk);
                }

                using (var adttex0 = CASC.OpenFile(filename.Replace(".adt", "_tex0.adt")))
                {
                    ReadTexFile(filename, adttex0, ref chunk);
                }
            }
        }
Exemple #7
0
        public MCNK ReadMCNKChunk(BlizzHeader chunk, BinaryReader bin)
        {
            //256 of these chunks per file
            MCNK mapchunk = new MCNK();
            
            mapchunk.header = bin.Read<MCNKheader>();

            MemoryStream stream = new MemoryStream(bin.ReadBytes((int)chunk.Size - 128));
            
            var subbin = new BinaryReader(stream);
            
            BlizzHeader subchunk;
            
            long subpos = 0;

            while (subpos < stream.Length)
            {
                subbin.BaseStream.Position = subpos;
                subchunk = new BlizzHeader(subbin.ReadChars(4), subbin.ReadUInt32());
                subchunk.Flip();
                subpos = stream.Position + subchunk.Size;

                switch (subchunk.ToString())
                {
                    case "MCVT":
                        mapchunk.vertices = ReadMCVTSubChunk(subchunk, subbin);
                        break;
                    case "MCCV":
                        mapchunk.vertexShading = ReadMCCVSubChunk(subchunk, subbin);
                        break;
                    case "MCNR":
                        mapchunk.normals = ReadMCNRSubChunk(subchunk, subbin);
                        break;
                    case "MCSE":
                        mapchunk.soundEmitters = ReadMCSESubChunk(subchunk, subbin);
                        break;
                    case "MCBB":
                        mapchunk.blendBatches = ReadMCBBSubChunk(subchunk, subbin);
                        break;
                    case "MCLQ":
                    case "MCLV":
                        continue;
                    default:
                        throw new Exception(String.Format("Found unknown header at offset {1} \"{0}\" while we should've already read them all!", subchunk.ToString(), subpos.ToString()));
                }
            }
            return mapchunk;
        }
Exemple #8
0
        private WMOGroupFile ReadWMOGroupFile(string filename, Stream wmo)
        {
            WMOGroupFile groupFile = new WMOGroupFile();

            var bin = new BinaryReader(wmo);
            BlizzHeader chunk;

            long position = 0;
            while (position < wmo.Length)
            {
                wmo.Position = position;
                chunk = new BlizzHeader(bin.ReadChars(4), bin.ReadUInt32());
                chunk.Flip();
                position = wmo.Position + chunk.Size;

                switch (chunk.ToString())
                {
                    case "MVER":
                        groupFile.version = bin.Read<MVER>();
                        if (wmofile.version.version != 17)
                        {
                            throw new Exception("Unsupported WMO version! (" + wmofile.version.version + ")");
                        }
                        continue;
                    case "MOGP":
                        groupFile.mogp = ReadMOGPChunk(chunk, bin);
                        continue;
                    default:
                        throw new Exception(String.Format("{2} Found unknown header at offset {1} \"{0}\" while we should've already read them all!", chunk.ToString(), position.ToString(), filename));
                }
            }
            return groupFile;
        }
Exemple #9
0
        private void ReadWMO(string filename, Stream wmo)
        {
            var bin = new BinaryReader(wmo);
            BlizzHeader chunk;

            long position = 0;
            while (position < wmo.Length)
            {
                wmo.Position = position;
                chunk = new BlizzHeader(bin.ReadChars(4), bin.ReadUInt32());
                chunk.Flip();
                position = wmo.Position + chunk.Size;

                switch (chunk.ToString())
                {
                    case "MVER":
                        wmofile.version = bin.Read<MVER>();
                        if (wmofile.version.version != 17)
                        {
                            throw new Exception("Unsupported WMO version! (" + wmofile.version.version + ") (" + filename + ")");
                        }
                        continue;
                    case "MOTX":
                        wmofile.textures = ReadMOTXChunk(chunk, bin);
                        continue;
                    case "MOHD":
                        wmofile.header = ReadMOHDChunk(chunk, bin, filename);
                        continue;
                    case "MOGN":
                        wmofile.groupNames = ReadMOGNChunk(chunk, bin, wmofile.header.nGroups);
                        continue;
                    case "MOGI":
                        wmofile.groupInfo = ReadMOGIChunk(chunk, bin, wmofile.header.nGroups);
                        continue;
                    case "MOMT":
                        wmofile.materials = ReadMOMTChunk(chunk, bin, wmofile.header.nMaterials);
                        continue;
                    case "MODN":
                        wmofile.doodadNames = ReadMODNChunk(chunk, bin, wmofile.header.nModels);
                        continue;
                    case "MODD":
                        wmofile.doodadDefinitions = ReadMODDChunk(chunk, bin);
                        continue;
                    case "MOGP":
                    //ReadMOGPChunk(chunk, bin);
                    //continue;
                    case "MOSB":
                    case "MOPV":
                    case "MOPT":
                    case "MOPR":
                    case "MOVV": //Visible block vertices
                    case "MOVB": //Visible block list
                    case "MOLT":
                    case "MODS":
                    
                    case "MFOG":
                    case "MCVP":
                    case "GFID": // Legion
                        continue;
                    default:
                        throw new Exception(String.Format("{2} Found unknown header at offset {1} \"{0}\" while we should've already read them all!", chunk.ToString(), position.ToString(), filename));
                }
            }
            //open group files
            WMOGroupFile[] groupFiles = new WMOGroupFile[wmofile.header.nGroups];
            for (int i = 0; i < wmofile.header.nGroups; i++)
            {
                var groupfilename = filename.Replace(".WMO", "_" + i.ToString().PadLeft(3, '0') + ".WMO");
                groupfilename = groupfilename.Replace(".wmo", "_" + i.ToString().PadLeft(3, '0') + ".wmo");
                if (!CASC.FileExists(groupfilename))
                {
                    new WoWFormatLib.Utils.MissingFile(groupfilename);
                    return;
                }
                else
                {
                    using (Stream wmoStream = CASC.OpenFile(groupfilename))
                    {
                        groupFiles[i] = ReadWMOGroupFile(groupfilename, wmoStream);
                    }
                }
            }

            wmofile.group = groupFiles;
        }
Exemple #10
0
        public MOGP ReadMOGPChunk(BlizzHeader chunk, BinaryReader bin)
        {
            MOGP mogp = new MOGP();
            mogp.nameOffset = bin.ReadUInt32();
            mogp.descriptiveNameOffset = bin.ReadUInt32();
            mogp.flags = bin.ReadUInt32();
            mogp.boundingBox1 = bin.Read<Vector3>();
            mogp.boundingBox2 = bin.Read<Vector3>();
            mogp.ofsPortals = bin.ReadUInt16();
            mogp.numPortals = bin.ReadUInt16();
            mogp.numBatchesA = bin.ReadUInt16();
            mogp.numBatchesB = bin.ReadUInt16();
            mogp.numBatchesC = bin.ReadUInt32();
            //mogp.fogIndices = bin.ReadBytes(4);
            bin.ReadBytes(4);
            mogp.liquidType = bin.ReadUInt32();
            mogp.groupID = bin.ReadUInt32();
            mogp.unk0 = bin.ReadUInt32();
            mogp.unk1 = bin.ReadUInt32();
            MemoryStream stream = new MemoryStream(bin.ReadBytes((int)chunk.Size));
            var subbin = new BinaryReader(stream);
            BlizzHeader subchunk;
            long position = 0;
            int MOTVi = 0;
            mogp.textureCoords = new MOTV[2][];

            while (position < stream.Length)
            {
                stream.Position = position;
                subchunk = new BlizzHeader(subbin.ReadChars(4), subbin.ReadUInt32());
                subchunk.Flip();
                position = stream.Position + subchunk.Size;
                //Console.WriteLine(subchunk.ToString());
                switch (subchunk.ToString())
                {
                    case "MOVI": //Vertex indices for triangles
                        mogp.indices = ReadMOVIChunk(subchunk, subbin);
                        //Console.WriteLine("Read " + mogp.indices.Length + " indices!");
                        break;

                    case "MOVT": //Vertices chunk
                        mogp.vertices = ReadMOVTChunk(subchunk, subbin);
                        break;

                    case "MOTV": //Texture coordinates
                        mogp.textureCoords[MOTVi++] = ReadMOTVChunk(subchunk, subbin);
                        break;

                    case "MONR": //Normals
                        mogp.normals = ReadMONRChunk(subchunk, subbin);
                        break;

                    case "MOBA": //Render batches
                        mogp.renderBatches = ReadMOBAChunk(subchunk, subbin);
                        break;

                    case "MOPY": //Material info for triangles, two bytes per triangle.
                        mogp.materialInfo = ReadMOPYChunk(subchunk, subbin);
                        break;

                    case "MOBS": //Unk
                    case "MODR": //Doodad references
                    case "MOBN": //Array of t_BSP_NODE
                    case "MOBR": //Face indices
                    case "MOLR": //Light references
                    case "MOCV": //Vertex colors
                    case "MDAL": //Unk (new in WoD?)
                    case "MLIQ": //Liquids
                    case "MOTA": //Unknown
                    case "MOPL": //Unknown
                        continue;
                    default:
                        throw new Exception(String.Format("Found unknown header at offset {1} \"{0}\" while we should've already read them all!", subchunk.ToString(), position.ToString()));
                }
            }
            //if(MOTVi == 0) { throw new Exception("Didn't parse any MOTV??");  } // antiportal groups have no motv
            return mogp;
        }
Exemple #11
0
        private void ReadWDT(string filename, Stream wdt)
        {
            filename = Path.ChangeExtension(filename, "WDT");
            var bin = new BinaryReader(wdt);
            BlizzHeader chunk;
            long position = 0;
            while (position < wdt.Length)
            {
                wdt.Position = position;

                chunk = new BlizzHeader(bin.ReadChars(4), bin.ReadUInt32());
                chunk.Flip();

                position = wdt.Position + chunk.Size;

                switch (chunk.ToString())
                {
                    case "MVER": ReadMVERChunk(bin);
                        continue;
                    case "MAIN": ReadMAINChunk(bin, chunk, filename);
                        continue;
                    case "MWMO": ReadMWMOChunk(bin);
                        continue;
                    case "MPHD": wdtfile.mphd = ReadMPHDChunk(bin);
                        continue;
                    case "MPLT":
                    case "MODF": continue;
                    default:
                        throw new Exception(String.Format("{2} Found unknown header at offset {1} \"{0}\" while we should've already read them all!", chunk.ToString(), position.ToString(), filename));
                }
            }
        }