MW2 Bot in C# - Teil 6

In den nächsten Tagen werde ich nicht zum posten kommen, daher hier noch ein kleiner Artikel. Es handelt sich um ein relativ simples, aber dennoch extremst cooles Feature. Der Bone-ESP!

Der Bone-ESP zeigt uns einfach jeden der 20 Knochen an. In diesem Gesamtbild ergibt sie die Entfernung, sowie die Positionierung (liegen, stehend) des Spielers. Dadurch können wir auf eine Box um den Spieler oder so einfach verzichten und das ganze sieht echt gut aus (wenn man es in Bewegung sieht :P )

Für den Bone-ESP sind im Grunde genommen “nur” drei Schritte nötig:

  • Wir registrieren jeden einzelnen Bone und speichern das “Handle” in Tag XXX
  • Wir fordern in jedem Frame über eine EngineFunktion die Position dieses Bones mit dem Tag XXX an.
  • Wir wenden für jeden Bone die WorldToScreen Funkion drauf an!

Das Registrieren erfolgt über C# Code, welcher schnell erklärt ist:

public delegate ushort RegisterTagDelegate(Byte[] BoneName); // Das Delegate
 
public static RegisterTagDelegate RegisterTagFunc; // Die Funktion aus dem Delegate
// Alle Bone-Tags
public static String[] arBoneNames = new String[] {"j_helmet"     , "j_head"            , "j_neck"
            , "j_shoulder_le", "j_shoulder_ri"  , "j_elbow_le"     , "j_elbow_ri", "j_wrist_le", "j_wrist_ri", "j_gun"
            , "j_mainroot"   , "j_spineupper"   , "j_spinelower" , "j_spine4"
            , "j_hip_ri"     , "j_hip_le"       , "j_knee_le"    , "j_knee_ri" , "j_ankle_ri", "j_ankle_le"};

Wir legen also ein Array von Tags an, welche im folgenden Schritt dann registriert werden. Dabei wird ein Array vom Type “Bone” gefüllt!

// Im Konstruktor
 
RegisteredBones = new Bone[20];
            for (int i = 0; i < RegisteredBones.Length; i++)
            {
                RegisteredBones[i] = new Bone();
                RegisteredBones[i].sBoneName = PlayerManager.arBoneNames[i];
                RegisteredBones[i].iBoneID = PlayerManager.RegisterTagFunc(Encoding.ASCII.GetBytes(PlayerManager.arBoneNames[i]));
            }

Die Namen sollten soweit selbsterklärend sein… ;-)

Das interessante ist nun die BonePosition zu holen. Und dieses geht nur über InlineASM in C++, da sonst der Stackpointer außer Kontrolle gerät…

Also übergeben wir der C++-Wrapper Funktion die registrierte BoneID, sowie einen Zeiger der aktuellen PlayerKlasse. Dabei wird ein weiterer Zeiger übergeben. In diesem Zeiger wird dann die aktuelle Bone Position reingeschrieben. Ziemlich cool, oder?

public delegate int GetTagPosDelegate(int iBoneTag, IntPtr PtrToEntityStruct, IntPtr PtrToResult);
 
public static GetTagPosDelegate GetTagPosFunc;
 
private static IntPtr FreeTagPosSpace;
 
// In Konstruktor
FreeTagPosSpace = Marshal.AllocHGlobal(12); // Der Zeiger braucht ja noch Platz, wo er hinzeigen kann ^^

Unsere Funktion sieht dann also so aus:

public static Vector3 GetTagPosWrapped(MW2Player Player, int iBoneID)
{
      PlayerManager.GetTagPosFunc(iBoneID, Player.Entity.pStructOffset, FreeTagPosSpace); // FreeTagPosSpace ist der Zeiger, in den das Resultat gespeichert wird
 
      return MemoryHelper.GetClassFromAddress(FreeTagPosSpace); // aus dem Zeiger wird wieder ein Vector3
}

Natürlich darf der C++-Code der entsprechenden Funktion auch nicht fehlen, da das Tutorial ja nicht nur total auf C# ausgelegt sein sollte…

	static int GetPlayerTag (unsigned short Tag, int centity, int original)
	{
		__asm
		{
			movzx edi, Tag // Unser Tag kommt in EDI
			push original // Der Return-Pointer kommt auf den Stack
			mov esi, centity // Der Zeiger zur Player-Klasse kommt in ESI
			mov eax, 0x570720; // Die eigentliche Funktion (bzw Einsprungspunkt der Teilfunktion) kommt in EAX
			call eax // EAX wird angesprungen
			add esp, 0x4 // Der Stack wird gefixxt
		}
	}

Nun wird dieses auf jeden Bone angewendet, das Resultat wird in WorldToScreen in Bildschrimkoordinaten umgewandelt und wir haben unseren Bone-ESP, welcher sich mit den Figuren mitbewegt.

Und zum Abschluss noch ein LOL: In COD 7 (Black Ops) wird genau das selbe Tag-Prinzip verwendet. Doch dort gibt es noch 2 neue Tags: j_ball_le und j_ball_ri, welche die Eier des Spielers repräsentieren. Kein Witz!

Greez Easy

6 people like this post.

Andere Artikel zu dieser Serie

  1. MW2 Bot in C# – Teil 9
  2. MW2 Bot in C# – Teil 8
  3. MW2 Bot in C# – Teil 7
  4. MW2 Bot in C# - Teil 6 (This post)
  5. MW2 Bot in C# - Teil 5
  6. MW2 Bot in C# - Teil 4
  7. MW2 Bot in C# - Teil 3
  8. MW2 Bot in C# - Was will er eigentlich?
  9. MW2 Bot in C# - Teil 2
  10. MW2 Bot in C# - Teil 1
  11. MW2 Bot in C# - Teil 0
    • Cinda
    • 5. Jul. 2011 9:36am

    I can agree with you but this is not always the case… another thing: what would people do if I won 1 million usd?

    • Keyuko
    • 6. Jul. 2011 12:42am

    Meine güte du hast es echt drauf, danke für die Tutorials :)

  1. 17. Jun. 2011
    TrackBack von: MW2 Bot in C# – Teil 6


acht + = 14