Valhalla Legends Forums Archive | BnetDocs Research and Discussion | [D2] C# Structs

AuthorMessageTime
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:
[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]


Code:
[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]


Code:
[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]


Code:
[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]


Code:
[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;
        }
    }
}[/code]


and MemoryPointers.cs
Code:
[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
    }
}[/code]


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
July 20, 2007, 10:29 AM

Search