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


import keyboard
import time
import threading
import pyautogui
import json
import os
import traceback

try:
    import win32api
    import win32con
    DIRECT_INPUT = True
except ImportError:
    DIRECT_INPUT = False

class ParkourBot:
    def __init__(self):
        self.running = False
        self.paused = False
        self.current_pitch = 0
        
        self.timings = {
            'jump_delay': 0.1,
            'jump_hold': 0.15,
            'first_w_time': 0.15,
            'w_press_gap': 0.05,
            'second_w_time': 0.1,
            'post_jump_forward': 0.2,
            'camera_up_angle': 5,
            'landing_delay': 0.5,
            'color_tolerance': 15,
            'scan_speed': 0.02,
            'scan_step': 10,
            'resume_delay': 0.3,
        }
        
        self.block_colors = [
            (255, 23, 23), (255, 29, 30), (188, 17, 18), (196, 17, 18),
            (240, 20, 20), (250, 25, 25), (200, 20, 20), (180, 15, 15),
        ]
        
        self.load_settings()
    
    def load_settings(self):
        try:
            if os.path.exists('parkour_settings.json'):
                with open('parkour_settings.json', 'r') as f:
                    saved = json.load(f)
                    for key in self.timings:
                        if key in saved:
                            self.timings[key] = saved[key]
                print("Настройки загружены")
        except:
            print("Стандартные настройки")
    
    def save_settings(self):
        try:
            with open('parkour_settings.json', 'w') as f:
                json.dump(self.timings, f, indent=4)
            print("Настройки сохранены")
        except:
            print("Не удалось сохранить")
    
    def move_mouse(self, dx, dy):
        try:
            if DIRECT_INPUT:
                win32api.mouse_event(win32con.MOUSEEVENTF_MOVE, int(dx), int(dy), 0, 0)
        except:
            pass
    
    def find_block(self):
        try:
            img = pyautogui.screenshot()
            px = img.getpixel((img.size[0]//2, img.size[1]//2))
            tolerance = self.timings['color_tolerance']
            max_diff = 255 * 3 * tolerance / 100
            
            for color in self.block_colors:
                diff = abs(px[0]-color[0]) + abs(px[1]-color[1]) + abs(px[2]-color[2])
                if diff <= max_diff:
                    return True
            return False
        except:
            return False
    
    def do_sprint(self):
        keyboard.press('w')
        time.sleep(self.timings['first_w_time'])
        keyboard.release('w')
        time.sleep(self.timings['w_press_gap'])
        keyboard.press('w')
        time.sleep(self.timings['second_w_time'])
    
    def do_jump(self):
        self.move_mouse(0, -self.timings['camera_up_angle'])
        time.sleep(0.05)
        
        keyboard.press('space')
        time.sleep(self.timings['jump_hold'])
        keyboard.release('space')
        
        self.move_mouse(0, self.timings['camera_up_angle'])
        time.sleep(self.timings['post_jump_forward'])
        keyboard.release('w')
        time.sleep(self.timings['landing_delay'])
    
    def loop(self):
        while self.running:
            if self.paused:
                time.sleep(0.1)
                continue
            
            if self.find_block():
                print("Блок найден!")
                self.do_sprint()
                self.do_jump()
                time.sleep(self.timings['resume_delay'])
            else:
                for _ in range(18):
                    if not self.running or self.paused:
                        break
                    self.move_mouse(self.timings['scan_step'], 0)
                    time.sleep(self.timings['scan_speed'])
                    if self.find_block():
                        self.do_sprint()
                        self.do_jump()
                        break
                else:
                    if self.current_pitch < 15:
                        self.move_mouse(0, 2)
                        self.current_pitch += 2
                    else:
                        self.move_mouse(0, -15)
                        self.current_pitch = 0
                
                time.sleep(0.05)
    
    def start(self):
        print("=" * 40)
        print("БОТ ПАРКУРА MINECRAFT")
        print("=" * 40)
        print("F8 - пауза | F9 - стоп")
        print("=" * 40)
        
        self.running = True
        threading.Thread(target=self.loop, daemon=True).start()
        
        f8 = False
        while self.running:
            if keyboard.is_pressed('F8'):
                if not f8:
                    f8 = True
                    self.paused = not self.paused
                    if self.paused:
                        print("ПАУЗА")
                        keyboard.release('w')
                        keyboard.release('space')
                    else:
                        print("ПРОДОЛЖЕНИЕ")
            else:
                f8 = False
            
            if keyboard.is_pressed('F9'):
                self.running = False
                break
            
            time.sleep(0.05)
        
        keyboard.release('w')
        keyboard.release('space')
        print("Бот остановлен")

if __name__ == "__main__":
    print("Бот паркура Minecraft")
    print("Нужен запуск от администратора!")
    print("Чувствительность мыши в игре = 0%")
    print("Оконный режим")
    
    input("Нажмите Enter для запуска...")
    
    bot = ParkourBot()
    bot.save_settings()
    bot.start()