Coding a GW Bot
featuring the tt6
In diesem Guide werde ich euch mein Wissen in Thema Bot-Coding vermitteln. Vom GUI bis zum vollendeten Bot, werde ich alles detailliert beschreiben. Das ganze wird an einem Beispiel-Bot erklärt, dem Sanctum Cay Bot.
Inhaltsverzeichnis
1. Programme
2. Vorbereitung
3. GUI (Grafische Benutzeroberfläche)
4. Includes
5. Variablen
6. Hotkeys
7. Der Weg
8. Der FarmTeil
9. Die Main-Funktion
1. Programme
2. Vorbereitung
Übersichtshalber sollte man, vor jedem Bot coden, einen Ordner mit dem Namen des Bots erstellen. In meinem Beispiel "Sanctum Cay Bot 1.0", da der Bot vom Riff der Stille aus farmt. Der Kreativität sind hierbei keine Grenzen gesetzt, jedoch sollte ein gewisser Wiedererkennungswert im Namen enthalten seien. Kurz nach dem Erstellen des Ordners müssen die Hauptkerne eines menschlich-aussehenden Bots mit eingefügt werden. Zu einem die
NomadMemory.au3 ,mit der man den GW-Prozess und deren Memory-Adressen auslesen/schreiben kann. Zum Anderen die neuste

,bestehend aus den beiden Dateien: tt6.ini und tt6.au3. Mit der MoveTo lässt sich dem Bot ein flüssiger, menschlicher Weg bereiten. Zudem ist der Dumper auch recht nützlich für das herausfinden der Adressen, kann aber danach auch wieder gelöscht werden. Da die MoveTo aber mit Memory-Adressen arbeitet benötigen wir eine Update.ini, in der die aktuellen Memory Adressen enthalten sind.
Erklärung der Update.ini
Quote:
;Update.ini
[SECTION 9-A]
DEATH = 0xa0d204
; Diese Adresse wird für den Deathcheck gebraucht. Bei einem _Memoryread(0xa0d204,$hprocess) gibt die Adresse im Todesfall 1 aus, ansonsten 0, lebend.
CAMCOURSEB = 0xa0d0c8
; Hiermit wird die Blickrichtung, der Winkel der Kamerasicht ausgelesen.
[SECTION D]
POSX = 0xd30a44
POSY = 0xd30a48
; Die wichtigste Vorraussetzung für die MoveTo. Diese Adressen kann man sich wie in einem Koordiantensystem mit den x und y-Achsen vorstellen. Zu diesen Punkten bewegt sich der Bot.
CHECK_MAP = 0xd306e0
;Die Check_Map adresse gibt heraus in welchem Bereich in GW man sich gerade befindet. Beim Auslesen ergibt sich folgendes:
0 = Außenposten/Stadt
2 = Ladebildschirm
1 = Gebiet
|
Da sich aber die Memory-Adressen nach jedem Update verändern, müsst ihr sie entweder selbst mit der Cheatengine heraussuchen (->

)
oder ihr könnt euch die Werte mit anderen Usern teilen. Ich selbst schreibe, nach einem Update, die neuen Mems in den

.
3. GUI (Grafische Benutzeroberfläche)
Eine GUI ist eine Grafische Benutzeroberfläche, die dem User die Bedienung des Bots definitiv
erleichtern sollte. Es bringt nichts eine Millionen Funktionen einzubauen, wenn Außenstehende diese nicht verstehen.
Um ein GUI zu erstellen, müsst ihr zuerst in eurem Ordner (hier: Sanctum Cay Bot 1.0) eine AutoIT-Datei erstellen (rechter mausklick-> Neu-> AutoIt v3 Script). Auf dieses Script macht ihr einen rechtsklick und geht auf "edit Script". Nun erscheint euer Script, welches nur den Standard Komentar enthalten sollte. Für das Erstellen des GUI's gibt es den Koda(FormDesigner), zu finden unter Tools. Nun öffnet sich der Koda FormDesigner. Hier könnt ihr ein wenig herumspiele.
Mit F10 seht ihr, wie das GUI aussehen soll und mit F9 erscheint der vorgegeben Code für die GUI. Diesen solltet ihr in euer AutoIt-Script kopieren. Ein explizierteres Tut wird folgen, aber jetzt habe ich erst einmal nur diese GUI erstelle:
Code aus dem Form-Designer:
PHP Code:
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#Region ### START Koda GUI section ### Form=
$Bot = GUICreate("Sanctum Cay Bot", 256, 190, 193, 125)
$Start = GUICtrlCreateButton("Start", 64, 96, 113, 65, 0)
$Check_Sell = GUICtrlCreateCheckbox("Sell after", 24, 16, 65, 17)
$Check_Place = GUICtrlCreateCheckbox("Place Money", 24, 40, 81, 17)
$Input_Sell = GUICtrlCreateInput("", 104, 16, 33, 21)
$Label1 = GUICtrlCreateLabel("Runden", 144, 16, 42, 17)
$Input_Place = GUICtrlCreateInput("", 104, 40, 33, 21)
$Label2 = GUICtrlCreateLabel("Runden", 144, 40, 42, 17)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
EndSwitch
WEnd
Erklärung:
Zuerst bindet die GUI alle für sich wichtigen Includes ein. Danach werden die verschiedenen Bauteile erstellt und in einer Variablen gespeichert, um diese nachher auch abfragen zu können. Mit dem While-Befehl wird die ganze Zeit abgefragt, ob irgendwas im GUI gedrückt, verändert wurde.
PHP Code:
Case $GUI_EVENT_CLOSE
Exit
-> bedeutet, dass wenn im GUI "X" gedrückt wird, sich er Bot schließt.
4. Includes
Durch Includes können andere Scripts in deinen Bot mit eingebunden werden. Dies geschieht mit dem Befehl "#include". Das wohl wichtigste Script für euer Bot, die tt6.au3, sollte also mit eingebunden werden:
PHP Code:
#include "tt6.au3"
<- Dies muss in genau die selben Zeilen wie die Includes aus der GUI auch:
PHP Code:
#include-once
#include "tt6.au3"
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
Mit dem Befehl #inlcude-once werden die Scripte alle nur 1x mit eingebunden, so wie es sein soll.
5. Variablen
Um Daten zu speichern werden in meisten fällen

benutzt. Diese werden mit einem $ in AutoIt gekennzeichnet. Vor jedem Bot müssen Variablen, die man im Script benutzt, deklariert werden. Da diese aber im
ganzen Script abrufbar seien sollen, sollte man sie vorher mit global deklarieren, ist aber kein muss.
In unserem Beispiel Bot: Die Runden nach denen das Geld abgelegt werden soll (
$RundenP) -- und die Runden nach denen man verkauft (
$RundenS).
PHP Code:
Global $RundenS = 0, $RundenP = 0
--> Da die Runden beim Start des Bottes auch 0 betragen.
6. Hotkeys
Viele Bots benutzen Hotkeys um den Bot zu verstecken, beenden oder pausieren zu lassen. Hotkeys werden mit dem Befehl

zugewiesen. In Unserem BeispielBot benutze ich nur den Beenden Hotkey:
PHP Code:
Hotkeyset("{F1}","End")
--> Würde jetzt F1 beim Bot gedrückt wird die Funktion "End" aufgerufen.
Da wir aber die Funktion End noch gar nicht erstellt haben machen wir dies:
PHP Code:
Func End()
Exit
EndFunc
--> Funktion um den Bot zu beenden.
--------------------------BREAK--------------------------
Der bisherige Code sieht demnach wiefolg aus:
PHP Code:
#include-once
#include "tt6.au3"
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
Global $RundenS = 0, $RundenP = 0
Hotkeyset("{F2}","End")
#Region ### START Koda GUI section ### Form=
$Bot = GUICreate("Sanctum Cay Bot", 256, 190, 193, 125)
$Start = GUICtrlCreateButton("Start", 64, 96, 113, 65, 0)
$Check_Sell = GUICtrlCreateCheckbox("Sell after", 24, 16, 65, 17)
$Check_Place = GUICtrlCreateCheckbox("Place Money", 24, 40, 81, 17)
$Input_Sell = GUICtrlCreateInput("", 104, 16, 33, 21)
$Label1 = GUICtrlCreateLabel("Runden", 144, 16, 42, 17)
$Input_Place = GUICtrlCreateInput("", 104, 40, 33, 21)
$Label2 = GUICtrlCreateLabel("Runden", 144, 40, 42, 17)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
EndSwitch
WEnd
Func End()
Exit
EndFunc
Meine Ordnung ist eigentlich immer wiefolgt:
Includes-> Global Variables -> Hotkeys -> GUI -> GUI/Hotkey-Relevante Funktionen -> Bot-Code
--------------------------BREAK End--------------------------
7. Der Weg
Jetzt geht das Bot-Coding los:
Zunächst müssen wir uns erst einmal überlegen, was der Bot machen soll. Zuerst sollte er aus dem Riff der Stille herausgehen, farmen, resignen, checken ob Verkauft oder Geld abgelegt werden soll, und wieder neu anfangen. Da dies auch nur ein kleiner Bot ist, der kaum/gar nicht rentabel ist, ist die Vorüberlegung auch demnach kürzer.
Wie oben schon erwähnt benutzen wir die MoveTo-Funktion. Diese benötigt aber Koordianten die wir vorher mit dem Dumper herausfinden sollten. Deshalb öffnen wir GuildWars, reisen zu dem gewünschten Punkt (hier: Riff der Stille) und schmeißen den Dumper an. Dieser zeigt uns ein haufen von Zahlen an, von denen für uns erstmal nur die
ersten 4 entscheident sind. Die ersten beiden Zahlen (x und y) zeigen die Position der Maus im Gw-Fenster und die nächsten beiden Zahlen (x und y) zeigen unsere Koordinaten an, die wir für unsere MoveTo brauchen.
Weil die MoveTo aber nur läuft wenn vorher ein prepmoveto() verwendet wurde starten wir unser Bot-Script mit folgender Funktion:
PHP Code:
Func goout()
prepmoveto()
Nun sollten wir unsere Spawnpoints checken, damit der Bot auch vom richtigen Punkt den richtigen Weg nimmt. Dazu müssen wir wieder und wieder ins Riff reisen, um jede Spawn-Koordinate zu ermitteln. Also drücken wir an einem Spawnpunkt im Numpad auf "0", damit der Dumper die aktuelle Koordiante in einer Textdatei (dump.txt) abspeichert (bsp: MoveTo(1, -21202, 4918)). Wir wollen aber gucken ob wir uns an dieser Stelle befinden und nicht zu dem Punkt laufen, deswegen löschen wir das
MoveTo(1, und ersetzen es durch ein
Checkarea(x,y) (bsp: Checkarea(-21202, 4918))
-> hiermit wird überprüft, ob man sich an der gewünschten Stelle befindet.
Nun haben wir unseren 1. Checkarea Point. Ob wir uns aber nach einem Resign o.Ä. wieder an dieser Stelle befinden ist Fraglich. Deswegen bauen wir eine

ein, um abzufragen an welcher Stelle wir uns gerade befinden. Mal auf Deutsch:
PHP Code:
Func goout()
prepmoveto()
If Checkarea(-21202, 4918) Then
Wenn sich also unser Bot an der gewünschten Stelle befindet, sollte der loslaufen, aber wohin? Ich würde sagen zum Ausgang, weswegen wir unseren Char in Richtung Portal bewegen, während wir mit 0 die Koordianten in größeren Abständen abspeichern.
Aus dem Dumper.txt entnehmen wir nun folgende Daten:
MoveTo(1, -21489, 5066)
MoveTo(1, -21825, 5429)
MoveTo(1, -22063, 6039)
MoveTo(1, -22270, 6447)
MoveTo(1, -22688, 6909)
, welche wir in unsere Funktion einbauen sollten:
PHP Code:
Func goout()
prepmoveto()
If Checkarea(-21202, 4918) Then
MoveTo(1, -21489, 5066)
MoveTo(1, -21825, 5429)
MoveTo(1, -22063, 6039)
MoveTo(1, -22270, 6447)
MoveTo(1, -22688, 6909)
Das ist nun unser 1. Weg zum Portal. Aber es gibt ja mehrer Spawnpoints...
Also wechseln wir den Distritk und beginnen wieder von vorne.
Checkarea
MoveTo(1, -22165, 4897) --> Checkarea(-22165, 4897)
Weg
MoveTo(1, -22137, 5442)
MoveTo(1, -22144, 6100)
MoveTo(1, -22220, 6324)
MoveTo(1, -22448, 6632)
MoveTo(1, -22707, 6901)
Script erweitern:
PHP Code:
Func goout()
prepmoveto()
If Checkarea(-21202, 4918) Then
MoveTo(1, -21489, 5066)
MoveTo(1, -21825, 5429)
MoveTo(1, -22063, 6039)
MoveTo(1, -22270, 6447)
MoveTo(1, -22688, 6909)
ElseIf Checkarea(-22165, 4897) Then
MoveTo(1, -22137, 5442)
MoveTo(1, -22144, 6100)
MoveTo(1, -22220, 6324)
MoveTo(1, -22448, 6632)
MoveTo(1, -22707, 6901)
Und noch einmal:
PHP Code:
Func goout()
prepmoveto()
If Checkarea(-21202, 4918) Then
MoveTo(1, -21489, 5066)
MoveTo(1, -21825, 5429)
MoveTo(1, -22063, 6039)
MoveTo(1, -22270, 6447)
MoveTo(1, -22688, 6909)
ElseIf Checkarea(-22165, 4897) Then
MoveTo(1, -22137, 5442)
MoveTo(1, -22144, 6100)
MoveTo(1, -22220, 6324)
MoveTo(1, -22448, 6632)
MoveTo(1, -22707, 6901)
ElseIf Checkarea(-22040, 6359) Then
MoveTo(1, -22291, 6590)
MoveTo(1, -22782, 7012)
EndIf
PHP Code:
Wenn Checkarea(x,y) dann ...
WennSonst Checkarea(x,y) dann..
Ende-Wenn
<-- Grob übersetzt
nachdem der Bot kurz vor dem Portal angekommen ist wird ihm dann nochmal ein Keepmoveto() angeordnet, damit der Bot noch weiter ins Portal läuft. Wenn er dann am Portal angekommen ist, öffnet sich der Ladebildschirm, d.h. es muss die Loadout-Funktion aufgerufen werden. Diese habe ich in die tt6.au3 schon integriert.
PHP Code:
Func loadout()
While _memoryread($memmap, $hprocess) <> 1
Sleep(500)
WEnd
Sleep(10000)
EndFunc
<-- Während der Ladebildschirm aktiv ist, "schläft" das Skript, bis der Ladebildschirm bei 100% ist. Danach wird noch einmal 10 Sekunden gewartet.
PHP Code:
Func goout()
prepmoveto()
If Checkarea(-21202, 4918) Then
MoveTo(1, -21489, 5066)
MoveTo(1, -21825, 5429)
MoveTo(1, -22063, 6039)
MoveTo(1, -22270, 6447)
MoveTo(1, -22688, 6909)
ElseIf Checkarea(-22165, 4897) Then
MoveTo(1, -22137, 5442)
MoveTo(1, -22144, 6100)
MoveTo(1, -22220, 6324)
MoveTo(1, -22448, 6632)
MoveTo(1, -22707, 6901)
ElseIf Checkarea(-22040, 6359) Then
MoveTo(1, -22291, 6590)
MoveTo(1, -22782, 7012)
EndIf
keepmoveto()
loadout()
EndFunc
8. Der FarmTeil
Somit ist unsere Ausgangsfunktion beendet. Nun kommt es zum
Farming Teil
Da die Gegner hier gleich schon am Anfang sind macht es aus meiner Sicht keinen Sinn, extra MoveTo's zu verwenden. Mit dem Befehl Keysend(" "), welcher auch in der tt6.au3 enthalten ist, lassen sich sehr leicht virtuelle Tastaturschläge drücken. So beginnt unser Bot mit dem Bewegen zu den Gegnern (mit "c" und "space"). Da der Bot nun ein kleines Stück laufen muss, bauen wir eine Sleepzeit ein, bis der Bot bei den Gegnern angekommen ist.
PHP Code:
Func fight()
keysend("c")
Sleep(200)
keysend("space")
Sleep(20000)
Danach sollte der Bot die Gegner töten. Dazu werden die SKills 1,2 und 3 benutzt. Auch zwischen diesen Castzeiten müsen wieder Sleepzeiten eingebaut werden.
PHP Code:
Func fight()
keysend("c")
keysend("space")
sleep(20000)
keysend("1")
sleep(1500)
keysend("2")
sleep(1500)
keysend("2")
sleep(2400)
Nun sollten die Gegner getötet sein, und die Drop müssen aufgehoben werden. Dazu benutzen wir eine
PHP Code:
For $i = 0 to 2
keysend("o")
Slp(60)
keySend("space")
Slp(600)
next
-> Für die Variable $i, die 0 ist, werden die nachfolgenden Befehle ausgeführt, bis $i = 2 ist.
PHP Code:
Func fight()
keysend("c")
keysend("space")
sleep(20000)
keysend("1")
sleep(1500)
keysend("2")
sleep(1500)
keysend("2")
sleep(2400)
For $i = 0 to 2
keysend("o")
Slp(60)
keySend("space")
Slp(600)
next
Nachdem 2x versucht wurde Items aufzuheben, sollte der Bot resignen. Dies geschieht mit der resign() - Funktion aus der tt6. Nachdem der Bot dann auf den "Zurück zum Außenposten" - Button geklickt hat, müssen wir wieder die Ladezeit abwarten. Diesmal mit Loadin(), da wir in einen Außenposten reisen. Da der Run danach abgeschlossen ist, addieren wir zu den beiden Variablen $RundenP/S +1.
PHP Code:
Func fight()
keysend("c")
keysend("space")
sleep(20000)
keysend("1")
sleep(1500)
keysend("2")
sleep(1500)
keysend("2")
sleep(2400)
For $i = 0 to 2
keysend("o")
Slp(60)
keySend("space")
Slp(600)
next
resign()
loadin()
$RundenS += 1
$RundenP += 1
Der bot benutzt am Ende die resign() - Funktion aus der tt6. Jetzt kann man in der tt6.au3 nach "Func resign()" suchen und dann steht da:
Quote:
Func Resign($wdelay = 50)
$cnt = 0
Do
keysend("-")
Sleep($wdelay)
keysend("r")
Sleep($wdelay)
keysend("e")
Sleep($wdelay)
keysend("s")
Sleep($wdelay)
keysend("i")
Sleep($wdelay)
keysend("g")
Sleep($wdelay)
keysend("n")
Sleep($wdelay)
keysend("RETURN")
RndSleep(5500)
$cnt +=1
Until (_memoryread($memdeath,$hprocess) = 1) Or $cnt >3
ControlClick($client, "", "", "left", 1, $DTclickX, $DTclickY)
EndFunc
|
Am Ende der Controlclick ist für den "Zurückreisen" - Button zuständig. Die Positionen sind oben als DTClick deklariert, siehe:
Quote:
Const $DTclickX = Int(IniRead("tt6.ini","click positions","DTclickX",0))
Const $DTclickY = Int(IniRead("tt6.ini","click positions","DTclickY",0))
|
Um die Click Position zu ändern, geht man in die tt6.ini und schreibst bei DTclickX und DTclickY seine Koordianten ein, die man mit dem Dumper herausfinden kann.
9. Die Main-Funktion
Bis hierhin haben wir unsere Funktionen goout() & fight() fertiggestellt. Nun müssen wir diese Funktionen aufrufen, aber auch checken, ob wir verkaufen, oder das gold in der Truhe ablegen wollen.
Dies machen wir am besten in einer neuen Funktion: Main()
PHP Code:
Func Main()
While 1
If Guictrlread($Check_Sell) = 1 Then
If Guictrlread($Input_Sell) = $RundenS Then GoSell()
EndIf
If Guictrlread($Check_Place) = 1 Then
If Guictrlread($Input_Place) = $RundenP Then GoPlace()
EndIf
Goout()
Farm()
Wend
EndFunc
--> Erklärung:
Mit

lesen wir aus, ob die Checkbox aktiviert wurde. Falls diese Aktiviert wurde, soll auch gecheckt werden, ob die Runden nach denen wir verkaufen/deponieren wollen auch mit denen aus der GUI übereinstimmen.
Danach werden die beiden Funktionen ausgeführt.
Vorsicht
Die Funktionen GoSell() und GoPlace() habe ich mit Absicht nicht eingebaut, da ihr, wenn ihr alles verstanden habt, selbst dazu in der Lage seien solltet. Auch habe ich mit Absicht nicht die aktuelle Update.ini eingefügt!
Trotzdem hoffe ich konnte euch einen kleinen Einblick ins Bot-Coden mit der tt6 geben und wünsche euch viel Spaß dabei.
Falls fragen aufkommen, einfach fragen, schließlich ist dazu ein Forum da