[Googled] How to parse ADT in C# menu

User Tag List

Results 1 to 1 of 1
  1. #1
    Viano's Avatar Active Member
    Reputation
    37
    Join Date
    May 2008
    Posts
    172
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [Googled] How to parse ADT in C#

    Hi everyone,

    I found this precious copy'n'pasta on the internet and want to share it with you. Seems to be all good for parsing ADT in cataclysm plus it is written in C#. Thanks to the author, who ever it was.

    using System; using System.Collections.Generic; using System.Drawing; using S - Pastebin.com

    Code:
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.IO;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Text.RegularExpressions;
    
    namespace WoWWorldReader
    {
        public class ChunkStream : Stream
        {
            private readonly long _start;
            private readonly long _length;
            private long _position;
            private readonly Stream _parent;
    
            public Stream Parent
            {
                get { return _parent; }
            }
    
            public string Identifier { get; private set; }
    
            public ChunkStream(Stream parent)
            {
                var reader = new BinaryReader(parent);
                lock (parent)
                {
                    _parent = parent;
    
                    // read in header
                    var id = reader.ReadBytes(4);
                    Identifier = "" + (char)id[3] + (char)id[2] + (char)id[1] + (char)id[0];
                    _length = reader.ReadUInt32();
                    _start = _parent.Position;
                }
            }
    
            public ChunkStream Ascend()
            {
                return _parent as ChunkStream;
            }
    
            public ChunkStream Descend()
            {
                lock (_parent)
                {
                    var pos = _start;
                    _parent.Position = pos;
                    return pos + 8 > _parent.Length ? null : new ChunkStream(_parent);
                }
            }
    
            public ChunkStream Next()
            {
                lock (_parent)
                {
                    var pos = _start + _length;
                    _parent.Position = pos;
                    return pos + 8 > _parent.Length ? null : new ChunkStream(_parent);
                }
            }
    
            #region unsupported
    
            public override void Flush()
            {
                throw new NotImplementedException();
            }
    
            public override long Seek(long offset, SeekOrigin origin)
            {
                throw new NotImplementedException();
            }
    
            public override void SetLength(long value)
            {
                throw new NotImplementedException();
            }
    
            public override void Write(byte[] buffer, int offset, int count)
            {
                throw new NotImplementedException();
            }
    
            #endregion
    
            public override int Read(byte[] buffer, int offset, int count)
            {
                lock (_parent)
                {
                    //var oldPos = _parent.Position;
                    try
                    {
                        _parent.Position = _position + _start;
                        return _parent.Read(buffer, offset, count);
                    }
                    finally
                    {
                        _position = _parent.Position - _start;
                        //_parent.Position = oldPos + (_parent.Position - _position);
                    }
                }
            }
    
            public override bool CanRead
            {
                get { return true; }
            }
    
            public override bool CanSeek
            {
                get { return true; }
            }
    
            public override bool CanWrite
            {
                get { return false; }
            }
    
            public override long Length
            {
                get { return _length; }
            }
    
            public override long Position
            {
                get { return _position; }
                set 
                {
                    if (value > _length)
                        throw new ArgumentOutOfRangeException();
                    _position = value;
                    lock (_parent)
                        _parent.Position = _start + _position;
                }
            }
        }
    
        public static class Extensions
        {
            public static T ReadStruct<T>(this Stream s) where T : struct
            {
                var sz = Marshal.SizeOf(typeof(T));
                var buf = new byte[sz];
                s.Read(buf, 0, sz);
                var handle = GCHandle.Alloc(buf, GCHandleType.Pinned);
                var t =  (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
                handle.Free();
                return t;
            }
        }
    
        [StructLayout(LayoutKind.Sequential, Size=4)]
        public struct MHDR
        {
            public uint Flags;
            public uint mcin;
            public uint mtex;
            public uint mmdx;
            public uint mmid;
            public uint mwmo;
            public uint mwid;
            public uint mddf;
            public uint modf;
            public uint mfbo;                     // this is only set if flags & mhdr_MFBO.
            public uint mh2o;
            public uint mtfx;
        }
    
        [StructLayout(LayoutKind.Sequential, Size = 4)]
        public struct Vec3F
        {
            public float X, Y, Z;
        }
    
    
        [StructLayout(LayoutKind.Sequential, Size = 4)]
        public struct MCNK
        {
            public uint flags;
            public uint IndexX;
            public uint IndexY;
            public uint nLayers;				// maximum 4
            public uint nDoodadRefs;
            public uint ofsHeight;
            public uint ofsNormal;
            public uint ofsLayer;
            public uint ofsRefs;
            public uint ofsAlpha;
            public uint sizeAlpha;
            public uint ofsShadow;				// only with flags&0x1
            public uint sizeShadow;
            public uint areaid;
            public uint nMapObjRefs;
            public uint holes;
    
            public uint reallyLowQualityTextureingMap0;
            public uint reallyLowQualityTextureingMap1;
            public uint reallyLowQualityTextureingMap2;
            public uint reallyLowQualityTextureingMap3;
    
    
            public uint predTex;				// 03-29-2005 By ObscuR; TODO: Investigate
            public uint noEffectDoodad;				// 03-29-2005 By ObscuR; TODO: Investigate
            public uint ofsSndEmitters;
            public uint nSndEmitters;				//will be set to 0 in the client if ofsSndEmitters doesn&#039;t point to MCSE!
            public uint ofsLiquid;
            public uint sizeLiquid;  			// 8 when not used; only read if >8.
            public Vec3F position;
            public uint ofsMCCV; 				// only with flags&0x40, had UINT32 textureId; in ObscuR&#039;s structure.
            public uint ofsMCLV; 				// introduced in Cataclysm
        }
    
        public class MapParser
        {
            public const int Size = 16 * 17;
            public float[,] Data = new float[Size, Size];
    
            public float MaxV { get; private set; }
            public float MinV { get; private set; }
    
            public MapParser(Stream adt)
            {
                MaxV = Single.MinValue;
                MinV = Single.MaxValue;
    
                var chunk = new ChunkStream(adt);
                if (chunk.Identifier != "MVER")
                    throw new Exception();
                chunk = chunk.Next(); // skip MVER
    
                if (chunk.Identifier != "MHDR")
                    throw new Exception();
                var hdr = chunk.ReadStruct<MHDR>();
    
    
    
    
                while (chunk != null)
                {
                    if (chunk.Identifier == "MCNK")
                        ParseMapPiece(chunk);
                    else
                        Console.WriteLine(chunk.Identifier);
                    chunk = chunk.Next();
                }
            }
    
            private void ParseMapPiece(ChunkStream s)
            {
                var hdr = s.ReadStruct<MCNK>();
                var ofs = hdr.ofsHeight - 8;
                var z = hdr.position.Z;
    
                s.Position = ofs;
                var mcvt = new ChunkStream(s);
    
                var r = new BinaryReader(mcvt);
    
                var xoff = hdr.IndexX * 17;
                var yoff = hdr.IndexY * 17;
    
                // read the data points
                var y = 0;
                while (true)
                {
                    for (var x = 0; x < 9; x++)
                    {
                        var v = r.ReadSingle() + z;
                        if (v > MaxV)
                            MaxV = v;
                        if (v < MinV)
                            MinV = v;
                        Data[yoff + y, xoff + x * 2] = v;
                    }
                    y++;
                    if (y == 17)
                        break;
                    for (var x = 0; x < 8; x++)
                    {
                        var v = r.ReadSingle() + z;
                        if (v > MaxV)
                            MaxV = v;
                        if (v < MinV)
                            MinV = v;
                        Data[yoff + y, xoff + x * 2 + 1] = v;
                    }
                    y++;
                }
    
                
                // interpolate mid values
                // (might use a different scheme here..)
                for (y = 0; y < 17; y += 2)
                {
                    for (var x = 0; x < 8; x++)
                    {
                        var pl = Data[yoff + y, xoff + x * 2];
                        var pr = Data[yoff + y, xoff + x * 2 + 2];
                        Data[yoff + y, xoff + x * 2 + 1] = (pl + pr) * 0.5f;
    
                        pl = Data[yoff + x * 2, xoff + y];
                        pr = Data[yoff + x * 2 + 2, xoff + y];
                        Data[yoff + x * 2 + 1, xoff + y] = (pl + pr) * 0.5f;
                    }
                }
                 
            }
    
            public void Dump(string filename)
            {
                var d = MaxV - MinV;
                var scale = 255.0f / d;
                var bmp = new Bitmap(Size, Size);
                for (var y = 0; y < Size; y++)
                {
                    for (var x = 0; x < Size; x++)
                    {
                        var v = (int)((Data[y, x] - MinV) * scale);
                        if (v < 0)
                            v = 0;
                        if (v > 255)
                            v = 255;
                        bmp.SetPixel(x, y, Color.FromArgb(v, v, v));
                    }
                }
    
                bmp.Save(filename);
            }
        }
    
        class Program
        {
    
            public static void Dump(float [,] data, int size, float min, float max, int xoff, int yoff, string filename)
            {
                var d = max - min;
                var scale = 255.0f / d;
                var bmp = new Bitmap(size, size);
                for (var y = 0; y < size; y++)
                {
                    for (var x = 0; x < size; x++)
                    {
                        var v = (int)((data[y + yoff, x + xoff] - min) * scale);
                        if (v < 0)
                            v = 0;
                        if (v > 255)
                            v = 255;
                        bmp.SetPixel(x, y, Color.FromArgb(v, v, v));
                    }
                }
    
                bmp.Save(filename);
                bmp.Dispose();
            }
    
    
            static void Main(string[] args)
            {
                const int megaSize = 64 * MapParser.Size;
                var megamap = new float[megaSize, megaSize];
    
                const string path = @"G:\World of Warcraft\Work\world\maps\Azeroth";
                const string prefix = "Azeroth_";
    
                var maxV = Single.MinValue;
                var minV = Single.MaxValue;
    
                for (var y = 0; y < 64; y++)
                {
                    for (var x = 0; x < 64; x++)
                    {
                        var filename = path + "\\" + prefix + y + "_" + x + ".adt";
                        if (!File.Exists(filename))
                            continue;
    
                        Console.WriteLine(filename);
                        var f = new FileStream(filename, FileMode.Open, FileAccess.Read);
                        var map = new MapParser(f);
    
                        // copy to megamap
                        var yoff = MapParser.Size * x;
                        var xoff = MapParser.Size * y;
                        for (var yy = 0; yy < MapParser.Size; yy++)
                            for (var xx = 0; xx < MapParser.Size; xx++)
                                megamap[yoff + yy, xoff + xx] = map.Data[yy, xx];
    
                        if (map.MaxV > maxV)
                            maxV = map.MaxV;
                        if (map.MinV < minV)
                            minV = map.MinV;
                    }
                }
    
    
                Console.WriteLine("Dumping...");
                var fs = new FileStream("map.dat", FileMode.Create, FileAccess.Write);
                var w = new BinaryWriter(fs);
                w.Write(megaSize);
                w.Write(megaSize);
                w.Write(minV);
                w.Write(maxV);
                for (var y = 0; y < megaSize; y++)
                    for (var x = 0; x < megaSize; x++)
                        w.Write(megamap[y, x]);
                w.Close();
    
    
                /*
                for (var y = 0; y < 4; y++)
                    for (var x = 0; x < 4; x++)
                        Dump(megamap, 16 * MapParser.Size, minV, maxV,
                             16 * MapParser.Size * x, 16 * MapParser.Size * y,
                             "Azeroth_" + y + "_" + x + ".bmp");
                */
    
                Console.WriteLine("Press any key");
                Console.ReadKey();
            }
        }
    }
    Viano

    [Googled] How to parse ADT in C#

Similar Threads

  1. [source] How to parse player list (example)
    By Midi12 in forum GW2 Memory Editing
    Replies: 13
    Last Post: 11-28-2012, 12:25 AM
  2. Replies: 2
    Last Post: 12-24-2007, 06:01 AM
  3. How to use Google to download music.
    By t0x in forum Community Chat
    Replies: 3
    Last Post: 12-10-2007, 09:18 PM
  4. How do you find .adt numbers?
    By Darthgnomer in forum WoW ME Questions and Requests
    Replies: 2
    Last Post: 11-24-2007, 01:09 PM
  5. Manually edit .adts how
    By KanKan in forum WoW ME Questions and Requests
    Replies: 2
    Last Post: 09-14-2007, 07:07 AM
All times are GMT -5. The time now is 07:32 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search