You are not logged in.
Пока что тольок задумал способ "добавления" места в структуры фиксированного размера (будь то CPed, или CVehicle).
Пока что думаю сделать так (всё это можно сделать, изменяя игровые процедуры):
1) При создании педа (CPed::CPed) создавать новый буфер, указатель на него записать в структуру. Жертвуем полем структуры в 4 байт.
2) При удалении (CPed::~CPed) удаляем буфер.
3) Поле структуры, которым пожертвовали, теперь "перенести" в созданный буфер, т.е., заменить все ссылки к нему.
В общем, выглядит всё просто, есть ли тут какие-то неполадки, возможные сбои?
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
Да, все просто, но а если игра сама захочет создать/разрушить CPed?
Offline
Метод, в общем, логичный.
Неиспользуемое поле в CPed - найти не вопрос. Как вариант - использовать поля CPlacement, которые используются только в статических объектах.
Проблема с созданием/удалением объекта решается перехватом конструктора и деструктора (~5 точек)
Offline
5 раз? Можно ли просто "пропатчить" конструктор и деструктор?
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
Можно, но это тоже получится не меньше четырех точек (а делать это будет сложнее).
С одной стороны, приятно, что можно ограничиться только CPed (т.е. не нужно трогать CPlayerPed и CEmergencyPed), с дургой стороны, у CPed три конструктора и один деструктор (что и дает нам четыре точки)
Offline
А чем отличаются эти конструкторы?
И сколько их у CVehicle?
PS речь идёт о классах СА.
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
Вот CLEO-версия *извращенец*
{$CLEO} { RwMalloc = 0x72F420 RwFree = 0x72F430 refs to CPed.field_780 (turretPosMode) 0x5111E4 - mov ecx, [ebp+780h] , get 0x5E7EA8 - mov [esi+780h], edx , set } 0AC6: 0@ = label @ctor offset 0AC6: 1@ = label @ctorJmp offset 0AB1: call_scm_func @asmdef 4 asm_inj 0@ jump_from 0x5E812B then_jump 0x5E8131 offset_jump_in_asm 1@ 0AC6: 0@ = label @dtor offset 0AC6: 1@ = label @dtorJmp offset 0AB1: call_scm_func @asmdef 4 asm_inj 0@ jump_from 0x5E8656 then_jump 0x5E865F offset_jump_in_asm 1@ 0AC6: 0@ = label @field_780_get offset 0AC6: 1@ = label @field_780_getJmp offset 0AB1: call_scm_func @asmdef 4 asm_inj 0@ jump_from 0x5111E4 then_jump 0x5111EA offset_jump_in_asm 1@ 0AC6: 0@ = label @field_780_set offset 0AC6: 1@ = label @field_780_setJmp offset 0AB1: call_scm_func @asmdef 4 asm_inj 0@ jump_from 0x5E7EA8 then_jump 0x5E7EAE offset_jump_in_asm 1@ 0A93: :ctor hex 89 48 0C 89 48 10 B8 20 F4 72 00 // mov eax, 0x72F420 6A 64 // push 0x64 FF D0 // call eax 89 30 // mov [eax], esi 89 86 80 07 00 00 // mov [esi+780h], eax 83 C4 04 // add esp, 4 end :ctorJmp hex E9 00 00 00 00 end :dtor hex 83 C4 04 8B 86 80 07 00 00 // mov eax, [esi+780h] 85 C0 // test eax, eax 74 0B // jz short 0xB 50 // push eax B8 30 F4 72 00 // mov eax, 0x72F430 FF D0 // call eax 83 C4 04 // add esp, 4 8A 86 77 04 00 00 A8 01 end :dtorJmp hex E9 00 00 00 00 end :field_780_get hex 8B 8D 80 07 00 00 // mov ecx, [ebp+780h] 8B 49 04 // mov ecx, [ecx+4] end :field_780_getJmp hex E9 00 00 00 00 end :field_780_set hex 8B B6 80 07 00 00 // mov esi, [esi+780h] 89 56 04 // mov [esi+4], edx end :field_780_setJmp hex E9 00 00 00 00 end :asmdef 0A8C: write_memory 1@ size 1 value 0xE9 virtual_protect 1 0085: 4@ = 1@ 4@ += 5 0062: 0@ -= 4@ 1@ += 1 0A8C: write_memory 1@ size 4 value 0@ virtual_protect 1 0085: 4@ = 3@ 4@ += 5 0062: 2@ -= 4@ 3@ += 1 0A8C: write_memory 3@ size 4 value 2@ virtual_protect 1 0AB2: ret 0
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
Здравствуйте.
Решил всё это дело перенести в отдельный плугин, правда с изменениями.
Идея такая: выделяем под пул (CVehicle) массив указателей (размер массива - кол-во элементов в пуле). Этот указатель указывает на дополнительные буферы для структуры.
Информация об этих буферах хранится в списке (list).
В конструкторе (CVehicle::CVehicle) проходимся по этим буферам и инициализируем их. В деструкторе - деинициализация.
В общем, получилось такое:
// Переменные void **vehicleAdditional; unsigned int vehiclePluginsSize; struct tStructPluginDesc { unsigned int size; unsigned int userId; void *constructor; void *destructor; }; list<tStructPluginDesc*>vehiclePlugins; // Функции void AllocateAdditionalData() { vehicleAdditional = new void*[(*(CPool<void *> **)0xB74494)->m_Size]; vehiclePluginsSize = 0; } void ReleaseVehicleAdditional() { delete[] vehicleAdditional; for(auto i = vehiclePlugins.begin(); i != vehiclePlugins.end(); ++i) delete i._Ptr->_Myval; } unsigned int plugin::StructPlugins::RegisterVehiclePlugin(unsigned int size, unsigned int userId, void *constructor, void *destructor) { tStructPluginDesc *plugin = new tStructPluginDesc; plugin->size = size; plugin->userId = userId; plugin->constructor = constructor; plugin->destructor = destructor; vehiclePlugins.push_back(plugin); unsigned int result = vehiclePluginsSize; vehiclePluginsSize += size; return result; } void *plugin::StructPlugins::GetVehiclePlugin(CVehicle *vehicle, unsigned int id) { unsigned int vehicleId = ((unsigned int)vehicle - (unsigned int)(*(CPool<void> **)0xB74494)->m_Objects) / 0xA18; return (void *)((unsigned int)vehicleAdditional[vehicleId] + id); } void *FindVehiclePluginByUserId(CVehicle *vehicle, unsigned int userId) { unsigned int vehicleId = ((unsigned int)vehicle - (unsigned int)(*(CPool<void> **)0xB74494)->m_Objects) / 0xA18; unsigned int size = 0; for(auto i = vehiclePlugins.begin(); i != vehiclePlugins.end(); ++i) { if(i._Ptr->_Myval->userId == userId) return (void *)((unsigned int)vehicleAdditional[vehicleId] + size); size += i._Ptr->_Myval->size; } return NULL; } void __fastcall OnVehicleConstructor(CVehicle *vehicle) { unsigned int vehicleId = ((unsigned int)vehicle - (unsigned int)(*(CPool<void> **)0xB74494)->m_Objects) / 0xA18; vehicleAdditional[vehicleId] = new __int8[vehiclePluginsSize]; unsigned int size = 0; for(auto i = vehiclePlugins.begin(); i != vehiclePlugins.end(); ++i) { ((void (*)(CVehicle *, void *))i._Ptr->_Myval->constructor)(vehicle, (void *)((unsigned int)vehicleAdditional[vehicleId] + size)); size += i._Ptr->_Myval->size; } }; void __fastcall OnVehicleDestructor(CVehicle *vehicle) { unsigned int vehicleId = ((unsigned int)vehicle - (unsigned int)(*(CPool<void> **)0xB74494)->m_Objects) / 0xA18; unsigned int size = 0; for(auto i = vehiclePlugins.begin(); i != vehiclePlugins.end(); ++i) { ((void (*)(CVehicle *, void *))i._Ptr->_Myval->destructor)(vehicle, (void *)((unsigned int)vehicleAdditional[vehicleId] + size)); size += i._Ptr->_Myval->size; } delete vehicleAdditional[vehicleId]; };
Ну и использоваться будет примерно так (пример - структура для хранения информации о запасе бензина):
// Регистрация буфера struct tVehicleGasolineData { float gasolineState; float fuelCapacity; unsigned int timeLastRefueled; }; unsigned int gGasolineDataId; void VehicleGasolineDataConstructor(CVehicle *vehicle, tVehicleGasolineData *gasoline) { gasoline->gasolineState = 1.0; gasoline->fuelCapacity = 1.0; gasoline->timeLastRefueled = 0; } void VehicleGasolineDataDestructor(CVehicle *vehicle, tVehicleGasolineData *gasoline) { } void RegisterGasolineStruct() { gGasolineDataId = plugin::StructPlugins::RegisterVehiclePlugin(sizeof(tVehicleGasolineData), 0xABCDEF, VehicleGasolineDataConstructor, VehicleGasolineDataDestructor); }
//Пример использование буфера float SetVehicleGasolineState(CVehicle *vehicle, float state) { ((tVehicleGasolineData *)plugin::StructPlugins::GetVehiclePlugin(vehicle, gGasolineDataId))->gasolineState = state; }
Есть ли замечания по поводу такой реализации?)
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
Метод оказался полностью рабочим, я его уже задействовал в ImVehFt:
Last edited by DK22Pac (02-02-2014 15:34)
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
Да, всё это идёт в отдельной dll.
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
mfisto, да.
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
Ты подключаешь файлы plugin.dll (хедеры) к себе в проект, и вызываешь функцию регистрации своих "ячеек".
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
Пример с педами. При создании педа выбирается случайное имя, которое позже рисуется на экране.
Не могу прикрепить файл, вот, в общем pedNames.txt
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
Поправил
Offline