diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..a1b3471 --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +TOGGLE_HOTKEY=f6 +#TOGGLE_HOTKEY=alt+f6 diff --git a/README.md b/README.md index f48edf5..823cd53 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,13 @@ # PerfectKachalka -Бот для мини-игры со шкалой навыка (skill-check): синяя полупрозрачная шкала -с движущимся курсором и двумя цветными зонами. Бот распознаёт шкалу, зону и -курсор по экрану и нажимает `E` в нужный момент. +## Установка -## Требования - -- Игра запущена в режиме **Exclusive Fullscreen** (не оконный безрамочный) - - это нужно для `bettercam`, который умеет захватывать такой режим. -- Зависимости уже установлены в `.venv` (`opencv-python`, `numpy`, - `bettercam`, `pydirectinput`, `keyboard`, `mss`). При необходимости - переустановить: `.venv\Scripts\python.exe -m pip install -r requirements.txt`. - -## Проверка детекции (опционально, но рекомендуется) - -``` -.venv\Scripts\python.exe debug_snapshot.py +```bash +python -m venv venv +.venv\Scripts\python.exe -m pip install -r requirements.txt +cp .env.example .env ``` -- Скрипт ждёт 5 секунд - успейте переключиться в игру так, чтобы шкала - мини-игры была видна на экране. -- После снимка он напечатает найденные координаты шкалы/зоны/курсора и - сохранит `debug_snapshot.png` с нарисованными рамками: синяя рамка - шкала, - красная - узкая (целевая) зона, пурпурная линия - курсор. -- Если что-то не нашлось, скрипт сохранит `debug_full.png` (полный кадр без - рамок) - по нему можно подправить пороги в `config.py`. ## Запуск бота @@ -41,6 +24,22 @@ не видна). - **Ctrl+C** в консоли - полностью завершить программу. + +## Проверка детекции (опционально) + +``` +.venv\Scripts\python.exe debug_snapshot.py +``` + +- Скрипт ждёт 5 секунд - успейте переключиться в игру так, чтобы шкала + мини-игры была видна на экране. +- После снимка он напечатает найденные координаты шкалы/зоны/курсора и + сохранит `debug_snapshot.png` с нарисованными рамками: синяя рамка - шкала, + красная - узкая (целевая) зона, пурпурная линия - курсор. +- Если что-то не нашлось, скрипт сохранит `debug_full.png` (полный кадр без + рамок) - по нему можно подправить пороги в `config.py`. + + ## Если игра запущена с правами администратора `pydirectinput` может не достучаться до окна игры из-за защиты Windows @@ -64,14 +63,3 @@ потребуется сглаживание скорости курсора (сообщите, чтобы добавить). Изменения в `config.py` применяются после перезапуска `bot.py`. - -## Структура проекта - -- `bot.py` - основной цикл: поиск шкалы, отслеживание курсора, нажатие `E`, - переключение по F6. -- `vision.py` - распознавание шкалы/зон/курсора по кадру (OpenCV/HSV). -- `capture.py` - захват экрана (`bettercam`, с откатом на `mss`). -- `input_sender.py` - отправка нажатия клавиши (`pydirectinput`). -- `config.py` - все настраиваемые пороги и параметры. -- `debug_snapshot.py` - однократный снимок экрана с визуализацией найденных - шкалы/зоны/курсора, для отладки. diff --git a/bot.py b/bot.py index da7f9a6..b1736a2 100644 --- a/bot.py +++ b/bot.py @@ -1,3 +1,5 @@ +import sys +import threading import time import keyboard @@ -7,6 +9,17 @@ import vision from capture import ScreenCapture from input_sender import press_action_key +if sys.platform == "win32": + import winsound + + def _play_sound(frequency, duration_ms): + threading.Thread(target=winsound.Beep, args=(frequency, duration_ms), daemon=True).start() +else: + def _play_sound(frequency, duration_ms): + # На Linux/macOS нет аналога winsound.Beep без доп. зависимостей - + # используем системный звуковой сигнал терминала (BEL). + print("\a", end="", flush=True) + class Bot: def __init__(self): @@ -22,7 +35,10 @@ class Bot: def toggle(self): self.enabled = not self.enabled print(f"[Bot] {'ВКЛЮЧЕН' if self.enabled else 'выключен'}") - if not self.enabled: + if self.enabled: + _play_sound(config.SOUND_ON_FREQ, config.SOUND_DURATION_MS) + else: + _play_sound(config.SOUND_OFF_FREQ, config.SOUND_DURATION_MS) self.bar_bbox = None self.was_in_zone = False self.prev_cursor_x = None diff --git a/config.py b/config.py index 54de0ac..60c0eeb 100644 --- a/config.py +++ b/config.py @@ -1,5 +1,13 @@ -# Горячая клавиша вкл/выкл бота -TOGGLE_HOTKEY = "f6" +import os + +from dotenv import load_dotenv + +load_dotenv() + +# Горячая клавиша вкл/выкл бота. Можно задать комбинацию с модификатором, +# например "ctrl+f6", "alt+f6", "ctrl+alt+f6" (синтаксис библиотеки keyboard). +# Значение задаётся в .env (TOGGLE_HOTKEY) для удобной подстройки без правки кода. +TOGGLE_HOTKEY = os.getenv("TOGGLE_HOTKEY", "f6") # Клавиша, которую бот нажимает при попадании курсора в узкую (целевую) зону ACTION_KEY = "e" @@ -40,6 +48,12 @@ LOCATE_RETRY_INTERVAL = 1 # После скольких подряд неудачных кадров считать, что шкала исчезла, и искать заново MAX_TRACK_MISSES = 30 +# Звуковой сигнал при включении/выключении бота по горячей клавише +# (частота в Гц, длительность в мс) +SOUND_ON_FREQ = 880 +SOUND_OFF_FREQ = 440 +SOUND_DURATION_MS = 150 + # Целевая частота опроса в режиме отслеживания курсора (кадров/сек) TRACK_FPS = 60 @@ -50,4 +64,4 @@ TRACK_FPS = 60 # принимается по предсказанной позиции = текущая + скорость * это время. # Увеличивайте, если нажатие происходит позже, чем нужно; уменьшайте/обнулите, # если нажатие происходит раньше входа в зону. -CURSOR_LEAD_TIME = 0.10 \ No newline at end of file +CURSOR_LEAD_TIME = 0.10 diff --git a/requirements.txt b/requirements.txt index 86fac20..f0529d0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,5 @@ numpy bettercam pydirectinput keyboard -mss \ No newline at end of file +mss +python-dotenv \ No newline at end of file