Wir schreiben einen Angelbot im Spiel Albion Online in Python

Bild

Hallo allerseits, ich bin ein glücklicher Benutzer des GNU / Linux-Betriebssystems. Und wie viele Leute wissen, gibt es viel weniger Spielzeug, das ohne zusätzliche Tänze mit einem Tamburin zu Linux geht als unter Windows.

Und noch weniger Spiele im MMORPG-Genre.

Vor ungefähr einem halben oder einem Jahr fand ich jedoch heraus, dass sie das Albion Online-Spiel auf Linux portiert hatten.
Das Spiel ist sehr unterhaltsam, nimmt aber ziemlich viel Zeit in Anspruch. Und um meine kostbaren Lebensstunden nicht umsonst zu verschwenden, beschloss ich, einen Bot zu schreiben. Wer wird mir Ressourcen bewirtschaften, während ich meinem Geschäft nachgehe?

Das Spiel hat viele Arten von Kunsthandwerk, man kann Holz schneiden, Steine ​​graben, sogar Gärten anlegen, aber ich habe mich für das Angeln entschieden.

Die Essenz des Online-Fischens in Albion ist also einfach: Nehmen Sie eine Angelrute, gehen Sie zum Teich, halten Sie den Knopf gedrückt, um den Köder zu werfen, und warten Sie auf eine bestimmte Bisszeit.

Bild

Beim Picken müssen Sie erneut die Tasten drücken und ein Minispiel spielen.

Hier müssen Sie abwechselnd ziehen, dann ziehen Sie nicht an der Angelrute, abhängig von den Bewegungen des Schwimmers. Der Schwimmer bewegt sich immer zufällig mit unterschiedlichen Sequenzen und Geschwindigkeiten. Und wenn Sie alles richtig machen und der Schwimmer nicht über die zulässige Zone hinausgeht, werden Sie Fische fangen.

Also werden wir all dieses Geschäft automatisieren. Mit Hilfe der Computersprache Python. Ich entschied mich für das Schwierigste, nämlich für den Moment, in dem das Spiel mit einem Float beginnt. Auch hier kam mir meine Lieblings- OpenCV- Computer-Vision- Bibliothek zu Hilfe. Durch das Starten können wir Objekte beispielsweise in Bildern erkennen. Die Bibliothek selbst weiß jedoch nicht genau, was wir entdecken müssen. Natürlich gibt es viele Muster, in denen verschiedene Objekte dargestellt werden, um sie zu definieren. Es gibt jedoch definitiv keine Floats für Albion Online.

Aber in dieser Bibliothek gibt es eine wunderbare Suchfunktion für eine bestimmte Vorlage. Und als Vorlage habe ich gerade einen Screenshot unseres Schwimmers gemacht.

Bild

Und wie wir sehen, war alles perfekt auf dem Bild zu finden.

Und der Unterschied zwischen dem Bild und dem Streaming-Video ist nicht groß, denn es handelt sich tatsächlich nur um einen Stream von Bildern mit einer sehr hohen Geschwindigkeit und einigen Codezeilen. Und jetzt können wir den Float bereits im Streaming-Video finden.

Code
import numpy as np import cv2 from mss.linux import MSS as mss from PIL import Image import time import pyautogui as pg import cv2 import mss import numpy template = cv2.imread("2019-07-02_06-55_1.png", cv2.IMREAD_GRAYSCALE) w, h = template.shape[::-1] with mss.mss() as sct: monitor = {"top": 40, "left": 0, "width": 800, "height": 640} while "Screen capturing": last_time = time.time() img = numpy.array(sct.grab(monitor)) cv2.imshow("OpenCV/Numpy normal", img) print("fps: {}".format(1 / (time.time() - last_time))) gray_frame = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) res = cv2.matchTemplate(gray_frame, template, cv2.TM_CCOEFF_NORMED) loc = np.where(res >= 0.7) for pt in zip(*loc[::-1]): cv2.rectangle(img, pt, (pt[0] + w, pt[1] + h), (0, 255, 0), 3) cv2.imshow("Frame", img) key = cv2.waitKey(1) if cv2.waitKey(25) & 0xFF == ord("q"): cv2.destroyAllWindows() break 


Wir gehen weiter. Der Schwimmer selbst bewegt sich hin und her und wir müssen ihn auch durch Drücken der Maustaste bewegen.

Und deshalb brauchen wir seine Koordinaten. Und dafür helfen uns diese Zeilen.

 for p in img: pts = (pt[0],pt[1]) x = (pt[0]) y = (pt[1]) print (x) cv2.circle(template,pts,5,(200,0,0),2) cv2.putText(img, "%d-%d" % (x,y), (x+10,y-10), cv2.FONT_HERSHEY_SIMPLEX, 1, color_yellow, 2) 

Dann verwenden wir einfach die PyAutoGUI- Bibliothek, die die Maustaste festklemmt und mit einer bestimmten Frequenz drückt.

 if 100 < x < 500: pyautogui.mouseDown(button='left') time.sleep(1) pyautogui.mouseUp(button='left') x = 0 

Und das Minispiel selbst ist erfolgreich gewonnen.

Bild

Wir setzen das Ganze in eine Funktion und lassen es vorerst.

Dann kehren wir zum Originalteil zurück, wo wir den Schwimmer überwachen müssen.

Es ist alles ein bisschen anders, zum Beispiel können wir bestimmen, wohin sich der Schwimmer selbst wirft, und versuchen, diesen Teil des Bildschirms auf das Vorhandensein des Schwimmers zu analysieren. Der ins Wasser geworfene Schwimmer erscheint jedoch in unterschiedlichen Winkeln und schwankt ständig.

In diesem Fall werden wir diese etwas andere Methode anwenden. Das Wesentliche ist, dass wir den Unterschied in Pixeln innerhalb des verfolgten Fragments analysieren. Was, wenn kein Float vorhanden ist, gegen Null geht.

Als Ergebnis wurde der optimale Wert gefunden, bei dem wir mit dem Verschwinden des Schwimmers Aktionen ausführen können.

Code
 def screen_record(): sct = mss.mss() last_time = time.time() while(True): img = sct.grab(mon) print('loop took {} seconds'.format(time.time() - last_time)) last_time = time.time() img = np.array(img) processed_image = process_image(img) mean = np.mean(processed_image) print('mean = ', mean) if mean <= float(0.11): print('SSSSSSSS ') pyautogui.click(button='left') break return else: time.sleep(0.01) continue return if cv2.waitKey(25) & 0xFF == ord('q'): cv2.destroyAllWindows() break 


Und wir produzieren sie, nämlich per Mausklick. Wir setzen dies auch in die Funktion ein.

Und zum Schluss schreiben wir einfach ein Skript, in dem wir in einer Endlosschleife eine Angel werfen und abwechselnd die erste und die zweite Funktion ausführen.

 while "": time.sleep(1) pyautogui.moveTo(431,175,duration=1) pyautogui.mouseDown(button='left') pyautogui.moveTo(450.200,duration=1) pyautogui.mouseUp(button='left') time.sleep(2) screen_record() time.sleep(0.01) ss() 

Hier ist eine vollständige Videoanweisung und ein Beispiel für die Arbeit dieses Bots:


Es gibt wirklich einige Nuancen, die Sie mit Zahlen schamanisieren müssen, da diese Zahlen für meinen Monitor, meinen Standort, meinen Charakter und meine Ausrüstung ausgewählt sind. Aber ich denke für einen kompetenten Pythonisten wird dies kein Problem sein.

Das ganze Drehbuch:

Code
 import numpy as np import cv2 from mss.linux import MSS as mss from PIL import Image import time import pyautogui as pg import imutils import mss import numpy import pyautogui template = cv2.imread("2019-07-02_06-55_1.png", cv2.IMREAD_GRAYSCALE) w, h = template.shape[::-1] color_yellow = (0,255,255) mon = {'top': 80, 'left': 350, 'width': 100, 'height': 100} def process_image(original_image): processed_image = cv2.cvtColor(original_image, cv2.COLOR_BGR2GRAY) processed_image = cv2.Canny(processed_image, threshold1=200, threshold2=300) return processed_image def ss(): op = 1 with mss.mss() as sct: monitor = {"top": 40, "left": 0, "width": 800, "height": 640} while "Screen capturing": last_time = time.time() img = numpy.array(sct.grab(monitor)) gray_frame = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) res = cv2.matchTemplate(gray_frame, template, cv2.TM_CCOEFF_NORMED) loc = np.where(res >= 0.7) op += 1 print (op) for pt in zip(*loc[::-1]): cv2.rectangle(img, pt, (pt[0] + w, pt[1] + h), (0, 255, 0), 3) for p in img: pts = (pt[0],pt[1]) x = (pt[0]) y = (pt[1]) print (x) if 100 < x < 490: pyautogui.mouseDown(button='left') time.sleep(2) pyautogui.mouseUp(button='left') x = 0 break else: continue break else: continue break key = cv2.waitKey(1) if cv2.waitKey(25) & 0xFF == ord("q"): cv2.destroyAllWindows() if op > 35: return def screen_record(): sct = mss.mss() last_time = time.time() while(True): img = sct.grab(mon) print('loop took {} seconds'.format(time.time() - last_time)) last_time = time.time() img = np.array(img) processed_image = process_image(img) mean = np.mean(processed_image) print('mean = ', mean) if mean <= float(0.11): print('SSSSSSSS ') pyautogui.click(button='left') break return else: time.sleep(0.01) continue return if cv2.waitKey(25) & 0xFF == ord('q'): cv2.destroyAllWindows() break while "": time.sleep(1) pyautogui.moveTo(431,175,duration=1) pyautogui.mouseDown(button='left') pyautogui.moveTo(450.200,duration=1) pyautogui.mouseUp(button='left') time.sleep(2) screen_record() time.sleep(0.01) ss() 


Diejenigen, die gerne sagen, dass dies Zeitverschwendung ist, werden feststellen, dass dies nur ein Werkzeug ist. Sie können diese Bibliotheken in anderen Projekten verwenden. Computer Vision selbst wird sowohl beim Schweben ballistischer Raketen als auch in Programmen zur Unterstützung von Menschen mit Behinderungen eingesetzt. Wo Sie sich entscheiden, sie anzuwenden, nur Ihr Wunsch.

Vielen Dank für Ihre Aufmerksamkeit.

Source: https://habr.com/ru/post/de459110/


All Articles