로스트아크 찌 낚시 완성 (로아낚시매크로3)

자 이제 이 포스팅 내용만 적용하면 일단 낚시 매크로를 사용할 수 있는 수준까지 될겁니다. ! 들어가기 전에 복습한번 해보죠. 첫번째 시간에는 마우스 좌표를 얻어와서 낚시터 이름과 함께 init.txt 에 저장했었습니다. 두번째 시간에는 느낌표 검출을 하는 방법을 알아 봤구요. 이번 시간에는 앞선 포스트에서 개발했던 코드에 Keyboard, Mouse 이벤트를 버무려서 자동 낚시가 되도록 해보겠습니다.

 

우선 Pycharm 을 관리자 권한으로 열어줍니다. 

그리고 init_config.pylostark_fishing.py 파일을 만들어 줍니다. 

그러면 폴더 구조는 아래처럼 되겠죠 

프로젝트 구조

1. init.txt 수정

init.txt 는 낚시 매크로를 돌리는 데 필요한 변수들이 저장되는 파일 입니다. 

파일을 열어 수정 해보죠 포스트 시리즈를 따라 오셨다면 init.txt 에 아래 내용이 보일 것입니다. 

[lostark_fishing]
width = 200
heght = 200

이 부분이 보인 다면 바로 아래에 다음과 같이 입력하세요

wait_time = 5
mark_image_name = LA_exclamation_mark.png
detect_cnt = 120

wait_time 은 한번의 낚시가 끝나고 또 찌를 던지기 까지 기다리는 시간입니다. (초단위)
mark_image_name 은 스크린샷을 뜬 느낌표 img 파일의 이름입니다. detect_cnt 는 찌를 던지고 느낌표를 검출하는 루틴이 돌게 될 텐데 그 루틴을 얼마만큼 돌릴 것이냐에 대한 내용 이죠 이는 컴퓨터 성능마다 모니터 해상도 마다 다를 수 있지만 Full HD 에서는 120이면 될 것 같습니다.

init.txt 내용

2. init_config.py 코딩

이 파일은 별거 없습니다. 그냥 configparser를 이용하여 메모장의 내용을 Python 변수로 바꿔주는 역할을 합니다. 

init_config.py 파일에 아래와 같이 입력합니다. 

import configparser
import os

configFile = os.path.dirname(os.path.realpath(__file__)) + '\\' + 'init.txt'
config = configparser.ConfigParser()
config.read(configFile)

FISHING_WIDTH = int(config['lostark_fishing']['width'])
FISHING_HEIGHT = int(config['lostark_fishing']['heght'])
FISHING_WAIT_TIME = int(config['lostark_fishing']['wait_time'])
FISHING_EXCLAMATION_MARK_IMG_NAME = config['lostark_fishing']['mark_image_name']
FISHING_EXCLAMATION_MARK_DETECT_CNT = int(config['lostark_fishing']['detect_cnt'])

우리는 이 FISHING_~~~ 변수들을 lostark_fishing.py 에서 사용 할 것입니다. 그러 바로 lostark_fishing.py 파일에 코드를 작성해 보죠 

3. lostark_fishing.py

이 파일에서 실제 낚시가 이루어 집니다. 

이전 포스트에서 만들었던 fishing_image.py, fishing_place.py 파일을 Import 하여 사용하고 있습니다. 그리고 findImgAndPressKey 함수에서  PyAutoGui 라이브러리를 통해 Key 이벤트를 발생시키는 것을 확인 할 수 있습니다. 

fishingLostArk 의 입력 인자를 살펴 보겠습니다. 

  • wait : 위에서 언급했듯 낚시 성공 후 다음 낚시를 위해 기다리는 시간입니다. 
  • setPos : 0 인 경우 F12 를 눌러 낚시 포인트를 지정해야 합니다. 1인 경우에는 init.txt 에 저장되어 있는 낚시 터 관련 정보를 이용합니다. 
  • fishingKey : 찌 낚시를 시작할 Key 입니다. 저의 경우는 ‘w’ 이고 입력하지 않는 다면 ‘w’ 로 동작합니다. 

 

아래 내용을 입력한 뒤 실행해 보세요 

 

import fishing_image as fi
import fishing_place as fp
import pyautogui as pa
import random
import time
from init_config import *

# - 이미지 이름을 입력 받아 이미지가 존재하게 될경우 입력 받은 Key 이벤트 발생 -
def findImgAndPressKey(imgName, key, startPos, cnt=60, confidence=.8, wait=0.1):
    posBtn = fi.findImageUntil(imgName, startPos=startPos, cnt=cnt, confidence=confidence, wait=wait)
    if posBtn == None:
        return False

    else:
        pa.press(key)
        return True

# - 자동 낚시 main 함수 -
def fishingLostArk(wait, setPos = 1, fishingKey = 'w'):
    fishingFailCnt = 0
    posList = []

    # - 마우스를 움직여 3개의 포인트를 지정
    if setPos == 0:
        posList = fp.getMousePointWithKey(3)
    # - init.txt 의 낚시터별 포인트를 불러옴
    else:
        posList = fp.getFishingPointList()
        print('point of init : ', str(posList))

    # - init_config.py 에서 저장한 값
    width = FISHING_WIDTH
    height = FISHING_HEIGHT

    # - 자동 낚시 무한 반복 -
    while True:
        # - 20번이상 실패하면 프로그램 종료 -
        if fishingFailCnt > 20:
            print("Fishing Too Much Fail")
            return

        if len(posList) > 0:
            idx = random.randrange(0, len(posList))
            #idx = fising_cnt % 3
            pa.moveTo(posList[idx][0], posList[idx][1], 1)
        else:
            print("Can't get fishing point")
            return

        pa.press(fishingKey)
        time.sleep(1)

        # - 느낌표를 검출할 영역
        region = fi.makeRegion(fi.getCenterOfScreen(), width, height)

        res = findImgAndPressKey(FISHING_EXCLAMATION_MARK_IMG_NAME, fishingKey, startPos=region, cnt=FISHING_EXCLAMATION_MARK_DETECT_CNT, confidence=0.8, wait=0.1)
        if res == True:
            print('Fishing Success')
            time.sleep(wait)
            if fishingFailCnt > 0:
                fishingFailCnt -= 1
        else:
            print('fishing Fail')
            fishingFailCnt += 1
            time.sleep(2)

        
if __name__=="__main__":
        fishingLostArk(FISHING_WAIT_TIME, setPos=1, fishingKey='w')
        

4. 테스트

테스트는 은빛 물결 호수에서 수행 했습니다. 참고로 전체화면 모드에서만 동작합니다. ~

코드를 실행하고 로스트아크로 작업 전환을 하게 되면 Pycharm 결과창이 아래와 같이 될 것입니다. setPos 를 0으로 해서 돌린 내용입니다. 1로 세팅해서 시험해 보세요 ! 

낚시 매크로 결과 화면

이로써 로스트아크 찌 낚시 매크로가 완성되었습니다. 

다만 불편한점이 있는데요 매크로를 실행한 뒤 로스트 아크를 선택해서 작업 전환을 해줘야 한다는 점입니다. 

또 다른 문제점은 팀뷰어 입니다. 저는 팀뷰어를 자주쓰는데요 

무료버전일 경우 연결을 끊으면 팀뷰어 팝업창이 뜨면서 화면 정중앙을 가려 버립니다. 그러면 이제 찌만 계속 소비하고 낚시는 실패하는 것이죠 .. 

Pywinauto 라는 라이브러리를 사용하면 위 문제를 해결 할 수 있습니다. 

다음 포스트에서는 이 라이브러리를 이용해 위에 언급했던 문제를 해결해 보도록 하겠습니다. 그리고 통발과 투망에 대해서도 포스팅 해보죠 

You may also like...

12 Responses

  1. 신기해용 댓글:

    로아에 적용해도 키입력, 마우스입력이 반영이 안되는데 키입력을 막은걸까요? 메모장에는 잘되네요 ㅎㅎ

    • 호그 댓글:

      개발하신 프로그램을 관리자 권한으로 실행 시켜 보시겠어요 ?? ㅎㅎ 혹시 CMD 환경에서 실행시키신 다면 CMD 를 관리자 권한으로 실행 시키면 되고 Pycharm 으로 하신다면 Pycharm 을 관리자 권한으로 실행 시키면 됩니다. !! ㅎㅎ

  2. 우하하 댓글:

    소중하고 유익한 정보 감사합니다! ㅎㅎ
    이걸로 연구를 해보고싶은데 어디서 부터 해야할지 고민이네요ㅠㅠ ㅎㅎ
    다음 강의도 완전 기대중입니다^^ ㅎㅎ
    엄청 기다려 지내요

    • 호그 댓글:

      ㅎㅎ 감사합니다 python 기본을 좀 공부하시고 보시면 더 좋을거에요 ㅎㅎ

  3. 박현 댓글:

    로스트아크 낚시 매크로가 필요합니다.

    완성된 낚시 매크로 압축해서 좀 보내주시면 안될가요?

    cmoonsoo88@gmail.com 으로 부탁 드립니다.

    • 호그 댓글:

      죄송합니다만 ㅠㅠ 해당 포스팅은 교육 목적입니다 배포 못한다는점 양해 부탁드립니다 ㅠㅠ

  4. 1rm 댓글:

    투망낚시까지 가져갈수있는 방법은 없을까요?>

    • 호그 댓글:

      코드 상으로 가능은 합니다. ㅎㅎ 투망 조건이 됬을때 뜨는 그림을 인식한뒤 투망 스킬을 눌러주면 되겠죠 !! 근데 죄송하지만 현제는 다른 일이 많아서 투망 코드는 만들기 좀 힘들것 같아요 ㅜㅜ

  5. 할수있어 댓글:

    느낌표 검출해서 이전포스팅에 보여주신 이지미처럼 검출확인됩니다.
    이제 init_config.py 와 lostark_fishing.py 두개를 위에 올려주신 코드 그대로 넣고

    lostark_fishing.py 실행했더니.
    C:\Python36-32\python.exe C:/Lostark/lostark_fishing.py
    0. fishingpoint_CRO
    **selectPlace :
    위에 뜨며, **selectPlace : 바로 옆에 CRONA 앞에 적었던 장소를 넣었는데요

    Traceback (most recent call last):
    File “C:/Lostark/lostark_fishing.py”, line 64, in
    fishingLostArk(FISHING_WAIT_TIME, setPos=1, fishingKey=’w’)
    File “C:/Lostark/lostark_fishing.py”, line 28, in fishingLostArk
    posList = fp.getFishingPointList()
    File “C:\Lostark\fishing_place.py”, line 72, in getFishingPointList
    index = int(input(strs))
    ValueError: invalid literal for int() with base 10: ‘CR0’

    위와같이 빨간글씨로 오류?가 뜹니다. 왜이럴까요 ㅠㅠ 거의 다 온것같은데요

  6. 할수 있어 댓글:

    느낌표 검출 완료하고 해당 포스팅 마지막 피싱 코드까지 다넣어서 실행하니

    C:\Python36-32\python.exe C:/Lostark/lostark_fishing.py
    0. fishingpoint_CRO
    **selectPlace : CRONA
    Traceback (most recent call last):
    File “C:/Lostark/lostark_fishing.py”, line 64, in
    fishingLostArk(FISHING_WAIT_TIME, setPos=1, fishingKey=’w’)
    File “C:/Lostark/lostark_fishing.py”, line 28, in fishingLostArk
    posList = fp.getFishingPointList()
    File “C:\Lostark\fishing_place.py”, line 72, in getFishingPointList
    index = int(input(strs))
    ValueError: invalid literal for int() with base 10: ‘CRONA’

    이렇게 뜹니다. **selectPlace : CRONA < CRONA는 제가 입력한거고 이후 아래
    글자들이 빨간색 오류로 나오네요.
    혹시 듀얼모니터로 써야하나요? 로아 실행한 후 창모드가서 코드실행하고
    다시 로아 들어가려한건데요. 로아 다시 들어가기도 전에 저런 오류가 뜨네요

    3시간 걸쳐서 여기까지온건데 포기할수가없네요 ㅠㅠ