Beispiel #1
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));
                }
            }
        }
Beispiel #2
0
        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));
                }
            }
        }
Beispiel #3
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);
        }
Beispiel #4
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);
        }
Beispiel #5
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++)
            {
                string groupfilename = groupfilename = filename.Replace(".wmo", "_" + i.ToString().PadLeft(3, '0') + ".wmo");

                if (_lod)
                {
                    if (CASC.FileExists(groupfilename.Replace(".wmo", "_lod2.wmo")))
                    {
                        groupfilename = groupfilename.Replace(".wmo", "_lod2.wmo");
                        Console.WriteLine("[LOD] Loading LOD 2 for group " + i);
                    }
                    else if (CASC.FileExists(groupfilename.Replace(".wmo", "_lod1.wmo")))
                    {
                        groupfilename = groupfilename.Replace(".wmo", "_lod1.wmo");
                        Console.WriteLine("[LOD] Loading LOD 1 for group " + i);
                    }
                    else
                    {
                        Console.WriteLine("[LOD] No LOD " + i);
                    }
                }

                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;
        }
Beispiel #6
0
        public MOGP ReadMOGPChunk(BlizzHeader chunk, BinaryReader bin)
        {
            MOGP mogp = new MOGP();

            mogp.nameOffset            = bin.ReadUInt32();
            mogp.descriptiveNameOffset = bin.ReadUInt32();
            mogp.flags        = (MOGPFlags)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;

            if (mogp.flags.HasFlag(MOGPFlags.Flag_0x40000000))
            {
                mogp.textureCoords = new MOTV[3][];
            }
            else
            {
                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
                case "MOLP":     //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);
        }
Beispiel #7
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));
            }
        }
Beispiel #8
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));
            }
        }
Beispiel #9
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);
                }
            }
        }