본문 바로가기
일상

인터파크 취켓팅 매크로

by 강성주의 알고리즘 2022. 2. 16.

다른 방식의 매크로 만들기가 궁금하다면 ?? 

2023.11.29 - [분류 전체보기] - 인터파크 매크로 만들기. [1. 환경 구축]

2023.11.29 - [분류 전체보기] - 인터파크 매크로 만들기. [2. 로그인]

2023.11.30 - [그냥 끄적끄적] - 인터파크 매크로 [3. 공연 스케쥴 선택하기 - 1]

2023.11.30 - [그냥 끄적끄적] - 인터파크 매크로 [3. 공연 스케쥴 선택하기 - 2]

2023.12.01 - [그냥 끄적끄적] - 인터파크 매크로 만들기 [4. 좌석 선점하기 - 1]

2023.12.01 - [그냥 끄적끄적] - 인터파크 매크로 만들기 [4. 좌석 선점하기 - 마무리]


 

리뉴얼 했습니다. 2023년 11월 16일 오후 10시 7분 기준 GUI 형태로 수정완료 했습니다. (2연석까지 제공 가능합니다. 2/3층에서 좌석 선택 가능합니다.)

main.py
0.01MB

코드에서 self.need_seat_cnt = 1로하면 1석, 2로 하면 2연석 가능합니다. (좌석 색 달라도 가능), 인터파크 구동 영상.

 

전체 파이썬 코드

더보기
import tkinter as tk
import pyautogui
import keyboard
import random
from PIL import ImageGrab, Image, ImageTk
import time as ttt
import threading
import time

class MacroLoopApp:
    def __init__(self, root):
        self.root = root

        # 무한 루프 동작 여부를 나타내는 플래그
        self.is_running = False

        self.seat_axis = []
        self.seat_class = set()
        self.time_axis = []
        self.pay_axis = []
        self.floor_axis = []
        self.need_seat_cnt = 2  # 연석인 경우 2 로 근데 잘 될지 모르겠음

        # 버튼 생성
        self.play_button1 = tk.Button(self.root, text="1층 매크로 시작", command=self.start_first_floor)
        self.play_button1.place(x=700, y=120)

        # 버튼 생성
        self.play_button2 = tk.Button(self.root, text="2/3층 매크로 시작", command=self.start_second_floor)
        self.play_button2.place(x=700, y=150)

        self.pause_button = tk.Button(self.root, text="매크로 중지", command=self.stop_infinite_loop)
        self.pause_button.place(x=700, y=180)

        self.canvas = tk.Canvas(self.root, width=500, height=500)
        self.canvas.place(x=100, y=100)

        # 버튼 생성
        self.button1 = tk.Button(self.root, text="좌석 영역 선택하기", command=self.get_axis)
        self.button1.place(x=700, y=460)

        self.button1 = tk.Button(self.root, text="2/3층 영역 선택하기", command=self.get_floor_axis)
        self.button1.place(x=700, y=490)

        self.button2 = tk.Button(self.root, text="좌석 등급 선택하기", command=self.get_color)
        self.button2.place(x=700, y=520)

        self.button3 = tk.Button(self.root, text="시간 선택 좌표 가져오기", command=self.get_time)
        self.button3.place(x=700, y=550)

        self.button4 = tk.Button(self.root, text="좌석 선택 완료 좌표 가져오기", command=self.select_axis)
        self.button4.place(x=700, y=580)

        self.color_listbox = tk.Listbox(self.root)
        self.color_listbox.place(x=700, y=280)
        self.color_listbox.bind("<ButtonRelease-1>", self.on_listbox_click)

        # 캔버스 생성
        self.color_canvas = tk.Canvas(self.root, width=50, height=30, bg="white")
        self.color_canvas.place(x=700, y=230)

    def start_first_floor(self):
        # 이미 무한 루프가 실행 중인 경우 중복 실행 방지
        if not self.is_running:
            self.is_running = True
            # 무한 루프를 새로운 스레드에서 실행
            threading.Thread(target=self.first_loop).start()

    def start_second_floor(self):
        # 이미 무한 루프가 실행 중인 경우 중복 실행 방지
        if not self.is_running:
            self.is_running = True
            # 무한 루프를 새로운 스레드에서 실행
            threading.Thread(target=self.second_loop).start()

    def stop_infinite_loop(self):
        # 무한 루프 동작을 멈추도록 플래그 설정
        self.is_running = False

    def first_loop(self):
        # 무한 루프
        while self.is_running:
            try:
                print(f"1층 매크로 실행중")
                self.same_rutine()
                time.sleep(2)
                self.search_seat()
            except:
                self.is_running = False
                print("error 발생")
                return

        print("Infinite Loop stopped.")

    def second_loop(self):
        # 무한 루프
        while self.is_running:
            try:
                print(f"2층 매크로 실행중")
                self.same_rutine()
                time.sleep(2)
                self.go_other_floor()
                time.sleep(1)
                self.search_seat()
            except:
                self.is_running = False
                print("error 발생")
                return

        print("Infinite Loop stopped.")

    def get_axis(self):
        while True:
            if keyboard.read_key() == "a":
                left_top = pyautogui.position()
                break

        while True:
            if keyboard.read_key() == "b":
                right_bottom = pyautogui.position()
                break

        self.seat_axis = [left_top, right_bottom]
        print(self.seat_axis)

        self.capture_region(left_top, right_bottom)
        return

    def get_floor_axis(self):
        while True:
            if keyboard.read_key() == "a":
                self.floor_axis = pyautogui.position()
                break
        return

    def capture_region(self, left_top, right_bottom):
        # 캡처하고자 하는 영역 캡처
        captured_image = ImageGrab.grab(bbox=(left_top[0], left_top[1], right_bottom[0], right_bottom[1]))
        captured_image = captured_image.resize((500, 500))

        # Tkinter PhotoImage로 변환
        tk_image = ImageTk.PhotoImage(captured_image)

        # Canvas를 사용하여 이미지 표시
        self.canvas.delete("all")  # 기존에 표시된 이미지 삭제
        self.canvas.create_image(0, 0, anchor=tk.NW, image=tk_image)

        # Canvas 크기 조절
        self.canvas.image_names = tk_image

    def update_listbox(self):
        # 리스트 박스 업데이트
        self.color_listbox.delete(0, tk.END)
        for color in self.seat_class:
            self.color_listbox.insert(tk.END, color)
        return

    def on_listbox_click(self, event):
        selected_index = self.color_listbox.curselection()

        if selected_index:
            selected_color = self.color_listbox.get(selected_index)
            print(f"Selected Color: {selected_color}")
            self.draw_color_rectangle(selected_color)
        return

    def draw_color_rectangle(self, rgb_values):
        # 캔버스 초기화
        self.color_canvas.delete("all")
        # RGB 값을 캔버스에 적용하여 사각형 그리기
        color_hex = "#{:02X}{:02X}{:02X}".format(rgb_values[0], rgb_values[1], rgb_values[2])
        self.color_canvas.create_rectangle(0, 0, 50, 50, fill=color_hex)
        return

    def get_color(self):
        my_class_list = []
        screen = ImageGrab.grab()
        while True:
            if keyboard.read_key() == "a":
                x, y = pyautogui.position()
                rgb = screen.getpixel((x, y))
                my_class_list.append(rgb)
            if keyboard.read_key() == "c":
                self.seat_class = set(my_class_list)
                self.update_listbox()
                break
        return

    def get_time(self):
        while True:
            if keyboard.read_key() == "a":
                self.time_axis = pyautogui.position()
                break

    def select_axis(self):
        while True:
            if keyboard.read_key() == "a":
                self.pay_axis = pyautogui.position()
                break

    def click(self, x, y):
        pyautogui.click(x, y)
        return

    def double_click(self, x, y):
        pyautogui.click(x, y)
        pyautogui.click(x, y)
        return

    def just_move(self, x, y):
        pyautogui.moveTo(x, y)
        return

    def press_up(self):
        pyautogui.press('up')
        return

    def press_down(self):
        pyautogui.press('down')
        return

    def go_other_floor(self):
        self.click(self.floor_axis[0], self.floor_axis[1])
        return

    def same_rutine(self):
        self.double_click(self.time_axis[0], self.time_axis[1])
        self.press_up()
        ttt.sleep(0.5)
        self.press_down()
        return

    def search_seat(self):
        delta_error = 10
        screen = ImageGrab.grab()

        for j in range(self.seat_axis[0][1], self.seat_axis[1][1], 7):
            for i in range(self.seat_axis[0][0], self.seat_axis[1][0], 7):
                # self.just_move(i,j)
                rgb = screen.getpixel((i, j))
                for r, g, b in self.seat_class:
                    if abs(rgb[0]-r) <= delta_error and abs(rgb[1] - g) <= delta_error and abs(rgb[2] - b) <= delta_error:
                        if self.need_seat_cnt == 2:
                            rgb2 = screen.getpixel((i+10, j))
                            for r2, g2, b2 in self.seat_class:
                                if abs(rgb2[0] - r2) <= delta_error and abs(rgb2[1] - g2) <= delta_error and abs(rgb2[2] - b2) <= delta_error:
                                    self.click(i, j)
                                    self.click(i+10, j)
                                    self.click(self.pay_axis[0], self.pay_axis[1])
                                    self.is_running = False
                                    return

                        elif self.need_seat_cnt == 1:
                            self.click(i, j)
                            self.click(self.pay_axis[0], self.pay_axis[1])
                            self.is_running = False
                            return
        return



if __name__ == "__main__":
    root = tk.Tk()
    root.title("please win this war..")
    # 윈도우 크기 고정
    root.geometry("900x700")
    # 윈도우 실행

    app = MacroLoopApp(root)
    root.mainloop()

기존 매크로랑 사용법은 동일하고, 2층/3층 매크로 구동 시 서버 상태 등 잘맞춰서 딜레이 조절하시면 됩니다.

jupyter notebook 이나 pycharm 사용하세요! 

기본 선택 버튼은 마우스 커서를 올려두고 'a' 키 누르시면 됩니다. 버튼 순서대로 따라서 좌표값 입력하세요. 


좌석 영역 선택하기 버튼 : 좌석 좌상단지점 커서 올려두고 'a', 우하단 지점 커서 올려주고 'b' 누르면 직사각형 영역 좌표 저장됨

2/3층 영역 선택하기 버튼 : 2/3층 매크로 돌릴때만 사용하고 2/3층 넘어가는 인터페이스 위에 마우스 올려두고 'a' 누르면 좌표 저장됨

좌석 등급 선택하기 버튼 : 우측 VIP, S, R 이렇게 쓰여있는 좌석 정보 옆에 사각형 색 위에 커서 올리고 'a' 누르면 선택한 좌석들만 탐색 가능함. 종료할 땐 'c' 키 눌러주세요

시간 선택 좌표 가져오기 버튼 : 내가 보고싶은 시간 선택하고 시간 옆에 마우스 올려두고 'a' 키. 아래 예시에서는 14시 30분이라고 쓰여있는 곳에 마우스 올려야함. 

좌석 선택 완료 버튼 : 그냥 아래 버튼위에 마우스 올려놓고 'a' 키

모든 버튼에 대한 좌표값을 다 땄으면 1층 또는 2/3층 매크로 시작 버튼 누르면 됩니다. 종료하고 싶으면 종료 버튼 누르세요.

무단 배포나 공유를 금지하지 않습니다. 널리 알려 이롭게 하세요. 어차피 안쓰면 바보됨

추가적인 질문은 댓글로 ㄱㄱ. 제발 홍광호좀 봅시다 다같이. 전 성공함

 

파이썬코드를 jupyter notebook 이나, pycharm 등 IDE 를 통해 실행시키거나 pyinstaller 와 같은 툴로 실행파일로 변환하여 실행하시면 됩니다. (후자는 비추입니다.)
사람은 기계를 이길 수 없습니다. ㅅㅂ
https://mapled.tistory.com/entry/Python-%EC%A3%BC%ED%94%BC%ED%84%B0-%EB%85%B8%ED%8A%B8%EB%B6%81Jupyter-Notebook-%EC%84%A4%EC%B9%98

 

[Python + Jupyter Notebook] 주피터! 설치부터 실행까지

안녕하세요. 메이플입니다! 오늘은 파이썬을 코딩할 때 많이 사용되는 주피너 노트북에 대해서 설명하고 설치 방법을 알려 드리겠습니다. 0. 주피터 노트북이란? 주피터 노트북(Jupyter Notebook)은

mapled.tistory.com


6월 13일 자로 업데이트 되었습니다.
VIP, R, S, 등 원하는 좌석 등급을 선택할 수 있게 되었습니다.
취케팅 전용입니다. 연석 불가능


빡치시는 분들 많은거같아서 공유함.
실행시 시작 까지 시간이 좀 오래 걸립니다. ( jupyter notebook 이나 파이썬 파일을 실행하면 바로 실행됩니다.)


한놈만 패는 버전으로 돌아왔습니다.
원하는 요일, 시간대 좌석을 하루종일 탐색 할 수 있습니다.


프로그램 실행 후, 원하는 요일과 시간대의 공연정보를 선택해줍니다.
자세한 사용법은 아래 영상을 참고해주세요.


코드 보기. (파이썬)

더보기

코드

import pyautogui
import keyboard
import random
from PIL import ImageGrab
import numpy as np
import time as ttt

def m(a, b, x, y):
    pyautogui.moveTo(dayx, dayy, duration=0.4)
    pyautogui.click(dayx, dayy)
    pyautogui.moveTo(a, b)
    pyautogui.click(a, b)
    pyautogui.moveTo(timex,timey, duration=0.3)
    pyautogui.click(timex, timey)
    pyautogui.moveTo(x, y)
    pyautogui.click(x, y)
    

def main():
       
    print("시간 | 좌석선택완료 버튼 좌표 가져오기\n 마우스 가져다 대고 순서대로 a, b 를 누르면 됨\n")

    while True:
        if keyboard.read_key() == "a":
            xxx, yyy = pyautogui.position()
            break;

    while True:
        if keyboard.read_key() == "b":
            selx, sely = pyautogui.position()
            break;

    print(selx, sely, xxx, yyy)

    print("좌석 캡쳐 영역 잡기 (왼쪽 상단, 오른쪽 하단)\n 마우스 가져다 대고 a, b 순서대로 누르면 됨\n")
    while True:
        if keyboard.read_key() == "a":
            left_top = pyautogui.position()
            break;

    while True:
        if keyboard.read_key() == "b":
            right_bottom = pyautogui.position()
            break;

    print(left_top, right_bottom)

    print("종료는 ctrl + alt + delete 로 빠져나가셈...ㅎㅎ")
    index = 0
    iter_num = 0
    flag = True

    # 좌석 색.
    
    color = []
    
    print( "좌표 색상 저장 , a 저장, c 종료 ")
    while True:
        screen = ImageGrab.grab()
        if keyboard.read_key() == "a":
            x, y = pyautogui.position()
            rgb = screen.getpixel((x, y))
            color.append(rgb)
            print(rgb, "저장 완료")
        if keyboard.read_key() == "c":
            break;

    #좌측상단의 x, 우측하단의 y값을 저장해둔다
    left_top_x = left_top[0]
    right_bottom_y = right_bottom[1]

    #캡쳐 범위의 폭과 높이를 구한다
    capture_width = right_bottom[0]-left_top[0]
    capture_height = right_bottom[1]-left_top[1]

    #좌측상단의 x, 우측하단의 y값을 저장해둔다
    left_top_x = left_top[0]
    right_bottom_y = right_bottom[1]

    #캡쳐 범위의 폭과 높이를 구한다
    capture_width = right_bottom[0]-left_top[0]
    capture_height = right_bottom[1]-left_top[1]


    pyautogui.click(xxx,yyy)
    colorlen = len(color)
    for i in color:
        print(i)
    dif = 10
    
    while flag:

        pyautogui.press('up')
        pyautogui.press('down')

        index = index + 1
        iter_num += 1

        img = ImageGrab.grab()
        for i in range(left_top[0], right_bottom[0], 2):
            if flag == True:
                for j in range(left_top[1], right_bottom[1], 2):
                    rgb = img.getpixel((i,j))
                    if flag == True:
                        for ss in range(colorlen): 
                            if(abs(rgb[0] - color[ss][0]) <= dif and abs(rgb[1] - color[ss][1]) <= dif and abs(rgb[2] - color[ss][2]) <= dif):
                                pyautogui.moveTo(i,j)
                                pyautogui.click(i+1,j+1)
                                pyautogui.moveTo(selx,sely)
                                pyautogui.click(selx,sely)
                                flag = False
                                break

        ttt.sleep(1)

if __name__ == "__main__":
    main()

24/11/22 추가.

현생에 쪼들려서 댓글 확인을 못했습니다. ChatGPT를 기반으로 수정한 코드를 아래에 첨부합니다.

더보기
import tkinter as tk
import pyautogui
import keyboard
import random
from PIL import ImageGrab, Image, ImageTk
import threading
import time


class MacroLoopApp:
    def __init__(self, root):
        self.root = root

        # 상태 플래그
        self.is_running = False

        # 설정값 저장
        self.seat_axis = []
        self.seat_class = set()
        self.time_axis = []
        self.pay_axis = []
        self.floor_axis = []
        self.need_seat_cnt = 2  # 연석인 경우 2

        # 버튼 생성
        self.create_buttons()

        # 캔버스 생성
        self.canvas = tk.Canvas(self.root, width=500, height=500)
        self.canvas.place(x=100, y=100)

        # 색상 미리보기 캔버스
        self.color_canvas = tk.Canvas(self.root, width=50, height=30, bg="white")
        self.color_canvas.place(x=700, y=230)

        # 색상 리스트박스
        self.color_listbox = tk.Listbox(self.root)
        self.color_listbox.place(x=700, y=280)
        self.color_listbox.bind("<ButtonRelease-1>", self.on_listbox_click)

    def create_buttons(self):
        """버튼을 생성하고 배치하는 메서드"""
        buttons = [
            ("1층 매크로 시작", self.start_first_floor, 120),
            ("2/3층 매크로 시작", self.start_second_floor, 150),
            ("매크로 중지", self.stop_infinite_loop, 180),
            ("좌석 영역 선택하기", self.get_axis, 460),
            ("2/3층 영역 선택하기", self.get_floor_axis, 490),
            ("좌석 등급 선택하기", self.get_color, 520),
            ("시간 선택 좌표 가져오기", self.get_time, 550),
            ("좌석 선택 완료 좌표 가져오기", self.select_axis, 580),
        ]

        for text, command, y in buttons:
            tk.Button(self.root, text=text, command=command).place(x=700, y=y)

    def start_floor_loop(self, floor_function):
        """층별 루프를 시작하는 메서드"""
        if not self.is_running:
            self.is_running = True
            threading.Thread(target=floor_function).start()

    def start_first_floor(self):
        self.start_floor_loop(self.first_loop)

    def start_second_floor(self):
        self.start_floor_loop(self.second_loop)

    def stop_infinite_loop(self):
        """루프 중지"""
        self.is_running = False

    def first_loop(self):
        self.run_macro(self.search_seat)

    def second_loop(self):
        self.run_macro(lambda: (self.go_other_floor(), self.search_seat()))

    def run_macro(self, search_function):
        """공통 매크로 실행 루프"""
        while self.is_running:
            try:
                print("매크로 실행 중")
                self.same_routine()
                time.sleep(2)
                search_function()
            except Exception as e:
                self.is_running = False
                print(f"Error 발생: {e}")
                return
        print("Infinite Loop stopped.")

    def get_position(self, key="a"):
        """키 입력으로 위치를 받아오는 메서드"""
        while True:
            if keyboard.read_key() == key:
                return pyautogui.position()

    def get_axis(self):
        """좌석 영역 선택"""
        left_top = self.get_position("a")
        right_bottom = self.get_position("b")
        self.seat_axis = [left_top, right_bottom]
        print(self.seat_axis)
        self.capture_region(left_top, right_bottom)

    def get_floor_axis(self):
        """층 이동 버튼 좌표 선택"""
        self.floor_axis = self.get_position()

    def capture_region(self, left_top, right_bottom):
        """선택한 영역을 캡처하고 캔버스에 표시"""
        captured_image = ImageGrab.grab(bbox=(left_top[0], left_top[1], right_bottom[0], right_bottom[1]))
        captured_image = captured_image.resize((500, 500))
        tk_image = ImageTk.PhotoImage(captured_image)
        self.canvas.delete("all")
        self.canvas.create_image(0, 0, anchor=tk.NW, image=tk_image)
        self.canvas.image_names = tk_image

    def update_listbox(self):
        """리스트 박스 업데이트"""
        self.color_listbox.delete(0, tk.END)
        for color in self.seat_class:
            self.color_listbox.insert(tk.END, color)

    def on_listbox_click(self, event):
        """리스트박스 클릭 이벤트 처리"""
        selected_index = self.color_listbox.curselection()
        if selected_index:
            selected_color = self.color_listbox.get(selected_index)
            print(f"Selected Color: {selected_color}")
            self.draw_color_rectangle(selected_color)

    def draw_color_rectangle(self, rgb_values):
        """선택된 색상을 캔버스에 표시"""
        self.color_canvas.delete("all")
        color_hex = "#{:02X}{:02X}{:02X}".format(rgb_values[0], rgb_values[1], rgb_values[2])
        self.color_canvas.create_rectangle(0, 0, 50, 50, fill=color_hex)

    def get_color(self):
        """좌석 등급 색상 선택"""
        screen = ImageGrab.grab()
        my_class_list = []
        while True:
            if keyboard.read_key() == "a":
                x, y = pyautogui.position()
                rgb = screen.getpixel((x, y))
                my_class_list.append(rgb)
            if keyboard.read_key() == "c":
                self.seat_class = set(my_class_list)
                self.update_listbox()
                break

    def get_time(self):
        """시간 선택 좌표 가져오기"""
        self.time_axis = self.get_position()

    def select_axis(self):
        """좌석 선택 완료 좌표 가져오기"""
        self.pay_axis = self.get_position()

    def click(self, x, y):
        pyautogui.click(x, y)

    def double_click(self, x, y):
        pyautogui.doubleClick(x, y)

    def press_key(self, key):
        pyautogui.press(key)

    def go_other_floor(self):
        self.click(*self.floor_axis)

    def same_routine(self):
        """공통 루틴 실행"""
        self.double_click(*self.time_axis)
        self.press_key('up')
        time.sleep(0.5)
        self.press_key('down')

    def search_seat(self):
        """좌석 검색"""
        delta_error = 10
        screen = ImageGrab.grab()
        for j in range(self.seat_axis[0][1], self.seat_axis[1][1], 7):
            for i in range(self.seat_axis[0][0], self.seat_axis[1][0], 7):
                rgb = screen.getpixel((i, j))
                for r, g, b in self.seat_class:
                    if all(abs(rgb[k] - color) <= delta_error for k, color in enumerate((r, g, b))):
                        if self.need_seat_cnt == 2:
                            rgb2 = screen.getpixel((i + 10, j))
                            if all(abs(rgb2[k] - color) <= delta_error for k, color in enumerate((r, g, b))):
                                self.click(i, j)
                                self.click(i + 10, j)
                                self.click(*self.pay_axis)
                                self.is_running = False
                                return
                        elif self.need_seat_cnt == 1:
                            self.click(i, j)
                            self.click(*self.pay_axis)
                            self.is_running = False
                            return


if __name__ == "__main__":
    root = tk.Tk()
    root.title("please win this war..")
    root.geometry("900x700")
    app = MacroLoopApp(root)
    root.mainloop()

 

반응형

'일상' 카테고리의 다른 글

하.. 드디어 데스노트 봄  (0) 2022.05.21
왕십리제일곱창 왕십리역 맛집  (1) 2022.02.27
몽탄에 가다. 삼각지 역 맛집  (0) 2022.02.10
야스노야 남영역 주변 맛집  (0) 2022.01.08
청량리 원조 남원통닭  (0) 2021.10.21