-
Member
Originally Posted by
Aigewen
Hi Razzue, How to read other players' names? I read other threads and you mentioned it should be read in the name cache. Is it the address [Base + Object_Manager.Names]. I read this address and find it is a pointer to other pointers but I can't find any names.
I'm also interested in this question, I think it has something to do with the GUID
this is how it was done on 3,3,5
Code:
char* PlayerObject::GetName()
{
char* Wname[12];
unsigned long mask, base_, offset, current, shortGUID, testGUID;
mask = WowMemory->ReadUint(nameStore + nameMask);
base_ = WowMemory->ReadUint(nameStore + nameBase);
shortGUID = this->GetGuid() & 0xffffffff;
offset = 12 * (mask & shortGUID);
current = WowMemory->ReadUint(base_ + offset + 8);
offset = WowMemory->ReadUint(base_ + offset);
if ((current & 0x1) == 0x1) { return "error1"; }
testGUID = WowMemory->ReadUint(current);
while (testGUID != shortGUID)
{
current = WowMemory->ReadUint(current + offset + 4);
if ((current & 0x1) == 0x1) { return "error1"; }
testGUID = WowMemory->ReadUint(current);
}
return encode(WowMemory->ReadCStr(current + nameString,12),12);
}
I think it's something like this too
I would like to understand how to do this in the current version
-
Contributor
Avid Ailurophile
-
Member
Thanks I found the compiled version, I will test it, everything turned out to be much easier than I expected, thanks a lot
-
Active Member
@Razzue, thanks for the continuous post of the offsets!
@Hrap Just FYI, I'm using a tough way to do this(under c#), Really do not suggest creating a thread for every name call. I believe there is an easier way to do this, but as I just started, I will leave it as this for now until some bro tells me a better way.
//replace 0xCC with address of the allocated memory cave
byte[] asm =
{
0x49, 0xC7, 0xC1, 0x00, 0x00, 0x00, 0x00, //"mov r9, 0x0"
0x49, 0xC7, 0xC0, 0x01, 0x00, 0x00, 0x00, //"mov r8, 0x01"
0x48, 0xC7, 0xC2, 0x04, 0x00, 0x00, 0x00, //mov rdx, 0x04
0x48, 0xB9, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, //mov rcx, objptr
0x48, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, //mov rax, ((ulong)BaseAddress + (ulong) namecall address //first dword after this one 48 8D 54 24 68 45 33 C9 ?? 89 ?? 24 68 44 8B C0 48 8B CE E8
0x48, 0x83, 0xEC, 0x28, //sub rsp, 0x28
0xFF, 0xD0, //call rax
0x48, 0x83, 0xC4, 0x28, //add rsp, 0x28
0x48, 0xA3, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, //mov [0xcccccccccccccccc], rax //get return value
0xC3 //ret
};
Last edited by tommingc; 11-04-2022 at 04:08 AM.
-
Contributor
Avid Ailurophile
Originally Posted by
tommingc
~~
Originally Posted by
Aigewen
~~
Originally Posted by
Hrap
~~
Code:
public ConcurrentDictionary<GUID, string> _playerNames = new();
public string PlayerName(GUID input)
=> _playerNames.TryGetValue(input, out var value) ? value : "Unknown";
public async Task UpdateNames()
{
await Task.Factory.StartNew(() =>
{
var address = Game.Address + Offset;
var maximum = Memory.Read<int>(address + 0x38);
var pointerArray = Memory.ReadArray<IntPtr>(Memory.Read<IntPtr>(address + 0x10), maximum);
if (pointerArray is { Length: <= 0 }) return;
for (var i = 0; i < pointerArray.Length; i++)
{
var pointer = pointerArray[i];
do
{
var guid = Memory.Read<GUID>(pointer + 0x8);
var name = Memory.ReadString(pointer + 0x19, null, 20);
if (!guid.IsEmpty() && !string.IsNullOrEmpty(name))
_playerNames.AddOrUpdate(guid, name, (k, v) => v = name);
pointer = Memory.Read<IntPtr>(pointer + 0x0);
} while (pointer.ToInt64() != 0);
}
});
}
Last edited by Razzue; 11-04-2022 at 09:05 AM.
"May all your bacon burn"
-
Post Thanks / Like - 1 Thanks
tommingc (1 members gave Thanks to Razzue for this useful post)
-
Member
Originally Posted by
Razzue
Code:
public ConcurrentDictionary<GUID, string> _playerNames = new();
public string PlayerName(GUID input)
=> _playerNames.TryGetValue(input, out var value) ? value : "Unknown";
public async Task UpdateNames()
{
await Task.Factory.StartNew(() =>
{
var address = GameOverlay.Address + Offset;
var maximum = Memory.Read<int>(address + 0x38);
var pointerArray = Memory.ReadArray<IntPtr>(Memory.Read<IntPtr>(address + 0x10), maximum);
if (pointerArray is { Length: <= 0 }) return;
for (var i = 0; i < pointerArray.Length; i++)
{
var pointer = pointerArray[i];
do
{
var guid = Memory.Read<GUID>(pointer + 0x8);
var name = Memory.ReadString(pointer + 0x19, null, 20);
if (!guid.IsEmpty() && !string.IsNullOrEmpty(name))
_playerNames.AddOrUpdate(guid, name, (k, v) => v = name);
pointer = Memory.Read<IntPtr>(pointer + 0x0);
} while (pointer.ToInt64() != 0);
}
});
}
Fantastic!! Thanks, Razzue.
-
Member
-
Member
Greetings, Razzue
Such a question, what are the possible options for clicking on an object?
For example, while fishing, in what way is it possible to click on the float
Perhaps you, as a more experienced one, have already encountered this
-
Member
I believe it can be calculated.
Let's say I know the position and tilt of the camera and the position of the float object, I think, given the perspective, it is possible to calculate which point on the screen to click to get into the game on the float
But it's quite difficult, it seems to me, maybe there is an easier way, because the game calculates all this?
-
Member
Originally Posted by
Hrap
I believe it can be calculated.
Let's say I know the position and tilt of the camera and the position of the float object, I think, given the perspective, it is possible to calculate which point on the screen to click to get into the game on the float
But it's quite difficult, it seems to me, maybe there is an easier way, because the game calculates all this?
Just use OpenGL or DirectX WorldToScreen, you can easily find how to do it in google.
here's how i do it with dx
Code:
var proj = Matrix.PerspectiveFovRH(Fov * 0.6f, aspect, nearClip, farClip);
var eye = new SharpDX.Vector3(cameraPos.X, cameraPos.Y, cameraPos.Z);
var lookAt = new SharpDX.Vector3(cameraPos.X + m[0, 0], cameraPos.Y + m[0, 1], cameraPos.Z + m[0, 2]);
var up = new SharpDX.Vector3(0f, 0f, 1f);
var View = Matrix.LookAtRH(eye, lookAt, up);
var inPos = new SharpDX.Vector3(pos.X, pos.Y, pos.Z);
var outValue = SharpDX.Vector3.Project(inPos, bounds.X, bounds.Y, bounds.Width, bounds.Height,
nearClip, farClip, Matrix.Identity * View * proj);
if (!bounds.Contains((int)outValue.X, (int)outValue.Y))
{
return System.Numerics.Vector2.Zero;
}
return new System.Numerics.Vector2(outValue.X, outValue.Y);
-
Member
Originally Posted by
tayl
Just use OpenGL or DirectX WorldToScreen, you can easily find how to do it in google.
here's how i do it with dx
Code:
var proj = Matrix.PerspectiveFovRH(Fov * 0.6f, aspect, nearClip, farClip);
var eye = new SharpDX.Vector3(cameraPos.X, cameraPos.Y, cameraPos.Z);
var lookAt = new SharpDX.Vector3(cameraPos.X + m[0, 0], cameraPos.Y + m[0, 1], cameraPos.Z + m[0, 2]);
var up = new SharpDX.Vector3(0f, 0f, 1f);
var View = Matrix.LookAtRH(eye, lookAt, up);
var inPos = new SharpDX.Vector3(pos.X, pos.Y, pos.Z);
var outValue = SharpDX.Vector3.Project(inPos, bounds.X, bounds.Y, bounds.Width, bounds.Height,
nearClip, farClip, Matrix.Identity * View * proj);
if (!bounds.Contains((int)outValue.X, (int)outValue.Y))
{
return System.Numerics.Vector2.Zero;
}
return new System.Numerics.Vector2(outValue.X, outValue.Y);
Thanks,
Will this work from external applications without intercepting Directx functions?
-
Contributor
Avid Ailurophile
-
Member
As an option)
But a couple of questions arise
How safe it is to write to the game's memory.
And is there a game memory protection against such actions?
Last edited by Hrap; 11-12-2022 at 07:26 AM.
-
Active Member
or you can also createremotethread to do the interact action, but it still requires writeprocessmemory..
-
Member
the fact is that I want to avoid writing to the process memory as much as possible
Previously, for the exact rotation of the player, I recorded the angle of rotation I needed in Player.position.rotation
and this once led to a ban (though on a private server)
now I do everything by sending keystrokes.
It's not as accurate, but it works.