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