This is a mini-tutorial that explains how to create an enumerator to walk the list of objects in the object manager.
Objects in the memory space of the World of Warcraft game client are held in a linked list that can be iterated over once you have the base address of the in-game Object Manager class. Walking that list of memory addresses can be a troublesome issue for many would-be developers. The easiest way that I have found, for C# development, is to create an enumerable list of memory addresses which can be treated just like any other collection to be iterated over.
Fortunately for C# developrs, creating a list of memory addresses is trivial using the enumerator interfaces built in to .NET.
The two classes provided below work by taking the pointer to the game client object manager class, and iterating over the linked list structure in-situ. Rather than doing the dirty work of juggling pointers in your own code, and trying to detect if you have run off the end of the linked list, you can simply use the built-in “foreach” loop structure of whatever your favourite .NET language is to retrieve the memory address of each game object. From there it is possible to write a wrapper class to manipulate the game object, or overlay the appropriate game object structure at the memory address.
A trivial example that makes use of the enumerable and enumerator classes is provided that walks the linked list of Warcraft game objects.
In the Enumerator class given below the “ObjectManagerPtr” is determined in the usual manner for accessing the list of locally cached in-game objects.
Code:
public class ObjectMemoryAddresses : IEnumerable
{
public ObjectMemoryAddresses()
{
}
public IEnumerator GetEnumerator()
{
return (new ObjectMemoryAddressesEnumerator());
}
}
public class ObjectMemoryAddressesEnumerator : IEnumerator
{
// The following two offsets apply to the 3.2.2a game client.
public const uint OBJECT_LIST_OFFSET = 0x70;
public const uint NEXT_OBJECT_OFFSET = 0x3C;
private uint m_currentAddress = 0;
public ObjectMemoryAddressesEnumerator()
{
}
private uint GetNextAddress()
{
if (m_currentAddress == 0)
{
m_currentAddress = ObjectManagerPtr + OBJECT_LIST_OFFSET;
}
return MemoryEditor.ReadUInt(m_currentAddress + NEXT_OBJECT_OFFSET);
}
private bool IsValidAddress(uint address)
{
if (address == 0)
{
return (false);
}
if ((address & 1) != 0)
{
return (false);
}
if (address == m_currentAddress)
{
return (false);
}
return (true);
}
public bool MoveNext()
{
uint newAddress = GetNextAddress();
if (!IsValidAddress(newAddress))
{
m_currentAddress = uint.MaxValue;
return (false);
}
m_currentAddress = newAddress;
return (true);
}
public void Reset()
{
m_currentAddress = 0;
}
public object Current
{
get
{
if ((m_currentAddress == 0) || (m_currentAddress == uint.MaxValue))
{
throw new InvalidOperationException();
}
return (m_currentAddress);
}
}
}
Example usage:
Code:
List<WowObject> objectList = new List<WowObject>();
ObjectMemoryAddresses objectMemory = new ObjectMemoryAddresses();
// get the memory address of each object
foreach (uint memoryAddress in objectMemory)
{
objectList.Add(GetWoWObjectFromPtr(memoryAddress));
}
You can also apply this same enumerator technique to walking the player name cache or the auras. I believe that the auras and the player name cache are both stored in a C++ STL Map or something similar because of the “two lists” that are apparent in the memory structure. Most game client name cache functions found in the wild emulate the functionality of a C++ STL Map lookup.