# Forum > World of Warcraft > World of Warcraft Bots and Programs > WoW Memory Editing >  [Retail] Shadowlands 9.0.1.36230 Offsets

## scizzydo

Here's some of what I'm using and have found so far:


```
#define GETPOINTERFROMTOKEN					0x1A237B0	//837 0x16A6820
#define FRAMESCRIPT_REGISTERFUNCTION				0x792340	//837 0x523C20
#define FRAMESCRIPT_UNREGISTERFUNCTION				0x7925C0	//837 0x523EA0
#define LUAL_LOADBUFFER						0x1D72CC0	//837 0x19E76A0
#define LUA_PCALL						0x25FDE0	//837 0x1D8E20
#define LUA_GETTOP						0x25F860	//837 0x1D88A0
#define LUA_SETTOP						0x260AB3	//837 0x1D9AF0
#define TEXTEND							0x2E42998	//837 0x29B0170
#define LUA_TOBOOLEAN						0x260C90	//837 0x1D9CD0
#define LUA_PUSHNIL						0x2600E0	//837 0x1D9120
#define LUA_PUSHVALUE						0x260200	//837 0x1D9240
#define LUA_CREATETABLE						0x25F160	//837 0x1D81A0
#define LUA_REMOVE						0x260620	//837 0x1D9660
#define LUA_REPLACE						0x2606E0	//837 0x1D9720
#define LUAL_ERROR						0x1D72610	//837 0x19E6FF0
#define LUA_TOLSTRING						0x260D70	//837 0x1D9DB0
#define LUA_TONUMBER						0x260E10	//837 0x1D9E50
#define LUA_PUSHBOOLEAN						0x25FE70	//837 0x1D8EB0
#define LUA_INSERT						0x25F9C0	//837 0x1D8A00
#define LUAV_GETTABLE						0x25E3C0	//837 0x1D7410
#define LUA_CONCAT						0x25EFD0	//837 0x1D8020
#define LUA_NEWUSERDATA						0x25FCA0	//837 0x1D8CE0
#define LUA_ISNUMBER						0x25FB10	//837 0x1D8B50
#define LUA_TYPE						0x260F20	//837 0x1D9F60
#define LUA_PUSHSTRING						0x260120	//837 0x1D9160
#define LUA_GETFIELD						0x25F740	//837 0x1D8780
#define LUA_PUSHLSTRING						0x260060	//837 0x1D90A0
#define LUA_GETSTACK						0x2577C0	//837 0x1D08E0
#define LUA_PUSHINTEGER						0x260010	//837 0x1D9050
#define LUA_PUSHCCLOSURE					0x25FEA0	//837 0x1D8EE0
#define LUAL_CALLMETA						0x1D721C0	//837 0x19E6BA0
#define LUA_SETFIELD						0x260910	//837 0x1D9950
#define LUAS_NEWLSTR						0x2596C0	//837 0x1D2790
#define LUA_OBJLEN						0x25FD60	//837 0x1D8DA0
#define FRAMESCRIPT_GETTEXT					0x7951F0	//837 0x526B60
#define LUA_RAWGETI						0x2603C0	//837 0x1D9400
#define LUA_ERROR						0x25F280	//837 0x1D82C0
#define LUAV_SETTABLE						0x5E660		//837 0x1D76B0
#define LUA_PUSHNUMBER						0x260100	//837 0x1D9140
#define LUA_SETTABLE						0x260A60	//837 0x1D9AA0
#define LUA_TOUSERDATA						0x260EE0	//837 0x1D9F20
#define LUA_SETMETATABLE					0x2609A0	//837 0x1D99E0
#define LUA_ISSTRING						0x25FB40	//837 0x1D8B80
#define LUA_PUSHLIGHTUSERDATA					0x260040	//837 0x1D9080
#define LUAG_RUNERROR						0x257290	//837 0x1D03B0
#define LUA_RAWGET						0x260330	//837 0x1D9370
#define LUA_ISGUID						0x797DC0	//837 0x529780
#define LUA_TOGUID						0x797FE0	//837 0x5299A0
#define LUA_PUSHGUID						0x797F20	//837 0x5298E0
#define LUA_TOPOINTER						0x260E50	//837 0x1D9E90
#define LUA_TOCFUNCTION						0x260CC0	//837 0x1D9D00
#define LUA_TOINTEGER						0x260CF0	//837 0x1D9D30
#define LUA_CONTEXT						0x2E24B08	//837 0x2987908
```

----------


## gdfsxwy

CameraMgr = 0x00000000000038D8
MouseOverGuid = 0x0000000002F6DE50
TraceLine = 0x1A4 DCF0
pcall = 0x0000000141D75240
RunScript = 0x000000014082DBD0
CurMgr = 0x2EBB9F0
CurMgrOffse = 0x120
FirstObject = -0x28
Type = 0x10
Guid = 0x18
CastingID = 0xA78
UnitHealth = 0x1378+ 0x680（8.3 + 0x680）
TARGET = 0x1540 + 0x680（8.3 + 0x680）

----------


## Tirthankara

PlayerName = 0x2DA55A8
GameBuild = 0x25D3824
GameReleaseDate = 0x25E4D98
GameVersion = 0x25E4D8C
InGameFlag = 0x2F6DE4C

TargetGUID = 0x02C9DAD0
LastTargetGUID = 0x02C9DAE0 


Help please  :Wtfsmilie: 

ObjMgrOffset = 0x120 ??
FirstObj = 0x18 ??
Type = 0x10 ??

----------


## vegoo

```
# ##OFFSETS ##

currentGameVersion = '9.0.1.36230'
GameVersionOffset = 0x24F2518
playerNameoffset = 0x2DA55A8
objManageroffset = 0x2EBB9F0
MouseOverGUIDOffset = 0x2F6DE50
MyTargetGUIDOffset = 0x2C9DAD0
IsInCinematicOffset = 0x2F6D8B0
StopCinematicOffset = 0x14932C0
IsInGameOffset = 0x2F6DE4C
AllowCustomScriptsOffset = 0x2F6DE10


# OBJECT MANAGER OFFSETS

# player guid is outside of objects in manager
playerGUIDOffset = 0x140

firstObject = 0x120
NextObject = 0x0

# object type is byte
# Object Types for BoA:
# 1 - item
# 5 - npc, no idea if it includes monsters
# 6 - other players
# 7 - localplayer

# Standard offset for calculating other offsets
StandardOffset = -0x28

ObjectType = StandardOffset + 0x10

ObjectGUID = StandardOffset + 0x18

# Y and Z are directly after X in memory
UnitObjectXOffset = StandardOffset + 0x650

NPCItemIDOffset = StandardOffset + 0x5E4

# RotationOffset is addition to XOffset

RotationOffset = 0x10

# HP and Mana (since 8.3 probably 4 bytes) - don't know if it's current or max, I don't really use them
currentHPOffset = StandardOffset + 0x19F0
currentManaOffset = StandardOffset + 0x19F8

# race is byte
raceOffset = StandardOffset + 0x1C3C

# byte, 0 when not on flight, other value when on flight
IsOnFlightOffset = StandardOffset + 0x1C40 + 0x2
```

----------


## Rathkor

Target of a spell cast regardless if targeting or not = 0xA90

----------


## CaptainCode

> ```
> # ##OFFSETS ##
> 
> currentGameVersion = '9.0.1.36230'
> GameVersionOffset = 0x24F2518
> playerNameoffset = 0x2DA55A8
> objManageroffset = 0x2EBB9F0
> MouseOverGUIDOffset = 0x2F6DE50
> MyTargetGUIDOffset = 0x2C9DAD0
> ...


I'm curious, do you have any explanation for why there might be a negative offset? Why would a linked list, point to the middle of an object?

----------


## H3XC0R3

That is actually how the list has a pointer to a variable of the object and not the object itself.



```
objMgr = WoWProcess.Read<CGObjectManager>(new IntPtr(0x3657750), true);
for(long i = WoWProcess.Read<long>(new IntPtr(objMgr.VisibleObjects.Next), false); i != objMgr.VisibleObjects.Next; i = WoWProcess.Read<long>(new IntPtr(i), false))
                {
                    var entity_ptr = i - 0x28;
                    var gameObject = GetVisibleWoWObject(entity_ptr);
                    if(gameObject != null)
                    {
                        objects.Add(gameObject);
                    }
                }
```

This is the structure i use:




```
[StructLayout(LayoutKind.Explicit, Pack = 1)]
	public unsafe class TSGrowableArray
	{
		[FieldOffset(0x0)]
		public ulong Capacity;
		[FieldOffset(0x8)]
		public long Array;
		[FieldOffset(0x16)]
		public ulong Allocated;
	};

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public unsafe class TSLink
	{
		public long Next; // TSLink
		public long Previous;
	};

	[StructLayout(LayoutKind.Explicit, Pack = 1)]
	public unsafe class CGObjectManager
	{
		[FieldOffset(0x0)]
		public TSGrowableArray ActiveObjects;  // 0x000
		[FieldOffset(0x20)]
		public TSGrowableArray InvalidObjects; // 0x020
		//[MarshalAs(UnmanagedType.LPArray, SizeConst = 14)]
		//TSLink unk_040;             // 0x040

		[FieldOffset(0x120)]
		public TSLink VisibleObjects;          // 0x120
		//TSLink unk_120;                 // 0x128

		[FieldOffset(0x140)]
		public ObjectGuid LocalGuid;            // 0x140
		
		[FieldOffset(0x150)]
		public uint MapId;                 // 0x150
		//[FieldOffset(0x154)]
		//uint unk_154;               // 0x154
		//[FieldOffset(0x158)]
		//uint unk_158;              // 0x158

		[FieldOffset(0x160)]
		public uint MovementGlobals;      // 0x160
	};
```

----------


## CaptainCode

> That is actually how the list has a pointer to a variable of the object and not the object itself.
> 
> 
> 
> ```
> objMgr = WoWProcess.Read<CGObjectManager>(new IntPtr(0x3657750), true);
> for(long i = WoWProcess.Read<long>(new IntPtr(objMgr.VisibleObjects.Next), false); i != objMgr.VisibleObjects.Next; i = WoWProcess.Read<long>(new IntPtr(i), false))
>                 {
>                     var entity_ptr = i - 0x28;
> ...


Thanks, I tried doing something like this, although I started with an object pointer. 

My idea was to find an NPC, find his object by searching for his health/mana/coordinates/etc., and then by going back along this linked list, to find the object manager.

I found the NPC object, everything seems to be in the right place (GUID, coordinates, etc.)

However, when I follow the list, it's not null-terminated or self-link-terminated. It's just a cyclic linked list, the last element points back to the first element. There seem to be some objects I'm not processing correctly (it looks like I'm only getting NPCs right), but I'm mostly curious about the cyclic linked list.

Any idea what I may have found? Or if I'm doing something wrong?

Here is my code:


```
void write_list(DWORD pid, uint64_t p) {
    HANDLE proc = OpenProcess(PROCESS_VM_READ | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION, FALSE, pid);

    auto first = p;
    while (p) {
        uint64_t next;
        ReadProcessMemory(proc, (char*)p, & next, 8, 0);
        string s = get_name(proc, p - 0x28);
        Coord c;
        ReadProcessMemory(proc, (char*)p + 0x650 - 0x28, &c, 12, 0);
        printf("Object at: %llx   name: %25s   coord: %8.2f %8.2f %8.2f\n",
            p - 0x28, s.c_str(), c.x, c.y, c.z);
        
        if (p == next) { cerr << "equal!"<<endl; break; }
        if (next == first) { cerr << "Loop!" << endl; break; }
        p = next;  
       
    }

    CloseHandle(proc);
}
```

Here is the output: 


```
Object at: 1fd2654c228   name:                     Burok   coord:   272.16 -4769.88    11.54
Object at: 1fd237be168   name:                             coord:    -0.00     0.00     0.55
Object at: 1fd2654e21c   name:                    Harruk   coord:   273.27 -4713.46    11.91
Object at: 1fd237be92c   name:                             coord:    -0.00     0.00    -1.00
Object at: 1fd237bf0f0   name:                             coord:    -0.00     0.00     0.51
Object at: 1fd26464118   name:                      Jark   coord:   321.55 -4838.40    10.52
Object at: 1fd2625606c   name:                     Rawrk   coord:   330.35 -4826.93    10.52
Object at: 1fd2645e13c   name:                    Egbert   coord:   332.03 -4702.34    17.25
Object at: 1fd26550210   name:              Grunt Kor'ja   coord:   170.60 -4769.92    14.48
Object at: 1fd265541f8   name:                     Cutac   coord:   367.88 -4770.91    12.47
Object at: 1fd26552204   name:          Razor Hill Grunt   coord:   368.94 -4761.18    12.20
Object at: 1fd320ec7cc   name:                             coord:    -0.00     0.00    -0.34
Object at: 1fd265561ec   name:        Darkspear Guardian   coord:   291.56 -4687.58    11.66
Object at: 1fd2656618c   name:          Razor Hill Grunt   coord:   293.74 -4685.52    11.65
Object at: 1fd265621a4   name:          Razor Hill Grunt   coord:   246.10 -4849.67    13.63
Object at: 1fd237bd9a4   name:                             coord:    -0.00     0.00     0.91
Object at: 1fcac4633f8   name:                             coord:     0.00     0.00     0.00
Object at: 1fd51dfe090   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd1d3181a0   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd1d318b14   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd1d319488   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd51dfec8c   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd1d319dfc   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd1d31a770   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd1d31b0e4   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd1d31ba58   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd1d31c3cc   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd1d31cd40   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd1d31d6b4   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd1d31e028   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd1d31e99c   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd1d31f310   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd51dff888   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd1d31fc84   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd1d3205f8   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd1d320f6c   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd1d3218e0   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd1d322254   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd51e0a0a0   name:                             coord:   269.41 -4766.24    11.48
Object at: 1fd51e00484   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd1d322bc8   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd1d32353c   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd1d323eb0   name:                             coord:    -0.00     0.00     0.00
Object at: 1fd262480c0   name:          Razor Hill Grunt   coord:   310.87 -4768.06     9.56
Object at: 1fd2624a0b4   name:                    Narzak   coord:   352.85 -4749.77    12.33
Object at: 1fd320e7a24   name:                             coord:    -0.00     0.00    -0.94
Object at: 1fd320e89ac   name:                             coord:    -0.00     0.00    -1.00
Object at: 1fd2624c0a8   name:                     Runda   coord:   329.04 -4762.35    12.56
Object at: 1fd320e9170   name:                             coord:    -0.00     0.00    -0.99
Object at: 1fd26250090   name:                    Ghrawt   coord:   362.10 -4763.84    12.47
Object at: 1fd26252084   name:             Gail Nozzywig   coord:   287.75 -4770.54    11.69
Object at: 1fd26258060   name:                    Shifty   coord:   352.77 -4751.50    12.60
Object at: 1fd2625a054   name:        Darkspear Guardian   coord:   250.17 -4735.30    10.10
Object at: 1fd2625e03c   name:                     Flakk   coord:   327.34 -4764.90    12.32
Object at: 1fd320e9934   name:                             coord:    -0.00     0.00     0.48
Object at: 1fd320ea8bc   name:                             coord:    -0.00     0.00    -0.44
Object at: 1fd320eb080   name:                             coord:    -0.00     0.00     0.49
Object at: 1fd26260030   name:          Razor Hill Grunt   coord:   319.10 -4812.88    10.52
Object at: 1fd320eb844   name:                             coord:    -0.00     0.00    -0.94
Object at: 1fd320ec008   name:                             coord:    -0.00     0.00    -0.89
Object at: 1fd26262024   name:          Razor Hill Grunt   coord:   215.76 -4715.79    15.60
Object at: 1fd26264018   name:          Razor Hill Grunt   coord:   243.62 -4742.10    10.10
Object at: 1fd2626600c   name:                   Tai'jin   coord:   294.88 -4831.49    10.52
Object at: 1fd264481c0   name:                  Gar'Thok   coord:   274.99 -4709.30    17.77
Object at: 1fd320ecf90   name:                             coord:    -0.00     0.00     0.15
Object at: 1fd2644c1a8   name:          Razor Hill Grunt   coord:   256.62 -4831.34    11.11
Object at: 1fd2644e19c   name:                     Swart   coord:   307.11 -4839.91    10.52
Object at: 1fd26450190   name:           Orgnil Soulscar   coord:   287.27 -4724.88    13.13
Object at: 1fd26452184   name:          Razor Hill Grunt   coord:   248.01 -4737.42    10.10
Object at: 1fd26454178   name:          Razor Hill Grunt   coord:   300.15 -4770.21     9.47
Object at: 1fd2645616c   name:                    Thotar   coord:   275.34 -4704.00    11.90
Object at: 1fd26458160   name:        Tarshaw Jaggedscar   coord:   311.35 -4827.79     9.58
Object at: 1fd2645a154   name:          Razor Hill Grunt   coord:   302.01 -4815.57    10.52
Object at: 1fd320ed754   name:                             coord:    -0.00     0.00    -0.70
Object at: 1fd320edf18   name:                             coord:    -0.00     0.00    -1.00
Object at: 1fd320ee6dc   name:                             coord:    -0.00     0.00     0.75
Object at: 1fd26460130   name:          Razor Hill Grunt   coord:   244.25 -4730.20    10.10
Object at: 1fd26462124   name:                    Kaplak   coord:   268.13 -4710.94    17.77
Object at: 1fd2646610c   name:                  Shoja'my   coord:   333.31 -4711.64    14.53
Object at: 1fd26548240   name:                     Jabul   coord:   342.06 -4771.40    12.63
Object at: 1fd2654a234   name:                  Un'Thuwa   coord:   334.72 -4767.62    12.64
Object at: 1fd237bd1e0   name:                             coord:    -0.00     0.00     0.05
Loop!
```

----------


## ChrisIsMe

> Thanks, I tried doing something like this, although I started with an object pointer. 
> 
> My idea was to find an NPC, find his object by searching for his health/mana/coordinates/etc., and then by going back along this linked list, to find the object manager.
> 
> I found the NPC object, everything seems to be in the right place (GUID, coordinates, etc.)
> 
> However, when I follow the list, it's not null-terminated or self-link-terminated. It's just a cyclic linked list, the last element points back to the first element. There seem to be some objects I'm not processing correctly (it looks like I'm only getting NPCs right), but I'm mostly curious about the cyclic linked list.
> 
> Any idea what I may have found? Or if I'm doing something wrong?
> ...


 while (((uintptr_t)first != 0) && (((uintptr_t)first & 1) == 0)) {

----------


## CaptainCode

> while (((uintptr_t)first != 0) && (((uintptr_t)first & 1) == 0)) {


What's the logic here?

First part, fine, typical : You go until you get a null pointer.

But "&1 == 0" just means an even number. What's this about stopping when you get an odd pointer? There were no odd pointers in my list above, anyhow.

----------


## ChrisIsMe

> What's the logic here?
> 
> First part, fine, typical : You go until you get a null pointer.
> 
> But "&1 == 0" just means an even number. What's this about stopping when you get an odd pointer? There were no odd pointers in my list above, anyhow.


Sorry I thought this was classic. 

Retail code in IDA checks `first against current` entry and breaks, since it is an infinite list.

----------


## CaptainCode

> Sorry I thought this was classic. 
> 
> Retail code in IDA checks `first against current` entry and breaks, since it is an infinite list.


Aha perfect, that makes sense, like I said it seems to be a circular list -- I was just confused because everyone else seemed to be assuming it was a normal linked list.

----------


## ChrisIsMe

> Aha perfect, that makes sense, like I said it seems to be a circular list -- I was just confused because everyone else seemed to be assuming it was a normal linked list.


It's because more than half the people here are posting offsets dumped from a public offset dumper and never actually open IDA to see how to do anything.  :Thumbsup:

----------


## H3XC0R3

> Thanks, I tried doing something like this, although I started with an object pointer. 
> 
> My idea was to find an NPC, find his object by searching for his health/mana/coordinates/etc., and then by going back along this linked list, to find the object manager.
> 
> I found the NPC object, everything seems to be in the right place (GUID, coordinates, etc.)
> 
> However, when I follow the list, it's not null-terminated or self-link-terminated. It's just a cyclic linked list, the last element points back to the first element. There seem to be some objects I'm not processing correctly (it looks like I'm only getting NPCs right), but I'm mostly curious about the cyclic linked list.
> 
> Any idea what I may have found? Or if I'm doing something wrong?
> ...


This is actually what you want to use here:


```
for (auto i = *(uintptr_t*)(m_CurObjectMgr->VisibleObjects.Next); i != m_CurObjectMgr->VisibleObjects.Next; i = *(uintptr_t*)(i))
{
	CGObject* wowObj = reinterpret_cast<CGObject*>(i - 0x18);
}
```

----------


## ChrisIsMe

> This is actually what you want to use here:
> 
> 
> ```
> for (auto i = *(uintptr_t*)(m_CurObjectMgr->VisibleObjects.Next); i != m_CurObjectMgr->VisibleObjects.Next; i = *(uintptr_t*)(i))
> {
> 	CGObject* wowObj = reinterpret_cast<CGObject*>(i - 0x18);
> }
> ```


Yes a while loop that checks the current object against the first object. 

Thank you for writing it in a more complicated way.  :Lll. .:

----------


## ChrisIsMe

In retail (probably TBCC too, I haven't looked because it's relatively useless (to me)...) there's also a count of active objects @ s_curMgr] + 0x10

But you can't reliably loop the objects with that amount, since they change too frequently.

----------


## ChrisIsMe

I know combat reach/bounding radius, I think the surrounding bit of the struct is 

Key: 
< == going backwards in struct from offset
> == going forward in struct from offset 
@ == size of variable

charm @ 0x10 bytes < 
summon @ 0x10 bytes < 
critter @ 0x10 bytes < 
charmedBy @ 0x10 bytes < 
summonedBy @ 0x10 bytes < 
createdBy @ 0x10 bytes < 
demonCreator @ 0x10 bytes < 
lookAtControllerTarget @ 0x10 bytes < 

0x1c38 TargetGUID start

target GUID @ 0x10 byes >
battlepetcompanionguid @10 bytes >
battlepetdbid @8 bytes

flags 1<
flags2 <

0x1cc4 Flags 3 start

flags 3 > 
aurastate > 
rangedattackbasetime > 
bounding radius >
combat reach > 
attack round base time @0x8 byte size >
display ID >
display scale >
native display ID (aka mount?) >
native display scale 

CGUnit_C descriptors at least. 

I'm not really interested in getting all of the information in the struct, I thought about trying but it seems like in retail there's a lot of different stuff going on, like power is always 0 and health is not actually the health shown in game (20 at level 1 === 622 in memory for example), it doesn't seem like a worth while time sink.

----------


## ejt

> In retail (probably TBCC too, I haven't looked because it's relatively useless (to me)...) there's also a count of active objects @ s_curMgr] + 0x10
> 
> But you can't reliably loop the objects with that amount, since they change too frequently.


You're thinking about the TSHashTable which is the first object inside the curmgr, its similar to classic from what I can remember and should be 0x50 in size. Directly after it comes another TSHashTable containing invalid objects, after that of course comes a bunch of TSList's or maybe TSLink, can't remember off the top of my head. Should be around 15 of them and lastly you have things like local guid, map id, movement globals, connection manager. 

I'm feeling generous today so here's the TSHashTable for classic, should be similar or identical to what retail uses, you figure it out.



```
// size = 0x50
template <typename T>
struct TSHashTable
{
	uintptr_t vtable;			// 0x00
	TSList<T> List;				// 0x08
	TSGrowableArray<T> Array;	// 0x20
	int32_t SlotMask;			// 0x38
	int32_t unk_03C;			// 0x3C
	int32_t unk_040;			// 0x40
	int32_t unk_044;			// 0x44
	int32_t key;				// 0x48
	int32_t unk_04C;			// 0x4C

	T* operator[](WowGuid guid)
	{
		auto k1 = 0xA2AA033B * static_cast<uint32_t>(guid.high & 0xFFFFFFFF);
		auto k2 = 0x292FE70B * static_cast<uint32_t>(guid.low & 0xFFFFFFFF);
		auto k3 = 0xA2AA033B * guid.high;
		auto k4 = 0xD6D018F5 * guid.low;

		uint32_t hash = static_cast<uint32_t>(k1 - k2 + ((k3 + k4) >> 32));
		auto index = hash % key;

		auto obj = (Array.Data + index)->object;
		while (!(reinterpret_cast<uintptr_t>(obj) & 1) && obj)
		{
			if (obj->GuidHash == hash)
				return obj;

			obj = obj->LastLink.Next;
		}

		return nullptr;
	}
};
```

Have not tested the hashing algorithm for tbcc but should not have changed since 1.13

----------


## ChrisIsMe

> You're thinking about the TSHashTable which is the first object inside the curmgr, its similar to classic from what I can remember and should be 0x50 in size. Directly after it comes another TSHashTable containing invalid objects, after that of course comes a bunch of TSList's or maybe TSLink, can't remember off the top of my head. Should be around 15 of them and lastly you have things like local guid, map id, movement globals, connection manager. 
> 
> I'm feeling generous today so here's the TSHashTable for classic, should be similar or identical to what retail uses, you figure it out.
> 
> 
> 
> ```
> // size = 0x50
> template <typename T>
> ...


It's relatively useless in Classic in my opinion, because there doesn't seem to be as many environmental triggers or 'hidden' objects that would benefit you as such in Retail. It can be quite valuable to visualize where certain types of 'trap doors' or such are, that will let you know when hidden ground destruction mechanics or things like that, will take place. 

This is basically a '0 day' share though, can't wait for the next public bot to feature thousands more objects than previous.  :O O: 

Good share, regardless.

// Edit; And no, the object count I'm referring to is not related to this hashlist. The hashlist count is usually like 2048 or 4096. 

The count I'm talking about is the actual size of the Linked List, but the list changes quite quickly.

Although the GUID hashing algorithm is the same as the name cache, so it should be simple for everyone to port the code and use. 

Alll of the GUID hash tables seem to be built around GitHub - jandrewrogers/MetroHash: MetroHash v1: Exceptionally fast and statistically robust hash functions or something very very similar.

----------


## ejt

> It's relatively useless in Classic in my opinion, because there doesn't seem to be as many environmental triggers or 'hidden' objects that would benefit you as such in Retail.


Hash tables are used to increase speed not get access to any "hidden" objects. All the objects in the active objects hash table also exist in the other lists. 

Looking up guid => object using the hash method is O(1) while using the linked-lists is O(n). This is why you use the hash table.




> This is basically a '0 day' share though, can't wait for the next public bot to feature thousands more objects than previous.


This is not a 0day share, they used this for a while now and is well known and reversed. Also as mentioned above, you don't get access to any "hidden" or extra objects by using the hash table.




> // Edit; And no, the object count I'm referring to is not related to this hashlist. The hashlist count is usually like 2048 or 4096. 
> 
> The count I'm talking about is the actual size of the Linked List, but the list changes quite quickly.


There are two storages in the hash tables, a linked-list and a dynamically allocated array. What you are mentioning here (2048 & 4096) is the number of allocated objects in the dynamic array.

When you say it changes quickly I think you mean the number of objects in the list and of course depending on if you're standing in a big city or a desert its going to be faster or slower adding/removing objects. If you're not syncing when reading objects it's inevitably going to end up with misses no matter which list or method you choose.

----------


## ChrisIsMe

> Hash tables are used to increase speed not get access to any "hidden" objects. All the objects in the active objects hash table also exist in the other lists. 
> 
> Looking up guid => object using the hash method is O(1) while using the linked-lists is O(n). This is why you use the hash table.
> 
> 
> 
> This is not a 0day share, they used this for a while now and is well known and reversed. Also as mentioned above, you don't get access to any "hidden" or extra objects by using the hash table.
> 
> 
> ...


If you're not seeing substantially more objects then this is something different than I am thinking of entirely. 

Without comparing your ObjectManager class/struct to mine, I couldn't tell you. 

 :Thumbsup:  

Now I've said too much

----------


## ejt

> Now I've said too much


Ignorance is bliss

----------

