![]() |
Всем привет, недавно меня подцепил снова Skyrim и решил для него написать скриптики на Python. Для начала решил написать скрипт, который будет бегать за меня из точки А в точку Б. Пол дня проебал, дабы выяснить как работать с памятью, искал сами адреса памяти для скайрима через Cheat Engine, потом выяснил, что после перезахода всё адреса памяти меняются. Крч не суть.
Написав, что то адекватное ( как мне казалось ) я решил протестить, но кнч столкнулся с багами. Выставив координаты по которым нужно бежать персонажу, запустив скрипт, понял, что он просто не добегает до нужной точки. Думал-думал как пофиксить и крч никак не получилось. Кто в целом сможет мне помочь буду сильно Вам благодарен. Код: [CODE] # ================================================ # ИМПООООООРТ # ================================================ import math import time import threading from threading import Thread from typing import Optional , Tuple import cv2 import keyboard import numpy as np import pydirectinput import pymem import pygetwindow as gw import win32gui from mss import mss # ================================================ # КОНФИГУРАЦИЯ (Можно вообще добавить темку, что он сам дедектит из оффсета нужный адрес памяти) # ================================================ MEMORY_ADDRESSES = { 'coord_x' : 0x248C1A7D4E4 , 'coord_y' : 0x248C1A7D4E8 , 'coord_z' : 0x248C1A7D4EC , # TODO: Добавить адрес для угла камеры } CONFIG = { 'position_epsilon' : 2.0 , # Радиус достижения цели 'stuck_threshold' : 0.1 , # Порог обнаружения застревания 'stuck_attempts' : 10 , # Количество проверок для обнаружения застревания 'polling_interval' : 0.05 , # Интервал обновления управления (сек) 'turn_speed' : 0.25 , # Чувствительность поворота 'status_update_interval' : 1 # Интервал обновления координат (сек) } # ================================================ # КЛАСС ДЛЯ РАБОТЫ С ПАМЯТЬЮ # ================================================ class MemoryReader : def __init__ ( self ) : self . _process_handler = None self . _connect ( ) def _connect ( self ) - > bool : """Подключение к процессу игры""" try : self . _process_handler = pymem . Pymem ( "SkyrimSE.exe" ) ( "Успешное подключение к процессу" ) return True except pymem . exception . ProcessNotFound : ( "Ошибка: Процесс SkyrimSE.exe не найден" ) return False except Exception as e : ( f"Критическая ошибка подключения:{str(e)}" ) return False def read_position ( self ) - > Optional [ Tuple [ float , float , float ] ] : """Чтение координат из памяти игры""" if not self . _process_handler : return None try : return ( self . _process_handler . read_float ( MEMORY_ADDRESSES [ 'coord_x' ] ) , self . _process_handler . read_float ( MEMORY_ADDRESSES [ 'coord_y' ] ) , self . _process_handler . read_float ( MEMORY_ADDRESSES [ 'coord_z' ] ) ) except pymem . exception . MemoryReadError : ( "Ошибка чтения памяти: возможно, неверные адреса" ) return None except Exception as e : ( f"Неизвестная ошибка при чтении памяти:{str(e)}" ) return None # ================================================ # ОСНОВНОЙ КЛАСС АВТОПЕРЕДВИЖЕНИЯ # ================================================ class AutoWalker : def __init__ ( self ) : self . memory = MemoryReader ( ) self . target_position = ( 0.0 , 0.0 , 0.0 ) self . is_running = False self . _exit_flag = False self . _movement_thread = None self . _current_camera_angle = 0.0 # TODO: Реализовать чтение угла камеры def _calculate_target_angle ( self , current_pos : Tuple [ float , float ] ) - > float : """Вычисление угла до цели в градусах""" dx = self . target_position [ 0 ] - current_pos [ 0 ] dy = self . target_position [ 1 ] - current_pos [ 1 ] return math . degrees ( math . atan2 ( dy , dx ) ) def _handle_stuck ( self ) : """Алгоритм выхода из застревания""" pydirectinput . keyUp ( 'w' ) # Прыжок + кратковременное движение назад pydirectinput . press ( 'space' ) pydirectinput . keyDown ( 's' ) time . sleep ( 0.3 ) pydirectinput . keyUp ( 's' ) time . sleep ( 0.2 ) pydirectinput . keyDown ( 'w' ) def _movement_loop ( self ) : """Основной цикл управления движением""" last_position = ( 0.0 , 0.0 , 0.0 ) stuck_counter = 0 while self . is_running and not self . _exit_flag : # Получение текущих координат current_pos = self . memory . read_position ( ) if not current_pos or None in current_pos : time . sleep ( 1 ) continue # Обнаружение застревания if math . dist ( current_pos , last_position ) CONFIG [ 'stuck_attempts' ] : self . _handle_stuck ( ) stuck_counter = 0 else : stuck_counter = 0 last_position = current_pos # Вычисление углов target_angle = self . _calculate_target_angle ( current_pos [ : 2 ] ) angle_diff = ( target_angle - self . _current_camera_angle + 180 ) % 360 - 180 # Поворот камеры if abs ( angle_diff ) > 2 : mouse_move = int ( angle_diff * CONFIG [ 'turn_speed' ] ) pydirectinput . moveRel ( mouse_move , 0 , relative = True ) # Движение вперед pydirectinput . keyDown ( 'w' ) # Проверка достижения цели if math . dist ( current_pos [ : 2 ] , self . target_position [ : 2 ] ) Видео работы: |
| Время: 16:30 |