Загрузка данных


import pyautogui
import keyboard
import time
import math
import threading

class ParkourBot:
    def __init__(self):
        self.running = False
        self.block_found = False
        self.current_pitch = 0  # Угол наклона головы (вверх/вниз)
        self.min_pitch = -30  # Минимальный наклон вниз
        self.max_pitch = 0    # Максимальный наклон (прямо)
        self.sensitivity = 0.5
        self.scan_speed = 5  # Скорость сканирования
        
        # Цвета блоков для детекции (нужно настроить под ваш сервер)
        self.block_colors = [
            (210, 180, 140),  # Песчаник
            (160, 160, 160),  # Камень
            (200, 200, 200),  # Белый бетон
        ]
        
    def find_block(self):
        """Сканирует экран на наличие блока"""
        screenshot = pyautogui.screenshot()
        width, height = screenshot.size
        
        # Центральная область для поиска
        center_x = width // 2
        center_y = height // 2
        search_area = 100  # Радиус поиска
        
        for y in range(center_y - search_area, center_y + search_area, 10):
            for x in range(center_x - search_area, center_x + search_area, 10):
                pixel = screenshot.getpixel((x, y))
                
                # Проверяем, похож ли цвет на цвет блока
                for block_color in self.block_colors:
                    if self.color_similar(pixel, block_color, 30):
                        return True, (x, y)
        
        return False, None
    
    def color_similar(self, color1, color2, tolerance):
        """Проверяет схожесть цветов"""
        return (abs(color1[0] - color2[0]) < tolerance and
                abs(color1[1] - color2[1]) < tolerance and
                abs(color1[2] - color2[2]) < tolerance)
    
    def rotate_head_horizontal(self):
        """Поворот головы по горизонтали на 360 градусов"""
        print("Сканирование по горизонтали...")
        steps = 360 // self.scan_speed
        
        for i in range(steps):
            if not self.running:
                break
            
            pyautogui.moveRel(10, 0, duration=0.05)  # Двигаем мышь вправо
            time.sleep(0.01)
            
            # Проверяем, нашли ли блок
            found, _ = self.find_block()
            if found:
                self.block_found = True
                return True
        
        return False
    
    def look_down(self):
        """Опускает голову немного вниз"""
        self.current_pitch = max(self.current_pitch - 2, self.min_pitch)
        pyautogui.moveRel(0, 2, duration=0.1)  # Двигаем мышь вниз
        print(f"Наклон головы: {self.current_pitch}°")
    
    def reset_head_position(self):
        """Возвращает голову в исходное положение"""
        pyautogui.moveRel(0, -self.current_pitch, duration=0.2)
        self.current_pitch = 0
    
    def calculate_jump(self, block_pos):
        """Рассчитывает тип прыжка в зависимости от высоты блока"""
        screen_center_y = pyautogui.size()[1] // 2
        block_y = block_pos[1]
        
        # Определяем высоту блока относительно центра экрана
        height_diff = screen_center_y - block_y
        
        if height_diff > 150:  # Блок высоко - сильный прыжок
            return "high_jump"
        elif height_diff > 50:  # Блок на средней высоте
            return "medium_jump"
        else:  # Блок на уровне или ниже
            return "low_jump"
    
    def perform_jump(self, jump_type):
        """Выполняет прыжок в зависимости от типа"""
        print(f"Выполняю прыжок: {jump_type}")
        
        # Подготовка к прыжку
        keyboard.press('w')  # Движение вперед
        time.sleep(0.05)
        
        if jump_type == "high_jump":
            # Сильный прыжок с разбега
            keyboard.press('space')
            time.sleep(0.1)
            keyboard.release('space')
            time.sleep(0.05)
            keyboard.press('space')  # Двойной прыжок если нужно
            
        elif jump_type == "medium_jump":
            # Обычный прыжок
            keyboard.press('space')
            time.sleep(0.1)
            
        else:  # low_jump
            # Легкий прыжок
            keyboard.press('space')
            time.sleep(0.05)
        
        keyboard.release('space')
        time.sleep(0.2)
        keyboard.release('w')
    
    def parkour_cycle(self):
        """Основной цикл паркура"""
        print("Начинаю паркур...")
        
        while self.running:
            # Проверяем наличие блока перед собой
            found, block_pos = self.find_block()
            
            if found:
                print("Блок найден!")
                self.block_found = True
                
                # Рассчитываем и выполняем прыжок
                jump_type = self.calculate_jump(block_pos)
                self.perform_jump(jump_type)
                
                # Небольшая пауза после прыжка
                time.sleep(0.3)
                self.block_found = False
                
            else:
                print("Блок не найден, сканирую...")
                
                # Пробуем найти блок, вращая голову
                if not self.rotate_head_horizontal():
                    # Если не нашли после полного оборота, опускаем голову
                    self.look_down()
                    
                    # Если голова слишком низко, возвращаем в исходное
                    if self.current_pitch <= self.min_pitch:
                        self.reset_head_position()
                
                time.sleep(0.1)
    
    def start(self):
        """Запуск бота"""
        self.running = True
        print("Бот паркура запущен!")
        print("Нажмите 'P' для паузы/продолжения")
        print("Нажмите 'ESC' для остановки")
        
        # Запускаем основной цикл в отдельном потоке
        bot_thread = threading.Thread(target=self.parkour_cycle)
        bot_thread.daemon = True
        bot_thread.start()
        
        # Ожидаем команды пользователя
        while True:
            if keyboard.is_pressed('esc'):
                self.running = False
                print("Бот остановлен!")
                break
            elif keyboard.is_pressed('p'):
                self.running = not self.running
                state = "продолжен" if self.running else "приостановлен"
                print(f"Бот {state}")
                time.sleep(0.3)  # Защита от двойного нажатия
            
            time.sleep(0.1)

# Улучшенная версия с определением блоков по текстуре
class AdvancedParkourBot(ParkourBot):
    def __init__(self):
        super().__init__()
        # Добавляем дополнительные параметры для продвинутого определения блоков
        
    def detect_block_edge(self):
        """Определяет край блока для точного позиционирования"""
        screenshot = pyautogui.screenshot()
        width, height = screenshot.size
        
        center_x = width // 2
        center_y = height // 2
        
        # Ищем резкие переходы цвета (края блоков)
        for x in range(center_x - 50, center_x + 50, 5):
            pixel1 = screenshot.getpixel((x, center_y))
            pixel2 = screenshot.getpixel((x + 5, center_y))
            
            if self.color_similar(pixel1, pixel2, 10) == False:
                return True, x
        
        return False, None

# Основная программа
if __name__ == "__main__":
    print("=== Бот для паркура в Minecraft ===")
    print("\nИнструкция:")
    print("1. Встаньте в ровную позу перед началом паркура")
    print("2. Убедитесь, что окно Minecraft активно")
    print("3. Настройте чувствительность мыши в игре на минимум")
    print("4. Запустите программу и нажмите клавиши управления")
    print("\nВыберите режим:")
    print("1 - Базовый режим")
    print("2 - Продвинутый режим")
    
    choice = input("\nВаш выбор (1/2): ")
    
    if choice == "2":
        bot = AdvancedParkourBot()
    else:
        bot = ParkourBot()
    
    # Даем время переключиться на окно Minecraft
    print("Программа запустится через 3 секунды...")
    time.sleep(3)
    
    # Запускаем бота
    bot.start()