Не хочу создавать лишний тред уже, но можешь дать несколько советов вообще про ранфрейм? Типа чего не нужно делать в ранфрейме и своими файликами чита. А так же, как правильно аллоцировать память? Типа не против если я гдето создам оператором new. Ну вот например чтобы удобно хранить всякие штуки про героев:
(возможно в чем-то ошибаюсь)
ну во-первых new/delete хуйня, есть std::unique_ptr который делает то же самое но у него есть деструктор который делете вызывает.
std::vector<std::unique_ptr<PlayerData>> playersData;
...
auto my_data = std::make_unqiue<PlayerData>();
my_data->blablabla... //ну или в ктор сразу параметры
playersData.push_back(std::move(my_data));
ну либо нахуй тебе ваще нужны указатели если ты в векторе сами объекты напрямую можешь хранить? std::vector<PlayerData> + emplace_back или PlayerData my_data{}; my_data.govno = 123; playersData.push_back(std::move(my_data))
во-вторых глобальные переменные в длл умирают при вызове ентрипоинта(не дллмейна а той функцию которая его вызывает(дллмейн это не самая главная функция - есть являющаяся частью рантаймы майкрософтовской самая мега-главная функция-обертка которая уже потом дллмейн вызывает)) с DLL_PROCESS_DETACH. собственно если у тебя этого не происходит(ммап блаблабла) то глобалы и статики не будут умирать, так что если у тебя гдето логика в деструкторах то учитывай это
в-третьих по факту память это только виртуальные странички(ну есть еще физическая память но не суть), т.е. системный вызов NtAllocateVirtualMemory, всё остальное - malloc, new(он маллок юзает) и тд это просто обертки которые обычно заблаговременно резервируют некий кусок памяти и потом по кусочкам раздают его по запросу, либо аллоцируют новый виртуальный кусок если надо, и не спешат деаллоцировать память при освобождении а могут сохранять ее чтобы потом в будущем ее уже раздавать, в общем это "менеджеры" аллокаций. у них там свои "таблицы" сколько где в каких страничках "свободного" места и тд; есть системный менеджер(RtlCreateHeap и тд), его твоя длл и будет юзать(RtlCreateHeap хендл возвращает, там у каждой длл/exe свой хендл на свой менеджер); в сурс движке юзается tier0!g_pMemAlloc. главное не нарушать целостность этих "таблиц", т.е. не удалять то что аллоцированно чужим менеджером и не аллоцировать своим то что потом будет удалять чужой менеджер, не удалять дважды и тд.
кароче главное что тебе нужно понимать это то что реальные аллокации происходят системным вызовом, существует системный менеджер Rtl...Heap(new malloc и тд его юзают), концепции передачи/хранения объектов с владением(кто взял/получил/хранит объект тот и несет ответственность за удаление и тд) и просмотром(просто взяли посмотреть, не управляют жизнью и смертью объекта), а также где чья юрисдикция(какие вещи габен будет через свой g_pMemAlloc удалять(например если ты редактируешь(элементы добавляешь) в CUtlVector где-нибудь габеновский то тебе надо через его аллокатор это делать потому что потом рано или поздно он полезет удалять память из под этого вектора и если она не аллоцирована его аллокатором то это ему очень не понравится), какие ты сам будешь удалять и тд).
в-четвертых, при чем здесь ранфрейм и файлы? хук ранфрейма дает тебе КОНТЕКСТ, т.е. ПОТОК, т.е. та виндосовская хуйня которая запускается на ядре процессора, у которой в регистрах лежат свои данные и тд; работа с игровой хуйней прежде всего должна происходить в игровом контексте, как минимум из соображений синронизации(ты не можешь параллельно на своем ядре процессора итерировать сущности, потому что их в любой момент другое ядро может удалить к хуям одновременно с тем как ты с ними работаешь; если ты хукаешь ранфрейм(или другие функции) то ты получаешь прежде всего запуск кода на том же самом ядре(ну точнее в том же контексте), и в строго определенном порядке, до или после того как игра будет делать какието нужные/ненужные тебе вещи). файлы же в свою очередь это просто translation unit'ы(.c(pp) файлы) которые имеют закрепленные за ними переменные/функции(или упомянания чужих(из других спп файлов) переменных/функций)(internal linkage это то что принадлежит юниту, extern[al linkage] это упомянания вещей из других юнитов(мол они где-то есть пусть линкер сам ищет среди всей кучи юнитов данную вещь и "вставляет" ее сюда оттуда)), которые линкер собирает воедино(грубо говоря из кучи .cpp файлов делает один большой мега-cpp файл(это не так но суть примерно такая же) который потом в .exe/dll превращается)(.h(pp) файлы это просто ничего не значащий сам по себе мусор который компилятор в прямом смысле вставляет напрямую(ctrl+c, ctrl+v) в спп файлы когда видит #include)
в-пятых, т.к. ранфрейм в другом потоке то естественно если у тебя какойто мультитрединг/тредлокал шлак то надо с этим аккуратно быть, например в дравлисты всякие лучше не добавлять(без синхронизации. мьютекс хотя бы какой-нибудь. чтобы не было такого что ты на одном ядре читаешь а на другом пишешь в этот же самый момент. ничем хорошим не закончится) т.к. рендер(чтение из этих дравлистов) в другом потоке(не в мейн треде) происходит и тд.; аллокации впринципе должны быть тредсейф(т.е. либо нечего там синхронизировать либо есть механизмы синхронизации), читай документацию майкрософтовской рантаймы(ну судя по настройкам компилятора связанных с рантаймой, по названиям опций Multithreaded можно судить что да там тредсейф)