• Welcome to Valhalla Legends Archive.
 

[D2] C# Structs

Started by Insolence, July 20, 2007, 05:29 AM

Previous topic - Next topic

Insolence

EDIT: Sorry, seems like this is in the wrong forum--confused this with a global research forum, but this is for BNetDocs, sorry.

Someone PM'd me asking about my structs and how I used them, so I PM'd them back with all my structs and classes I use for memory stuff.  I think it's appropriate to share it here, too:

Here are all my structs, and my Memory class, wrapped around the ProcessReader class.
Code:
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace Chief.Structs
{
    /// <summary>
    /// Thanks to MyndFyre for this first example!
    /// </summary>
    [StructLayout(LayoutKind.Explicit)]
    public struct UnitAny
    {
        [FieldOffset(0)]    public uint dwType;
        [FieldOffset(4)]    public uint dwTxtFileNo;
        [FieldOffset(8)]    public uint _1;
        [FieldOffset(0x0c)] public uint dwUnitId;
        [FieldOffset(0x10)] public uint dwMode;

        // first union
        [FieldOffset(0x14)] public IntPtr ptrPlayerData;
        [FieldOffset(0x14)] public IntPtr ptrItemData;
        [FieldOffset(0x14)] public IntPtr ptrMonsterData;
        [FieldOffset(0x14)] public IntPtr ptrObjectData;

        [FieldOffset(0x18)] public uint dwAct;
        [FieldOffset(0x1c)] public IntPtr ptrAct;
        [FieldOffset(0x20)] [MarshalAs(UnmanagedType.ByValArray, SizeConst=2)]  public uint[] dwSeed;
        [FieldOffset(0x28)] public uint _2;

        // second union
        [FieldOffset(0x2c)] public IntPtr ptrPath;
        [FieldOffset(0x2c)] public IntPtr ptrItemPath;
        [FieldOffset(0x2c)] public IntPtr ptrObjectPath;

        [FieldOffset(0x30)] [MarshalAs(UnmanagedType.ByValArray, SizeConst=5)]  public uint[] _3;
        [FieldOffset(0x44)] public uint dwGfxFrame;
        [FieldOffset(0x48)] public uint dwFrameRemain;
        [FieldOffset(0x4c)] public ushort wFrameRate;
        [FieldOffset(0x4e)] public ushort _4;
        [FieldOffset(0x50)] public IntPtr ptrGfxUnk;
        [FieldOffset(0x54)] public IntPtr ptrGfxInfo;
        [FieldOffset(0x58)] public uint _5;
        [FieldOffset(0x5c)] public IntPtr ptrStats;
        [FieldOffset(0x60)] public IntPtr ptrInventory;
        [FieldOffset(0x64)] public IntPtr ptrtLight;
        [FieldOffset(0x68)] [MarshalAs(UnmanagedType.ByValArray, SizeConst=9)]  public uint[] _6;

        [FieldOffset(0x8c)] public ushort wX;
        [FieldOffset(0x8e)] public ushort wY;

        [FieldOffset(0x90)] public uint _7;

        [FieldOffset(0x94)] public uint dwOwnerType;
        [FieldOffset(0x98)] public uint dwOwnerId;

        [FieldOffset(0x9c)] [MarshalAs(UnmanagedType.ByValArray, SizeConst=3)]  public uint[] _8;

        [FieldOffset(0xa8)] public IntPtr ptrInfo;

        [FieldOffset(0xac)] [MarshalAs(UnmanagedType.ByValArray, SizeConst=6)]  public uint[] _9;

        [FieldOffset(0xc4)] public uint dwFlags;
        [FieldOffset(0xc8)] public uint dwFlags2;

        [FieldOffset(0xcc)] [MarshalAs(UnmanagedType.ByValArray, SizeConst=5)]  public uint[] _10;

        [FieldOffset(0xe0)] public IntPtr ptrChangedNext;
        [FieldOffset(0xe4)] public IntPtr ptrRoomNext;
        [FieldOffset(0xe8)] public IntPtr ptrListNext;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct StatList
    {
       [MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)] public uint[] _1;               
       public IntPtr pStat;               
       public UInt16 wStatCount1;           
       public UInt16 wStatCount2;           
       [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public uint[] _2;               
       public IntPtr _3;                 
        public uint _4;                 
       public IntPtr pNext;           
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct Stat
    {
        public uint dwStatId;               
        public uint dwStatValue;           
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct SkillInfo
    {
       public UInt16 wSkillId;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct Skill
    {
       public IntPtr pSkillInfo;         
       public IntPtr pNextSkill;           
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public uint[] _1;
       public uint dwSkillLevel;           
       [MarshalAs(UnmanagedType.ByValArray, SizeConst=2)]  public uint[] _2;
       public uint dwFlags;               
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct Info
    {
       public IntPtr pGame1C;               
       public IntPtr pFirstSkill;         
       public IntPtr pLeftSkill;           
       public IntPtr pRightSkill;         
    }

   
    [StructLayout(LayoutKind.Explicit)]
    public struct MonsterData
    {
       [FieldOffset(0x00)] [MarshalAs(UnmanagedType.ByValArray, SizeConst=22)] public byte[] _1;
     
       
      //[FieldOffset(0x16)] public byte  fFlags;
        [FieldOffset(0x16)] public byte Flags;

       [FieldOffset(0x17)] public UInt16   _2;                 
       [FieldOffset(0x18)] public uint     _3;                 
       [FieldOffset(0x1C)] [MarshalAs(UnmanagedType.ByValArray, SizeConst=9)]  public byte[] anEnchants;           
       [FieldOffset(0x25)] public byte     _4;                 
       [FieldOffset(0x26)] public UInt16   wUniqueNo;               
       [FieldOffset(0x28)] public byte     _5;                 

      [FieldOffset(0x2C)] [MarshalAs(UnmanagedType.ByValTStr, SizeConst=28)]  public string wName;
    }
   
    /*
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct MonsterData
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 22)]
        public byte[] _1;

        public byte Flags;

        public UInt16 _2;
        public uint _3;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)]
        public byte[] anEnchants;
        public byte _4;
        public UInt16 wUniqueNo;
        public byte _5;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 28)]
        public string wName;
    }
*/
    [Flags]
    public enum MonsterDataFlags
    {
        None,
        Minion = 10,
        Champion = 16
    }
}



Code:
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace Chief.Structs
{
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct GameInfo
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst=6)]  public uint[] _1;
       public UInt16  _1a;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst=24)] public string szGameName;
       [MarshalAs(UnmanagedType.ByValTStr, SizeConst=86)] public string szGameServerIp;
       [MarshalAs(UnmanagedType.ByValTStr, SizeConst=48)] public string szAccountName;
       [MarshalAs(UnmanagedType.ByValTStr, SizeConst=24)] public string szCharName;
       [MarshalAs(UnmanagedType.ByValTStr, SizeConst=24)] public string szRealmName;
       [MarshalAs(UnmanagedType.ByValArray, SizeConst=0x157)]  public uint[] _2;
       [MarshalAs(UnmanagedType.ByValTStr, SizeConst=24)] public string szGamePassword;     
    }
    /*
    I'm trying to represent "CHAR szGameName[0x18];" in a C# struct, I'm sure I have the correct offsets and such, but I get overlapping errors unless I use: "[MarshalAs(UnmanagedType.U1, SizeConst=24)] public byte szGameName;" -- which doesn't give me the character array, but the number 97
     */
}



Code:
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace Chief.Structs
{
    [StructLayout(LayoutKind.Sequential)]
    public struct Control
    {
       public uint dwType;               
       [MarshalAs(UnmanagedType.ByValArray, SizeConst=2)]  public uint[] _1;               
       public uint dwPosX;               
       public uint dwPosY;               
       public uint dwSizeX;               
       public uint dwSizeY;               
       public uint fnCallback;           
       [MarshalAs(UnmanagedType.ByValArray, SizeConst=7)]  public uint[] _3;               
       public IntPtr pNext;           
       [MarshalAs(UnmanagedType.ByValArray, SizeConst=5)]  public uint[] _4;               
       public uint dwSelectStart;         
       public uint dwSelectEnd;           
       [MarshalAs(UnmanagedType.ByValArray, SizeConst=256)]  public byte[] wText;           
       public uint dwCursorPos;           
       public uint dwIsCloaked;           
    }
}



Code:
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace Chief.Structs
{
    [StructLayout(LayoutKind.Explicit)]
    public struct PresetUnit
    {
       [FieldOffset(0x0)]  [MarshalAs(UnmanagedType.ByValArray, SizeConst=2)]   public uint[] _1;
        [FieldOffset(0x08)] public uint dwPosY;
       [FieldOffset(0x0C)] public int  dwClassID;
        [FieldOffset(0x10)] [MarshalAs(UnmanagedType.ByValArray, SizeConst=1)]   public uint[] _2;
        [FieldOffset(0x1C)] public IntPtr pPresetNext;
        [FieldOffset(0x20)] public uint dwPosX;
        [FieldOffset(0x24)] public uint dwType;
    }

    /// <summary>
    /// Sizeof = 0x230
    /// </summary>
    [StructLayout(LayoutKind.Explicit)]
    public struct Level
    {
        [FieldOffset(0x00)]    public uint _1;                  //0x00
        [FieldOffset(0x04)]    public int dwPosX;               //0x04
        [FieldOffset(0x08)]    public int dwPosY;               //0x08
        [FieldOffset(0x0C)]    public int dwSizeX;               //0x0C
        [FieldOffset(0x10)]    public int dwSizeY;               //0x10
       [FieldOffset(0x14)]     public uint nLevelNo;
       [FieldOffset(0x18)]     [MarshalAs(UnmanagedType.ByValArray, SizeConst=120)] public uint[] _1a;
       [FieldOffset(0x1F8)]    public uint seed;
       [FieldOffset(0x1FC)]    [MarshalAs(UnmanagedType.ByValArray, SizeConst=1)]   public uint[] _2;
        [FieldOffset(0x204)]    public IntPtr ptrRoom2First;
        [FieldOffset(0x208)]    public IntPtr ptrDrlgMisc;
       [FieldOffset(0x20C)]    [MarshalAs(UnmanagedType.ByValArray, SizeConst=8)]   public uint[] _3;
        [FieldOffset(0x22C)]    public IntPtr ptrLevelNext;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct Act
    {
       [MarshalAs(UnmanagedType.ByValArray, SizeConst=2)] public uint[] _1;
        public IntPtr pMisc;
        public IntPtr pRoom1;
        public uint _2;
        public uint dwAct;
        public uint pfnCallBack;           
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct ActMisc
    {
       [FieldOffset(0x0)]     [MarshalAs(UnmanagedType.ByValArray, SizeConst=33)]   public uint[] _1;
       [FieldOffset(0x84)]    public IntPtr ptrDrlgAct;
       [FieldOffset(0x88)]    public uint   nBossTombLvl;
       [FieldOffset(0x8C)]    [MarshalAs(UnmanagedType.ByValArray, SizeConst=248)]  public uint[] _2;
       [FieldOffset(0x46C)]   public IntPtr ptrLevelFirst;
       [FieldOffset(0x470)]   [MarshalAs(UnmanagedType.ByValArray, SizeConst=2)]    public uint[] _3;
       [FieldOffset(0x478)]   public uint   nStaffTombLvl;
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct Path
    {
       [FieldOffset(0x00)]   public UInt16 xOffset;               
       [FieldOffset(0x02)]   public UInt16 xPos;                 
       [FieldOffset(0x04)]   public UInt16 yOffset;               
       [FieldOffset(0x06)]   public UInt16 yPos;   
               
       [FieldOffset(0x08)]   [MarshalAs(UnmanagedType.ByValArray, SizeConst=2)]  public uint[] _1;
       [FieldOffset(0x10)]   public UInt16 xTarget;               
       [FieldOffset(0x12)]   public UInt16 yTarget;
        [FieldOffset(0x14)]   [MarshalAs(UnmanagedType.ByValArray, SizeConst=2)]  public uint[] _2;
        [FieldOffset(0x1C)]   public IntPtr pRoom1;               
        [FieldOffset(0x20)]   public IntPtr pRoomUnk;           
       [FieldOffset(0x24)]   [MarshalAs(UnmanagedType.ByValArray, SizeConst=3)]  public uint[] _3;
        [FieldOffset(0x30)]   public IntPtr pUnit;           
       [FieldOffset(0x34)]   public uint dwFlags;               
       [FieldOffset(0x38)]   public uint _4;                 
       [FieldOffset(0x3C)]   public uint dwPathType;           
       [FieldOffset(0x40)]   public uint dwPrevPathType;         
       [FieldOffset(0x44)]   public uint dwUnitSize;           
       [FieldOffset(0x48)]   [MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]  public uint[] _5;
        [FieldOffset(0x58)]   public IntPtr pTargetUnit;         
       [FieldOffset(0x5C)]   public uint dwTargetType;           
       [FieldOffset(0x60)]   public uint dwTargetId;           
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct Room1
    {
       [FieldOffset(0x00)]   [MarshalAs(UnmanagedType.ByValArray, SizeConst=2)] public uint[] dwSeed;
       [FieldOffset(0x08)]   public uint dwXStart;               
       [FieldOffset(0x0C)]   public uint dwYStart;               
       [FieldOffset(0x10)]   public uint dwXSize;               
       [FieldOffset(0x14)]   public uint dwYSize;               
       [FieldOffset(0x18)]   [MarshalAs(UnmanagedType.ByValArray, SizeConst=7)] public uint[] _1;
       [FieldOffset(0x34)]   public IntPtr pRoomsNear;           
       [FieldOffset(0x38)]   public IntPtr pRoom2;               
       [FieldOffset(0x3C)]   public IntPtr pUnitFirst;         
       [FieldOffset(0x40)]   [MarshalAs(UnmanagedType.ByValArray, SizeConst=6)] public uint[] _2;
       [FieldOffset(0x58)]   public IntPtr _1s;                 
       [FieldOffset(0x5C)]   public uint _3;                 
       [FieldOffset(0x60)]   public IntPtr Coll;               
       [FieldOffset(0x64)]   [MarshalAs(UnmanagedType.ByValArray, SizeConst=2)] public uint[] _4;
       [FieldOffset(0x6C)]   public IntPtr pAct;                 
       [FieldOffset(0x70)]   public uint _5;                 
       [FieldOffset(0x74)]   public IntPtr pRoomNext;           
       [FieldOffset(0x78)]   public int nUnknown;               
       [FieldOffset(0x7C)]   public uint dwRoomsNear;           
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct Room2
    {
       [FieldOffset(0x00)]   public IntPtr pRoomTiles;         
       [FieldOffset(0x04)]   public uint _1;                 
       [FieldOffset(0x08)]   public uint dwPresetType;           
       [FieldOffset(0x0C)]   public uint _2;                 
       [FieldOffset(0x10)]   public uint dwRoomsNear;           
       [FieldOffset(0x14)]   [MarshalAs(UnmanagedType.ByValArray, SizeConst=2)] public uint[] _3;
       [FieldOffset(0x1C)]   public IntPtr pLevel;               
       [FieldOffset(0x20)]   public uint dwPosX;               
       [FieldOffset(0x24)]   public uint dwPosY;               
       [FieldOffset(0x28)]   public uint dwSizeX;               
       [FieldOffset(0x2C)]   public uint dwSizeY;               
       [FieldOffset(0x30)]   public IntPtr pRoom2Near;         
       [FieldOffset(0x34)]   public IntPtr pPreset;         
       [FieldOffset(0x38)]   public IntPtr pRoom2Next;           
       [FieldOffset(0x3C)]   [MarshalAs(UnmanagedType.ByValArray, SizeConst=34)] public uint[] _4;
       [FieldOffset(0xC4)]   public IntPtr pRoom2Prev;           
       [FieldOffset(0xC8)]   public IntPtr pRoom2Other;         
       [FieldOffset(0xCC)]   public uint _5;                 
       [FieldOffset(0xD0)]   [MarshalAs(UnmanagedType.ByValArray, SizeConst=2)] public uint[] dwSeed;
       [FieldOffset(0xD8)]   public uint _6;                 
       [FieldOffset(0xDC)]   public IntPtr pType2Info;           
       [FieldOffset(0xE0)]   [MarshalAs(UnmanagedType.ByValArray, SizeConst=2)] public uint[] _7;
       [FieldOffset(0xE8)]   public IntPtr pRoom1;               
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct RoomTile
    {
        [FieldOffset(0x00)] public uint _1;                 
        [FieldOffset(0x04)] public IntPtr pRoom2;               
        [FieldOffset(0x08)] public IntPtr pNext;           
        [FieldOffset(0x0c)] public IntPtr nNum;               
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct LevelText
    {
       [FieldOffset(0x00)] public uint dwLevelNo;           
       [FieldOffset(0x04)] [MarshalAs(UnmanagedType.ByValArray, SizeConst=60)] public uint[] _1;               
       [FieldOffset(0xF4)] public byte _2;                 
       [FieldOffset(0xF5)] [MarshalAs(UnmanagedType.LPStr, SizeConst=40)]  public string szName;
       [FieldOffset(0x11D)] [MarshalAs(UnmanagedType.LPStr, SizeConst=40)]  public string  szEntranceText;
       [FieldOffset(0x145)] [MarshalAs(UnmanagedType.LPStr, SizeConst=41)]  public string  szLevelDesc;
       [FieldOffset(0x16E)] [MarshalAs(UnmanagedType.LPStr, SizeConst=40)]  public string  wName;
       [FieldOffset(0x1BE)] [MarshalAs(UnmanagedType.LPStr, SizeConst=40)]  public string  wEntranceText;
       [FieldOffset(0x196)] [MarshalAs(UnmanagedType.ByValArray, SizeConst=8)] public byte[] nObjGroup;
       [FieldOffset(0x19E)] [MarshalAs(UnmanagedType.ByValArray, SizeConst=8)] public byte[] nObjPrb;
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct Coll
    {
        [FieldOffset(0x00)]
        public uint dwPosGameX;           
        [FieldOffset(0x04)]
        public uint dwPosGameY;           
        [FieldOffset(0x08)]
        public uint dwSizeGameX;           
        [FieldOffset(0x0C)]
        public uint dwSizeGameY;           
        [FieldOffset(0x10)]
        public uint dwPosRoomX;           
        [FieldOffset(0x14)]
        public uint dwPosRoomY;           
        [FieldOffset(0x18)]
        public uint dwSizeRoomX;           
        [FieldOffset(0x1C)]
        public uint dwSizeRoomY;           
        [FieldOffset(0x20)]
        public IntPtr pMapStart;           
        [FieldOffset(0x22)]
        public IntPtr pMapEnd;               
    }
}



Code:
using System;
using System.Collections.Generic;
using System.Text;

using ProcessMemoryReaderLib;

using D2Data;

using Chief;

using Chief.Structs;

namespace Chief
{
    public class Memory
    {
        public ProcessMemoryReader Reader;

        public Memory(ProcessMemoryReader reader)
        {
            this.Reader = reader;
        }

        public bool IsInGame()
        {
            return this.GetPlayerUnit().dwUnitId != 0;
        }

        public UnitAny GetPlayerUnit()
        {
            IntPtr playerPointer = (IntPtr)BitConverter.ToUInt32(this.Reader.Read((int)DllBase.D2Client + 0x11C1E0, 4), 0);

            return (UnitAny)this.Reader.Read(playerPointer, typeof(UnitAny));
        }

        /*
        public List<Stat> GetPlayerStats()
        {
            List<Stat> tempList = new List<Stat>();

            for (StatList statList = (StatList)this.Reader.Read(this.GetPlayerUnit().ptrStats, typeof(StatList));
                ;
                statList = (StatList)this.Reader.Read(statList.pNext, typeof(StatList)))
            {
                for (int i = 0; i < statList.wStatCount1; i++)
                    tempList.Add((Stat)this.Reader.Read((IntPtr)((int)statList.pStat + (i*8)), typeof(Stat)));

                if (statList.pNext == (IntPtr)0)
                    break;
            }

            return tempList;
        }*/

        public Path GetPlayerPath()
        {
            return (Path)this.Reader.Read(this.GetPlayerUnit().ptrPath, typeof(Path));
        }

        public Act GetCurrentAct()
        {
            return (Act)this.Reader.Read(this.GetPlayerUnit().ptrAct, typeof(Act));
        }

        public Room1 GetPlayerRoom1()
        {
            return (Room1)this.Reader.Read(this.GetPlayerPath().pRoom1, typeof(Room1));
        }

        public Room2 GetPlayerRoom2()
        {
            return (Room2)this.Reader.Read(this.GetPlayerRoom1().pRoom2, typeof(Room2));
        }

        public Level GetCurrentLevel()
        {
            return (Level)this.Reader.Read(this.GetPlayerRoom2().pLevel, typeof(Level));
        }

        public List<Room2> GetAllRoom2()
        {
            return this.GetAllRoom2(this.GetCurrentLevel());
        }
        public List<Room2> GetAllRoom2(Level level)
        {
            List<Room2> room2List = new List<Room2>();

            // Save first room
            Room2 tempRoom = (Room2)this.Reader.Read(level.ptrRoom2First, typeof(Room2));
            room2List.Add(tempRoom);

            for (; ; )
            {
                // Get next room
                tempRoom = (Room2)this.Reader.Read(tempRoom.pRoom2Next, typeof(Room2));

                room2List.Add(tempRoom);

                if (tempRoom.pRoom2Next == (IntPtr) 0)
                    break;
            }

            return room2List;
        }

        public PresetUnit GetPresetUnit(Room2 room2)
        {
            IntPtr presetUnitPointer = room2.pPreset;

            return (PresetUnit)this.Reader.Read(presetUnitPointer, typeof(PresetUnit));
        }

        public List<RoomTile> GetTiles(Room2 room2)
        {
            List<RoomTile> tileList = new List<RoomTile>();

            // Save first tile
            RoomTile tempTile = (RoomTile)this.Reader.Read(room2.pRoomTiles, typeof(RoomTile));
            tileList.Add(tempTile);

            for (; ; )
            {
                // Get next room
                tempTile = (RoomTile)this.Reader.Read(tempTile.pNext, typeof(RoomTile));

                tileList.Add(tempTile);

                if (tempTile.pNext == (IntPtr)0)
                    break;
            }

            return tileList;
        }

        public GameInfo GetGameInfo()
        {
            IntPtr gameInfoPointer = (IntPtr)BitConverter.ToUInt32(this.Reader.Read((int)DllBase.D2Client + 0x10D618, 4), 0);

            return (GameInfo)this.Reader.Read(gameInfoPointer, typeof(GameInfo));
        }

        public Dictionary<SkillType, int> GetPlayerSkills()
        {
            Info info = (Info)this.Reader.Read(this.GetPlayerUnit().ptrInfo, typeof(Info));

            Dictionary<SkillType, int> skillList = new Dictionary<SkillType, int>();

            // Save first tile
            Skill tempSkill = (Skill)this.Reader.Read(info.pFirstSkill, typeof(Skill));
            Structs.SkillInfo skillInfo = (Structs.SkillInfo)this.Reader.Read(tempSkill.pSkillInfo, typeof(Structs.SkillInfo));
            skillList.Add((SkillType)skillInfo.wSkillId, (int)tempSkill.dwSkillLevel);

            for (; ; )
            {
                // Get next room
                tempSkill = (Skill)this.Reader.Read(tempSkill.pNextSkill, typeof(Skill));
                skillInfo = (Structs.SkillInfo)this.Reader.Read(tempSkill.pSkillInfo, typeof(Structs.SkillInfo));
                skillList.Add((SkillType)skillInfo.wSkillId, (int)tempSkill.dwSkillLevel);

                if (tempSkill.pNextSkill == (IntPtr)0)
                    break;
            }

            return skillList;
        }

        /// <summary>
        /// Must be in the same act as the unit
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public UnitAny GetUnit(NPCCode code)
        {
            for (Room1 room1 = (Room1)this.Reader.Read(this.GetCurrentAct().pRoom1, typeof(Room1));
                ;
                room1 = (Room1)this.Reader.Read(room1.pRoomNext, typeof(Room1)))
            {
                for (UnitAny unit = (UnitAny)this.Reader.Read(room1.pUnitFirst, typeof(UnitAny));
                    ;
                    unit = (UnitAny)this.Reader.Read(unit.ptrListNext, typeof(UnitAny)))
                {
                    if (unit.dwTxtFileNo == (uint)code)
                        return unit;

                    if (unit.ptrListNext == (IntPtr)0)
                        break;
                }

                if (room1.pRoomNext == (IntPtr)0)
                    break;
            }

            return new UnitAny();
        }

        /// <summary>
        /// Must be in the same act as the unit
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public UnitAny GetUnit(UniqueMonster code)
        {
            for (Room1 room1 = (Room1)this.Reader.Read(this.GetCurrentAct().pRoom1, typeof(Room1));
                ;
                room1 = (Room1)this.Reader.Read(room1.pRoomNext, typeof(Room1)))
            {
                for (UnitAny unit = (UnitAny)this.Reader.Read(room1.pUnitFirst, typeof(UnitAny));
                    ;
                    unit = (UnitAny)this.Reader.Read(unit.ptrListNext, typeof(UnitAny)))
                {
                    if ((UniqueMonster)this.GetMonsterData(unit).wUniqueNo == code)
                        return unit;

                    if (unit.ptrListNext == (IntPtr)0)
                        break;
                }

                if (room1.pRoomNext == (IntPtr)0)
                    break;
            }

            return new UnitAny();
        }

        /// <summary>
        /// Gets monsters in the same act
        /// </summary>
        /// <returns></returns>
        public List<UnitAny> GetUnits()
        {
            List<UnitAny> tempList = new List<UnitAny>();

            for (Room1 room1 = (Room1)this.Reader.Read(this.GetCurrentAct().pRoom1, typeof(Room1));
                ;
                room1 = (Room1)this.Reader.Read(room1.pRoomNext, typeof(Room1)))
            {
                for (UnitAny unit = (UnitAny)this.Reader.Read(room1.pUnitFirst, typeof(UnitAny));
                    ;
                    unit = (UnitAny)this.Reader.Read(unit.ptrListNext, typeof(UnitAny)))
                {
                    tempList.Add(unit);

                    if (unit.ptrListNext == (IntPtr)0)
                        break;
                }

                if (room1.pRoomNext == (IntPtr)0)
                    break;
            }

            return tempList;
        }

        /// <summary>
        /// Gets monsters in the same level of specified type
        /// </summary>
        /// <returns></returns>
        public List<UnitAny> GetUnits(NPCCode code)
        {
            List<UnitAny> tempList = new List<UnitAny>();

            for (Room1 room1 = (Room1)this.Reader.Read(this.GetCurrentAct().pRoom1, typeof(Room1));
                ;
                room1 = (Room1)this.Reader.Read(room1.pRoomNext, typeof(Room1)))
            {
                for (UnitAny unit = (UnitAny)this.Reader.Read(room1.pUnitFirst, typeof(UnitAny));
                    ;
                    unit = (UnitAny)this.Reader.Read(unit.ptrListNext, typeof(UnitAny)))
                {
                    if((NPCCode)unit.dwTxtFileNo == code)
                        tempList.Add(unit);

                    if (unit.ptrListNext == (IntPtr)0)
                        break;
                }

                if (room1.pRoomNext == (IntPtr)0)
                    break;
            }

            return tempList;
        }

        public MonsterData GetMonsterData(UniqueMonster code)
        {
            return (MonsterData)this.Reader.Read(this.GetUnit(code).ptrMonsterData, typeof(MonsterData));
        }
        public MonsterData GetMonsterData(UnitAny monster)
        {
            return (MonsterData)this.Reader.Read(monster.ptrMonsterData, typeof(MonsterData));
        }
        public List<MonsterData> GetMonsterData(List<UnitAny> monsters)
        {
            List<MonsterData> tempList = new List<MonsterData>();

            foreach (UnitAny monster in monsters)
                tempList.Add(this.GetMonsterData(monster));

            return tempList;
        }

        public List<Enchant> GetMonsterEnchants(NPCCode code)
        {
            return this.GetMonsterEnchants(this.GetUnit(code));
        }
        public List<Enchant> GetMonsterEnchants(UniqueMonster code)
        {
            return this.GetMonsterEnchants(this.GetUnit(code));
        }
        public List<Enchant> GetMonsterEnchants(UnitAny monster)
        {
            return this.GetMonsterEnchants(this.GetMonsterData(monster));
        }
        public List<Enchant> GetMonsterEnchants(MonsterData monster)
        {
            List<Enchant> tempList = new List<Enchant>();

            foreach (byte b in monster.anEnchants)
                tempList.Add((Enchant)b);

            return tempList;
        }

        public List<Control> GetControls()
        {
            List<Control> tempList = new List<Control>();

            IntPtr firstControlPtr = (IntPtr)BitConverter.ToUInt32(this.Reader.Read((int)DllBase.D2Win + 0x20488, 4), 0);

            for (Control control = (Control)this.Reader.Read(firstControlPtr, typeof(Control));
                ;
                control = (Control)this.Reader.Read(control.pNext, typeof(Control)))
            {
                tempList.Add(control);

                if (control.pNext == (IntPtr)0)
                    break;
            }
           
            return tempList;
        }

        public OutOfGameState GetState()
        {
            List<Control> controls = this.GetControls();

            foreach (Control control in controls)
            {
                string text = new System.Text.UnicodeEncoding().GetString(control.wText);

                if (text.Contains("CHANNEL"))
                    return OutOfGameState.Lobby;

                if (text.Contains("CONVERT TO"))
                    return OutOfGameState.CharacterSelect;

                if (text.Contains("LOG IN"))
                    return OutOfGameState.Login;

                if (text.Contains("GATEWAY"))
                    return OutOfGameState.Start;

                //if(text.Contains("");
            }

            return OutOfGameState.None;
        }

        public bool WaitForState(OutOfGameState state, int timeOut)
        {
            DateTime start = DateTime.Now;

            while(this.GetState() != state)
            {
                if (((TimeSpan)DateTime.Now.Subtract(start)).TotalMilliseconds > timeOut)
                    return false;

                System.Threading.Thread.Sleep(10);
            }

            return true;
        }
    }
}



and MemoryPointers.cs
Code:
using System;
using System.Collections.Generic;
using System.Text;

namespace Chief
{
    public enum DllBase : int
    {
        D2Client    = 0x6FAB0000,
        D2Common    = 0x6FD50000,
        D2Gfx       = 0x6FA80000,
        D2Win       = 0x6F8E0000,
        D2Lang      = 0x6FC00000,
        D2Cmp       = 0x6FE10000,
        D2Multi     = 0x6F9D0000,
        BNClient    = 0x6FF20000,
        D2Net       = 0x6FFB0000, // conflict with STORM.DLL
        Storm       = 0x6FBF0000,
        Fog         = 0x6FF50000
    }
}



Phew. Hope that should be enough to get you started with your work. Also see my ChiefTrist project for an example usage of ET's libs:
http://www.edgeofnowhere.cc/viewtopic.php?t=358562