
Bonjour à tous, je suis un utilisateur heureux du système d'exploitation GNU / Linux. Et comme beaucoup de gens le savent, il y a beaucoup moins de jouets qui vont à Linux sans danses supplémentaires avec un tambourin que sous Windows.
Et encore moins de jeux dans le genre MMORPG.
Cependant, il y a environ six mois ou un an, j'ai découvert qu'ils avaient porté le jeu Albion Online sur Linux.
Le jeu est très amusant, mais prend beaucoup de temps. Et pour ne pas gaspiller mes précieuses heures de vie en vain, j'ai décidé d'écrire un bot. Qui m'exploitera des ressources pendant que j'exploiterai mon entreprise.
Le jeu a de nombreux types d'artisanat, vous pouvez couper du bois, creuser des pierres, même cultiver des jardins, mais mon choix a été fait en faveur de la pêche.
Ainsi, l'essence de la pêche en ligne à Albion est simple, prenez une canne à pêche, allez à l'étang, maintenez le bouton enfoncé pour lancer l'appât, attendez un certain temps de morsure.

Lorsque vous picorez, vous devez à nouveau appuyer sur les boutons et jouer à un mini-jeu.
Ici, vous devrez tirer alternativement, puis ne tirez pas sur la canne à pêche, en fonction des mouvements du flotteur. Le flotteur se déplace toujours de façon aléatoire, avec différentes séquences et vitesses. Et si vous faites tout correctement et que le flotteur ne dépasse pas la zone autorisée, vous attraperez du poisson.
Nous allons donc automatiser toutes ces activités. Au moyen du langage informatique python. J'ai décidé de partir du plus difficile, à savoir à partir du moment où le jeu commence par un flotteur. Là encore, ma
bibliothèque de vision par ordinateur
OpenCV préférée est venue à mon secours. En le lançant, nous pouvons détecter des objets, par exemple, dans des images. Cependant, la bibliothèque elle-même ne sait pas exactement ce que nous devons découvrir. Bien sûr, il existe de nombreux modèles où divers objets sont présentés pour les définir. Cependant, il n'y a certainement aucun flotteur pour Albion Online.
Mais dans cette bibliothèque, il existe une merveilleuse fonction de recherche pour un modèle donné. Et comme modèle, je viens de prendre une capture d'écran de notre flotteur.

Et comme nous le voyons, tout était parfaitement trouvé sur la photo.
Et la différence entre l'image et la vidéo en streaming n'est pas grande, car en fait ce n'est qu'un flux d'images avec une vitesse très rapide et quelques lignes de code. Et maintenant, nous pouvons déjà trouver le flotteur sur la vidéo en streaming.
Codeimport 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
Nous allons plus loin. Le flotteur lui-même se déplace d'avant en arrière et nous devons également le déplacer en appuyant sur le bouton de la souris.
Et donc, nous avons besoin de ses coordonnées. Et pour cela, ces lignes nous aident.
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)
Ensuite, nous utilisons simplement la bibliothèque
PyAutoGUI , qui
bloquera le bouton de la souris et l'enfoncera avec une certaine fréquence.
if 100 < x < 500: pyautogui.mouseDown(button='left') time.sleep(1) pyautogui.mouseUp(button='left') x = 0
Et le mini-jeu lui-même est remporté avec succès.

Nous mettons le tout dans une fonction et le laissons pour le moment.
Ensuite, nous revenons à la partie d'origine, où nous devons surveiller le flotteur.
C'est un peu différent, par exemple, nous pouvons déterminer où le flotteur sera lancé et essayer d'analyser cette partie de l'écran pour la présence du flotteur. Cependant, le flotteur jeté dans l'eau apparaît sous différents angles et oscille constamment.
Dans ce cas, nous prendrons cette méthode légèrement différente. Son essence est que nous analysons, disons la différence de pixels à l'intérieur du fragment suivi. Qui, s'il n'y a pas de flotteur, approche de zéro.
En conséquence, la valeur optimale a été trouvée à laquelle, avec la disparition du flotteur, nous pouvons effectuer des actions.
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
Et nous les produisons, à savoir, cliquez sur le bouton de la souris. Nous avons également mis cela dans la fonction.
Et enfin, en conclusion, nous écrivons simplement un script où, dans une boucle infinie, nous jetons une canne à pêche et effectuons les première et deuxième fonctions en alternance.
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()
Voici une instruction vidéo complète et un exemple du travail de ce bot:
Il y a vraiment quelques nuances dans le fait que vous devez chamaniser avec des nombres, car ces nombres sont sélectionnés pour mon moniteur, mon emplacement, mon personnage et mon équipement. Mais je pense que pour un pythoniste compétent, ce ne sera pas un problème.
Le script entier:
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()
Ceux qui aiment dire que c'est une perte de temps, je remarquerai que ce n'est qu'un outil, vous pouvez utiliser ces bibliothèques dans d'autres projets. La vision par ordinateur elle-même est utilisée à la fois pour le survol de missiles balistiques et pour les programmes d'aide aux personnes handicapées. Où vous décidez de les appliquer, uniquement votre désir.
Merci à tous pour votre attention.