다른 방식의 매크로 만들기가 궁금하다면 ??
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층에서 좌석 선택 가능합니다.)
코드에서 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
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 |