로스트아크 낚시 매크로 with Python (로아낚시매크로1)

로스트아크에서 낚시는 굉장히 귀찮은 컨텐츠중 하나인 것 같습니다. 

하지만 다른 생활에 비해 쉬워서 많은 사람들이 낚시를 선택하시는 것 같습니다. 

난이도는 쉽지만 그래도 시간이 많이 들어가는 종목이죠 .. 사실 로아에서 하루에 할 숙제가 얼마나 많이 있습니까 .. 

카던, 레이드, 플필, 큐브, 보물지도, 에포나 등등등 이렇게나 할게 많은데 

직장인들 바쁜 사람들은 생활을 할 시간이 어디 있겠어요 ㅜㅜㅜㅜ

 

그래서 숙제 하나라도 줄이자는 의미에서 자동 낚시 프로그램을 만들어 보았습니다.

(물론 지금 돌려봐야 고기값, 낚시로 만들 수 있는 배틀아이템 등이 너무 싸져서 전기세가 아깝겠지만 교육적인 차원에서 포스팅을 해봅니다. ㅋㅋㅋ 그리고 이 매크로를 만들어서 24시간 돌려야 겠다보다는 여기에 쓰이는 라이브러리 등을 이용해 뭔가 더 재미있고 유익한 것을 만들 수 있겠구나 정도로 생각해 주시면 감사하겠습니다. 추가로 매크로 남용은 게임을 병들게 하고 계정 정지를 유발할 수 있으니 절대 남용 하시지 말길 당부드립니다. )

 

낚시의 메커니즘은 반복적입니다. 

  1. 생활스킬로 트리를 변경한다. 
  2. 마우스를 물가로 움직인다.  
  3. 키보드(‘w’)로 찌를 던진다. 
  4. 느낌표가 나올때 까지 기다린다. 
  5. 느낌표가 나오면 키보드로(‘w’)로 찌를 회수한다. 
  6. 2~ 5번을 반복한다. 

 

이 반복적인 행위를 Python 으로 쉽게 해결하기 위해 아래와 같은 방법을 생각했습니다. 

  1.  생활 스킬 변경(수동으로)
  2. 모니터 상의 물가 좌표를 미리 받아와서 마우스를 그 좌표로 이동
  3. ‘w’ 를 누르도록 명령
  4. 반복적으로 화면 중앙에 느낌표가 생기는지 확인 
  5. 느낌표를 검출하는 순간 ‘w’ 를 누르도록 명령 
  6.  2 ~ 5번을 반복 

그러면 Python 으로 위 알고리즘을 구현해 보겠습니다.

개발환경 세팅은 아래 링크를 참조해 주시는데 아래 주의 사항을 참고해 주세요 !

  • 파이썬 버전은 3.6 64bit 로 진행하겠습니다. (32 비트 버전로 해도 큰 차이는 없을 것이라고 생각 됩니다.)
  • Virtualenv 는 선택 사항 입니다. 만약 세팅 하신다면 “Library root가 다른 곧에 있을 때” 항목을 참조해 주세요

1. 낚시 포인트 얻기 

우선 찌를 던질 수 있는 물가의 좌표를 알아야 겠죠 ? 그리고 이 좌표는 낚시 터 별로 지정을 해야 여러 곳에서 낚시를 할 수 있을 것입니다. 

lostark 라는 폴더를 만들고 그 아래 fishing_place.py 파일을 생성합니다. 그리고 설정내용을 담을 init.txt 파일 또한 생성합니다. 

/lostark

/ – fishing_place.py

/ – init.txt

그리고 pip 혹은 Pycharm을 이용해 아래 라이브러리를 설치합니다. 

pip install configparser
pip install keyboard
pip install mouse

configparser 는 좌표데이터를 init.txt 에 쉽게 저장해주기 위한 라이브러리이고 keyboard와 mouse 라이브러리는 window 의 Keyboard, mouse 관련 이벤트를 Hooking 하거나 발생시켜 주는 역할을 합니다. 

자 그럼 낚시 포인트 설정을 위해 ‘F12’를 누르면 현제 Mouse 위치의 좌표를 돌려주는 함수를 만들어 보죠 

(추가로 Pycharm 혹은 CMD 에서 기능을 테스트 할때 반드시 관리자 권한으로 실행시켜 주세요 !!!)

import os
import configparser
import mouse as mo
import keyboard as key
from ast import literal_eval

def getMousePointWithKey(cnt):
    state = False
    returnList = []
    tcnt = 0
    while True:
        val = key.is_pressed('F12')
        if state != val:
            if val == True:
                tcnt += 1
                returnList.append(mo.get_position())
                print ('Point ', tcnt, ' Catched')
            state = val
        if tcnt >= cnt:
            return returnList

if __name__ == "__main__":
    print(getMousePointWithKey(1))

위 코드를 실행 한 상태에서 ‘F12’ 를 누르면 아래와 같이 현제 마우스 포인트의 좌표가 리스트 형태로 출력됩니다. cnt 를 변경해서 시험해 보세요 !

2. 얻어온 낚시 포인트 저장하고 읽기

 이제 얻어온 낚시 포인트를 configparser를 이용해 낚시터 정보와 함께 init.txt 에 저장해보겠습니다. 

import os
import configparser
import mouse as mo
import keyboard as key
from ast import literal_eval

# --------------------- F12 를 누르면 현제 Mouse 의 좌표를 돌려주는 함수 -------
def getMousePointWithKey(cnt):
    state = False
    returnList = []
    tcnt = 0
    while True:
        val = key.is_pressed('F12')
        if state != val:
            if val == True:
                tcnt += 1
                returnList.append(mo.get_position())
                print ('Point ', tcnt, ' Catched')
            state = val
        if tcnt >= cnt:
            return returnList

# --------------------- 낚시 장소 및 포인트 저장 -------------------------------

def writeOptionOnConfig(section, option, val):
    flag = False
    configFile = os.path.dirname(os.path.realpath(__file__)) + '\\' + 'init.txt'

    config = configparser.ConfigParser()
    config.read(configFile)

    for idx, sec in enumerate(config.sections()):
        if sec == section:
            config[section][option] = val
            flag = True

    if flag == False:
        config.add_section(section)
        config[section][option] = val


    with open(configFile, 'w') as config_file:
        config.write(config_file)
    pass



def writeFishingPos(fishingPlace):
    poss = getMousePointWithKey(3)
    prefixFishingPlace = 'fishingpoint_' + fishingPlace
    for i, pos in enumerate(poss):
        opt = 'point' + str(i+1)
        print(opt, ' ', pos)
        writeOptionOnConfig(prefixFishingPlace, opt, str(pos))

def saveFishingPlaceAndPoint():
    name = input('fishing place name :')
    print("move mouse to water and press F12 ")
    writeFishingPos(name)

# --------------------- 낚시 장소 및 포인트 조회 -------------------------------

def getFishingPlaceList():
    configFile = os.path.dirname(os.path.realpath(__file__)) + '\\' + 'init.txt'
    returnList = []
    config = None
    try:
        config = configparser.ConfigParser()
        config.read(configFile)
        for section in config.sections():
            if section.find('fishingpoint') >= 0:
                returnList.append(section)

    except Exception as e:
        print(str(e))

    return returnList, config



def getFishingPointList():
    returnList, config = getFishingPlaceList()
    pointList = []
    placeList = []
    if len(returnList) > 0:
        strs = ''
        for idx, place in enumerate(returnList):
            strs += str(idx) + '. ' + place + '\n'
            placeList.append(place)

        strs += '**selectPlace : '
        index = int(input(strs))


        if index < 0 and index > len(returnList):
            print('invalid Index')
            return False

        if config != None:
            for i in config[returnList[index]]:
                pointList.append(literal_eval(config[returnList[index]][i]))

    return pointList

if __name__ == "__main__":
    opt = 0
    if opt == 0:
        saveFishingPlaceAndPoint()
    else:
        result = getFishingPointList()
        print(result)

 

이 코드에서 opt = 0 으로 설정한뒤 Pycharm 에서 실행하면 낚시 장소를 입력 하라는 Prompt가 뜹니다. 그러면 현제 위치를 영어로 입력하면 되구요 그 다음엔 설명 대로 마우스를 물가로 움직인 다음 ‘F12’를 누르시는데 3 개의 포인트를 지정하도록 했습니다. 즉 찌를 던질 포인트를 3개 지정했다는 소리 입니다. (캐릭터랑 너무 멀지 않게 선택해 주세요 )

 

그럼 아래와 같은 결과가 출력 될 것입니다. 

장소 크로나항구

위 출력 화면을 확인 했으면 init.txt 파일을 열어보겠습니다. 

아래 그림 처럼 내가 입력한 이름에 ‘fishingpoint_’ 가 Prefix로 더해져서 낚시 터가 저장 되었고 마우스 좌표가 3개 입력 되어 있는 것을 확인 하실 수 있습니다. 

참고로 [fishingpoint_crona] 부분을 section 이라고 부르고 point1, point2, point3 를 option 이라고 합니다. 마지막으로 option 에 할당된 값을 value 라고 하구요

코드 실행 후 init.txt

다음으로는 configparser를 통해 대화형으로 저장된 낚시 포인트를 가져와 보겠습니다. 

위 코드에서 opt 를 1로 한뒤 코드를 실행해 보세요 

아래와 같이 나올 탠데요 0. fishingpoint_crona 가 우리가 지정한 낚시 터 이름입니다. 

그리고 숫자 0을 입력하면 저장한 포인트를 리스트 형태로 얻어 오실 수 있습니다. 지정한 장소가 많을 경우 0, 1, 2, 3 이런식으로 장소가 나오겠지요 

이번 포스트에서는 낚시 장소 및 포인트를 저장하고 불러오는 모듈을 만들어 보았습니다. 

다음 포스트에서는 느낌표를 검출해 보도록 하겠습니다. ~

You may also like...

13 Responses

  1. B_okkkkk 댓글:

    그리고 pip 혹은 Pycharm을 이용해 아래 라이브러리를 설치합니다.

    pip install configparser
    pip install keyboard
    pip install mouse

    이 부분에서 라이브러리를 어떻게 추가하는지 모르겠습니다 도움요청드려요 ㅠㅠ

    • 호그 댓글:

      혹시 Pycharm 이용하신다면 왼쪽 상단에 File 버튼이 있을 거에요 ! 그래서
      file > Settings… > Project:본인프로젝트이름 > Project interpreter 를 선택하면
      오른쪽에 보면 + 버튼이 있어요 그 버튼을 누르면 Available Packages 가 뜨는데 여기서 configparser, keyboard, mouse 를 검색해서 나오는 라이브러리를 Install Package 버튼으로 설치 하시면 됩니다.
      CMD 의 경우에는 가상환경 Enable 한 뒤 아래 택스트를 한줄 씩 복사 붙혀넣기 하면 됩니다. !!
      pip install configparser
      pip install keyboard
      pip install mouse

  2. B_okkkkk 댓글:

    1번까지는 무사히 마쳤는데
    2번부터 나오는 코딩은 똑같이 1번 설명에 나온 코딩 끝에서부터 다시 입력하면 되는걸까요??

  3. B_okkkkk 댓글:

    if __name__ == “__main__”:
    print(getMousePointWithKey(1))

    이 코딩 뒤에 바로 이어서 2번 설명의 코딩을 쭉 이어가면 되는건지 알고싶어요!
    죄송합니다 컴알못이라 많은 가르침이 필요해요 ㅠ!

  4. ㅠㅠ 댓글:

    따라해보려고 해도 첫문장에서부터 막혀서 GG…. 컴맹은 울고 갑니다 ㅜㅜ..

  5. 기우 댓글:

    마우스 포인트로 좌표를 출력해서 그 좌표에서 낚시를 하는게 맞는건건가요?
    그리고 혹시 만약 창모드로 했을 시 창을 이동하게 되면 이동과상관없이 기존 위치값을 추적해서 낚시를 하나요?

    • 호그 댓글:

      마우스 포인터로 찌를 던지게 됩니다.!! 모니터 절대값으로 던지는 것이므로 창모드 이동시 오 동작할 수 있습니다.

  6. 멍멍이멍멍 댓글:

    제가 파이썬을 몰라서 그러는데
    import mouse as mo
    import keyboard as key
    를 하게 되면 윈도우즈의 키보드, 마우스 이벤트 관련 api 를 사용할 수 있게 되나요?

    • 호그 댓글:

      해당 라이브러리는 윈도우즈 관련 api 를 기반으로 좀 편하게 쓸 수 있도록 만들어진 함수입니다. ㅎㅎ 그럼으로 간접적으로 사용한다고 볼 수 있을 것 같아요
      pywin32 라이브러리 사용하시면 마우스, 이벤트 API 기능을 좀더 자유롭게 쓸수 있을 겁니다.

댓글 남기기

이메일은 공개되지 않습니다.