iw4nna.rock
Ты там вирусню какую-то пишешь?
nes
Какая ещё вирусня?
Мне нужно было просто понять почему в TCC (tiny c compiler) не работает экспорт глобальной переменной. А потом меня занесло и теперь пишу cheatengine.
iw4nna.rock
> А потом меня занесло и теперь пишу cheatengine.
Гиблое дело. Современные игры, особенно онлайн, имеют полный арсенал защиты. Скрытие OEP (Original Entry Point), скрытие таблицы импорта и т.д. Тренироваться нужно на относительно простых штуках, например найти пожатый чем-нибудь простеньким исполняемый модуль, восстановить таблицу импорта и сдампить на диск.
З.Ы.
Можно просто поизучать код сциллы, поcмотреть как осуществляется длл-инъекция и дамп памяти чужого процесса.
Базовый адрес - одно число. Начиная с него можно искать глобальные переменные. Но не получится найти локальные. Так как адреса локальных переменных начинаются с числа, которое существенно меньше базового адреса, и в то же время они огромные. Так например некая локальная переменная в программе А имеет адрес 600 с лишним миллиардов. Потребуется вечность, чтобы начиная с нуля найти переменную в пространстве с размером под 1 триллион байт.
iw4nna.rock
> Потребуется вечность, чтобы начиная с нуля найти переменную в пространстве с размером под 1 триллион байт.
Так тебе и не нужно всё виртуальное адресное пространство лопатить, достаточно найти адрес сегмента стека и пройтись по нему. Стек имеет фиксированный размер, его размер указан где-то в PE структурах исполняемого файла, можно посмотреть утилитой dumpbin из комплекта навожуал студии. Кроме того, регистр sp указывает на текущую вершину стека, можешь под отладчиком в той же навожуал студии посмотреть его значение и вычислить адрес текущего фрейма стека, а за одно изучить что в нем лежит и сравнить с кодом ф-ии, в которой сработала точка останова.
З.Ы.
И да, адрес сегмента стека вычисляется от того же базового адреса, его смещение по-моему тоже утилитой dumpbin можно посмотреть, но это не точно.
З.Ы.Ы.
И да, у каждого потока свой стек.
totoro
Надо было просто читать (ReadProcessMemory) большими блоками, а не по 4 байта - всплыло в памяти по дороге в пятёрочку.
Т.е. читаешь блок размером например 32768 байтов, а потом уже ищешь в этом блоке. Позже попробую.
В cheatengine кстати поиск начинается с нуля.
> достаточно найти адрес сегмента стека
не хочу использовать посторонние программы.
Хочу чтобы при попадании близлежащего объекта в поле зрения игрока с ним можно было взаимодействовать нажатием клавиши на клавиатуре.
void ACPlayer::DoInteraction() { const double Threshold = 0.8; for ( auto Component : InteractiveComponents) { auto LookAt = Component->GetComponentLocation( ) - CameraComponent->GetComponentLocation( ); auto LookDir = CameraComponent->GetComponentRotation( ).Vector( ); LookAt.Normalize( ); LookDir.Normalize( ); auto DotProduct = FVector::DotProduct( LookAt, LookDir); if ( DotProduct > Threshold) { Component->DoInteraction( this); break; } } }
Сойдет или можно улучшить?
totoro
> auto Component
Заменить на:
auto & c
> LookDir
Сделать глобальной переменной и вычислять её один раз за итерацию главного цикла программы и там же нормализовать.
totoro
> Сойдет или можно улучшить?
Как минимум надо не отваливаться на первом же подходящем объекте:
void ACPlayer::DoInteraction() { double Threshold = 0.8; InteractiveComponent BestComponent = nullptr; for ( auto Component : InteractiveComponents) { auto LookAt = Component->GetComponentLocation( ) - CameraComponent->GetComponentLocation( ); auto LookDir = CameraComponent->GetComponentRotation( ).Vector( ); LookAt.Normalize( ); LookDir.Normalize( ); auto DotProduct = FVector::DotProduct( LookAt, LookDir); if ( DotProduct > Threshold) { BestComponent = Component; Threshold = DotProduct; } } if ( BestComponent) BestComponent->DoInteraction( this); }
Потому что первый попавшийся != ближайший, который хочет выбрать пользователь.
iw4nna.rock
Ну я как бы не в контексте того что в коде можно улучшить вопрос задал, а про сам алгоритм обнаружения интерактивного объекта. Сейчас логика такая: определяется вектор направления игрока по отношению к объекту и вектор взгляда камеры, определяется разница между длиной проекции одного вектора на другой и длиной вектора на который осуществляется проекция, если разница не превышает заданной величины, то считается, что вектора +/- совпадают. При небольшом расстоянии между камерой и объектом это не критично, но чем дальше объект от камеры, тем больше расстояние между объектом и направлением взгляда.
totoro
> про сам алгоритм обнаружения
> интерактивного объекта
Тогда вообще не годится.
Вы делаете сталкер, а сталкер не про шарики.
Если ваша камера смотрит на пупок (центр/пивот/оригин) бандита, стоящего за шлагбаумом, то в итоге с кем ваша камера должна взаимодействовать? С бандитом или шлагбаумом?
По вашему коду - с бандитом, ведь пупок возле центра/пивота/оригина модели. А должно быть со шлагбаумом, ведь тот перед бандитом - ближе к камере по факту, а не своим центром/пивотом/оригином.
MrShoor
Да, пожалуй так будет честнее выборка, но может оказаться, что наиболее точно попавший в центр камеры компонент находится дальше других.
iw4nna.rock
> Если ваша камера смотрит на пупок (центр/пивот/оригин) бандита, стоящего за шлагбаумом, то в итоге с кем ваша камера должна взаимодействовать? С бандитом или шлагбаумом?
Видимо нужно еще ориентироваться на расстояние до объекта и площадь занимаемого экранного пространства, иначе получается, что автомат можно подобрать просто посмотрев в его сторону, но чтобы поговорить с бандитом придется пыриться ему в пупок(
totoro
Вам нужно в джи-буфере сделать рендер цвета-идентификатора объекта, а потом использовать пиксель в центре полученной текстуры для определения конкретного объекта в прицеле.
В этом случае не нужно искать расстояния, так как камера всегда будет смотреть на конкретный объект (тест глубины уже сделан видеокартой за вас).
totoro
> Да, пожалуй так будет честнее выборка, но может оказаться, что наиболее точно попавший в центр камеры компонент находится дальше других.
Ну добавь рейкаст например
MrShoor
> добавь рейкаст
Так-то можно было, но не хочется переплачивать, у меня уже есть список объектов, которые расположены в непосредственной близости от игрока, осталось только определить на какой(ие) объект(ы) смотрит игрок и выбрать тот, что ближе всего.
Логика следующая: каждый интерактивный объект - это иерархия внутри узла сцены, состоящая из меша и сферы:
Узел -|
- Меш
- Сфера
При пересечении сферы с игроком интерактивный объект добавляет себя в список интерактивных предметов игрока, а при выходе из пересечения - удаляет. Выходит, что задача сводится к тому, чтобы найти пересечение луча только с ограниченным количеством объектов, но в Анриле такой функциональности нет, есть только методы, определяющие пересечение со всеми объектами сцены заданного типа: https://dev.epicgames.com/documentation/en-us/unreal-engine/API/R… eByObjectType
В общем этот подход надо как-то перепроектировать, либо основательно, либо придумать как находить пересечение луча с ограниченным количеством объектов.