You must know a little more about how WoW stores and accesses its entities in the world to know how to proceed.
Basiclly, every object has a structure. This is the current struct as I know it to be as of this post.
Code:
public struct WowObjectData {
// x32 : x64
readonly IntPtr vtable; // 0x00 0x00
readonly IntPtr LegionExtra; // 0x08 0x18
public IntPtr Descriptors; // 0x04 0x10
readonly IntPtr unk1; // 0x08 0x18
public int TypeCode; // 0x0C 0x20
readonly IntPtr unk3; // 0x10 0x24
readonly IntPtr unk4; // 0x14 0x28
readonly IntPtr unk5; // 0x18 0x30
readonly IntPtr unk6; // 0x1C 0x38
readonly IntPtr unk7; // 0x20 0x40
readonly IntPtr unk8; // 0x24 0x48
public WowGuid Guid; // 0x28 0x50
}
The objects real type can be found at the "TypeCode" offset. The types and example:
Code:
public enum WowObjectType {
Object = 0,
Item = 1,
Container = 2,
Unit = 3,
Player = 4,
GameObject = 5,
DynamicObject = 6,
Corpse = 7,
AreaTrigger = 8,
SceneObject = 9,
Conversation = 10
}
Code:
IntPtr current = IntPtr.Zero // the real address of the entity here
var typeOffset = Marshal.OffsetOf(typeof(WowObjectData), "TypeCode").ToInt32();
var type = (WowObjectType) Memory.Read<int>(current + typeOffset);
Now as far as ClntObjMgrEnumVisibleObjects goes, that is normally a function people call in-process where you pass your own call back pointer to the function. Here is how it looks like externally. You can get the missing structures and the example this was based on here WowMoPObjMgrTest/ObjectManager.cs at master * tomrus88/WowMoPObjMgrTest * GitHub
Code:
/// <summary>
/// A static class to handle creating a list of entites containing the <see cref="WowObjectData" /> structure.
/// </summary>
public static class EntityList {
/// <summary>
/// Collects a dictonary of current entitie with the guid as the key.
/// </summary>
public static Dictionary<WowGuid, WowObject> EntitiesAsDictionary {
get {
var woWObjects = new Dictionary<WowGuid, WowObject>();
CollectEntities(GetFirstObject(), woWObjects);
return woWObjects;
}
}
/// <summary>
/// A collection of current entities.
/// </summary>
public static IEnumerable<WowObject> Entities => EntitiesAsDictionary.Values.ToList();
/// <summary>
/// Gets the pointer to the first object in the list.
/// </summary>
/// <returns></returns>
static IntPtr GetFirstObject() {
var mgr = Wow64.CurrentManager;
return mgr.VisibleObjects.m_fulllist.baseClass.m_terminator.m_next;
}
/// <summary>
/// Gets the pointer to the next object in the list.
/// </summary>
/// <param name="current">The current objects pointer.</param>
/// <returns>SetObjectManager pointer to the next object.</returns>
static IntPtr GetNextObjectFrom(IntPtr current) {
var mgr = Wow64.CurrentManager;
return Wow.Memory.Read<IntPtr>(current + mgr.VisibleObjects.m_fulllist.baseClass.m_linkoffset + IntPtr.Size);
}
/// <summary>
/// Generates the dictonary of entities.
/// </summary>
/// <param name="firstObject">The address to the first object of the entity list.</param>
/// <param name="wowObjectDictionary">The dictonary to fill results with.</param>
[SuppressMessage("ReSharper", "SwitchStatementMissingSomeCases")]
static void CollectEntities(IntPtr firstObject, IDictionary<WowGuid, WowObject> wowObjectDictionary) {
var typeOffset = Marshal.OffsetOf(typeof(WowObjectData), "TypeCode").ToInt32();
var type = (WoWObjectType) Memory.Read<int>(current + typeOffset);
var current = firstObject;
while ((current.ToInt64() & 1) == 0 && current != IntPtr.Zero) {
var type = (WoWObjectType) Wow.Memory.Read<int>(current + typeOffset);
switch (type) {
case WoWObjectType.Item:
AddTo(wowObjectDictionary, new WowItem(current));
break;
case WoWObjectType.Container:
AddTo(wowObjectDictionary, new WowContainer(current));
break;
case WoWObjectType.Unit:
AddTo(wowObjectDictionary, new WowUnit(current));
break;
case WoWObjectType.Player:
AddTo(wowObjectDictionary, new WowPlayer(current));
break;
case WoWObjectType.GameObject:
AddTo(wowObjectDictionary, new WowGameObject(current));
break;
case WoWObjectType.Corpse:
AddTo(wowObjectDictionary, new WowCorpse(current));
break;
default:
AddTo(wowObjectDictionary, new WowObject(current));
break;
}
current = GetNextObjectFrom(current);
}
}
static void AddTo(IDictionary<WowGuid, WowObject> wowObjects, WowObject wowObject) {
wowObjects.Add(wowObject.Guid, wowObject);
}
}