-
Context: i want to make videos with default (or at least constant) camera distance but people type -cam 2000, -cam 3000 etc and camera distance changes when watching replay
Problem: i can't find camera distance offset to manually set it
DotA has various anti hack measures and doesn't allow most tools which can do it.
ReplaySeeker with SimpleCamera works but it doesnt let me set the distance, only to zoom in/out with hotkeys.
I tried to adapt the code from SimpleCamera repository (https://github.com/StarveTheEgo/SimpleCamera/blob/master/CameraManager.cs) but it doesnt seem to work (tried to get offsets with private static void GetMemoryLocationsForReplayData(IProcessMemory pMemory, out int memPosition, out int memOther, out int memUnitPointer, out int memFog)
{
memPosition = 0;
memOther = 0;
memUnitPointer = 0;
memFog = 0;
for (int index = 0; index <= 12288; ++index)
{
pMemory.OpenProcess();
if (memOther == 0)
{
int num0 = (index << 16);
if (pMemory.ReadProcessInt32(num0 + 736) == 1080) // 736
{
memOther = num0;
memPosition = pMemory.ReadProcessInt32(num0 + 1868) & -65536;
// System.Diagnostics.Debug.WriteLine("memOther memPosition 0");
}
int num1 = (index << 16) + 9472;// 9472;
if (pMemory.ReadProcessInt32(num1 + 832 + 44) == 1080)
{
memOther = num1;
memPosition = pMemory.ReadProcessInt32(num1 + 1868) & -65536;
//System.Diagnostics.Debug.WriteLine("memOther memPosition 1");
}
int num2 = index << 16;
if (pMemory.ReadProcessInt32(num2 + 832 + 44) == 1080)
{
memOther = num2;
memPosition = pMemory.ReadProcessInt32(num2 + 1868) & -65536;
// System.Diagnostics.Debug.WriteLine("memOther memPosition 2");
}
int num3 = (index << 16) + 9536;
if (pMemory.ReadProcessInt32(num3 + 832 + 44) == 1148)
{
memOther = num3;
memPosition = pMemory.ReadProcessInt32(num3 + 1868) & -65536;
// System.Diagnostics.Debug.WriteLine("memOther memPosition 3");
}
}
if (memUnitPointer == 0)
{
int num = index << 16;
if (pMemory.ReadProcessInt32(num + 164) == 1767994469)
{
memUnitPointer = num + 476;
// System.Diagnostics.Debug.WriteLine("memUnit");
}
}
if (memFog == 0)
{
int num = index << 16;
if (pMemory.ReadProcessInt32(num + 108) == 1196377672)
{
memFog = num;
// System.Diagnostics.Debug.WriteLine("memFog");
}
}
}
try
{
pMemory.CloseHandle();
}
catch
{
int num = (int) MessageBox.Show("Error in memory handler!");
}
}
and
public float distance
{
get
{
return this.pMemory.ReadFloat32(this.memoryBlockOther + 832);
}
set
{
this.pMemory.WriteFloat32(this.memoryBlockOther + 832, value);
}
}
by copy-pasting and adjusting the code to execute it in a standalone program. The loop in GetMemoryLocationsForReplayData basically runs through and never reads the expected values. Its full of magic numbers, so i dont fully understand which offsets and why its checking, apparently searching for the camera object. The offsets there are added to the game.dll base address in my code)
What i need is either the static offset from Game.dll (if exists), advice on how to adapt the mentioned code better or any other working method. Any help would be greatly appreciated.
@AntlermanXXL
-
Game.dll module address is dynamic (even if it can persist for years, it is still dynamic), so you gotta always get current base address of this module in runtime;
For example, w3loader tries to find base address using this function:
https://github.com/w3lh/w3l/blob/d4b0bf403891c6528024e0375c81c2d6d6652f0a/exe/w3l.c#L299
-
Magic numbers are from original ReplaySeeker / SimpleCamera code by the way
Also some offsets in SimpleCamera are not alright, you might have to re-discover those yourself, in case they still will not work
-
I mean static offset off game.dll implying i can get the address of game.dll itself already.
Now that you mention it maybe the code in simplecamera is wrong and this is why it doesnt work. Is the code in the repository not the same as the one the original dll was compiled from? Because as i said the plugin inside replayseeker works fine
-
I mean static offset off game.dll implying i can get the address of game.dll itself already.
Then i have zero idea what is meant by static offset of game.dll here, aren`t you messing up with terms?
Now that you mention it maybe the code in simplecamera is wrong and this is why it doesnt work. Is the code in the repository not the same as the one the original dll was compiled from? Because as i said the plugin inside replayseeker works fine
Yesh, there is an old version of SimpleCamera plugin in my repository, but not newer one
NOTE: This plugin is deprecated, i will upload improved version soon (fixed, based on SimpleCamera V2 Beta)
Well, 'soon' did not happen since no one wanted it, including me :-D
You can find dll of v2-beta plugin (which is not perfect too, but way more cool) and decompile it yourself
-
I am not into digging all this stuff about Warcraft once again, since i am not playing it
Here is also my camhack removal code in w3loader, just in case:
// Distance camhack remover
/*
33D2 xor edx,edx
8D4A 01 lea ecx,dword ptr ds:[edx+1]
E8 *56BEF4FF call <game.sub_2460710>
8BC8 mov ecx,eax
E8 *0F16F4FF call <game.sub_2455ED0>
8B4C24 0C mov ecx,dword ptr ss:[esp+C]
D901 fld st(0),dword ptr ds:[ecx]
8B5424 08 mov edx,dword ptr ss:[esp+8]
8B4C24 04 mov ecx,dword ptr ss:[esp+4]
6A 01 push 1
83EC 08 sub esp,8
D95C24 04 fstp dword ptr ss:[esp+4],st(0)
D902 fld st(0),dword ptr ds:[edx]
D91C24 fstp dword ptr ss:[esp],st(0)
51 push ecx
8BC8 mov ecx,eax
E8 *7B11F5FF call game.2465A60
C3 ret
*/
char camhack_remove_sig_data[] = {
0xff, 0x33, 0xff, 0xD2, 0xff, 0x8D, 0xff, 0x4A, 0xff, 0x01,
0xff, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x8B, 0xff, 0xC8, 0xff, 0xE8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x8B, 0xff, 0x4C, 0xff, 0x24,
0xff, 0x0C, 0xff, 0xD9, 0xff, 0x01, 0xff, 0x8B, 0xff, 0x54,
0xff, 0x24, 0xff, 0x08, 0xff, 0x8B, 0xff, 0x4C, 0xff, 0x24,
0xff, 0x04, 0xff, 0x6A, 0xff, 0x01, 0xff, 0x83, 0xff, 0xEC,
0xff, 0x08, 0xff, 0xD9, 0xff, 0x5C, 0xff, 0x24, 0xff, 0x04,
0xff, 0xD9, 0xff, 0x02, 0xff, 0xD9, 0xff, 0x1C, 0xff, 0x24,
0xff, 0x51, 0xff, 0x8B, 0xff, 0xC8, 0xff, 0xE8, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xC3
};
t_sig camhack_remove_limit_sig = {
54,
camhack_remove_sig_data,
0,
"camHackRemove"
};
char camhack_remove_patch_data[] = {
0xC3, 0x90
};
t_patch camhack_remove_patch = {
2,
camhack_remove_patch_data,
"camHackRemove",
FALSE
};
Some rough memory patch that removes affection of -cam command
---
Also, even simpler, you can use CheatEngine or similar, find there offset of camera distance and just freeze it to desired value
-
Well, static in the sense that its always same on every launch. I did some exploring with cheat engine and the distance is basically stored on a dynamic address which is stored in some structure which address is based on value of some registers, so i couldnt get track of any static offset to find the distance. Maybe i just dont have enough experience to evaluate the register values, seems like a lot of work. Or maybe i made some mistake because there were actually many places where the needed value/pointer to that value can be stored but the only actually working 1 was the one i mentioned.
You can find dll of v2-beta plugin (which is not perfect too, but way more cool) and decompile it yourself
Good idea, need to try, weird that i didnt think of that (guess because i assumed the repository code is the same but you said its not)
Also, even simpler, you can use CheatEngine or similar, find there offset of camera distance and just freeze it to desired value
This was the first thing i tried. Dota doesnt like cheat engine and keeps crashing, also its hard to find the value inside replay + its really annoying to do all this every time
-
irrelevant
-
The address is dynamic but the offset off that address can be static (like fog offset in maphacks) or dynamic (stored somewhere which seems to be the case)
-
I see what you want, but i did not invest time into finding static offset of Camera structure
Yet, i found lots of cool structures myself while doing Lobby stats feature, so have experience about this
-
https://github.com/hackerlank/dreamdota
Here you can dig whole bank of game.dll knowledge, those guys went crazy into finding structures and offsets
Not sure if there is whole camera structure, but i believe their source code is extremely helpful
-
https://github.com/hackerlank/dreamdota/blob/master/DreamWarcraft/UIStructs.h#L58
Like, here is Camera structure without lots of fields, but it most likely has your desired distance field
It will require some work to find static offset of Camera structure anyway
Either you finish their work there (is not really hard, btw), recognize and uncomment CCamera properties; Then just access global UI object and get camera from there
Either find this Camera structure yourself
Either google it somehow
-
Here are offsets for global UI btw:
https://github.com/hackerlank/dreamdota/blob/master/DreamWarcraft/Offsets.cpp#L989
2nd argument (int value) is version code of Game.dll file
1.26a is probably 6401 afaik, but you better ensure yourself
3rd argument is a static offset from Game.dll
From there you can find way to access your desired value: UI->CCameraWar3->CCamera->distance
-
I will check it out thanks a lot!
Either google it somehow
If it was so easy i wouldnt ask in the first place
-
So, there are 2 camera distance variables.
1. Is the one you can track from dreamdota offsets
GLOBAL_UI (Game.dll + 0xAB4F80) -> CCameraWar3 (*GLOBAL_UI + 0x254) -> CCamera (*CCameraWar3+0x34) -> Distance float (*CCamera + 0x8C)
It shows the actual value of camera distance but changing it doesn't do anything. Upon changing it in Cheat Engine it changes itself back with no effect (if you freeze it its same). Basically its read only value.
2. Is the actual camera value which is updated through player structure i was talking about before (according to debugging when you type -cam in dota, for example, basically when you change it with triggers). When you change it in Cheat Engine it changes the camera distance in game.
See screenshot for clarity
When i took apart 1 .mix based maphack it used a static offset which was pointing to the 1 variable as well. However adjusting distance using that tool works while changing it at the same offset manually doesn't which really puzzles me.
-
Does //0x40 CCamera exist and have distance too?
-
Does //0x40 CCamera exist and have distance too?
It points to the same address as 0x34
-
It seems that the camera object is created during loading, so i can just track the value with Cheat Engine. Guess will have to use this method