It would make more sense to post in that thread instead of creating your own, with a random name.
You are probably not understanding what that piece of code is doing or why it is doing so. I don't blame you as it is quite cryptic. First of all, the "ui_component_table" is internal to a hash table. It contains an array of linked lists. In memory this translates to an array of
pointers. Diablo is a 32-bit process, so the size of a
pointer is 4 bytes, hence the multiplication by 4.
Some of my code might shed some light on how it works:
Code:
public class HashTable : MemoryObject
{
internal const int SizeOf = 72;
public HashTable(ProcessMemory memory, int address)
: base(memory, address) { }
public int Base { get { return Read<int>(0x008); } }
public int Size { get { return Read<int>(0x010); } }
public int Mask { get { return Read<int>(0x040); } }
}
public class UIComponentMap : HashTable, IEnumerable<UIComponent>
{
public UIComponentMap(ProcessMemory memory, int address)
: base(memory, address) { }
internal Pair this[int bucket]
{
get
{
int pairPtr = Memory.Read<int>(Base + bucket * sizeof(int));
if (pairPtr == 0)
{
return null;
}
else
{
return new Pair(Memory, pairPtr);
}
}
}
public IEnumerator<UIComponent> GetEnumerator()
{
int count = Size;
for (int i = 0; i < count; i++)
{
int pairPtr = Memory.Read<int>(Base + i * sizeof(int));
if (pairPtr != 0)
{
Pair pair = new Pair(Memory, pairPtr);
while (pair != null)
{
yield return pair.Value;
pair = pair.Next;
}
}
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
internal class Pair : MemoryObject
{
public Pair(ProcessMemory memory, int address)
: base(memory, address) { }
public Pair Next
{
get
{
Pair next = null;
int nextPointer = Read<int>(0x000);
if (nextPointer > 0)
next = new Pair(Memory, nextPointer);
return next;
}
}
public UIReference Key { get { return new UIReference(Memory, Address + 0x004); } }
public UIComponent Value { get { return new UIComponent(Memory, Read<int>(0x210)); } }
}
}
EDIT: Now I understand better why it's so confusing. The method is filling an array (in that case), so it would be logical to assume the last number is the size of that array. However, you should see the 2nd parameter as a pointer to where you want the data (this is some PInvoke magic in the works), meaning you have to specify how much to read as bytes.