I'm happy to help, thanks
So, in the past it was possible to change the ammo damage of weapons or the damage factor of the nodes to a crazy high number to get one hit kill, but it got patched and i think there is server side checks for how fast you kill a player that gives you a client error.
I don't think there is a true OHK hack, but what you can do is changing the dimension of the head and nick hitbox of the player, that way if the head is large all your hits will hit the head, so now we need to find the data of the bones and change it, the way CF stores the data is to make a large array of Node struct (not an array of pointers unlike Weapon manager), we need to find the address of that array, as always CF loads the data from files so it has to reference the strings of the attributes inside the file which helps us do our static analysis and find the addresses and offset.
A bone has many attributes, one of them is "DamageFactor" if we search for that string we get:
Then we go to the only reference:
1-> The address for the Node array (Node manager) it's a Node[]
2-> Is the offset of DamageFactor (0x24) inside the Node.
So:
Code:
#define NODE_MANAGER 0x1515364
Another attribute of Node struct which is interesting is "Radius", if we look at references for that string:
We see something different, if you notice there is 3 offsets each one is 0x4 bytes larger than the other one, which means there is three values ( of types float ) in sequence which belong to "Radius" attribute, it's the x_radius then y_radius then z_radius (0x38, 0x3C and 0x40) it's a 3D vector.
One more thing we need is the size of Node struct because it's an array of Node struct (not an array of pointers), if we look at how CF assigns the value of "DamageFactor":
We see that the array start address is moved into eax then we offset eax by edi then add the offset of DamageFactor.
So we need to know by how much edi is added every loop, so if we go waaaaay down at the end of this function (sub) paying attention to edi we see in this section:
1-> edi is added by 0x9C ( the size of the Node struct )
2-> Then we loop again to load the next node.
If we create some sudo code to help us explain what happens:
Code:
// THIS IS SUDO CODE
// eax is the start of the array
DWORD eax = node_mgr_addr;
// edi is the offset (initialized to 0)
DWORD edi = 0;
// Loop over all nodes
while(haven_t_finished_yet)
{
// calculate the current node
DWORD current_node = eax + edi;
// Load DamageFactor attribute
*(float*)(current_node + 0x24) = LoadFloatAttribute("DamageFactor");
// Load other attributes.
...
// add 0x9C to edi
edi += 0x9C;
}
We now understand how this piece of code works, and know that the size of Node struct is 0x9C
Now we can use some basic method to change all Radius of the head hitbox, or we can reconstruct the Node struct.
This is the Node struct from my analysis:
Code:
struct Vector3
{
float x, y, z;
};
struct ColorRGBA
{
float r, g, b, a;
};
struct Node
{
char spacer01[4];
char name[0x20];
float damage_factor;
Vector3 relative_position;
float priority;
Vector3 dimension; // 0x38, 0x3C, 0x40
ColorRGBA object_color;
DWORD node_type; // 0x54
char spacer02[0x44];
};
sizeof Node is 0x9C (This is important)
So let's code our hack:
Code:
#define NODE_MANAGER 0x1515364
#define NODE_MANAGER_COUNT 0x636
// Calculate the address of the Nodes array
DWORD node = *(DWORD*)((DWORD)cshell_base + NODE_MANAGER);
// Cast it into a Node array.
Node* nodes = (Node*)node_mgr;
// Loop over all nodes
for (int i = 0; i < NODE_MANAGER_COUNT; i++)
{
// Check if it's a head ( the name contains head )
if (strstr(nodes[i].name, "Head") || strstr(nodes[i].name, "head"))
{
// Increase the dimensions of the head hitbox 10 times
nodes[i].dimension.x *= 10;
nodes[i].dimension.y *= 10;
nodes[i].dimension.z *= 10;
}
}
Note: that the modification to the hitboxes take effect when you join the game, basically you should edit the hitboxes before you join the game.
Another note: just like Weapon checks (client_error_28_3), there is check for hitboxes data, there is also a function GetNodeByIndex you can patch one call to that function to avoid client_error_28_5, i think you can try simulation without client_error_28_5
You don't have to check for game status, but you may need to bypass client_error_28_5.
You can figure out how i got NODE_MANAGER_COUNT, i will leave it as that because this post is getting too long.
As always, i'm happy to help