Estamos escribiendo un bot de pesca en el juego Albion Online en Python

imagen

Hola a todos, soy un usuario feliz del sistema operativo GNU / Linux. Y como mucha gente sabe, hay muchos menos juguetes yendo a Linux sin bailes adicionales con una pandereta que en Windows.

Y aún menos juegos en el género MMORPG.

Sin embargo, hace aproximadamente medio año o un año, descubrí que habían portado el juego Albion Online a Linux.
El juego es muy entretenido, pero lleva bastante tiempo. Y para no desperdiciar mis preciosas horas de vida en vano, decidí escribir un bot. ¿Quién me dedicará recursos mientras realizo mis actividades?

El juego tiene muchos tipos de manualidades, puedes cortar madera, cavar piedras e incluso cultivar jardines, pero mi elección fue a favor de la pesca.

Por lo tanto, la esencia de la pesca en línea en Albion es simple, tomar una caña de pescar, ir al estanque, mantener presionado el botón para lanzar el cebo, esperar un cierto tiempo de mordisco.

imagen

Al picotear, debes presionar nuevamente los botones y jugar un mini-juego.

Aquí deberá tirar alternativamente, luego no tire de la caña de pescar, dependiendo de los movimientos del flotador. El flotador siempre se mueve al azar, con diferentes secuencias y velocidades. Y si haces todo bien y el flotador no va más allá de la zona permitida, entonces pescarás.

Entonces, automatizaremos todo este negocio. Mediante el lenguaje informático python. Decidí comenzar desde lo más difícil, es decir, desde el momento en que el juego comienza con un flotador. Aquí nuevamente, mi biblioteca favorita de visión por computadora OpenCV vino a mi rescate. Al iniciarlo, podemos detectar objetos, por ejemplo, en imágenes. Sin embargo, la biblioteca en sí misma no sabe exactamente qué necesitamos descubrir. Por supuesto, hay muchos patrones donde se presentan varios objetos para definirlos. Sin embargo, definitivamente no hay carrozas para Albion Online.

Pero en esta biblioteca hay una maravillosa función de búsqueda para una plantilla determinada. Y como plantilla, acabo de tomar una captura de pantalla de nuestro flotador.

imagen

Y como vemos, todo se encontró perfectamente en la imagen.

Y la diferencia entre la imagen y la transmisión de video no es grande, porque de hecho es solo una secuencia de imágenes con una velocidad muy rápida y unas pocas líneas de código. Y ahora ya podemos encontrar el flotador en la transmisión de video.

Código
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 


Vamos más allá El flotador se mueve hacia adelante y hacia atrás y también debemos moverlo presionando el botón del mouse.

Y por lo tanto, necesitamos sus coordenadas. Y para esto, estas líneas nos ayudan.

 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) 

Luego solo usamos la biblioteca PyAutoGUI , que apretará el botón del mouse y lo presionará con cierta frecuencia.

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

Y el mini-juego en sí mismo se ganó con éxito.

imagen

Ponemos todo en una función y lo dejamos por ahora.

Luego volvemos a la parte original, donde debemos monitorear el flotador.

Todo es un poco diferente, por ejemplo, podemos determinar dónde se lanzará el flotador e intentar analizar esa parte de la pantalla en busca de la presencia del flotador. Sin embargo, el flotador arrojado al agua aparece en diferentes ángulos y se balancea constantemente.

En este caso, tomaremos ese método ligeramente diferente. Su esencia es que analizamos, digamos la diferencia en píxeles dentro del fragmento rastreado. Que, si no hay flotante, se acerca a cero.

Como resultado, se encontró el valor óptimo en el cual, con la desaparición del flotador, podemos realizar acciones.

Código
 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 


Y los producimos, a saber, haga clic en el botón del mouse. También ponemos esto en la función.

Y finalmente, en conclusión, simplemente escribimos un guión donde en un bucle infinito lanzamos una caña de pescar y realizamos la primera y la segunda funciones alternativamente.

 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() 

Aquí hay una instrucción de video completa y un ejemplo del trabajo de este bot:


Realmente hay algunos matices en el sentido de que necesita chamanizar con números, ya que estos números se seleccionan para mi monitor, ubicación, personaje y equipo. Pero creo que para un pitonista competente esto no será un problema.

El guión completo:

Código
 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() 


Aquellos a quienes les gusta decir que esto es una pérdida de tiempo, notaré que esto es solo una herramienta, pueden usar estas bibliotecas en otros proyectos. La visión por computadora en sí misma se usa tanto en los misiles balísticos como en los programas para ayudar a las personas con discapacidades. Donde decidas aplicarlos, solo tu deseo.

Gracias a todos por su atención.

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


All Articles