-
Автор темы
- #1
Хайоу, сегодня я покажу как можно довольно быстро и просто сделать 3D боксы на Python.
Шаг №1 "Установка Python":
Для начала нам необходимо установить интерпретатор Python'а, для этого переходим на официальный сайт языка:
Качаем установщик интерпретатора последней версии, для этого наводим мышь на "Downloads" и нажимаем кнопку "Python 3.10.X".
Запускаем установщик и обязательно нажимаем флаг "Add to PATH" если вы не хотите потом вручную ебаться с изменением системных переменных среды.
Шаг №2 "Установка необходимых модулей и библиотек":
Итак, если первый шаг прошел без проблем, то мы можем открыть консоль и написать команду "pip".
Если вывод консоли не пуст, то все выполнено правильно, вывод должен выглядеть подобным образом:
pip - пакетный менеджер языка Python, он нужен нам для загрузки внешних модулей и библиотек.
Нам понадобится 3 внешних модуля для создания нашего чита:
Также есть возможность скачать несколько модулей за раз, для этого их просто нужно разделить пробелами.
P.S. у меня уже установлены модули, у вас должна будет появиться шкала прогресса и вывод о успешной установки.
Шаг №3 "Написание кода":
После того, как интерпретатор и библиотеки установлены может перейти к написанию кода.
Напишем код в файл содержащий основные функции нашего чита "logic.py":
Напишем код с самим читом, включающий ф-ии файла logic.py "main.py":
Основные идеи и релизация расписаны в комментариях, если вам нужно больше подробностей по работе pyextoverlay или pymemoryapi - вы можете найти информацию тут:
Шаг №4 "Запуск чита:
Тут все довольно просто. Вариантов запуска нашего чита несколько.
1. Мы можем запустать наш main.py как обычный исполняемый файл просто нажав по нему 2 раза лкм.
2. Можно запустить скрипт напрямую через интерпретатор, для этого нужно открыть консоль и написать там: python <название файла>.
P.S. Важно чтобы игра была запущена в полном окне без рамок. Боксы будут вести себя неправильно при неполном экране, чтобы это починить нужно менять положение оверлея в точности под положение окна игры.
Пишите ваши мысли, задавайте вопросы (буду пытаться отвечать).
Наш дискорд сервер:
Мой дискорд: Xenely#7771
Шаг №1 "Установка Python":
Для начала нам необходимо установить интерпретатор Python'а, для этого переходим на официальный сайт языка:
Пожалуйста, авторизуйтесь для просмотра ссылки.
Качаем установщик интерпретатора последней версии, для этого наводим мышь на "Downloads" и нажимаем кнопку "Python 3.10.X".
Шаг №2 "Установка необходимых модулей и библиотек":
Итак, если первый шаг прошел без проблем, то мы можем открыть консоль и написать команду "pip".
Если вывод консоли не пуст, то все выполнено правильно, вывод должен выглядеть подобным образом:
pip - пакетный менеджер языка Python, он нужен нам для загрузки внешних модулей и библиотек.
Нам понадобится 3 внешних модуля для создания нашего чита:
- pymemoryapi - модуль для работы с памятью процесса.
- pyextoverlay - модуль для создания оверлея и рисовки самих ESP.
- request - модуль для GET и POST запросов. Через него мы будет получать оффсеты.
Также есть возможность скачать несколько модулей за раз, для этого их просто нужно разделить пробелами.
Шаг №3 "Написание кода":
После того, как интерпретатор и библиотеки установлены может перейти к написанию кода.
Напишем код в файл содержащий основные функции нашего чита "logic.py":
logic.py:
import ctypes
def get_window_geometry(window_name: str) -> tuple:
"""Получает положение и размер окна по назавнию.
Возвращает кортеж. (x, y, w, h), содержащий информацию о положении и размере окна."""
ctypes.windll.user32.SetProcessDPIAware()
hwnd = ctypes.windll.user32.FindWindowW(0, window_name)
rect = ctypes.wintypes.RECT()
ctypes.windll.user32.GetWindowRect(hwnd, ctypes.pointer(rect))
return (rect.left, rect.top, rect.right, rect.bottom)
def get_view_matrix(process: object, base_module: int, view_matrix_offset: int) -> list:
"""Получает видовую матрицу.
Возвращает список видовой матрицы, содержащий 16 float чисел."""
matrix = []
for i in range(16):
matrix.append(process.read_float(base_module + view_matrix_offset + 4 * i))
return matrix
def world_to_screen(view_matrix: list, screen_size: tuple, x: float, y: float, z: float) -> tuple:
"""Транслирует координаты объекта в экранные координаты.
Возвращает кортеж (x, y), содержащий координаты объекта на плоскости монитора."""
screen_w = (view_matrix[12] * x) + (view_matrix[13] * y) + (view_matrix[14] * z) + view_matrix[15]
if screen_w > 0.001:
screen_x = (view_matrix[0] * x) + (view_matrix[1] * y) + (view_matrix[2] * z) + view_matrix[3]
screen_y = (view_matrix[4] * x) + (view_matrix[5] * y) + (view_matrix[6] * z) + view_matrix[7]
camera_x = screen_size[0] // 2
camera_y = screen_size[1] // 2
return(camera_x + (camera_x * screen_x // screen_w), camera_y - (camera_y * screen_y // screen_w))
main.py:
import pymemoryapi
import threading
import requests
import time
from logic import *
from pyextoverlay import *
# Получение оффсетов.
offsets = requests.get("https://raw.githubusercontent.com/frk1/hazedumper/master/csgo.json").json()
dwViewMatrix = int(offsets['signatures']['dwViewMatrix'])
dwLocalPlayer = int(offsets['signatures']['dwLocalPlayer'])
dwEntityList = int(offsets['signatures']["dwEntityList"])
m_vecOrigin = int(offsets['netvars']['m_vecOrigin'])
m_iTeamNum = int(offsets['netvars']['m_iTeamNum'])
m_bDormant = int(offsets['signatures']['m_bDormant'])
m_iHealth = int(offsets['netvars']['m_iHealth'])
# Подключение к процессу и работа с ним.
process = pymemoryapi.Process(process_name="csgo.exe")
base_module = process.get_module_info("client.dll").BaseAddress
# Инициализация и запуск оверлея.
application = application_init()
# 1000 / 17 = ~58.8235 fps
overlay = Overlay(17)
overlay.showFullScreen()
overlay.show()
# Ф-ия - поток ESP
def esp() -> None:
"""Ф-ия ESP (должна вызываться в новом потоке)."""
print("Запуск ESP.")
# настройки ESP (RGB цвет, толщина линий бокса).
box_color = (0, 255, 127)
line_width = 2
while True:
# Сюда мы будет помешять данные отрисовки, которые в дальнейшем будут переноситься в стек отрисовки оверлея.
esp_lines = []
# Полученим видовой матрицы и информации о окне игры
view_matrix = get_view_matrix(process, base_module, dwViewMatrix)
window_info = get_window_geometry("Counter-Strike: Global Offensive - Direct3D 9")
# Нахожденим адрес нашего игрока, нужен чтобы не рисовать бокс на самого себя в дальнейшем.
local_player = process.read_int(base_module + dwLocalPlayer)
# Игроки - объекты в списке в памяти игры, получаем 32 игрока (с запасом).
for i in range(32):
# Получаем самого игрока, его хп и состояние (действущий или бездействующий)
entity = process.read_int(base_module + dwEntityList + i * 0x10)
entity_health = process.read_int(entity + m_iHealth)
dormant = process.read_int(entity + m_bDormant)
# Если игрок существует, его хп, он не бездействуюий и не является нашим игроком (local player'ом).
if entity and entity_health and not dormant and entity != local_player:
# Итерируемся по каждому существующему игроку и получаем его координаты.
entity_x = process.read_float(entity + m_vecOrigin + 0x0)
entity_y = process.read_float(entity + m_vecOrigin + 0x4)
entity_z = process.read_float(entity + m_vecOrigin + 0x8)
# Пробразовываем координаты игрока в координаты точек (данные 4 точки являются нижней крышкой бокса, которые при соединении дают квадрат).
bottom1 = world_to_screen(view_matrix, (window_info[2], window_info[3]), entity_x - 15, entity_y + 15, entity_z)
bottom2 = world_to_screen(view_matrix, (window_info[2], window_info[3]), entity_x + 15, entity_y - 15, entity_z)
bottom3 = world_to_screen(view_matrix, (window_info[2], window_info[3]), entity_x - 15, entity_y - 15, entity_z)
bottom4 = world_to_screen(view_matrix, (window_info[2], window_info[3]), entity_x + 15, entity_y + 15, entity_z)
# Тут все тоже самое, только поднимаем коодинату z, тем самым создавая точки над головой игрока.
up1 = world_to_screen(view_matrix, (window_info[2], window_info[3]), entity_x - 15, entity_y + 15, entity_z + 75)
up2 = world_to_screen(view_matrix, (window_info[2], window_info[3]), entity_x + 15, entity_y - 15, entity_z + 75)
up3 = world_to_screen(view_matrix, (window_info[2], window_info[3]), entity_x - 15, entity_y - 15, entity_z + 75)
up4 = world_to_screen(view_matrix, (window_info[2], window_info[3]), entity_x + 15, entity_y + 15, entity_z + 75)
# Проверяем целостность точкек и соединяем их линиями, тем самым создавая бокс (добавляем все линии в наш заготовленный выше список).
if bottom1 and bottom2 and bottom3 and bottom4 and up1 and up2 and up3 and up4:
esp_lines.append({"type": "line", "x1": int(bottom1[0] - 6), "y1": int(bottom1[1]), "x2": int(bottom3[0]) - 6, "y2": int(bottom3[1]), "linesize": line_width, "linetype": pentype["solid"], "color": box_color})
esp_lines.append({"type": "line", "x1": int(bottom1[0] - 6), "y1": int(bottom1[1]), "x2": int(bottom4[0]) - 6, "y2": int(bottom4[1]), "linesize": line_width, "linetype": pentype["solid"], "color": box_color})
esp_lines.append({"type": "line", "x1": int(bottom4[0] - 6), "y1": int(bottom4[1]), "x2": int(bottom2[0]) - 6, "y2": int(bottom2[1]), "linesize": line_width, "linetype": pentype["solid"], "color": box_color})
esp_lines.append({"type": "line", "x1": int(bottom3[0] - 6), "y1": int(bottom3[1]), "x2": int(bottom2[0]) - 6, "y2": int(bottom2[1]), "linesize": line_width, "linetype": pentype["solid"], "color": box_color})
esp_lines.append({"type": "line", "x1": int(up1[0] - 6), "y1": int(up1[1]), "x2": int(up3[0]) - 6, "y2": int(up3[1]), "linesize": line_width, "linetype": pentype["solid"], "color": box_color})
esp_lines.append({"type": "line", "x1": int(up1[0] - 6), "y1": int(up1[1]), "x2": int(up4[0]) - 6, "y2": int(up4[1]), "linesize": line_width, "linetype": pentype["solid"], "color": box_color})
esp_lines.append({"type": "line", "x1": int(up4[0] - 6), "y1": int(up4[1]), "x2": int(up2[0]) - 6, "y2": int(up2[1]), "linesize": line_width, "linetype": pentype["solid"], "color": box_color})
esp_lines.append({"type": "line", "x1": int(up3[0] - 6), "y1": int(up3[1]), "x2": int(up2[0]) - 6, "y2": int(up2[1]), "linesize": line_width, "linetype": pentype["solid"], "color": box_color})
esp_lines.append({"type": "line", "x1": int(bottom1[0] - 6), "y1": int(bottom1[1]), "x2": int(up1[0]) - 6, "y2": int(up1[1]), "linesize": line_width, "linetype": pentype["solid"], "color": box_color})
esp_lines.append({"type": "line", "x1": int(bottom2[0] - 6), "y1": int(bottom2[1]), "x2": int(up2[0]) - 6, "y2": int(up2[1]), "linesize": line_width, "linetype": pentype["solid"], "color": box_color})
esp_lines.append({"type": "line", "x1": int(bottom3[0] - 6), "y1": int(bottom3[1]), "x2": int(up3[0]) - 6, "y2": int(up3[1]), "linesize": line_width, "linetype": pentype["solid"], "color": box_color})
esp_lines.append({"type": "line", "x1": int(bottom4[0] - 6), "y1": int(bottom4[1]), "x2": int(up4[0]) - 6, "y2": int(up4[1]), "linesize": line_width, "linetype": pentype["solid"], "color": box_color})
# Переносим содержимое нашего списка (наши линии) в стек отрисовки РАЗОМ, дабы не создавать мерзкие и неприятные блики и визуальные пролаги.
# Т.к. оверлей работает в отдельном потоке, то по истечению таймера он затриггерит ф-ию отрисовки, которая уже и обработает наш стек.
# Т.к. все работает в цикле, в начале которого мы и создаем список отрисовки, очищать его нет никакого смысла, ибо это произайдет само.
overlay.draw_stack = [*esp_lines]
time.sleep(0.01)
# Запуск потока ESP и оверлея.
# ОБЯЗАТЕЛЬНО СОЗДАВАТЬ ОТДЕЛНЫЙ ПОТОК! т.к. application_start() вызовет уже свой вечный цикл.
threading.Thread(target=esp).start()
application_start(application)
# Запуск потока ESP и оверлея
threading.Thread(target=esp).start()
application_start(application)
Основные идеи и релизация расписаны в комментариях, если вам нужно больше подробностей по работе pyextoverlay или pymemoryapi - вы можете найти информацию тут:
- pymemoryapi: Пожалуйста, авторизуйтесь для просмотра ссылки.
- Отрисовка примитивов на Qt: Пожалуйста, авторизуйтесь для просмотра ссылки.иПожалуйста, авторизуйтесь для просмотра ссылки.
Шаг №4 "Запуск чита:
Тут все довольно просто. Вариантов запуска нашего чита несколько.
1. Мы можем запустать наш main.py как обычный исполняемый файл просто нажав по нему 2 раза лкм.
2. Можно запустить скрипт напрямую через интерпретатор, для этого нужно открыть консоль и написать там: python <название файла>.
P.S. Важно чтобы игра была запущена в полном окне без рамок. Боксы будут вести себя неправильно при неполном экране, чтобы это починить нужно менять положение оверлея в точности под положение окна игры.
Пишите ваши мысли, задавайте вопросы (буду пытаться отвечать).
Наш дискорд сервер:
Пожалуйста, авторизуйтесь для просмотра ссылки.
Мой дискорд: Xenely#7771
Последнее редактирование: