Ich habe grade tierisch langeweile, und hab mein altes WoW Projekt auf der Festplatte gefunden - ein Bot den ich vor ner ganzen Weile anfing selbst zu entwickeln. Da ich ihn aber nie fertiggestellt hatte mangels Zeit & Wichtigerem dachte ich mir "Gibst halt zumindestens dein erarbeitetes Wissen etwas weiter".
Fangen wir also an..
Worum geht es?
Das entwickeln eines Bots der für uns mit einem Waypoint System eine Route abläuft, und dort dann Erze abbaut, und Monster die ihm gefährlich werden bekämpft. Alles ziemlich Simpel gehalten, und verbuggt - aber es dient ja den Lernzwecken.. grins
Zunächst schauen uns wir einmal die Konzept Skizzen an:
Die erste Idee
Das ganze in ner GUI verpackt und bisschen verändert..
Nun, wie ich schon sagte wird unser Bot lediglich Stupide eine Waypoint Route ablaufen - jedoch bekommt der Bot noch zusätzlich einen Walkbot spendiert der uns von Punkt A zu Punkt B bringen kann (Wenn wir zu Faul sind um von SW zum MOP Portal zu fliegen zb).
Nun fangen wir mal an.. was braucht man um einen Bot zu entwickeln?
- Der Bot muss irgendwie sich bewegen können. Wir müssen in der Lage sein ihn in der 3D Spielwelt von Punkt A nach B zu bringen.
Welche Möglichkeiten bieten sich uns hier?
Nun da wäre zum einen das Simulieren von Tastenschlägen (W,A,S,D,Space).. aber das ist enorm auffällig, jeder Spieler der unseren Bot sehen würde, würde direkt verdacht schöpfen bei diesem Verhaltensmuster.
Zusätzlich ist es ziemlich schwer das ganze gut genug zu Organisieren weil man die Laufstrecken schlecht bemessen kann damit man Schlussendlich auch steht wo man stehen möchte.
Dann gibts noch die lustige Funktion die wir Click-To-Move nennen.
Wenn diese Funktion aktiviert ist, bewegt sich unser Spielcharakter an den Ort wohin wir mit der Rechten Maustaste geklickt haben. Dieses Verhalten ist wesentlich unauffälliger wenn man entsprechend gute Unstuck-Funktionen sowie Stuckfreie Profile zur Verfügung hat.
Doch wie nutzen wir nun diese Funktion ohne Tasten-Simulation?
Zunächst einmal muss man wissen wie die Funktion im Hintergrund funktioniert!
Wenn wir die mit aktivierter Funktion irgendwohin klicken, werden genau 4 Werte an die CTM Funktion übergeben. Und zwar..
- X, Y sowie Z Achse des Mausklicks in der Spielwelt
Dies ist unsere Ziel-Koordinate wo sich der Spielcharakter hinbewegen soll.
- CTM_ACTION
Dies ist ein Wert der verschiedene Zahlen beeinhalten kann, und dieser Wert ist abhängig davon wohin wir klicken.
Code:
const static int CTM_WALK = 4; //Move to Coord const static int CTM_WALK2 = 8; //Walk without a Coord const static int CTM_STOP = 6; //Anhalten, Alternative Code 9 fürs Stoppen const static int CTM_IDLE = 13; //Nichts zu tun? Idle..
Man sieht hier -> Wenn man mit der Maustaste auf einen erreichbaren Ort klickt, wird der Wert 4 übergeben. Wenn man jedoch auf einen Unendlich Weiten, nicht direkt anklickbaren Ort (beispielsweise den Himmel) klickt, wird der Wert 8 übergeben. Der Wert 8 bedeutet sogesehen "Laufe solange bis ich dir etwas anderes sage". Ist gerade kein Lauf-Befehl im Gange, steht an der entsprechenden Speicherstelle einfach eine 13 - was soviel heißt wie "Ich hab grade nichts zu tun", IDLE eben. Die Zahl 6 stoppt den aktuell im Gange stehenden Befehl und der Charakter bleibt stehen.
Wir wissen nun also schon wie wir unsere Click-To-Move Funktion ansteuern müssen - das geht ganz einfach - jedoch fehlt uns noch eine entscheidende Sache! Nämlich die Funktion der wir die Daten übergebe müssen..oder nicht? ein.. die Funktion holt sich die Daten selbst ! Die Funktion ist nämlich keine normale Funktion die wir hooken müssen. Wir müssen einfach nur die richtigen Werte im Prozess schreiben.
Es reicht einfach unsere Zielkoordinaten (X,Y,Z) an die richtige Stelle im WoW Prozess zu schreiben, und anschließend CTM_ACTION auf den Wert 4 zu setzen. Sofort flitzt unser Spielcharakter flink zur gewünschten Koordinate Vorraussetzung ist natürlich das nichts im Weg ist.. aber hierfür gibt es ja unser Waypoint System, womit wir uns als nächstes beschäftigen.
Über das Reversen der entsprechenden Speicherstellen + Offsets werde ich nicht eingehen (im ganzen HowTo), da dies im jeden Patch andere Offsets und Speicherstellen sind - wenn ihr einen Bot entwickeln möchtet solltet ihr in der Lage sein sowas selbst zu lernen.
- Der Bot muss irgendwie Laufwege besitzen - nur zu einer einzigen Stelle latschen ist nicht grade Hilfreich
Wir benötigen also ein System, um unserem Bot Laufwege beizubringen.
Es gibt hierfür verschiedene Wege - manche Bots nutzen Mesh Navigationen, aber wir nutzen die Noob Variante..
Das Waypoint System.
Nun, was ist ein Waypoint System?
Das ist ganz einfach Erklärt!
Wir definieren Orte in einem 3D System durch 3 Achsen - X,Y und Z Achse.
Wollen wir nun von einem Ort zu einem anderem laufen, und ein Hinderniss umgehen, müssen wir zunächst
eine andere Koordinate im 3D Raum ansteuern, von der wir dann zur eigendlichen Ziel Koordinate gehen.
Man kann also sagen das ein Waypoint System auf einer Liste von verschiedenen (nah beieinander liegenden) Koordinaten besteht, die vom Bot einzelnd der Reihe nach abgelaufen werden.
Zur Verdeutlichung ein Bild:
Nun, wie setzen wir dies um? Ganz einfach - wir basteln uns hierfür 2 Programmteile.
1) Ein Programm was uns Profile erstellen kann, in denen Waypoints gespeichert werden.
2) Ein Programm was unsere Profile auslesen kann, und dem Bot dann die Koordinaten zur verfügung stellt damit er sie ablaufen kann.
Punkt 1. ist ziemlich leicht - wir müssen nur mit einem Debugger rausfinden wo die aktuelle X,Y und Z Achse unseres Charakters im WoW Prozess gespeichert wird. Dann bestimmen wir ein Intervall in dem die Koordinaten ausgelesen werden, und speichern die jeweilige Koordinate dann in eine Ini Datei. Den aufbau dieser Ini Datei überlasse ich jedem selbst, meine sah so aus:
Code:
[Walkbot Gatherprofile] [Waypoint1] X=49.755291 Y=1.164894 Z=-16.689102 [Waypoint2] X=51.223572 Y=1.201463 Z=-16.707321 [Waypoint3] X=53.824524 Y=1.325729 Z=-17.647299 [...]
Und den 2. Teil bekommt denke ich jeder selbst hin und bedarf keiner Erklärung. Hier muss nur die Ini Datei ausgelesen werden, und die Koordinaten dann anschließend an die ClickToMove Funktion übergeben werden.
Man könnte i das Profil noch den Interval eintragen, da es hier erhebliche Unterschiede in der Präzision eines Waypoint-Profiles gibt , jenachdem ob man Geht, Läuft, Schwimmt oder Fliegt (zusätzlich Reise-Tempo des Mounts).
Geht man langsam, kann man ein größeren Interval nehmen, fliegt man jedoch brauch es einen kleineren + mehr Waypoints (= größerer Speicherverbrauch). Sollte man immer im Hinterkopf behalten das ganze!
So, wenn wir alles richtig gemacht haben sollte nun unser Bot erfolgreich durch die Gegend marschieren können ohne das wir die irgendwas hinzu tun Unsere Walkbot Funktion ist also schon einmal fertig - die entsprechenden Profile muss man natürlich dann selbst aufnehmen und das möglichst Bugfrei und dem richtigem Interval.
Doch halt.. da war noch etwas! Unser Bot soll ja auch noch Kräuter und Erze einsammeln..Hmm.. Wie erledigen wir dies am besten? Wie können wir unserem Bot Symbolisch gesehen Wahrnehmungssinne verpassen, so das der Bot weiß wo die ganzen Rohstoffe sind...?
Nun, World of Warcraft hat im Prozess eine Art "Liste" von Objekten in der Nähe des Spielcharakters. Wir können nun diese Liste durchgehen, und finden dort Monster, andere Spieler, benutzbare Objekte wie Stühle, Türen, und natürlich auch Rohstoffe die wir abbauen können.
Dieses Vorgehen, btw die Liste nennt sich im allgemeinen Sprachgebrauch "Objektmanager". Einfach gesagt ist es einfach eine Start-Stelle im Speicher die auf eine weitere Stelle zeigt mit dem nächsten Objekt, und von diesem Objekt können wir uns wieder zum nächsten hangeln.
Euch nun zu Erklären wie man den Objektmanager nutzt ginge zu weit, hierfür gibt es schon genug Erklärungen im Netz. Das ganze würde hier nur diesen Thread sprengen an Informationen.
Gehen wir weiter darauf ein was wir tun müssen damit unser Bot nun weiß "Wohin soll ich gehen?". Also, wir haben den Objektmanager, und können hier jedes in der Nähe befindliche Objekt durchgehen.. was tun wir also?
Genau! Wir parsen unsere Liste an Objekten nach Rohstoffen die uns interessieren, und lesen dann von ihnen die entsprechende 3D Koordinate (X,Y,Z) aus. Diese steuern wir nun an, sofern sie in einem bestimmten Radius um unserem Waypoint - Weg liegt. Andernfalls ignorieren wir den Rohstoff - wieso? Weil es sonst dazu führen kann das sich unser Charakter ganz böse feststuckt wenn wir zurücklaufen.. das hat das Waypoint System leider an sich. Es erfüllt aber den Grundlegenden Lerneffekt denke ich ganz gut.
So, nun kann unser Bot also schon einmal Rohstoffe auffinden, und ansteuern.. wenn da nur nicht diese Bösen Monster wären die uns angreifen könnten !..
Ja.. was tun wir denn dagegen..? Ihr habt es erraten - wir kämpfen!
Erinnern wir uns noch einmal an unseren Objekt Manager.. Dort ist eine Liste aller Objekte in der Nähe. Somit auch alle Monster, NPC und Neutralen Mobs.
Wenn wir nun also "sehen" das dort ein Böses Monster in der Nähe unseres Charakters ist, visieren wir es an und greifen an.
Im normalfall würde ich euch jetzt ein komplexes Kampfsystem erklären können, aber das wäre der totale Overkill für dieses Howto.. deshalb reisse ich es nur Grob an, und erkläre euch danach die leichtere Methode
Kämpfen :
1) Gegner auffinden (Objekt Manager - Neutraler oder Agressiver Mob?Agressiv? Weiter mit Punkt 2)
2) In Nähe laufen vom Gegner
3) Anhand eines Komplexen Kampfsystem das unsere Cooldowns, Zauber, Charakterklasse und Rasse im Auge hat kämpfen. Hier könnten wir uns eine eigene Charakter-Kampf Klasse basteln die verschiedene Verhalten an den Tag legt, und anhand bestimmten Situationen reagiert.
Beispielsweise .. Stunned? -> Fähigkeit auslösen um aus Stun zu entkommen.
Wir sollten diese Charakter-Kampf Klasse aber nicht Hardcoden, sondern extern in einer Datei lagern.
So können wir daran Änderungen vornehmen ohne ständig den ganzen Bot neu zu kompilieren.
Und sollten andere Leute unseren Bot nutzen wolle (unwahrscheinlich so buggy und noobig wie er ist), dan können diese die Kampfklasse anpassen und einsehen ohne den ganzen Sourcecode eures Bot zu benötigen.
4) Solange Fähigkeiten einsetzen bis die Lebenspunkte des Gegners auf 0 fallen (Stichwort Objektmanger..Lebenspunkte usw steht dort alles drin).
So, das war die ganz knappe umreissung eines Systems das man nutzen könnte. Wesentlich einfacher ist es wenn man in der Nähe eines Agressiven Mobs ist einfach einmal die Tab-Taste (alternativ die Funktion direkt per Write Memory) zu betätigen lassen, und dann wild die Tasten 1 bis 4 durchhämmern lassen. Wenn man das ganze dann Möglichst effizient und schön machen möchte, hooked man die LUA Schnittstelle und führt die Befehle (Zaubern zb) per Lua aus.
Beispielsweise steht einem hier der Befehl
Code:
CastSpellById();
Hat man ein Klassen-System kann man für jede Klasse die wichtigsten Id´s darin speichern, die beste Methode wäre aber man liest sie einfach aus dem Prozess - was aber gute Reversing Kenntnisse benötigt.
Wenn wir uns nun unseren Weg zu unserem Heiß begehrtem Rohstoff Mühsam erkämpft haben, wollen wir es natürlich auch abbauen.. doch wie machen wir sowas?
Ihr habt es erfasst.. mit Interact With Objekt, genau die Funktion die auch ausgelöst würde wenn wir das ganze mit der Rechten Maustaste auslösen würden. Es steht einem Frei ob man das ganze löst indem man das ganze per LUA Code macht, oder per Hooks. Das ist eure entscheidung
So, fassten wir nochmal alles zusammen..
Unser Bot kann umher laufen, Rohstoffe erkennen und aufsammeln, Gegner Noobhaft bekämpfen, und besitz eine einfache Version von Profilen die wir nutzen können um bestimmte Waypoints abzulaufen und auf dem Weg dann Rohstoffe zu sammeln.. Grundlegend ist unser Bot nun schon fertig.
Wir können nun noch Funktionen hinzufügen wie zum Beispiel Blacklisting, Meiden von bestimmten Elite Mobs, Erkennen von Spielern in der Umgebung mit Reaktion des ausloggens, Unstuck Funktionen und vieles mehr.
Was ihr in euren Bot einfügen werdet überlasse ich euch - nur seid euch bewusst das dieser Bot immer total Noobig sein wird.
Er ist nicht schwer zu endecken da er immer die exakten Wege läuft, und er wird sich immer irgendwo feststucken sofern ihr kein Kluges System zum unstuck einfügen werdet.
Kurz gesagt - Das ganze diente nur dazu euch näher zu bringen wie so ein Bot vom Theoretischen Aufbau funktionieren KANN.So ein Bot ist nicht dafür geeignet um damit ernsthaft zu botten. Der Bot hat keinerlei Sicherheitsmaßnahmen gegen Warden, ist total auffällig usw.. aber er sollte funktionieren wenn ihr alles richtig macht. Und ihr habt was gelernt, und nur darum ging es hierbei in diesem Thread.
Ich hoffe ich konnte dem einen oder anderem helfen, und hoffe ich habe euch zumindestens etwas den Tag versüßt.. auch wenn ich selbst noch ziemlicher Anfänger auf diesem Gebiet bin.
Grüße